//******************************************************************************************************// MainWindow.xaml.cs - Gbtc//// Copyright © 2012, Grid Protection Alliance. All Rights Reserved.//// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See// the NOTICE file distributed with this work for additional information regarding copyright ownership.// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may// not use this file except in compliance with the License. You may obtain a copy of the License at://// http://www.opensource.org/licenses/MIT//// Unless agreed to in writing, the subject software distributed under the License is distributed on an// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the// License for the specific language governing permissions and limitations.//// Code Modification History:// ----------------------------------------------------------------------------------------------------// 08/10/2010 - Stephen C. Wills// Generated original version of source code.// 12/18/2011 - J. Ritchie Carroll// Set likely default archive locations on initial startup and removed disabled points from the// display list.// 09/29/2012 - J. Ritchie Carroll// Updated to code to use roll-over yielding ArchiveReader.// 12/20/2012 - Starlynn Danyelle Gilliam// Modified Header.////****************************************************************************************************** using System;using System.Collections.Generic;using System.ComponentModel;using System.Globalization;using System.IO;using System.Linq;using System.Reflection;using System.Text;using System.Text.RegularExpressions;using System.Windows;using System.Windows.Controls;using System.Windows.Input;using System.Xml.Linq;using GSF;using GSF.COMTRADE;using GSF.Historian;using GSF.Historian.Files;using GSF.IO;using GSF.Units.EE;using Microsoft.Win32; namespace HistorianView{ /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow { #region [ Members ] // Nested Types /// <summary> /// Defines a comparison class to property sort metadata. /// </summary> public class MetadataSorter : IComparer<MetadataWrapper> { /// <summary> /// Compares one metadata record to another. /// </summary> /// <param name="left">Left metadata record to compare.</param> /// <param name="right">Right metadata record to compare.</param> /// <returns>Comparison sort order of metadata record.</returns> public int Compare(MetadataWrapper left, MetadataWrapper right) { // Perform initial sort based on analogs followed by status flags, then digitals int result = ChannelMetadataSorter.Default.Compare(ConvertToChannelMetadata(left), ConvertToChannelMetadata(right)); // Fall back on historian ID for secondary sort order if (result == 0) result = left.PointNumber.CompareTo(right.PointNumber); return result; } /// <summary> /// Default instance of the metadata record sorter. /// </summary> public static readonly MetadataSorter Default = new MetadataSorter(); } /// <summary> /// This is a wrapper around a MetadataRecord that allows auto-generation /// of columns in the data grid based on the public properties of this class. /// </summary> public class MetadataWrapper : INotifyPropertyChanged { #region [ Members ] // Events /// <summary> /// Event triggered when a property is changed. /// </summary> public event PropertyChangedEventHandler PropertyChanged; // Fields private readonly ArchiveReader m_archiveReader; private readonly MetadataRecord m_metadata; private bool m_export; #endregion #region [ Constructors ] /// <summary> /// Creates a new instance of the <see cref="MetadataWrapper"/> class. /// </summary> /// <param name="archiveReader">The <see cref="ArchiveReader"/> that the metadata record came from.</param> /// <param name="metadata">The <see cref="MetadataRecord"/> to be wrapped.</param> public MetadataWrapper(ArchiveReader archiveReader, MetadataRecord metadata) { metadata.Synonym2 = ValidateSynonym2(metadata.Synonym2); m_archiveReader = archiveReader; m_metadata = metadata; } #endregion #region [ Properties ] /// <summary> /// Determines whether the measurement represented by this metadata record /// should be exported to CSV or displayed on the graph by the Historian Data Viewer. /// </summary> public bool Export { get { return m_export; } set { m_export = value; OnPropertyChanged("Export"); } } /// <summary> /// Gets the point number of the measurement. /// </summary> public int PointNumber { get { return m_metadata.HistorianID; } } /// <summary> /// Gets the name of the measurement. /// </summary> public string Name { get { // This formats name in accordance with COMTRADE standard Annex H (may need to make this optional) return FormatName(m_metadata.Name, m_metadata.Synonym1, m_metadata.Synonym2); } } /// <summary> /// Gets the point tag of the measurement. /// </summary> public string PointTag { get { return m_metadata.Name; } } /// <summary> /// Gets the description of the measurement. /// </summary> public string Description { get { return m_metadata.Description; } } /// <summary> /// Gets the first alternate name for the measurement. /// </summary> public string Synonym1 { get { return m_metadata.Synonym1; } } /// <summary> /// Gets the second alternate name for the measurement. /// </summary> public string Synonym2 { get { return m_metadata.Synonym2; } } /// <summary> /// Gets the third alternate name for the measurement. /// </summary> public string Synonym3 { get { return m_metadata.Synonym3; } } /// <summary> /// Gets the system name. /// </summary> public string System { get { return m_metadata.SystemName; } } /// <summary> /// Gets the low range of the measurement. /// </summary> public Single LowRange { get { return m_metadata.Summary.LowRange; } } /// <summary> /// Gets the high range of the measurement. /// </summary> public Single HighRange { get { return m_metadata.Summary.HighRange; } } /// <summary> /// Gets the engineering units used to measure the values. /// </summary> public string EngineeringUnits { get { return m_metadata.AnalogFields.EngineeringUnits; } } /// <summary> /// Gets the unit number of the measurement. /// </summary> public int Unit { get { return m_metadata.UnitNumber; } } #endregion #region [ Methods ] /// <summary> /// Returns the <see cref="ArchiveReader"/> that the metadata record came from. /// </summary> /// <returns>The archive reader.</returns> public ArchiveReader GetArchiveReader() { return m_archiveReader; } /// <summary> /// Returns the wrapped <see cref="MetadataRecord"/>. /// </summary> /// <returns>The wrapped metadata record.</returns> public MetadataRecord GetMetadata() { return m_metadata; } // Triggers the PropertyChanged event. private void OnPropertyChanged(string propertyName) { if ((object)PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } private string ValidateSynonym2(string synonym2) { return !string.IsNullOrEmpty(synonym2) ? synonym2.Trim() : "ALOG"; } private string FormatName(string name, string synonym1, string synonym2) { string[] parts; int lastIndexOf; if (string.IsNullOrEmpty(name)) return name; parts = name.Split(':'); if (parts.Length > 1) { // Separate name from point tag suffix name = parts[0]; switch (synonym2) { case "FLAG": return name; case "DIGI": case "ALOG": case "STAT": case "ALRM": lastIndexOf = synonym1.LastIndexOf('-'); if (lastIndexOf > 0) return name + ':' + synonym1.Substring(lastIndexOf + 1); return name + ':' + synonym2; default: lastIndexOf = name.LastIndexOf('-'); if (lastIndexOf > 0) return name.Substring(0, lastIndexOf) + ':' + name.Substring(lastIndexOf + 1); return name + ':' + synonym2; } } return name + ':' + synonym2; } #endregion } // Fields private readonly ICollection<ArchiveReader> m_archiveReaders; private readonly List<MetadataWrapper> m_metadata; private string[] m_tokens; private string m_currentSessionPath; private DateTime m_startTime; private DateTime m_endTime; private bool m_showDisabledPoints; private FileType m_exportFileType; private int m_exportFrameRate; private double m_exportNominalFrequency; private bool m_alignTimestampsInExport; private readonly ICollection<MenuItem> m_contextMenuItems; private readonly ICollection<string> m_visibleColumns; private ChartWindow m_chartWindow; #endregion #region [ Constructors ] /// <summary> /// Creates a new instance of the <see cref="MainWindow"/> class. /// </summary> public MainWindow() { m_archiveReaders = new List<ArchiveReader>(); m_metadata = new List<MetadataWrapper>(); m_contextMenuItems = new List<MenuItem>(); m_visibleColumns = new HashSet<string>(); InitializeComponent(); InitializeChartWindow(); m_exportFrameRate = 30; m_exportNominalFrequency = 60.0D; m_alignTimestampsInExport = true; m_currentTimeCheckBox.IsChecked = true; } #endregion #region [ Properties ] /// <summary> /// Gets or sets a boolean that determines whether an archive is open or not. /// </summary> public bool ArchiveIsOpen { get { return m_saveButton.IsEnabled; } set { m_saveButton.IsEnabled = value; m_saveMenuItem.IsEnabled = value; m_saveAsMenuItem.IsEnabled = value; m_trendButton.IsEnabled = value; m_trendMenuItem.IsEnabled = value; m_exportButton.IsEnabled = value; m_exportMenuItem.IsEnabled = value; ShowDisabledMenuItem.IsEnabled = value; } } /// <summary> /// Gets or sets the start time to be displayed on the graph or exported to CSV. /// </summary> public DateTime StartTime { get { return m_startTime; } set { m_startTime = value; m_startTimeDatePicker.SelectedDate = value; m_startTimeTextBox.Text = value.ToString("HH:mm:ss.fff"); } } /// <summary> /// Gets or sets the end time to be displayed on the graph or exported to CSV. /// </summary> public DateTime EndTime { get { return m_endTime; } set { m_endTime = value; m_endTimeDatePicker.SelectedDate = value; m_endTimeTextBox.Text = value.ToString("HH:mm:ss.fff"); } } #endregion #region [ Methods ] // Initializes the chart window. private void InitializeChartWindow() { if (m_chartWindow == null) { m_chartWindow = new ChartWindow(); m_chartWindow.ChartUpdated += ChartWindow_ChartUpdated; m_chartWindow.Closing += ChildWindow_Closing; TrySetChartInterval(null); } } // Gets a string representation of the start time to be used when reading from the archive. private string GetStartTime() { StringBuilder startTimeBuilder = new StringBuilder(); if (!m_currentTimeCheckBox.IsChecked.GetValueOrDefault()) { startTimeBuilder.Append(m_startTime.ToString("MM/dd/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture)); } else { startTimeBuilder.Append("*-"); startTimeBuilder.Append(m_currentTimeTextBox.Text); startTimeBuilder.Append(m_currentTimeComboBox.SelectionBoxItem.ToString()[0]); }Lines 1–500 of 1732. Load more
//****************************************************************************************************** // MainWindow.xaml.cs - Gbtc // // Copyright © 2012, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the MIT License (MIT), the "License"; you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/MIT // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 08/10/2010 - Stephen C. Wills // Generated original version of source code. // 12/18/2011 - J. Ritchie Carroll // Set likely default archive locations on initial startup and removed disabled points from the // display list. // 09/29/2012 - J. Ritchie Carroll // Updated to code to use roll-over yielding ArchiveReader. // 12/20/2012 - Starlynn Danyelle Gilliam // Modified Header. // //****************************************************************************************************** using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Text.RegularExpressions; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Xml.Linq; using GSF; using GSF.COMTRADE; using GSF.Historian; using GSF.Historian.Files; using GSF.IO; using GSF.Units.EE; using Microsoft.Win32; namespace HistorianView { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow { #region [ Members ] // Nested Types /// <summary> /// Defines a comparison class to property sort metadata. /// </summary> public class MetadataSorter : IComparer<MetadataWrapper> { /// <summary> /// Compares one metadata record to another. /// </summary> /// <param name="left">Left metadata record to compare.</param> /// <param name="right">Right metadata record to compare.</param> /// <returns>Comparison sort order of metadata record.</returns> public int Compare(MetadataWrapper left, MetadataWrapper right) { // Perform initial sort based on analogs followed by status flags, then digitals int result = ChannelMetadataSorter.Default.Compare(ConvertToChannelMetadata(left), ConvertToChannelMetadata(right)); // Fall back on historian ID for secondary sort order if (result == 0) result = left.PointNumber.CompareTo(right.PointNumber); return result; } /// <summary> /// Default instance of the metadata record sorter. /// </summary> public static readonly MetadataSorter Default = new MetadataSorter(); } /// <summary> /// This is a wrapper around a MetadataRecord that allows auto-generation /// of columns in the data grid based on the public properties of this class. /// </summary> public class MetadataWrapper : INotifyPropertyChanged { #region [ Members ] // Events /// <summary> /// Event triggered when a property is changed. /// </summary> public event PropertyChangedEventHandler PropertyChanged; // Fields private readonly ArchiveReader m_archiveReader; private readonly MetadataRecord m_metadata; private bool m_export; #endregion #region [ Constructors ] /// <summary> /// Creates a new instance of the <see cref="MetadataWrapper"/> class. /// </summary> /// <param name="archiveReader">The <see cref="ArchiveReader"/> that the metadata record came from.</param> /// <param name="metadata">The <see cref="MetadataRecord"/> to be wrapped.</param> public MetadataWrapper(ArchiveReader archiveReader, MetadataRecord metadata) { metadata.Synonym2 = ValidateSynonym2(metadata.Synonym2); m_archiveReader = archiveReader; m_metadata = metadata; } #endregion #region [ Properties ] /// <summary> /// Determines whether the measurement represented by this metadata record /// should be exported to CSV or displayed on the graph by the Historian Data Viewer. /// </summary> public bool Export { get { return m_export; } set { m_export = value; OnPropertyChanged("Export"); } } /// <summary> /// Gets the point number of the measurement. /// </summary> public int PointNumber { get { return m_metadata.HistorianID; } } /// <summary> /// Gets the name of the measurement. /// </summary> public string Name { get { // This formats name in accordance with COMTRADE standard Annex H (may need to make this optional) return FormatName(m_metadata.Name, m_metadata.Synonym1, m_metadata.Synonym2); } } /// <summary> /// Gets the point tag of the measurement. /// </summary> public string PointTag { get { return m_metadata.Name; } } /// <summary> /// Gets the description of the measurement. /// </summary> public string Description { get { return m_metadata.Description; } } /// <summary> /// Gets the first alternate name for the measurement. /// </summary> public string Synonym1 { get { return m_metadata.Synonym1; } } /// <summary> /// Gets the second alternate name for the measurement. /// </summary> public string Synonym2 { get { return m_metadata.Synonym2; } } /// <summary> /// Gets the third alternate name for the measurement. /// </summary> public string Synonym3 { get { return m_metadata.Synonym3; } } /// <summary> /// Gets the system name. /// </summary> public string System { get { return m_metadata.SystemName; } } /// <summary> /// Gets the low range of the measurement. /// </summary> public Single LowRange { get { return m_metadata.Summary.LowRange; } } /// <summary> /// Gets the high range of the measurement. /// </summary> public Single HighRange { get { return m_metadata.Summary.HighRange; } } /// <summary> /// Gets the engineering units used to measure the values. /// </summary> public string EngineeringUnits { get { return m_metadata.AnalogFields.EngineeringUnits; } } /// <summary> /// Gets the unit number of the measurement. /// </summary> public int Unit { get { return m_metadata.UnitNumber; } } #endregion #region [ Methods ] /// <summary> /// Returns the <see cref="ArchiveReader"/> that the metadata record came from. /// </summary> /// <returns>The archive reader.</returns> public ArchiveReader GetArchiveReader() { return m_archiveReader; } /// <summary> /// Returns the wrapped <see cref="MetadataRecord"/>. /// </summary> /// <returns>The wrapped metadata record.</returns> public MetadataRecord GetMetadata() { return m_metadata; } // Triggers the PropertyChanged event. private void OnPropertyChanged(string propertyName) { if ((object)PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } private string ValidateSynonym2(string synonym2) { return !string.IsNullOrEmpty(synonym2) ? synonym2.Trim() : "ALOG"; } private string FormatName(string name, string synonym1, string synonym2) { string[] parts; int lastIndexOf; if (string.IsNullOrEmpty(name)) return name; parts = name.Split(':'); if (parts.Length > 1) { // Separate name from point tag suffix name = parts[0]; switch (synonym2) { case "FLAG": return name; case "DIGI": case "ALOG": case "STAT": case "ALRM": lastIndexOf = synonym1.LastIndexOf('-'); if (lastIndexOf > 0) return name + ':' + synonym1.Substring(lastIndexOf + 1); return name + ':' + synonym2; default: lastIndexOf = name.LastIndexOf('-'); if (lastIndexOf > 0) return name.Substring(0, lastIndexOf) + ':' + name.Substring(lastIndexOf + 1); return name + ':' + synonym2; } } return name + ':' + synonym2; } #endregion } // Fields private readonly ICollection<ArchiveReader> m_archiveReaders; private readonly List<MetadataWrapper> m_metadata; private string[] m_tokens; private string m_currentSessionPath; private DateTime m_startTime; private DateTime m_endTime; private bool m_showDisabledPoints; private FileType m_exportFileType; private int m_exportFrameRate; private double m_exportNominalFrequency; private bool m_alignTimestampsInExport; private readonly ICollection<MenuItem> m_contextMenuItems; private readonly ICollection<string> m_visibleColumns; private ChartWindow m_chartWindow; #endregion #region [ Constructors ] /// <summary> /// Creates a new instance of the <see cref="MainWindow"/> class. /// </summary> public MainWindow() { m_archiveReaders = new List<ArchiveReader>(); m_metadata = new List<MetadataWrapper>(); m_contextMenuItems = new List<MenuItem>(); m_visibleColumns = new HashSet<string>(); InitializeComponent(); InitializeChartWindow(); m_exportFrameRate = 30; m_exportNominalFrequency = 60.0D; m_alignTimestampsInExport = true; m_currentTimeCheckBox.IsChecked = true; } #endregion #region [ Properties ] /// <summary> /// Gets or sets a boolean that determines whether an archive is open or not. /// </summary> public bool ArchiveIsOpen { get { return m_saveButton.IsEnabled; } set { m_saveButton.IsEnabled = value; m_saveMenuItem.IsEnabled = value; m_saveAsMenuItem.IsEnabled = value; m_trendButton.IsEnabled = value; m_trendMenuItem.IsEnabled = value; m_exportButton.IsEnabled = value; m_exportMenuItem.IsEnabled = value; ShowDisabledMenuItem.IsEnabled = value; } } /// <summary> /// Gets or sets the start time to be displayed on the graph or exported to CSV. /// </summary> public DateTime StartTime { get { return m_startTime; } set { m_startTime = value; m_startTimeDatePicker.SelectedDate = value; m_startTimeTextBox.Text = value.ToString("HH:mm:ss.fff"); } } /// <summary> /// Gets or sets the end time to be displayed on the graph or exported to CSV. /// </summary> public DateTime EndTime { get { return m_endTime; } set { m_endTime = value; m_endTimeDatePicker.SelectedDate = value; m_endTimeTextBox.Text = value.ToString("HH:mm:ss.fff"); } } #endregion #region [ Methods ] // Initializes the chart window. private void InitializeChartWindow() { if (m_chartWindow == null) { m_chartWindow = new ChartWindow(); m_chartWindow.ChartUpdated += ChartWindow_ChartUpdated; m_chartWindow.Closing += ChildWindow_Closing; TrySetChartInterval(null); } } // Gets a string representation of the start time to be used when reading from the archive. private string GetStartTime() { StringBuilder startTimeBuilder = new StringBuilder(); if (!m_currentTimeCheckBox.IsChecked.GetValueOrDefault()) { startTimeBuilder.Append(m_startTime.ToString("MM/dd/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture)); } else { startTimeBuilder.Append("*-"); startTimeBuilder.Append(m_currentTimeTextBox.Text); startTimeBuilder.Append(m_currentTimeComboBox.SelectionBoxItem.ToString()[0]); }