1345 lines
59 KiB
C#
1345 lines
59 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading.Tasks;
|
|
using DTS.Common.Classes.Groups;
|
|
using DTS.Common.Enums;
|
|
using DTS.Common.Enums.Sensors;
|
|
using DTS.Common.Events;
|
|
using DTS.Common.Events.RegionOfInterest.RegionOfInterestChannels;
|
|
using DTS.Common.Interface;
|
|
using DTS.Common.Interface.Channels;
|
|
using DTS.Common.Interface.DataRecorders;
|
|
using DTS.Common.Interface.Groups.GroupList;
|
|
using DTS.Common.Interface.RegionOfInterest;
|
|
using DTS.Common.Interface.RegionOfInterest.RegionOfInterestChannels;
|
|
using DTS.Common.Interface.TestDefinition;
|
|
using DTS.Common.Interface.TestSetups.TestSetupsList;
|
|
using DTS.Common.Utils;
|
|
|
|
using RegionOfInterestChannels.Resources;
|
|
using DTS.Common.Classes.TestSetups;
|
|
using DTS.Common.Classes.Sensors;
|
|
using DTS.Common.Enums.Hardware;
|
|
using DTS.Common.Interactivity;
|
|
|
|
namespace RegionOfInterestChannels
|
|
{
|
|
public class RegionOfInterestChannelsViewModel : IRegionOfInterestChannelsViewModel
|
|
{
|
|
/// <summary>
|
|
/// Creates a new instance of the HardwareListViewModel
|
|
/// </summary>
|
|
/// <param name="view"></param>
|
|
/// <param name="regionManager">The logical placeholder defined within the application's UI (in the shell or within views) into which views are displayed.</param>
|
|
/// <param name="eventAggregator">The EventAggregator which allows different components to publish/subscribe to events without being coupled to each other.</param>
|
|
/// <param name="unityContainer">The unityContainer.</param>
|
|
public RegionOfInterestChannelsViewModel(IRegionOfInterestChannelsView view,Prism.Regions.IRegionManager regionManager,
|
|
Prism.Events.IEventAggregator eventAggregator, Unity.IUnityContainer unityContainer)
|
|
{
|
|
View = view;
|
|
View.DataContext = this;
|
|
|
|
NotificationRequest = new InteractionRequest<Notification>();
|
|
ConfirmationRequest = new InteractionRequest<Confirmation>();
|
|
|
|
_eventAggregator = eventAggregator;
|
|
_regionManager = regionManager;
|
|
_eventAggregator.GetEvent<RaiseNotification>().Subscribe(OnRaiseNotification);
|
|
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>()
|
|
.Subscribe(OnBusyIndicatorNotification, Prism.Events.ThreadOption.PublisherThread, true);
|
|
RegionsOfInterest = new BindingList<IRegionOfInterest>();
|
|
}
|
|
|
|
#region Properties
|
|
#region base interface
|
|
public bool IsDirty { get; private set; }
|
|
private bool _isBusy;
|
|
|
|
public bool IsBusy
|
|
{
|
|
get => _isBusy;
|
|
set
|
|
{
|
|
_isBusy = value;
|
|
OnPropertyChanged("IsBusy");
|
|
}
|
|
}
|
|
|
|
private bool _isMenuIncluded;
|
|
|
|
public bool IsMenuIncluded
|
|
{
|
|
get => _isMenuIncluded;
|
|
set
|
|
{
|
|
_isMenuIncluded = value;
|
|
OnPropertyChanged("IsMenuIncluded");
|
|
}
|
|
}
|
|
|
|
private bool _isNavigationIncluded;
|
|
|
|
public bool IsNavigationIncluded
|
|
{
|
|
get => _isNavigationIncluded;
|
|
set
|
|
{
|
|
_isNavigationIncluded = value;
|
|
OnPropertyChanged("IsNavigationIncluded");
|
|
}
|
|
}
|
|
|
|
public IRegionOfInterestChannelsView View { get; set; }
|
|
#endregion
|
|
private const string VoltageString = " (Voltage)";
|
|
private const string CurrentString = " (Current)";
|
|
private object Parent;
|
|
private string _currentFilter = String.Empty;
|
|
private Dictionary<Fields, string> _filterByField = new Dictionary<Fields, string>();
|
|
private Prism.Events.IEventAggregator _eventAggregator { get; }
|
|
|
|
private Prism.Regions.IRegionManager _regionManager;
|
|
|
|
public InteractionRequest<Notification> NotificationRequest { get; }
|
|
public InteractionRequest<Confirmation> ConfirmationRequest { get; }
|
|
|
|
private ITestSummary _testSummary;
|
|
|
|
|
|
private BindingList<IRegionOfInterest> _regionsOfInterest;
|
|
public BindingList<IRegionOfInterest> RegionsOfInterest
|
|
{
|
|
get => _regionsOfInterest;
|
|
set
|
|
{
|
|
_regionsOfInterest = value;
|
|
if (null != _regionsOfInterest)
|
|
{
|
|
//FB16120: scrub list of channel names not found in case of bad data
|
|
foreach (var roi in _regionsOfInterest)
|
|
{
|
|
if (null == roi.ChannelNames) { continue; }
|
|
var channelList = new List<string>();
|
|
var channelIdList = new List<long>();
|
|
foreach (var channelName in roi.ChannelNames)
|
|
{
|
|
var noParentChannel = RegionOfInterest.RemoveParentDASName(channelName);
|
|
channelList.Add(noParentChannel);
|
|
}
|
|
foreach (var channelId in roi.ChannelIds)
|
|
{
|
|
channelIdList.Add(channelId);
|
|
}
|
|
|
|
var notFound = new List<string>();
|
|
var idsNotFound = new List<long>();
|
|
var allChannelHash = new HashSet<string>();
|
|
var allChannelIdHash = new HashSet<long>();
|
|
var allChannelsUnfilteredIndex = 0;
|
|
//18349: Cannot perform download ROI using download data tab.
|
|
//in the download data route there is no SensorData, trying to access it will throw an exception ...
|
|
foreach (var ach in AllChannelsUnfiltered)
|
|
{
|
|
if (null != ach.SensorData)
|
|
{
|
|
var achHardware = ach.SensorData.IsTestSpecificEmbedded ? DTS.Common.Classes.TestSetups.TestTemplateBase.GetEmbeddedChannelHardware(ach) : ach.Hardware;
|
|
|
|
//Check for ROI channels that did not have a and now have a hardware channel via ID or manual assignment
|
|
//If there is an EID, we want to strip off the leading "Assigned by ID"
|
|
achHardware = RegionOfInterest.RemoveAssignedByIDFromHardwareString(achHardware);
|
|
//33237 Don't unassign multiple ROI channels if Compact is selected in Hardware step
|
|
var embedded = ach.SensorData?.IsTestSpecificEmbedded ?? false;
|
|
var thermo = ach.SensorData?.IsTestSpecificThermo ?? false;
|
|
var serialNumber = ChannelSerialNumber.SerialNumberFromChannel(embedded || thermo, ach.Sensor, ach.SensorData?.SerialNumber ?? ach.Sensor);
|
|
var hashName = RegionOfInterest.GetAnalogChanName(serialNumber, achHardware, HardwareConstants.TSR_AIR_PREPEND, ach.Sensor);
|
|
allChannelHash.Add(hashName);
|
|
//The channelList entry may have no hardware channel or one that's
|
|
//different than the one assigned later by ID. Additionally,
|
|
//there may be more than one channel with the same sensor.
|
|
|
|
//If we find an exact match, we're don't need to add/replace the hardware channel
|
|
if (!channelList.Contains(hashName))
|
|
{
|
|
//An exact match was not found, so add/replace the hardware channel if there is
|
|
//one and only one with this sensor serial number.
|
|
UpdateChannelList(ach.SensorData.SerialNumber, hashName, channelList, allChannelsUnfilteredIndex);
|
|
}
|
|
var hashId = ach.Id;
|
|
allChannelIdHash.Add(hashId);
|
|
allChannelsUnfilteredIndex++;
|
|
}
|
|
}
|
|
foreach (var ch in channelList)
|
|
{
|
|
if (allChannelHash.Count > 0 && !allChannelHash.Contains(ch))
|
|
{
|
|
notFound.Add(ch);
|
|
}
|
|
}
|
|
foreach (var id in channelIdList)
|
|
{
|
|
if (allChannelIdHash.Count > 0 && !allChannelIdHash.Contains(id))
|
|
{
|
|
idsNotFound.Add(id);
|
|
}
|
|
}
|
|
|
|
foreach (var name in notFound)
|
|
{
|
|
channelList.RemoveAll(str => str == name);
|
|
}
|
|
foreach (var id in idsNotFound)
|
|
{
|
|
channelIdList.RemoveAll(lng => lng == id);
|
|
}
|
|
|
|
roi.SetChannelNamesNoNotify(channelList.ToArray());
|
|
roi.SetChannelIdsNoNotify(channelIdList.ToArray());
|
|
}
|
|
}
|
|
ResetDataView();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// If there is one and only one entry in the list with a given serial number
|
|
/// update it with different hardware.
|
|
/// </summary>
|
|
/// <param name="serialNumber"></param>
|
|
/// <param name="hashName"></param>
|
|
/// <param name="channelList"></param>
|
|
private void UpdateChannelList(string serialNumber, string hashName, List<string> channelList, int startingIndex)
|
|
{
|
|
var index = 0;
|
|
foreach (var channel in channelList)
|
|
{
|
|
if (index >= startingIndex)
|
|
{
|
|
var channelSerialNumber = channel.Substring(channel.LastIndexOf('\\') + 1);
|
|
if (channelSerialNumber == serialNumber)
|
|
{
|
|
channelList[index] = hashName;
|
|
return;
|
|
}
|
|
}
|
|
index++;
|
|
}
|
|
}
|
|
private PossibleFilters BridgeFilter { get; set; } = PossibleFilters.All;
|
|
/// <Summary>
|
|
/// holds a term (should be in lower case) to filter in/search for
|
|
/// </Summary>
|
|
private string SearchTerm { get; set; } = string.Empty;
|
|
public List<DTS.Common.Classes.Groups.GroupChannel> AllChannelsUnfiltered { get; set; } = new List<DTS.Common.Classes.Groups.GroupChannel>();
|
|
|
|
/// <summary>
|
|
/// this is all the channels displayed in the UI (but not any channels filtered out)
|
|
/// </summary>
|
|
public ObservableCollection<GroupChannel> AllChannels { get; set; }
|
|
|
|
private ObservableCollection<ITestChannel> AllTestChannels { get; set; }
|
|
|
|
public string[] AllChannelSSNs
|
|
{
|
|
get
|
|
{
|
|
var ssns = new List<string>();
|
|
|
|
//13477 Crash when clicking + to add second ROI for CSV export
|
|
//when coming from the export tile, AllChannels is null
|
|
if (null != AllChannels && AllChannels.Any())
|
|
{
|
|
foreach (var ch in AllChannels)
|
|
{
|
|
if (ch.IsDisabled) { continue; }
|
|
|
|
if (ch.SensorId < 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var chHardware = ch.SensorData.IsTestSpecificEmbedded ? DTS.Common.Classes.TestSetups.TestTemplateBase.GetEmbeddedChannelHardware(ch) : ch.Hardware;
|
|
var serialNumber = ChannelSerialNumber.SerialNumberFromChannel(ch.SensorData.IsTestSpecificEmbedded || ch.SensorData.IsTestSpecificThermo, ch.Sensor, ch.SensorData.SerialNumber);
|
|
ssns.Add(chHardware + "\\" + serialNumber);
|
|
}
|
|
}
|
|
else if (null != AllTestChannels && AllTestChannels.Any())
|
|
{
|
|
foreach (var ch in AllTestChannels)
|
|
{
|
|
ssns.Add(ch.HardwareChannelName + "\\" + (ch.Bridge.ToUpperInvariant() == "SQUIB" || ch.Bridge.ToUpperInvariant() == "TOMDIGITAL" ? ch.Description.Replace(VoltageString, string.Empty).Replace(CurrentString, string.Empty) : ch.SerialNumber));
|
|
}
|
|
}
|
|
|
|
return ssns.ToArray();
|
|
}
|
|
}
|
|
|
|
private BindingList<ChannelEnabler> _channelList = new BindingList<ChannelEnabler>();
|
|
public BindingList<ChannelEnabler> ChannelList
|
|
{
|
|
get => _channelList;
|
|
set
|
|
{
|
|
if (null != _channelList)
|
|
{
|
|
_channelList.ListChanged -= CheckboxesOnListChanged;
|
|
}
|
|
_channelList = value;
|
|
if (null != _channelList)
|
|
{
|
|
_channelList.ListChanged += CheckboxesOnListChanged;
|
|
}
|
|
OnPropertyChanged("ChannelList");
|
|
}
|
|
}
|
|
|
|
private ObservableCollection<ColumnDescriptor> _columns;
|
|
public ObservableCollection<ColumnDescriptor> Columns
|
|
{
|
|
get => _columns;
|
|
set
|
|
{
|
|
_columns = value;
|
|
OnPropertyChanged("Columns");
|
|
}
|
|
|
|
}
|
|
|
|
private void CheckboxesOnListChanged(object sender, ListChangedEventArgs listChangedEventArgs)
|
|
{
|
|
if (listChangedEventArgs.PropertyDescriptor.Name.Equals("LastIndexChanged"))
|
|
{
|
|
var chChangedIndex = listChangedEventArgs.NewIndex;
|
|
var roiChangedIndex = ((BindingList<ChannelEnabler>)sender)[chChangedIndex].LastIndexChanged;
|
|
|
|
var checkedIds = new List<long>();
|
|
var checkedGuidStringList = new List<string>();
|
|
foreach (var channel in (BindingList<ChannelEnabler>)sender)
|
|
{
|
|
if (channel.ROIIncludes[roiChangedIndex].Checked)
|
|
{
|
|
checkedIds.Add(channel.ChannelId);
|
|
checkedGuidStringList.Add(channel.GuidString);
|
|
}
|
|
}
|
|
var checkedGuidStringIdDict = new Dictionary<string, long>();
|
|
|
|
var channelNameList = new List<string>();
|
|
var checkedChannelIdList = new List<long>();
|
|
|
|
foreach (var checkedId in checkedIds)
|
|
{
|
|
checkedChannelIdList.Add(checkedId);
|
|
}
|
|
var checkedIndex = 0;
|
|
foreach (var guidString in checkedGuidStringList)
|
|
{
|
|
checkedGuidStringIdDict[guidString] = checkedChannelIdList[checkedIndex];
|
|
checkedIndex++;
|
|
}
|
|
|
|
foreach (var guidStringIdPair in checkedGuidStringIdDict)
|
|
{
|
|
var channelName = string.Empty;
|
|
if (guidStringIdPair.Value == -1)
|
|
{
|
|
channelName = ((BindingList<ChannelEnabler>)sender).Where(ch => ch.GuidString == guidStringIdPair.Key).Select(ch => ch.Descriptor).FirstOrDefault<string>();
|
|
}
|
|
else
|
|
{
|
|
channelName = ((BindingList<ChannelEnabler>)sender).Where(ch => ch.ChannelId == guidStringIdPair.Value).Select(ch => ch.Descriptor).FirstOrDefault<string>();
|
|
}
|
|
channelNameList.Add(channelName);
|
|
}
|
|
|
|
_regionsOfInterest[roiChangedIndex].ChannelNames = channelNameList.ToArray();
|
|
_regionsOfInterest[roiChangedIndex].ChannelIds = checkedChannelIdList.ToArray();
|
|
_eventAggregator.GetEvent<RegionOfInterestChannelsSelectedEvent>()
|
|
.Publish(new RegionOfInterestChannelsSelectedEventArgs(_regionsOfInterest[roiChangedIndex].Suffix,
|
|
_regionsOfInterest[roiChangedIndex].ChannelNames,
|
|
_regionsOfInterest[roiChangedIndex].ChannelIds,
|
|
Parent));
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Methods
|
|
public void SetParent(object o)
|
|
{
|
|
Parent = o;
|
|
}
|
|
private void ResetDataView()
|
|
{
|
|
try
|
|
{
|
|
var columnsList = new ObservableCollection<ColumnDescriptor>();
|
|
//column order
|
|
columnsList.Add(new ColumnDescriptor()
|
|
{ HeaderText = "Group Name", DisplayMember = "GroupName", MemberType = typeof(string) });
|
|
if (ISOViewMode == IsoViewMode.ISOAndUserCode || ISOViewMode == IsoViewMode.UserCodeOnly)
|
|
{
|
|
columnsList.Add(new ColumnDescriptor()
|
|
{ HeaderText = "User Code", DisplayMember = "UserCode", MemberType = typeof(string) });
|
|
columnsList.Add(new ColumnDescriptor()
|
|
{ HeaderText = "User Channel Name", DisplayMember = "UserChannelName", MemberType = typeof(string) });
|
|
}
|
|
else if (ISOViewMode == IsoViewMode.ISOOnly || ISOViewMode == IsoViewMode.ISOAndUserCode)
|
|
{
|
|
columnsList.Add(new ColumnDescriptor()
|
|
{ HeaderText = "ISO Code", DisplayMember = "ISOCode", MemberType = typeof(string) });
|
|
columnsList.Add(new ColumnDescriptor()
|
|
{ HeaderText = "ISO Channel Name", DisplayMember = "ISOChannelName", MemberType = typeof(string) });
|
|
}
|
|
else if (ISOViewMode == IsoViewMode.ChannelNameOnly)
|
|
{
|
|
columnsList.Add(new ColumnDescriptor()
|
|
{ HeaderText = StringResources.ChannelName, DisplayMember = "ChannelName", MemberType = typeof(string) });
|
|
}
|
|
columnsList.Add(new ColumnDescriptor()
|
|
{ HeaderText = "Hardware", DisplayMember = "Hardware", MemberType = typeof(string) });
|
|
columnsList.Add(new ColumnDescriptor()
|
|
{ HeaderText = "Serial Number", DisplayMember = "SerialNumber", MemberType = typeof(string) });
|
|
columnsList.Add(new ColumnDescriptor()
|
|
{ HeaderText = "Sensor Name", DisplayMember = "SensorName", MemberType = typeof(string) });
|
|
columnsList.Add(new ColumnDescriptor()
|
|
{ HeaderText = "DAS Serial Number", DisplayMember = "DASSerialNumber", MemberType = typeof(string) });
|
|
columnsList.Add(new ColumnDescriptor()
|
|
{ HeaderText = "Sample Rate", DisplayMember = "SampleRate", MemberType = typeof(string) });
|
|
columnsList.Add(new ColumnDescriptor()
|
|
{ HeaderText = "Display Units", DisplayMember = "DisplayUnits", MemberType = typeof(string) });
|
|
for (var i = 0; i < _regionsOfInterest.Count; i++)
|
|
{
|
|
columnsList.Add(new ColumnDescriptor()
|
|
{
|
|
HeaderText = _regionsOfInterest[i].Suffix,
|
|
DisplayMember = "ROIIncludes[" + i.ToString() + "]",
|
|
MemberType = typeof(bool)
|
|
});
|
|
}
|
|
|
|
if (_testSummary != null)
|
|
{
|
|
//export tile use
|
|
BuildChannelListFromSummary();
|
|
|
|
}
|
|
else
|
|
{
|
|
//everywhere else
|
|
BuildChannelListFromGroupChannels();
|
|
}
|
|
|
|
Columns = columnsList;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
DTS.Common.Utilities.Logging.APILogger.Log("ResetDataView exception: ", ex);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
private string GetChannelCode(ITestChannel testChannel)
|
|
{
|
|
switch (ISOViewMode)
|
|
{
|
|
case IsoViewMode.ISOOnly:
|
|
return testChannel.IsoCode;
|
|
case IsoViewMode.ISOAndUserCode:
|
|
return $"{testChannel.UserCode}/{testChannel.IsoCode}";
|
|
case IsoViewMode.UserCodeOnly:
|
|
return testChannel.UserCode;
|
|
case IsoViewMode.ChannelNameOnly: return string.Empty;
|
|
}
|
|
|
|
return "";
|
|
}
|
|
private void BuildChannelListFromSummary()
|
|
{
|
|
var channelList = new BindingList<ChannelEnabler>();
|
|
foreach (var ch in AllTestChannels)
|
|
{
|
|
var serialNumber = ChannelSerialNumber.SerialNumberFromChannel(ch.SerialNumber == "TSA_Embedded", ch.UserChannelName, ch.SerialNumber);
|
|
var newEnabler = new ChannelEnabler()
|
|
{
|
|
UserCode = ch.UserCode,
|
|
UserChannelName = ch.UserChannelName,
|
|
ISOCode = ch.IsoCode,
|
|
ISOChannelName = ch.IsoChannelName,
|
|
Hardware = ch.HardwareChannelName,
|
|
SerialNumber = ch.SerialNumber,
|
|
SensorName = ch.Description,
|
|
DASSerialNumber = ch.HardwareChannelName ?? "N/A", //fix this
|
|
SampleRate = ch.SampleRateHz.ToString(), //test this
|
|
Code = GetChannelCode(ch),
|
|
DisplayUnits = ch.Eu,
|
|
GroupName = ch.ChannelGroupName ?? string.Empty,
|
|
Descriptor = ch.HardwareChannelName + "\\" + serialNumber,
|
|
GuidString = Guid.NewGuid().ToString(),
|
|
ChannelId = ParseChannelId(ch.ChannelId)
|
|
};
|
|
|
|
foreach (var roi in _regionsOfInterest)
|
|
{
|
|
if (null == roi.ChannelIds)
|
|
{
|
|
newEnabler.ROIIncludes.Add(new State(false));
|
|
}
|
|
else { newEnabler.ROIIncludes.Add(new State(roi.ChannelIds.Contains(newEnabler.ChannelId))); }
|
|
}
|
|
|
|
channelList.Add(newEnabler);
|
|
}
|
|
ChannelList = channelList;
|
|
}
|
|
/// <summary>
|
|
/// 44068 Older .dts files have a ChannelId consisting of: <Guid or channel name>_<number>_<unique number>,
|
|
/// for example, "H3-3ch_0_2" or "f9f0bfe8-afc4-4730-8045-8f1e45340573_0_8533". The ChannelId in
|
|
/// current .dts files is simply the unique number.
|
|
/// </summary>
|
|
/// <param name="channelIdString"></param>
|
|
/// <returns></returns>
|
|
private static long ParseChannelId(string channelIdString)
|
|
{
|
|
if (channelIdString.EndsWith(DTS.Common.Constants.CURRENT_SUFFIX))
|
|
{
|
|
channelIdString = channelIdString.Substring(0, channelIdString.Length - DTS.Common.Constants.CURRENT_SUFFIX.Length);
|
|
}
|
|
var parsedChannelId = string.Empty;
|
|
|
|
var lastUnderscore = channelIdString.LastIndexOf('_');
|
|
if (lastUnderscore != -1)
|
|
{
|
|
//Must be an older .dts file, so parse out the unique number
|
|
var channelIdLen = channelIdString.Length - (lastUnderscore + 1);
|
|
parsedChannelId = channelIdString.Substring(lastUnderscore + 1, channelIdLen);
|
|
}
|
|
else
|
|
{
|
|
parsedChannelId = channelIdString;
|
|
}
|
|
|
|
//the parse here would throw an exception with this dataset:
|
|
// http://manuscript.dts.local/f/cases/45091/Add-ability-to-export-HDF-using-SLICEWare-data
|
|
if (long.TryParse(parsedChannelId, out var l)) { return l; }
|
|
return -1;
|
|
}
|
|
public IsoViewMode ISOViewMode { get; set; }
|
|
private void BuildChannelListFromGroupChannels()
|
|
{
|
|
try
|
|
{
|
|
//FB 18875 cache sensor calibration
|
|
//we don't need calibrations for ROI view!
|
|
IReadOnlyDictionary<string, DTS.SensorDB.SensorCalibration> cals = null;
|
|
var channelList = new BindingList<ChannelEnabler>();
|
|
var roiChannelNames = new Dictionary<IRegionOfInterest, HashSet<string>>();
|
|
var roiChannelIds = new Dictionary<IRegionOfInterest, HashSet<long>>();
|
|
foreach (var roi in _regionsOfInterest)
|
|
{
|
|
roiChannelNames[roi] = new HashSet<string>();
|
|
roiChannelIds[roi] = new HashSet<long>();
|
|
foreach (var name in roi.ChannelNames)
|
|
{
|
|
roiChannelNames[roi].Add(name);
|
|
}
|
|
foreach (var channelId in roi.ChannelIds)
|
|
{
|
|
roiChannelIds[roi].Add(channelId);
|
|
}
|
|
}
|
|
foreach (var ch in AllChannels ?? new ObservableCollection<GroupChannel>())
|
|
{
|
|
if (ch.IsDisabled || ch.SensorId <= 0)
|
|
{
|
|
continue;
|
|
}
|
|
DTS.SensorDB.SensorData sd = null;
|
|
if (null != ch.SensorData)
|
|
{
|
|
sd = ch.SensorData as DTS.SensorDB.SensorData;
|
|
}
|
|
if (null == sd)
|
|
{
|
|
if (null == cals)
|
|
{
|
|
cals = DTS.SensorDB.SensorsCollection.GetLatestCalibrations();
|
|
}
|
|
sd = DTS.SensorDB.SensorsCollection.SensorsList.GetSensorById(ch.SensorId, true, cals);
|
|
}
|
|
if (null == sd)
|
|
{
|
|
DTS.Common.Utilities.Logging.APILogger.Log(
|
|
"BuildChannelListFromGroupChannels: failed to find sensor: ", ch.SensorId);
|
|
continue;
|
|
}
|
|
if (sd.IsDigitalOutput() || sd.IsTestSpecificDigitalOutput)
|
|
{
|
|
//FB14896: scrub digital outs from ROI
|
|
DTS.Common.Utilities.Logging.APILogger.Log(
|
|
"BuildChannelListFromGroupChannels: roi sensor is digital out: ", ch.SensorId);
|
|
continue;
|
|
}
|
|
|
|
// FB16382: if sensor data missing from groupchannel, we already searched for it above so assign it while we're here
|
|
if (null == ch.SensorData) { ch.SensorData = sd; }
|
|
var chHardware = ch.SensorData.IsTestSpecificEmbedded ? DTS.Common.Classes.TestSetups.TestTemplateBase.GetEmbeddedChannelHardware(ch) : ch.Hardware;
|
|
//If there is an EID, we want to strip off the leading "Assigned by ID"
|
|
chHardware = RegionOfInterest.RemoveAssignedByIDFromHardwareString(chHardware);
|
|
chHardware = RegionOfInterest.RemoveParentDASName(chHardware);
|
|
var serialNumber = ChannelSerialNumber.SerialNumberFromChannel(sd.IsTestSpecificEmbedded || sd.IsTestSpecificThermo, ch.Sensor, sd.SerialNumber);
|
|
var newEnabler = new ChannelEnabler
|
|
{
|
|
UserCode = ch.UserCode,
|
|
UserChannelName = ch.UserChannelName,
|
|
ISOCode = ch.IsoCode,
|
|
ISOChannelName = ch.IsoChannelName,
|
|
Hardware = ch.Hardware,
|
|
SerialNumber = sd?.SerialNumber ?? "???",
|
|
SensorName = sd?.Comment ?? "???",
|
|
DASSerialNumber = ch.HardwareChannel?.GetParentDAS().SerialNumber ?? "N/A",
|
|
SampleRate = ch.TestSampleRate == 0 ? "N/A" : ch.TestSampleRate.ToString(),
|
|
Code = ch.GetChannelCode(ISOViewMode),
|
|
DisplayUnits = sd.Calibration?.Records?.Records[0]?.EngineeringUnits ?? "N/A",//cal?.Records?.Records.First()?.EngineeringUnits ?? "N/A",
|
|
GroupName = ch.GroupName,
|
|
Descriptor = chHardware + "\\" + serialNumber,
|
|
GuidString = Guid.NewGuid().ToString(),
|
|
ChannelId = Convert.ToInt64(ch.Id)
|
|
};
|
|
|
|
foreach (var roi in _regionsOfInterest)
|
|
{
|
|
if (null == roi.ChannelNames || null == roi.ChannelIds)
|
|
{
|
|
newEnabler.ROIIncludes.Add(new State(false));
|
|
}
|
|
else
|
|
{
|
|
newEnabler.ROIIncludes.Add(new State(roiChannelIds[roi].Contains(newEnabler.ChannelId)));
|
|
}
|
|
}
|
|
|
|
channelList.Add(newEnabler);
|
|
}
|
|
|
|
ChannelList = channelList;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
DTS.Common.Utilities.Logging.APILogger.Log("Exception in BuildChannelListFromGroupChannels", ex);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public void SetTest(string path, IsoViewMode viewMode)
|
|
{
|
|
ISOViewMode = viewMode;
|
|
_filterByField.Clear();
|
|
var tml = new DTS.Common.Classes.Viewer.TestMetadata.TestMetadataList();
|
|
var tsl = tml.GetTestSummaryList(this, path);
|
|
foreach (var test in tsl)
|
|
{
|
|
Utils.SetChannelInfo(test.TestMetadata, path, DTS.Serialization.SliceRaw.File.PersistentChannel.GetIsoCode);
|
|
test.Channels = test.TestMetadata.TestRun.Channels;
|
|
test.Graphs = test.TestMetadata.TestSetup.TestGraphs;
|
|
test.CalculatedChannels = test.TestMetadata.TestRun.CalculatedChannels;
|
|
}
|
|
|
|
_testSummary = tsl[0];
|
|
if (null == AllTestChannels)
|
|
{
|
|
AllTestChannels = new ObservableCollection<ITestChannel>();
|
|
}
|
|
Filter();
|
|
ResetDataView();
|
|
}
|
|
|
|
private void ProcessChannels(IGroupChannel[] allChannels, Dictionary<string, IDASHardware> hardwareLookup, IGroup[] groups, Dictionary<IGroupChannel, IGroup> groupLookup)
|
|
{
|
|
AllChannelsUnfiltered.Clear();
|
|
var channelLookup = new Dictionary<string, IHardwareChannel>();
|
|
|
|
foreach (var hl in hardwareLookup)
|
|
{
|
|
var channels = hl.Value.GetIHardwareChannels();
|
|
foreach (var ch in channels)
|
|
{
|
|
channelLookup[$"{hl.Value.DASId}_{ch.ChannelNumber}"] = ch;
|
|
}
|
|
}
|
|
|
|
foreach (var ch in allChannels)
|
|
{
|
|
if (ch.IsDisabled || ch.SensorId < 0) { continue; }
|
|
|
|
AllChannelsUnfiltered.Add((GroupChannel)ch);
|
|
}
|
|
Filter();
|
|
}
|
|
public void Filter(string term)
|
|
{
|
|
SearchTerm = term.ToLower();
|
|
Filter();
|
|
}
|
|
//sets the persistent filter to a given type and performs the filter
|
|
public void SetFilter(PossibleFilters bridgeFilter)
|
|
{
|
|
BridgeFilter = bridgeFilter;
|
|
Filter();
|
|
}
|
|
|
|
public void Filter(object tag, string term)
|
|
{
|
|
if (Enum.TryParse((string)tag, out Fields field))
|
|
{
|
|
_filterByField[field] = term;
|
|
Filter();
|
|
}
|
|
}
|
|
|
|
private void Filter()
|
|
{
|
|
if (null != AllChannels)
|
|
{
|
|
AllChannels.Clear();
|
|
AllChannelsUnfiltered?.Sort();
|
|
//FB 18875 cache sensor calibration
|
|
var latestCalibrations = DTS.SensorDB.SensorsCollection.GetLatestCalibrations();
|
|
|
|
foreach (var ch in AllChannelsUnfiltered)
|
|
{
|
|
if (ChannelFilter(ch, latestCalibrations) && ChannelSearch(ch))
|
|
{
|
|
AllChannels.Add(ch);
|
|
}
|
|
}
|
|
OnPropertyChanged("AllChannels");
|
|
BuildChannelListFromGroupChannels();
|
|
}
|
|
else if (null != _testSummary)
|
|
{
|
|
AllTestChannels.Clear();
|
|
foreach (var ch in _testSummary.Channels)
|
|
{
|
|
if (ChannelFilter(ch) && ChannelSearch(ch))
|
|
{
|
|
AllTestChannels.Add(ch);
|
|
}
|
|
}
|
|
OnPropertyChanged("AllTestChannels");
|
|
BuildChannelListFromSummary();
|
|
}
|
|
}
|
|
|
|
public enum Fields
|
|
{
|
|
ChannelName,
|
|
DisplayName,
|
|
SerialNumber,
|
|
SensorName,
|
|
DASSerialNumber,
|
|
SampleRate,
|
|
ISOCode,
|
|
DisplayUnits,
|
|
GroupName,
|
|
ROIIncludes
|
|
}
|
|
private bool ChannelFilter(GroupChannel ch, IReadOnlyDictionary<string, DTS.SensorDB.SensorCalibration> calLookup = null)
|
|
{
|
|
var fields = Enum.GetValues(typeof(Fields)).Cast<Fields>().ToArray();
|
|
//FB 18875 cache sensor calibration
|
|
var sd = DTS.SensorDB.SensorsCollection.SensorsList.GetSensorById(ch.SensorId, true, calLookup);
|
|
var channelName = ch.GetChannelName(ISOViewMode);
|
|
foreach (var field in fields)
|
|
{
|
|
if (!_filterByField.ContainsKey(field)) { continue; }
|
|
var term = _filterByField[field];
|
|
if (string.IsNullOrWhiteSpace(term)) { continue; }
|
|
switch (field)
|
|
{
|
|
case Fields.ChannelName:
|
|
if (!(System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(channelName, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0)) { return false; } //@TODO
|
|
break;
|
|
case Fields.DisplayName:
|
|
if (!(System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(channelName, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0)) { return false; } //@TODO
|
|
break;
|
|
case Fields.SerialNumber:
|
|
if (!(System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(sd.SerialNumber, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0)) { return false; }
|
|
break;
|
|
case Fields.SensorName:
|
|
if (!(System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(sd.Comment, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0)) { return false; }
|
|
break;
|
|
case Fields.DASSerialNumber:
|
|
if (!(System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(ch.HardwareChannel?.GetParentDAS().SerialNumber ?? "N/A", term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0)) { return false; }
|
|
break;
|
|
case Fields.SampleRate:
|
|
if (!(System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(ch.TestSampleRate.ToString(), term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0)) { return false; }
|
|
break;
|
|
case Fields.ISOCode:
|
|
if (!(System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(ch.IsoCode, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0)) { return false; }
|
|
break;
|
|
case Fields.DisplayUnits:
|
|
var cal = DTS.SensorDB.SensorCalibrationList.GetLatestCalibrationBySerialNumber(sd);
|
|
if (!(System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(cal?.Records?.Records?.First()?.EngineeringUnits ?? string.Empty, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0)) { return false; }
|
|
break;
|
|
case Fields.GroupName:
|
|
if (!(System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(ch.GroupName, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0)) { return false; }
|
|
break;
|
|
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
/// <summary>
|
|
/// this method will return true as long as there's one field in the channel that contains the searchterm
|
|
/// </summary>
|
|
/// <param name="ch"></param>
|
|
/// <returns></returns>
|
|
private bool ChannelSearch(ITestChannel ch)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(SearchTerm)) { return true; }
|
|
var fields = Enum.GetValues(typeof(Fields)).Cast<Fields>().ToArray();
|
|
foreach (var field in fields)
|
|
{
|
|
switch (field)
|
|
{
|
|
case Fields.ChannelName:
|
|
if (ch.ChannelName2.ToLower().Contains(SearchTerm)) { return true; }
|
|
break;
|
|
case Fields.DisplayName:
|
|
if (ch.ChannelDisplayName.ToLower().Contains(SearchTerm)) { return true; }
|
|
break;
|
|
case Fields.SerialNumber:
|
|
if (ch.SerialNumber.ToLower().Contains(SearchTerm)) { return true; }
|
|
break;
|
|
case Fields.SensorName:
|
|
if (ch.Description.ToLower().Contains(SearchTerm)) { return true; }
|
|
break;
|
|
case Fields.DASSerialNumber:
|
|
if (ch.HardwareChannelName.ToLower().Contains(SearchTerm)) { return true; }
|
|
break;
|
|
case Fields.SampleRate:
|
|
{
|
|
if (ch.SampleRateHz.ToString().Contains(SearchTerm)) { return true; }
|
|
if (ch.SampleRateHz.ToString("N").Contains(SearchTerm)) { return true; }
|
|
}
|
|
break;
|
|
case Fields.ISOCode:
|
|
if (ch.IsoCode.ToLower().Contains(SearchTerm)) { return true; }
|
|
break;
|
|
case Fields.DisplayUnits:
|
|
if (ch.Eu.ToLower().Contains(SearchTerm)) { return true; }
|
|
break;
|
|
case Fields.GroupName:
|
|
if (ch.ChannelGroupName.ToLower().Contains(SearchTerm)) { return true; }
|
|
break;
|
|
case Fields.ROIIncludes:
|
|
//I'm not sure it makes sense to search for this field, so just ignore it
|
|
break;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
/// <summary>
|
|
/// this method will return true as long as there's one field in the channel that contains the searchterm
|
|
/// </summary>
|
|
/// <param name="ch"></param>
|
|
/// <returns></returns>
|
|
private bool ChannelSearch(IGroupChannel ch)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(SearchTerm)) { return true; }
|
|
var fields = Enum.GetValues(typeof(Fields)).Cast<Fields>().ToArray();
|
|
var sd = DTS.SensorDB.SensorsCollection.SensorsList.GetSensorById(ch.SensorId);
|
|
var channelName = ch.GetChannelName(ISOViewMode);
|
|
foreach (var field in fields)
|
|
{
|
|
switch (field)
|
|
{
|
|
case Fields.ChannelName:
|
|
if (channelName.ToLower().Contains(SearchTerm)) { return true; }
|
|
break;
|
|
case Fields.DisplayName:
|
|
//in Filter this appears to use channelName again, this is redundant, so skip for now
|
|
break;
|
|
case Fields.SerialNumber:
|
|
if (sd.SerialNumber.ToLower().Contains(SearchTerm)) { return true; }
|
|
break;
|
|
case Fields.SensorName:
|
|
if (sd.Comment.ToLower().Contains(SearchTerm)) { return true; }
|
|
break;
|
|
case Fields.DASSerialNumber:
|
|
{
|
|
if (null == ch.HardwareChannel) { continue; }
|
|
if (null == ch.HardwareChannel.GetParentDAS()) { continue; }
|
|
if (ch.HardwareChannel.GetParentDAS().SerialNumber.ToLower().Contains(SearchTerm)) { return true; }
|
|
}
|
|
break;
|
|
case Fields.SampleRate:
|
|
{
|
|
if (ch.TestSampleRate.ToString().Contains(SearchTerm)) { return true; }
|
|
if (ch.TestSampleRate.ToString("N").Contains(SearchTerm)) { return true; }
|
|
}
|
|
break;
|
|
case Fields.ISOCode:
|
|
if (ch.IsoCode.ToLower().Contains(SearchTerm)) { return true; }
|
|
break;
|
|
case Fields.DisplayUnits:
|
|
var cal = DTS.SensorDB.SensorCalibrationList.GetLatestCalibrationBySerialNumber(sd);
|
|
if (null == cal) { continue; }
|
|
if (null == cal.Records) { continue; }
|
|
if (null == cal.Records.Records || 0 == cal.Records.Records.Length) { continue; }
|
|
if (cal.Records.Records[0].EngineeringUnits.ToLower().Contains(SearchTerm)) { return true; }
|
|
break;
|
|
case Fields.GroupName:
|
|
if (ch.GroupName.ToLower().Contains(SearchTerm)) { return true; }
|
|
break;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
private bool ChannelFilter(ITestChannel ch)
|
|
{
|
|
var fields = Enum.GetValues(typeof(Fields)).Cast<Fields>().ToArray();
|
|
foreach (var field in fields)
|
|
{
|
|
if (!_filterByField.ContainsKey(field)) { continue; }
|
|
var term = _filterByField[field];
|
|
if (string.IsNullOrWhiteSpace(term)) { continue; }
|
|
switch (field)
|
|
{
|
|
case Fields.ChannelName:
|
|
if (!(System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(ch.ChannelName2, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0)) { return false; }
|
|
break;
|
|
case Fields.DisplayName:
|
|
if (!(System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(ch.ChannelDisplayName, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0)) { return false; }
|
|
break;
|
|
case Fields.SerialNumber:
|
|
if (!(System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(ch.SerialNumber, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0)) { return false; }
|
|
break;
|
|
case Fields.SensorName:
|
|
if (!(System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(ch.Description, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0)) { return false; }
|
|
break;
|
|
case Fields.DASSerialNumber:
|
|
if (!(System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(ch.HardwareChannelName, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0)) { return false; } //fix this
|
|
break;
|
|
case Fields.SampleRate:
|
|
if (!(System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(ch.SampleRateHz.ToString(), term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0)) { return false; }
|
|
break;
|
|
case Fields.ISOCode:
|
|
if (!(System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(ch.IsoCode, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0)) { return false; }
|
|
break;
|
|
case Fields.DisplayUnits:
|
|
if (!(System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(ch.Eu, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0)) { return false; }
|
|
break;
|
|
case Fields.GroupName:
|
|
if (!(System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(ch.ChannelGroupName, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0)) { return false; }
|
|
break;
|
|
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
public void ClearAllFilters()
|
|
{
|
|
_filterByField.Clear();
|
|
}
|
|
private bool _sortAscending { get; set; } = true;
|
|
private ChannelEnablerComparer _comparer = new ChannelEnablerComparer();
|
|
private Fields _sortField { get; set; } = Fields.GroupName;
|
|
public void Sort(object o, bool bColumnClick)
|
|
{
|
|
if (!(o is string s)) { return; }
|
|
if (s.Contains("["))
|
|
{
|
|
if (int.TryParse(s.Split("[]".ToCharArray())[1], out var sortIndex))
|
|
{
|
|
_comparer.SortFieldIndex = sortIndex;
|
|
}
|
|
s = s.Substring(0, s.IndexOf("["));
|
|
}
|
|
if (!Enum.TryParse(s, out Fields field)) { return; }
|
|
|
|
if (bColumnClick)
|
|
{
|
|
if (field != _sortField)
|
|
{
|
|
_sortField = field;
|
|
_sortAscending = true;
|
|
}
|
|
else
|
|
{
|
|
_sortAscending = !_sortAscending;
|
|
}
|
|
}
|
|
|
|
_comparer.SortAscending = _sortAscending;
|
|
_comparer.SortField = _sortField;
|
|
var channelList = ChannelList.ToList();
|
|
channelList.Sort(_comparer);
|
|
if (ChannelList.SequenceEqual(channelList) && ChannelList.Count > 1)
|
|
{
|
|
//list was already in order. flip it for the user
|
|
_sortAscending = !_sortAscending;
|
|
_comparer.SortAscending = _sortAscending;
|
|
channelList.Sort(_comparer);
|
|
}
|
|
ChannelList = new BindingList<ChannelEnabler>(channelList);
|
|
//OnPropertyChanged("Channels");
|
|
}
|
|
|
|
public void SelectAll(int roiIndex, bool selection)
|
|
{
|
|
if (roiIndex < 0 || roiIndex > RegionsOfInterest.Count - 1) { return; }
|
|
foreach (var ch in ChannelList)
|
|
{
|
|
ch.ROIIncludes[roiIndex].Checked = selection;
|
|
}
|
|
}
|
|
|
|
private void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)
|
|
{
|
|
// The NotificationRequest.Raise triggers the Invoke() method of the PopupWindowAction object to show the NotificationWindow window
|
|
// Notification object expects a NotificationContentEventArgsWithoutTitle object and a Title string.
|
|
var eventArgsWithoutTitle = new NotificationContentEventArgs(eventArgsWithTitle.Message, "",
|
|
eventArgsWithTitle.Image, string.Empty);
|
|
|
|
NotificationRequest.Raise(new Notification
|
|
{
|
|
Content = eventArgsWithoutTitle,
|
|
Title = eventArgsWithTitle.Title
|
|
});
|
|
}
|
|
|
|
private void OnBusyIndicatorNotification(bool eventArg)
|
|
{
|
|
IsBusy = eventArg;
|
|
}
|
|
|
|
#region interfaces
|
|
public void Activated()
|
|
{
|
|
|
|
}
|
|
|
|
public void Cleanup()
|
|
{
|
|
|
|
}
|
|
|
|
public Task CleanupAsync()
|
|
{
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public void Initialize()
|
|
{
|
|
|
|
}
|
|
|
|
public void Initialize(object parameter)
|
|
{
|
|
|
|
}
|
|
|
|
public void Initialize(object parameter, object model)
|
|
{
|
|
|
|
}
|
|
|
|
public Task InitializeAsync()
|
|
{
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task InitializeAsync(object parameter)
|
|
{
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
public void OnPropertyChanged(string propertyName)
|
|
{
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
}
|
|
|
|
public bool Validate(ref List<string> errors)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public void SetGroups(ITestSetup testSetup, Dictionary<string, IDASHardware> serialNumberToHardware,
|
|
IsoViewMode viewMode)
|
|
{
|
|
ISOViewMode = viewMode;
|
|
_filterByField.Clear();
|
|
var groupLookup = new Dictionary<IGroupChannel, IGroup>();
|
|
var allChannels = new List<IGroupChannel>();
|
|
if (null == AllChannels)
|
|
{
|
|
AllChannels = new ObservableCollection<GroupChannel>();
|
|
}
|
|
bool bHasPhantomDASAssignment = false;
|
|
foreach (var group in testSetup.Groups)
|
|
{
|
|
var channels = testSetup.ChannelsForGroup[group];
|
|
allChannels.AddRange(channels);
|
|
foreach (var ch in channels)
|
|
{
|
|
groupLookup[ch] = group;
|
|
if (ch.DASId > 0)
|
|
{
|
|
if (ch.DASChannelIndex < 0)
|
|
{
|
|
bHasPhantomDASAssignment = true;
|
|
continue;
|
|
}
|
|
var serialNumber = string.Empty;
|
|
foreach (var h in serialNumberToHardware)
|
|
{
|
|
if (h.Value.DASId == ch.DASId)
|
|
{
|
|
serialNumber = h.Key;
|
|
break;
|
|
}
|
|
}
|
|
if (!string.IsNullOrWhiteSpace(serialNumber))
|
|
{
|
|
ch.TestSampleRate = testSetup.DASSampleRateList[serialNumber];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ch.TestSampleRate = 0;
|
|
}
|
|
}
|
|
}
|
|
if (bHasPhantomDASAssignment)
|
|
{
|
|
_eventAggregator.GetEvent<PageErrorEvent>().Publish(new PageErrorArg(new[] { StringResources.PhantomDASChannelAssignment }, null));
|
|
}
|
|
allChannels.Sort((a, b) => a.TestSetupOrder.CompareTo(b.TestSetupOrder));
|
|
ProcessChannels(allChannels.ToArray(), serialNumberToHardware, testSetup.Groups.ToArray(), groupLookup);
|
|
ResetDataView();
|
|
}
|
|
|
|
#endregion
|
|
#endregion
|
|
|
|
}
|
|
|
|
public sealed class ChannelEnabler : INotifyPropertyChanged
|
|
{
|
|
public ChannelEnabler()
|
|
{
|
|
ROIIncludes = new BindingList<State>();
|
|
ROIIncludes.ListChanged += RoiIncludesOnListChanged;
|
|
}
|
|
|
|
public int LastIndexChanged { get; set; }
|
|
|
|
private void RoiIncludesOnListChanged(object sender, ListChangedEventArgs listChangedEventArgs)
|
|
{
|
|
LastIndexChanged = listChangedEventArgs.NewIndex;
|
|
OnPropertyChanged("LastIndexChanged");
|
|
//OnPropertyChanged("ROIIncludes"/* + listChangedEventArgs.NewIndex.ToString()*/);
|
|
}
|
|
|
|
public string GetChannelName(IsoViewMode isoViewMode)
|
|
{
|
|
switch (isoViewMode)
|
|
{
|
|
case IsoViewMode.ISOOnly: return !string.IsNullOrWhiteSpace(ISOChannelName) ? ISOChannelName : SerialNumber;
|
|
case IsoViewMode.ChannelNameOnly:
|
|
case IsoViewMode.UserCodeOnly: return !string.IsNullOrWhiteSpace(UserChannelName) ? UserChannelName : SerialNumber;
|
|
case IsoViewMode.ISOAndUserCode:
|
|
default:
|
|
if (string.IsNullOrWhiteSpace(ISOChannelName))
|
|
{
|
|
return UserChannelName;
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(UserChannelName))
|
|
{
|
|
return ISOChannelName;
|
|
}
|
|
if (string.IsNullOrWhiteSpace(ISOChannelName) && string.IsNullOrWhiteSpace(UserChannelName))
|
|
{
|
|
return SerialNumber;
|
|
}
|
|
return $"{UserChannelName}\\{ISOChannelName}";
|
|
}
|
|
}
|
|
|
|
public BindingList<State> ROIIncludes { get; private set; }
|
|
|
|
public string UserCode { get; set; }
|
|
public string UserChannelName { get; set; }
|
|
public string ChannelName => UserChannelName;
|
|
public string GuidString { get; set; }
|
|
public long ChannelId { get; set; }
|
|
public string ISOCode { get; set; }
|
|
public string ISOChannelName { get; set; }
|
|
|
|
public string Hardware { get; set; }
|
|
public string SerialNumber { get; set; }
|
|
|
|
public string SensorName { get; set; }
|
|
|
|
public string DASSerialNumber { get; set; }
|
|
|
|
public string SampleRate { get; set; }
|
|
|
|
public string Code { get; set; }
|
|
public string DisplayUnits { get; set; }
|
|
public string GroupName { get; set; }
|
|
internal string Descriptor { get; set; }
|
|
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
public void OnPropertyChanged(string propertyName)
|
|
{
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
}
|
|
}
|
|
|
|
sealed class ChannelEnablerComparer : IComparer<ChannelEnabler>
|
|
{
|
|
public RegionOfInterestChannelsViewModel.Fields SortField { get; set; }
|
|
public bool SortAscending { get; set; }
|
|
public int SortFieldIndex { get; set; } = -1;
|
|
public int Compare(ChannelEnabler left, ChannelEnabler right)
|
|
{
|
|
if (left == right)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
var a = left; var b = right;
|
|
if (!SortAscending) { a = right; b = left; }
|
|
if (null == a)
|
|
{
|
|
return -1;
|
|
}
|
|
if (null == b)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
var aValue = a.GetType().GetProperty(SortField.ToString())?.GetValue(a, null);
|
|
var bValue = b.GetType().GetProperty(SortField.ToString())?.GetValue(b, null);
|
|
|
|
if (aValue is System.Collections.IList aList && SortFieldIndex >= 0 && SortFieldIndex < aList.Count)
|
|
{
|
|
aValue = aList[SortFieldIndex];
|
|
}
|
|
if (bValue is System.Collections.IList bList && SortFieldIndex >= 0 && SortFieldIndex < bList.Count)
|
|
{
|
|
bValue = bList[SortFieldIndex];
|
|
}
|
|
|
|
return string.Compare(aValue?.ToString(),
|
|
bValue?.ToString(),
|
|
StringComparison.InvariantCultureIgnoreCase);
|
|
}
|
|
}
|
|
|
|
public sealed class State : INotifyPropertyChanged
|
|
{
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
private bool _checked;
|
|
public bool Checked
|
|
{
|
|
get => _checked;
|
|
set { _checked = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public void Toggle()
|
|
{
|
|
Checked = !Checked;
|
|
}
|
|
|
|
public State(bool c)
|
|
{
|
|
Checked = c;
|
|
}
|
|
|
|
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
|
{
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return Checked.ToString();
|
|
}
|
|
}
|
|
|
|
|
|
public sealed class ROIChannelEnabler : INotifyPropertyChanged
|
|
{
|
|
public ROIChannelEnabler(string suffix, string channel, bool enabled)
|
|
{
|
|
ROISuffix = suffix;
|
|
ChannelName = channel;
|
|
IsEnabled = enabled;
|
|
}
|
|
|
|
private string _roiSuffix = String.Empty;
|
|
public string ROISuffix
|
|
{
|
|
get => _roiSuffix;
|
|
set
|
|
{
|
|
_roiSuffix = value;
|
|
OnPropertyChanged("ROISuffix");
|
|
}
|
|
}
|
|
|
|
private string _channelName = String.Empty;
|
|
public string ChannelName
|
|
{
|
|
get => _channelName;
|
|
set
|
|
{
|
|
_channelName = value;
|
|
OnPropertyChanged("ChannelName");
|
|
}
|
|
}
|
|
|
|
private bool _isEnabled = false;
|
|
|
|
public bool IsEnabled
|
|
{
|
|
get => _isEnabled;
|
|
set
|
|
{
|
|
_isEnabled = value;
|
|
OnPropertyChanged("IsEnabled");
|
|
}
|
|
}
|
|
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
public void OnPropertyChanged(string propertyName)
|
|
{
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
}
|
|
}
|
|
|
|
public sealed class ColumnDescriptor
|
|
{
|
|
public string HeaderText { get; set; }
|
|
public string DisplayMember { get; set; }
|
|
public Type MemberType { get; set; }
|
|
}
|
|
}
|