using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using DTS.Common.Classes.Groups; using DTS.Common.Classes.Sensors.SensorsList; using DTS.Common.Controls; using DTS.Common.Enums; using DTS.Common.Enums.Channels; using DTS.Common.Events; using DTS.Common.Events.Groups.GroupChannelList; using DTS.Common.Interface.Channels; using DTS.Common.Interface.DataRecorders; using DTS.Common.Interface.Groups.GroupChannelList; using DTS.Common.Settings; using DTS.Common.Utils; using Prism.Ioc; using Prism.Events; // ReSharper disable CheckNamespace namespace GroupChannelList { /// /// /// Interaction logic for GroupChannelListView.xaml /// public partial class GroupChannelListView : IGroupChannelListView { /// /// 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 { if (null == DataContext) { return false; } if (DataContext is IGroupChannelListViewModel model) { return model.ReadOnlyChannelsMode; } return false; } } public GroupChannelListView() { InitializeComponent(); var eventAggregator = ContainerLocator.Container.Resolve(); eventAggregator.GetEvent().Subscribe(OnListViewEvent); } private void OnListViewEvent(ListViewStatusArg arg) { if (arg.Status != ListViewStatusArg.ListViewStatus.ScrollToBottom) { return; } if (!(DataContext is GroupChannelListViewModel model)) { return; } if (model.ListViewId != arg.Id) { return; } ChannelListListView.Items.MoveCurrentToLast(); ChannelListListView.ScrollIntoView(ChannelListListView.Items.CurrentItem); } private void Clear_Click(object sender, RoutedEventArgs e) { if (!(DataContext is GroupChannelListViewModel viewModel)) { return; } if (!(sender is Control control)) { return; } if (!(control.DataContext is IGroupChannel channel)) { return; } viewModel.Clear(channel); viewModel.NotifyChannelsChanged(); } private void Delete_Click(object sender, RoutedEventArgs e) { if (!(DataContext is GroupChannelListViewModel viewModel)) { return; } if (!(sender is Control control)) { return; } if (!(control.DataContext is IGroupChannel channel)) { return; } 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 (viewModel.UseTestSetupOrder) { if (channel.TestSetupOrder <= 0) { return; } } else { if (channel.GroupChannelOrder <= 0) { return; } } } var eventAggregator = ContainerLocator.Container.Resolve(); eventAggregator.GetEvent().Publish(new GroupChannelDeleteRequestEventArgs( viewModel.Page, channel)); } private void GridViewColumnHeaderSearchable_OnSearch(object sender, RoutedEventArgs e) { var searchTerm = (string)e.OriginalSource; var columnTag = (sender as GridViewColumnHeaderSearchable)?.Tag; var viewModel = (IGroupChannelListViewModel)DataContext; viewModel.Filter(columnTag, searchTerm); } private void TextBox_KeyDown(object sender, KeyEventArgs e) { if (!(DataContext is GroupChannelListViewModel viewModel)) { return; } if (!(sender is Control control)) { return; } if (!(control.DataContext is IGroupChannel channel)) { return; } viewModel.MarkModified(channel); } public void HandleColumns(IsoViewMode viewMode) { if (!(DataContext is IGroupChannelListViewModel vm)) { return; } var showGroups = SettingsDB.GetGlobalValueBool("ShowGroups", true); if (!vm.UseTestSetupOrder || !showGroups) { RemoveGroupColumn(); } else { AddGroupColumn(); } switch (viewMode) { case IsoViewMode.ISOOnly: RemoveUserCodeColumns(); AddIsoCodeColumns(vm.UseTestSetupOrder); break; case IsoViewMode.ISOAndUserCode: AddUserAndIsoCodeColumns(vm.UseTestSetupOrder); break; case IsoViewMode.UserCodeOnly: RemoveIsoCodeColumns(); AddUserCodeColumns(vm.UseTestSetupOrder, true); break; case IsoViewMode.ChannelNameOnly: RemoveIsoCodeColumns(); AddUserCodeColumns(vm.UseTestSetupOrder, false); break; } if (vm.UseTestSetupOrder) { ShowTestSetupOrder(true); } else { ShowTestSetupOrder(false); } if (vm.ShowDallasIdColumn) { AddDallasIdColumn(); } else { RemoveDallasIdColumn(); } } private void ShowTestSetupOrder(bool test) { if (!(ChannelListListView.View is DTS.Common.Controls.AutoSizedGridView view)) { return; } if (test) { if (view.Columns.Contains(GroupOrderColumn)) { view.Columns.Remove(GroupOrderColumn); } if (!view.Columns.Contains(TestSetupOrderColumn)) { view.Columns.Insert(0, TestSetupOrderColumn); } } else { if (view.Columns.Contains(TestSetupOrderColumn)) { view.Columns.Remove(TestSetupOrderColumn); } if (!view.Columns.Contains(GroupOrderColumn)) { view.Columns.Insert(0, GroupOrderColumn); } } } private void RemoveGroupColumn() { if (!(ChannelListListView.View is DTS.Common.Controls.AutoSizedGridView view)) { return; } if (view.Columns.Contains(GroupColumn)) { view.Columns.Remove(GroupColumn); } } private void AddDallasIdColumn() { if (!(ChannelListListView.View is AutoSizedGridView view)) { return; } if (!view.Columns.Contains(DallasIdColumn)) { var index = view.Columns.IndexOf(HardwareColumn); view.Columns.Insert(index, DallasIdColumn); } } private void RemoveDallasIdColumn() { if (!(ChannelListListView.View is AutoSizedGridView view)) { return; } if (view.Columns.Contains(DallasIdColumn)) { view.Columns.Remove(DallasIdColumn); } } private void AddGroupColumn() { if (!(ChannelListListView.View is DTS.Common.Controls.AutoSizedGridView view)) { return; } if (!view.Columns.Contains(GroupColumn)) { view.Columns.Insert(1, GroupColumn); } } private void AddUserAndIsoCodeColumns(bool usingTestSetup) { if (!(ChannelListListView.View is DTS.Common.Controls.AutoSizedGridView view)) { return; } if (!view.Columns.Contains(UserCodeColumn)) { view.Columns.Insert(usingTestSetup ? 1 : 0, UserCodeColumn); } if (!view.Columns.Contains(UserChannelNameColumn)) { view.Columns.Insert(usingTestSetup ? 2 : 1, UserChannelNameColumn); } if (!view.Columns.Contains(ISOCodeColumn)) { view.Columns.Insert(usingTestSetup ? 3 : 2, ISOCodeColumn); } if (!view.Columns.Contains(ISOChannelNameColumn)) { view.Columns.Insert(usingTestSetup ? 4 : 3, ISOChannelNameColumn); } } private void AddIsoCodeColumns(bool usingTestSetup) { if (!(ChannelListListView.View is DTS.Common.Controls.AutoSizedGridView view)) { return; } if (!view.Columns.Contains(ISOCodeColumn)) { view.Columns.Insert(usingTestSetup ? 1 : 0, ISOCodeColumn); } if (!view.Columns.Contains(ISOChannelNameColumn)) { view.Columns.Insert(usingTestSetup ? 2 : 1, ISOChannelNameColumn); } } private void RemoveIsoCodeColumns() { if (!(ChannelListListView.View is DTS.Common.Controls.AutoSizedGridView view)) { return; } if (view.Columns.Contains(ISOCodeColumn)) { view.Columns.Remove(ISOCodeColumn); } if (view.Columns.Contains(ISOChannelNameColumn)) { view.Columns.Remove(ISOChannelNameColumn); } } private void RemoveUserCodeColumns() { if (!(ChannelListListView.View is DTS.Common.Controls.AutoSizedGridView view)) { return; } if (view.Columns.Contains(UserCodeColumn)) { view.Columns.Remove(UserCodeColumn); } if (view.Columns.Contains(UserChannelNameColumn)) { view.Columns.Remove(UserChannelNameColumn); } } private void AddUserCodeColumns(bool usingTestSetup, bool addCodeColumn) { if (!(ChannelListListView.View is DTS.Common.Controls.AutoSizedGridView view)) { return; } var insertPoint = usingTestSetup ? 1 : 0; if (!view.Columns.Contains(UserCodeColumn) && addCodeColumn) { view.Columns.Insert(insertPoint, UserCodeColumn); } if (addCodeColumn) { insertPoint++; } if (!view.Columns.Contains(UserChannelNameColumn)) { view.Columns.Insert(insertPoint, UserChannelNameColumn); } } private void ChannelList_DragOver(object sender, DragEventArgs e) { if (!(DataContext is IGroupChannelListViewModel vm)) { return; } var lv = ChannelListListView; var index = GetIndex(lv); if (index < 0) { e.Effects = DragDropEffects.None; e.Handled = true; return; } if (lv.Items.Count <= index) { e.Effects = DragDropEffects.None; e.Handled = true; return; } if (!(lv.Items[index] is GroupChannel item)) { e.Effects = DragDropEffects.None; e.Handled = true; return; } if (null == e.Data) { e.Effects = DragDropEffects.None; e.Handled = true; return; } var formats = e.Data.GetFormats(); foreach (var format in formats) { switch (format) { case DragAndDropPayload.ALT_FORMAT: e.Effects = DragDropEffects.Copy; e.Handled = true; return; case DragAndDropPayload.CTRL_FORMAT: e.Effects = DragDropEffects.None; e.Handled = true; return; case DragAndDropPayload.FORMAT: e.Effects = DragDropEffects.Copy; e.Handled = true; return; case DTS.Common.Classes.Hardware.DragAndDropPayload.FORMAT: e.Effects = DragDropEffects.Copy; e.Handled = true; return; case DTS.Common.Classes.Hardware.DragAndDropPayload.CTRL_FORMAT: e.Effects = DragDropEffects.None; e.Handled = true; return; case DTS.Common.Classes.Hardware.DragAndDropPayload.ALT_FORMAT: e.Effects = DragDropEffects.None; e.Handled = true; return; default: e.Effects = DragDropEffects.None; e.Handled = true; return; } } e.Effects = DragDropEffects.None; e.Handled = true; } private static int GetIndex(ListView lv) { for (var i = 0; i < lv.Items.Count; i++) { var item = GetListViewItem(lv, i); if (null == item) { continue; } if (IsMouseOverTarget(item)) { return i; } } return -1; } private static ListViewItem GetListViewItem(ListView lv, int index) { if (lv.ItemContainerGenerator.Status != System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated) { return null; } return (ListViewItem)lv.ItemContainerGenerator.ContainerFromIndex(index); } private static bool IsMouseOverTarget(Visual target) { if (null == target) { return false; } // We need to use MouseUtilities to figure out the cursor // coordinates because, during a drag-drop operation, the WPF // mechanisms for getting the coordinates behave strangely. var bounds = VisualTreeHelper.GetDescendantBounds(target); var mousePos = MouseUtilities.GetMousePosition(target); var bContained = bounds.Contains(mousePos); return bContained; } private void ChannelList_Drop(object sender, DragEventArgs e) { if (!(DataContext is GroupChannelListViewModel vm)) { return; } var lv = ChannelListListView; var index = GetIndex(lv); if (index < 0) { e.Effects = DragDropEffects.None; e.Handled = true; return; } if (lv.Items.Count <= index) { e.Effects = DragDropEffects.None; e.Handled = true; return; } if (null == e.Data) { e.Effects = DragDropEffects.None; e.Handled = true; return; } var formats = e.Data.GetFormats(); if (((int)e.KeyStates & (int)DragDropKeyStates.AltKey) == (int)DragDropKeyStates.AltKey) { for (var i = 0; i < formats.Length; i++) { formats[i] = $"ALT_{formats[i]}"; } } else if (((int)e.KeyStates & (int)DragDropKeyStates.ControlKey) == (int)DragDropKeyStates.ControlKey) { for (var i = 0; i < formats.Length; i++) { formats[i] = $"CTRL_{formats[i]}"; } } foreach (var format in formats) { switch (format) { case DragAndDropPayload.FORMAT: //insert sensors on the channels in question vm.DoSensorAssignment((IGroupChannel)ChannelListListView.Items[index], ((DragAndDropPayload)e.Data.GetData(format)).Items); e.Handled = true; break; case DTS.Common.Classes.Hardware.DragAndDropPayload.FORMAT: //insert hardware assignments at the channel in question vm.DoHardwareAssignment((IGroupChannel)ChannelListListView.Items[index], (IHardwareChannel[])e.Data.GetData(format)); e.Handled = true; break; case DragAndDropPayload.ALT_FORMAT: case DragAndDropPayload.CTRL_FORMAT: case DTS.Common.Classes.Hardware.DragAndDropPayload.CTRL_FORMAT: case DTS.Common.Classes.Hardware.DragAndDropPayload.ALT_FORMAT: default: e.Effects = DragDropEffects.None; e.Handled = true; return; } } CheckDragAndDropFilterWarning(); } private void CheckDragAndDropFilterWarning() { if (!(DataContext is GroupChannelListViewModel viewModel)) { return; } viewModel.NotifyUserIfFiltering(); } private void TextBox_DragOver(object sender, DragEventArgs e) { if (null == e.Data) { e.Effects = DragDropEffects.None; e.Handled = true; return; } var formats = e.Data.GetFormats(); if (((int)e.KeyStates & (int)DragDropKeyStates.AltKey) == (int)DragDropKeyStates.AltKey) { for (var i = 0; i < formats.Length; i++) { formats[i] = $"ALT_{formats[i]}"; } } else if (((int)e.KeyStates & (int)DragDropKeyStates.ControlKey) == (int)DragDropKeyStates.ControlKey) { for (var i = 0; i < formats.Length; i++) { formats[i] = $"CTRL_{formats[i]}"; } } foreach (var format in formats) { switch (format) { case DragAndDropPayload.ALT_FORMAT: e.Effects = DragDropEffects.Copy; e.Handled = true; break; case DragAndDropPayload.CTRL_FORMAT: e.Effects = DragDropEffects.None; e.Handled = true; break; case DragAndDropPayload.FORMAT: //insert sensors on the channels in question e.Handled = true; break; case DTS.Common.Classes.Hardware.DragAndDropPayload.FORMAT: //insert hardware assignments at the channel in question //DoHardwareAssignment(index, e.Data.GetData(format) as IHardwareChannel[]); e.Handled = true; break; case DTS.Common.Classes.Hardware.DragAndDropPayload.CTRL_FORMAT: e.Effects = DragDropEffects.None; e.Handled = true; break; case DTS.Common.Classes.Hardware.DragAndDropPayload.ALT_FORMAT: e.Effects = DragDropEffects.None; e.Handled = true; break; default: e.Effects = DragDropEffects.None; e.Handled = true; return; } } } private void TextBox_Drop(object sender, DragEventArgs e) { if (null == e.Data) { e.Effects = DragDropEffects.None; e.Handled = true; return; } IGroupChannel groupChannel = null; if (sender is Control control) { groupChannel = (IGroupChannel)control.DataContext; } else if (sender is TextBlock textBlock) { groupChannel = (IGroupChannel)textBlock.DataContext; } else { e.Effects = DragDropEffects.None; e.Handled = false; return; } if (!(DataContext is GroupChannelListViewModel vm)) { e.Effects = DragDropEffects.None; e.Handled = true; return; } if (null == groupChannel) { e.Effects = DragDropEffects.None; e.Handled = true; return; } var formats = e.Data.GetFormats(); if (((int)e.KeyStates & (int)DragDropKeyStates.AltKey) == (int)DragDropKeyStates.AltKey) { for (var i = 0; i < formats.Length; i++) { formats[i] = $"ALT_{formats[i]}"; } } else if (((int)e.KeyStates & (int)DragDropKeyStates.ControlKey) == (int)DragDropKeyStates.ControlKey) { for (var i = 0; i < formats.Length; i++) { formats[i] = $"CTRL_{formats[i]}"; } } foreach (var format in formats) { switch (format) { case DragAndDropPayload.ALT_FORMAT: e.Effects = DragDropEffects.Copy; e.Handled = true; break; case DragAndDropPayload.CTRL_FORMAT: e.Effects = DragDropEffects.None; e.Handled = true; break; case DragAndDropPayload.FORMAT: //insert sensors on the channels in question var payload = (DragAndDropPayload)e.Data.GetData(format); vm.DoSensorAssignment(groupChannel, payload.Items); e.Handled = true; break; case DTS.Common.Classes.Hardware.DragAndDropPayload.FORMAT: //insert hardware assignments at the channel in question vm.DoHardwareAssignment(groupChannel, e.Data.GetData(format) as IHardwareChannel[]); e.Handled = true; break; case DTS.Common.Classes.Hardware.DragAndDropPayload.CTRL_FORMAT: e.Effects = DragDropEffects.None; e.Handled = true; break; case DTS.Common.Classes.Hardware.DragAndDropPayload.ALT_FORMAT: e.Effects = DragDropEffects.None; e.Handled = true; break; default: e.Effects = DragDropEffects.None; e.Handled = true; return; } } CheckDragAndDropFilterWarning(); } private void MoveBottom_Click(object sender, RoutedEventArgs e) { if (!(sender is Control control)) { return; } if (!(DataContext is IGroupChannelListViewModel vm)) { return; } if (!(control.DataContext is IGroupChannel channel)) { return; } var items = ChannelListListView.SelectedItems; if (items.Count > 1 && items.Contains(channel)) { IGroupChannel[] groupChannels = GetSelectedChannelsOrdered(); vm.MoveBottom(groupChannels); } else { vm.MoveBottom(new[] { channel }); } } private void MoveDown_Click(object sender, RoutedEventArgs e) { if (!(sender is Control control)) { return; } if (!(DataContext is IGroupChannelListViewModel vm)) { return; } if (!(control.DataContext is IGroupChannel channel)) { return; } var items = ChannelListListView.SelectedItems; if (items.Count > 1 && items.Contains(channel)) { IGroupChannel[] groupChannels = GetSelectedChannelsOrdered(); vm.MoveDown(groupChannels); } else { vm.MoveDown(new[] { channel }); } } private void MoveUp_Click(object sender, RoutedEventArgs e) { if (!(sender is Control control)) { return; } if (!(DataContext is IGroupChannelListViewModel vm)) { return; } if (!(control.DataContext is IGroupChannel channel)) { return; } var items = ChannelListListView.SelectedItems; if (items.Count > 1 && items.Contains(channel)) { IGroupChannel[] groupChannels = GetSelectedChannelsOrdered(); vm.MoveUp(groupChannels); } else { vm.MoveUp(new[] { channel }); } } private IGroupChannel[] GetSelectedChannelsOrdered() { var list = new List(); foreach (var item in ChannelListListView.SelectedItems) { if (item is IGroupChannel channel) { list.Add(channel); } } list.Sort((a, b) => { return ChannelListListView.Items.IndexOf(a).CompareTo(ChannelListListView.Items.IndexOf(b)); }); return list.ToArray(); } private void MoveTop_Click(object sender, RoutedEventArgs e) { if (!(sender is Control control)) { return; } if (!(DataContext is IGroupChannelListViewModel vm)) { return; } if (!(control.DataContext is IGroupChannel channel)) { return; } var items = ChannelListListView.SelectedItems; if (items.Count > 1 && items.Contains(channel)) { IGroupChannel[] groupChannels = GetSelectedChannelsOrdered(); vm.MoveTop(groupChannels); } else { vm.MoveTop(new[] { channel }); } } private void ChannelCodeBuilder_OnChannelCodeSelected(object sender, string code, string name, ChannelEnumsAndConstants.ChannelCodeType codeType) { if (!(DataContext is GroupChannelListViewModel viewModel)) { return; } if (!(sender is Control control)) { return; } if (!(control.DataContext is IGroupChannel channel)) { return; } if (codeType == ChannelEnumsAndConstants.ChannelCodeType.ISO) { channel.IsoCode = code; if (string.IsNullOrWhiteSpace(channel.IsoChannelName)) { channel.IsoChannelName = name; } } else { channel.UserCode = code; if (string.IsNullOrWhiteSpace(channel.UserChannelName)) { channel.UserChannelName = name; } } viewModel.MarkModified(channel); } /// /// Sets channel code/name when the user clicks on a selection from the popup window /// 17565 - Predictive text on "ISO channel name" column when in test set up / groups to make /// (); foreach (var item in ChannelListListView.SelectedItems) { if (!(item is IGroupChannel groupChannel)) { continue; } list.Add(groupChannel); } if (bUp) { vm.MoveUp(list.ToArray()); } else { vm.MoveDown(list.ToArray()); } } private void ISOCode_LostFocus(object sender, RoutedEventArgs e) { if (!(DataContext is GroupChannelListViewModel viewModel)) { return; } if (!(sender is Control control)) { return; } if (!(control.DataContext is IGroupChannel channel)) { return; } if (viewModel.UseISOCodeFilterMapping) { //FB 15523 passes available filters var filters = DTS.SensorDB.SoftwareFilter.GetSoftwareFilters(); //FB 15574 FB 13120 channel.FilterClass = channel.GetFilterClassFromISOCode(filters, channel.IsoCode); } } /// /// handles hyperlink clicks, specifically for a sensor /// 15125 Navigate to selected sensor from run test diagnostics /// private void Hyperlink_Click(object sender, RoutedEventArgs e) { if (!(DataContext is GroupChannelListViewModel vm)) { return; } if (!(sender is Hyperlink hl)) { return; } if (!(hl.DataContext is GroupChannel groupChannel)) { return; } var eventAggregator = ContainerLocator.Container.Resolve(); eventAggregator.GetEvent().Publish(new PageNavigationRequest( PageNavigationRequest.Destinations.Sensor, groupChannel, vm)); } } }