using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; using System.Reflection; using System.Text.RegularExpressions; using System.Windows; using System.Windows.Input; using System.Windows.Threading; using DTS.Common; using DTS.Common.Base; using DTS.Common.Classes.Viewer.Commands; using DTS.Common.Enums; using DTS.Common.Enums.Sensors; using DTS.Common.Events; using DTS.Common.Interface; using DTS.Common.Utils; using DTS.Common.Settings; using DTS.Viewer.Resources; using Xceed.Wpf.AvalonDock.Layout; using Xceed.Wpf.AvalonDock.Layout.Serialization; using System.Globalization; using DTS.Common.Interactivity; using Prism.Regions; using Prism.Events; using Unity; // ReSharper disable CheckNamespace // ReSharper disable InconsistentNaming // ReSharper disable NotAccessedField.Local // ReSharper disable UnusedMember.Local // ReSharper disable RedundantDefaultMemberInitializer namespace DTS.Viewer { public class ViewerMainViewModel : BaseViewModel, IViewerMainViewModel { public IBaseView View { get; set; } private IBaseWindowModel Parent { get; set; } private IEventAggregator _eventAggregator { get; set; } private IUnityContainer _unityContainer { get; set; } public InteractionRequest NotificationRequest { get; private set; } public new InteractionRequest ConfirmationRequest { get; private set; } /// /// Creates a new instance of the MainViewModel. /// /// 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 Unity container. public ViewerMainViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer) : base(regionManager, eventAggregator, unityContainer) { NotificationRequest = new InteractionRequest(); ConfirmationRequest = new InteractionRequest(); _eventAggregator = eventAggregator; _unityContainer = unityContainer; View = _unityContainer.Resolve(); View.DataContext = this; } #region Methods /// /// sets SelectedDataFile and marks it as selected in viewer/model /// 16158 Browse button on View Data tab not functiona /// public void SelectAndIncludeDataFile(string value) { if (string.IsNullOrEmpty(value)) return; _selectedDataFile = value; _eventAggregator.GetEvent().Publish(new DataFolderSelectionArg { Path = string.Empty, File = _selectedDataFile, SetSelected = true, ParentVM = this }); OnPropertyChanged("SelectedDataFile"); } private void OnDataFileSelected(DataFileSelectionArg arg) { if (this != arg.ParentVM) return; SelectAndIncludeDataFile(arg?.File); } private void Subscribe() { _eventAggregator.GetEvent().Subscribe(OnLoadViewModul, ThreadOption.PublisherThread, true); _eventAggregator.GetEvent().Subscribe(OnTestLoadedChanged); _eventAggregator.GetEvent().Subscribe(OnTestSelectedCountChanged); _eventAggregator.GetEvent().Subscribe(OnGraphLoadedCountChanged); _eventAggregator.GetEvent().Subscribe(OnShiftT0Event); _eventAggregator.GetEvent().Subscribe(OnGraphSelectedCountChanged); _eventAggregator.GetEvent().Subscribe(OnGraphChannelsReadCompleted, ThreadOption.UIThread); _eventAggregator.GetEvent().Subscribe(OnViewerSettingsVisibilityChanged); _eventAggregator.GetEvent().Subscribe(OnDataFileSelected); _eventAggregator.GetEvent().Subscribe(OnSaveToPDFRequested); } private void OnViewerSettingsVisibilityChanged(Visibility settingsVisibility) { SettingsVisibility = settingsVisibility; } private Visibility _settingsVisibility = Visibility.Visible; public Visibility SettingsVisibility { get => _settingsVisibility; private set { _settingsVisibility = value; OnPropertyChanged("SettingsVisibility"); } } /// /// Initialize without parameter /// public override void Initialize() { Subscribe(); } /// /// Initialize with parameter - Parent /// public override void Initialize(object parameter) { Parent = (IBaseWindowModel)parameter; Parent.IsMenuIncluded = _isMenuIncluded; Parent.IsNavigationIncluded = _isNavigationIncluded; Subscribe(); View.DataContext = this; } public override void Activated() { } private void OnGraphLoadedCountChanged(GraphLoadedCountNotificationArg arg) { if (this != arg?.ParentVM) return; TotalLoadedGraphs = arg.LoadedCount; } private void OnGraphSelectedCountChanged(GraphSelectedChannelCountNotificationArg arg) { if (this != arg?.ParentVM) return; TotalSelectedGraphs = arg.SelectedChannelCount; } private void OnGraphChannelsReadCompleted(GraphChannelsReadCompletedNotificationArgs arg) { if (null == arg) { return; } if (((IGraphView)ContextGraphRegion).DataContext != arg?.GraphVM) return; _eventAggregator.GetEvent().Publish(!arg.IsReadCompleted); } private void OnTestLoadedChanged(TestLoadedCountNotificationArg arg) { if (this != arg?.ParentVM) return; TotalLoadedTests = arg.LoadedCount; } private void OnTestSelectedCountChanged(TestSummaryCountNotificationArg arg) { if (this != arg?.ParentVM) return; TotalSelectedTests = arg.SummaryCount; } /// /// Private Event handler for Status change event. /// private void OnStatusChange(StatusInfo content) { Dispatcher.CurrentDispatcher.InvokeAsync(() => { IsBusy = content.IsBusy; IsBusyMessage = content.Text; }, DispatcherPriority.Normal); } private void OnLoadViewModul(LoadViewModulArg arg) { IsBusy = true; IsBusyMessage = "Loading view list"; if (null == ContextGraphRegion) ContextGraphRegion = GetGraphView(this); if (null == ContextTestsRegion) ContextTestsRegion = GetTestDefinitionView(this); if (null == ContextGraphListRegion) ContextGraphListRegion = GetGraphListView(this); if (null == ContextChartOptionsRegion) ContextChartOptionsRegion = GetChartOptionsView(this); if (null == ContextTestModificationRegion) ContextTestModificationRegion = GetTestModificationView(this); if (null == ContextViewerSettingsRegion) ContextViewerSettingsRegion = GetViewerSettingsView(this); IsBusy = false; IsBusyMessage = string.Empty; } public void ZoomReset() { _eventAggregator.GetEvent().Publish(true); } public void LeftKeyPress() { //inform any other modules and models of a T0 shift _eventAggregator.GetEvent().Publish(new ShiftT0EventArguments(-1, false, true)); } public void RightKeyPress() { //inform any other modules and models of a T0 shift _eventAggregator.GetEvent().Publish(new ShiftT0EventArguments(1, false, true)); } private void OnShiftT0Event(ShiftT0EventArguments args) { if (args.IsInitialization) { return; } if (args.T0Time != 0) { ShowModifications = true; } if (args.T0Steps != 0) { ShowModifications = true; } } #endregion #region Views private INavigationView GetNavigationView(IBaseViewModel parent) { var view = _unityContainer.Resolve(); var viewModel = _unityContainer.Resolve(); view.DataContext = viewModel; viewModel.Initialize(parent); return view; } private INavigationViewModel GetNavigationViewModel(IBaseViewModel parent) { var view = _unityContainer.Resolve(); var viewModel = _unityContainer.Resolve(); view.DataContext = viewModel; viewModel.Initialize(parent); return viewModel; } private IChartOptionsView GetChartOptionsView(IBaseViewModel parent) { var view = _unityContainer.Resolve(); var viewModel = _unityContainer.Resolve(); view.DataContext = viewModel; viewModel.Initialize(parent); return view; } private IGraphView GetGraphView(IBaseViewModel parent) { var view = _unityContainer.Resolve(); var viewModel = _unityContainer.Resolve(); view.DataContext = viewModel; viewModel.Initialize(parent); return view; } private IGraphMainView GetGraphListView(IBaseViewModel parent) { var view = _unityContainer.Resolve(); var viewModel = _unityContainer.Resolve(); view.DataContext = viewModel; viewModel.Initialize(parent); return view; } private IViewerSettingsView GetViewerSettingsView(IBaseViewModel parent) { var view = _unityContainer.Resolve(); var viewModel = _unityContainer.Resolve(); view.DataContext = viewModel; viewModel.Initialize(parent); return view; } private ITestModificationView GetTestModificationView(IBaseViewModel parent) { var view = _unityContainer.Resolve(); var viewModel = _unityContainer.Resolve(); view.DataContext = viewModel; try { viewModel.UseISOCodeFilterMapping = SettingsDB.GetGlobalValueBool("UseISOCodeFilterMapping", true); } catch (Exception) { } viewModel.Initialize(parent); return view; } private ITestSummaryListView GetTestDefinitionView(IBaseViewModel parent) { var view = _unityContainer.Resolve(); var viewModel = _unityContainer.Resolve(); view.DataContext = viewModel; viewModel.Initialize(parent); return view; } #endregion Views #region ContextRegion private IBaseViewModel _activeContent; public IBaseViewModel ActiveContent { get => _activeContent; set { _activeContent = value; OnPropertyChanged("ActiveContent"); } } #region Graph public object ContextGraphRegion { get => ((ViewerMainViewGrid)View).GraphRegion.Content; set { ((ViewerMainViewGrid)View).GraphRegion.Content = value; OnPropertyChanged("ContextGraphRegion"); } } public object ContextGraphListRegion { get => ((ViewerMainViewGrid)View).GraphListRegion.Content; set { ((ViewerMainViewGrid)View).GraphListRegion.Content = value; OnPropertyChanged("ContextGraphListRegion"); } } #endregion Graph public object ContextTestsRegion { get => ((ViewerMainViewGrid)View).TestsRegion.Content; set { ((ViewerMainViewGrid)View).TestsRegion.Content = value; OnPropertyChanged("ContextTestsRegion"); } } public object ContextGraphsRegion { get => ((ViewerMainViewGrid)View).GraphListRegion.Content; set { ((ViewerMainViewGrid)View).GraphListRegion.Content = value; OnPropertyChanged("ContextGraphsRegion"); } } public object ContextLegendRegion { get => ((ViewerMainViewGrid)View).LegendRegion.Content; set { ((ViewerMainViewGrid)View).LegendRegion.Content = value; OnPropertyChanged("ContextLegendRegion"); } } public object ContextDiagRegion { get => ((ViewerMainViewGrid)View).DiagRegion.Content; set { ((ViewerMainViewGrid)View).DiagRegion.Content = value; OnPropertyChanged("ContextDiagRegion"); } } public object ContextStatsRegion { get => ((ViewerMainViewGrid)View).StatsRegion.Content; set { ((ViewerMainViewGrid)View).StatsRegion.Content = value; OnPropertyChanged("ContextStatsRegion"); } } public object ContextCursorRegion { get =>((ViewerMainViewGrid)View).CursorRegion.Content; set { ((ViewerMainViewGrid)View).CursorRegion.Content = value; OnPropertyChanged("ContextCursorRegion"); } } public object ContextPropertyRegion { get; set; } public object ContextChartOptionsRegion { get => ((ViewerMainViewGrid)View).ChartOptionsRegion.Content; set { ((ViewerMainViewGrid)View).ChartOptionsRegion.Content = value; OnPropertyChanged("ContextChartOptionsRegion"); } } public object ContextTestModificationRegion { get => ((ViewerMainViewGrid)View).TestModificationRegion.Content; set { ((ViewerMainViewGrid)View).TestModificationRegion.Content = value; OnPropertyChanged("ContextTestModificationRegion"); } } public object ContextViewerSettingsRegion { get => ((ViewerMainViewGrid)View).SettingsRegion.Content; set { ((ViewerMainViewGrid)View).SettingsRegion.Content = value; OnPropertyChanged("ContextViewerSettingsRegion"); } } public List GetRegions() { var items = new List(); Utils.GetChildrenByName(((ViewerMainViewGrid)View).MainShell, "Region", ref items); return items; } private readonly object saveLock = new object(); private void OnSaveToPDFRequested(string directory) { if (null == (ViewerMainViewGrid)View) return; lock (saveLock) { var pdfFileName = DateTime.Now.ToString("M'/'d'/'yyyy", CultureInfo.InvariantCulture).Replace("/", "_") + "_" + DateTime.Now.ToString("h':'mm' 'tt", CultureInfo.InvariantCulture).Replace(":", "_") + "_" + DateTime.Now.Second + "_" + DateTime.Now.Millisecond + ".pdf"; var intResult = ((ViewerMainViewGrid)View).SaveToPDF(directory, pdfFileName); var output = string.Empty; if (intResult > 0) { //Success output = string.Format(StringResources.SavePDFSuccess, Environment.NewLine, Path.Combine(directory, pdfFileName), Environment.NewLine, Path.Combine(directory, pdfFileName.Replace(".pdf", ".png"))); _eventAggregator.GetEvent().Publish(new PageErrorArg(new string[] { output }, null)); } else if (intResult < 0) { //Failure output = StringResources.SavePDFError; _eventAggregator.GetEvent().Publish(new PageErrorArg(new string[] { output }, null)); } } } public string ConfigPath { get; set; } #endregion #region Properties #region Test Title private string _titleTests = StringResources.TestsDefaultTitle; public string TitleTests { get => _titleTests; set { _titleTests = value; OnPropertyChanged("TitleTests"); } } private int _totalSelectedTests = 0; public int TotalSelectedTests { get => _totalSelectedTests; set { _totalSelectedTests = value; TitleTests = StringResources.TestsDefaultTitle + TotalSelectedTests + "/" + TotalLoadedTests; if (_totalSelectedTests == 0) { TitleGraphs = StringResources.GraphsDefaultTitle; } OnPropertyChanged("TotalSelectedTests"); } } private int _totalLoadedTests = 0; public int TotalLoadedTests { get => _totalLoadedTests; set { _totalLoadedTests = value; TitleTests = StringResources.TestsDefaultTitle + TotalSelectedTests + "/" + TotalLoadedTests; OnPropertyChanged("TotalLoadedTests"); } } #endregion Test Title #region Graph Title private string _titleGraphs = StringResources.GraphsDefaultTitle; public string TitleGraphs { get => _titleGraphs; set { _titleGraphs = value; OnPropertyChanged("TitleGraphs"); } } private int _totalSelectedGraphs = 0; public int TotalSelectedGraphs { get => _totalSelectedGraphs; set { _totalSelectedGraphs = value; TitleGraphs = StringResources.GraphsDefaultTitle + TotalSelectedGraphs + "/" + TotalLoadedGraphs; OnPropertyChanged("TotalSelectedGraphs"); } } private int _totalLoadedGraphs = 0; public int TotalLoadedGraphs { get => _totalLoadedGraphs; set { _totalLoadedGraphs = value; TitleGraphs = StringResources.GraphsDefaultTitle + TotalSelectedGraphs + "/" + TotalLoadedGraphs; OnPropertyChanged("TotalLoadedGraphs"); } } #endregion Graph Title private string _selectedDataFolder = string.Empty; public string SelectedDataFolder { get => _selectedDataFolder; set { if (string.IsNullOrEmpty(value)) return; _selectedDataFolder = value; _eventAggregator.GetEvent().Publish(new DataFolderSelectionArg { Path = _selectedDataFolder, File = string.Empty, ParentVM = this }); OnPropertyChanged("SelectedDataFolder"); } } public bool DoesUserHaveEditPermission { get; set; } = false; private string _selectedDataFile = string.Empty; public string SelectedDataFile { get => _selectedDataFile; set { if (string.IsNullOrEmpty(value)) return; _selectedDataFile = value; _eventAggregator.GetEvent().Publish(new DataFolderSelectionArg { Path = string.Empty, File = _selectedDataFile, ParentVM = this }); OnPropertyChanged("SelectedDataFile"); } } public bool _showModifications = false; public bool ShowModifications { get => _showModifications; set { _showModifications = value; OnPropertyChanged("ShowModifications"); } } private IsoViewMode _channelCodeViewMode = IsoViewMode.ISOAndUserCode; public IsoViewMode ChannelCodeViewMode { get => _channelCodeViewMode; set { _channelCodeViewMode = value; _eventAggregator.GetEvent().Publish(value); OnPropertyChanged("ChannelCodeViewMode"); } } private CalibrationBehaviors _calibrationBehaviorSetting = CalibrationBehaviors.NonLinearIfAvailable; public CalibrationBehaviors CalibrationBehaviorSetting { get => _calibrationBehaviorSetting; set { _calibrationBehaviorSetting = value; _eventAggregator.GetEvent().Publish(value); OnPropertyChanged("CalibrationBehaviorSetting"); } } private bool _calibrationBehaviorSettableInViewer = true; public bool CalibrationBehaviorSettableInViewer { get => _calibrationBehaviorSettableInViewer; set { _calibrationBehaviorSettableInViewer = value; _eventAggregator.GetEvent().Publish(value); OnPropertyChanged("CalibrationBehaviorSettableInViewer"); //FB13946: Test tab should be the first if in Viewer Tile, graphs tab if in Run Test/Download //CalibrationSettableInViewer is a proxy here for which tile we're in ((ViewerMainViewGrid)View).graphsTab.IsSelected = !value; ((ViewerMainViewGrid)View).testsTab.IsSelected = value; //FB 14797 select first tab always to not switch when the graph is loading. ((ViewerMainViewGrid)View).chartOptTab.IsSelected = true; ((ViewerMainViewGrid)View).chartOptTab.Focusable = true; ((ViewerMainViewGrid)View).chartOptTab.Focus(); } } //List _assemblyGroupList = new List(); //public List AssemblyGroupList //{ // get { return _assemblyGroupList; } // set { _assemblyGroupList = value; OnPropertyChanged("AssemblyGroupList"); } //} /// ///Occurs when a property value changes. /// public new event PropertyChangedEventHandler PropertyChanged; private new void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } private bool _isBusy = false; /// /// Display or hide Busy Indicator /// public new bool IsBusy { get => _isBusy; set { _isBusy = value; OnPropertyChanged("IsBusy"); } } private string _isBusyMessage = string.Empty; /// /// Busy Message text /// public new string IsBusyMessage { get => _isBusyMessage; set { _isBusyMessage = value; OnPropertyChanged("IsBusyMessage"); } } private bool _isMenuIncluded = false; public new bool IsMenuIncluded { get => _isMenuIncluded; set { _isMenuIncluded = value; OnPropertyChanged("IsMenuIncluded"); } } private bool _isNavigationIncluded = false; public new bool IsNavigationIncluded { get => _isNavigationIncluded; set { _isNavigationIncluded = value; OnPropertyChanged("IsNavigationIncluded"); } } /// /// Gets the HeaderInfo. /// public string HeaderInfo => "MainRegion"; #endregion #region Commands #region LoadLayoutCommand RelayCommand _loadLayoutCommand = null; public ICommand LoadLayoutCommand => _loadLayoutCommand ?? (_loadLayoutCommand = new RelayCommand(OnLoadLayout, CanLoadLayout)); private bool CanLoadLayout(object parameter) { return File.Exists(@".\DataProViewerAvalonDock.config"); } private void OnLoadLayout(object parameter) { var layoutSerializer = new XmlLayoutSerializer(((ViewerMainView)View).DockManager); //Here I've implemented the LayoutSerializationCallback just to show // a way to feed layout desarialization with content loaded at runtime //Actually I could in this case let AvalonDock to attach the contents //from current layout using the content ids //LayoutSerializationCallback should anyway be handled to attach contents //not currently loaded layoutSerializer.LayoutSerializationCallback += (s, e) => { //if (e.Model.ContentId == FileStatsViewModel.ToolContentId) // e.Content = Workspace.This.FileStats; //else if (!string.IsNullOrWhiteSpace(e.Model.ContentId) && // File.Exists(e.Model.ContentId)) // e.Content = Workspace.This.Open(e.Model.ContentId); }; layoutSerializer.Deserialize(@".\DataProViewerAvalonDock.config"); } #endregion #region SaveLayoutCommand RelayCommand _saveLayoutCommand = null; public ICommand SaveLayoutCommand => _saveLayoutCommand ?? (_saveLayoutCommand = new RelayCommand(OnSaveLayout, CanSaveLayout)); public object ContextNavigationRegion { get; set; } private bool CanSaveLayout(object parameter) { return true; } private void OnSaveLayout(object parameter) { var layoutSerializer = new XmlLayoutSerializer(((ViewerMainView)View).DockManager); layoutSerializer.Serialize(@".\AvalonDock.config"); } #endregion #endregion } }