using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.ComponentModel.Composition; using System.Linq; using System.Threading.Tasks; using System.Windows.Input; using DTS.Common.Classes.Groups; using DTS.Common.Enums; using DTS.Common.Enums.Sensors; using DTS.Common.Events; using DTS.Common.Events.Groups.GroupChannelList; using DTS.Common.Interface.Channels; using DTS.Common.Interface.Channels.ChannelCodes; using DTS.Common.Interface.Groups.GroupChannelList; using DTS.Common.Interface.Groups.GroupList; using DTS.Common.Interface.Sensors.SensorsList; using DTS.Common.Interface.Sensors; using DTS.Common.Interface.DataRecorders; using DTS.Common.Interface.TestSetups.TestSetupsList; using Prism.Ioc; using DTS.Common.Storage; using DTS.Common.Enums.Sensors.SensorsList; using System.Collections.Specialized; using DTS.Common.Converters; using DTS.Common.Enums.Hardware; using Prism.Events; using DTS.Common.Interactivity; using Unity; using Prism.Regions; using Prism.Commands; // ReSharper disable CheckNamespace // ReSharper disable MemberCanBePrivate.Global // ReSharper disable InconsistentNaming namespace GroupChannelList { /// /// /// this class handles GroupChannelList functionality /// [PartCreationPolicy(CreationPolicy.Shared)] public class GroupChannelListViewModel : IGroupChannelListViewModel { /// /// The GroupChannelList view /// public IGroupChannelListView View { get; set; } public IGroupChannelSettingsListView SettingsView { get; set; } private IEventAggregator _eventAggregator { get; } private IUnityContainer UnityContainer { get; } public InteractionRequest NotificationRequest { get; } public InteractionRequest ConfirmationRequest { get; } /// /// /// Occurs when a property value changes. /// public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); if (propertyName == "ChannelCount") { _eventAggregator.GetEvent() .Publish(new GroupChannelsChangedEventArgs(Group, ChannelCount)); } } #region constructors and initializers /// /// Creates a new instance of the GroupChannelListViewModel /// /// /// The logical placeholder defined within the application's UI (in the shell or within views) into which views are displayed. /// The EventAggregator which allows different components to publish/subscribe to events without being coupled to each other. /// The unityContainer. /// public GroupChannelListViewModel(IGroupChannelListView view, IGroupChannelSettingsListView settingsView, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer) { ChannelCodesFunc = new Func>(GetAllChannels); View = view; View.DataContext = this; SettingsView = settingsView; SettingsView.DataContext = this; NotificationRequest = new InteractionRequest(); ConfirmationRequest = new InteractionRequest(); _eventAggregator = eventAggregator; UnityContainer = unityContainer; _eventAggregator.GetEvent().Subscribe(OnRaiseNotification); _eventAggregator.GetEvent() .Subscribe(OnBusyIndicatorNotification, ThreadOption.PublisherThread, true); _eventAggregator.GetEvent().Subscribe(OnTextPasted); SelectedChannelItems = new ObservableCollection(); } #endregion #region Methods /// /// updates all the low g channels on the given das to the range on the channel in the parameters /// /// public void UpdateRangeLowG(IGroupChannel channelChanged) { foreach (var channel in Channels) { if (channel.Equals(channelChanged)) { continue; } if (channel.DASId != channelChanged.DASId) { continue; } if (channel.RangeModifiableSensorLowG) { channel.RangeLowG = channelChanged.RangeLowG; } } } /// /// updates all the ars channels on the given das to the range on the channel in the parameters /// /// public void UpdateRangeARS(IGroupChannel channelChanged) { foreach (var channel in Channels) { if (channel.Equals(channelChanged)) { continue; } if (channel.DASId != channelChanged.DASId) { continue; } if (channel.RangeModifiableSensorARS) { channel.Range = channelChanged.Range; } } } /// /// updates the state of all other channels on DAS with AC coupling mode enabled /// http://manuscript.dts.local/f/cases/29760/Implement-ACCoupleEnable-for-TSR-AIR /// public void UpdateACCouplingEnabled(IGroupChannel channelChanged) { foreach (var channel in Channels) { if (channel.Equals(channelChanged)) { continue; } if (channel.DASId != channelChanged.DASId) { continue; } if (channel is GroupChannel gc) { gc.ACCouplingEnabled = ((GroupChannel)channelChanged).ACCouplingEnabled; } } } private IEnumerable ParseText(string text, object tag, out bool oneColumn) { oneColumn = false; var channelDefaults = GetChannelSettingDefaults(); var list = new List(); var errors = new List(); var lines = text.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); for (var i = 0; i < lines.Length; i++) { var line = lines[i]; if (string.IsNullOrWhiteSpace(line)) { continue; } var tokens = line.Split(','); if (tokens.Length < 2) { tokens = line.Split('\t'); } if (tokens.Length < 2) { tokens = line.Split(';'); } IGroupChannel newGroupChannel = null; var groupName = string.Empty; var isoCode = string.Empty; var isoChannelName = string.Empty; var userCode = string.Empty; var userChannelName = string.Empty; var sensorRef = string.Empty; var hardwareRef = string.Empty; var groupNameValid = false; var isoCodeValid = false; var isoChannelNameValid = false; var userCodeValid = false; var userChannelNameValid = false; var tagField = Fields.GroupName; switch ((string)tag) { case "GroupName": tagField = Fields.GroupName; break; case "ISOCode": tagField = Fields.ISOCode; break; case "UserCode": tagField = Fields.UserCode; break; case "UserChannelName": case "ChannelName": tagField = Fields.UserChannelName; break; case "ISOChannelName": tagField = Fields.ISOChannelName; break; } if (tokens.Length == 1) { oneColumn = true; switch (tagField) { case Fields.GroupName: groupNameValid = true; groupName = tokens[0]; break; case Fields.UserCode: userCodeValid = true; userCode = tokens[0]; break; case Fields.UserChannelName: userChannelName = tokens[0]; userChannelNameValid = true; break; case Fields.ISOCode: isoCode = tokens[0]; isoCodeValid = true; break; case Fields.ISOChannelName: isoChannelName = tokens[0]; isoChannelNameValid = true; break; case Fields.Sensor: sensorRef = tokens[0]; break; case Fields.Hardware: hardwareRef = tokens[0]; break; } } else { var columns = GetColumns(); if (tokens.Length > columns.Length) { errors.Add(string.Format(Resources.StringResources.InvalidLine, line)); continue; } for (var idx = 0; idx < tokens.Length; idx++) { var token = tokens[idx]; var column = columns[idx]; if (tokens.Length != columns.Length) { var startIndex = columns.ToList().IndexOf(tagField); var columnIndex = startIndex + idx; if (columnIndex < columns.Length) { column = columns[columnIndex]; } else { continue; } } switch (column) { case Fields.GroupName: groupName = token; groupNameValid = true; break; case Fields.UserCode: userCode = token; userCodeValid = true; break; case Fields.UserChannelName: userChannelName = token; userChannelNameValid = true; break; case Fields.ISOCode: isoCode = token; isoCodeValid = true; break; case Fields.ISOChannelName: isoChannelName = token; isoChannelNameValid = true; break; case Fields.Sensor: sensorRef = token; break; case Fields.Hardware: hardwareRef = token; break; } } } if (UseTestSetupOrder && string.IsNullOrWhiteSpace(groupName)) { groupName = Resources.StringResources.TestChannelsGroupName; } if (UseTestSetupOrder && !string.IsNullOrWhiteSpace(groupName)) { //create group if needed var group = CreateGroupIfNeeded(groupName); newGroupChannel = new GroupChannel(true, groupName, group, channelDefaults); } else { newGroupChannel = new GroupChannel(false, Group?.DisplayName ?? "", Group, channelDefaults); } isoCode = isoCode.Trim(); if (isoCode.Length > 16) { isoCode = isoCode.Substring(0, 16); } newGroupChannel.IsoCode = isoCode; newGroupChannel.IsoChannelName = isoChannelName.Trim(); newGroupChannel.UserChannelName = userChannelName.Trim(); newGroupChannel.UserCode = userCode; newGroupChannel.GroupNameValid = groupNameValid; newGroupChannel.IsoCodeValid = isoCodeValid; newGroupChannel.IsoChannelNameValid = isoChannelNameValid; newGroupChannel.UserCodeValid = userCodeValid; newGroupChannel.UserChannelNameValid = userChannelNameValid; sensorRef = sensorRef.Trim(); hardwareRef = hardwareRef.Trim(); if (!string.IsNullOrWhiteSpace(sensorRef)) { if (_serialNumberToSensorDictionary.ContainsKey(sensorRef)) { var sd = _serialNumberToSensorDictionary[sensorRef]; newGroupChannel.SensorId = sd.DatabaseId; ((GroupChannel)newGroupChannel).SetSensorData(sd, null, true); } else { if (int.TryParse(sensorRef, out var id)) { if (_idToSensorDictionary.ContainsKey(id)) { var sd = _idToSensorDictionary[id]; newGroupChannel.SensorId = sd.DatabaseId; ((GroupChannel)newGroupChannel).SetSensorData(sd, null, true); } else { errors.Add(string.Format(Resources.StringResources.InvalidSensor, line)); //continue; } } else { errors.Add(string.Format(Resources.StringResources.InvalidSensor, line)); //continue; } } } if (!string.IsNullOrWhiteSpace(hardwareRef)) { if (_displayToHardwareChannel.ContainsKey(hardwareRef)) { newGroupChannel.SetHardwareChannel(_displayToHardwareChannel[hardwareRef]); if (TestSetup == null) { newGroupChannel.TestSampleRate = 0; } else { newGroupChannel.TestSampleRate = TestSetup.DASSampleRateList[newGroupChannel.HardwareChannel.GetParentDAS().SerialNumber]; } } } list.Add(newGroupChannel); } if (errors.Any()) { var eventAggregator = ContainerLocator.Container.Resolve(); eventAggregator.GetEvent().Publish(new PageErrorArg(errors.ToArray(), Page)); } return list.ToArray(); } public IGroup CreateGroupIfNeeded(ITestSetup testSetup, string groupName) { return GroupList.Model.Group.CreateGroupIfNeeded(testSetup, groupName); } private IGroup CreateGroupIfNeeded(string groupName) { return GroupList.Model.Group.CreateGroupIfNeeded(TestSetup, groupName); } private void OnTextPasted(ITextPastedEventArgs args) { if (args.Id != GroupChannel.PASTE_ID) { return; } var tag = args.Tag; if (!(args.Sender is IGroupChannel groupChannel)) { return; } var groupChannels = ParseText(args.Text, tag, out var oneColumn); int index = AllChannels.IndexOf((IGroupChannel)args.Sender); IGroupChannel last = null; if (AllChannels.Any()) { last = AllChannels.Last(); AllChannels.Remove(last); last.IsoChannelName = ""; last.IsoCode = ""; last.UserCode = ""; last.UserChannelName = ""; } foreach (var code in groupChannels) { if (index < AllChannels.Count && index >= 0) { var ch = AllChannels[index++]; if (ch.Group != code.Group && code.GroupNameValid) { if (UseTestSetupOrder) { var list = TestSetup.ChannelsForGroup[ch.Group].ToList(); list.Remove(ch); TestSetup.ChannelsForGroup[ch.Group] = list.ToArray(); } } ch.Copy(code); } else { index++; AllChannels.Add(code); if (UseTestSetupOrder) { var list = TestSetup.ChannelsForGroup[code.Group].ToList(); list.Add(code); TestSetup.ChannelsForGroup[code.Group] = list.ToArray(); } } } for (var i = 0; i < AllChannels.Count; i++) { if (AllChannels[i].IsBlank()) { continue; } if (UseTestSetupOrder) { AllChannels[i].TestSetupOrder = 1 + i; } else { AllChannels[i].GroupChannelOrder = 1 + i; } } if (null != last) { AllChannels.Add(last); } Filter(SearchTerm); _eventAggregator.GetEvent() .Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page)); OnPropertyChanged("ChannelCount"); } public void DoSensorAssignment(IGroupChannel groupChannel, IDragAndDropItem[] sensors) { var index = Channels.IndexOf(groupChannel); int i = 0; var defaults = GetChannelSettingDefaults(); for (i = 0; i < sensors.Length && (index + i + 1) < Channels.Count; i++) { var channel = Channels[index + i]; if (null != channel.HardwareChannel && channel.HardwareChannel.IsTSRAIR && !channel.HardwareChannel.IsStreamOut && !channel.HardwareChannel.IsUart) { //refuse assignment to a channel that has TSR AIR hardware, the sensor is hard wired to the channel [for now, may need to revisit when //or if there are external sensors] //18270 User should not be allowed to assign different sensors or hardware to TSR AIR channels //27002 (except for Stream Output) continue; } channel.SetSensor(sensors[i], defaults, ApplySensorDataToBlankChannels); channel.BorderShouldShowOutOfDate = AllowSensorPushAndPull; //36718 Handle sensors both with and without a value in the Name field if (channel.SensorData == null && channel.Sensor != null) { var dictionaryKey = GetSensorSerialNumber(channel.Sensor); if (dictionaryKey != null) { if (_serialNumberToSensorDictionary.ContainsKey(dictionaryKey)) { var sd = _serialNumberToSensorDictionary[dictionaryKey]; channel.SetSensorData(sd, null, ApplySensorDataToBlankChannels); } } } if (!_dontFilterList.Contains(channel)) { _dontFilterList.Add(channel); } if (null == channel.Group) { var group = Group; if (null == group) { group = CreateGroupIfNeeded(Resources.StringResources.TestChannelsGroupName); } channel.Group = group; channel.GroupName = group.DisplayName; if (UseTestSetupOrder) { var channels = TestSetup.ChannelsForGroup[group].ToList(); channels.Add(channel); TestSetup.ChannelsForGroup[group] = channels.ToArray(); } } MarkModified(channel, false); } if (i < sensors.Length) { var list = new List(); for (; i < sensors.Length; i++) { list.Add(sensors[i]); } AddChannels(list.ToArray()); } NotifyChannelsChanged(); } /// /// A channel's Sensor string may contain either simply the Serial Number (if there is no Name), for example SG1, /// or the Name followed by the Serial Number in parentheses, for example "strain gauge 1 (SG1)". /// /// /// private string GetSensorSerialNumber(string channelSensor) { var dictionaryKey = channelSensor; if (channelSensor != null && channelSensor.Contains('(')) { var startingCharIndex = channelSensor.IndexOf('(') + 1; var endingCharIndex = channelSensor.LastIndexOf(')') - 1; var contentsLength = (endingCharIndex - startingCharIndex) + 1; if (contentsLength > 0) { var contents = channelSensor.Substring(startingCharIndex, contentsLength); if (!string.IsNullOrWhiteSpace(contents)) { //There is a non-blank string in the parens, because the sensor has both a name and a serial number dictionaryKey = contents; } } } return dictionaryKey; } public void DoHardwareAssignment(IGroupChannel groupChannel, IHardwareChannel[] hardwareChannels) { var index = Channels.IndexOf(groupChannel); int i = 0; for (i = 0; i < hardwareChannels.Length && (index + i + 1) < Channels.Count; i++) { var channel = Channels[index + i]; if (null != channel.HardwareChannel && channel.HardwareChannel.IsTSRAIR) { //if there's a TSR AIR channel on this channel already, there's no changing hardware or sensor ... //18270 User should not be allowed to assign different sensors or hardware to TSR AIR channels continue; } if (hardwareChannels[i].GetParentDAS().IsTSRAIR()) { if (!channel.IsBlank() && !channel.IsStreamOut && !channel.IsUart) { //refuse to set if a TSRAir channel is dragged to a non blank, non streamout channel ... //only allow going to a blank or streamout channel continue; } } channel.SetHardwareChannel(hardwareChannels[i]); if (TestSetup == null) { channel.TestSampleRate = 0; } else { channel.TestSampleRate = TestSetup.DASSampleRateList[channel.HardwareChannel.GetParentDAS().SerialNumber]; } if (!_dontFilterList.Contains(channel)) { _dontFilterList.Add(channel); } if (null == channel.Group) { var group = Group; if (null == group) { group = CreateGroupIfNeeded(Resources.StringResources.TestChannelsGroupName); } channel.Group = group; channel.GroupName = group.DisplayName; if (UseTestSetupOrder) { var channels = TestSetup.ChannelsForGroup[group].ToList(); channels.Add(channel); TestSetup.ChannelsForGroup[group] = channels.ToArray(); } } MarkModified(channel); } if (i < hardwareChannels.Length) { var list = new List(); for (; i < hardwareChannels.Length; i++) { if (hardwareChannels[i].IsTSRAIR) { //if it's already assigned don't allow another assignment! if (AllChannels.Exists(chan => chan.HardwareChannel == hardwareChannels[i])) { continue; } } list.Add(hardwareChannels[i]); } AddChannels(list.ToArray()); } } private IChannelSetting[] GetChannelSettingDefaults() { var channelSettings = new IChannelSetting[] { }; try { channelSettings = DbOperations.GetChannelSettingDefaults(); } catch (Exception ex) { DTS.Common.Utilities.Logging.APILogger.LogException(ex); } return channelSettings; } public void Unset() { _settingsViewLoaded = false; AllChannels.Clear(); Channels.Clear(); _idToSensorDictionary.Clear(); _serialNumberToSensorDictionary.Clear(); _displayToHardwareChannel.Clear(); ClearAllFilters(); } public void ClearAllFilters() { SearchTerm = ""; BridgeFilter = PossibleFilters.All; _filterByField.Clear(); _dontFilterList.Clear(); _eventAggregator.GetEvent().Publish(new ListViewStatusArg(ListViewStatusArg.ListViewStatus.Unloaded, ListViewId)); } public void OnSetActive() { foreach (var channel in AllChannels) { if (Group != null) { channel.GroupName = Group.DisplayName; } if (!AllowSensorPushAndPull) continue; CompareAndMarkChannelParameters(channel); } OnPropertyChanged("UseTestSetupOrder"); OnPropertyChanged("ChannelCount"); OnPropertyChanged("AssignedPhysicalChannelCount"); OnPropertyChanged("AvailableChannelCount"); View?.HandleColumns(ISOViewMode); SettingsView?.SetDisplayOptions(ShowSensorChannelUserValues); SettingsView?.HandleColumns(ISOViewMode); SettingsView?.SetFilterMode(BridgeFilter); SettingsView.SetOrderMode(UseTestSetupOrder); _currentSortField = Fields.Order; _sortAscending = true; SettingsViewLoaded = false; ResetSettingChannels(); OnPropertyChanged("SelectedDeleteShouldBeEnabled"); } /// /// Check to see if any of the channel's values that can be modified /// in the Parameters step are different than the corresponding /// sensor's values in the sensor database, so that they can be /// decorated, along with the Parameters step (FB 15245) /// /// /// public bool CompareAndMarkChannelParameters(IGroupChannel ch) { var anyChanged = false; if (ch.SensorData == null || ch.SensorData.SerialNumber == SensorConstants.TEST_SPECIFIC_ANALOG_SERIAL || ch.SensorData.SerialNumber == SensorConstants.TEST_SPECIFIC_CLOCK_SERIAL || ch.SensorData.SerialNumber == SensorConstants.TEST_SPECIFIC_DIGITAL_IN_SERIAL || ch.SensorData.SerialNumber == SensorConstants.TEST_SPECIFIC_DIGITAL_OUT_SERIAL || ch.SensorData.SerialNumber == SensorConstants.TEST_SPECIFIC_SQUIB_SERIAL || ch.SensorData.SerialNumber == SensorConstants.TEST_SPECIFIC_UART_SERIAL || ch.SensorData.SerialNumber == SensorConstants.TEST_SPECIFIC_STREAM_OUT_SERIAL || ch.SensorData.SerialNumber == SensorConstants.TEST_SPECIFIC_STREAM_IN_SERIAL || ch.SensorData.SerialNumber == SensorConstants.TEST_SPECIFIC_THERMOCOUPLER) { //None of these have actual sensors that can be pulled, so there's nothing to be different from. ch.SetNotDifferent(); } else { switch (ch.SensorData.Bridge) { case SensorConstants.BridgeType.FullBridge: //(Analogs) case SensorConstants.BridgeType.HalfBridge: case SensorConstants.BridgeType.HalfBridge_SigPlus: case SensorConstants.BridgeType.QuarterBridge: case SensorConstants.BridgeType.IEPE: anyChanged = ch.SetDifferent("Range"); // anyChanged = ch.SetDifferent("CFC") || anyChanged; anyChanged = ch.SetDifferent("FilterClass") || anyChanged; anyChanged = ch.SetDifferent("Polarity") || anyChanged; anyChanged = ch.SetDifferent("ZeroMethod") || anyChanged; anyChanged = ch.SetDifferent("ZeroMethodStart") || anyChanged; anyChanged = ch.SetDifferent("ZeroMethodEnd") || anyChanged; anyChanged = ch.SetDifferent("InitialOffset") || anyChanged; break; case SensorConstants.BridgeType.SQUIB: anyChanged = ch.SetDifferent("SquibFireMode") || anyChanged; anyChanged = ch.SetDifferent("SquibDelay") || anyChanged; anyChanged = ch.SetDifferent("SquibLimitDuration") || anyChanged; anyChanged = ch.SetDifferent("SquibDuration") || anyChanged; anyChanged = ch.SetDifferent("SquibCurrent") || anyChanged; break; case SensorConstants.BridgeType.TOMDigital: anyChanged = ch.SetDifferent("DigitalOutputMode") || anyChanged; anyChanged = ch.SetDifferent("DigitalOutDelay") || anyChanged; anyChanged = ch.SetDifferent("DigitalOutLimitDuration") || anyChanged; anyChanged = ch.SetDifferent("DigitalOutDuration") || anyChanged; break; case SensorConstants.BridgeType.DigitalInput: anyChanged = ch.SetDifferent("DigitalInputMode") || anyChanged; anyChanged = ch.SetDifferent("DefaultValue") || anyChanged; anyChanged = ch.SetDifferent("ActiveValue") || anyChanged; break; case SensorConstants.BridgeType.UART: anyChanged = ch.SetDifferent("UartBaudRate") || anyChanged; anyChanged = ch.SetDifferent("UartDataBits") || anyChanged; anyChanged = ch.SetDifferent("UartStopBits") || anyChanged; anyChanged = ch.SetDifferent("UartParity") || anyChanged; anyChanged = ch.SetDifferent("UartFlowControl") || anyChanged; anyChanged = ch.SetDifferent("UartDataFormat") || anyChanged; break; case SensorConstants.BridgeType.StreamOut: anyChanged = ch.SetDifferent("StreamOutUDPProfile") || anyChanged; anyChanged = ch.SetDifferent("StreamOutUDPAddress") || anyChanged; anyChanged = ch.SetDifferent("StreamOutUDPTimeChannelId") || anyChanged; anyChanged = ch.SetDifferent("StreamOutUDPDataChannelId") || anyChanged; anyChanged = ch.SetDifferent("StreamOutUDPTmNSConfig") || anyChanged; anyChanged = ch.SetDifferent("StreamOutIRIGTimeDataPacketIntervalMs") || anyChanged; break; case SensorConstants.BridgeType.StreamIn: anyChanged = ch.SetDifferent("StreamInUDPAddress") || anyChanged; break; case SensorConstants.BridgeType.CAN: anyChanged = ch.SetDifferent("Arb/BaseBitrate") || anyChanged; anyChanged = ch.SetDifferent("Arb/BaseSJW") || anyChanged; anyChanged = ch.SetDifferent("DataBitrate") || anyChanged; anyChanged = ch.SetDifferent("DataSJW") || anyChanged; anyChanged = ch.SetDifferent("FileType") || anyChanged; break; } } return anyChanged; } private void ResetSettingChannels() { SettingChannels.Clear(); var list = Channels.ToList(); var comparer = new GroupChannelComparer() { SortAscending = _sortAscending, SortField = _currentSortField, UseTestSetupOrder = UseTestSetupOrder }; list.Sort(comparer); var settingChannels = new ObservableCollection(); foreach (var ch in list) { if (ch.IsBlank()) { continue; } settingChannels.Add(ch); //FB 28107 For digital out when the hardware is TDAS TOM use the max value allowed 1600 if (ch.IsDigitalOut) { var hardwareType = ch.HardwareChannel?.GetParentDAS().DASTypeEnum; bool isTOM = ch.HardwareChannel?.ModuleSerialNumber.Contains("TOM") ?? false; if (hardwareType == HardwareTypes.TDAS_Pro_Rack && isTOM) { ch.DigitalOutDurationMax = DTS.Common.Constants.TDAS_TOM_DIGITAL_OUT_DURATION_MAX; } } } SettingChannels = settingChannels; if (SettingsViewLoaded) OnPropertyChanged("SettingChannels"); } /// /// indicates that the attached SettingsView has loaded /// private bool _settingsViewLoaded; public bool SettingsViewLoaded { get => _settingsViewLoaded; set { _settingsViewLoaded = value; if (value) { OnPropertyChanged("SettingChannels"); } } } /// /// indicates that the SettingChannel UI elements were created /// private bool _settingChannelsLoaded; public bool SettingChannelsLoaded { get => _settingChannelsLoaded; set { _settingChannelsLoaded = value; if (value) { //FB14148 : mark App Available when the Channel UI elements have been created _eventAggregator.GetEvent().Publish(AppStatusArg.Available); } else { //FB14148 : mark App Busy while the Channel UI elements are being created _eventAggregator.GetEvent().Publish(AppStatusArg.Busy); } } } public IDictionary PopulateChannels(object page, IDictionary sensorLookup, IDictionary hardwareLookup, IChannelSetting[] channelDefaults, bool allowChannelDeletionByNonAdminUser = true, bool userIsAdmin = true, bool allowSensorPushAndPull = false, bool keepExistingChannels = false, bool allowChannelDeletionFromFixedGroup = false) { Page = page; //17930 New channels get wiped out in Edit Group //keep a record of channels as they were before they get wiped out var existingChannels = new List(); if (keepExistingChannels) { foreach (var existingChannel in AllChannels) { if (existingChannel.IsBlank()) { continue; } existingChannels.Add(existingChannel); } } AllChannels.Clear(); Channels.Clear(); _idToSensorDictionary = sensorLookup; _displayToHardwareChannel.Clear(); _serialNumberToSensorDictionary.Clear(); using (var eSensor = _idToSensorDictionary.GetEnumerator()) { while (eSensor.MoveNext()) { _serialNumberToSensorDictionary[eSensor.Current.Value.SerialNumber] = eSensor.Current.Value; } } var includedHardwareIds = new List(); if (TestSetup != null) { includedHardwareIds = TestSetup.GetAllIncludedHardware().ToList(); } if (Group != null) { includedHardwareIds = Group.IncludedHardware.ToList(); ; } var embeddedSensorChannels = new Dictionary(); var hardware = hardwareLookup.Values.ToArray(); var list = new List(); using (var eHardware = hardwareLookup.GetEnumerator()) { while (eHardware.MoveNext()) { var channels = eHardware.Current.Value.GetIHardwareChannels(); foreach (var channel in channels) { _displayToHardwareChannel[channel.ToString(hardware)] = channel; } } } //Always enable the Delete button in Groups tile, but in Test Setups tile only if setting is True or user is Admin. AllowChannelDeletionByNonAdminUser = allowChannelDeletionByNonAdminUser; //FB 18618 AllowChannelDeletionFromFixedGroup = allowChannelDeletionFromFixedGroup; UserIsAdmin = userIsAdmin; if (null != Group) { var existingTSRAIRList = new List(); IGroupChannel[] channels = null; //if we are keeping existing channels there's no need to call Group.GetAllChannels, since we already have all the channels //we want to know about if (keepExistingChannels) { channels = existingChannels.ToArray(); } else { channels = Group.GetAllChannels(null == Group, sensorLookup, hardwareLookup, channelDefaults, allowSensorPushAndPull); } foreach (var channel in channels.Where(chn => !chn.IsClock)) { if ((channel.HardwareChannel == null) || //A regular channel without hardware assigned (channel.HardwareChannel?.IsTSRAIR ?? false) || //A regular channel with hardware assigned includedHardwareIds.Contains(channel.DASId)) //A channel for an embedded sensor in an TSR-AIR { channel.RemoveSensorVisibility = ((channel.HardwareChannel?.IsTSRAIR ?? false) || (channel.HardwareChannel?.IsSLICETC ?? false)) ? System.Windows.Visibility.Hidden : System.Windows.Visibility.Visible; list.Add(channel); if (channel.HardwareChannel != null && !existingTSRAIRList.Contains(channel.HardwareChannel.GetParentDAS().SerialNumber)) { existingTSRAIRList.Add(channel.HardwareChannel.GetParentDAS().SerialNumber); } } } foreach (var pair in embeddedSensorChannels) { //Only add embedded sensors from an TSR-AIR if that unit isn't already in the Group if (!existingTSRAIRList.Contains(pair.Value.HardwareChannel.GetParentDAS().SerialNumber)) { if (pair.Value.IsBlank() || pair.Value.IsClock) { //remove any blank channels or clock channels from group continue; } list.Add(pair.Value); } } } if (null != TestSetup) { foreach (var group in TestSetup.Groups) { var allChannels = TestSetup.ChannelsForGroup[group]; foreach (var channel in allChannels) { if (channel.IsBlank() || channel.IsClock) { //remove any blank channels or clock channels from group continue; } //FB 18618 Should not allow deleting the fixed group in test setup if (!AllowChannelDeletionFromFixedGroup) { if (group.StaticGroupId != null) { //It's in a fixed group, disable the delete button channel.DeleteShouldBeEnabled = false; } } else { //Enable the Delete button for all channels in Test Setups if AllowChannelDeletionByNonAdminUser setting is True or user is Admin. channel.DeleteShouldBeEnabled = UserIsAdmin || AllowChannelDeletionByNonAdminUser; } channel.RemoveSensorVisibility = ((channel.HardwareChannel?.IsTSRAIR ?? false) || (channel.HardwareChannel?.IsSLICETC ?? false)) ? System.Windows.Visibility.Hidden : System.Windows.Visibility.Visible; list.Add(channel); } } } list.Sort(); for (var i = 0; i < list.Count; i++) { if (UseTestSetupOrder) { list[i].TestSetupOrder = 1 + i; } else { list[i].GroupChannelOrder = 1 + i; } list[i].CanMoveDown = true; list[i].CanMoveUp = true; } AllChannels.AddRange(list.ToArray()); var ch = new GroupChannel(null == Group, Group?.DisplayName ?? "", Group, channelDefaults, allowSensorPushAndPull); AllChannels.Add(ch); OnPropertyChanged("ChannelCount"); Filter(SearchTerm, false); if (null != TestSetup) { return TestSetup.ChannelsForGroup; } var lookup = new Dictionary(); lookup[Group] = AllChannels.ToArray(); return lookup; } 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 void Activated() { } /// /// Private Event handler for RaiseNotification event. /// private void OnBusyIndicatorNotification(bool eventArg) { IsBusy = eventArg; } /// /// Private Event handler for RaiseNotification event. /// 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 }); } public void ReportErrors(string[] errors) { _eventAggregator.GetEvent().Publish(new PageErrorArg(errors, Page)); } public void GroupNameChanged(IGroupChannel channel) { if (null == TestSetup) { return; } //this is slightly complicated, when the group name changes: //1) remove this channel from the channel list for the old group if (channel.Group != null && TestSetup.ChannelsForGroup[channel.Group].Contains(channel)) { var groupChannels = TestSetup.ChannelsForGroup[channel.Group].ToList(); groupChannels.Remove(channel); TestSetup.ChannelsForGroup[channel.Group] = groupChannels.ToArray(); if (!groupChannels.Any()) { //2) remove the old group if it's now empty TestSetup.RemoveGroup(channel.Group); TestSetup.ChannelsForGroup.Remove(channel.Group); } } //3) add a new group if one doesn't exist //4) add the channel to the group var group = CreateGroupIfNeeded(channel.GroupName); channel.Group = group; var list = TestSetup.ChannelsForGroup[group].ToList(); if (!list.Contains(channel)) { list.Add(channel); TestSetup.ChannelsForGroup[group] = list.ToArray(); } //_eventAggregator.GetEvent() // .Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page)); } public void MarkModified(IGroupChannel channel, bool bNotifyChanged = true) { if (Channels.ToList().Last() == channel) { if (Channels[0] != channel) { channel.CanMoveUp = true; Channels[Channels.Count - 2].CanMoveDown = true; //remember that AllChannels.Count is base 1, while index is base 0 } if (UseTestSetupOrder) { channel.TestSetupOrder = AllChannels.Count; } else { channel.GroupChannelOrder = AllChannels.Count; } if (null == channel.Group) { var group = Group; if (null == group) { group = CreateGroupIfNeeded(Resources.StringResources.TestChannelsGroupName); } channel.Group = group; channel.GroupName = group.DisplayName; if (UseTestSetupOrder) { var list = TestSetup.ChannelsForGroup[channel.Group].ToList(); if (!list.Contains(channel)) { list.Add(channel); TestSetup.ChannelsForGroup[channel.Group] = list.ToArray(); } } } var defaults = GetChannelSettingDefaults(); var newChannel = new GroupChannel(null == Group, Group?.DisplayName ?? "", Group, defaults); AllChannels.Add(newChannel); Channels.Add(newChannel); DetermineButtonState(); //OnPropertyChanged("Channels"); } if (bNotifyChanged) { NotifyChannelsChanged(); } } public void NotifyChannelsChanged() { _eventAggregator.GetEvent() .Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page)); _eventAggregator.GetEvent() .Publish(new GroupUpdatedEventArgs(Page, GroupUpdatedEventArgs.Status.AssignmentsMade)); OnPropertyChanged("ChannelCount"); OnPropertyChanged("AssignedPhysicalChannelCount"); } public void Clear(IGroupChannel channel) { channel.Clear(); } public void Remove(IGroupChannel channel, bool notifyChanged = true) { if (Channels.ToList().Last() == channel) { var defaults = GetChannelSettingDefaults(); Channels.Add(new GroupChannel(null == Group, Group?.DisplayName ?? "", Group, defaults)); } AllChannels.Remove(channel); Channels.Remove(channel); if (UseTestSetupOrder) { if (null != channel.Group) { var list = TestSetup.ChannelsForGroup[channel.Group].ToList(); list.Remove(channel); TestSetup.ChannelsForGroup[channel.Group] = list.ToArray(); if (!list.Any()) { TestSetup.RemoveGroup(channel.Group); } } } DetermineButtonState(); //OnPropertyChanged("Channels"); OnPropertyChanged("ChannelCount"); if (notifyChanged) { NotifyChannelsChanged(); } } private void DetermineButtonState() { if (!Channels.Any()) { return; } foreach (var channel in Channels) { channel.CanMoveDown = true; channel.CanMoveUp = true; } Channels[0].CanMoveUp = false; var bFoundBottom = false; for (var i = Channels.Count - 1; i >= 0; i--) { if (Channels[i].IsBlank()) { Channels[i].CanMoveDown = false; Channels[i].CanMoveUp = false; continue; } if (i > 0) { Channels[0].CanMoveDown = true; } Channels[i].CanMoveDown = false; bFoundBottom = true; break; } if (!bFoundBottom) { Channels[0].CanMoveDown = false; } } private void Filter(string term, bool initiatedByUser) { if (initiatedByUser) { _dontFilterList.Clear(); } SearchTerm = term; AllChannels.Sort(); List newChannels = new List(); foreach (var channel in AllChannels) { if (channel.IsBlank()) { newChannels.Add(channel); continue; } if (_dontFilterList.Contains(channel)) { newChannels.Add(channel); continue; } if (string.IsNullOrWhiteSpace(SearchTerm)) { //no filtering needed } else if (!channel.Filter(SearchTerm)) { continue; } ISensorData sensor = null; if (channel.SensorId >= 0 && _idToSensorDictionary.ContainsKey(channel.SensorId)) { sensor = _idToSensorDictionary[channel.SensorId]; } switch (BridgeFilter) { case PossibleFilters.All: break; case PossibleFilters.Analog: if (channel.IsAnalog) { break; } else { continue; } case PossibleFilters.Squib: if (!channel.IsSquib) { continue; } break; case PossibleFilters.DigitalIn: if (!channel.IsDigitalIn) { continue; } break; case PossibleFilters.DigitalOut: if (!channel.IsDigitalOut) { continue; } break; case PossibleFilters.UART: if (!channel.IsUart) { continue; } break; case PossibleFilters.StreamOut: if (!channel.IsStreamOut) { continue; } break; case PossibleFilters.StreamIn: if (!channel.IsStreamIn) { continue; } break; case PossibleFilters.CAN: if (!channel.IsCan) { continue; } break; default: throw new ArgumentOutOfRangeException(); } var filters = Enum.GetValues(typeof(Fields)).Cast().ToArray(); var passed = true; foreach (var filter in filters) { if (!passed) { break; } if (_filterByField.ContainsKey(filter)) { var fieldTerm = _filterByField[filter]; if (string.IsNullOrWhiteSpace(fieldTerm)) { continue; } switch (filter) { case Fields.GroupName: if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf( channel.GroupName, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } break; case Fields.IEPE: { var s = channel.IEPESupport; if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf( s, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.Sensor: if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf( ((GroupChannel)channel).Sensor, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } break; case Fields.Hardware: if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf( ((GroupChannel)channel).Hardware, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } break; case Fields.UserCode: if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf( channel.UserCode, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } break; case Fields.UserChannelName: if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf( channel.UserChannelName, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } break; case Fields.ISOCode: if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf( channel.IsoCode, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } break; case Fields.ISOChannelName: if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf( channel.IsoChannelName, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } break; case Fields.Range: if (BridgeFilter == PossibleFilters.Analog) { var range = channel.Range.ToString("N2"); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(range, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.Capacity: if (BridgeFilter == PossibleFilters.Analog) { var capacity = channel.Capacity.ToString("N2"); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(capacity, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.Sensitivity: if (BridgeFilter == PossibleFilters.Analog) { if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(channel.Sensitivity, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.Units: if (BridgeFilter == PossibleFilters.Analog) { if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(channel.Units, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.InitialOffset: { if (BridgeFilter == PossibleFilters.Analog) { var converter = new EnumDescriptionTypeConverter(typeof(InitialOffsetTypes)); var initialOffset = converter.ConvertToString(channel.InitialOffset.Form); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(initialOffset, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } } break; case Fields.ZeroMethod: if (BridgeFilter == PossibleFilters.Analog) { var zm = channel.ZeroMethod.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(zm, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.ZeroMethodStart: if (BridgeFilter == PossibleFilters.Analog) { var zms = channel.ZeroMethodStart.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(zms, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.ZeroMethodEnd: if (BridgeFilter == PossibleFilters.Analog) { var zme = channel.ZeroMethodEnd.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(zme, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; //FB 13120 set filter class case Fields.FilterClass: if (BridgeFilter == PossibleFilters.Analog) { var filterClass = channel.FilterClass.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(filterClass, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.Polarity: if (BridgeFilter == PossibleFilters.Analog) { if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(channel.Polarity, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.InputMode: if (BridgeFilter == PossibleFilters.DigitalIn) { var mode = channel.DigitalInputMode.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(mode, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.DefaultValue: if (BridgeFilter == PossibleFilters.DigitalIn) { if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(channel.DefaultValue, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.ActiveValue: if (BridgeFilter == PossibleFilters.DigitalIn) { var range = channel.Range.ToString("N2"); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(channel.ActiveValue, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.OutputMode: if (BridgeFilter == PossibleFilters.DigitalOut) { var mode = channel.DigitalOutputMode.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(mode, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.OutputDelay: if (BridgeFilter == PossibleFilters.DigitalOut) { var delay = channel.DigitalOutDelay.ToString("N1"); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(delay, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.OutputLimitDuration: if (BridgeFilter == PossibleFilters.DigitalOut) { var limit = channel.DigitalOutLimitDuration.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(limit, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.OutputDuration: if (BridgeFilter == PossibleFilters.DigitalOut) { var duration = channel.DigitalOutDuration.ToString("N1"); if (channel.DigitalOutLimitDuration) { if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(duration, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } } break; case Fields.SquibFireMode: if (BridgeFilter == PossibleFilters.Squib) { var mode = channel.SquibFireMode.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(mode, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.SquibDelay: if (BridgeFilter == PossibleFilters.Squib) { //FB14623 Set the default to 0.0 but since we are not setting the value to null this should always get over written. string delay = "0.0"; if (channel.SquibDelay.HasValue) delay = channel.SquibDelay.Value.ToString("N1"); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(delay, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.SquibCurrent: if (BridgeFilter == PossibleFilters.Squib) { var current = channel.SquibCurrent.ToString("N1"); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(current, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.SquibLimitDuration: if (BridgeFilter == PossibleFilters.Squib) { var limit = channel.SquibLimitDuration.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(limit, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.SquibDuration: if (BridgeFilter == PossibleFilters.Squib) { var duration = channel.SquibDuration.ToString("N1"); if (channel.SquibLimitDuration) { if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(duration, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } } break; //18363 UART-settings-as-channels case Fields.UartBaudRate: if (BridgeFilter == PossibleFilters.UART) { var baudrate = channel.UartBaudRate.ToString("N0"); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(baudrate, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.UartDataBits: if (BridgeFilter == PossibleFilters.UART) { var databits = channel.UartDataBits.ToString("N0"); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(databits, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.UartStopBits: if (BridgeFilter == PossibleFilters.UART) { var stopbits = channel.UartStopBits.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(stopbits, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.UartParity: if (BridgeFilter == PossibleFilters.UART) { var parity = channel.UartParity.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(parity, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.UartFlowControl: if (BridgeFilter == PossibleFilters.UART) { var flowcontrol = channel.UartFlowControl.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(flowcontrol, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.UartDataFormat: if (BridgeFilter == PossibleFilters.UART) { var dataformat = channel.UartDataFormat.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(dataformat, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.StreamInUDPAddress: if (BridgeFilter == PossibleFilters.StreamIn) { var address = channel.StreamInUDPAddress.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(address, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.StreamOutUDPProfile: if (BridgeFilter == PossibleFilters.StreamOut) { var profile = channel.StreamOutUDPProfile.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(profile, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.StreamOutUDPAddress: if (BridgeFilter == PossibleFilters.StreamOut) { var address = channel.StreamOutUDPAddress.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(address, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.StreamOutUDPTimeChannelId: if (BridgeFilter == PossibleFilters.StreamOut) { var chid = channel.StreamOutUDPTimeChannelId.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(chid, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.StreamOutUDPDataChannelId: if (BridgeFilter == PossibleFilters.StreamOut) { var chid = channel.StreamOutUDPDataChannelId.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(chid, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.StreamOutUDPTmNSConfig: if (BridgeFilter == PossibleFilters.StreamOut) { var config = channel.StreamOutUDPTmNSConfig.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(config, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.StreamOutIRIGTimeDataPacketIntervalMs: if (BridgeFilter == PossibleFilters.StreamOut) { var interval = channel.StreamOutIRIGTimeDataPacketIntervalMs.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(interval, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.CanIsFD: if (BridgeFilter == PossibleFilters.CAN) { var isFD = channel.CanIsFD.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(isFD, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.CanArbBaseBitrate: if (BridgeFilter == PossibleFilters.CAN) { var arbBaseBitrate = channel.CanArbBaseBitrate.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(arbBaseBitrate, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.CanArbBaseSJW: if (BridgeFilter == PossibleFilters.CAN) { var arbBaseSJW = channel.CanArbBaseSJW.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(arbBaseSJW, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.CanDataBitrate: if (BridgeFilter == PossibleFilters.CAN) { var dataBitrate = channel.CanDataBitrate.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(dataBitrate, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.CanDataSJW: if (BridgeFilter == PossibleFilters.CAN) { var dataSJW = channel.CanDataSJW.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(dataSJW, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; case Fields.CanFileType: if (BridgeFilter == PossibleFilters.CAN) { var fileType = channel.CanFileType.ToString(); if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(fileType, fieldTerm, System.Globalization.CompareOptions.OrdinalIgnoreCase) < 0) { passed = false; } } break; } } } if (!passed) { continue; } newChannels.Add(channel); } if (!Channels.SequenceEqual(newChannels)) { Channels.Clear(); Channels.AddRange(newChannels); //OnPropertyChanged("Channels"); } DetermineButtonState(); ResetSettingChannels(); } public void Filter(string term) { Filter(term, true); } //sets the persistent filter to a given type and performs the filter private IGroup _group; public IGroup Group { get => _group; set { var hash = value?.GetHashCode(); _group = value; } } private ITestSetup _testSetup; public ITestSetup TestSetup { get => _testSetup; set { _testSetup = value; OnPropertyChanged("UseTestSetupOrder"); } } public void SetFilter(PossibleFilters bridgeFilter) { BridgeFilter = bridgeFilter; Filter(SearchTerm); SettingsView?.SetFilterMode(bridgeFilter); } public bool UseTestSetupOrder => TestSetup != null; /// /// whether to show or hide the dallas id column /// public bool ShowDallasIdColumn { get; set; } = false; public bool CanMoveSelectedUp => SelectedChannelItems.Count > 0 && SelectedChannelItems.All(ch => ch.CanMoveUp); public bool CanMoveSelectedDown => SelectedChannelItems.Count > 0 && SelectedChannelItems.All(ch => ch.CanMoveDown); public bool SelectedDeleteShouldBeEnabled => SelectedChannelItems.Count > 0 && (UserIsAdmin || AllowChannelDeletionByNonAdminUser); public bool SelectedDeleteShouldDisplayTooltip => !UserIsAdmin && !AllowChannelDeletionByNonAdminUser && UseTestSetupOrder; //Only display tooltip if in Edit Test Setup, not Edit Group public void MoveDown(IGroupChannel[] channels) { var list1 = channels.ToList(); list1.Sort((a, b) => Channels.IndexOf(a).CompareTo(Channels.IndexOf(b))); var index0 = Channels.IndexOf(list1[0]); for (var i = list1.Count - 1; i >= 0; i--)//start moving from the bottom-most item { var channel = list1[i]; if (channel.IsBlank()) { continue; } var index = Channels.IndexOf(channel); if (index == Channels.Count - 2) { continue; } if (list1.Contains(Channels[index0 + i + 1])) { //avoid swapping, so if the channel we are moving to is also a channel we are moving, then //we are swapping, so just ignore continue; } // FB14637: "snap" selected items together when moving Channels.Move(index, index0 + i + 1); } var list = Channels.ToList(); SetOrderAndButtonState(list.ToArray()); _eventAggregator.GetEvent() .Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page)); OnPropertyChanged("CanMoveSelectedDown"); OnPropertyChanged("CanMoveSelectedUp"); OnPropertyChanged("SelectedDeleteShouldBeEnabled"); OnPropertyChanged("SelectedDeleteShouldDisplayTooltip"); } private void SetOrderAndButtonState(IGroupChannel[] channels) { var listDisplayOrders = new List(); foreach (var channel in channels) { if (UseTestSetupOrder) { listDisplayOrders.Add(channel.TestSetupOrder); } else { listDisplayOrders.Add(channel.GroupChannelOrder); } } listDisplayOrders.Sort(); //the negative numbers are at the top now, we have to fix that ... var negatives = new List(); for (int i = listDisplayOrders.Count - 1; i >= 0; i--) { if (listDisplayOrders[i] < 1) { negatives.Add(listDisplayOrders[i]); listDisplayOrders.RemoveAt(i); } } if (negatives.Any()) { negatives.Sort(); listDisplayOrders.AddRange(negatives); } for (var i = 0; i < channels.Length; i++) { if (UseTestSetupOrder) { channels[i].TestSetupOrder = listDisplayOrders[i]; } else { channels[i].GroupChannelOrder = listDisplayOrders[i]; } } DetermineButtonState(); } public void MoveBottom(IGroupChannel[] channels) { foreach (var channel in channels) { if (channel.IsBlank()) { continue; } var index = Channels.IndexOf(channel); var bottom = -1; for (var i = Channels.Count - 1; i >= 0; i--) { if (Channels[i].IsBlank()) { continue; } bottom = i; break; } if (index == bottom) { continue; } Channels.Move(index, bottom); } var list = Channels.ToList(); SetOrderAndButtonState(list.ToArray()); _eventAggregator.GetEvent() .Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page)); OnPropertyChanged("CanMoveSelectedDown"); OnPropertyChanged("CanMoveSelectedUp"); OnPropertyChanged("SelectedDeleteShouldBeEnabled"); OnPropertyChanged("SelectedDeleteShouldDisplayTooltip"); } public void MoveUp(IGroupChannel[] channels) { var list1 = channels.ToList(); list1.Sort((a, b) => Channels.IndexOf(a).CompareTo(Channels.IndexOf(b))); var index0 = Channels.IndexOf(list1[0]); for (var i = 0; i < list1.Count; i++) { var channel = list1[i]; if (channel.IsBlank()) { continue; } var index = Channels.IndexOf(channel); if (index == 0) { continue; } if (list1.Contains(Channels[index0 + i - 1])) { //avoid swapping channels, if the channel we are moving to is //also in the list of channels to move, then we hit a swap condition, ignore it. continue; } // FB14637: "snap" selected items together when moving Channels.Move(index, index0 + i - 1); } var list = Channels.ToList(); SetOrderAndButtonState(list.ToArray()); _eventAggregator.GetEvent() .Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page)); OnPropertyChanged("CanMoveSelectedDown"); OnPropertyChanged("CanMoveSelectedUp"); OnPropertyChanged("SelectedDeleteShouldBeEnabled"); OnPropertyChanged("SelectedDeleteShouldDisplayTooltip"); } public void MoveTop(IGroupChannel[] channels) { var list1 = channels.ToList(); list1.Reverse(); foreach (var channel in list1) { if (channel.IsBlank()) { continue; } var index = Channels.IndexOf(channel); if (0 == index) { continue; } Channels.Move(index, 0); } var list = Channels.ToList(); SetOrderAndButtonState(list.ToArray()); _eventAggregator.GetEvent() .Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page)); OnPropertyChanged("CanMoveSelectedDown"); OnPropertyChanged("CanMoveSelectedUp"); OnPropertyChanged("SelectedDeleteShouldBeEnabled"); OnPropertyChanged("SelectedDeleteShouldDisplayTooltip"); } //FB 23327 Move the selected channels to the expected index public void MoveToIndex(IGroupChannel[] channels, int expectedIndex) { bool moveDown = false; var list1 = channels.ToList(); if (Channels.IndexOf(list1[0]) > expectedIndex) { list1.Reverse(); } else { moveDown = true; } foreach (var channel in list1) { if (channel.IsBlank()) { continue; } var index = Channels.IndexOf(channel); if (-1 == index) { continue; } if (expectedIndex - 1 >= Channels.Count - 1) { continue; } if (index == expectedIndex) { break; } if (moveDown) { Channels.Move(index, expectedIndex - 1); } else { Channels.Move(index, expectedIndex); } } var list = Channels.ToList(); SetOrderAndButtonState(list.ToArray()); _eventAggregator.GetEvent() .Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page)); OnPropertyChanged("CanMoveSelectedDown"); OnPropertyChanged("CanMoveSelectedUp"); OnPropertyChanged("SelectedDeleteShouldBeEnabled"); OnPropertyChanged("SelectedDeleteShouldDisplayTooltip"); } public void Filter(PossibleFilters filter) { BridgeFilter = filter; Filter(SearchTerm); } public void Filter(object tag, string term) { if (Enum.TryParse((string)tag, out Fields field)) { _filterByField[field] = term; Filter(SearchTerm, true); } } public void AddChannels(IDragAndDropItem[] sensors) { var defaults = GetChannelSettingDefaults(); var last = AllChannels.Last(); AllChannels.Remove(last); foreach (var sensor in sensors) { var group = Group; if (null == group) { group = CreateGroupIfNeeded(Resources.StringResources.TestChannelsGroupName); } IGroupChannel channel = null; if (sensor is IAnalogSensor analogSensor) { channel = new GroupChannel(UseTestSetupOrder, group.DisplayName, group, defaults) { //FB 13120 set filter class FilterClass = analogSensor.FilterClass, Range = analogSensor.Capacity, Polarity = analogSensor.Polarity ? "+" : "-", SensorId = sensor.DatabaseId, IsoCode = analogSensor.ISOCode, IsoChannelName = analogSensor.ISOChannelName, UserCode = analogSensor.UserCode, UserChannelName = analogSensor.UserChannelName, ZeroMethod = analogSensor.ZeroMethod, ZeroMethodStart = analogSensor.ZeroMethodStart, ZeroMethodEnd = analogSensor.ZeroMethodEnd, UserValue1 = analogSensor.UserValue1, UserValue2 = analogSensor.UserValue2, UserValue3 = analogSensor.UserValue3, AvailableInitialOffsets = analogSensor.InitialOffsets }; } else if (sensor is IDigitalInputSetting digitalInput) { channel = new GroupChannel(UseTestSetupOrder, group.DisplayName, group, defaults) { SensorId = sensor.DatabaseId, IsoCode = digitalInput.ISOCode, IsoChannelName = digitalInput.ISOChannelName, UserCode = digitalInput.UserCode, UserChannelName = digitalInput.UserChannelName, ActiveValue = digitalInput.ActiveValue, DefaultValue = digitalInput.DefaultValue, DigitalInputMode = digitalInput.Mode }; } else if (sensor is ISquib squib) { channel = new GroupChannel(UseTestSetupOrder, group.DisplayName, group, defaults) { SensorId = sensor.DatabaseId, IsoCode = squib.ISOCode, IsoChannelName = squib.ISOChannelName, UserCode = squib.UserCode, UserChannelName = squib.UserChannelName, SquibFireMode = squib.Mode, SquibLimitDuration = squib.LimitDuration, SquibDelay = squib.SQDelay, SquibDuration = squib.SQDuration, SquibCurrent = squib.SQCurrent }; } else if (sensor is IDigitalOutputSetting digitalOut) { channel = new GroupChannel(UseTestSetupOrder, group.DisplayName, group, defaults) { SensorId = sensor.DatabaseId, IsoCode = digitalOut.ISOCode, IsoChannelName = digitalOut.ISOChannelName, UserCode = digitalOut.UserCode, UserChannelName = digitalOut.UserChannelName, DigitalOutDelay = digitalOut.DODelay, DigitalOutDuration = digitalOut.DODuration, DigitalOutputMode = digitalOut.DOMode, DigitalOutLimitDuration = digitalOut.LimitDuration }; } else if (sensor is IUartIOSetting uart) { channel = new GroupChannel(UseTestSetupOrder, group.DisplayName, group, defaults) { SensorId = sensor.DatabaseId, IsoCode = uart.ISOCode, IsoChannelName = uart.ISOChannelName, UserCode = uart.UserCode, UserChannelName = uart.UserChannelName, UartBaudRate = uart.BaudRate, UartDataBits = uart.DataBits, UartStopBits = uart.StopBits, UartParity = uart.Parity, UartDataFormat = uart.DataFormat }; } else if (sensor is IStreamOutputSetting streamOut) { channel = new GroupChannel(UseTestSetupOrder, group.DisplayName, group, defaults) { SensorId = sensor.DatabaseId, IsoCode = streamOut.ISOCode, IsoChannelName = streamOut.ISOChannelName, UserCode = streamOut.UserCode, UserChannelName = streamOut.UserChannelName, StreamOutUDPProfile = streamOut.UDPProfile, StreamOutUDPAddress = streamOut.UDPAddress, StreamOutUDPTimeChannelId = streamOut.UDPTimeChannelId, StreamOutUDPDataChannelId = streamOut.UDPDataChannelId, StreamOutUDPTmNSConfig = streamOut.UDPTmNSConfig, StreamOutIRIGTimeDataPacketIntervalMs = streamOut.IRIGTimeDataPacketIntervalMs, StreamOutTMATSIntervalMs = streamOut.TMATSIntervalMs }; } else if (sensor is IStreamInputSetting streamIn) { channel = new GroupChannel(UseTestSetupOrder, group.DisplayName, group, defaults) { SensorId = sensor.DatabaseId, IsoCode = streamIn.ISOCode, IsoChannelName = streamIn.ISOChannelName, UserCode = streamIn.UserCode, UserChannelName = streamIn.UserChannelName, StreamInUDPAddress = streamIn.UDPAddress }; } else if (sensor is ICanIOSetting can) { channel = new GroupChannel(UseTestSetupOrder, group.DisplayName, group, defaults) { SensorId = sensor.DatabaseId, IsoCode = can.ISOCode, IsoChannelName = can.ISOChannelName, UserCode = can.UserCode, UserChannelName = can.UserChannelName, CanIsFD = can.CanIsFD, CanArbBaseBitrate = can.CanArbBaseBitrate, CanArbBaseSJW = can.CanArbBaseSJW, CanDataBitrate = can.CanDataBitrate, CanDataSJW = can.CanArbBaseSJW, CanFileType = can.CanFileType }; } if (null != channel) { channel.SetSensor(sensor, defaults, ApplySensorDataToBlankChannels); if (channel.SensorData == null) { channel.BorderShouldShowOutOfDate = AllowSensorPushAndPull; var sd = _serialNumberToSensorDictionary[sensor.SerialNumber]; channel.SetSensorData(sd, null, false); } AllChannels.Add(channel); _dontFilterList.Add(channel); if (UseTestSetupOrder) { var list = TestSetup.ChannelsForGroup[channel.Group].ToList(); if (!list.Contains(channel)) { list.Add(channel); TestSetup.ChannelsForGroup[channel.Group] = list.ToArray(); } } MarkModified(channel); } } for (int i = 0; i < AllChannels.Count; i++) { if (UseTestSetupOrder) { AllChannels[i].TestSetupOrder = 1 + i; } else { AllChannels[i].GroupChannelOrder = 1 + i; } } AllChannels.Add(last); Filter(SearchTerm, false); } /// /// sets the range of all analog sensors according to input /// /// public void SetRange(CACOption option) { if (option == CACOption.Manual) { return; }//nothing to do ... foreach (var ch in AllChannels) { if (ch.IsBlank()) { continue; } if (ch.SensorId < 1) { continue; } if (!ch.IsAnalog) { continue; } ch.SetRange(option); } Filter(SearchTerm); } public void AddChannels(IGroupChannel[] channels) { IGroupChannel last; if (AllChannels.Any()) // http://fogbugz/fogbugz/default.asp?14507 - Unhandled exception after clicking save in hardware disco { last = AllChannels.Last(); AllChannels.Remove(last); AllChannels.AddRange(channels); AllChannels.Add(last); } else { AllChannels.AddRange(channels); } if (null != TestSetup) { foreach (var ch in channels) { if (!TestSetup.ChannelsForGroup.ContainsKey(ch.Group)) { TestSetup.ChannelsForGroup[ch.Group] = new IGroupChannel[0]; } var list = TestSetup.ChannelsForGroup[ch.Group].ToList(); if (!list.Contains(ch)) { list.Add(ch); } TestSetup.ChannelsForGroup[ch.Group] = list.ToArray(); } } Filter(SearchTerm, false); } public void AddChannels(IHardwareChannel[] channels) { var defaults = GetChannelSettingDefaults(); var last = AllChannels.Last(); AllChannels.Remove(last); foreach (var hardwarechannel in channels) { var group = Group; if (null == group) { group = CreateGroupIfNeeded(Resources.StringResources.TestChannelsGroupName); } var sensorId = -1; var sensorName = ""; ISensorData sd = null; if (hardwarechannel.IsDigitalOut) { sd = DTS.SensorDB.SensorsCollection.SensorsList.GetSensorBySerialNumber( SensorConstants.TEST_SPECIFIC_DIGITAL_OUT_SERIAL); } else if (hardwarechannel.IsSquib) { sd = DTS.SensorDB.SensorsCollection.SensorsList.GetOriginalSensorBySerialNumber( SensorConstants.TEST_SPECIFIC_SQUIB_SERIAL); } else if (hardwarechannel.IsTSRAIR) { sd = hardwarechannel.IsClock ? DTS.SensorDB.SensorsCollection.SensorsList.GetOriginalSensorBySerialNumber(SensorConstants.TEST_SPECIFIC_CLOCK_SERIAL) : hardwarechannel.IsStreamOut ? DTS.SensorDB.SensorsCollection.SensorsList.GetOriginalSensorBySerialNumber(SensorConstants.TEST_SPECIFIC_STREAM_OUT_SERIAL) : hardwarechannel.IsUart ? DTS.SensorDB.SensorsCollection.SensorsList.GetOriginalSensorBySerialNumber(SensorConstants.TEST_SPECIFIC_UART_SERIAL) : DTS.SensorDB.SensorsCollection.SensorsList.GetOriginalSensorBySerialNumber(SensorConstants.TEST_SPECIFIC_ANALOG_SERIAL); } else if (hardwarechannel.IsUart) { sd = DTS.SensorDB.SensorsCollection.SensorsList.GetSensorBySerialNumber( SensorConstants.TEST_SPECIFIC_UART_SERIAL); } else if (hardwarechannel.IsStreamOut) { sd = DTS.SensorDB.SensorsCollection.SensorsList.GetSensorBySerialNumber( SensorConstants.TEST_SPECIFIC_STREAM_OUT_SERIAL); } else if (hardwarechannel.IsStreamIn) { sd = DTS.SensorDB.SensorsCollection.SensorsList.GetSensorBySerialNumber( SensorConstants.TEST_SPECIFIC_STREAM_IN_SERIAL); } else if (hardwarechannel.IsThermocoupler) { sd = DTS.SensorDB.SensorsCollection.SensorsList.GetSensorBySerialNumber( SensorConstants.TEST_SPECIFIC_THERMOCOUPLER); } else if (hardwarechannel.IsCan) { sd = DTS.SensorDB.SensorsCollection.SensorsList.GetSensorBySerialNumber( SensorConstants.TEST_SPECIFIC_CAN_SERIAL); } else if (hardwarechannel.IsAnalog) { if (CreateVoltageInputChannels) { sd = DTS.SensorDB.SensorsCollection.SensorsList.GetSensorBySerialNumber( SensorConstants.TEST_SPECIFIC_ANALOG_SERIAL, false, false); sd.Calibration.ZeroMethods = new DTS.Common.Classes.Sensors.ZeroMethods(new[] { new DTS.Common.Classes.Sensors.ZeroMethod(ZeroMethodType.None, -.05, .05), new DTS.Common.Classes.Sensors.ZeroMethod(ZeroMethodType.UsePreEventDiagnosticsZero, -.05, .05), new DTS.Common.Classes.Sensors.ZeroMethod(ZeroMethodType.AverageOverTime, -.05, .05) }); sd.Calibration.RemoveOffset = false; sd.BridgeResistance = -1; } } if (null != sd) { sensorId = sd.DatabaseId; sensorName = GroupChannel.GetString(sd, hardwarechannel); } GroupChannel channel = null; if (null != sd && sd.IsTestSpecificEmbedded) { if (hardwarechannel.IsTSRAIR) { channel = GroupChannel.CreateTSRAirChannel(hardwarechannel, group, sd, defaults); } else { channel = GroupChannel.CreateVoltageInsertionChannel(hardwarechannel, group, sd, defaults); } channel.GroupNameEditable = UseTestSetupOrder; } else if (null != sd && sd.IsTestSpecificThermo) { if (hardwarechannel.IsThermocoupler) { channel = GroupChannel.CreateSLICETCChannel(hardwarechannel, group, sd, defaults); } } else { channel = new GroupChannel(UseTestSetupOrder, group.DisplayName, group, defaults) { DASId = hardwarechannel.GetParentDAS().DASId, DASChannelIndex = hardwarechannel.ChannelNumber, Hardware = hardwarechannel.ToString(), SensorId = sensorId }; } channel.SetHardwareChannel(hardwarechannel); channel.RemoveSensorVisibility = hardwarechannel.IsTSRAIR ? System.Windows.Visibility.Hidden : System.Windows.Visibility.Visible;// channel.HardwareChannel.IsTSRAIR ? System.Windows.Visibility.Hidden : System.Windows.Visibility.Visible; if (null != sd) { channel.SetSensor(sd, true); } if (UseTestSetupOrder) { var groupChannels = TestSetup.ChannelsForGroup[channel.Group].ToList(); groupChannels.Add(channel); TestSetup.ChannelsForGroup[channel.Group] = groupChannels.ToArray(); } MarkModified(channel, false); AllChannels.Add(channel); _dontFilterList.Add(channel); if (UseTestSetupOrder) { var list = TestSetup.ChannelsForGroup[channel.Group].ToList(); if (!list.Contains(channel)) { list.Add(channel); TestSetup.ChannelsForGroup[channel.Group] = list.ToArray(); } } } for (int i = 0; i < AllChannels.Count; i++) { if (UseTestSetupOrder) { AllChannels[i].TestSetupOrder = 1 + i; } else { AllChannels[i].GroupChannelOrder = 1 + i; } } AllChannels.Add(last); Filter(SearchTerm, false); NotifyChannelsChanged(); } /// /// the code here warns the user if they are currently filtering. /// it doesn't seem necessary anymore, but I've left it in incase things change. /// public void NotifyUserIfFiltering() { //bool bFiltering = false; //using( var enumFilters = _filterByField.GetEnumerator() ) //{ // while( enumFilters.MoveNext() ) // { // if( string.IsNullOrWhiteSpace(enumFilters.Current.Value) ) { continue; } // bFiltering = true; // break; // } //} //if( !string.IsNullOrWhiteSpace(SearchTerm) ){ bFiltering = true; } //if( bFiltering ) //{ // _eventAggregator.GetEvent().Publish(new PageErrorArg(new []{ Resources.StringResources.DragAndDropFilterWarning }, Page) ); //} } private Fields[] GetColumns() { var list = new List(); if (UseTestSetupOrder) { list.Add(Fields.GroupName); } if (ShowUserCodes) { list.Add(Fields.UserCode); list.Add(Fields.UserChannelName); } if (ShowISOCodes) { list.Add(Fields.ISOCode); list.Add(Fields.ISOChannelName); } if (ChannelNamesOnly) { list.Add(Fields.UserChannelName); } list.Add(Fields.Sensor); list.Add(Fields.Hardware); return list.ToArray(); } public void SetIncludedHardware(IDASHardware[] hardwares) { _includedHardware = hardwares; OnPropertyChanged("AvailableChannelCount"); } private void SelectedChannelItemsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { OnPropertyChanged("CanMoveSelectedDown"); OnPropertyChanged("CanMoveSelectedUp"); OnPropertyChanged("SelectedDeleteShouldBeEnabled"); OnPropertyChanged("SelectedDeleteShouldDisplayTooltip"); } #endregion #region Properties /// /// whether voltage insertion channels should be created when dragging on an analog hardware channel onto /// a blank channel with no sensor set yet /// public bool CreateVoltageInputChannels { get; set; } = true; private bool _readOnlyChannelsMode = false; /// /// returns whether the user input controls in the view should be read only /// 16284 Channels table in EditTestSetup is enabled when it shouldn't be /// public bool ReadOnlyChannelsMode { get => _readOnlyChannelsMode; set { _readOnlyChannelsMode = value; OnPropertyChanged("ReadOnlyChannelsMode"); } } private bool _readOnlyParametersMode = false; public bool ReadOnlyParametersMode { get => _readOnlyParametersMode; set { _readOnlyParametersMode = value; OnPropertyChanged("ReadOnlyParametersMode"); } } /// /// describes whether the isocode should always match the filter and vice versa /// 13871 Changing ISO code of a channel in a group does not automatically change the CFC drop-down in parameters /// public bool UseISOCodeFilterMapping { get; set; } /// /// list of channels which should _NOT_ be filtered out /// 13534 Cannot assign sensors or hardware channels when the column filter is set /// new rows were being filtered out, we want to keep them at least for the operation after filtering /// private List _dontFilterList = new List(); private IDASHardware[] _includedHardware = new IDASHardware[0]; public int AvailableChannelCount { get { int count = 0; foreach (var h in _includedHardware) { var channels = h.GetIHardwareChannels(); //don't count ECM in channel count if (h.IsSLICEEthernetController) { continue; } for (var i = 0; i < channels.Length; i++) { if (h.IsTSRAIR()) { GroupChannel.GetTSRAppendString(channels[i], out var serial, out var moduleName, out var channelNumber, out var hardware); if (!HardwareConstants.HasEmbeddedChannelType(h.DASTypeEnum, moduleName)) { continue; } if (GroupChannel.ExcludeChannelFromCount(channels[i])) { continue; } } count++; if (channels[i].IsSquib) { i++;//skip next squib channel [voltage/current] } } } return count; } } public int AssignedPhysicalChannelCount { get { int count = 0; var hash = new HashSet(); foreach (var ch in AllChannels) { if (ch.IsBlank() || !ch.HardwareValid) { continue; } var key = $"{ch.DASId}_{ch.DASChannelIndex}"; if (!hash.Contains(key)) { hash.Add(key); count++; } } return count; } } public int ChannelCount => AllChannels.Count - 1; private IDictionary _idToSensorDictionary = new Dictionary(); private IDictionary _serialNumberToSensorDictionary = new Dictionary(); private IDictionary _displayToHardwareChannel = new Dictionary(); public enum Fields { GroupName, UserCode, UserChannelName, ISOCode, ISOChannelName, Sensor, Hardware, Range, Capacity, Sensitivity, Units, FilterClass, Polarity, InputMode, DefaultValue, ActiveValue, OutputMode, OutputDelay, OutputLimitDuration, OutputDuration, SquibFireMode, SquibDelay, SquibLimitDuration, SquibDuration, SquibCurrent, Order, IEPE, ZeroMethod, ZeroMethodStart, ZeroMethodEnd, InitialOffset, UartBaudRate, UartDataBits, UartStopBits, UartParity, UartFlowControl, UartDataFormat, StreamOutUDPProfile, StreamOutUDPAddress, StreamOutUDPTimeChannelId, StreamOutUDPDataChannelId, StreamOutUDPTmNSConfig, StreamOutIRIGTimeDataPacketIntervalMs, StreamInUDPAddress, //44881 CanIsFD, CanArbBaseBitrate, CanArbBaseSJW, CanDataBitrate, CanDataSJW, CanFileType } private Dictionary _filterByField = new Dictionary(); private PossibleFilters BridgeFilter { get; set; } = PossibleFilters.All; private string SearchTerm { get; set; } public object Page { get; private set; } public bool IsDirty { get; private set; } private bool _isBusy = false; 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 string ListViewId => "GroupChannelListView"; public List AllChannels { get; } = new List(); private IList GetAllChannels() { return ChannelCodes.Model.ChannelCode.ChannelCodes; } public void Sort(object columnTag, bool bUserClick) { if (!(columnTag is string sField)) { return; } if (!(Enum.TryParse(sField, out Fields field))) { return; } if (bUserClick) { if (field != _currentSortField) { _currentSortField = field; _sortAscending = true; } else { _sortAscending = !_sortAscending; } ResetSettingChannels(); } } public class GroupChannelComparer : IComparer { public Fields SortField { get; set; } public bool SortAscending { get; set; } public bool UseTestSetupOrder { get; set; } public int Compare(IGroupChannel x, IGroupChannel y) { if (x == y) { return 0; } if (null == x) { return 1; } if (null == y) { return -1; } var left = x; var right = y; if (!SortAscending) { left = y; right = x; } switch (SortField) { case Fields.GroupName: return left.GroupName.CompareTo(right.GroupName); case Fields.UserCode: return left.UserCode.CompareTo(right.UserCode); case Fields.UserChannelName: return left.UserChannelName.CompareTo(right.UserChannelName); case Fields.ISOCode: return left.IsoCode.CompareTo(right.IsoCode); case Fields.ISOChannelName: return left.IsoChannelName.CompareTo(right.IsoChannelName); case Fields.Sensor: return left.Sensor.CompareTo(right.Sensor); case Fields.Hardware: return left.Hardware.CompareTo(right.Hardware); case Fields.Range: return left.Range.CompareTo(right.Range); case Fields.Capacity: return left.Capacity.CompareTo(right.Capacity); case Fields.Sensitivity: return left.Sensitivity.CompareTo(right.Sensitivity); case Fields.Units: return left.Units.CompareTo(right.Units); case Fields.ZeroMethod: return left.ZeroMethod.CompareTo(right.ZeroMethod); //FB 13120 set filter class case Fields.FilterClass: return left.FilterClass.CompareTo(right.FilterClass); case Fields.Polarity: return left.Polarity.CompareTo(right.Polarity); case Fields.InputMode: return left.DigitalInputMode.ToString().CompareTo(right.DigitalInputMode.ToString()); case Fields.DefaultValue: return left.DefaultValue.CompareTo(right.DefaultValue); case Fields.ActiveValue: return left.ActiveValue.CompareTo(right.ActiveValue); case Fields.OutputMode: return left.DigitalOutputMode.ToString().CompareTo(right.DigitalOutputMode.ToString()); case Fields.OutputDelay: return left.DigitalOutDelay.CompareTo(right.DigitalOutDelay); case Fields.OutputLimitDuration: return left.DigitalOutDuration.CompareTo(right.DigitalOutDuration); case Fields.OutputDuration: return left.DigitalOutDuration.CompareTo(right.DigitalOutDuration); case Fields.SquibFireMode: return left.SquibFireMode.ToString().CompareTo(right.SquibFireMode); //FB14623 Not setting any null value so this should work as before. case Fields.SquibDelay: return left.SquibDelay.Value.CompareTo(right.SquibDelay.Value); case Fields.SquibCurrent: return left.SquibCurrent.CompareTo(right.SquibCurrent); case Fields.SquibLimitDuration: return left.SquibLimitDuration.CompareTo(right.SquibLimitDuration); case Fields.SquibDuration: return left.SquibDuration.CompareTo(right.SquibDuration); case Fields.IEPE: return left.IEPESupport.CompareTo(right.IEPESupport); //18363 UART-settings-as-channels case Fields.UartBaudRate: return left.UartBaudRate.CompareTo(right.UartBaudRate); case Fields.UartDataBits: return left.UartDataBits.CompareTo(right.UartDataBits); case Fields.UartStopBits: return left.UartStopBits.ToString().CompareTo(right.UartStopBits.ToString()); case Fields.UartParity: return left.UartParity.ToString().CompareTo(right.UartParity.ToString()); case Fields.UartFlowControl: return left.UartFlowControl.ToString().CompareTo(right.UartFlowControl.ToString()); case Fields.UartDataFormat: return left.UartDataFormat.ToString().CompareTo(right.UartDataFormat.ToString()); //18364 Streaming Out-settings-as-channels case Fields.StreamOutUDPProfile: return left.StreamOutUDPProfile.CompareTo(right.StreamOutUDPProfile); case Fields.StreamOutUDPAddress: return left.StreamOutUDPAddress.CompareTo(right.StreamOutUDPAddress); case Fields.StreamOutUDPTimeChannelId: return left.StreamOutUDPTimeChannelId.CompareTo(right.StreamOutUDPTimeChannelId); case Fields.StreamOutUDPDataChannelId: return left.StreamOutUDPDataChannelId.CompareTo(right.StreamOutUDPDataChannelId); case Fields.StreamOutUDPTmNSConfig: return left.StreamOutUDPTmNSConfig.CompareTo(right.StreamOutUDPTmNSConfig); case Fields.StreamOutIRIGTimeDataPacketIntervalMs: return left.StreamOutIRIGTimeDataPacketIntervalMs.CompareTo(right.StreamOutIRIGTimeDataPacketIntervalMs); //26828 Streaming In-settings-as-channels case Fields.StreamInUDPAddress: return left.StreamInUDPAddress.CompareTo(right.StreamInUDPAddress); //FB 44881 case Fields.CanIsFD: return left.CanIsFD.CompareTo(right.CanIsFD); case Fields.CanArbBaseBitrate: return left.CanArbBaseBitrate.CompareTo(right.CanArbBaseBitrate); case Fields.CanArbBaseSJW: return left.CanArbBaseSJW.CompareTo(right.CanArbBaseSJW); case Fields.CanDataBitrate: return left.CanDataBitrate.CompareTo(right.CanDataBitrate); case Fields.CanDataSJW: return left.CanDataSJW.CompareTo(right.CanDataSJW); case Fields.CanFileType: return left.CanFileType.CompareTo(right.CanFileType); case Fields.InitialOffset: { var converter = new EnumDescriptionTypeConverter(typeof(InitialOffsetTypes)); var leftIO = converter.ConvertToString(left.InitialOffset.Form); var rightIO = converter.ConvertToString(right.InitialOffset.Form); return leftIO.CompareTo(rightIO); } case Fields.Order: default: { if (UseTestSetupOrder) { return left.TestSetupOrder.CompareTo(right.TestSetupOrder); } else { return left.GroupChannelOrder.CompareTo(right.GroupChannelOrder); } } } } } private bool _sortAscending = true; private Fields _currentSortField = Fields.Order; public Func> ChannelCodesFunc { get; } public string CapacityFormat { get; set; } public ObservableCollection Channels { get; set; } = new ObservableCollection(); public ObservableCollection SettingChannels { get; set; } = new ObservableCollection(); private IsoViewMode _isoViewMode = IsoViewMode.ISOAndUserCode; public bool ApplySensorDataToBlankChannels { get; set; } public bool AllowChannelDeletionByNonAdminUser { get; set; } public bool AllowChannelDeletionFromFixedGroup { get; set; } public bool UserIsAdmin { get; set; } public bool AllowSensorPushAndPull { get; set; } public IsoViewMode ISOViewMode { get => _isoViewMode; set { _isoViewMode = value; OnPropertyChanged("ShowISOCodes"); OnPropertyChanged("ShowUserCodes"); OnPropertyChanged("ChannelNamesOnly"); OnPropertyChanged("ISOViewMode"); } } public bool ShowISOCodes => _isoViewMode == IsoViewMode.ISOOnly || _isoViewMode == IsoViewMode.ISOAndUserCode; public bool ShowUserCodes => _isoViewMode == IsoViewMode.ISOAndUserCode || _isoViewMode == IsoViewMode.UserCodeOnly; public bool ChannelNamesOnly => _isoViewMode == IsoViewMode.ChannelNameOnly; private bool _showISOStringBuilder = true; public bool ShowISOStringBuilder { get => _showISOStringBuilder; set { _showISOStringBuilder = value; OnPropertyChanged("ShowISOStringBuilder"); } } private bool _uniqueISOCodesRequired = false; public bool UniqueISOCodesRequired { get => _uniqueISOCodesRequired; set { _uniqueISOCodesRequired = value; OnPropertyChanged("UniqueISOCodesRequired"); } } private bool _showChannelCodeLookupHelper = true; public bool ShowChannelCodeLookupHelper { get => _showChannelCodeLookupHelper; set { _showChannelCodeLookupHelper = value; OnPropertyChanged("ShowChannelCodeLookupHelper"); } } private bool _showSensorChannelUserValues = false; public bool ShowSensorChannelUserValues { get => _showSensorChannelUserValues; set { _showSensorChannelUserValues = value; OnPropertyChanged("ShowSensorChannelUserValues"); } } private ObservableCollection _selectedChannelItems; public ObservableCollection SelectedChannelItems { get => _selectedChannelItems; set { if (_selectedChannelItems != null) { _selectedChannelItems.CollectionChanged -= SelectedChannelItemsOnCollectionChanged; } _selectedChannelItems = value; if (_selectedChannelItems != null) { _selectedChannelItems.CollectionChanged += SelectedChannelItemsOnCollectionChanged; } } } private int _expectedIndex = 0; public int ExpectedIndex { get => _expectedIndex; set { _expectedIndex = value; OnPropertyChanged("ExpectedIndex"); } } public int UserID { get; set; } #endregion Properties #region Commands private ICommand _moveSelectedChannelsToTopCommand; public ICommand MoveSelectedChannelsToTopCommand => _moveSelectedChannelsToTopCommand ?? (_moveSelectedChannelsToTopCommand = new DelegateCommand(MoveSelectedChannelsToTop)); private void MoveSelectedChannelsToTop() { MoveTop(SelectedChannelItems.OrderBy(ch => Channels.IndexOf(ch)).ToArray()); NotifyChannelsChanged(); } private ICommand _moveSelectedChannelsToIndexCommand; public ICommand MoveSelectedChannelsToIndexCommand => _moveSelectedChannelsToIndexCommand ?? (_moveSelectedChannelsToIndexCommand = new DelegateCommand(MoveSelectedChannelsToIndex)); private void MoveSelectedChannelsToIndex() { MoveToIndex(SelectedChannelItems.OrderBy(ch => Channels.IndexOf(ch)).ToArray(), ExpectedIndex); NotifyChannelsChanged(); } private ICommand _moveSelectedChannelsUpCommand; public ICommand MoveSelectedChannelsUpCommand => _moveSelectedChannelsUpCommand ?? (_moveSelectedChannelsUpCommand = new DelegateCommand(MoveSelectedChannelsUp)); private void MoveSelectedChannelsUp() { MoveUp(SelectedChannelItems.OrderBy(ch => Channels.IndexOf(ch)).ToArray()); NotifyChannelsChanged(); } private ICommand _moveSelectedChannelsDownCommand; public ICommand MoveSelectedChannelsDownCommand => _moveSelectedChannelsDownCommand ?? (_moveSelectedChannelsDownCommand = new DelegateCommand(MoveSelectedChannelsDown)); private void MoveSelectedChannelsDown() { MoveDown(SelectedChannelItems.OrderBy(ch => Channels.IndexOf(ch)).ToArray()); NotifyChannelsChanged(); } private ICommand _moveSelectedChannelsToBottomCommand; public ICommand MoveSelectedChannelsToBottomCommand => _moveSelectedChannelsToBottomCommand ?? (_moveSelectedChannelsToBottomCommand = new DelegateCommand(MoveSelectedChannelsToBottom)); private void MoveSelectedChannelsToBottom() { MoveBottom(SelectedChannelItems.OrderBy(ch => Channels.IndexOf(ch)).ToArray()); NotifyChannelsChanged(); } private ICommand _removeSelectedSensorsCommand; public ICommand RemoveSelectedSensorsCommand => _removeSelectedSensorsCommand ?? (_removeSelectedSensorsCommand = new DelegateCommand(RemoveSelectedSensors)); private void RemoveSelectedSensors() { foreach (var channel in SelectedChannelItems) { if (!(channel as GroupChannel).EmbeddedSensor) { Clear(channel); } } NotifyChannelsChanged(); } private ICommand _deleteSelectedChannelsCommand; public ICommand DeleteSelectedChannelsCommand => _deleteSelectedChannelsCommand ?? (_deleteSelectedChannelsCommand = new DelegateCommand(DeleteSelectedChannels)); private void DeleteSelectedChannels() { for (var i = 0; i < SelectedChannelItems.Count; i++) { var channel = SelectedChannelItems[i]; if (channel.IsBlank()) { //14546 // Cannot use delete action button in edit group/test // it's possible the channel is blank but still has an order assigned, we have to allow it to be // deleted still then ... if (UseTestSetupOrder) { if (channel.TestSetupOrder <= 0) { continue; } } else { if (channel.GroupChannelOrder <= 0) { continue; } } } Remove(channel); i--; } NotifyChannelsChanged(); } #endregion } }