init
This commit is contained in:
@@ -0,0 +1,407 @@
|
||||
using DTS.Common.Base;
|
||||
using DTS.Common.Events;
|
||||
using DTS.Common.Interactivity;
|
||||
using DTS.Common.Interface;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using DTS.Common.Settings;
|
||||
using DTS.Common.Storage;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.SensorDB;
|
||||
using DTS.Viewer.ChartOptions.Model;
|
||||
using DTS.Viewer.TestModification.Model;
|
||||
using Prism.Commands;
|
||||
using Prism.Events;
|
||||
using Prism.Regions;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using Unity;
|
||||
// ReSharper disable CheckNamespace
|
||||
// ReSharper disable ConvertToAutoProperty
|
||||
// ReSharper disable InconsistentNaming
|
||||
// ReSharper disable UnusedAutoPropertyAccessor.Local
|
||||
// ReSharper disable NotAccessedField.Local
|
||||
// ReSharper disable RedundantDefaultMemberInitializer
|
||||
|
||||
namespace DTS.Viewer.TestModification
|
||||
{
|
||||
public class TestModificationViewModel : BaseViewModel<ITestModificationViewModel>, ITestModificationViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// retrieves latest calibration from database (or null if not in database or an error occurs)
|
||||
/// <summary>
|
||||
private static ISensorCalDbRecord GetLatestCalibration(ISensorDbRecord sensor)
|
||||
{
|
||||
if ( null == sensor)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
try
|
||||
{
|
||||
var records = GetCalibrationsDb(sensor.id, sensor.SerialNumber);
|
||||
if ( null == records || 0 == records.Length) { return null; }
|
||||
Array.Sort(records, CompareCalibrations);
|
||||
//calibrations should now be in ascending order so take the "last" one
|
||||
return records[records.Length - 1];
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//there's no access to APILogger here, so rather than adding a reference, just eat the error
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private static ISensorCalDbRecord[] GetCalibrationsDb(int sensorId, string serialNumber)
|
||||
{
|
||||
_ = DbOperations.SensorCalibrationsGet(sensorId, serialNumber, out var records);
|
||||
return records;
|
||||
}
|
||||
/// <summary>
|
||||
/// compares two sensor calibration records
|
||||
/// </summary>
|
||||
private static int CompareCalibrations(ISensorCalDbRecord left, ISensorCalDbRecord right)
|
||||
{
|
||||
if (left == right) { return 0; }
|
||||
if (null == left) { return 1; }
|
||||
if (null == right) { return -1; }
|
||||
var res = left.CalibrationDate.CompareTo(right.CalibrationDate);
|
||||
if (res != 0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
return left.ModifyDate.CompareTo(right.ModifyDate);
|
||||
}
|
||||
/// <summary>
|
||||
/// returns sensor given serial number
|
||||
/// </summary>
|
||||
private static ISensorDbRecord GetSensor(ISensorDbRecord[] records)
|
||||
{
|
||||
if ( null == records || 0 == records.Length) { return null; }
|
||||
return records[0];
|
||||
}
|
||||
/// <summary>
|
||||
/// updates calibration in db
|
||||
/// http://manuscript.dts.local/f/cases/43735/SW-NFR-DataPRO-Add-option-to-map-sensitivity-edit-in-Viewer-back-to-Sensor-Database
|
||||
/// </summary>
|
||||
public void UpdateDatabaseMethod()
|
||||
{
|
||||
try
|
||||
{
|
||||
var cal = Model.Cal;
|
||||
if (null == cal) { return; }
|
||||
cal.CalibrationId = -1;
|
||||
cal.ModifyDate = DateTime.Now;
|
||||
var sc = new SensorCalibration(cal);
|
||||
DbOperations.SensorCalibrationsInsert(sc, 0, true);
|
||||
Model.Cal = GetLatestCalibration(Model.Sensor);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_eventAggregator.GetEvent<PageErrorEvent>().Publish(new PageErrorArg(new[] { $"{Resources.StringResources.FailedToModifySensitivity} {ex.Message}" }, null));
|
||||
}
|
||||
}
|
||||
public ITestModificationView View { get; set; }
|
||||
public IBaseViewModel Parent { get; set; }
|
||||
private IEventAggregator _eventAggregator { get; set; }
|
||||
|
||||
private IUnityContainer _unityContainer { get; set; }
|
||||
public InteractionRequest<Notification> NotificationRequest { get; private set; }
|
||||
public new InteractionRequest<Confirmation> ConfirmationRequest { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the TestModificationViewListModel.
|
||||
/// </summary>
|
||||
/// <param name="view">The TestModification View interface.</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 TestModificationViewModel(ITestModificationView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)
|
||||
: base(regionManager, eventAggregator, unityContainer)
|
||||
{
|
||||
Model = new TestModificationModel();
|
||||
View = view;
|
||||
View.DataContext = this;
|
||||
NotificationRequest = new InteractionRequest<Notification>();
|
||||
ConfirmationRequest = new InteractionRequest<Confirmation>();
|
||||
|
||||
_eventAggregator = eventAggregator;
|
||||
_unityContainer = unityContainer;
|
||||
_eventAggregator.GetEvent<RaiseNotification>().Subscribe(OnRaiseNotification);
|
||||
_eventAggregator.GetEvent<GraphSelectedChannelsNotification>().Subscribe(OnGraphSelectedCountChanged);
|
||||
_eventAggregator.GetEvent<ShiftT0Event>().Subscribe(OnShiftT0Event);
|
||||
_eventAggregator.GetEvent<SetUseZeroForUnfilteredEvent>().Subscribe(OnSetUseZeroForUnfiltered);
|
||||
}
|
||||
private void OnSetUseZeroForUnfiltered(bool useZeroForUnfiltered)
|
||||
{
|
||||
UseZeroForUnfiltered = useZeroForUnfiltered;
|
||||
}
|
||||
private void OnShiftT0Event(ShiftT0EventArguments args)
|
||||
{
|
||||
if (args.IsInitialization) { return; }
|
||||
if (args.IsKeyPress)
|
||||
{
|
||||
if (null == Model) { return; }
|
||||
//if we can't modify no reason to continue, short circuit out
|
||||
if (!TestModificationVisability) { return; }
|
||||
|
||||
if (null == Model.SelectedChannel || null == Model.SelectedChannel.ParentModule) { return; }
|
||||
else
|
||||
{
|
||||
//go and modify the T0!
|
||||
//calculate a new T0 given the sample rate
|
||||
var t0 = Model.T0 + args.T0Steps * (1000D / Model.SelectedChannel.ParentModule.SampleRateHz);
|
||||
|
||||
Model.T0 = t0;
|
||||
}
|
||||
_eventAggregator.GetEvent<TestModificationChangedEvent>().Publish(Model);
|
||||
}
|
||||
else { Model.T0 = args.T0Time; }
|
||||
}
|
||||
|
||||
#region Methods
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Initialize(object parameter)
|
||||
{
|
||||
Parent = (IBaseViewModel)parameter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Private Event handler for RaiseNotification event.
|
||||
/// </summary>
|
||||
private void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)
|
||||
{
|
||||
// Notification object expects a NotificationContentEventArgsWithoutTitle object and a Title string.
|
||||
var eventArgsWithoutTitle = new NotificationContentEventArgs(eventArgsWithTitle.Message, eventArgsWithTitle.MessageDetails, eventArgsWithTitle.Image);
|
||||
|
||||
NotificationRequest.Raise(new Notification
|
||||
{
|
||||
Content = eventArgsWithoutTitle,
|
||||
Title = eventArgsWithTitle.Title
|
||||
});
|
||||
}
|
||||
private static bool IsPopulating { get; set; }
|
||||
private void OnGraphSelectedCountChanged(GraphSelectedChannelsNotificationArg arg)
|
||||
{
|
||||
if (Parent != arg?.ParentVM) return;
|
||||
var channels = arg.SelectedChannels;
|
||||
var canModify = channels.Count == 1 && channels.Count(x => x.IsSelected) == 1;
|
||||
TestModificationVisability = canModify;
|
||||
|
||||
if (canModify)
|
||||
{
|
||||
IsPopulating = true;
|
||||
Model.IsT0ModeTestOnly = SettingsDB.GetGlobalValueBool(Keys.ApplyShiftT0ModsTestOnly.ToString(), false);
|
||||
var viewModel = _unityContainer.TryResolve<IViewerMainViewModel>();
|
||||
|
||||
Model.EnableSensitivityControl = viewModel.DoesUserHaveEditPermission;
|
||||
Model.EnableLineFitControl = viewModel.DoesUserHaveEditPermission;
|
||||
Model.EnableDescriptionControl = viewModel.DoesUserHaveEditPermission;
|
||||
Model.EnableEUMultiplierControl = viewModel.DoesUserHaveEditPermission;
|
||||
Model.EnableEUOffsetControl = viewModel.DoesUserHaveEditPermission;
|
||||
Model.EnableFilterControl = viewModel.DoesUserHaveEditPermission;
|
||||
Model.IsT0Enabled = viewModel.DoesUserHaveEditPermission;
|
||||
Model.IsDataFlagEnabled = viewModel.DoesUserHaveEditPermission;
|
||||
Model.SelectedChannel = channels[0];
|
||||
TestModelManipulation.PopulateFromChannel(Model);
|
||||
IsPopulating = false;
|
||||
IsBackedUp = TestModelManipulation.BackupExists(Model);
|
||||
_eventAggregator.GetEvent<ShowT0CursorEvent>().Publish(true);
|
||||
DbOperations.SensorsGet(channels[0].SerialNumber, out var records);
|
||||
var sensor = GetSensor(records);
|
||||
|
||||
if (null != sensor && 0 == sensor.SensorType)
|
||||
{
|
||||
//for now we only display analog sensor calibrations ...
|
||||
Model.Sensor = sensor;
|
||||
Model.Cal = GetLatestCalibration(Model.Sensor);
|
||||
}
|
||||
}
|
||||
else if (channels.Count == 0)
|
||||
{
|
||||
Model.SelectedChannel = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
_eventAggregator.GetEvent<ShowT0CursorEvent>().Publish(false);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ContextRegion
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Commands
|
||||
private DelegateCommand _previewCommand;
|
||||
public DelegateCommand PreviewCommand => _previewCommand ?? (_previewCommand = new DelegateCommand(PreviewMethod));
|
||||
|
||||
private void PreviewMethod()
|
||||
{
|
||||
TestModelManipulation.PreviewLineFit(Model);
|
||||
}
|
||||
|
||||
private DelegateCommand _writeCommand;
|
||||
public DelegateCommand WriteCommand => _writeCommand ?? (_writeCommand = new DelegateCommand(WriteMethod));
|
||||
|
||||
private void WriteMethod()
|
||||
{
|
||||
var window = Application.Current.MainWindow;
|
||||
if (null == window) { return; }
|
||||
|
||||
//14661 Shifting T zero beyond post trigger seconds crashes application
|
||||
//don't allow T0 to shift beyond test data
|
||||
if (Model.IsModifiedT0 && !Model.ValidateT0())
|
||||
{
|
||||
_eventAggregator.GetEvent<PageErrorEvent>()
|
||||
.Publish(new PageErrorArg(new[] { Resources.StringResources.T0MustBeInDataset }, null));
|
||||
return;
|
||||
}
|
||||
|
||||
var dialogResult = MessageBox.Show(window, Resources.StringResources.WriteFilesPrompt, "", MessageBoxButton.YesNo);
|
||||
try
|
||||
{
|
||||
UseISOCodeFilterMapping = SettingsDB.GetGlobalValueBool("UseISOCodeFilterMapping", true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
APILogger.Log(Resources.StringResources.WriteFilesPrompt, $"User pressed {dialogResult.ToString()}");
|
||||
if (dialogResult == MessageBoxResult.Yes)
|
||||
{
|
||||
TestModelManipulation.SaveModification(Model, UseISOCodeFilterMapping, UseZeroForUnfiltered);
|
||||
IsBackedUp = TestModelManipulation.BackupExists(Model);
|
||||
}
|
||||
}
|
||||
private DelegateCommand _undoCommand;
|
||||
public DelegateCommand UndoCommand => _undoCommand ?? (_undoCommand = new DelegateCommand(UndoMethod));
|
||||
|
||||
private void UndoMethod()
|
||||
{
|
||||
var window = Application.Current.MainWindow;
|
||||
if (null == window) { return; }
|
||||
var dialogResult = MessageBox.Show(window, Resources.StringResources.UndoPrompt, "", MessageBoxButton.YesNo);
|
||||
APILogger.Log(Resources.StringResources.UndoPrompt, $"User pressed {dialogResult.ToString()}");
|
||||
if (dialogResult == MessageBoxResult.Yes)
|
||||
{
|
||||
TestModelManipulation.UndoModification(Model);
|
||||
}
|
||||
}
|
||||
private DelegateCommand _undoAllCommand;
|
||||
public DelegateCommand UndoAllCommand => _undoAllCommand ?? (_undoAllCommand = new DelegateCommand(UndoAllMethod));
|
||||
|
||||
private void UndoAllMethod()
|
||||
{
|
||||
var window = Application.Current.MainWindow;
|
||||
if (null == window) { return; }
|
||||
var dialogResult = MessageBox.Show(window, Resources.StringResources.UndoAllPrompt, "", MessageBoxButton.YesNo);
|
||||
APILogger.Log(Resources.StringResources.UndoAllPrompt, $"User pressed {dialogResult.ToString()}");
|
||||
if (dialogResult == MessageBoxResult.Yes)
|
||||
{
|
||||
TestModelManipulation.UndoAllModification(Model);
|
||||
IsBackedUp = TestModelManipulation.BackupExists(Model);
|
||||
}
|
||||
}
|
||||
public void PublishChanges()
|
||||
{
|
||||
if (!IsPopulating && Model.IsModifiedDataFlag)
|
||||
{
|
||||
//Write this immediately
|
||||
TestModelManipulation.SaveModificationDataFlag(Model);
|
||||
IsBackedUp = TestModelManipulation.BackupExists(Model);
|
||||
}
|
||||
|
||||
_eventAggregator?.GetEvent<TestModificationChangedEvent>().Publish(Model);
|
||||
}
|
||||
#endregion Commands
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// when true forces the ISOCode field filter SoftwareFilter to always match the SoftwareFilter of the channel
|
||||
/// Whenever the softwarefilter for a graph channel is modified it will check this value before
|
||||
/// modifying the channel isocode
|
||||
/// </summary>
|
||||
public bool UseISOCodeFilterMapping { get; set; } = false;
|
||||
|
||||
private TestModificationModel _model = null; // new TestModificationModel();
|
||||
public new TestModificationModel Model
|
||||
{
|
||||
get => _model;
|
||||
set
|
||||
{
|
||||
if (_model != null) _model.Parent = null;
|
||||
_model = value;
|
||||
if (_model != null) _model.Parent = this;
|
||||
OnPropertyChanged("Model");
|
||||
}
|
||||
}
|
||||
public bool UseZeroForUnfiltered
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
private bool _isFilterEnabled = false;
|
||||
public bool IsFilterEnabled { get => _isFilterEnabled; set { _isFilterEnabled = value; OnPropertyChanged("IsFilterEnabled"); } }
|
||||
|
||||
private bool _testModificationVisability = false;
|
||||
public bool TestModificationVisability { get => _testModificationVisability; set { _testModificationVisability = value; OnPropertyChanged("TestModificationVisability"); } }
|
||||
|
||||
///<summary>
|
||||
///Occurs when a property value changes.
|
||||
///</summary>
|
||||
public new event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private new void OnPropertyChanged(string propertyName)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HeaderInfo.
|
||||
/// </summary>
|
||||
public string HeaderInfo => "TestSummaryRegion";
|
||||
|
||||
private bool _isBusy = false;
|
||||
public new bool IsBusy
|
||||
{
|
||||
get => _isBusy;
|
||||
set { _isBusy = value; OnPropertyChanged("IsBusy"); }
|
||||
}
|
||||
|
||||
private bool _isDirty;
|
||||
public new bool IsDirty
|
||||
{
|
||||
get => _isDirty;
|
||||
set => _isDirty = value;
|
||||
}
|
||||
|
||||
private bool _isNavigationIncluded;
|
||||
public new bool IsNavigationIncluded
|
||||
{
|
||||
get => _isNavigationIncluded;
|
||||
set => _isNavigationIncluded = value;
|
||||
}
|
||||
|
||||
private bool _isBackedUp;
|
||||
public bool IsBackedUp
|
||||
{
|
||||
get => _isBackedUp;
|
||||
private set
|
||||
{
|
||||
_isBackedUp = value;
|
||||
OnPropertyChanged("IsBackedUp");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user