//******************************************************************************************************
// 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
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow
{
#region [ Members ]
// Nested Types
///
/// Defines a comparison class to property sort metadata.
///
public class MetadataSorter : IComparer
{
///
/// Compares one metadata record to another.
///
/// Left metadata record to compare.
/// Right metadata record to compare.
/// Comparison sort order of metadata record.
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;
}
///
/// Default instance of the metadata record sorter.
///
public static readonly MetadataSorter Default = new MetadataSorter();
}
///
/// 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.
///
public class MetadataWrapper : INotifyPropertyChanged
{
#region [ Members ]
// Events
///
/// Event triggered when a property is changed.
///
public event PropertyChangedEventHandler PropertyChanged;
// Fields
private readonly ArchiveReader m_archiveReader;
private readonly MetadataRecord m_metadata;
private bool m_export;
#endregion
#region [ Constructors ]
///
/// Creates a new instance of the class.
///
/// The that the metadata record came from.
/// The to be wrapped.
public MetadataWrapper(ArchiveReader archiveReader, MetadataRecord metadata)
{
metadata.Synonym2 = ValidateSynonym2(metadata.Synonym2);
m_archiveReader = archiveReader;
m_metadata = metadata;
}
#endregion
#region [ Properties ]
///
/// Determines whether the measurement represented by this metadata record
/// should be exported to CSV or displayed on the graph by the Historian Data Viewer.
///
public bool Export
{
get
{
return m_export;
}
set
{
m_export = value;
OnPropertyChanged("Export");
}
}
///
/// Gets the point number of the measurement.
///
public int PointNumber
{
get
{
return m_metadata.HistorianID;
}
}
///
/// Gets the name of the measurement.
///
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);
}
}
///
/// Gets the point tag of the measurement.
///
public string PointTag
{
get
{
return m_metadata.Name;
}
}
///
/// Gets the description of the measurement.
///
public string Description
{
get
{
return m_metadata.Description;
}
}
///
/// Gets the first alternate name for the measurement.
///
public string Synonym1
{
get
{
return m_metadata.Synonym1;
}
}
///
/// Gets the second alternate name for the measurement.
///
public string Synonym2
{
get
{
return m_metadata.Synonym2;
}
}
///
/// Gets the third alternate name for the measurement.
///
public string Synonym3
{
get
{
return m_metadata.Synonym3;
}
}
///
/// Gets the system name.
///
public string System
{
get
{
return m_metadata.SystemName;
}
}
///
/// Gets the low range of the measurement.
///
public Single LowRange
{
get
{
return m_metadata.Summary.LowRange;
}
}
///
/// Gets the high range of the measurement.
///
public Single HighRange
{
get
{
return m_metadata.Summary.HighRange;
}
}
///
/// Gets the engineering units used to measure the values.
///
public string EngineeringUnits
{
get
{
return m_metadata.AnalogFields.EngineeringUnits;
}
}
///
/// Gets the unit number of the measurement.
///
public int Unit
{
get
{
return m_metadata.UnitNumber;
}
}
#endregion
#region [ Methods ]
///
/// Returns the that the metadata record came from.
///
/// The archive reader.
public ArchiveReader GetArchiveReader()
{
return m_archiveReader;
}
///
/// Returns the wrapped .
///
/// The wrapped metadata record.
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 m_archiveReaders;
private readonly List 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