492 lines
19 KiB
C#
492 lines
19 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.ComponentModel;
|
|
using System.ComponentModel.Composition;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Data;
|
|
using DTS.Common.Events;
|
|
using DTS.Common.Events.TTSImport;
|
|
using DTS.Common.Interface.DataRecorders;
|
|
using DTS.Common.Interface.TestSetups.Imports.TTS;
|
|
using DTS.Common.Interface.TestSetups.Imports.TTS.ReadFile;
|
|
using Prism.Events;
|
|
using Unity;
|
|
using DTS.Common.Interactivity;
|
|
using Prism.Regions;
|
|
using Prism.Commands;
|
|
using TTSImport.Model;
|
|
using TTSImport.Resources;
|
|
using DTS.DASLib.Service;
|
|
|
|
// ReSharper disable CheckNamespace
|
|
// ReSharper disable MemberCanBePrivate.Global
|
|
// ReSharper disable InconsistentNaming
|
|
|
|
namespace TTSImport
|
|
{
|
|
/// <summary>
|
|
/// this class handles Level Trigger edit/create functionality
|
|
/// </summary>
|
|
[PartCreationPolicy(CreationPolicy.Shared)]
|
|
public class TOMChannelsViewModel : ITOMChannelsViewModel
|
|
{
|
|
/// <summary>
|
|
/// The Hardware Scan view
|
|
/// </summary>
|
|
public ITOMChannelsView View { get; set; }
|
|
|
|
private IEventAggregator _eventAggregator { get; }
|
|
private IRegionManager _regionManager;
|
|
private IUnityContainer UnityContainer { get; }
|
|
|
|
public InteractionRequest<Notification> NotificationRequest { get; }
|
|
public InteractionRequest<Confirmation> ConfirmationRequest { get; }
|
|
|
|
/// <summary>
|
|
/// Creates a new instance of the TechnologyDomainEditViewModel.
|
|
/// </summary>
|
|
/// <param name="view">The ITOMChannelsView.</param>
|
|
/// <param name="regionManager">The logical placeholder defined within the application's UI (in the shell or within views) into which views are displayed.</param>
|
|
/// <param name="eventAggregator">The EventAggregator which allows different components to publish/subscribe to events without being coupled to each other.</param>
|
|
/// <param name="unityContainer">The unityContainer.</param>
|
|
public TOMChannelsViewModel(ITOMChannelsView view, IRegionManager regionManager,
|
|
IEventAggregator eventAggregator, IUnityContainer unityContainer)
|
|
{
|
|
View = view;
|
|
View.DataContext = this;
|
|
|
|
NotificationRequest = new InteractionRequest<Notification>();
|
|
ConfirmationRequest = new InteractionRequest<Confirmation>();
|
|
|
|
_eventAggregator = eventAggregator;
|
|
UnityContainer = unityContainer;
|
|
_regionManager = regionManager;
|
|
_eventAggregator.GetEvent<RaiseNotification>().Subscribe(OnRaiseNotification);
|
|
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>()
|
|
.Subscribe(OnBusyIndicatorNotification, ThreadOption.PublisherThread, true);
|
|
_eventAggregator.GetEvent<AssignedChannelsChangedEvent>().Subscribe(OnAssignedChannelsChangedEvent,
|
|
ThreadOption.PublisherThread, true);
|
|
_eventAggregator.GetEvent<TTSImportHardwareScanFinishedEvent>()
|
|
.Subscribe(OnHardwareScanComplete, ThreadOption.PublisherThread, true);
|
|
_eventAggregator.GetEvent<TTSImportReadFileStatusEvent>().Subscribe(OnReadFileFinished, ThreadOption.PublisherThread, true);
|
|
}
|
|
|
|
#region Methods
|
|
private void OnReadFileFinished(ReadFileStatusArg statusArg)
|
|
{
|
|
_setup = statusArg.TTSSetup;
|
|
_hardware = null;
|
|
}
|
|
private void OnHardwareScanComplete(List<IDASHardware> hardware)
|
|
{
|
|
_hardware = hardware;
|
|
}
|
|
|
|
private void OnAssignedChannelsChangedEvent(ITTSSetup setup)
|
|
{
|
|
if (!Application.Current.Dispatcher.CheckAccess())
|
|
{
|
|
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
{
|
|
OnAssignedChannelsChangedEvent(setup);
|
|
}));
|
|
return;
|
|
}
|
|
_setup = setup;
|
|
if (null == _hardware || null == _setup) { return; }
|
|
var channels = new ObservableCollection<Model.DASChannel>();
|
|
var remainingChannels = new ObservableCollection<ITTSChannelRecord>();
|
|
var channelIdToChannel = new Dictionary<string, Model.DASChannel>();
|
|
foreach (var das in _hardware)
|
|
{
|
|
var ichannels = das.GetIHardwareChannels();
|
|
for (var i = 0; i < ichannels.Length; i += 2)
|
|
{
|
|
var ch = ichannels[i];
|
|
if (!ch.IsSquib) { continue; }
|
|
var newChannel = new Model.DASChannel(ch);
|
|
channels.Add(newChannel);
|
|
channelIdToChannel[ch.GetId()] = newChannel;
|
|
}
|
|
}
|
|
|
|
foreach (var channelRecord in _setup.Channels)
|
|
{
|
|
if (channelRecord.IsEmptyRecord)
|
|
{
|
|
continue;
|
|
}
|
|
if (!channelRecord.IsSquib)
|
|
{
|
|
continue;
|
|
}
|
|
if (!channelRecord.IsChannelCodeValid)
|
|
{
|
|
continue;
|
|
}
|
|
if (channelRecord.ChannelCode == TTSChannelRecord.NONE)
|
|
{
|
|
continue;
|
|
}
|
|
if (null != channelRecord.HardwareChannel)
|
|
{
|
|
if (channelIdToChannel.ContainsKey(channelRecord.HardwareChannel.GetId()))
|
|
{
|
|
channelIdToChannel[channelRecord.HardwareChannel.GetId()].SetITTSChannelRecord(channelRecord);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
remainingChannels.Add(channelRecord);
|
|
}
|
|
}
|
|
|
|
DASChannels = channels;
|
|
RemainingChannels = remainingChannels;
|
|
OnPropertyChanged("DASChannels");
|
|
OnPropertyChanged("RemainingChannels");
|
|
}
|
|
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()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Private Event handler for RaiseNotification event.
|
|
/// </summary>
|
|
private void OnBusyIndicatorNotification(bool eventArg)
|
|
{
|
|
IsBusy = eventArg;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Private Event handler for RaiseNotification event.
|
|
/// </summary>
|
|
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
|
|
});
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Properties
|
|
private ITTSSetup _setup;
|
|
private IList<IDASHardware> _hardware;
|
|
public bool IsDirty { get; private set; }
|
|
private bool _isBusy;
|
|
|
|
public bool IsBusy
|
|
{
|
|
get => _isBusy;
|
|
set
|
|
{
|
|
_isBusy = value;
|
|
OnPropertyChanged("IsBusy");
|
|
}
|
|
}
|
|
|
|
private bool _isMenuIncluded;
|
|
|
|
public bool IsMenuIncluded
|
|
{
|
|
get => _isMenuIncluded;
|
|
set
|
|
{
|
|
_isMenuIncluded = value;
|
|
OnPropertyChanged("IsMenuIncluded");
|
|
}
|
|
}
|
|
|
|
private bool _isNavigationIncluded;
|
|
|
|
public bool IsNavigationIncluded
|
|
{
|
|
get => _isNavigationIncluded;
|
|
set
|
|
{
|
|
_isNavigationIncluded = value;
|
|
OnPropertyChanged("IsNavigationIncluded");
|
|
}
|
|
}
|
|
public bool AssignEnabled { get; set; }
|
|
public bool RemoveEnabled { get; set; }
|
|
public bool EnableOrDisableEnabled { get; set; }
|
|
public ObservableCollection<Model.DASChannel> DASChannels { get; set; } = new ObservableCollection<Model.DASChannel>();
|
|
public ObservableCollection<ITTSChannelRecord> RemainingChannels { get; set; } =
|
|
new ObservableCollection<ITTSChannelRecord>();
|
|
|
|
private ITTSChannelRecord _selectedRemainingChannel;
|
|
public ITTSChannelRecord SelectedRemainingChannel
|
|
{
|
|
get => _selectedRemainingChannel;
|
|
set
|
|
{
|
|
_selectedRemainingChannel = value;
|
|
if (null == _selectedRemainingChannel || null == SelectedDASChannel) return;
|
|
AssignEnabled = true;
|
|
OnPropertyChanged("AssignEnabled");
|
|
}
|
|
}
|
|
private void DetermineRemoveEnableStatus()
|
|
{
|
|
if (_selectedDASChannel?.Channel != null)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(_selectedDASChannel.EID) &&
|
|
_selectedDASChannel.EID == _selectedDASChannel.Channel.SensorEID)
|
|
{
|
|
//can only be replaced, can't be removed
|
|
RemoveEnabled = false;
|
|
}
|
|
RemoveEnabled = true;
|
|
}
|
|
else
|
|
{
|
|
RemoveEnabled = false;
|
|
}
|
|
OnPropertyChanged("RemoveEnabled");
|
|
AssignEnabled = null != _selectedDASChannel && null != _selectedRemainingChannel;
|
|
OnPropertyChanged("AssignEnabled");
|
|
EnableOrDisableEnabled = _selectedDASChannel?.Channel != null;
|
|
OnPropertyChanged("EnableOrDisableEnabled");
|
|
OnPropertyChanged("EnableOrDisableText");
|
|
}
|
|
private Model.DASChannel _selectedDASChannel;
|
|
public Model.DASChannel SelectedDASChannel
|
|
{
|
|
get => _selectedDASChannel;
|
|
set
|
|
{
|
|
_selectedDASChannel = value;
|
|
DetermineRemoveEnableStatus();
|
|
}
|
|
}
|
|
|
|
public string EnableOrDisableText
|
|
{
|
|
get
|
|
{
|
|
if (SelectedDASChannel?.Channel == null)
|
|
{
|
|
return StringResources.Analog_Enable;
|
|
}
|
|
return SelectedDASChannel.Channel.Disabled
|
|
? StringResources.Analog_Enable
|
|
: StringResources.Analog_Disable;
|
|
}
|
|
}
|
|
#endregion Properties
|
|
|
|
#region Commands
|
|
#region assign
|
|
/// <summary>
|
|
/// Assign a channel code to a channel
|
|
/// </summary>
|
|
private DelegateCommand _assignCommand;
|
|
public DelegateCommand AssignCommand => _assignCommand ?? (_assignCommand = new DelegateCommand(Assign));
|
|
private void Assign()
|
|
{
|
|
if (SelectedRemainingChannel == null) { return; }
|
|
|
|
_eventAggregator.GetEvent<TTSImportTestSetupChangedEvent>().Publish(_setup);
|
|
//BEFORE we go any further, check the state of sensor ids
|
|
//if the channel has a sensor id AND there's a sensor on the channel with the same id
|
|
//then prompt on replacing the id
|
|
//IF the channel has a sensor id and there's no sensor on the channel BUT the new sensor has a different id
|
|
//then prompt on replacing the id
|
|
var bReplacingID = false;
|
|
if (!string.IsNullOrWhiteSpace(SelectedDASChannel.EID))
|
|
{
|
|
if (null != SelectedRemainingChannel && SelectedRemainingChannel.SensorEID != SelectedDASChannel.EID)
|
|
{
|
|
bReplacingID = true;
|
|
}
|
|
//if existing channel has this ID, we will need to clear out the old id and assign a new one...
|
|
if (null != SelectedDASChannel.Channel && SelectedDASChannel.Channel.SensorEID == SelectedDASChannel.EID)
|
|
{
|
|
bReplacingID = true;
|
|
}
|
|
}
|
|
if (bReplacingID)
|
|
{
|
|
Task.Run(() =>
|
|
{
|
|
var dialogResult = MessageBox.Show(StringResources.AssignSensorPrompt, StringResources.UserFeedbackRequired, MessageBoxButton.YesNo);
|
|
if (dialogResult == MessageBoxResult.Yes)
|
|
{
|
|
Application.Current.Dispatcher.BeginInvoke(new Action(AssignWork));
|
|
}
|
|
});
|
|
return;
|
|
}
|
|
|
|
AssignWork();
|
|
}
|
|
|
|
/// <summary>
|
|
/// assigns a channel record to a physical channel
|
|
/// </summary>
|
|
private void AssignWork()
|
|
{
|
|
if (null != SelectedDASChannel.Channel)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(SelectedDASChannel.EID))
|
|
{
|
|
SelectedDASChannel.Channel.SensorEID = "";
|
|
}
|
|
RemainingChannels.Add(SelectedDASChannel.Channel);
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(SelectedDASChannel.EID))
|
|
{
|
|
SelectedRemainingChannel.SensorEID = SelectedDASChannel.EID;
|
|
}
|
|
|
|
SelectedDASChannel.SetITTSChannelRecord(SelectedRemainingChannel);
|
|
|
|
var channel = SelectedRemainingChannel;
|
|
var index = RemainingChannels.IndexOf(channel);
|
|
SelectedRemainingChannel = null;
|
|
RemainingChannels.Remove(channel);
|
|
if (index < RemainingChannels.Count)
|
|
{
|
|
SelectedRemainingChannel = RemainingChannels[index];
|
|
OnPropertyChanged("SelectedRemainingChannel");
|
|
}
|
|
else if (RemainingChannels.Count > 0)
|
|
{
|
|
SelectedRemainingChannel = RemainingChannels[index - 1];
|
|
OnPropertyChanged("SelectedRemainingChannel");
|
|
}
|
|
CollectionViewSource.GetDefaultView(DASChannels)?.Refresh();
|
|
index = DASChannels.IndexOf(SelectedDASChannel);
|
|
for (var i = index; i < DASChannels.Count; i++)
|
|
{
|
|
var dasChannel = DASChannels[i];
|
|
if (null != dasChannel.Channel) { continue; }
|
|
SelectedDASChannel = dasChannel;
|
|
OnPropertyChanged("SelectedDASChannel");
|
|
return;
|
|
}
|
|
//didn't find a match, start from the beginning?
|
|
for (var i = 0; i < index; i++)
|
|
{
|
|
var dasChannel = DASChannels[i];
|
|
if (null != dasChannel.Channel)
|
|
{
|
|
continue;
|
|
}
|
|
SelectedDASChannel = dasChannel;
|
|
OnPropertyChanged("SelectedDASChannel");
|
|
return;
|
|
}
|
|
//if we get here there's no new channel to go to, but we need to set the remove/enable/disable button status
|
|
OnPropertyChanged("SelectedDASChannel");
|
|
DetermineRemoveEnableStatus();
|
|
}
|
|
#endregion
|
|
#region remove
|
|
private DelegateCommand _removeCommand;
|
|
public DelegateCommand RemoveCommand => _removeCommand ?? (_removeCommand = new DelegateCommand(Remove));
|
|
/// <summary>
|
|
/// remove a hardware channel assignment (does not remove the channel from the test setup though?)
|
|
/// </summary>
|
|
private void Remove()
|
|
{
|
|
if (null == SelectedDASChannel || null == SelectedDASChannel.Channel) { return; }
|
|
_eventAggregator.GetEvent<TTSImportTestSetupChangedEvent>().Publish(_setup);
|
|
RemainingChannels.Add(SelectedDASChannel.Channel);
|
|
SelectedDASChannel.SetITTSChannelRecord(null);
|
|
CollectionViewSource.GetDefaultView(DASChannels)?.Refresh();
|
|
var index = DASChannels.IndexOf(SelectedDASChannel);
|
|
for (var i = index; i < DASChannels.Count; i++)
|
|
{
|
|
if (null == DASChannels[i].Channel) { continue; }
|
|
SelectedDASChannel = DASChannels[i];
|
|
OnPropertyChanged("SelectedDASChannel");
|
|
return;
|
|
}
|
|
for (var i = 0; i < index; i++)
|
|
{
|
|
if (null == DASChannels[i].Channel) { continue; }
|
|
SelectedDASChannel = DASChannels[i];
|
|
OnPropertyChanged("SelectedDASChannel");
|
|
return;
|
|
}
|
|
//if we get here there's no new channel to go to, but we need to set the remove/enable/disable button status
|
|
OnPropertyChanged("SelectedDASChannel");
|
|
DetermineRemoveEnableStatus();
|
|
}
|
|
#endregion
|
|
#region enableordisable
|
|
private DelegateCommand _enableOrDisableCommand;
|
|
public DelegateCommand EnableOrDisableCommand =>
|
|
_enableOrDisableCommand ?? (_enableOrDisableCommand = new DelegateCommand(EnableOrDisable));
|
|
/// <summary>
|
|
/// enables or disables a channel in the test.
|
|
/// </summary>
|
|
private void EnableOrDisable()
|
|
{
|
|
if (SelectedDASChannel?.Channel == null) { return; }
|
|
SelectedDASChannel.Channel.Disabled = !SelectedDASChannel.Channel.Disabled;
|
|
SelectedDASChannel.Disabled = SelectedDASChannel.Channel.Disabled;
|
|
|
|
OnPropertyChanged("EnableOrDisableText");
|
|
_eventAggregator.GetEvent<TTSImportTestSetupChangedEvent>().Publish(_setup);
|
|
}
|
|
#endregion
|
|
#endregion
|
|
|
|
/// <inheritdoc />
|
|
/// <summary>
|
|
/// Occurs when a property value changes.
|
|
/// </summary>
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
|
|
public void OnPropertyChanged(string propertyName)
|
|
{
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
}
|
|
}
|
|
}
|