This commit is contained in:
2026-04-17 14:55:32 -04:00
commit bc3ac1d4c9
18017 changed files with 4371742 additions and 0 deletions

View File

@@ -0,0 +1,175 @@
<base:BaseView x:Class="DTS.Viewer.AddCalculatedChannel.AddCalculatedChannelView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:base="clr-namespace:DTS.Common.Base;assembly=DTS.Common"
xmlns:root="clr-namespace:DTS.Viewer.AddCalculatedChannel"
xmlns:toolkit="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:converters="clr-namespace:DTS.Common.Converters;assembly=DTS.Common"
xmlns:controls="clr-namespace:DTS.Common.Controls;assembly=DTS.Common"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<base:BaseView.Resources>
<Style TargetType="TextBox" BasedOn="{StaticResource PageContentTextBoxStyle}" />
<Style TargetType="TextBlock" BasedOn="{StaticResource PageContentTextStyle}" />
<Style TargetType="CheckBox" BasedOn="{StaticResource PageContentCheckBoxStyle}" />
<Style TargetType="PasswordBox" BasedOn="{StaticResource PageContentPasswordBoxStyle}" />
<Style TargetType="Button" BasedOn="{StaticResource FlatButton}"/>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<Style TargetType="toolkit:DoubleUpDown" BasedOn="{StaticResource PageContentXCDoubleUpDown}">
<Setter Property="Width" Value="150"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="FormatString" Value="N0"/>
<Setter Property="Increment" Value="1"/>
</Style>
<sys:Double x:Key="HIC_LENGTH_MIN">1</sys:Double>
<sys:Double x:Key="HIC_LENGTH_MAX">100</sys:Double>
</base:BaseView.Resources>
<Grid Background="{StaticResource Brush_ApplicationContentBackground}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- Page Title -->
<TextBlock Style="{StaticResource BaselineTextStyle4}" Text="{root:TranslateExtension AddCalculatedChannel}" Grid.Row="0"/>
<!-- Content-->
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto" MinWidth="480"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Channel Name-->
<TextBlock Grid.Column="0" Grid.Row="0" Text="{root:TranslateExtension ChannelName}"/>
<TextBox Grid.Column="1" Grid.Row="0" Text="{Binding ChannelName, Mode=TwoWay, FallbackValue=Integration}" x:Name="tbChannelName" MaxLength="100" />
<!-- Channel Description-->
<TextBlock Grid.Column="0" Grid.Row="1" Text="{root:TranslateExtension Description}" Visibility="Collapsed"/>
<TextBox Grid.Column="1" Grid.Row="1" Text="{Binding ChannelDescription, Mode=TwoWay}" IsEnabled="False" x:Name="tbChannelDescription" Visibility="Collapsed"/>
<!-- ISO Code-->
<TextBlock Grid.Column="0" Grid.Row="2" Text="{root:TranslateExtension ISOCode}"/>
<TextBox Grid.Column="1" Grid.Row="2" Text="{Binding IsoCode, Mode=TwoWay, FallbackValue=????????????????}" MaxLength="25"/>
<!-- Calculation Type -->
<TextBlock Grid.Column="0" Grid.Row="3" Text="{root:TranslateExtension Calculation}"/>
<ComboBox Grid.Column="1" Grid.Row="3" ItemsSource="{Binding CalculationList}" SelectedItem="{Binding SelectedCalculation}" /><!--SelectionChanged="cbCalculationList_SelectionChanged" x:Name="cbCalculationList"/>-->
<!--multiple channel selector-->
<TextBlock Grid.Column="0" Grid.Row="4" Visibility="{Binding MultipleChannelSelectorVisibility, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Visible}" Text="{root:TranslateExtension InputChannels}" VerticalAlignment="Top"/>
<!-- Single Channel Selector -->
<TextBlock Grid.Column="0" Grid.Row="4" Text="{root:TranslateExtension CalculationInputChannel}" Visibility="{Binding SingleChannelSelectorVisibility, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Collapsed}"/>
<ComboBox Grid.Column="1" Grid.Row="4" ItemsSource="{Binding ChannelList}" SelectedItem="{Binding SourceChannel}" Visibility="{Binding SingleChannelSelectorVisibility, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Collapsed}" />
<!--multiple channel selector-->
<ListView ItemsSource="{Binding ChannelListObjects}" Grid.Row="4" Grid.Column="1" Visibility="{Binding MultipleChannelSelectorVisibility, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Visible}"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListView.View>
<GridView>
<GridViewColumn Header=" " Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsThreeState="False" IsChecked="{Binding Path=IsIncluded}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension Channel}" DisplayMemberBinding="{Binding Path=DisplayName}" />
</GridView>
</ListView.View>
</ListView>
<!--ThreeDIRTRACC-->
<Grid Grid.Row="4" Grid.Column="0" Visibility="{Binding ThreeDIRTRACCVisibility, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Visibility.Collapsed}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Grid.RowSpan="3" Text="{root:TranslateExtension InputChannels}" />
</Grid>
<Grid Grid.Row="4" Grid.Column="1" Visibility="{Binding ThreeDIRTRACCVisibility, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Collapsed}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="{root:TranslateExtension ThreeD_IRTracc}" HorizontalAlignment="Right" VerticalAlignment="Center"/>
<TextBlock Grid.Column="0" Grid.Row="1" Text="{root:TranslateExtension ThreeD_RotPot1}" HorizontalAlignment="Right" VerticalAlignment="Center"/>
<TextBlock Grid.Column="0" Grid.Row="2" Text="{root:TranslateExtension ThreeD_RotPot2}" HorizontalAlignment="Right" VerticalAlignment="Center"/>
<ComboBox Grid.Row="0" ItemsSource="{Binding IRTraccChannelList}" SelectedItem="{Binding IRTraccChannel}" Grid.Column="1" DisplayMemberPath="DisplayName"/>
<ComboBox Grid.Row="1" ItemsSource="{Binding Pot1ChannelList}" SelectedItem="{Binding Pot1Channel}" Grid.Column="1" DisplayMemberPath="DisplayName" />
<ComboBox Grid.Row="2" ItemsSource="{Binding Pot2ChannelList}" SelectedItem="{Binding Pot2Channel}" Grid.Column="1" DisplayMemberPath="DisplayName" />
</Grid>
<!--HIC-->
<StackPanel Grid.Row="4" Grid.Column="0" Orientation="Vertical" Visibility="{Binding HICChannelSelectorVisibility, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Visibility.Collapsed}">
<TextBlock Grid.Row="0" Text="{root:TranslateExtension ClipLengthMS}" />
<TextBlock Grid.Row="1" Text="{root:TranslateExtension HICAccelerationX}" />
<TextBlock Grid.Row="2" Text="{root:TranslateExtension HICAccelerationY}" />
<TextBlock Grid.Row="3" Text="{root:TranslateExtension HICAccelerationZ}" />
</StackPanel>
<StackPanel Grid.Row="4" Grid.Column="1" Visibility="{Binding HICChannelSelectorVisibility, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Collapsed}">
<toolkit:DoubleUpDown Grid.Column="0" Grid.Row="0"
Minimum="{StaticResource HIC_LENGTH_MIN}" Maximum="{StaticResource HIC_LENGTH_MAX}"
Value="{Binding HICLength}" />
<ComboBox Grid.Column="0" Grid.Row="1" ItemsSource="{Binding AvailableHICChannels}" DisplayMemberPath="DisplayName"
AutomationProperties.AutomationId="HICAccelerationXComboBox"
SelectedItem="{Binding HICAccelerationX}" />
<ComboBox Grid.Column="0" Grid.Row="2" ItemsSource="{Binding AvailableHICChannels}" DisplayMemberPath="DisplayName" AutomationProperties.AutomationId="HICAccelerationYComboBox"
SelectedItem="{Binding HICAccelerationY}" />
<ComboBox Grid.Column="0" Grid.Row="3" ItemsSource="{Binding AvailableHICChannels}" DisplayMemberPath="DisplayName" AutomationProperties.AutomationId="HICAccelerationZComboBox"
SelectedItem="{Binding HICAccelerationZ}" />
</StackPanel>
</Grid>
</Grid>
</base:BaseView>

View File

@@ -0,0 +1,387 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace DTS.Viewer.AddCalculatedChannel.Resources {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class StringResources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal StringResources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DTS.Viewer.AddCalculatedChannel.Resources.StringResources", typeof(StringResources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Add Calculated Channel.
/// </summary>
internal static string AddCalculatedChannel {
get {
return ResourceManager.GetString("AddCalculatedChannel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Average.
/// </summary>
internal static string CalculatedChannel_Average {
get {
return ResourceManager.GetString("CalculatedChannel_Average", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 3D IR-TRACC (upper thorax).
/// </summary>
internal static string CalculatedChannel_IRTRACC3D {
get {
return ResourceManager.GetString("CalculatedChannel_IRTRACC3D", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 3D IR-TRACC (abdomen).
/// </summary>
internal static string CalculatedChannel_IRTRACC3D_Abdomen {
get {
return ResourceManager.GetString("CalculatedChannel_IRTRACC3D_Abdomen", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 3D IR-TRACC (lower thorax).
/// </summary>
internal static string CalculatedChannel_IRTRACC3D_LowerThorax {
get {
return ResourceManager.GetString("CalculatedChannel_IRTRACC3D_LowerThorax", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 3D IR-TRACC (thorax).
/// </summary>
internal static string CalculatedChannel_IRTRACC3D_Thorax {
get {
return ResourceManager.GetString("CalculatedChannel_IRTRACC3D_Thorax", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 3D IR-TRACC (abdomen).
/// </summary>
internal static string CalculatedChannel_IRTRACC3DAbdomen {
get {
return ResourceManager.GetString("CalculatedChannel_IRTRACC3DAbdomen", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 3D IR-TRACC (lower thorax).
/// </summary>
internal static string CalculatedChannel_IRTRACC3DLowerThorax {
get {
return ResourceManager.GetString("CalculatedChannel_IRTRACC3DLowerThorax", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sum.
/// </summary>
internal static string CalculatedChannel_Sum {
get {
return ResourceManager.GetString("CalculatedChannel_Sum", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Calculation.
/// </summary>
internal static string Calculation {
get {
return ResourceManager.GetString("Calculation", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cosine.
/// </summary>
internal static string CALCULATION_Cos {
get {
return ResourceManager.GetString("CALCULATION_Cos", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Derivative.
/// </summary>
internal static string CALCULATION_Derivative {
get {
return ResourceManager.GetString("CALCULATION_Derivative", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Double integral.
/// </summary>
internal static string CALCULATION_DoubleIntegral {
get {
return ResourceManager.GetString("CALCULATION_DoubleIntegral", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Integral.
/// </summary>
internal static string CALCULATION_Integral {
get {
return ResourceManager.GetString("CALCULATION_Integral", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sine.
/// </summary>
internal static string CALCULATION_Sin {
get {
return ResourceManager.GetString("CALCULATION_Sin", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 3D IR-TRACC (upper thorax).
/// </summary>
internal static string CALCULATION_ThreeDIRTracc {
get {
return ResourceManager.GetString("CALCULATION_ThreeDIRTracc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 3D IR-TRACC (abdomen).
/// </summary>
internal static string CALCULATION_ThreeDIRTraccAbdomen {
get {
return ResourceManager.GetString("CALCULATION_ThreeDIRTraccAbdomen", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 3D IR-TRACC (lower thorax).
/// </summary>
internal static string CALCULATION_ThreeDIRTraccLowerThorax {
get {
return ResourceManager.GetString("CALCULATION_ThreeDIRTraccLowerThorax", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Calculation Input Channel.
/// </summary>
internal static string CalculationInputChannel {
get {
return ResourceManager.GetString("CalculationInputChannel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Channel.
/// </summary>
internal static string Channel {
get {
return ResourceManager.GetString("Channel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Channel Name.
/// </summary>
internal static string ChannelName {
get {
return ResourceManager.GetString("ChannelName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Clip length (ms).
/// </summary>
internal static string ClipLengthMS {
get {
return ResourceManager.GetString("ClipLengthMS", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Description.
/// </summary>
internal static string Description {
get {
return ResourceManager.GetString("Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Acceleration X.
/// </summary>
internal static string HICAccelerationX {
get {
return ResourceManager.GetString("HICAccelerationX", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Acceleration Y.
/// </summary>
internal static string HICAccelerationY {
get {
return ResourceManager.GetString("HICAccelerationY", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to AccelerationZ.
/// </summary>
internal static string HICAccelerationZ {
get {
return ResourceManager.GetString("HICAccelerationZ", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error: Head injury criterion requires 3 channels.
/// </summary>
internal static string HICRequires3Channels {
get {
return ResourceManager.GetString("HICRequires3Channels", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Input channels.
/// </summary>
internal static string InputChannels {
get {
return ResourceManager.GetString("InputChannels", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to ISO Code.
/// </summary>
internal static string ISOCode {
get {
return ResourceManager.GetString("ISOCode", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error: No channels included.
/// </summary>
internal static string NoChannelsIncluded {
get {
return ResourceManager.GetString("NoChannelsIncluded", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error: Units don&apos;t match for all input channels.
/// </summary>
internal static string ResultantUnitsDontMatch {
get {
return ResourceManager.GetString("ResultantUnitsDontMatch", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error: Sample rates don&apos;t match for all input channels.
/// </summary>
internal static string SampleRatesDontMatch {
get {
return ResourceManager.GetString("SampleRatesDontMatch", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Calculation contains multiple sample rates. Input will be resampled to the highest sample rate using linear interpolation..
/// </summary>
internal static string SuperSamplingWarning {
get {
return ResourceManager.GetString("SuperSamplingWarning", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to IR-TRACC.
/// </summary>
internal static string ThreeD_IRTracc {
get {
return ResourceManager.GetString("ThreeD_IRTracc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to R. Pot Y.
/// </summary>
internal static string ThreeD_RotPot1 {
get {
return ResourceManager.GetString("ThreeD_RotPot1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to R. Pot Z.
/// </summary>
internal static string ThreeD_RotPot2 {
get {
return ResourceManager.GetString("ThreeD_RotPot2", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,228 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AddCalculatedChannel" xml:space="preserve">
<value>Add Calculated Channel</value>
</data>
<data name="Calculation" xml:space="preserve">
<value>Calculation</value>
</data>
<data name="CalculationInputChannel" xml:space="preserve">
<value>Calculation Input Channel</value>
</data>
<data name="Channel" xml:space="preserve">
<value>Channel</value>
</data>
<data name="ChannelName" xml:space="preserve">
<value>Channel Name</value>
</data>
<data name="Description" xml:space="preserve">
<value>Description</value>
</data>
<data name="InputChannels" xml:space="preserve">
<value>Input channels</value>
</data>
<data name="ISOCode" xml:space="preserve">
<value>ISO Code</value>
</data>
<data name="CalculatedChannel_Average" xml:space="preserve">
<value>Average</value>
</data>
<data name="CalculatedChannel_IRTRACC3D" xml:space="preserve">
<value>3D IR-TRACC (upper thorax)</value>
</data>
<data name="CalculatedChannel_IRTRACC3DAbdomen" xml:space="preserve">
<value>3D IR-TRACC (abdomen)</value>
</data>
<data name="CalculatedChannel_IRTRACC3DLowerThorax" xml:space="preserve">
<value>3D IR-TRACC (lower thorax)</value>
</data>
<data name="CalculatedChannel_IRTRACC3D_Abdomen" xml:space="preserve">
<value>3D IR-TRACC (abdomen)</value>
</data>
<data name="CalculatedChannel_IRTRACC3D_LowerThorax" xml:space="preserve">
<value>3D IR-TRACC (lower thorax)</value>
</data>
<data name="CalculatedChannel_IRTRACC3D_Thorax" xml:space="preserve">
<value>3D IR-TRACC (thorax)</value>
</data>
<data name="CalculatedChannel_Sum" xml:space="preserve">
<value>Sum</value>
</data>
<data name="CALCULATION_Cos" xml:space="preserve">
<value>Cosine</value>
</data>
<data name="CALCULATION_Derivative" xml:space="preserve">
<value>Derivative</value>
</data>
<data name="CALCULATION_DoubleIntegral" xml:space="preserve">
<value>Double integral</value>
</data>
<data name="CALCULATION_Integral" xml:space="preserve">
<value>Integral</value>
</data>
<data name="CALCULATION_Sin" xml:space="preserve">
<value>Sine</value>
</data>
<data name="CALCULATION_ThreeDIRTracc" xml:space="preserve">
<value>3D IR-TRACC (upper thorax)</value>
</data>
<data name="CALCULATION_ThreeDIRTraccAbdomen" xml:space="preserve">
<value>3D IR-TRACC (abdomen)</value>
</data>
<data name="CALCULATION_ThreeDIRTraccLowerThorax" xml:space="preserve">
<value>3D IR-TRACC (lower thorax)</value>
</data>
<data name="ThreeD_IRTracc" xml:space="preserve">
<value>IR-TRACC</value>
</data>
<data name="ThreeD_RotPot1" xml:space="preserve">
<value>R. Pot Y</value>
</data>
<data name="ThreeD_RotPot2" xml:space="preserve">
<value>R. Pot Z</value>
</data>
<data name="SuperSamplingWarning" xml:space="preserve">
<value>Calculation contains multiple sample rates. Input will be resampled to the highest sample rate using linear interpolation.</value>
</data>
<data name="ClipLengthMS" xml:space="preserve">
<value>Clip length (ms)</value>
</data>
<data name="HICAccelerationX" xml:space="preserve">
<value>Acceleration X</value>
</data>
<data name="HICAccelerationY" xml:space="preserve">
<value>Acceleration Y</value>
</data>
<data name="HICAccelerationZ" xml:space="preserve">
<value>AccelerationZ</value>
</data>
<data name="HICRequires3Channels" xml:space="preserve">
<value>Error: Head injury criterion requires 3 channels</value>
</data>
<data name="NoChannelsIncluded" xml:space="preserve">
<value>Error: No channels included</value>
</data>
<data name="ResultantUnitsDontMatch" xml:space="preserve">
<value>Error: Units don't match for all input channels</value>
</data>
<data name="SampleRatesDontMatch" xml:space="preserve">
<value>Error: Sample rates don't match for all input channels</value>
</data>
</root>

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DTS.Viewer.AddCalculatedChannel")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DTS.Viewer.AddCalculatedChannel")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("6451f3ed-934e-47e3-a1ca-33c223a6507a")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,21 @@
using System;
using System.Windows.Markup;
using DTS.Viewer.AddCalculatedChannel.Resources;
namespace DTS.Viewer.AddCalculatedChannel
{
[MarkupExtensionReturnType(typeof(string))]
public class TranslateExtension : MarkupExtension
{
private readonly string _key;
public TranslateExtension(string key) { _key = key; }
private const string NotFound = "#stringnotfound#";
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (string.IsNullOrEmpty(_key)) { return NotFound; }
return StringResources.ResourceManager.GetString(_key) ?? NotFound + " " + _key;
}
}
}

View File

@@ -0,0 +1,969 @@
using DTS.Common.Enums.Sensors;
using DTS.Common.Utilities.Logging;
using DTS.Common.Utils;
using DTS.Serialization;
using DTS.Slice.Control;
using DTS.Common;
using DTS.Common.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using static DTS.Viewer.AddCalculatedChannel.AddCalculatedChannelViewModel;
using Prism.Ioc;
using DTS.Common.Calculations;
using DTS.Common.Utilities;
using Prism.Events;
namespace DTS.Viewer.AddCalculatedChannel.Model
{
public class CalculatedChannelCreator
{
private static readonly int ChannelNumberCalculationChannelIndicator = 100000;
public static Test.Module.CalculatedChannel[] CreateChannels(string testId,
string folder,
Calculation calculation,
List<Test.Module.Channel> inputChannels,
string channelName,
int startingNumber,
List<Test.Module.Channel> allChannels,
int clipLength,
out List<string> errorList,
int defaultEncoding)
{
Test.Module.CalculatedChannel[] calculatedChannels = null;
errorList = new List<string>();
switch (calculation)
{
case Calculation.ThreeDIRTracc: calculatedChannels = Create3DIRTraccChannels(testId, folder, inputChannels, channelName, ThreeDIRTraccType.Thorax, startingNumber, defaultEncoding); break;
case Calculation.ThreeDIRTraccLowerThorax: calculatedChannels = Create3DIRTraccChannels(testId, folder, inputChannels, channelName, ThreeDIRTraccType.LowerThorax, startingNumber, defaultEncoding); break;
case Calculation.ThreeDIRTraccAbdomen: calculatedChannels = Create3DIRTraccChannels(testId, folder, inputChannels, channelName, ThreeDIRTraccType.Abdomen, startingNumber, defaultEncoding); break;
case Calculation.SUM:
case Calculation.AVE:
case Calculation.Resultant:
case Calculation.HIC:
calculatedChannels = CreateChannelsAggregateOperation(testId, folder, calculation, inputChannels, channelName, startingNumber, clipLength);
break;
default: calculatedChannels = CreateChannelsBinaryOperation(testId, folder, calculation, inputChannels, channelName, startingNumber); break;
}
if (null == calculatedChannels) return null;
for (var i = 0; i < calculatedChannels.Length; i++)
{
calculatedChannels[i].AbsoluteDisplayOrder = startingNumber + i;
}
if (ValidateChannelName(channelName, inputChannels, allChannels, out errorList)) return calculatedChannels;
//ReportErrors(errorList);
return null;
}
private static Serialization.SliceRaw.File.PersistentChannel CreatePersistentInformationObject(Test.Module.CalculatedChannel channel, string filepath)
{
var channelHeader = new Serialization.SliceRaw.File.BinaryChannelHeader
{
NumberOfTriggers = (ushort)(channel.ParentModule.TriggerSampleNumbers.Count)
};
channelHeader.TriggerSampleNumbers = new ulong[channelHeader.NumberOfTriggers];
// Do trigger sample information.
for (var i = 0; i < channelHeader.NumberOfTriggers; i++)
{
channelHeader.TriggerSampleNumbers[i] = channel.ParentModule.TriggerSampleNumbers[i];
}
// Do EU information.
if (channel is Common.DAS.Concepts.DAS.Channel.IEngineeringUnitAware)
{ //
// Persistent object property accessors already pad out EU so data will be word-aligned,
// so we'll want to make sure we do the same thing here.
//
var eu = (channel as Common.DAS.Concepts.DAS.Channel.IEngineeringUnitAware).EngineeringUnits;
var paddedEu = (1 == eu.Length % 2) ? (eu.Clone() as string).PadRight(eu.Length + 1, ' ') : eu;
channelHeader.EuFieldLengthWithTerminator = (ushort)(paddedEu.Length + 1);
channelHeader.EngineeringUnit = new char[channelHeader.EuFieldLengthWithTerminator - 1];
for (var j = 0; j < channelHeader.EuFieldLengthWithTerminator - 1; j++)
{
channelHeader.EngineeringUnit[j] = paddedEu[j];
}
}
else
{
channelHeader.EuFieldLengthWithTerminator = 1;
channelHeader.EngineeringUnit = new char[0];
}
// Do ISO code information.
channelHeader.IsoCode = new char[16];
// Make sure memory-mapped file does NOT exist (persistent channel object will overwrite header but append data
// after old file data... don't want that!)
if (System.IO.File.Exists(filepath))
{
GC.Collect();
FileUtils.DeleteFileOrMove(filepath, APILogger.Log);
////Rename existing channel file and kick off thread that will deleted it some time later. This needs to
////happen in this case as the test tree still contains references to the original file and it can't be deleted
////here. After a new channel is added, the old one is removed. The worker thread should wait long enough for that
////to happen (or better, check to see when it does) and then delete the file. This should eliminate the File.IO
////Exception that was being thrown.
//string tmpfilepath = filepath + ".bak";
//APILogger.Log("Renaming: " + filepath + " to " + tmpfilepath + " and deferring deletion.");
//System.IO.Path.ChangeExtension(filepath, Guid.NewGuid().ToString());
//System.Threading.ThreadPool.QueueUserWorkItem(DeleteChannelFile, tmpfilepath);
}
// Create the persistent channel object and return it.
return new Serialization.SliceRaw.File.PersistentChannel(filepath, channelHeader, true);
}
/// <summary>
/// this function takes a calculation and a list of input channels and returns
/// a list of doubles that is the output of doing that calculation
/// </summary>
/// <param name="calculation"></param>
/// <param name="channels"></param>
/// <returns></returns>
private static IList<double> PerformCalculationsAggregate(Calculation calculation,
List<Test.Module.Channel> channels)
{
var maxSampleRate = channels.Select(ch => ch.ParentModule.SampleRateHz).Max();
//this will hold the unfiltered input data for all the input channels
var unfilteredDataEU = new List<List<double>>();
//this will hold the output data
var dOutput = new List<double>();
//this will hold the emc channel data for the input channels (the input channels already have this data
//but keeping a local reference here removes some repeated casting that we'd have to do
var emcChannels = new List<Event.Module.Channel>();
//we may have different start times and the sample indices may not align, if we pick the first channel as a reference
//channel, then we can keep track of the delta for each channels start and the reference channel start in terms of samples
foreach (var ch in channels)
{
var emc = ch.emc as Event.Module.Channel;
emcChannels.Add(emc);
var data = emc.GetUnfilteredDataEu();
unfilteredDataEU.Add(data);
var start = GetTimeOfFirstSample(emc);
}
//any aggregate channels (SUM/AVE) just keep a single double and update it as needed while processing samples
var dAggregateValue = 0D;
var bAdd = true;
var currentChannelSampleIndex = 0;
//to properly aggregate, we need to put both datasets to the right sample rate
//using interpolation
//we need to calculate the min/max time across all channels and then
//the specific min of each channel, this tells us how to align data
var minStart = channels.Select(ch => ((double)ch.ParentModule.TriggerSampleNumbers[0] - ch.ParentModule.StartRecordSampleNumber) / ch.ParentModule.SampleRateHz).Min();
var minEnd = double.MaxValue;
var channelOffsetStarts = new List<int>();
var rates = new List<double>();
for (int i = 0; i < channels.Count; i++)
{
var ch = channels[i];
var chStart = ((double)ch.ParentModule.TriggerSampleNumbers[0] - ch.ParentModule.StartRecordSampleNumber) / ch.ParentModule.SampleRateHz;
var channelOffsetStart = (int)((chStart - minStart) * ch.ParentModule.SampleRateHz);
channelOffsetStarts.Add(channelOffsetStart);
var chEnd = ch.ParentModule.NumberOfSamples - chStart * ch.ParentModule.SampleRateHz;
minEnd = Math.Min(minEnd, chEnd / ch.ParentModule.SampleRateHz);
var rate = maxSampleRate / ch.ParentModule.SampleRateHz;
rates.Add(rate);
}
minStart = -1D * Math.Truncate(1000D * minStart) / 1000D;
minEnd = Math.Truncate(1000D * minEnd) / 1000D;
var totalSamples = Convert.ToInt32(Math.Floor((minEnd - minStart) * maxSampleRate));
for (var iSampleIDX = 0; iSampleIDX < totalSamples; iSampleIDX++)
{
var timeAtIndex =
dAggregateValue = 0;
bAdd = true;
var dSumSquares = 0D;
for (var iChannel = 0; iChannel < emcChannels.Count; iChannel++)
{
var rate = rates[iChannel];
var indexAtCurrentTime = (iSampleIDX - channelOffsetStarts[iChannel]) / rate;
var thisChannelsIndexAtCurrentTime = Convert.ToInt32(Math.Floor(indexAtCurrentTime));
var step = Convert.ToInt32(Math.Ceiling(indexAtCurrentTime) - thisChannelsIndexAtCurrentTime);
if (currentChannelSampleIndex < 0 || currentChannelSampleIndex >= unfilteredDataEU[iChannel].Count)
{
bAdd = false;
break;
}
var dataAtPoint = unfilteredDataEU[iChannel][thisChannelsIndexAtCurrentTime];
var increment = 0D;
if ((1 + thisChannelsIndexAtCurrentTime) < unfilteredDataEU[iChannel].Count)
{
increment = (unfilteredDataEU[iChannel][1 + thisChannelsIndexAtCurrentTime] - dataAtPoint) / rate;
}
else
{
increment = (dataAtPoint - unfilteredDataEU[iChannel][thisChannelsIndexAtCurrentTime - 1]) / rate;
}
dataAtPoint += (increment * step);
dAggregateValue += dataAtPoint;
//HIC must be in g's
if (calculation == Calculation.HIC)
{
if (((Event.Module.AnalogInputChannel)emcChannels[iChannel]).EngineeringUnits.ToLower().Trim() != "g")
{
//convert from m/sec^2 to g
dataAtPoint *= 9.80665D;
}
}
dSumSquares += Math.Pow(dataAtPoint, 2);
}
if (!bAdd) continue;
switch (calculation)
{
case Calculation.AVE: dOutput.Add(dAggregateValue / channels.Count); break;
case Calculation.SUM: dOutput.Add(dAggregateValue); break;
case Calculation.Resultant:
case Calculation.HIC:
dOutput.Add(Math.Sqrt(dSumSquares));
break;
}
}
return dOutput;
}
/// <summary>
/// performs calculations for a binary calculation channel (integrate/differentiate/FFT, etc)
/// </summary>
/// <param name="calculation"></param>
/// <param name="channel"></param>
/// <returns></returns>
private static IList<double> PerformCalculationBinary(Calculation calculation, Event.Module.Channel channel)
{
var data = channel.GetUnfilteredDataEu();
var sampleRate = Convert.ToInt32(channel.ParentModule.SampleRateHz);
switch (calculation)
{
case Calculation.Integral:
{
var db = new ClonableDoubles();
db.AddRange(data.ToArray());
var integral = new Common.Utilities.Math.Nhtsa.Integration(db, sampleRate);
return integral.Range;
}
case Calculation.DoubleIntegral:
{
var db = new ClonableDoubles();
db.AddRange(data.ToArray());
var integral = new Common.Utilities.Math.Nhtsa.Integration(db, sampleRate);
db = new ClonableDoubles();
db.AddRange(integral.Range);
var doubleIntegral = new Common.Utilities.Math.Nhtsa.Integration(db, sampleRate);
return doubleIntegral.Range;
}
case Calculation.Derivative:
{
var db = new ClonableDoubles();
db.AddRange(data.ToArray());
var derivative = new Common.Utilities.Math.Nhtsa.Differentiation(db, sampleRate);
return derivative.Range;
}
case Calculation.Sin:
{
return channel.DataEu.Select(euSample => Math.Sin(euSample)).ToList();
}
case Calculation.Cos:
{
return channel.DataEu.Select(euSample => Math.Cos(euSample)).ToList();
}
}
return new List<double>();
}
private static Test.Module.CalculatedChannel CreateCalculatedChannelsIRTRACC(Calculation calculation, Test.Module.Channel[] inputChannels)
{
switch (calculation)
{
case Calculation.ThreeDIRTracc:
case Calculation.ThreeDIRTraccAbdomen:
case Calculation.ThreeDIRTraccLowerThorax:
return Test.Module.CalculatedChannel.CreateInstance(new[]
{
inputChannels[0],
inputChannels[1],
inputChannels[2]
});
default:
return Test.Module.CalculatedChannel.CreateInstance(inputChannels[0]);
}
}
//private Event.Module.Channel GetSourceEMC()
//{
// switch (_calculation)
// {
// case Calculation.ThreeDIRTracc:
// case Calculation.ThreeDIRTraccAbdomen:
// case Calculation.ThreeDIRTraccLowerThorax:
// return
// (cbIRTracc.SelectedItem as ChannelHelper).MyChannel.emc as Event.Module.Channel;
// default:
// return _sourceChannel.emc as Event.Module.Channel;
// }
//}
//private static void DeleteChannelFile(object filepath)
//{
// FileUtils.DeleteFileOrMove((string)filepath, APILogger.Log);
//}
/// <summary>
/// performs the IR-Tracc 3D calculation
/// based on issue
/// 7489 Implement 2D/3D IRTRACC support
/// </summary>
/// <param name="dAX"></param>
/// <param name="dAY"></param>
/// <param name="dAZ"></param>
/// <param name="dOut"></param>
private static void PerformCalculation(out IList<double> dAX, out IList<double> dAY, out IList<double> dAZ, out IList<double> dOut,
Test.Module.Channel irTraccChannel, Test.Module.Channel rPot1Channel, Test.Module.Channel rPot2Channel, ThreeDIRTraccType irtraccType)
{
var maxRate = Math.Max(rPot1Channel.ParentModule.SampleRateHz, rPot2Channel.ParentModule.SampleRateHz);
maxRate = Math.Max(maxRate, irTraccChannel.ParentModule.SampleRateHz);
var irtraccEMC = irTraccChannel.emc as Event.Module.Channel;
var rPot1EMC = rPot1Channel.emc as Event.Module.Channel;
var rPot2EMC = rPot2Channel.emc as Event.Module.Channel;
if (0 != maxRate % rPot1Channel.ParentModule.SampleRateHz) { throw new InvalidOperationException($"Sample rate: {maxRate} is not a multiple of sample rate: {rPot1Channel.ParentModule.SampleRateHz}"); }
if (0 != maxRate % rPot2Channel.ParentModule.SampleRateHz) { throw new InvalidOperationException($"Sample rate: {maxRate} is not a multiple of sample rate: {rPot2Channel.ParentModule.SampleRateHz}"); }
if (0 != maxRate % irTraccChannel.ParentModule.SampleRateHz) { throw new InvalidOperationException($"Sample rate: {maxRate} is not a multiple of sample rate: {irTraccChannel.ParentModule.SampleRateHz}"); }
//this is the EU data for each channel NOTE - ALL CHANNELS MUST NOT BE USING ZEROING!!! (we handle zeroing already below)
var irTraccEUData = irtraccEMC.GetUnfilteredDataEu();
DiskUtility.ReplaceDataIfNeeded(ref irTraccEUData, "DISPLEU.txt");
//var irTraccmVData = irtraccEMC.GetUnfilteredDataMV();
var rPot1EUData = rPot1EMC.GetUnfilteredDataEu();
DiskUtility.ReplaceDataIfNeeded(ref rPot1EUData, "YPOTEU.txt");
var rPot2EUData = rPot2EMC.GetUnfilteredDataEu();
DiskUtility.ReplaceDataIfNeeded(ref rPot2EUData, "ZPOTEU.txt");
//this calculates start time for each channel
var startIRTracc = (double)(irTraccChannel.ParentModule.TriggerSampleNumbers[0] - irTraccChannel.ParentModule.StartRecordSampleNumber) / irTraccChannel.ParentModule.SampleRateHz;
startIRTracc = -1D * Math.Truncate(startIRTracc * 1000D) / 1000D;
var startRPot1 = (double)(rPot1Channel.ParentModule.TriggerSampleNumbers[0] - rPot1Channel.ParentModule.StartRecordSampleNumber) / rPot1Channel.ParentModule.SampleRateHz;
startRPot1 = -1D * Math.Truncate(startRPot1 * 1000D) / 1000D;
var startRPot2 = (double)(rPot2Channel.ParentModule.TriggerSampleNumbers[0] - rPot2Channel.ParentModule.StartRecordSampleNumber) / rPot2Channel.ParentModule.SampleRateHz;
startRPot2 = -1D * Math.Truncate(startRPot2 * 1000D) / 1000D;
//this calculates the end for each channel
var endIRTracc = (irTraccChannel.ParentModule.NumberOfSamples + startIRTracc * irTraccChannel.ParentModule.SampleRateHz) / irTraccChannel.ParentModule.SampleRateHz;
endIRTracc = Math.Truncate(endIRTracc * 1000D) / 1000D;
var endRPot1 = (rPot1Channel.ParentModule.NumberOfSamples + startRPot1 * rPot1Channel.ParentModule.SampleRateHz) / rPot1Channel.ParentModule.SampleRateHz;
endRPot1 = Math.Truncate(endRPot1 * 1000D) / 1000D;
var endRPot2 = (rPot2Channel.ParentModule.NumberOfSamples + startRPot2 * rPot2Channel.ParentModule.SampleRateHz) / rPot2Channel.ParentModule.SampleRateHz;
endRPot2 = Math.Truncate(endRPot2 * 1000D) / 1000D;
//here we select the latest start between channels
var start = Math.Max(startIRTracc, startRPot1);
start = Math.Max(start, startRPot2);
//here we find the earliest end between the channels
var end = Math.Min(endIRTracc, endRPot1);
end = Math.Min(end, endRPot2);
// we will super sample to the highest sample rate, and use a common start/stop between all channels.
var length = Convert.ToInt32(Math.Floor((end - start) * maxRate));
//these are the containers for our output data
dAX = new List<double>(length);
dAY = new List<double>(length);
dAZ = new List<double>(length);
dOut = new List<double>(length);
var aicIRTRACC = irTraccChannel as Test.Module.AnalogInputChannel;
var aicRPot1 = rPot1Channel as Test.Module.AnalogInputChannel;
var aicRPOT2 = rPot2Channel as Test.Module.AnalogInputChannel;
//calculates the rate of each channel relative to the highest rate of any of the channels
var rateIRTracc = Convert.ToInt32(Math.Ceiling(maxRate / irTraccChannel.ParentModule.SampleRateHz));
var rateRPot1 = Convert.ToInt32(Math.Ceiling(maxRate / rPot1Channel.ParentModule.SampleRateHz));
var rateRPot2 = Convert.ToInt32(Math.Ceiling(maxRate / rPot2Channel.ParentModule.SampleRateHz));
var R0 = aicIRTRACC.LinearizationFormula.CalibrationFactor * Math.Pow(aicIRTRACC.ZeroPoint, aicIRTRACC.LinearizationFormula.LinearizationExponent);
//we are converting to volt as sensitivity is in mV/V and our original calculation is in deg/V/V
var θy0 = aicRPot1.InitialEu; //((1000D/aicRPot1.Sensitivity)/aicRPot1.FactoryExcitationVoltage)*aicRPot1.ZeroPoint;
var θz0 = aicRPOT2.InitialEu; //((1000D/aicRPOT2.Sensitivity)/aicRPOT2.FactoryExcitationVoltage)*aicRPOT2.ZeroPoint;
//all the formulas use the first data point to zero the output channel data, these variables will hold that zero data for out output channels
//this is columns V through Y
var xa1_0 = double.NaN;
var ya1_0 = double.NaN;
var za1_0 = double.NaN;
var dOut_0 = double.NaN;
//your delta and D0 are dependent on your 3D-IRTRACC type, we get the constant for each type from the config file
var δ = 0D;
var D0 = 0D;
switch (irtraccType)
{
case ThreeDIRTraccType.Abdomen:
δ = SensorConstants.δAbdomen;
D0 = SensorConstants.D0Abdomen;
break;
case ThreeDIRTraccType.Thorax:
δ = SensorConstants.δThorax;
D0 = SensorConstants.D0Thorax;
break;
case ThreeDIRTraccType.LowerThorax:
δ = SensorConstants.δThoraxLower;
D0 = SensorConstants.D0ThoraxLower;
break;
default:
throw new NotSupportedException("unsupported irtracc type: " + irtraccType.ToString());
}
//calculates the offset in samples for each channels start relative to the
//latest common start time between channels
var irTraccOffsetStart = (int)(startIRTracc - start) * irTraccChannel.ParentModule.SampleRateHz;
var rPot1OffsetStart = (int)(startRPot1 - start) * rPot1Channel.ParentModule.SampleRateHz;
var rPot2OffsetStart = (int)(startRPot2 - start) * rPot2Channel.ParentModule.SampleRateHz;
//go through all samples in the output, calculate the index for each channel and do some calcs
for (var i = 0; i < length; i++)
{
//this is the index for the given time, this index could be theoretical
//and doesn't exist (ie 1.5)
var indexAtCurrentTimeIRTracc = (i - irTraccOffsetStart) / rateIRTracc;
//this is the actual index that physically exists (1 for 1.5 for instance)
var actualIndexAtCurrentTimeIRTracc = Convert.ToInt32(Math.Floor(indexAtCurrentTimeIRTracc));
//this is the linear interpolation "step" between this sample and the next
//sample
var stepIRTracc = Convert.ToInt32(Math.Ceiling(indexAtCurrentTimeIRTracc) - actualIndexAtCurrentTimeIRTracc);
var indexAtCurrentTimeRPot1 = (i - rPot1OffsetStart) / rateRPot1;
var actualIndexAtCurrentTimeRPot1 = Convert.ToInt32(Math.Floor(indexAtCurrentTimeRPot1));
var stepRPot1 = Convert.ToInt32(Math.Ceiling(indexAtCurrentTimeIRTracc) - actualIndexAtCurrentTimeIRTracc);
var indexAtCurrentTimeRPot2 = (i - rPot2OffsetStart) / rateRPot2;
var actualIndexAtCurrentTimeRPot2 = Convert.ToInt32(Math.Floor(indexAtCurrentTimeRPot2));
var stepRPot2 = Convert.ToInt32(Math.Ceiling(indexAtCurrentTimeRPot2) - actualIndexAtCurrentTimeRPot2);
var incrementIRTracc = 0D;
var valueIRTraccAtPoint = irTraccEUData[actualIndexAtCurrentTimeIRTracc];
var incrementRPot1 = 0D;
var valueRPot1AtPoint = rPot1EUData[actualIndexAtCurrentTimeRPot1];
var incrementRPot2 = 0D;
var valueRPot2AtPoint = rPot2EUData[actualIndexAtCurrentTimeRPot2];
//calculate the interpolation value per step for channel
//for instance for 10k and 20k sps for sample 2 of the 10k
//increment would be (data[2]-data[1])/2
if ((1 + actualIndexAtCurrentTimeIRTracc) < irTraccEUData.Count)
{
incrementIRTracc = (irTraccEUData[1 + actualIndexAtCurrentTimeIRTracc] - valueIRTraccAtPoint) / rateIRTracc;
}
else
{
incrementIRTracc = (valueIRTraccAtPoint - irTraccEUData[actualIndexAtCurrentTimeIRTracc - 1]) / rateIRTracc;
}
if ((1 + actualIndexAtCurrentTimeRPot1) < rPot1EUData.Count)
{
incrementRPot1 = (rPot1EUData[1 + actualIndexAtCurrentTimeRPot1] - valueRPot1AtPoint) / rateRPot1;
}
else
{
incrementRPot1 = (valueRPot1AtPoint - rPot1EUData[actualIndexAtCurrentTimeRPot1 - 1]) / rateRPot1;
}
if ((1 + actualIndexAtCurrentTimeRPot2) < rPot2EUData.Count)
{
incrementRPot2 = (rPot2EUData[1 + actualIndexAtCurrentTimeRPot2] - valueRPot2AtPoint) / rateRPot2;
}
else
{
incrementRPot2 = (valueRPot2AtPoint = rPot2EUData[actualIndexAtCurrentTimeRPot2 - 1]) / rateRPot2;
}
//math magic from excel
//double b = D0 + System.Math.Abs(irTraccEUData[i] - calFactorInterceptRemoval) - R0;
//double R = aicIRTRACC.LinearizationFormula.CalibrationFactor*
// System.Math.Pow(irTraccmVData[i]/1000D, aicIRTRACC.LinearizationFormula.LinearizationExponent);
//D0+(R-R0) this is column N
//double r = D0 + (R - R0);
var r = valueIRTraccAtPoint + incrementIRTracc * stepIRTracc;
//θy'=θy-θy0 this is column O
var θyprime = valueRPot1AtPoint + incrementRPot1 * stepRPot1 - θy0;
//θz'=θz-θz0 this is column p
var θzprime = valueRPot2AtPoint + incrementRPot2 * stepRPot2 - θz0;
//this is column r
var xa1 = -1D * δ * Math.Sin(θyprime * Math.PI / 180) + r * Math.Cos(θzprime * Math.PI / 180) * Math.Cos(θyprime * Math.PI / 180);
//this is column s
var ya1 = r * Math.Sin(θzprime * Math.PI / 180);
//this is column t
var za1 = -1D * δ * Math.Cos(θyprime * Math.PI / 180D) - r * Math.Cos(θzprime * Math.PI / 180D) * Math.Sin(θyprime * Math.PI / 180D);
//assign the output channel zero points if needed
if (double.IsNaN(xa1_0)) { xa1_0 = xa1; }
if (double.IsNaN(ya1_0)) { ya1_0 = ya1; }
if (double.IsNaN(za1_0)) { za1_0 = za1; }
//add in our data to the output channels
dAX.Add(xa1 - xa1_0);
dAY.Add(ya1 - ya1_0);
dAZ.Add(za1 - za1_0);
//this is column Z
var temp = Math.Sqrt(Math.Pow(r, 2) + Math.Pow(δ, 2));
if (double.IsNaN(dOut_0)) { dOut_0 = temp; }
dOut.Add(temp - dOut_0);
}
}
private static double GetTimeOfFirstSample(Event.Module.Channel channel)
{
return ((double)channel.ParentModule.TriggerSampleNumbers[0] -
channel.ParentModule.StartRecordSampleNumber) / channel.ParentModule.SampleRateHz;
}
private static Test.Module.CalculatedChannel[] Create3DIRTraccChannels(string testId, string folder,
List<Test.Module.Channel> inputChannels, string channelName, ThreeDIRTraccType irTraccType, int offset, int defaultEncoding)
{
System.Diagnostics.Trace.Assert(3 == inputChannels.Count, "3D IR-TRACC requires 3 channels");
var maxRate = inputChannels.Select(ch => ch.ParentModule.SampleRateHz).Max();
var distinctRates = inputChannels.Select(ch => ch.ParentModule.SampleRateHz).Distinct().ToArray();
foreach (var rate in distinctRates)
{
if (0 != maxRate % rate)
{
throw new NotSupportedException($"Sample rate: {maxRate} is not a multiple of sample rate: {rate}");
}
}
if (distinctRates.Length > 1)
{
var eventAggregator = ContainerLocator.Container.Resolve<IEventAggregator>();
eventAggregator.GetEvent<PageErrorEvent>().Publish(new PageErrorArg(new[] { Resources.StringResources.SuperSamplingWarning }, null));
}
var irtraccEMC = inputChannels[0].emc as Event.Module.Channel;
var rPot1EMC = inputChannels[1].emc as Event.Module.Channel;
var rPot2EMC = inputChannels[2].emc as Event.Module.Channel;
var calc = Calculation.ThreeDIRTracc;
switch (irTraccType)
{
case ThreeDIRTraccType.Abdomen: calc = Calculation.ThreeDIRTraccAbdomen; break;
case ThreeDIRTraccType.Thorax: calc = Calculation.ThreeDIRTracc; break;
case ThreeDIRTraccType.LowerThorax: calc = Calculation.ThreeDIRTraccLowerThorax; break;
}
var ccDeltaAX = CreateCalculatedChannelsIRTRACC(calc, new[] { inputChannels[0], inputChannels[1], inputChannels[2] });
ccDeltaAX.ChannelDescriptionString = channelName + " (dAX)";
var ccDeltaAY = CreateCalculatedChannelsIRTRACC(calc, new[] { inputChannels[0], inputChannels[1], inputChannels[2] });
ccDeltaAY.ChannelDescriptionString = channelName + " (dAY)";
var ccDeltaAZ = CreateCalculatedChannelsIRTRACC(calc, new[] { inputChannels[0], inputChannels[1], inputChannels[2] });
ccDeltaAZ.ChannelDescriptionString = channelName + " (dAZ)";
var ccDistanceDelta = CreateCalculatedChannelsIRTRACC(calc, new[] { inputChannels[0], inputChannels[1], inputChannels[2] });
ccDistanceDelta.ChannelDescriptionString = channelName;
var outputChannels = new Test.Module.CalculatedChannel[] { ccDeltaAX, ccDeltaAY, ccDeltaAZ, ccDistanceDelta };
foreach (var cc in outputChannels)
{
cc.Calculation = calc.ToString();
cc.AbsoluteDisplayOrder = ChannelNumberCalculationChannelIndicator + irtraccEMC.AbsoluteDisplayOrder + offset;
cc.Number = ChannelNumberCalculationChannelIndicator + offset;
cc.ProportionalToExcitation = false;
cc.ZeroMvInADC = 0;
cc.OriginalOffsetADC = 0;
cc.Data.MvPerEu = 1;
cc.Data.Multiplier = 1;
cc.Data.UnitConversion = 1;
cc.Data.UserOffsetEU = 0;
cc.ExcitationVoltage = 0;
cc.Excitation = 0;
cc.ZeroMethod = ZeroMethodType.None;
cc.RemoveOffset = false;
cc.ChannelId = irtraccEMC.ChannelId + "_" + (cc.Number + offset);
cc.ChannelGroupName = irtraccEMC.ChannelGroupName;
cc.IsInverted = false;
cc.PreTestZeroLevelAdc = 0;
cc.SerialNumber = cc.ChannelDescriptionString;
var emc = new Event.Module.AnalogInputChannel(cc, irtraccEMC.ParentModule, cc.Number);
cc.emc = emc;
offset++;
}
ccDeltaAX.EngineeringUnits = "mm";
ccDeltaAY.EngineeringUnits = "mm";
ccDeltaAZ.EngineeringUnits = "mm";
ccDistanceDelta.EngineeringUnits = "mm";
PerformCalculation(out IList<double> dax, out IList<double> day, out IList<double> daz, out IList<double> dDistance, inputChannels[0], inputChannels[1], inputChannels[2], irTraccType);
irtraccEMC = null;
rPot1EMC = null;
rPot2EMC = null;
var datas = new[] { dax, day, daz, dDistance };
for (var i = 0; i < datas.Length && i < outputChannels.Length; i++)
{
var data = datas[i];
var scaleFactor = 0D;
var adcData = ScaleEuData(ref data, out scaleFactor);
outputChannels[i].Sensitivity = scaleFactor;
outputChannels[i].DesiredRange = Constants.ADC_MIDPOINT / scaleFactor;
//adjust the output channel with the max rate we super sampled to
//and update the number of samples...
outputChannels[i].SampleRateHz = maxRate;
outputChannels[i].ParentModule.NumberOfSamples = Convert.ToUInt64(data.Count);
((Event.Module.AnalogInputChannel)outputChannels[i].emc).ParentModule.SampleRateHz = maxRate;
((Event.Module.AnalogInputChannel)outputChannels[i].emc).ParentModule.NumberOfSamples = Convert.ToUInt64(data.Count);
var f = new Serialization.SliceRaw.File { DefaultEncoding = defaultEncoding };
var fileName = new Serialization.SliceRaw.File().GetCalculatedChannelFileNameFromTestNameAndChannelNumber(testId, outputChannels[i].Number);
var filepath = System.IO.Path.Combine(folder, fileName);
outputChannels[i].Data.ScaleFactorMv = 1 / scaleFactor;
outputChannels[i].Data.ScaleFactorEU = 1 / scaleFactor;
outputChannels[i].LinearizationFormula.MarkValid(false);
outputChannels[i].PersistentChannelInfo = CreatePersistentInformationObject(outputChannels[i], filepath);
outputChannels[i].PersistentChannelInfo.BeginAppendSession();
outputChannels[i].PersistentChannelInfo.AppendSessionData(adcData.ToArray());
outputChannels[i].PersistentChannelInfo.EndAppendSession();
var writer = (f.Exporter as Serialization.SliceRaw.File.Writer);
writer?.CreatePersistentChannel(outputChannels[i], outputChannels[i].ParentModule.NumberOfSamples, outputChannels[i].ParentModule.SampleRateHz, null, null, 0, 0);
var bypass = false;
var reader = f.Importer as Serialization.SliceRaw.File.Reader;
reader?.ReadChannel(outputChannels[i], outputChannels[i].ParentModule, filepath, ref bypass);
(outputChannels[i].emc as Event.Module.Channel).UnfilteredData = outputChannels[i].PersistentChannelInfo;
(outputChannels[i].emc as Event.Module.Channel).Scaler.SetScaleFactorMv(1D / scaleFactor);
}
return outputChannels.ToArray();
}
private static Test.Module.CalculatedChannel[] CreateChannelsAggregateOperation(string testId, string folder,
Calculation calculation, List<Test.Module.Channel> inputChannels, string channelName, int channelOffset, int clipLength)
{
System.Diagnostics.Trace.Assert(1 < inputChannels.Count,
calculation.ToString() + " requires at least 1 channel");
var sourceEmc = inputChannels[0].emc as Event.Module.Channel;
var sourceChannel = inputChannels[0];
var maxSampleRate = inputChannels.Select(ch => ch.ParentModule.SampleRateHz).Max();
var distinctRates = inputChannels.Select(ch => ch.ParentModule.SampleRateHz).Distinct().ToArray();
foreach (var rate in distinctRates)
{
if (maxSampleRate % rate != 0)
{
throw new NotSupportedException($"Sample rate: {maxSampleRate} is not a multiple of {rate}");
}
}
if (distinctRates.Length > 1)
{
var eventAggregator = ContainerLocator.Container.Resolve<IEventAggregator>();
eventAggregator.GetEvent<PageErrorEvent>().Publish(new PageErrorArg(new[] { Resources.StringResources.SuperSamplingWarning }, null));
}
//Create new test channel
var cc = CreateCalculatedChannelsIRTRACC(calculation, new[] { sourceChannel });
cc.SampleRateHz = maxSampleRate;
cc.Calculation = calculation.ToString();
cc.ChannelDescriptionString = channelName;
cc.AbsoluteDisplayOrder = ChannelNumberCalculationChannelIndicator + channelOffset;
cc.Number = ChannelNumberCalculationChannelIndicator + channelOffset;
cc.ProportionalToExcitation = false;
cc.ZeroMvInADC = 0;
cc.OriginalOffsetADC = 0;
cc.Data.MvPerEu = 1;
cc.Data.Multiplier = sourceEmc.Multiplier;
cc.Data.UnitConversion = sourceEmc.UnitConversion;
cc.Data.UserOffsetEU = sourceEmc.UserOffsetEU;
cc.ExcitationVoltage = 0;
cc.Excitation = 0;
cc.ZeroMethod = ZeroMethodType.None;
cc.RemoveOffset = false;
cc.ChannelId = sourceChannel.ChannelId + "_" + cc.Number;
cc.ChannelGroupName = sourceChannel.ChannelGroupName;
cc.IsInverted = false;
var emc = new Event.Module.AnalogInputChannel(cc, sourceEmc.ParentModule, sourceEmc.AbsoluteNumber);
cc.emc = emc;
//Do the maths. Use source channel as source for data as it's properly set up.
var euData = PerformCalculationsAggregate(calculation, inputChannels);
cc.ParentModule.NumberOfSamples = Convert.ToUInt64(euData.Count);
emc.ParentModule.NumberOfSamples = Convert.ToUInt64(euData.Count);
//Don't use the source channel emc anymore.
sourceEmc = null;
//Scale the data
var adcData = ScaleEuData(ref euData, out double scaleFactor);
cc.Sensitivity = scaleFactor;
//Test by writing source channel data. Readback should be identical
var f = new Serialization.SliceRaw.File();
f.DefaultEncoding = Encoding.Unicode.CodePage;
//Create file with from source channel. At this point it's not complete -- it still needs number of
//samples, etc.
var filename = new Serialization.SliceRaw.File().GetCalculatedChannelFileNameFromTestNameAndChannelNumber(testId, cc.Number);
var filepath = System.IO.Path.Combine(folder, filename);
cc.Data.ScaleFactorMv = 1 / scaleFactor;
cc.Data.ScaleFactorEU = 1 / scaleFactor;
switch (calculation)
{
default:
cc.DesiredRange = Constants.ADC_MIDPOINT / scaleFactor;
if (sourceChannel is Test.Module.AnalogInputChannel analogInputChannel) { cc.EngineeringUnits = analogInputChannel.EngineeringUnits; }
else { cc.EngineeringUnits = "NOT DEFINED"; }
break;
case Calculation.Sin:
case Calculation.Cos:
cc.DesiredRange = 1.1;
cc.EngineeringUnits = "rads";
break;
}
//All done with channel. Create persistent object with what's in the channel object
cc.PersistentChannelInfo = CreatePersistentInformationObject(cc, filepath);
//Write out the data to the memory-mapped file
cc.PersistentChannelInfo.BeginAppendSession();
cc.PersistentChannelInfo.AppendSessionData(adcData.ToArray());
cc.PersistentChannelInfo.EndAppendSession();
//Use the export writer to update the binary channel fields with everything that's missing. This will also
//Update the CRC.
var writer = (f.Exporter as Serialization.SliceRaw.File.Writer);
writer.CreatePersistentChannel(cc, cc.ParentModule.NumberOfSamples, cc.ParentModule.SampleRateHz, null, null, 0, 0);
//At this point the PersistentChannel is blown away. Read it back in and hook it up.
var bypass = false;
(f.Importer as Serialization.SliceRaw.File.Reader).ReadChannel(cc, cc.ParentModule, filepath, ref bypass);
emc.UnfilteredData = cc.PersistentChannelInfo;
if (calculation == Calculation.HIC)
{
var channelData = new ChannelData("g");
channelData.FilteredEU = euData.ToArray();
var hic = HeadInjuryCriterion.GetHeadInjuryCriterion(channelData, cc.SampleRateHz, clipLength);
cc.T1 = Convert.ToUInt64(hic.StartSample);
cc.T2 = Convert.ToUInt64(hic.EndSample);
cc.HIC = hic.HIC;
}
return new[] { cc };
}
/// <summary>
/// creates a calculated channel for binary operations (sine/cosine/integral/ffs)
/// </summary>
/// <param name="testId"></param>
/// <param name="folder"></param>
/// <param name="calculation"></param>
/// <param name="inputChannels"></param>
/// <param name="channelName"></param>
/// <param name="channelOffset"></param>
/// <returns></returns>
private static Test.Module.CalculatedChannel[] CreateChannelsBinaryOperation(string testId, string folder,
Calculation calculation, List<Test.Module.Channel> inputChannels, string channelName, int channelOffset)
{
var sourceEmc = inputChannels[0].emc as Event.Module.Channel;
var sourceChannel = inputChannels[0];
//Create new test channel
var cc = CreateCalculatedChannelsIRTRACC(calculation, new[] { sourceChannel });
cc.Calculation = calculation.ToString();
cc.ChannelDescriptionString = channelName;
cc.AbsoluteDisplayOrder = ChannelNumberCalculationChannelIndicator + channelOffset;
cc.Number = ChannelNumberCalculationChannelIndicator + channelOffset;
cc.ProportionalToExcitation = false;
cc.ZeroMvInADC = 0;
cc.OriginalOffsetADC = 0;
cc.Data.MvPerEu = 1;
cc.Data.Multiplier = sourceEmc.Multiplier;
cc.Data.UnitConversion = sourceEmc.UnitConversion;
cc.Data.UserOffsetEU = sourceEmc.UserOffsetEU;
cc.Excitation = 0;
cc.ZeroMethod = ZeroMethodType.None;
cc.RemoveOffset = false;
cc.ChannelId = sourceChannel.ChannelId + "_" + cc.Number;
cc.ChannelGroupName = sourceChannel.ChannelGroupName;
cc.IsInverted = false;
var emc = new Event.Module.AnalogInputChannel(cc, sourceEmc.ParentModule, sourceEmc.AbsoluteNumber);
cc.emc = emc;
//Do the maths. Use source channel as source for data as it's properly set up.
var euData = PerformCalculationBinary(calculation, sourceEmc);
//Don't use the source channel emc anymore.
sourceEmc = null;
//Scale the data
var adcData = ScaleEuData(ref euData, out var scaleFactor);
cc.Sensitivity = scaleFactor;
//Test by writing source channel data. Readback should be identical
var f = new Serialization.SliceRaw.File { DefaultEncoding = Encoding.Unicode.CodePage };
//Create file with from source channel. At this point it's not complete -- it still needs number of
//samples, etc.
var filename = new Serialization.SliceRaw.File().GetCalculatedChannelFileNameFromTestNameAndChannelNumber(testId, cc.Number);
var filepath = System.IO.Path.Combine(folder, filename);
cc.Data.ScaleFactorMv = 1 / scaleFactor;
cc.Data.ScaleFactorEU = 1 / scaleFactor;
switch (calculation)
{
default:
cc.DesiredRange = Constants.ADC_MIDPOINT / scaleFactor;
if (sourceChannel is Test.Module.AnalogInputChannel analogInputChannel) { cc.EngineeringUnits = analogInputChannel.EngineeringUnits; }
else { cc.EngineeringUnits = "NOT DEFINED"; }
break;
case Calculation.Sin:
case Calculation.Cos:
cc.DesiredRange = 1.1;
cc.EngineeringUnits = "rads";
break;
}
//All done with channel. Create persistent object with what's in the channel object
cc.PersistentChannelInfo = CreatePersistentInformationObject(cc, filepath);
//Write out the data to the memory-mapped file
cc.PersistentChannelInfo.BeginAppendSession();
cc.PersistentChannelInfo.AppendSessionData(adcData.ToArray());
cc.PersistentChannelInfo.EndAppendSession();
//Use the export writer to update the binary channel fields with everything that's missing. This will also
//Update the CRC.
var writer = (f.Exporter as Serialization.SliceRaw.File.Writer);
writer.CreatePersistentChannel(cc, cc.ParentModule.NumberOfSamples, cc.ParentModule.SampleRateHz, null, null, 0, 0);
//At this point the PersistentChannel is blown away. Read it back in and hook it up.
var bypass = false;
(f.Importer as Serialization.SliceRaw.File.Reader).ReadChannel(cc, cc.ParentModule, filepath,
ref bypass);
emc.UnfilteredData = cc.PersistentChannelInfo;
return new[] { cc };
}
public enum ThreeDIRTraccType
{
Thorax,
Abdomen,
LowerThorax
}
private static short[] ScaleEuData(ref IList<double> euData, out double scaleFactor)
{
scaleFactor = 1.0;
var max = (from d in euData select Math.Abs(d)).Max();
if (0 == max)
{
max = 1;
}
//we used ABS above, so we need to consider that the signal could be bipolar and be peak to peak of 2*max
max *= 2;
if (short.MaxValue > max)
{
scaleFactor = short.MaxValue / max;
}
else
{
scaleFactor = max / short.MaxValue;
}
//Scale the data
var data = new List<short>();
foreach (var euSample in euData)
{
data.Add((short)(euSample * scaleFactor));
}
return data.ToArray();
}
/// <summary>
/// Validate name of the new calculated channel
/// </summary>
/// <param name="channelName">name of the new calculated channel</param>
/// <param name="inputChannels">existing channels</param>
/// <param name="allChannels">If null - calling form MakeCalculatedChannels() in Download.xaml.cs</param>
/// <param name="errorList">list of errors</param>
/// <returns>if anyy errors - returns false</returns>
public static bool ValidateChannelName(string channelName, List<Test.Module.Channel> inputChannels, List<Test.Module.Channel> allChannels, out List<string> errorList)
{
errorList = new List<string>();
if (allChannels == null) return errorList.Count == 0;
if (string.IsNullOrEmpty(channelName)) { errorList.Add("Channel name cannot be empty."); }
if (inputChannels.Exists(ch => ch.ChannelDescriptionString == channelName))
{ errorList.Add("Channel name is not unique. [input channels]"); }
if (allChannels.Exists(ch => ch.ChannelDescriptionString == channelName))
{ errorList.Add("Channel name is not unique. [all channels]"); }
return errorList.Count == 0;
}
#region helper classes
private sealed class ClonableDoubles : List<double>, ICloneable
{
object ICloneable.Clone()
{
var l = new List<double>();
l.AddRange(ToArray());
return l;
}
}
#endregion
}
}

View File

@@ -0,0 +1,139 @@
using System;
using System.Windows.Media.Imaging;
using DTS.Common;
using DTS.Common.Interface;
using DTS.Viewer.AddCalculatedChannel;
using Prism.Ioc;
using Prism.Modularity;
using Unity;
// ReSharper disable RedundantAttributeUsageProperty
// ReSharper disable UnusedParameter.Local
[assembly: AddCalculatedChannelModuleName()]
[assembly: AddCalculatedChannelModuleImageAttribute()]
namespace DTS.Viewer.AddCalculatedChannel
{
[Module(ModuleName = "AddCalculatedChannel")]
public class AddCalculatedChannelModule : IModule
{
/// <summary>
/// Injected unity container
/// </summary>
private readonly IUnityContainer _unityContainer;
/// <summary>
/// Initializes a new instance of the <see cref="AddCalculatedChannelModule"/> class.
/// </summary>
/// <param name="unityContainer">Obtained reference of the unity container by using dependency injection.</param>
public AddCalculatedChannelModule(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
public void Initialize()
{
// Register View & View-Model with Unity dependency injection container as a singleton.
_unityContainer.RegisterType<IAddCalculatedChannelView, AddCalculatedChannelView>();
_unityContainer.RegisterType<IAddCalculatedChannelViewModel, AddCalculatedChannelViewModel>();
}
public void OnInitialized(IContainerProvider containerProvider)
{
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
Initialize();
}
}
/// <summary>
/// Attribute class contains assembly name
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class AddCalculatedChannelModuleNameAttribute : TextAttribute
{
public AddCalculatedChannelModuleNameAttribute() : this(null) { }
public AddCalculatedChannelModuleNameAttribute(string s)
{
AssemblyName = AssemblyNames.AddCalculatedChannel.ToString();
}
public override string AssemblyName { get; }
public override Type GetAttributeType()
{
return typeof(TextAttribute);
}
public override string GetAssemblyName()
{
return AssemblyName;
}
}
/// <summary>
/// Attribute class contains assembly image and name - used on the Main screen to display available components
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class AddCalculatedChannelModuleImageAttribute : ImageAttribute
{
private BitmapImage _img;
public AddCalculatedChannelModuleImageAttribute() : this(null) { }
public override BitmapImage AssemblyImage
{
get { _img = AssemblyInfo.GetImage(AssemblyNames.AddCalculatedChannel.ToString()); return _img; }
}
public AddCalculatedChannelModuleImageAttribute(string s)
{
_img = AssemblyInfo.GetImage(AssemblyNames.AddCalculatedChannel.ToString());
}
public override Type GetAttributeType()
{
return typeof(ImageAttribute);
}
public override BitmapImage GetAssemblyImage()
{
return AssemblyImage;
}
private string _name;
public override string AssemblyName
{
get { _name = AssemblyNames.AddCalculatedChannel.ToString(); return _name; }
}
public override string GetAssemblyName()
{
return AssemblyName;
}
private string _group;
public override string AssemblyGroup
{
get { _group = eAssemblyGroups.Viewer.ToString(); return _group; }
}
public override string GetAssemblyGroup()
{
return AssemblyGroup;
}
private eAssemblyRegion _region;
public override eAssemblyRegion AssemblyRegion
{
get { _region = eAssemblyRegion.AddCalculatedChannelRegion; return _region; }
}
public override eAssemblyRegion GetAssemblyRegion()
{
return AssemblyRegion;
}
}
}

View File

@@ -0,0 +1,162 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{6451F3ED-934E-47E3-A1CA-33C223A6507A}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DTS.Viewer.AddCalculatedChannel</RootNamespace>
<AssemblyName>DTS.Viewer.AddCalculatedChannel</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Xaml.Behaviors">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Microsoft.Xaml.Behaviors.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="Prism">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.dll</HintPath>
</Reference>
<Reference Include="Prism.Unity.Wpf">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.Unity.Wpf.dll</HintPath>
</Reference>
<Reference Include="Prism.Wpf">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.Wpf.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="Unity.Abstractions">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Unity.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Unity.Container">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Unity.Container.dll</HintPath>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="Xceed.Wpf.Toolkit">
<HintPath>..\..\..\Common\DTS.Common\lib\Xceed.Wpf.Toolkit\Xceed.Wpf.Toolkit.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Model\CalculatedChannelCreator.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="AddCalculatedChannelModule.cs" />
<Compile Include="Resources\StringResources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>StringResources.resx</DependentUpon>
</Compile>
<Compile Include="Resources\TranslateExtension.cs" />
<Compile Include="ViewModel\AddCalculatedChannelViewModel.cs" />
<Compile Include="View\AddCalculatedChannelView.xaml.cs">
<DependentUpon>AddCalculatedChannelView.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Page Include="View\AddCalculatedChannelView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Common\DTS.Common.Calculations\DTS.Common.Calculations.csproj">
<Project>{5ce6f27b-1c5b-4101-88de-58a30b1e5f37}</Project>
<Name>DTS.Common.Calculations</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common.Core\DTS.Common.Core.csproj">
<Project>{fab1f470-1574-4301-b56e-d3364aa93679}</Project>
<Name>DTS.Common.Core</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common.DAS.Concepts\DTS.Common.DAS.Concepts.csproj">
<Project>{AE3987F7-C4C6-40FB-A353-1A2DADEF7A9A}</Project>
<Name>DTS.Common.DAS.Concepts</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common.SerializationPlus\DTS.Common.SerializationPlus.csproj">
<Project>{b9d1ac5b-7a6f-4b14-9ff8-3a1fc03519e2}</Project>
<Name>DTS.Common.SerializationPlus</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common.Serialization\DTS.Common.Serialization.csproj">
<Project>{0679d014-59c2-4327-b288-0e3bd1374710}</Project>
<Name>DTS.Common.Serialization</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common.Utilities\DTS.Common.Utilities.csproj">
<Project>{D6DA1B74-C711-43C2-91B1-1908A8D04DBF}</Project>
<Name>DTS.Common.Utilities</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common\DTS.Common.csproj">
<Project>{114edc77-f3b5-4576-a91b-40818d503b55}</Project>
<Name>DTS.Common</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\DataPRO\IService\IService.csproj">
<Project>{C9C45B72-05A3-4962-BC13-A78B1F4B1925}</Project>
<Name>IService</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\StringResources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>StringResources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,17 @@
using DTS.Common.Interface;
// ReSharper disable CheckNamespace
namespace DTS.Viewer.AddCalculatedChannel
{
/// <summary>
/// Interaction logic for AddCalculatedChannelView.xaml
/// </summary>
public partial class AddCalculatedChannelView : IAddCalculatedChannelView
{
public AddCalculatedChannelView()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,139 @@
using System;
using System.Windows.Media.Imaging;
using DTS.Common;
using DTS.Common.Interface;
using DTS.Viewer.AddCalculatedChannel;
using Prism.Ioc;
using Prism.Modularity;
using Unity;
// ReSharper disable RedundantAttributeUsageProperty
// ReSharper disable UnusedParameter.Local
[assembly: AddCalculatedChannelModuleName()]
[assembly: AddCalculatedChannelModuleImageAttribute()]
namespace DTS.Viewer.AddCalculatedChannel
{
[Module(ModuleName = "AddCalculatedChannel")]
public class AddCalculatedChannelModule : IModule
{
/// <summary>
/// Injected unity container
/// </summary>
private readonly IUnityContainer _unityContainer;
/// <summary>
/// Initializes a new instance of the <see cref="AddCalculatedChannelModule"/> class.
/// </summary>
/// <param name="unityContainer">Obtained reference of the unity container by using dependency injection.</param>
public AddCalculatedChannelModule(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
public void Initialize()
{
// Register View & View-Model with Unity dependency injection container as a singleton.
_unityContainer.RegisterType<IAddCalculatedChannelView, AddCalculatedChannelView>();
_unityContainer.RegisterType<IAddCalculatedChannelViewModel, AddCalculatedChannelViewModel>();
}
public void OnInitialized(IContainerProvider containerProvider)
{
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
Initialize();
}
}
/// <summary>
/// Attribute class contains assembly name
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class AddCalculatedChannelModuleNameAttribute : TextAttribute
{
public AddCalculatedChannelModuleNameAttribute() : this(null) { }
public AddCalculatedChannelModuleNameAttribute(string s)
{
AssemblyName = AssemblyNames.AddCalculatedChannel.ToString();
}
public override string AssemblyName { get; }
public override Type GetAttributeType()
{
return typeof(TextAttribute);
}
public override string GetAssemblyName()
{
return AssemblyName;
}
}
/// <summary>
/// Attribute class contains assembly image and name - used on the Main screen to display available components
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class AddCalculatedChannelModuleImageAttribute : ImageAttribute
{
private BitmapImage _img;
public AddCalculatedChannelModuleImageAttribute() : this(null) { }
public override BitmapImage AssemblyImage
{
get { _img = AssemblyInfo.GetImage(AssemblyNames.AddCalculatedChannel.ToString()); return _img; }
}
public AddCalculatedChannelModuleImageAttribute(string s)
{
_img = AssemblyInfo.GetImage(AssemblyNames.AddCalculatedChannel.ToString());
}
public override Type GetAttributeType()
{
return typeof(ImageAttribute);
}
public override BitmapImage GetAssemblyImage()
{
return AssemblyImage;
}
private string _name;
public override string AssemblyName
{
get { _name = AssemblyNames.AddCalculatedChannel.ToString(); return _name; }
}
public override string GetAssemblyName()
{
return AssemblyName;
}
private string _group;
public override string AssemblyGroup
{
get { _group = eAssemblyGroups.Viewer.ToString(); return _group; }
}
public override string GetAssemblyGroup()
{
return AssemblyGroup;
}
private eAssemblyRegion _region;
public override eAssemblyRegion AssemblyRegion
{
get { _region = eAssemblyRegion.AddCalculatedChannelRegion; return _region; }
}
public override eAssemblyRegion GetAssemblyRegion()
{
return AssemblyRegion;
}
}
}

View File

@@ -0,0 +1,162 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{6451F3ED-934E-47E3-A1CA-33C223A6507A}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DTS.Viewer.AddCalculatedChannel</RootNamespace>
<AssemblyName>DTS.Viewer.AddCalculatedChannel</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Xaml.Behaviors">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Microsoft.Xaml.Behaviors.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="Prism">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.dll</HintPath>
</Reference>
<Reference Include="Prism.Unity.Wpf">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.Unity.Wpf.dll</HintPath>
</Reference>
<Reference Include="Prism.Wpf">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.Wpf.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="Unity.Abstractions">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Unity.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Unity.Container">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Unity.Container.dll</HintPath>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="Xceed.Wpf.Toolkit">
<HintPath>..\..\..\Common\DTS.Common\lib\Xceed.Wpf.Toolkit\Xceed.Wpf.Toolkit.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Model\CalculatedChannelCreator.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="AddCalculatedChannelModule.cs" />
<Compile Include="Resources\StringResources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>StringResources.resx</DependentUpon>
</Compile>
<Compile Include="Resources\TranslateExtension.cs" />
<Compile Include="ViewModel\AddCalculatedChannelViewModel.cs" />
<Compile Include="View\AddCalculatedChannelView.xaml.cs">
<DependentUpon>AddCalculatedChannelView.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Page Include="View\AddCalculatedChannelView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Common\DTS.Common.Calculations\DTS.Common.Calculations.csproj">
<Project>{5ce6f27b-1c5b-4101-88de-58a30b1e5f37}</Project>
<Name>DTS.Common.Calculations</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common.Core\DTS.Common.Core.csproj">
<Project>{fab1f470-1574-4301-b56e-d3364aa93679}</Project>
<Name>DTS.Common.Core</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common.DAS.Concepts\DTS.Common.DAS.Concepts.csproj">
<Project>{AE3987F7-C4C6-40FB-A353-1A2DADEF7A9A}</Project>
<Name>DTS.Common.DAS.Concepts</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common.SerializationPlus\DTS.Common.SerializationPlus.csproj">
<Project>{b9d1ac5b-7a6f-4b14-9ff8-3a1fc03519e2}</Project>
<Name>DTS.Common.SerializationPlus</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common.Serialization\DTS.Common.Serialization.csproj">
<Project>{0679d014-59c2-4327-b288-0e3bd1374710}</Project>
<Name>DTS.Common.Serialization</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common.Utilities\DTS.Common.Utilities.csproj">
<Project>{D6DA1B74-C711-43C2-91B1-1908A8D04DBF}</Project>
<Name>DTS.Common.Utilities</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common\DTS.Common.csproj">
<Project>{114edc77-f3b5-4576-a91b-40818d503b55}</Project>
<Name>DTS.Common</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\DataPRO\IService\IService.csproj">
<Project>{C9C45B72-05A3-4962-BC13-A78B1F4B1925}</Project>
<Name>IService</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\StringResources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>StringResources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,969 @@
using DTS.Common.Enums.Sensors;
using DTS.Common.Utilities.Logging;
using DTS.Common.Utils;
using DTS.Serialization;
using DTS.Slice.Control;
using DTS.Common;
using DTS.Common.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using static DTS.Viewer.AddCalculatedChannel.AddCalculatedChannelViewModel;
using Prism.Ioc;
using DTS.Common.Calculations;
using DTS.Common.Utilities;
using Prism.Events;
namespace DTS.Viewer.AddCalculatedChannel.Model
{
public class CalculatedChannelCreator
{
private static readonly int ChannelNumberCalculationChannelIndicator = 100000;
public static Test.Module.CalculatedChannel[] CreateChannels(string testId,
string folder,
Calculation calculation,
List<Test.Module.Channel> inputChannels,
string channelName,
int startingNumber,
List<Test.Module.Channel> allChannels,
int clipLength,
out List<string> errorList,
int defaultEncoding)
{
Test.Module.CalculatedChannel[] calculatedChannels = null;
errorList = new List<string>();
switch (calculation)
{
case Calculation.ThreeDIRTracc: calculatedChannels = Create3DIRTraccChannels(testId, folder, inputChannels, channelName, ThreeDIRTraccType.Thorax, startingNumber, defaultEncoding); break;
case Calculation.ThreeDIRTraccLowerThorax: calculatedChannels = Create3DIRTraccChannels(testId, folder, inputChannels, channelName, ThreeDIRTraccType.LowerThorax, startingNumber, defaultEncoding); break;
case Calculation.ThreeDIRTraccAbdomen: calculatedChannels = Create3DIRTraccChannels(testId, folder, inputChannels, channelName, ThreeDIRTraccType.Abdomen, startingNumber, defaultEncoding); break;
case Calculation.SUM:
case Calculation.AVE:
case Calculation.Resultant:
case Calculation.HIC:
calculatedChannels = CreateChannelsAggregateOperation(testId, folder, calculation, inputChannels, channelName, startingNumber, clipLength);
break;
default: calculatedChannels = CreateChannelsBinaryOperation(testId, folder, calculation, inputChannels, channelName, startingNumber); break;
}
if (null == calculatedChannels) return null;
for (var i = 0; i < calculatedChannels.Length; i++)
{
calculatedChannels[i].AbsoluteDisplayOrder = startingNumber + i;
}
if (ValidateChannelName(channelName, inputChannels, allChannels, out errorList)) return calculatedChannels;
//ReportErrors(errorList);
return null;
}
private static Serialization.SliceRaw.File.PersistentChannel CreatePersistentInformationObject(Test.Module.CalculatedChannel channel, string filepath)
{
var channelHeader = new Serialization.SliceRaw.File.BinaryChannelHeader
{
NumberOfTriggers = (ushort)(channel.ParentModule.TriggerSampleNumbers.Count)
};
channelHeader.TriggerSampleNumbers = new ulong[channelHeader.NumberOfTriggers];
// Do trigger sample information.
for (var i = 0; i < channelHeader.NumberOfTriggers; i++)
{
channelHeader.TriggerSampleNumbers[i] = channel.ParentModule.TriggerSampleNumbers[i];
}
// Do EU information.
if (channel is Common.DAS.Concepts.DAS.Channel.IEngineeringUnitAware)
{ //
// Persistent object property accessors already pad out EU so data will be word-aligned,
// so we'll want to make sure we do the same thing here.
//
var eu = (channel as Common.DAS.Concepts.DAS.Channel.IEngineeringUnitAware).EngineeringUnits;
var paddedEu = (1 == eu.Length % 2) ? (eu.Clone() as string).PadRight(eu.Length + 1, ' ') : eu;
channelHeader.EuFieldLengthWithTerminator = (ushort)(paddedEu.Length + 1);
channelHeader.EngineeringUnit = new char[channelHeader.EuFieldLengthWithTerminator - 1];
for (var j = 0; j < channelHeader.EuFieldLengthWithTerminator - 1; j++)
{
channelHeader.EngineeringUnit[j] = paddedEu[j];
}
}
else
{
channelHeader.EuFieldLengthWithTerminator = 1;
channelHeader.EngineeringUnit = new char[0];
}
// Do ISO code information.
channelHeader.IsoCode = new char[16];
// Make sure memory-mapped file does NOT exist (persistent channel object will overwrite header but append data
// after old file data... don't want that!)
if (System.IO.File.Exists(filepath))
{
GC.Collect();
FileUtils.DeleteFileOrMove(filepath, APILogger.Log);
////Rename existing channel file and kick off thread that will deleted it some time later. This needs to
////happen in this case as the test tree still contains references to the original file and it can't be deleted
////here. After a new channel is added, the old one is removed. The worker thread should wait long enough for that
////to happen (or better, check to see when it does) and then delete the file. This should eliminate the File.IO
////Exception that was being thrown.
//string tmpfilepath = filepath + ".bak";
//APILogger.Log("Renaming: " + filepath + " to " + tmpfilepath + " and deferring deletion.");
//System.IO.Path.ChangeExtension(filepath, Guid.NewGuid().ToString());
//System.Threading.ThreadPool.QueueUserWorkItem(DeleteChannelFile, tmpfilepath);
}
// Create the persistent channel object and return it.
return new Serialization.SliceRaw.File.PersistentChannel(filepath, channelHeader, true);
}
/// <summary>
/// this function takes a calculation and a list of input channels and returns
/// a list of doubles that is the output of doing that calculation
/// </summary>
/// <param name="calculation"></param>
/// <param name="channels"></param>
/// <returns></returns>
private static IList<double> PerformCalculationsAggregate(Calculation calculation,
List<Test.Module.Channel> channels)
{
var maxSampleRate = channels.Select(ch => ch.ParentModule.SampleRateHz).Max();
//this will hold the unfiltered input data for all the input channels
var unfilteredDataEU = new List<List<double>>();
//this will hold the output data
var dOutput = new List<double>();
//this will hold the emc channel data for the input channels (the input channels already have this data
//but keeping a local reference here removes some repeated casting that we'd have to do
var emcChannels = new List<Event.Module.Channel>();
//we may have different start times and the sample indices may not align, if we pick the first channel as a reference
//channel, then we can keep track of the delta for each channels start and the reference channel start in terms of samples
foreach (var ch in channels)
{
var emc = ch.emc as Event.Module.Channel;
emcChannels.Add(emc);
var data = emc.GetUnfilteredDataEu();
unfilteredDataEU.Add(data);
var start = GetTimeOfFirstSample(emc);
}
//any aggregate channels (SUM/AVE) just keep a single double and update it as needed while processing samples
var dAggregateValue = 0D;
var bAdd = true;
var currentChannelSampleIndex = 0;
//to properly aggregate, we need to put both datasets to the right sample rate
//using interpolation
//we need to calculate the min/max time across all channels and then
//the specific min of each channel, this tells us how to align data
var minStart = channels.Select(ch => ((double)ch.ParentModule.TriggerSampleNumbers[0] - ch.ParentModule.StartRecordSampleNumber) / ch.ParentModule.SampleRateHz).Min();
var minEnd = double.MaxValue;
var channelOffsetStarts = new List<int>();
var rates = new List<double>();
for (int i = 0; i < channels.Count; i++)
{
var ch = channels[i];
var chStart = ((double)ch.ParentModule.TriggerSampleNumbers[0] - ch.ParentModule.StartRecordSampleNumber) / ch.ParentModule.SampleRateHz;
var channelOffsetStart = (int)((chStart - minStart) * ch.ParentModule.SampleRateHz);
channelOffsetStarts.Add(channelOffsetStart);
var chEnd = ch.ParentModule.NumberOfSamples - chStart * ch.ParentModule.SampleRateHz;
minEnd = Math.Min(minEnd, chEnd / ch.ParentModule.SampleRateHz);
var rate = maxSampleRate / ch.ParentModule.SampleRateHz;
rates.Add(rate);
}
minStart = -1D * Math.Truncate(1000D * minStart) / 1000D;
minEnd = Math.Truncate(1000D * minEnd) / 1000D;
var totalSamples = Convert.ToInt32(Math.Floor((minEnd - minStart) * maxSampleRate));
for (var iSampleIDX = 0; iSampleIDX < totalSamples; iSampleIDX++)
{
var timeAtIndex =
dAggregateValue = 0;
bAdd = true;
var dSumSquares = 0D;
for (var iChannel = 0; iChannel < emcChannels.Count; iChannel++)
{
var rate = rates[iChannel];
var indexAtCurrentTime = (iSampleIDX - channelOffsetStarts[iChannel]) / rate;
var thisChannelsIndexAtCurrentTime = Convert.ToInt32(Math.Floor(indexAtCurrentTime));
var step = Convert.ToInt32(Math.Ceiling(indexAtCurrentTime) - thisChannelsIndexAtCurrentTime);
if (currentChannelSampleIndex < 0 || currentChannelSampleIndex >= unfilteredDataEU[iChannel].Count)
{
bAdd = false;
break;
}
var dataAtPoint = unfilteredDataEU[iChannel][thisChannelsIndexAtCurrentTime];
var increment = 0D;
if ((1 + thisChannelsIndexAtCurrentTime) < unfilteredDataEU[iChannel].Count)
{
increment = (unfilteredDataEU[iChannel][1 + thisChannelsIndexAtCurrentTime] - dataAtPoint) / rate;
}
else
{
increment = (dataAtPoint - unfilteredDataEU[iChannel][thisChannelsIndexAtCurrentTime - 1]) / rate;
}
dataAtPoint += (increment * step);
dAggregateValue += dataAtPoint;
//HIC must be in g's
if (calculation == Calculation.HIC)
{
if (((Event.Module.AnalogInputChannel)emcChannels[iChannel]).EngineeringUnits.ToLower().Trim() != "g")
{
//convert from m/sec^2 to g
dataAtPoint *= 9.80665D;
}
}
dSumSquares += Math.Pow(dataAtPoint, 2);
}
if (!bAdd) continue;
switch (calculation)
{
case Calculation.AVE: dOutput.Add(dAggregateValue / channels.Count); break;
case Calculation.SUM: dOutput.Add(dAggregateValue); break;
case Calculation.Resultant:
case Calculation.HIC:
dOutput.Add(Math.Sqrt(dSumSquares));
break;
}
}
return dOutput;
}
/// <summary>
/// performs calculations for a binary calculation channel (integrate/differentiate/FFT, etc)
/// </summary>
/// <param name="calculation"></param>
/// <param name="channel"></param>
/// <returns></returns>
private static IList<double> PerformCalculationBinary(Calculation calculation, Event.Module.Channel channel)
{
var data = channel.GetUnfilteredDataEu();
var sampleRate = Convert.ToInt32(channel.ParentModule.SampleRateHz);
switch (calculation)
{
case Calculation.Integral:
{
var db = new ClonableDoubles();
db.AddRange(data.ToArray());
var integral = new Common.Utilities.Math.Nhtsa.Integration(db, sampleRate);
return integral.Range;
}
case Calculation.DoubleIntegral:
{
var db = new ClonableDoubles();
db.AddRange(data.ToArray());
var integral = new Common.Utilities.Math.Nhtsa.Integration(db, sampleRate);
db = new ClonableDoubles();
db.AddRange(integral.Range);
var doubleIntegral = new Common.Utilities.Math.Nhtsa.Integration(db, sampleRate);
return doubleIntegral.Range;
}
case Calculation.Derivative:
{
var db = new ClonableDoubles();
db.AddRange(data.ToArray());
var derivative = new Common.Utilities.Math.Nhtsa.Differentiation(db, sampleRate);
return derivative.Range;
}
case Calculation.Sin:
{
return channel.DataEu.Select(euSample => Math.Sin(euSample)).ToList();
}
case Calculation.Cos:
{
return channel.DataEu.Select(euSample => Math.Cos(euSample)).ToList();
}
}
return new List<double>();
}
private static Test.Module.CalculatedChannel CreateCalculatedChannelsIRTRACC(Calculation calculation, Test.Module.Channel[] inputChannels)
{
switch (calculation)
{
case Calculation.ThreeDIRTracc:
case Calculation.ThreeDIRTraccAbdomen:
case Calculation.ThreeDIRTraccLowerThorax:
return Test.Module.CalculatedChannel.CreateInstance(new[]
{
inputChannels[0],
inputChannels[1],
inputChannels[2]
});
default:
return Test.Module.CalculatedChannel.CreateInstance(inputChannels[0]);
}
}
//private Event.Module.Channel GetSourceEMC()
//{
// switch (_calculation)
// {
// case Calculation.ThreeDIRTracc:
// case Calculation.ThreeDIRTraccAbdomen:
// case Calculation.ThreeDIRTraccLowerThorax:
// return
// (cbIRTracc.SelectedItem as ChannelHelper).MyChannel.emc as Event.Module.Channel;
// default:
// return _sourceChannel.emc as Event.Module.Channel;
// }
//}
//private static void DeleteChannelFile(object filepath)
//{
// FileUtils.DeleteFileOrMove((string)filepath, APILogger.Log);
//}
/// <summary>
/// performs the IR-Tracc 3D calculation
/// based on issue
/// 7489 Implement 2D/3D IRTRACC support
/// </summary>
/// <param name="dAX"></param>
/// <param name="dAY"></param>
/// <param name="dAZ"></param>
/// <param name="dOut"></param>
private static void PerformCalculation(out IList<double> dAX, out IList<double> dAY, out IList<double> dAZ, out IList<double> dOut,
Test.Module.Channel irTraccChannel, Test.Module.Channel rPot1Channel, Test.Module.Channel rPot2Channel, ThreeDIRTraccType irtraccType)
{
var maxRate = Math.Max(rPot1Channel.ParentModule.SampleRateHz, rPot2Channel.ParentModule.SampleRateHz);
maxRate = Math.Max(maxRate, irTraccChannel.ParentModule.SampleRateHz);
var irtraccEMC = irTraccChannel.emc as Event.Module.Channel;
var rPot1EMC = rPot1Channel.emc as Event.Module.Channel;
var rPot2EMC = rPot2Channel.emc as Event.Module.Channel;
if (0 != maxRate % rPot1Channel.ParentModule.SampleRateHz) { throw new InvalidOperationException($"Sample rate: {maxRate} is not a multiple of sample rate: {rPot1Channel.ParentModule.SampleRateHz}"); }
if (0 != maxRate % rPot2Channel.ParentModule.SampleRateHz) { throw new InvalidOperationException($"Sample rate: {maxRate} is not a multiple of sample rate: {rPot2Channel.ParentModule.SampleRateHz}"); }
if (0 != maxRate % irTraccChannel.ParentModule.SampleRateHz) { throw new InvalidOperationException($"Sample rate: {maxRate} is not a multiple of sample rate: {irTraccChannel.ParentModule.SampleRateHz}"); }
//this is the EU data for each channel NOTE - ALL CHANNELS MUST NOT BE USING ZEROING!!! (we handle zeroing already below)
var irTraccEUData = irtraccEMC.GetUnfilteredDataEu();
DiskUtility.ReplaceDataIfNeeded(ref irTraccEUData, "DISPLEU.txt");
//var irTraccmVData = irtraccEMC.GetUnfilteredDataMV();
var rPot1EUData = rPot1EMC.GetUnfilteredDataEu();
DiskUtility.ReplaceDataIfNeeded(ref rPot1EUData, "YPOTEU.txt");
var rPot2EUData = rPot2EMC.GetUnfilteredDataEu();
DiskUtility.ReplaceDataIfNeeded(ref rPot2EUData, "ZPOTEU.txt");
//this calculates start time for each channel
var startIRTracc = (double)(irTraccChannel.ParentModule.TriggerSampleNumbers[0] - irTraccChannel.ParentModule.StartRecordSampleNumber) / irTraccChannel.ParentModule.SampleRateHz;
startIRTracc = -1D * Math.Truncate(startIRTracc * 1000D) / 1000D;
var startRPot1 = (double)(rPot1Channel.ParentModule.TriggerSampleNumbers[0] - rPot1Channel.ParentModule.StartRecordSampleNumber) / rPot1Channel.ParentModule.SampleRateHz;
startRPot1 = -1D * Math.Truncate(startRPot1 * 1000D) / 1000D;
var startRPot2 = (double)(rPot2Channel.ParentModule.TriggerSampleNumbers[0] - rPot2Channel.ParentModule.StartRecordSampleNumber) / rPot2Channel.ParentModule.SampleRateHz;
startRPot2 = -1D * Math.Truncate(startRPot2 * 1000D) / 1000D;
//this calculates the end for each channel
var endIRTracc = (irTraccChannel.ParentModule.NumberOfSamples + startIRTracc * irTraccChannel.ParentModule.SampleRateHz) / irTraccChannel.ParentModule.SampleRateHz;
endIRTracc = Math.Truncate(endIRTracc * 1000D) / 1000D;
var endRPot1 = (rPot1Channel.ParentModule.NumberOfSamples + startRPot1 * rPot1Channel.ParentModule.SampleRateHz) / rPot1Channel.ParentModule.SampleRateHz;
endRPot1 = Math.Truncate(endRPot1 * 1000D) / 1000D;
var endRPot2 = (rPot2Channel.ParentModule.NumberOfSamples + startRPot2 * rPot2Channel.ParentModule.SampleRateHz) / rPot2Channel.ParentModule.SampleRateHz;
endRPot2 = Math.Truncate(endRPot2 * 1000D) / 1000D;
//here we select the latest start between channels
var start = Math.Max(startIRTracc, startRPot1);
start = Math.Max(start, startRPot2);
//here we find the earliest end between the channels
var end = Math.Min(endIRTracc, endRPot1);
end = Math.Min(end, endRPot2);
// we will super sample to the highest sample rate, and use a common start/stop between all channels.
var length = Convert.ToInt32(Math.Floor((end - start) * maxRate));
//these are the containers for our output data
dAX = new List<double>(length);
dAY = new List<double>(length);
dAZ = new List<double>(length);
dOut = new List<double>(length);
var aicIRTRACC = irTraccChannel as Test.Module.AnalogInputChannel;
var aicRPot1 = rPot1Channel as Test.Module.AnalogInputChannel;
var aicRPOT2 = rPot2Channel as Test.Module.AnalogInputChannel;
//calculates the rate of each channel relative to the highest rate of any of the channels
var rateIRTracc = Convert.ToInt32(Math.Ceiling(maxRate / irTraccChannel.ParentModule.SampleRateHz));
var rateRPot1 = Convert.ToInt32(Math.Ceiling(maxRate / rPot1Channel.ParentModule.SampleRateHz));
var rateRPot2 = Convert.ToInt32(Math.Ceiling(maxRate / rPot2Channel.ParentModule.SampleRateHz));
var R0 = aicIRTRACC.LinearizationFormula.CalibrationFactor * Math.Pow(aicIRTRACC.ZeroPoint, aicIRTRACC.LinearizationFormula.LinearizationExponent);
//we are converting to volt as sensitivity is in mV/V and our original calculation is in deg/V/V
var θy0 = aicRPot1.InitialEu; //((1000D/aicRPot1.Sensitivity)/aicRPot1.FactoryExcitationVoltage)*aicRPot1.ZeroPoint;
var θz0 = aicRPOT2.InitialEu; //((1000D/aicRPOT2.Sensitivity)/aicRPOT2.FactoryExcitationVoltage)*aicRPOT2.ZeroPoint;
//all the formulas use the first data point to zero the output channel data, these variables will hold that zero data for out output channels
//this is columns V through Y
var xa1_0 = double.NaN;
var ya1_0 = double.NaN;
var za1_0 = double.NaN;
var dOut_0 = double.NaN;
//your delta and D0 are dependent on your 3D-IRTRACC type, we get the constant for each type from the config file
var δ = 0D;
var D0 = 0D;
switch (irtraccType)
{
case ThreeDIRTraccType.Abdomen:
δ = SensorConstants.δAbdomen;
D0 = SensorConstants.D0Abdomen;
break;
case ThreeDIRTraccType.Thorax:
δ = SensorConstants.δThorax;
D0 = SensorConstants.D0Thorax;
break;
case ThreeDIRTraccType.LowerThorax:
δ = SensorConstants.δThoraxLower;
D0 = SensorConstants.D0ThoraxLower;
break;
default:
throw new NotSupportedException("unsupported irtracc type: " + irtraccType.ToString());
}
//calculates the offset in samples for each channels start relative to the
//latest common start time between channels
var irTraccOffsetStart = (int)(startIRTracc - start) * irTraccChannel.ParentModule.SampleRateHz;
var rPot1OffsetStart = (int)(startRPot1 - start) * rPot1Channel.ParentModule.SampleRateHz;
var rPot2OffsetStart = (int)(startRPot2 - start) * rPot2Channel.ParentModule.SampleRateHz;
//go through all samples in the output, calculate the index for each channel and do some calcs
for (var i = 0; i < length; i++)
{
//this is the index for the given time, this index could be theoretical
//and doesn't exist (ie 1.5)
var indexAtCurrentTimeIRTracc = (i - irTraccOffsetStart) / rateIRTracc;
//this is the actual index that physically exists (1 for 1.5 for instance)
var actualIndexAtCurrentTimeIRTracc = Convert.ToInt32(Math.Floor(indexAtCurrentTimeIRTracc));
//this is the linear interpolation "step" between this sample and the next
//sample
var stepIRTracc = Convert.ToInt32(Math.Ceiling(indexAtCurrentTimeIRTracc) - actualIndexAtCurrentTimeIRTracc);
var indexAtCurrentTimeRPot1 = (i - rPot1OffsetStart) / rateRPot1;
var actualIndexAtCurrentTimeRPot1 = Convert.ToInt32(Math.Floor(indexAtCurrentTimeRPot1));
var stepRPot1 = Convert.ToInt32(Math.Ceiling(indexAtCurrentTimeIRTracc) - actualIndexAtCurrentTimeIRTracc);
var indexAtCurrentTimeRPot2 = (i - rPot2OffsetStart) / rateRPot2;
var actualIndexAtCurrentTimeRPot2 = Convert.ToInt32(Math.Floor(indexAtCurrentTimeRPot2));
var stepRPot2 = Convert.ToInt32(Math.Ceiling(indexAtCurrentTimeRPot2) - actualIndexAtCurrentTimeRPot2);
var incrementIRTracc = 0D;
var valueIRTraccAtPoint = irTraccEUData[actualIndexAtCurrentTimeIRTracc];
var incrementRPot1 = 0D;
var valueRPot1AtPoint = rPot1EUData[actualIndexAtCurrentTimeRPot1];
var incrementRPot2 = 0D;
var valueRPot2AtPoint = rPot2EUData[actualIndexAtCurrentTimeRPot2];
//calculate the interpolation value per step for channel
//for instance for 10k and 20k sps for sample 2 of the 10k
//increment would be (data[2]-data[1])/2
if ((1 + actualIndexAtCurrentTimeIRTracc) < irTraccEUData.Count)
{
incrementIRTracc = (irTraccEUData[1 + actualIndexAtCurrentTimeIRTracc] - valueIRTraccAtPoint) / rateIRTracc;
}
else
{
incrementIRTracc = (valueIRTraccAtPoint - irTraccEUData[actualIndexAtCurrentTimeIRTracc - 1]) / rateIRTracc;
}
if ((1 + actualIndexAtCurrentTimeRPot1) < rPot1EUData.Count)
{
incrementRPot1 = (rPot1EUData[1 + actualIndexAtCurrentTimeRPot1] - valueRPot1AtPoint) / rateRPot1;
}
else
{
incrementRPot1 = (valueRPot1AtPoint - rPot1EUData[actualIndexAtCurrentTimeRPot1 - 1]) / rateRPot1;
}
if ((1 + actualIndexAtCurrentTimeRPot2) < rPot2EUData.Count)
{
incrementRPot2 = (rPot2EUData[1 + actualIndexAtCurrentTimeRPot2] - valueRPot2AtPoint) / rateRPot2;
}
else
{
incrementRPot2 = (valueRPot2AtPoint = rPot2EUData[actualIndexAtCurrentTimeRPot2 - 1]) / rateRPot2;
}
//math magic from excel
//double b = D0 + System.Math.Abs(irTraccEUData[i] - calFactorInterceptRemoval) - R0;
//double R = aicIRTRACC.LinearizationFormula.CalibrationFactor*
// System.Math.Pow(irTraccmVData[i]/1000D, aicIRTRACC.LinearizationFormula.LinearizationExponent);
//D0+(R-R0) this is column N
//double r = D0 + (R - R0);
var r = valueIRTraccAtPoint + incrementIRTracc * stepIRTracc;
//θy'=θy-θy0 this is column O
var θyprime = valueRPot1AtPoint + incrementRPot1 * stepRPot1 - θy0;
//θz'=θz-θz0 this is column p
var θzprime = valueRPot2AtPoint + incrementRPot2 * stepRPot2 - θz0;
//this is column r
var xa1 = -1D * δ * Math.Sin(θyprime * Math.PI / 180) + r * Math.Cos(θzprime * Math.PI / 180) * Math.Cos(θyprime * Math.PI / 180);
//this is column s
var ya1 = r * Math.Sin(θzprime * Math.PI / 180);
//this is column t
var za1 = -1D * δ * Math.Cos(θyprime * Math.PI / 180D) - r * Math.Cos(θzprime * Math.PI / 180D) * Math.Sin(θyprime * Math.PI / 180D);
//assign the output channel zero points if needed
if (double.IsNaN(xa1_0)) { xa1_0 = xa1; }
if (double.IsNaN(ya1_0)) { ya1_0 = ya1; }
if (double.IsNaN(za1_0)) { za1_0 = za1; }
//add in our data to the output channels
dAX.Add(xa1 - xa1_0);
dAY.Add(ya1 - ya1_0);
dAZ.Add(za1 - za1_0);
//this is column Z
var temp = Math.Sqrt(Math.Pow(r, 2) + Math.Pow(δ, 2));
if (double.IsNaN(dOut_0)) { dOut_0 = temp; }
dOut.Add(temp - dOut_0);
}
}
private static double GetTimeOfFirstSample(Event.Module.Channel channel)
{
return ((double)channel.ParentModule.TriggerSampleNumbers[0] -
channel.ParentModule.StartRecordSampleNumber) / channel.ParentModule.SampleRateHz;
}
private static Test.Module.CalculatedChannel[] Create3DIRTraccChannels(string testId, string folder,
List<Test.Module.Channel> inputChannels, string channelName, ThreeDIRTraccType irTraccType, int offset, int defaultEncoding)
{
System.Diagnostics.Trace.Assert(3 == inputChannels.Count, "3D IR-TRACC requires 3 channels");
var maxRate = inputChannels.Select(ch => ch.ParentModule.SampleRateHz).Max();
var distinctRates = inputChannels.Select(ch => ch.ParentModule.SampleRateHz).Distinct().ToArray();
foreach (var rate in distinctRates)
{
if (0 != maxRate % rate)
{
throw new NotSupportedException($"Sample rate: {maxRate} is not a multiple of sample rate: {rate}");
}
}
if (distinctRates.Length > 1)
{
var eventAggregator = ContainerLocator.Container.Resolve<IEventAggregator>();
eventAggregator.GetEvent<PageErrorEvent>().Publish(new PageErrorArg(new[] { Resources.StringResources.SuperSamplingWarning }, null));
}
var irtraccEMC = inputChannels[0].emc as Event.Module.Channel;
var rPot1EMC = inputChannels[1].emc as Event.Module.Channel;
var rPot2EMC = inputChannels[2].emc as Event.Module.Channel;
var calc = Calculation.ThreeDIRTracc;
switch (irTraccType)
{
case ThreeDIRTraccType.Abdomen: calc = Calculation.ThreeDIRTraccAbdomen; break;
case ThreeDIRTraccType.Thorax: calc = Calculation.ThreeDIRTracc; break;
case ThreeDIRTraccType.LowerThorax: calc = Calculation.ThreeDIRTraccLowerThorax; break;
}
var ccDeltaAX = CreateCalculatedChannelsIRTRACC(calc, new[] { inputChannels[0], inputChannels[1], inputChannels[2] });
ccDeltaAX.ChannelDescriptionString = channelName + " (dAX)";
var ccDeltaAY = CreateCalculatedChannelsIRTRACC(calc, new[] { inputChannels[0], inputChannels[1], inputChannels[2] });
ccDeltaAY.ChannelDescriptionString = channelName + " (dAY)";
var ccDeltaAZ = CreateCalculatedChannelsIRTRACC(calc, new[] { inputChannels[0], inputChannels[1], inputChannels[2] });
ccDeltaAZ.ChannelDescriptionString = channelName + " (dAZ)";
var ccDistanceDelta = CreateCalculatedChannelsIRTRACC(calc, new[] { inputChannels[0], inputChannels[1], inputChannels[2] });
ccDistanceDelta.ChannelDescriptionString = channelName;
var outputChannels = new Test.Module.CalculatedChannel[] { ccDeltaAX, ccDeltaAY, ccDeltaAZ, ccDistanceDelta };
foreach (var cc in outputChannels)
{
cc.Calculation = calc.ToString();
cc.AbsoluteDisplayOrder = ChannelNumberCalculationChannelIndicator + irtraccEMC.AbsoluteDisplayOrder + offset;
cc.Number = ChannelNumberCalculationChannelIndicator + offset;
cc.ProportionalToExcitation = false;
cc.ZeroMvInADC = 0;
cc.OriginalOffsetADC = 0;
cc.Data.MvPerEu = 1;
cc.Data.Multiplier = 1;
cc.Data.UnitConversion = 1;
cc.Data.UserOffsetEU = 0;
cc.ExcitationVoltage = 0;
cc.Excitation = 0;
cc.ZeroMethod = ZeroMethodType.None;
cc.RemoveOffset = false;
cc.ChannelId = irtraccEMC.ChannelId + "_" + (cc.Number + offset);
cc.ChannelGroupName = irtraccEMC.ChannelGroupName;
cc.IsInverted = false;
cc.PreTestZeroLevelAdc = 0;
cc.SerialNumber = cc.ChannelDescriptionString;
var emc = new Event.Module.AnalogInputChannel(cc, irtraccEMC.ParentModule, cc.Number);
cc.emc = emc;
offset++;
}
ccDeltaAX.EngineeringUnits = "mm";
ccDeltaAY.EngineeringUnits = "mm";
ccDeltaAZ.EngineeringUnits = "mm";
ccDistanceDelta.EngineeringUnits = "mm";
PerformCalculation(out IList<double> dax, out IList<double> day, out IList<double> daz, out IList<double> dDistance, inputChannels[0], inputChannels[1], inputChannels[2], irTraccType);
irtraccEMC = null;
rPot1EMC = null;
rPot2EMC = null;
var datas = new[] { dax, day, daz, dDistance };
for (var i = 0; i < datas.Length && i < outputChannels.Length; i++)
{
var data = datas[i];
var scaleFactor = 0D;
var adcData = ScaleEuData(ref data, out scaleFactor);
outputChannels[i].Sensitivity = scaleFactor;
outputChannels[i].DesiredRange = Constants.ADC_MIDPOINT / scaleFactor;
//adjust the output channel with the max rate we super sampled to
//and update the number of samples...
outputChannels[i].SampleRateHz = maxRate;
outputChannels[i].ParentModule.NumberOfSamples = Convert.ToUInt64(data.Count);
((Event.Module.AnalogInputChannel)outputChannels[i].emc).ParentModule.SampleRateHz = maxRate;
((Event.Module.AnalogInputChannel)outputChannels[i].emc).ParentModule.NumberOfSamples = Convert.ToUInt64(data.Count);
var f = new Serialization.SliceRaw.File { DefaultEncoding = defaultEncoding };
var fileName = new Serialization.SliceRaw.File().GetCalculatedChannelFileNameFromTestNameAndChannelNumber(testId, outputChannels[i].Number);
var filepath = System.IO.Path.Combine(folder, fileName);
outputChannels[i].Data.ScaleFactorMv = 1 / scaleFactor;
outputChannels[i].Data.ScaleFactorEU = 1 / scaleFactor;
outputChannels[i].LinearizationFormula.MarkValid(false);
outputChannels[i].PersistentChannelInfo = CreatePersistentInformationObject(outputChannels[i], filepath);
outputChannels[i].PersistentChannelInfo.BeginAppendSession();
outputChannels[i].PersistentChannelInfo.AppendSessionData(adcData.ToArray());
outputChannels[i].PersistentChannelInfo.EndAppendSession();
var writer = (f.Exporter as Serialization.SliceRaw.File.Writer);
writer?.CreatePersistentChannel(outputChannels[i], outputChannels[i].ParentModule.NumberOfSamples, outputChannels[i].ParentModule.SampleRateHz, null, null, 0, 0);
var bypass = false;
var reader = f.Importer as Serialization.SliceRaw.File.Reader;
reader?.ReadChannel(outputChannels[i], outputChannels[i].ParentModule, filepath, ref bypass);
(outputChannels[i].emc as Event.Module.Channel).UnfilteredData = outputChannels[i].PersistentChannelInfo;
(outputChannels[i].emc as Event.Module.Channel).Scaler.SetScaleFactorMv(1D / scaleFactor);
}
return outputChannels.ToArray();
}
private static Test.Module.CalculatedChannel[] CreateChannelsAggregateOperation(string testId, string folder,
Calculation calculation, List<Test.Module.Channel> inputChannels, string channelName, int channelOffset, int clipLength)
{
System.Diagnostics.Trace.Assert(1 < inputChannels.Count,
calculation.ToString() + " requires at least 1 channel");
var sourceEmc = inputChannels[0].emc as Event.Module.Channel;
var sourceChannel = inputChannels[0];
var maxSampleRate = inputChannels.Select(ch => ch.ParentModule.SampleRateHz).Max();
var distinctRates = inputChannels.Select(ch => ch.ParentModule.SampleRateHz).Distinct().ToArray();
foreach (var rate in distinctRates)
{
if (maxSampleRate % rate != 0)
{
throw new NotSupportedException($"Sample rate: {maxSampleRate} is not a multiple of {rate}");
}
}
if (distinctRates.Length > 1)
{
var eventAggregator = ContainerLocator.Container.Resolve<IEventAggregator>();
eventAggregator.GetEvent<PageErrorEvent>().Publish(new PageErrorArg(new[] { Resources.StringResources.SuperSamplingWarning }, null));
}
//Create new test channel
var cc = CreateCalculatedChannelsIRTRACC(calculation, new[] { sourceChannel });
cc.SampleRateHz = maxSampleRate;
cc.Calculation = calculation.ToString();
cc.ChannelDescriptionString = channelName;
cc.AbsoluteDisplayOrder = ChannelNumberCalculationChannelIndicator + channelOffset;
cc.Number = ChannelNumberCalculationChannelIndicator + channelOffset;
cc.ProportionalToExcitation = false;
cc.ZeroMvInADC = 0;
cc.OriginalOffsetADC = 0;
cc.Data.MvPerEu = 1;
cc.Data.Multiplier = sourceEmc.Multiplier;
cc.Data.UnitConversion = sourceEmc.UnitConversion;
cc.Data.UserOffsetEU = sourceEmc.UserOffsetEU;
cc.ExcitationVoltage = 0;
cc.Excitation = 0;
cc.ZeroMethod = ZeroMethodType.None;
cc.RemoveOffset = false;
cc.ChannelId = sourceChannel.ChannelId + "_" + cc.Number;
cc.ChannelGroupName = sourceChannel.ChannelGroupName;
cc.IsInverted = false;
var emc = new Event.Module.AnalogInputChannel(cc, sourceEmc.ParentModule, sourceEmc.AbsoluteNumber);
cc.emc = emc;
//Do the maths. Use source channel as source for data as it's properly set up.
var euData = PerformCalculationsAggregate(calculation, inputChannels);
cc.ParentModule.NumberOfSamples = Convert.ToUInt64(euData.Count);
emc.ParentModule.NumberOfSamples = Convert.ToUInt64(euData.Count);
//Don't use the source channel emc anymore.
sourceEmc = null;
//Scale the data
var adcData = ScaleEuData(ref euData, out double scaleFactor);
cc.Sensitivity = scaleFactor;
//Test by writing source channel data. Readback should be identical
var f = new Serialization.SliceRaw.File();
f.DefaultEncoding = Encoding.Unicode.CodePage;
//Create file with from source channel. At this point it's not complete -- it still needs number of
//samples, etc.
var filename = new Serialization.SliceRaw.File().GetCalculatedChannelFileNameFromTestNameAndChannelNumber(testId, cc.Number);
var filepath = System.IO.Path.Combine(folder, filename);
cc.Data.ScaleFactorMv = 1 / scaleFactor;
cc.Data.ScaleFactorEU = 1 / scaleFactor;
switch (calculation)
{
default:
cc.DesiredRange = Constants.ADC_MIDPOINT / scaleFactor;
if (sourceChannel is Test.Module.AnalogInputChannel analogInputChannel) { cc.EngineeringUnits = analogInputChannel.EngineeringUnits; }
else { cc.EngineeringUnits = "NOT DEFINED"; }
break;
case Calculation.Sin:
case Calculation.Cos:
cc.DesiredRange = 1.1;
cc.EngineeringUnits = "rads";
break;
}
//All done with channel. Create persistent object with what's in the channel object
cc.PersistentChannelInfo = CreatePersistentInformationObject(cc, filepath);
//Write out the data to the memory-mapped file
cc.PersistentChannelInfo.BeginAppendSession();
cc.PersistentChannelInfo.AppendSessionData(adcData.ToArray());
cc.PersistentChannelInfo.EndAppendSession();
//Use the export writer to update the binary channel fields with everything that's missing. This will also
//Update the CRC.
var writer = (f.Exporter as Serialization.SliceRaw.File.Writer);
writer.CreatePersistentChannel(cc, cc.ParentModule.NumberOfSamples, cc.ParentModule.SampleRateHz, null, null, 0, 0);
//At this point the PersistentChannel is blown away. Read it back in and hook it up.
var bypass = false;
(f.Importer as Serialization.SliceRaw.File.Reader).ReadChannel(cc, cc.ParentModule, filepath, ref bypass);
emc.UnfilteredData = cc.PersistentChannelInfo;
if (calculation == Calculation.HIC)
{
var channelData = new ChannelData("g");
channelData.FilteredEU = euData.ToArray();
var hic = HeadInjuryCriterion.GetHeadInjuryCriterion(channelData, cc.SampleRateHz, clipLength);
cc.T1 = Convert.ToUInt64(hic.StartSample);
cc.T2 = Convert.ToUInt64(hic.EndSample);
cc.HIC = hic.HIC;
}
return new[] { cc };
}
/// <summary>
/// creates a calculated channel for binary operations (sine/cosine/integral/ffs)
/// </summary>
/// <param name="testId"></param>
/// <param name="folder"></param>
/// <param name="calculation"></param>
/// <param name="inputChannels"></param>
/// <param name="channelName"></param>
/// <param name="channelOffset"></param>
/// <returns></returns>
private static Test.Module.CalculatedChannel[] CreateChannelsBinaryOperation(string testId, string folder,
Calculation calculation, List<Test.Module.Channel> inputChannels, string channelName, int channelOffset)
{
var sourceEmc = inputChannels[0].emc as Event.Module.Channel;
var sourceChannel = inputChannels[0];
//Create new test channel
var cc = CreateCalculatedChannelsIRTRACC(calculation, new[] { sourceChannel });
cc.Calculation = calculation.ToString();
cc.ChannelDescriptionString = channelName;
cc.AbsoluteDisplayOrder = ChannelNumberCalculationChannelIndicator + channelOffset;
cc.Number = ChannelNumberCalculationChannelIndicator + channelOffset;
cc.ProportionalToExcitation = false;
cc.ZeroMvInADC = 0;
cc.OriginalOffsetADC = 0;
cc.Data.MvPerEu = 1;
cc.Data.Multiplier = sourceEmc.Multiplier;
cc.Data.UnitConversion = sourceEmc.UnitConversion;
cc.Data.UserOffsetEU = sourceEmc.UserOffsetEU;
cc.Excitation = 0;
cc.ZeroMethod = ZeroMethodType.None;
cc.RemoveOffset = false;
cc.ChannelId = sourceChannel.ChannelId + "_" + cc.Number;
cc.ChannelGroupName = sourceChannel.ChannelGroupName;
cc.IsInverted = false;
var emc = new Event.Module.AnalogInputChannel(cc, sourceEmc.ParentModule, sourceEmc.AbsoluteNumber);
cc.emc = emc;
//Do the maths. Use source channel as source for data as it's properly set up.
var euData = PerformCalculationBinary(calculation, sourceEmc);
//Don't use the source channel emc anymore.
sourceEmc = null;
//Scale the data
var adcData = ScaleEuData(ref euData, out var scaleFactor);
cc.Sensitivity = scaleFactor;
//Test by writing source channel data. Readback should be identical
var f = new Serialization.SliceRaw.File { DefaultEncoding = Encoding.Unicode.CodePage };
//Create file with from source channel. At this point it's not complete -- it still needs number of
//samples, etc.
var filename = new Serialization.SliceRaw.File().GetCalculatedChannelFileNameFromTestNameAndChannelNumber(testId, cc.Number);
var filepath = System.IO.Path.Combine(folder, filename);
cc.Data.ScaleFactorMv = 1 / scaleFactor;
cc.Data.ScaleFactorEU = 1 / scaleFactor;
switch (calculation)
{
default:
cc.DesiredRange = Constants.ADC_MIDPOINT / scaleFactor;
if (sourceChannel is Test.Module.AnalogInputChannel analogInputChannel) { cc.EngineeringUnits = analogInputChannel.EngineeringUnits; }
else { cc.EngineeringUnits = "NOT DEFINED"; }
break;
case Calculation.Sin:
case Calculation.Cos:
cc.DesiredRange = 1.1;
cc.EngineeringUnits = "rads";
break;
}
//All done with channel. Create persistent object with what's in the channel object
cc.PersistentChannelInfo = CreatePersistentInformationObject(cc, filepath);
//Write out the data to the memory-mapped file
cc.PersistentChannelInfo.BeginAppendSession();
cc.PersistentChannelInfo.AppendSessionData(adcData.ToArray());
cc.PersistentChannelInfo.EndAppendSession();
//Use the export writer to update the binary channel fields with everything that's missing. This will also
//Update the CRC.
var writer = (f.Exporter as Serialization.SliceRaw.File.Writer);
writer.CreatePersistentChannel(cc, cc.ParentModule.NumberOfSamples, cc.ParentModule.SampleRateHz, null, null, 0, 0);
//At this point the PersistentChannel is blown away. Read it back in and hook it up.
var bypass = false;
(f.Importer as Serialization.SliceRaw.File.Reader).ReadChannel(cc, cc.ParentModule, filepath,
ref bypass);
emc.UnfilteredData = cc.PersistentChannelInfo;
return new[] { cc };
}
public enum ThreeDIRTraccType
{
Thorax,
Abdomen,
LowerThorax
}
private static short[] ScaleEuData(ref IList<double> euData, out double scaleFactor)
{
scaleFactor = 1.0;
var max = (from d in euData select Math.Abs(d)).Max();
if (0 == max)
{
max = 1;
}
//we used ABS above, so we need to consider that the signal could be bipolar and be peak to peak of 2*max
max *= 2;
if (short.MaxValue > max)
{
scaleFactor = short.MaxValue / max;
}
else
{
scaleFactor = max / short.MaxValue;
}
//Scale the data
var data = new List<short>();
foreach (var euSample in euData)
{
data.Add((short)(euSample * scaleFactor));
}
return data.ToArray();
}
/// <summary>
/// Validate name of the new calculated channel
/// </summary>
/// <param name="channelName">name of the new calculated channel</param>
/// <param name="inputChannels">existing channels</param>
/// <param name="allChannels">If null - calling form MakeCalculatedChannels() in Download.xaml.cs</param>
/// <param name="errorList">list of errors</param>
/// <returns>if anyy errors - returns false</returns>
public static bool ValidateChannelName(string channelName, List<Test.Module.Channel> inputChannels, List<Test.Module.Channel> allChannels, out List<string> errorList)
{
errorList = new List<string>();
if (allChannels == null) return errorList.Count == 0;
if (string.IsNullOrEmpty(channelName)) { errorList.Add("Channel name cannot be empty."); }
if (inputChannels.Exists(ch => ch.ChannelDescriptionString == channelName))
{ errorList.Add("Channel name is not unique. [input channels]"); }
if (allChannels.Exists(ch => ch.ChannelDescriptionString == channelName))
{ errorList.Add("Channel name is not unique. [all channels]"); }
return errorList.Count == 0;
}
#region helper classes
private sealed class ClonableDoubles : List<double>, ICloneable
{
object ICloneable.Clone()
{
var l = new List<double>();
l.AddRange(ToArray());
return l;
}
}
#endregion
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DTS.Viewer.AddCalculatedChannel")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DTS.Viewer.AddCalculatedChannel")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("6451f3ed-934e-47e3-a1ca-33c223a6507a")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,387 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace DTS.Viewer.AddCalculatedChannel.Resources {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class StringResources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal StringResources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DTS.Viewer.AddCalculatedChannel.Resources.StringResources", typeof(StringResources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Add Calculated Channel.
/// </summary>
internal static string AddCalculatedChannel {
get {
return ResourceManager.GetString("AddCalculatedChannel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Average.
/// </summary>
internal static string CalculatedChannel_Average {
get {
return ResourceManager.GetString("CalculatedChannel_Average", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 3D IR-TRACC (upper thorax).
/// </summary>
internal static string CalculatedChannel_IRTRACC3D {
get {
return ResourceManager.GetString("CalculatedChannel_IRTRACC3D", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 3D IR-TRACC (abdomen).
/// </summary>
internal static string CalculatedChannel_IRTRACC3D_Abdomen {
get {
return ResourceManager.GetString("CalculatedChannel_IRTRACC3D_Abdomen", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 3D IR-TRACC (lower thorax).
/// </summary>
internal static string CalculatedChannel_IRTRACC3D_LowerThorax {
get {
return ResourceManager.GetString("CalculatedChannel_IRTRACC3D_LowerThorax", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 3D IR-TRACC (thorax).
/// </summary>
internal static string CalculatedChannel_IRTRACC3D_Thorax {
get {
return ResourceManager.GetString("CalculatedChannel_IRTRACC3D_Thorax", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 3D IR-TRACC (abdomen).
/// </summary>
internal static string CalculatedChannel_IRTRACC3DAbdomen {
get {
return ResourceManager.GetString("CalculatedChannel_IRTRACC3DAbdomen", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 3D IR-TRACC (lower thorax).
/// </summary>
internal static string CalculatedChannel_IRTRACC3DLowerThorax {
get {
return ResourceManager.GetString("CalculatedChannel_IRTRACC3DLowerThorax", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sum.
/// </summary>
internal static string CalculatedChannel_Sum {
get {
return ResourceManager.GetString("CalculatedChannel_Sum", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Calculation.
/// </summary>
internal static string Calculation {
get {
return ResourceManager.GetString("Calculation", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cosine.
/// </summary>
internal static string CALCULATION_Cos {
get {
return ResourceManager.GetString("CALCULATION_Cos", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Derivative.
/// </summary>
internal static string CALCULATION_Derivative {
get {
return ResourceManager.GetString("CALCULATION_Derivative", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Double integral.
/// </summary>
internal static string CALCULATION_DoubleIntegral {
get {
return ResourceManager.GetString("CALCULATION_DoubleIntegral", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Integral.
/// </summary>
internal static string CALCULATION_Integral {
get {
return ResourceManager.GetString("CALCULATION_Integral", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sine.
/// </summary>
internal static string CALCULATION_Sin {
get {
return ResourceManager.GetString("CALCULATION_Sin", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 3D IR-TRACC (upper thorax).
/// </summary>
internal static string CALCULATION_ThreeDIRTracc {
get {
return ResourceManager.GetString("CALCULATION_ThreeDIRTracc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 3D IR-TRACC (abdomen).
/// </summary>
internal static string CALCULATION_ThreeDIRTraccAbdomen {
get {
return ResourceManager.GetString("CALCULATION_ThreeDIRTraccAbdomen", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 3D IR-TRACC (lower thorax).
/// </summary>
internal static string CALCULATION_ThreeDIRTraccLowerThorax {
get {
return ResourceManager.GetString("CALCULATION_ThreeDIRTraccLowerThorax", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Calculation Input Channel.
/// </summary>
internal static string CalculationInputChannel {
get {
return ResourceManager.GetString("CalculationInputChannel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Channel.
/// </summary>
internal static string Channel {
get {
return ResourceManager.GetString("Channel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Channel Name.
/// </summary>
internal static string ChannelName {
get {
return ResourceManager.GetString("ChannelName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Clip length (ms).
/// </summary>
internal static string ClipLengthMS {
get {
return ResourceManager.GetString("ClipLengthMS", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Description.
/// </summary>
internal static string Description {
get {
return ResourceManager.GetString("Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Acceleration X.
/// </summary>
internal static string HICAccelerationX {
get {
return ResourceManager.GetString("HICAccelerationX", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Acceleration Y.
/// </summary>
internal static string HICAccelerationY {
get {
return ResourceManager.GetString("HICAccelerationY", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to AccelerationZ.
/// </summary>
internal static string HICAccelerationZ {
get {
return ResourceManager.GetString("HICAccelerationZ", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error: Head injury criterion requires 3 channels.
/// </summary>
internal static string HICRequires3Channels {
get {
return ResourceManager.GetString("HICRequires3Channels", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Input channels.
/// </summary>
internal static string InputChannels {
get {
return ResourceManager.GetString("InputChannels", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to ISO Code.
/// </summary>
internal static string ISOCode {
get {
return ResourceManager.GetString("ISOCode", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error: No channels included.
/// </summary>
internal static string NoChannelsIncluded {
get {
return ResourceManager.GetString("NoChannelsIncluded", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error: Units don&apos;t match for all input channels.
/// </summary>
internal static string ResultantUnitsDontMatch {
get {
return ResourceManager.GetString("ResultantUnitsDontMatch", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error: Sample rates don&apos;t match for all input channels.
/// </summary>
internal static string SampleRatesDontMatch {
get {
return ResourceManager.GetString("SampleRatesDontMatch", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Calculation contains multiple sample rates. Input will be resampled to the highest sample rate using linear interpolation..
/// </summary>
internal static string SuperSamplingWarning {
get {
return ResourceManager.GetString("SuperSamplingWarning", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to IR-TRACC.
/// </summary>
internal static string ThreeD_IRTracc {
get {
return ResourceManager.GetString("ThreeD_IRTracc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to R. Pot Y.
/// </summary>
internal static string ThreeD_RotPot1 {
get {
return ResourceManager.GetString("ThreeD_RotPot1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to R. Pot Z.
/// </summary>
internal static string ThreeD_RotPot2 {
get {
return ResourceManager.GetString("ThreeD_RotPot2", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,228 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AddCalculatedChannel" xml:space="preserve">
<value>Add Calculated Channel</value>
</data>
<data name="Calculation" xml:space="preserve">
<value>Calculation</value>
</data>
<data name="CalculationInputChannel" xml:space="preserve">
<value>Calculation Input Channel</value>
</data>
<data name="Channel" xml:space="preserve">
<value>Channel</value>
</data>
<data name="ChannelName" xml:space="preserve">
<value>Channel Name</value>
</data>
<data name="Description" xml:space="preserve">
<value>Description</value>
</data>
<data name="InputChannels" xml:space="preserve">
<value>Input channels</value>
</data>
<data name="ISOCode" xml:space="preserve">
<value>ISO Code</value>
</data>
<data name="CalculatedChannel_Average" xml:space="preserve">
<value>Average</value>
</data>
<data name="CalculatedChannel_IRTRACC3D" xml:space="preserve">
<value>3D IR-TRACC (upper thorax)</value>
</data>
<data name="CalculatedChannel_IRTRACC3DAbdomen" xml:space="preserve">
<value>3D IR-TRACC (abdomen)</value>
</data>
<data name="CalculatedChannel_IRTRACC3DLowerThorax" xml:space="preserve">
<value>3D IR-TRACC (lower thorax)</value>
</data>
<data name="CalculatedChannel_IRTRACC3D_Abdomen" xml:space="preserve">
<value>3D IR-TRACC (abdomen)</value>
</data>
<data name="CalculatedChannel_IRTRACC3D_LowerThorax" xml:space="preserve">
<value>3D IR-TRACC (lower thorax)</value>
</data>
<data name="CalculatedChannel_IRTRACC3D_Thorax" xml:space="preserve">
<value>3D IR-TRACC (thorax)</value>
</data>
<data name="CalculatedChannel_Sum" xml:space="preserve">
<value>Sum</value>
</data>
<data name="CALCULATION_Cos" xml:space="preserve">
<value>Cosine</value>
</data>
<data name="CALCULATION_Derivative" xml:space="preserve">
<value>Derivative</value>
</data>
<data name="CALCULATION_DoubleIntegral" xml:space="preserve">
<value>Double integral</value>
</data>
<data name="CALCULATION_Integral" xml:space="preserve">
<value>Integral</value>
</data>
<data name="CALCULATION_Sin" xml:space="preserve">
<value>Sine</value>
</data>
<data name="CALCULATION_ThreeDIRTracc" xml:space="preserve">
<value>3D IR-TRACC (upper thorax)</value>
</data>
<data name="CALCULATION_ThreeDIRTraccAbdomen" xml:space="preserve">
<value>3D IR-TRACC (abdomen)</value>
</data>
<data name="CALCULATION_ThreeDIRTraccLowerThorax" xml:space="preserve">
<value>3D IR-TRACC (lower thorax)</value>
</data>
<data name="ThreeD_IRTracc" xml:space="preserve">
<value>IR-TRACC</value>
</data>
<data name="ThreeD_RotPot1" xml:space="preserve">
<value>R. Pot Y</value>
</data>
<data name="ThreeD_RotPot2" xml:space="preserve">
<value>R. Pot Z</value>
</data>
<data name="SuperSamplingWarning" xml:space="preserve">
<value>Calculation contains multiple sample rates. Input will be resampled to the highest sample rate using linear interpolation.</value>
</data>
<data name="ClipLengthMS" xml:space="preserve">
<value>Clip length (ms)</value>
</data>
<data name="HICAccelerationX" xml:space="preserve">
<value>Acceleration X</value>
</data>
<data name="HICAccelerationY" xml:space="preserve">
<value>Acceleration Y</value>
</data>
<data name="HICAccelerationZ" xml:space="preserve">
<value>AccelerationZ</value>
</data>
<data name="HICRequires3Channels" xml:space="preserve">
<value>Error: Head injury criterion requires 3 channels</value>
</data>
<data name="NoChannelsIncluded" xml:space="preserve">
<value>Error: No channels included</value>
</data>
<data name="ResultantUnitsDontMatch" xml:space="preserve">
<value>Error: Units don't match for all input channels</value>
</data>
<data name="SampleRatesDontMatch" xml:space="preserve">
<value>Error: Sample rates don't match for all input channels</value>
</data>
</root>

View File

@@ -0,0 +1,21 @@
using System;
using System.Windows.Markup;
using DTS.Viewer.AddCalculatedChannel.Resources;
namespace DTS.Viewer.AddCalculatedChannel
{
[MarkupExtensionReturnType(typeof(string))]
public class TranslateExtension : MarkupExtension
{
private readonly string _key;
public TranslateExtension(string key) { _key = key; }
private const string NotFound = "#stringnotfound#";
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (string.IsNullOrEmpty(_key)) { return NotFound; }
return StringResources.ResourceManager.GetString(_key) ?? NotFound + " " + _key;
}
}
}

View File

@@ -0,0 +1,175 @@
<base:BaseView x:Class="DTS.Viewer.AddCalculatedChannel.AddCalculatedChannelView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:base="clr-namespace:DTS.Common.Base;assembly=DTS.Common"
xmlns:root="clr-namespace:DTS.Viewer.AddCalculatedChannel"
xmlns:toolkit="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:converters="clr-namespace:DTS.Common.Converters;assembly=DTS.Common"
xmlns:controls="clr-namespace:DTS.Common.Controls;assembly=DTS.Common"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<base:BaseView.Resources>
<Style TargetType="TextBox" BasedOn="{StaticResource PageContentTextBoxStyle}" />
<Style TargetType="TextBlock" BasedOn="{StaticResource PageContentTextStyle}" />
<Style TargetType="CheckBox" BasedOn="{StaticResource PageContentCheckBoxStyle}" />
<Style TargetType="PasswordBox" BasedOn="{StaticResource PageContentPasswordBoxStyle}" />
<Style TargetType="Button" BasedOn="{StaticResource FlatButton}"/>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<Style TargetType="toolkit:DoubleUpDown" BasedOn="{StaticResource PageContentXCDoubleUpDown}">
<Setter Property="Width" Value="150"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="FormatString" Value="N0"/>
<Setter Property="Increment" Value="1"/>
</Style>
<sys:Double x:Key="HIC_LENGTH_MIN">1</sys:Double>
<sys:Double x:Key="HIC_LENGTH_MAX">100</sys:Double>
</base:BaseView.Resources>
<Grid Background="{StaticResource Brush_ApplicationContentBackground}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- Page Title -->
<TextBlock Style="{StaticResource BaselineTextStyle4}" Text="{root:TranslateExtension AddCalculatedChannel}" Grid.Row="0"/>
<!-- Content-->
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto" MinWidth="480"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Channel Name-->
<TextBlock Grid.Column="0" Grid.Row="0" Text="{root:TranslateExtension ChannelName}"/>
<TextBox Grid.Column="1" Grid.Row="0" Text="{Binding ChannelName, Mode=TwoWay, FallbackValue=Integration}" x:Name="tbChannelName" MaxLength="100" />
<!-- Channel Description-->
<TextBlock Grid.Column="0" Grid.Row="1" Text="{root:TranslateExtension Description}" Visibility="Collapsed"/>
<TextBox Grid.Column="1" Grid.Row="1" Text="{Binding ChannelDescription, Mode=TwoWay}" IsEnabled="False" x:Name="tbChannelDescription" Visibility="Collapsed"/>
<!-- ISO Code-->
<TextBlock Grid.Column="0" Grid.Row="2" Text="{root:TranslateExtension ISOCode}"/>
<TextBox Grid.Column="1" Grid.Row="2" Text="{Binding IsoCode, Mode=TwoWay, FallbackValue=????????????????}" MaxLength="25"/>
<!-- Calculation Type -->
<TextBlock Grid.Column="0" Grid.Row="3" Text="{root:TranslateExtension Calculation}"/>
<ComboBox Grid.Column="1" Grid.Row="3" ItemsSource="{Binding CalculationList}" SelectedItem="{Binding SelectedCalculation}" /><!--SelectionChanged="cbCalculationList_SelectionChanged" x:Name="cbCalculationList"/>-->
<!--multiple channel selector-->
<TextBlock Grid.Column="0" Grid.Row="4" Visibility="{Binding MultipleChannelSelectorVisibility, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Visible}" Text="{root:TranslateExtension InputChannels}" VerticalAlignment="Top"/>
<!-- Single Channel Selector -->
<TextBlock Grid.Column="0" Grid.Row="4" Text="{root:TranslateExtension CalculationInputChannel}" Visibility="{Binding SingleChannelSelectorVisibility, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Collapsed}"/>
<ComboBox Grid.Column="1" Grid.Row="4" ItemsSource="{Binding ChannelList}" SelectedItem="{Binding SourceChannel}" Visibility="{Binding SingleChannelSelectorVisibility, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Collapsed}" />
<!--multiple channel selector-->
<ListView ItemsSource="{Binding ChannelListObjects}" Grid.Row="4" Grid.Column="1" Visibility="{Binding MultipleChannelSelectorVisibility, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Visible}"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListView.View>
<GridView>
<GridViewColumn Header=" " Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsThreeState="False" IsChecked="{Binding Path=IsIncluded}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension Channel}" DisplayMemberBinding="{Binding Path=DisplayName}" />
</GridView>
</ListView.View>
</ListView>
<!--ThreeDIRTRACC-->
<Grid Grid.Row="4" Grid.Column="0" Visibility="{Binding ThreeDIRTRACCVisibility, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Visibility.Collapsed}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Grid.RowSpan="3" Text="{root:TranslateExtension InputChannels}" />
</Grid>
<Grid Grid.Row="4" Grid.Column="1" Visibility="{Binding ThreeDIRTRACCVisibility, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Collapsed}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="{root:TranslateExtension ThreeD_IRTracc}" HorizontalAlignment="Right" VerticalAlignment="Center"/>
<TextBlock Grid.Column="0" Grid.Row="1" Text="{root:TranslateExtension ThreeD_RotPot1}" HorizontalAlignment="Right" VerticalAlignment="Center"/>
<TextBlock Grid.Column="0" Grid.Row="2" Text="{root:TranslateExtension ThreeD_RotPot2}" HorizontalAlignment="Right" VerticalAlignment="Center"/>
<ComboBox Grid.Row="0" ItemsSource="{Binding IRTraccChannelList}" SelectedItem="{Binding IRTraccChannel}" Grid.Column="1" DisplayMemberPath="DisplayName"/>
<ComboBox Grid.Row="1" ItemsSource="{Binding Pot1ChannelList}" SelectedItem="{Binding Pot1Channel}" Grid.Column="1" DisplayMemberPath="DisplayName" />
<ComboBox Grid.Row="2" ItemsSource="{Binding Pot2ChannelList}" SelectedItem="{Binding Pot2Channel}" Grid.Column="1" DisplayMemberPath="DisplayName" />
</Grid>
<!--HIC-->
<StackPanel Grid.Row="4" Grid.Column="0" Orientation="Vertical" Visibility="{Binding HICChannelSelectorVisibility, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Visibility.Collapsed}">
<TextBlock Grid.Row="0" Text="{root:TranslateExtension ClipLengthMS}" />
<TextBlock Grid.Row="1" Text="{root:TranslateExtension HICAccelerationX}" />
<TextBlock Grid.Row="2" Text="{root:TranslateExtension HICAccelerationY}" />
<TextBlock Grid.Row="3" Text="{root:TranslateExtension HICAccelerationZ}" />
</StackPanel>
<StackPanel Grid.Row="4" Grid.Column="1" Visibility="{Binding HICChannelSelectorVisibility, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Collapsed}">
<toolkit:DoubleUpDown Grid.Column="0" Grid.Row="0"
Minimum="{StaticResource HIC_LENGTH_MIN}" Maximum="{StaticResource HIC_LENGTH_MAX}"
Value="{Binding HICLength}" />
<ComboBox Grid.Column="0" Grid.Row="1" ItemsSource="{Binding AvailableHICChannels}" DisplayMemberPath="DisplayName"
AutomationProperties.AutomationId="HICAccelerationXComboBox"
SelectedItem="{Binding HICAccelerationX}" />
<ComboBox Grid.Column="0" Grid.Row="2" ItemsSource="{Binding AvailableHICChannels}" DisplayMemberPath="DisplayName" AutomationProperties.AutomationId="HICAccelerationYComboBox"
SelectedItem="{Binding HICAccelerationY}" />
<ComboBox Grid.Column="0" Grid.Row="3" ItemsSource="{Binding AvailableHICChannels}" DisplayMemberPath="DisplayName" AutomationProperties.AutomationId="HICAccelerationZComboBox"
SelectedItem="{Binding HICAccelerationZ}" />
</StackPanel>
</Grid>
</Grid>
</base:BaseView>

View File

@@ -0,0 +1,17 @@
using DTS.Common.Interface;
// ReSharper disable CheckNamespace
namespace DTS.Viewer.AddCalculatedChannel
{
/// <summary>
/// Interaction logic for AddCalculatedChannelView.xaml
/// </summary>
public partial class AddCalculatedChannelView : IAddCalculatedChannelView
{
public AddCalculatedChannelView()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.8", FrameworkDisplayName = "")]

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]

View File

@@ -0,0 +1 @@
12

View File

@@ -0,0 +1 @@
12

View File

@@ -0,0 +1,140 @@
using System;
using System.Windows.Media.Imaging;
using DTS.Common;
using DTS.Common.Interface;
using DTS.Viewer.ChartOptions;
using DTS.Viewer.ChartOptions.Model;
using Prism.Ioc;
using Prism.Modularity;
using Unity;
// ReSharper disable RedundantAttributeUsageProperty
// ReSharper disable UnusedParameter.Local
[assembly: ChartOptionsModuleName()]
[assembly: ChartOptionsModuleImageAttribute()]
namespace DTS.Viewer.ChartOptions
{
[Module(ModuleName = "DTS.Viewer.ChartOptions")]
public class ChartOptionsModule : IModule
{
/// <summary>
/// Injected unity container
/// </summary>
private readonly IUnityContainer _unityContainer;
/// <summary>
/// Initializes a new instance of the <see cref="ChartOptionsModule"/> class.
/// </summary>
/// <param name="unityContainer">Obtained reference of the unity container by using dependency injection.</param>
public ChartOptionsModule(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
public void Initialize()
{
// Register View & View-Model with Unity dependency injection container as a singleton.
_unityContainer.RegisterType<IChartOptionsView, ChartOptionsView>();
_unityContainer.RegisterType<IChartOptionsViewModel, ChartOptionsViewModel>();
_unityContainer.RegisterType<IChartOptionsModel, ChartOptionsModel>();
}
public void OnInitialized(IContainerProvider containerProvider)
{
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
Initialize();
}
}
/// <summary>
/// Attribute class contains assembly name
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class ChartOptionsModuleNameAttribute : TextAttribute
{
public ChartOptionsModuleNameAttribute() : this(null) { }
public ChartOptionsModuleNameAttribute(string s)
{
AssemblyName = AssemblyNames.ChartOptions.ToString();
}
public override string AssemblyName { get; }
public override Type GetAttributeType()
{
return typeof(TextAttribute);
}
public override string GetAssemblyName()
{
return AssemblyName;
}
}
/// <summary>
/// Attribute class contains assembly image and name - used on the Main screen to ChartOptions available components
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class ChartOptionsModuleImageAttribute : ImageAttribute
{
private BitmapImage _img;
public ChartOptionsModuleImageAttribute() : this(null) { }
public override BitmapImage AssemblyImage
{
get { _img = AssemblyInfo.GetImage(AssemblyNames.ChartOptions.ToString()); return _img; }
}
public ChartOptionsModuleImageAttribute(string s)
{
_img = AssemblyInfo.GetImage(AssemblyNames.ChartOptions.ToString());
}
public override Type GetAttributeType()
{
return typeof(ImageAttribute);
}
public override BitmapImage GetAssemblyImage()
{
return AssemblyImage;
}
private string _name;
public override string AssemblyName
{
get { _name = AssemblyNames.ChartOptions.ToString(); return _name; }
}
public override string GetAssemblyName()
{
return AssemblyName;
}
private string _group;
public override string AssemblyGroup
{
get { _group = eAssemblyGroups.Viewer.ToString(); return _group; }
}
public override string GetAssemblyGroup()
{
return AssemblyGroup;
}
private eAssemblyRegion _region;
public override eAssemblyRegion AssemblyRegion
{
get { _region = eAssemblyRegion.ChartOptionsRegion; return _region; }
}
public override eAssemblyRegion GetAssemblyRegion()
{
return AssemblyRegion;
}
}
}

View File

@@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ChartUnitType" xml:space="preserve">
<value>Chart Unit Type</value>
</data>
<data name="FilterOptions_Title" xml:space="preserve">
<value>Display Filter</value>
<comment>Title for Display Filter Options GroupBox</comment>
</data>
<data name="LockT" xml:space="preserve">
<value>Lock T</value>
</data>
<data name="MaxT" xml:space="preserve">
<value>Max:</value>
</data>
<data name="MaxY" xml:space="preserve">
<value>Max:</value>
</data>
<data name="MinT" xml:space="preserve">
<value>Min:</value>
</data>
<data name="MinY" xml:space="preserve">
<value>Min:</value>
</data>
<data name="Range" xml:space="preserve">
<value>Range</value>
</data>
<data name="ResetAll" xml:space="preserve">
<value>Reset All</value>
</data>
<data name="ResetT" xml:space="preserve">
<value>Reset T</value>
</data>
<data name="SaveChart" xml:space="preserve">
<value>Save Chart</value>
</data>
<data name="SaveToPDF" xml:space="preserve">
<value>Save to PDF</value>
</data>
<data name="TimeUnitType" xml:space="preserve">
<value>Time Unit Type</value>
</data>
</root>

View File

@@ -0,0 +1,157 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{9F161F2A-4FCD-438E-9768-BA96BA104D6C}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DTS.Viewer.ChartOptions</RootNamespace>
<AssemblyName>DTS.Viewer.ChartOptions</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="C1.WPF.4, Version=4.0.20163.541, Culture=neutral, PublicKeyToken=2aa4ec5576d6c3ce, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\Program Files (x86)\ComponentOne\WPF Edition\bin\v4\C1.WPF.4.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Practices.ServiceLocation">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Microsoft.Practices.ServiceLocation.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Xaml.Behaviors">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Microsoft.Xaml.Behaviors.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="Prism">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.dll</HintPath>
</Reference>
<Reference Include="Prism.Unity.Wpf">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.Unity.Wpf.dll</HintPath>
</Reference>
<Reference Include="Prism.Wpf">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.Wpf.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.Windows" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="Unity.Abstractions">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Unity.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Unity.Container">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Unity.Container.dll</HintPath>
</Reference>
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="ChartOptionsModule.cs" />
<Compile Include="Model\ChartOptionsModel.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Resources\StringResources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>StringResources.resx</DependentUpon>
</Compile>
<Compile Include="Resources\TranslateExtension.cs" />
<Compile Include="ViewModel\ChartOptionsViewModel.cs" />
<Compile Include="View\ChartOptionsView.xaml.cs">
<DependentUpon>ChartOptionsView.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Page Include="Resources\CheckBoxSlider.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Resources\ChartOptionsResources.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="View\ChartOptionsView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\StringResources.ja.resx" />
<EmbeddedResource Include="Resources\StringResources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>StringResources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Common\DTS.Common.Core\DTS.Common.Core.csproj">
<Project>{fab1f470-1574-4301-b56e-d3364aa93679}</Project>
<Name>DTS.Common.Core</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common\DTS.Common.csproj">
<Project>{114edc77-f3b5-4576-a91b-40818d503b55}</Project>
<Name>DTS.Common</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\DataPRO\SensorDB\SensorDB.csproj">
<Project>{444ef10c-046e-47ad-a9a5-17318d488723}</Project>
<Name>SensorDB</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,180 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace DTS.Viewer.ChartOptions.Resources {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class StringResources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal StringResources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DTS.Viewer.ChartOptions.Resources.StringResources", typeof(StringResources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Chart Unit Type.
/// </summary>
internal static string ChartUnitType {
get {
return ResourceManager.GetString("ChartUnitType", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Display Filter.
/// </summary>
internal static string FilterOptions_Title {
get {
return ResourceManager.GetString("FilterOptions_Title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Lock T.
/// </summary>
internal static string LockT {
get {
return ResourceManager.GetString("LockT", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Max:.
/// </summary>
internal static string MaxT {
get {
return ResourceManager.GetString("MaxT", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Max:.
/// </summary>
internal static string MaxY {
get {
return ResourceManager.GetString("MaxY", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Min:.
/// </summary>
internal static string MinT {
get {
return ResourceManager.GetString("MinT", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Min:.
/// </summary>
internal static string MinY {
get {
return ResourceManager.GetString("MinY", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Range.
/// </summary>
internal static string Range {
get {
return ResourceManager.GetString("Range", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Reset All.
/// </summary>
internal static string ResetAll {
get {
return ResourceManager.GetString("ResetAll", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Reset T.
/// </summary>
internal static string ResetT {
get {
return ResourceManager.GetString("ResetT", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Save Chart.
/// </summary>
internal static string SaveChart {
get {
return ResourceManager.GetString("SaveChart", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Save to PDF.
/// </summary>
internal static string SaveToPDF {
get {
return ResourceManager.GetString("SaveToPDF", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Time Unit Type.
/// </summary>
internal static string TimeUnitType {
get {
return ResourceManager.GetString("TimeUnitType", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Windows.Markup;
using DTS.Viewer.ChartOptions.Resources;
namespace DTS.Viewer.ChartOptions
{
[MarkupExtensionReturnType(typeof(string))]
public class TranslateExtension : MarkupExtension
{
private readonly string _key;
public TranslateExtension(string key) { _key = key; }
private const string NotFound = "#stringnotfound#";
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (string.IsNullOrEmpty(_key)) { return NotFound; }
return StringResources.ResourceManager.GetString(_key) ?? NotFound + " " + _key;
}
}
}

View File

@@ -0,0 +1,270 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using DTS.Common;
using DTS.Common.Classes.Sensors;
using DTS.Common.Enums.Viewer;
using DTS.Common.Interface;
using DTS.Common.Interface.Sensors.SoftwareFilters;
using Prism.Commands;
// ReSharper disable EmptyConstructor
// ReSharper disable RedundantDefaultMemberInitializer
// ReSharper disable UnassignedGetOnlyAutoProperty
namespace DTS.Viewer.ChartOptions.Model
{
public class ChartOptionsModel : Common.Base.BasePropertyChanged, IChartOptionsModel
{
private bool _bDisplayingVolts = false;
/// <summary>
/// indicates if current mV option is for Volts or mV
/// </summary>
public bool DisplayingVolts
{
get => _bDisplayingVolts;
set
{
SetProperty(ref _bDisplayingVolts, value, "DisplayingVolts");
OnPropertyChanged("MVOrV");
OnPropertyChanged("UnitTypeDescription");
}
}
/// <summary>
/// returns mV or V depending on DisplayingVolts value
/// </summary>
public string MVOrV => DisplayingVolts ? "V" : "mV";
public ChartOptionsModel()
{
}
#region Properties
private bool _isDigitalChannel = false;
public bool IsDigitalChannel { get { return _isDigitalChannel; } set { SetProperty(ref _isDigitalChannel, value, "IsDigitalChannel"); } }
private bool _supportsADC = true;
public bool SupportsADC
{
get => _supportsADC;
set
{
SetProperty(ref _supportsADC, value, "SupportsADC");
}
}
private bool _supportsMV = true;
public bool SupportsMV
{
get => _supportsMV;
set
{
SetProperty(ref _supportsMV, value, "SupportsMV");
}
}
private ChartUnitTypeEnum _unitType = ChartUnitTypeEnum.EU;
public ChartUnitTypeEnum UnitType
{
get => _unitType;
set
{
if (_unitType.Equals(value)) return;
_unitType = value;
ReadData = true;
// FB 13120 does not need to set SelectedFilter any more since it's not using enum
if (_unitType != ChartUnitTypeEnum.EU && _unitType != ChartUnitTypeEnum.PSD) { Filter = FilterOptionEnum.Unfiltered; }
else { Filter = FilterOptionEnum.TestSetupDefault; }
OnPropertyChanged("UnitType");
OnPropertyChanged("UnitTypeDescription");
}
}
private string _unitTypeDescription = ChartUnitTypeEnum.EU.ToString();
public string UnitTypeDescription
{
get
{
if (UnitType == ChartUnitTypeEnum.mV)
{
return DisplayingVolts ? "V" : "mV";
}
return UnitType.ToString();
}
}
private TimeUnitTypeEnum _timeUnitType = TimeUnitTypeEnum.MS;
public TimeUnitTypeEnum TimeUnitType
{
get => _timeUnitType;
set
{
if (_timeUnitType.Equals(value)) return;
_timeUnitType = value;
ReadData = true;
TimeUnitTypeDescription = _timeUnitType.ToString();
OnPropertyChanged("TimeUnitType");
}
}
private string _timeUnitTypeDescription = TimeUnitTypeEnum.MS.ToString();
public string TimeUnitTypeDescription
{
get => _timeUnitTypeDescription;
set
{
if (_timeUnitTypeDescription.Equals(value)) return;
_timeUnitTypeDescription = value;
OnPropertyChanged("TimeUnitTypeDescription");
}
}
//FB 13120 use filter class instead of cfc filter enum
private IFilterClass _selectedFilter = new FilterClass(Common.Enums.Sensors.FilterClassType.Unfiltered);
public IFilterClass SelectedFilter { get => _selectedFilter; set { _selectedFilter = value; ReadData = true; OnPropertyChanged("SelectedFilter"); } }
public void SetSelectedFilterToUnfilteredNoRead()
{
_selectedFilter = new FilterClass(Common.Enums.Sensors.FilterClassType.Unfiltered);
ReadData = false;
OnPropertyChanged("SelectedFilter");
}
#region Min/Max Fixed Y
private double _minFixedY = 0.00;
public double MinFixedY { get => _minFixedY; set { if (_minFixedY.Equals(value)) return; _minFixedY = value; OnPropertyChanged("MinFixedY"); } }
private double _maxFixedY = 0.00;
public double MaxFixedY { get => _maxFixedY; set { if (_maxFixedY.Equals(value)) return; _maxFixedY = value; OnPropertyChanged("MaxFixedY"); } }
#endregion Min/Max Fixed Y
#region Min/Max Fixed X
private double _minFixedT = 0.00;
public double MinFixedT { get => _minFixedT; set { if (_minFixedT.Equals(value)) return; _minFixedT = value; OnPropertyChanged("MinFixedT"); } }
private double _maxFixedT = 0.00;
public double MaxFixedT { get => _maxFixedT; set { if (_maxFixedT.Equals(value)) return; _maxFixedT = value; OnPropertyChanged("MaxFixedT"); } }
#endregion Min/Max Fixed X
private List<double> _fullScaleValues = new List<double> { 200D, 100D, 50D, 20D, 10D, 5D, 1D, 0.1D };
private readonly List<double> _euValues = new List<double> { 5000, 2500, 1000, 500, 100, 50, 10, 5 };
public List<double> FullScaleValues { get => UnitType == ChartUnitTypeEnum.EU || UnitType == ChartUnitTypeEnum.PSD ? _euValues : _fullScaleValues; set { _fullScaleValues = value; OnPropertyChanged("FullScaleValues"); } }
private double _selectedFullScaleValue = 100;
public double SelectedFullScaleValue { get => _selectedFullScaleValue; set { _selectedFullScaleValue = value; OnPropertyChanged("SelectedFullScaleValue"); } }
private bool _lockedT = false;
public bool LockedT { get => _lockedT; set { if (_lockedT.Equals(value)) return; _lockedT = value; OnPropertyChanged("LockedT"); } }
private bool _lockedY = false;
public bool LockedY { get => _lockedY; set { if (_lockedY.Equals(value)) return; _lockedY = value; OnPropertyChanged("LockedY"); } }
private bool _showCursor = false;
public bool ShowCursor
{
get => _showCursor;
set
{
if (_showCursor.Equals(value)) return;
_showCursor = value; Parent?.ShowCusor(_showCursor); OnPropertyChanged("ShowCursor");
}
}
private string _currentCursorValues = string.Empty;
public string CurrentCursorValues
{
get => _currentCursorValues;
set { _currentCursorValues = value; OnPropertyChanged("CurrentCursorValues"); }
}
private YRangeScaleEnum _yRange = YRangeScaleEnum.AutoRange;
public YRangeScaleEnum YRange
{
get => _yRange;
set { if (_yRange.Equals(value)) return; _yRange = value; LockedY = _yRange == YRangeScaleEnum.Fixed; OnPropertyChanged("YRange"); }
}
private FilterOptionEnum _filter = FilterOptionEnum.TestSetupDefault;
public FilterOptionEnum Filter { get => _filter; set { if (_filter.Equals(value)) return; _filter = value; ReadData = true; OnPropertyChanged("Filter"); } }
private IChartOptionsViewModel _parent;
public IChartOptionsViewModel Parent { get => _parent; set { if (_parent != null && _parent.Equals(value)) return; _parent = value; OnPropertyChanged("Parent"); } }
private bool _canPublishChanges = true;
public bool CanPublishChanges { get => _canPublishChanges; set { _canPublishChanges = value; OnPropertyChanged("CanPublishChanges"); } }
private bool _isCursorsAvailable = false;
public bool IsCursorsAvailable { get => _isCursorsAvailable; set { _isCursorsAvailable = value; OnPropertyChanged("IsCursorsAvailable"); } }
private bool _t0Cursor = false;
public bool T0Cursor { get => _t0Cursor; set { _t0Cursor = value; OnPropertyChanged("T0Cursor"); } }
private bool _minMaxCursors = false;
public bool MinMaxCursors { get => _minMaxCursors; set { _minMaxCursors = value; OnPropertyChanged("MinMaxCursors"); } }
private bool _readData = false;
public bool ReadData { get => _readData; set { _readData = value; OnPropertyChanged("ReadData"); } }
private DelegateCommand _resetZoomCommand;
public DelegateCommand ResetZoomCommand => _resetZoomCommand ?? (_resetZoomCommand = new DelegateCommand(ResetZoomMethod));
private void ResetZoomMethod()
{
Parent.ResetZoomMethod();
}
private DelegateCommand _resetTCommand;
public DelegateCommand ResetTCommand => _resetTCommand ?? (_resetTCommand = new DelegateCommand(ResetTMethod));
private void ResetTMethod()
{
Parent.ResetTMethod();
}
private DelegateCommand _saveToPDFCommand;
public DelegateCommand SaveToPDFCommand => _saveToPDFCommand ?? (_saveToPDFCommand = new DelegateCommand(SaveToPDFMethod));
private void SaveToPDFMethod()
{
Parent.SaveToPDFMethod();
}
///<summary>
///Occurs when a property value changes.
///</summary>
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
if (propertyName == "CanPublishChanges"
|| propertyName == "Parent"
|| propertyName == "ReadData"
|| propertyName == "UnitTypeDescription"
|| propertyName == "ShowCursor"
|| propertyName == "LockedT"
|| propertyName == "LockedY"
|| propertyName == "MVOrV"
|| propertyName == "DisplayingVolts"
|| propertyName == "DecimateData"
|| propertyName == "WidthPoints") return;
if (CanPublishChanges) { Parent?.PublishChanges(); }
}
public bool IsSaved { get; }
private bool _decimateData = false;
public bool DecimateData { get => _unitType != ChartUnitTypeEnum.PSD && _unitType != ChartUnitTypeEnum.FFT && _decimateData; set { _decimateData = value; OnPropertyChanged("DecimateData"); } }
private long _widthPoints = 0;
public long WidthPoints { get => _widthPoints; set { _widthPoints = value; OnPropertyChanged("WidthPoints"); } }
#endregion Properties
}
}

View File

@@ -0,0 +1,83 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="CheckRadioFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="14,0,0,0" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="SliderCheckBox" TargetType="{x:Type CheckBox}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<ControlTemplate.Resources>
<Storyboard x:Key="StoryboardIsChecked">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="CheckFlag">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="14"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="StoryboardIsCheckedOff">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="CheckFlag">
<EasingDoubleKeyFrame KeyTime="0" Value="14"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<BulletDecorator Background="Transparent" SnapsToDevicePixels="true">
<BulletDecorator.Bullet>
<Border x:Name="ForegroundPanel" BorderThickness="1" Width="35" Height="20" CornerRadius="10">
<Canvas>
<Border Background="White" x:Name="CheckFlag" CornerRadius="10" VerticalAlignment="Center" BorderThickness="1" Width="19" Height="18" RenderTransformOrigin="0.5,0.5">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
<Border.Effect>
<DropShadowEffect ShadowDepth="1" Direction="180" />
</Border.Effect>
</Border>
</Canvas>
</Border>
</BulletDecorator.Bullet>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/>
</BulletDecorator>
<ControlTemplate.Triggers>
<Trigger Property="HasContent" Value="true">
<Setter Property="FocusVisualStyle" Value="{StaticResource CheckRadioFocusVisual}"/>
<Setter Property="Padding" Value="4,0,0,0"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="ForegroundPanel" Property="Background" Value="Lime" /> <!-- {DynamicResource Accent} -->
<Trigger.EnterActions>
<BeginStoryboard x:Name="BeginStoryboardCheckedTrue" Storyboard="{StaticResource StoryboardIsChecked}" />
<RemoveStoryboard BeginStoryboardName="BeginStoryboardCheckedFalse" />
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter TargetName="ForegroundPanel" Property="Background" Value="Green" />
<Trigger.EnterActions>
<BeginStoryboard x:Name="BeginStoryboardCheckedFalse" Storyboard="{StaticResource StoryboardIsCheckedOff}" />
<RemoveStoryboard BeginStoryboardName="BeginStoryboardCheckedTrue" />
</Trigger.EnterActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ChartUnitType" xml:space="preserve">
<value>Y軸の表示方法</value>
</data>
<data name="FilterOptions_Title" xml:space="preserve">
<value>表示用ソフトウエアフィルター</value>
</data>
<data name="LockT" xml:space="preserve">
<value>時間軸固定</value>
</data>
<data name="Range" xml:space="preserve">
<value>レンジ設定</value>
</data>
<data name="ResetAll" xml:space="preserve">
<value>全リセット</value>
</data>
<data name="ResetT" xml:space="preserve">
<value>時間軸リセット</value>
</data>
<data name="TimeUnitType" xml:space="preserve">
<value>時間の単位</value>
</data>
</root>

View File

@@ -0,0 +1,164 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:common="clr-namespace:DTS.Common;assembly=DTS.Common">
<Style TargetType="Label">
<!--<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="HorizontalContentAlignment" Value="Right"/>-->
<Setter Property="Width" Value="100"/>
</Style>
<Style TargetType="StackPanel">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
<Style TargetType="{x:Type RadioButton}" >
<Setter Property="Width" Value="100"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<BulletDecorator Background="White" Cursor="Hand">
<BulletDecorator.Bullet>
<Grid Height="16" Width="16">
<!--Define size of the Bullet-->
<!--The two borders-->
<Border Name="RadioOuter" Background="Transparent" BorderBrush="Gainsboro" BorderThickness="2" CornerRadius="2" />
<Border CornerRadius="0" Margin="4" Name="RadioMark" Background="#FFADADAD" Visibility="Hidden" />
</Grid>
</BulletDecorator.Bullet>
<!--Text element-->
<TextBlock Margin="3,1,0,0" Foreground="#FF3E3E3E" FontFamily="Calibri" FontSize="12">
<ContentPresenter />
</TextBlock>
</BulletDecorator>
<!--If item is checked, trigger the visibility of the mark-->
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<!--If item is checked, trigger the visibility of the mark and change the color of the selected bullet into a darker gray for better highlighting-->
<Setter TargetName="RadioMark" Property="Visibility" Value="Visible"/>
<Setter TargetName="RadioOuter" Property="BorderBrush" Value="#FFADADAD" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border>
<!--<Rectangle SnapsToDevicePixels="true" Margin="4" Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1"/>-->
<Rectangle Margin="2" StrokeThickness="1" Stroke="LightGray" StrokeDashArray="1 2" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="RoundedButton" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderThickness" Value="3"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="0,0,1,1"/>
<Setter Property="Height" Value="25"/>
<Setter Property="Width" Value="100"/>
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ControlTemplate.Resources>
<Storyboard x:Key="ShowShine">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Shine" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="HideShine">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Shine" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Border CornerRadius="5,5,5,5" BorderThickness="1,1,1,1" RenderTransformOrigin="0.5,0.5" x:Name="border" BorderBrush="Silver">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Border.RenderTransform>
<Border Background="{TemplateBinding Background}" CornerRadius="5,5,5,5" x:Name="border1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.5*"/>
<RowDefinition Height="0.5*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" CornerRadius="5,5,0,0">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#00FFFFFF" Offset="0"/>
<GradientStop Color="#7EFFFFFF" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
</Border>
<Border Grid.Row="1" Opacity="0" x:Name="Shine" Width="Auto" Height="Auto" CornerRadius="0,0,5,5" Margin="1,0,-1,0" Background="{TemplateBinding BorderBrush}"/>
<ContentPresenter VerticalAlignment="Center" Grid.Row="0" Grid.RowSpan="2" HorizontalAlignment="Center" x:Name="contentPresenter"/>
</Grid>
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" TargetName="border1" Value="0.5"/>
<Setter Property="Opacity" TargetName="border" Value="1"/>
<Setter Property="Opacity" TargetName="contentPresenter" Value="0.5"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="RenderTransform" TargetName="border">
<Setter.Value>
<TransformGroup>
<ScaleTransform ScaleX="0.9" ScaleY="0.9"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource HideShine}" x:Name="HideShine_BeginStoryboard"/>
</Trigger.ExitActions>
<Trigger.EnterActions>
<BeginStoryboard x:Name="ShowShine_BeginStoryboard" Storyboard="{StaticResource ShowShine}"/>
</Trigger.EnterActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="FontFamily" Value="Calibri"/>
<Setter Property="FontSize" Value="12"/>
</Style>
<ObjectDataProvider x:Key="CfcFilterData" MethodName="GetValues" ObjectType="{x:Type system:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="common:CFCFilter"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</ResourceDictionary>

View File

@@ -0,0 +1,221 @@
<base:BaseView x:Class="DTS.Viewer.ChartOptions.ChartOptionsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:base="clr-namespace:DTS.Common.Base;assembly=DTS.Common"
xmlns:converters="clr-namespace:DTS.Common.Converters;assembly=DTS.Common"
xmlns:c1="http://schemas.componentone.com/winfx/2006/xaml"
xmlns:viewer="clr-namespace:DTS.Common.Enums.Viewer;assembly=DTS.Common"
xmlns:strings="clr-namespace:DTS.Viewer.ChartOptions"
VerticalAlignment="Top" HorizontalAlignment="Right" x:Name="chartViewOptions">
<base:BaseView.Resources>
<ResourceDictionary>
<converters:InverseBooleanToOpacityConverter x:Key="InverseBooleanToOpacityConverter" />
<converters:BooleanToOpacityConverter x:Key="BooleanToOpacityConverter" />
<converters:EnumBooleanConverter x:Key="EnumBooleanConverter" />
<converters:InverseBooleanConverter x:Key="InverseBooleanConverter" />
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<converters:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter" />
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Resources/ChartOptionsResources.xaml"/>
<ResourceDictionary Source="../Resources/CheckBoxSlider.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</base:BaseView.Resources>
<StackPanel Orientation="Vertical" Width="300" Height="500" VerticalAlignment="Top" HorizontalAlignment="Right"
IsEnabled="{Binding Path=ChartOptionsVisability, Mode=TwoWay}"
Opacity="{Binding Path=ChartOptionsVisability, Converter={StaticResource InverseBooleanToOpacityConverter}, Mode=TwoWay}">
<GroupBox Header="{strings:TranslateExtension ChartUnitType}" Margin="5,0,5,0" AutomationProperties.AutomationId="ChartUnitTypeGrpBx">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<RadioButton GroupName="UnitTypeGroup" Content="{x:Static viewer:ChartUnitTypeEnum.EU}" Margin="0,5,0,5" Width="50" IsChecked="{Binding Path=Model.UnitType, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.EU}}" AutomationProperties.AutomationId="EURdoBtn"/>
<!-- Content="{x:Static viewer:ChartUnitTypeEnum.mV}" -->
<RadioButton GroupName="UnitTypeGroup" Content="{Binding Path=Model.MVOrV}" Margin="10,5,0,5" Width="50" IsChecked="{Binding Path=Model.UnitType, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.mV}}"
AutomationProperties.AutomationId="mVRdoBtn" IsEnabled="{Binding Path=Model.SupportsMV}" />
<RadioButton GroupName="UnitTypeGroup" Content="{x:Static viewer:ChartUnitTypeEnum.ADC}" Margin="10,5,0,5" Width="50" IsChecked="{Binding Path=Model.UnitType, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.ADC}}"
AutomationProperties.AutomationId="ADCRdoBtn" IsEnabled="{Binding Path=Model.SupportsADC}" />
<RadioButton GroupName="UnitTypeGroup" Content="{x:Static viewer:ChartUnitTypeEnum.FFT}" Margin="10,5,0,5" Width="50" IsChecked="{Binding Path=Model.UnitType, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.FFT}}"
AutomationProperties.AutomationId="FFTdoBtn" />
</StackPanel>
</GroupBox>
<GroupBox Header="{strings:TranslateExtension Range}" Margin="5" AutomationProperties.AutomationId="RangeGrpBx">
<StackPanel Orientation="Vertical" HorizontalAlignment="Left">
<Grid Margin="10,10,0,0">
<RadioButton GroupName="Yaxis" Margin="0,5,0,5" Content="{Binding Path= Model.UnitTypeDescription, Mode=OneWay}" ContentStringFormat="Auto Range {0}" HorizontalAlignment="Left"
IsChecked="{Binding Path=Model.YRange, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:YRangeScaleEnum.AutoRange}}"
AutomationProperties.AutomationId="AutoRangeRdoBtn">
<RadioButton.Style>
<Style TargetType="RadioButton" BasedOn="{StaticResource {x:Type RadioButton}}">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Model.UnitType, Mode=OneWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.FFT}}" Value="True">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</RadioButton.Style>
</RadioButton>
<Button Content="{strings:TranslateExtension ResetAll}" Margin="0,0,10,0" Command="{Binding Path=Model.ResetZoomCommand}" HorizontalAlignment="Right" AutomationProperties.AutomationId="ResetAllBtn" />
</Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="10,2,0,0">
<StackPanel.Style>
<Style TargetType="StackPanel" BasedOn="{StaticResource {x:Type StackPanel}}">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Model.UnitType, Mode=OneWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.FFT}}" Value="True">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<RadioButton x:Name="RadioButtonFullScale" GroupName="Yaxis" Margin="0,5,0,5" Content="{Binding Path= Model.UnitTypeDescription, Mode=OneWay}" ContentStringFormat="% Full Scale {0}"
IsChecked="{Binding Path=Model.YRange, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:YRangeScaleEnum.FullScale}}"
AutomationProperties.AutomationId="PerFullScaleRdoBtn"/>
<ComboBox ItemsSource="{Binding Path=Model.FullScaleValues, Mode=TwoWay}"
IsEnabled="{Binding ElementName=RadioButtonFullScale, Path=IsChecked, Mode=TwoWay}"
SelectedItem="{Binding Path=Model.SelectedFullScaleValue, Mode=TwoWay}"
Opacity="{Binding ElementName=RadioButtonFullScale, Path=IsChecked, Mode=TwoWay, Converter={StaticResource InverseBooleanToOpacityConverter}}"
HorizontalAlignment="Center" VerticalAlignment="Center" Margin="60,0,0,0" Width="90" AutomationProperties.AutomationId="PerFullScaleCboBx"/>
</StackPanel>
<StackPanel Orientation="Vertical" HorizontalAlignment="Left" Margin="10,2,0,0">
<StackPanel.Style>
<Style TargetType="StackPanel" BasedOn="{StaticResource {x:Type StackPanel}}">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Model.UnitType, Mode=OneWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.FFT}}" Value="True">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<RadioButton x:Name="RadioButtonFixed" GroupName="Yaxis" Margin="0,5,0,5" HorizontalAlignment="Left" Content="{Binding Path= Model.UnitTypeDescription, Mode=OneWay}" ContentStringFormat="Fixed {0}"
IsChecked="{Binding Path=Model.YRange, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:YRangeScaleEnum.Fixed}, Mode=TwoWay}"
AutomationProperties.AutomationId="FixedRdoBtn"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="10,0,0,0"
IsEnabled="{Binding ElementName=RadioButtonFixed, Path=IsChecked}"
Opacity="{Binding ElementName=RadioButtonFixed, Path=IsChecked, Converter={StaticResource InverseBooleanToOpacityConverter}, Mode=TwoWay}">
<StackPanel Orientation="Horizontal" Margin="0,0,0,0">
<TextBlock Text="{strings:TranslateExtension MinY}" VerticalAlignment="Center" />
<c1:C1NumericBox Format="N3" VerticalAlignment="Center" Margin="5" Width="90" Value="{Binding Path=Model.MinFixedY, Mode=TwoWay}" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10,0,0,0">
<TextBlock Text="{strings:TranslateExtension MaxY}" VerticalAlignment="Center" />
<c1:C1NumericBox Format="N3" VerticalAlignment="Center" Margin="5" Width="90" Value="{Binding Path=Model.MaxFixedY, Mode=TwoWay}"/>
</StackPanel>
</StackPanel>
</StackPanel>
<StackPanel Orientation="Vertical" HorizontalAlignment="Left">
<StackPanel.Style>
<Style TargetType="StackPanel" BasedOn="{StaticResource {x:Type StackPanel}}">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Model.UnitType, Mode=OneWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.FFT}}" Value="True">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<Grid>
<CheckBox x:Name="CheckBoxLockT" Content="{strings:TranslateExtension LockT}" Margin="10,10,0,0" IsChecked="{Binding Path=Model.LockedT, Mode=TwoWay}" HorizontalAlignment="Left" />
<Button Content="{strings:TranslateExtension ResetT}" Margin="0,0,10,0" Command="{Binding Path=Model.ResetTCommand}" HorizontalAlignment="Right" AutomationProperties.AutomationId="ResetTBtn"/>
</Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="10,0,0,0" >
<StackPanel Orientation="Horizontal" Margin="10,0,0,0" >
<TextBlock Text="{strings:TranslateExtension MinT}" VerticalAlignment="Center" />
<c1:C1NumericBox Format="N3" VerticalAlignment="Center" Margin="5" Width="90" Value="{Binding Path=Model.MinFixedT, Mode=TwoWay}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="20,0,0,0">
<TextBlock Text="{strings:TranslateExtension MaxT}" VerticalAlignment="Center" />
<c1:C1NumericBox Format="N3" VerticalAlignment="Center" Margin="5" Width="90" Value="{Binding Path=Model.MaxFixedT, Mode=TwoWay}"/>
</StackPanel>
</StackPanel>
</StackPanel>
</StackPanel>
</GroupBox>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" >
<StackPanel.Style>
<Style TargetType="StackPanel" BasedOn="{StaticResource {x:Type StackPanel}}">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Model.UnitType, Mode=OneWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.FFT}}" Value="True">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<GroupBox Header="{strings:TranslateExtension FilterOptions_Title}" Margin="5,0,5,0" Width="130" AutomationProperties.AutomationId="FilterGrpBx">
<GroupBox.Style>
<Style TargetType="GroupBox" BasedOn="{StaticResource {x:Type GroupBox}}">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Model.UnitType, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.EU}}" Value="False">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=Model.IsDigitalChannel, Mode=TwoWay}" Value="True">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</GroupBox.Style>
<StackPanel Orientation="Vertical" >
<RadioButton Width="110" GroupName="FilterGroup" Margin="0,5,0,0" Content="{x:Static viewer:FilterOptionEnum.Unfiltered}" IsChecked="{Binding Path=Model.Filter, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:FilterOptionEnum.Unfiltered}}" AutomationProperties.AutomationId="UnfRdoBtn"/>
<RadioButton Width="110" GroupName="FilterGroup" Margin="0,5,0,0" Content="{x:Static viewer:FilterOptionEnum.TestSetupDefault}" IsChecked="{Binding Path=Model.Filter, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:FilterOptionEnum.TestSetupDefault}}" AutomationProperties.AutomationId="TestSetupDefRdoBtn"/>
<RadioButton Width="110" GroupName="FilterGroup" Margin="0,5,0,0" Content="{x:Static viewer:FilterOptionEnum.Custom}" x:Name="RbCustom" IsChecked="{Binding Path=Model.Filter, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:FilterOptionEnum.Custom}}"/>
<ComboBox DisplayMemberPath="FilterName" ItemsSource="{Binding ElementName=chartViewOptions, Path=AvailableCFC}" SelectedItem="{Binding Path=Model.SelectedFilter, Mode=TwoWay}"
IsEnabled="{Binding ElementName=RbCustom, Path=IsChecked, Mode=TwoWay}"
Opacity="{Binding ElementName=RbCustom, Path=IsChecked, Converter={StaticResource InverseBooleanToOpacityConverter}}"
AutomationProperties.AutomationId="CustomFilterCboBx"
HorizontalAlignment="Center"
Width="110"
Height="17"
VerticalAlignment="Center"
Margin="5" />
</StackPanel>
</GroupBox>
<GroupBox Header="{strings:TranslateExtension TimeUnitType}" Margin="5,0,5,0" Width="130" AutomationProperties.AutomationId="TimeUnitGrpBx">
<StackPanel Orientation="Vertical" HorizontalAlignment="Center">
<RadioButton GroupName="TimeUnitGroup" Content="{x:Static viewer:TimeUnitTypeEnum.MS}" Margin="0,5,0,5" Width="110" IsChecked="{Binding Path=Model.TimeUnitType, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:TimeUnitTypeEnum.MS}}" AutomationProperties.AutomationId="msRdoBtn"/>
<RadioButton GroupName="TimeUnitGroup" Content="{x:Static viewer:TimeUnitTypeEnum.Seconds}" Margin="0,5,0,5" Width="110" IsChecked="{Binding Path=Model.TimeUnitType, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:TimeUnitTypeEnum.Seconds}}" AutomationProperties.AutomationId="secRdoBtn"/>
</StackPanel>
</GroupBox>
</StackPanel>
<GroupBox Header="{strings:TranslateExtension SaveChart}" Margin="5" HorizontalAlignment="Left" AutomationProperties.AutomationId="SaveBx">
<StackPanel Orientation="Vertical" HorizontalAlignment="Left">
<Button Content="{strings:TranslateExtension SaveToPDF}" Margin="10" Padding="10, 5" Command="{Binding Path=Model.SaveToPDFCommand}" AutomationProperties.AutomationId="SaveToPDFBtn" />
</StackPanel>
</GroupBox>
</StackPanel>
</base:BaseView>

View File

@@ -0,0 +1,244 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using DTS.Common.Base;
using Unity;
using DTS.Common.Enums.Viewer;
using DTS.Common.Events;
using DTS.Common.Interface;
using Prism.Events;
using Prism.Regions;
using DTS.Common.Interactivity;
using Prism.Commands;
// ReSharper disable UnassignedGetOnlyAutoProperty
// ReSharper disable InconsistentNaming
// ReSharper disable NotAccessedField.Local
// ReSharper disable UnusedAutoPropertyAccessor.Local
// ReSharper disable CheckNamespace
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Local
// ReSharper disable RedundantDefaultMemberInitializer
namespace DTS.Viewer.ChartOptions
{
public class ChartOptionsViewModel : BaseViewModel<IChartOptionsViewModel>, IChartOptionsViewModel
{
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; }
public IBaseView View { get; set; }
private IChartOptionsModel _model;
public new IChartOptionsModel Model { get => _model; set { _model = value; OnPropertyChanged("Model"); } }
/// <summary>
/// Creates a new instance of the TestSummaryViewModel.
/// </summary>
/// <param name="view">The TestListView 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 ChartOptionsViewModel(IChartOptionsView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)
: base(regionManager, eventAggregator, unityContainer)
{
View = view;
View.DataContext = this;
NotificationRequest = new InteractionRequest<Notification>();
ConfirmationRequest = new InteractionRequest<Confirmation>();
_eventAggregator = eventAggregator;
_unityContainer = unityContainer;
_eventAggregator.GetEvent<ChartAxisChangedEvent>().Subscribe(OnChartAxisChangedEvent);
//Model = _unityContainer.Resolve<IChartOptionsModel>();
//Model.Parent = this;
//View.DataContext = Model;
}
public override void Initialize()
{
}
private string chartType = string.Empty;
public override void Initialize(object parameter)
{
Subscribe();
Model = _unityContainer.Resolve<IChartOptionsModel>();
Model.Parent = this;
View.DataContext = Model;
if (parameter is IViewerMainViewModel)
{
Parent = (IBaseViewModel)parameter;
Model.DecimateData = true;
}
else if (parameter is Tuple<IBaseViewModel, string> tuParam && tuParam.Item1 is IPSDReportMainViewModel)
{
Parent = tuParam.Item1;
chartType = tuParam.Item2;
Model.CanPublishChanges = false;
if ("Graph" == chartType)
{
Model.UnitType = ChartUnitTypeEnum.PSD;
Model.YRange = YRangeScaleEnum.Fixed;
Model.MaxFixedY = 1;
Model.MinFixedY = 1e-12; //log scale, can't be 0
Model.DecimateData = false;
}
else
{
Model.DecimateData = true;
Model.Filter = FilterOptionEnum.Unfiltered;
}
Model.CanPublishChanges = true;
}
}
private void Subscribe()
{
_eventAggregator.GetEvent<CursorsAlailableChangedEvent>().Subscribe(OnCursorsAlailableChanged);
_eventAggregator.GetEvent<GraphSelectedChannelsNotification>().Subscribe(OnGraphSelectedChannelsChanged);
}
private string Directory { get; set; }
private void OnGraphSelectedChannelsChanged(GraphSelectedChannelsNotificationArg arg)
{
if (Parent != arg?.ParentVM) return;
var channels = arg.SelectedChannels;
Model.Parent = this;
Directory = channels.Count > 0 ? channels[0].BinaryFilePath : string.Empty;
ChartOptionsVisability = (channels.Count > 0);
//whenever channels change, check the status of mV/ADC buttons
//18256 Implement StackChannelScaleFactorsEUPerADC Arm/Event Command
if (AllChannelsSupportADC(channels))
{
Model.SupportsADC = true;
}
else
{
Model.SupportsADC = false;
if (Model.UnitType == ChartUnitTypeEnum.ADC)
{
Model.UnitType = ChartUnitTypeEnum.EU;
}
}
if (AllChannelsSupportmV(channels))
{
Model.SupportsMV = true;
}
else
{
Model.SupportsMV = false;
if (Model.UnitType == ChartUnitTypeEnum.mV)
{
Model.UnitType = ChartUnitTypeEnum.EU;
}
}
PublishChanges();
}
/// <summary>
/// returns true if all channels support ADC
/// for now this is determined by looking at the sensor serial number, but we
/// can be more sophisticated in the future, as there are other channels that won't support ADC meaningfully as well
/// (like calculated channels)
/// </summary>
private bool AllChannelsSupportADC(List<ITestChannel> channels)
{
return !channels.Exists(x => Common.Enums.Hardware.HardwareConstants.IsTSRAIRSerialNumber(x.ParentModule.BaseSerialNumber));
}
/// <summary>
/// returns true if all channels support mV
/// </summary>
private bool AllChannelsSupportmV(List<ITestChannel> channels)
{
return !channels.Exists(x => Common.Enums.Hardware.HardwareConstants.IsTSRAIRSerialNumber(x.ParentModule.BaseSerialNumber));
}
private void OnCursorsAlailableChanged(bool value)
{
Model.IsCursorsAvailable = value;
}
private void OnChartAxisChangedEvent(ChartAxisChangedEventArg args)
{
if (args?.ParentVM != Parent) return;
Model.CanPublishChanges = false;
switch (args.Axis)
{
case "Y":
Model.MinFixedY = args.MinValue;
Model.MaxFixedY = args.MaxValue;
break;
case "X":
Model.MinFixedT = args.MinValue;
Model.MaxFixedT = args.MaxValue;
break;
}
Model.CanPublishChanges = true;
}
#region Properties
public object ContextSearchRegion { get; set; }
public new bool IsMenuIncluded { get; set; }
public new bool IsNavigationIncluded { get; set; }
public new bool IsBusy { get; set; }
public new bool IsDirty { get; }
private bool _chartOptionsVisability = false;
public bool ChartOptionsVisability { get => _chartOptionsVisability; set { _chartOptionsVisability = value; OnPropertyChanged("ChartOptionsVisability"); } }
public new event PropertyChangedEventHandler PropertyChanged;
public new void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion Properties
#region Methods
public void ShowMinMaxCursor(bool value)
{
_eventAggregator.GetEvent<CursorShowMinMaxChangedEvent>().Publish(value);
}
public void ResetZoomMethod()
{
Model.YRange = YRangeScaleEnum.AutoRange;
_eventAggregator.GetEvent<ResetZoomChangedEvent>().Publish(true);
}
public void ResetTMethod()
{
_eventAggregator.GetEvent<ResetZoomChangedEvent>().Publish(false);
}
public void SaveToPDFMethod()
{
_eventAggregator.GetEvent<SaveToPDFRequestedEvent>().Publish(Directory);
}
public void PublishChanges()
{
_eventAggregator.GetEvent<ChartOptionsChangedEvent>().Publish(new ChartOptionsChangedEventArg() { ParentVM = Parent, Model = Model, ChartType = chartType });
}
public void ShowCusor(bool value)
{
_eventAggregator.GetEvent<CursorShowChangedEvent>().Publish(value);
}
#endregion Methods
#region Commands
private DelegateCommand _clearMarkersCommand;
public DelegateCommand ClearMarkersCommand => _clearMarkersCommand ?? (_clearMarkersCommand = new DelegateCommand(ClearMarkersMethod));
private void ClearMarkersMethod()
{
_eventAggregator.GetEvent<CursorsClearChangedEvent>().Publish(true);
}
#endregion
}
}

View File

@@ -0,0 +1,29 @@
using DTS.Common.Interface;
using DTS.Common.Interface.Sensors.SoftwareFilters;
using DTS.SensorDB;
using System.Collections.Generic;
namespace DTS.Viewer.ChartOptions
{
/// <summary>
/// Interaction logic for ChartOptionsView.xaml
/// </summary>
public partial class ChartOptionsView : IChartOptionsView
{
public ChartOptionsView()
{
InitializeComponent();
}
/// <summary>
/// FB 13120 Available filter classes
/// </summary>
public List<IFilterClass> AvailableCFC
{
get
{
return new AnalogSettingDefaults().FilterOptions;
}
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DTS.Viewer.DTS.Viewer.ChartOptions")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DTS.Viewer.DTS.Viewer.ChartOptions")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("9f161f2a-4fcd-438e-9768-ba96ba104d6c")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,140 @@
using System;
using System.Windows.Media.Imaging;
using DTS.Common;
using DTS.Common.Interface;
using DTS.Viewer.ChartOptions;
using DTS.Viewer.ChartOptions.Model;
using Prism.Ioc;
using Prism.Modularity;
using Unity;
// ReSharper disable RedundantAttributeUsageProperty
// ReSharper disable UnusedParameter.Local
[assembly: ChartOptionsModuleName()]
[assembly: ChartOptionsModuleImageAttribute()]
namespace DTS.Viewer.ChartOptions
{
[Module(ModuleName = "DTS.Viewer.ChartOptions")]
public class ChartOptionsModule : IModule
{
/// <summary>
/// Injected unity container
/// </summary>
private readonly IUnityContainer _unityContainer;
/// <summary>
/// Initializes a new instance of the <see cref="ChartOptionsModule"/> class.
/// </summary>
/// <param name="unityContainer">Obtained reference of the unity container by using dependency injection.</param>
public ChartOptionsModule(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
public void Initialize()
{
// Register View & View-Model with Unity dependency injection container as a singleton.
_unityContainer.RegisterType<IChartOptionsView, ChartOptionsView>();
_unityContainer.RegisterType<IChartOptionsViewModel, ChartOptionsViewModel>();
_unityContainer.RegisterType<IChartOptionsModel, ChartOptionsModel>();
}
public void OnInitialized(IContainerProvider containerProvider)
{
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
Initialize();
}
}
/// <summary>
/// Attribute class contains assembly name
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class ChartOptionsModuleNameAttribute : TextAttribute
{
public ChartOptionsModuleNameAttribute() : this(null) { }
public ChartOptionsModuleNameAttribute(string s)
{
AssemblyName = AssemblyNames.ChartOptions.ToString();
}
public override string AssemblyName { get; }
public override Type GetAttributeType()
{
return typeof(TextAttribute);
}
public override string GetAssemblyName()
{
return AssemblyName;
}
}
/// <summary>
/// Attribute class contains assembly image and name - used on the Main screen to ChartOptions available components
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class ChartOptionsModuleImageAttribute : ImageAttribute
{
private BitmapImage _img;
public ChartOptionsModuleImageAttribute() : this(null) { }
public override BitmapImage AssemblyImage
{
get { _img = AssemblyInfo.GetImage(AssemblyNames.ChartOptions.ToString()); return _img; }
}
public ChartOptionsModuleImageAttribute(string s)
{
_img = AssemblyInfo.GetImage(AssemblyNames.ChartOptions.ToString());
}
public override Type GetAttributeType()
{
return typeof(ImageAttribute);
}
public override BitmapImage GetAssemblyImage()
{
return AssemblyImage;
}
private string _name;
public override string AssemblyName
{
get { _name = AssemblyNames.ChartOptions.ToString(); return _name; }
}
public override string GetAssemblyName()
{
return AssemblyName;
}
private string _group;
public override string AssemblyGroup
{
get { _group = eAssemblyGroups.Viewer.ToString(); return _group; }
}
public override string GetAssemblyGroup()
{
return AssemblyGroup;
}
private eAssemblyRegion _region;
public override eAssemblyRegion AssemblyRegion
{
get { _region = eAssemblyRegion.ChartOptionsRegion; return _region; }
}
public override eAssemblyRegion GetAssemblyRegion()
{
return AssemblyRegion;
}
}
}

View File

@@ -0,0 +1,157 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{9F161F2A-4FCD-438E-9768-BA96BA104D6C}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DTS.Viewer.ChartOptions</RootNamespace>
<AssemblyName>DTS.Viewer.ChartOptions</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="C1.WPF.4, Version=4.0.20163.541, Culture=neutral, PublicKeyToken=2aa4ec5576d6c3ce, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\Program Files (x86)\ComponentOne\WPF Edition\bin\v4\C1.WPF.4.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Practices.ServiceLocation">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Microsoft.Practices.ServiceLocation.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Xaml.Behaviors">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Microsoft.Xaml.Behaviors.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="Prism">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.dll</HintPath>
</Reference>
<Reference Include="Prism.Unity.Wpf">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.Unity.Wpf.dll</HintPath>
</Reference>
<Reference Include="Prism.Wpf">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.Wpf.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.Windows" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="Unity.Abstractions">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Unity.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Unity.Container">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Unity.Container.dll</HintPath>
</Reference>
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="ChartOptionsModule.cs" />
<Compile Include="Model\ChartOptionsModel.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Resources\StringResources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>StringResources.resx</DependentUpon>
</Compile>
<Compile Include="Resources\TranslateExtension.cs" />
<Compile Include="ViewModel\ChartOptionsViewModel.cs" />
<Compile Include="View\ChartOptionsView.xaml.cs">
<DependentUpon>ChartOptionsView.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Page Include="Resources\CheckBoxSlider.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Resources\ChartOptionsResources.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="View\ChartOptionsView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\StringResources.ja.resx" />
<EmbeddedResource Include="Resources\StringResources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>StringResources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Common\DTS.Common.Core\DTS.Common.Core.csproj">
<Project>{fab1f470-1574-4301-b56e-d3364aa93679}</Project>
<Name>DTS.Common.Core</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common\DTS.Common.csproj">
<Project>{114edc77-f3b5-4576-a91b-40818d503b55}</Project>
<Name>DTS.Common</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\DataPRO\SensorDB\SensorDB.csproj">
<Project>{444ef10c-046e-47ad-a9a5-17318d488723}</Project>
<Name>SensorDB</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,270 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using DTS.Common;
using DTS.Common.Classes.Sensors;
using DTS.Common.Enums.Viewer;
using DTS.Common.Interface;
using DTS.Common.Interface.Sensors.SoftwareFilters;
using Prism.Commands;
// ReSharper disable EmptyConstructor
// ReSharper disable RedundantDefaultMemberInitializer
// ReSharper disable UnassignedGetOnlyAutoProperty
namespace DTS.Viewer.ChartOptions.Model
{
public class ChartOptionsModel : Common.Base.BasePropertyChanged, IChartOptionsModel
{
private bool _bDisplayingVolts = false;
/// <summary>
/// indicates if current mV option is for Volts or mV
/// </summary>
public bool DisplayingVolts
{
get => _bDisplayingVolts;
set
{
SetProperty(ref _bDisplayingVolts, value, "DisplayingVolts");
OnPropertyChanged("MVOrV");
OnPropertyChanged("UnitTypeDescription");
}
}
/// <summary>
/// returns mV or V depending on DisplayingVolts value
/// </summary>
public string MVOrV => DisplayingVolts ? "V" : "mV";
public ChartOptionsModel()
{
}
#region Properties
private bool _isDigitalChannel = false;
public bool IsDigitalChannel { get { return _isDigitalChannel; } set { SetProperty(ref _isDigitalChannel, value, "IsDigitalChannel"); } }
private bool _supportsADC = true;
public bool SupportsADC
{
get => _supportsADC;
set
{
SetProperty(ref _supportsADC, value, "SupportsADC");
}
}
private bool _supportsMV = true;
public bool SupportsMV
{
get => _supportsMV;
set
{
SetProperty(ref _supportsMV, value, "SupportsMV");
}
}
private ChartUnitTypeEnum _unitType = ChartUnitTypeEnum.EU;
public ChartUnitTypeEnum UnitType
{
get => _unitType;
set
{
if (_unitType.Equals(value)) return;
_unitType = value;
ReadData = true;
// FB 13120 does not need to set SelectedFilter any more since it's not using enum
if (_unitType != ChartUnitTypeEnum.EU && _unitType != ChartUnitTypeEnum.PSD) { Filter = FilterOptionEnum.Unfiltered; }
else { Filter = FilterOptionEnum.TestSetupDefault; }
OnPropertyChanged("UnitType");
OnPropertyChanged("UnitTypeDescription");
}
}
private string _unitTypeDescription = ChartUnitTypeEnum.EU.ToString();
public string UnitTypeDescription
{
get
{
if (UnitType == ChartUnitTypeEnum.mV)
{
return DisplayingVolts ? "V" : "mV";
}
return UnitType.ToString();
}
}
private TimeUnitTypeEnum _timeUnitType = TimeUnitTypeEnum.MS;
public TimeUnitTypeEnum TimeUnitType
{
get => _timeUnitType;
set
{
if (_timeUnitType.Equals(value)) return;
_timeUnitType = value;
ReadData = true;
TimeUnitTypeDescription = _timeUnitType.ToString();
OnPropertyChanged("TimeUnitType");
}
}
private string _timeUnitTypeDescription = TimeUnitTypeEnum.MS.ToString();
public string TimeUnitTypeDescription
{
get => _timeUnitTypeDescription;
set
{
if (_timeUnitTypeDescription.Equals(value)) return;
_timeUnitTypeDescription = value;
OnPropertyChanged("TimeUnitTypeDescription");
}
}
//FB 13120 use filter class instead of cfc filter enum
private IFilterClass _selectedFilter = new FilterClass(Common.Enums.Sensors.FilterClassType.Unfiltered);
public IFilterClass SelectedFilter { get => _selectedFilter; set { _selectedFilter = value; ReadData = true; OnPropertyChanged("SelectedFilter"); } }
public void SetSelectedFilterToUnfilteredNoRead()
{
_selectedFilter = new FilterClass(Common.Enums.Sensors.FilterClassType.Unfiltered);
ReadData = false;
OnPropertyChanged("SelectedFilter");
}
#region Min/Max Fixed Y
private double _minFixedY = 0.00;
public double MinFixedY { get => _minFixedY; set { if (_minFixedY.Equals(value)) return; _minFixedY = value; OnPropertyChanged("MinFixedY"); } }
private double _maxFixedY = 0.00;
public double MaxFixedY { get => _maxFixedY; set { if (_maxFixedY.Equals(value)) return; _maxFixedY = value; OnPropertyChanged("MaxFixedY"); } }
#endregion Min/Max Fixed Y
#region Min/Max Fixed X
private double _minFixedT = 0.00;
public double MinFixedT { get => _minFixedT; set { if (_minFixedT.Equals(value)) return; _minFixedT = value; OnPropertyChanged("MinFixedT"); } }
private double _maxFixedT = 0.00;
public double MaxFixedT { get => _maxFixedT; set { if (_maxFixedT.Equals(value)) return; _maxFixedT = value; OnPropertyChanged("MaxFixedT"); } }
#endregion Min/Max Fixed X
private List<double> _fullScaleValues = new List<double> { 200D, 100D, 50D, 20D, 10D, 5D, 1D, 0.1D };
private readonly List<double> _euValues = new List<double> { 5000, 2500, 1000, 500, 100, 50, 10, 5 };
public List<double> FullScaleValues { get => UnitType == ChartUnitTypeEnum.EU || UnitType == ChartUnitTypeEnum.PSD ? _euValues : _fullScaleValues; set { _fullScaleValues = value; OnPropertyChanged("FullScaleValues"); } }
private double _selectedFullScaleValue = 100;
public double SelectedFullScaleValue { get => _selectedFullScaleValue; set { _selectedFullScaleValue = value; OnPropertyChanged("SelectedFullScaleValue"); } }
private bool _lockedT = false;
public bool LockedT { get => _lockedT; set { if (_lockedT.Equals(value)) return; _lockedT = value; OnPropertyChanged("LockedT"); } }
private bool _lockedY = false;
public bool LockedY { get => _lockedY; set { if (_lockedY.Equals(value)) return; _lockedY = value; OnPropertyChanged("LockedY"); } }
private bool _showCursor = false;
public bool ShowCursor
{
get => _showCursor;
set
{
if (_showCursor.Equals(value)) return;
_showCursor = value; Parent?.ShowCusor(_showCursor); OnPropertyChanged("ShowCursor");
}
}
private string _currentCursorValues = string.Empty;
public string CurrentCursorValues
{
get => _currentCursorValues;
set { _currentCursorValues = value; OnPropertyChanged("CurrentCursorValues"); }
}
private YRangeScaleEnum _yRange = YRangeScaleEnum.AutoRange;
public YRangeScaleEnum YRange
{
get => _yRange;
set { if (_yRange.Equals(value)) return; _yRange = value; LockedY = _yRange == YRangeScaleEnum.Fixed; OnPropertyChanged("YRange"); }
}
private FilterOptionEnum _filter = FilterOptionEnum.TestSetupDefault;
public FilterOptionEnum Filter { get => _filter; set { if (_filter.Equals(value)) return; _filter = value; ReadData = true; OnPropertyChanged("Filter"); } }
private IChartOptionsViewModel _parent;
public IChartOptionsViewModel Parent { get => _parent; set { if (_parent != null && _parent.Equals(value)) return; _parent = value; OnPropertyChanged("Parent"); } }
private bool _canPublishChanges = true;
public bool CanPublishChanges { get => _canPublishChanges; set { _canPublishChanges = value; OnPropertyChanged("CanPublishChanges"); } }
private bool _isCursorsAvailable = false;
public bool IsCursorsAvailable { get => _isCursorsAvailable; set { _isCursorsAvailable = value; OnPropertyChanged("IsCursorsAvailable"); } }
private bool _t0Cursor = false;
public bool T0Cursor { get => _t0Cursor; set { _t0Cursor = value; OnPropertyChanged("T0Cursor"); } }
private bool _minMaxCursors = false;
public bool MinMaxCursors { get => _minMaxCursors; set { _minMaxCursors = value; OnPropertyChanged("MinMaxCursors"); } }
private bool _readData = false;
public bool ReadData { get => _readData; set { _readData = value; OnPropertyChanged("ReadData"); } }
private DelegateCommand _resetZoomCommand;
public DelegateCommand ResetZoomCommand => _resetZoomCommand ?? (_resetZoomCommand = new DelegateCommand(ResetZoomMethod));
private void ResetZoomMethod()
{
Parent.ResetZoomMethod();
}
private DelegateCommand _resetTCommand;
public DelegateCommand ResetTCommand => _resetTCommand ?? (_resetTCommand = new DelegateCommand(ResetTMethod));
private void ResetTMethod()
{
Parent.ResetTMethod();
}
private DelegateCommand _saveToPDFCommand;
public DelegateCommand SaveToPDFCommand => _saveToPDFCommand ?? (_saveToPDFCommand = new DelegateCommand(SaveToPDFMethod));
private void SaveToPDFMethod()
{
Parent.SaveToPDFMethod();
}
///<summary>
///Occurs when a property value changes.
///</summary>
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
if (propertyName == "CanPublishChanges"
|| propertyName == "Parent"
|| propertyName == "ReadData"
|| propertyName == "UnitTypeDescription"
|| propertyName == "ShowCursor"
|| propertyName == "LockedT"
|| propertyName == "LockedY"
|| propertyName == "MVOrV"
|| propertyName == "DisplayingVolts"
|| propertyName == "DecimateData"
|| propertyName == "WidthPoints") return;
if (CanPublishChanges) { Parent?.PublishChanges(); }
}
public bool IsSaved { get; }
private bool _decimateData = false;
public bool DecimateData { get => _unitType != ChartUnitTypeEnum.PSD && _unitType != ChartUnitTypeEnum.FFT && _decimateData; set { _decimateData = value; OnPropertyChanged("DecimateData"); } }
private long _widthPoints = 0;
public long WidthPoints { get => _widthPoints; set { _widthPoints = value; OnPropertyChanged("WidthPoints"); } }
#endregion Properties
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DTS.Viewer.DTS.Viewer.ChartOptions")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DTS.Viewer.DTS.Viewer.ChartOptions")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("9f161f2a-4fcd-438e-9768-ba96ba104d6c")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,164 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:common="clr-namespace:DTS.Common;assembly=DTS.Common">
<Style TargetType="Label">
<!--<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="HorizontalContentAlignment" Value="Right"/>-->
<Setter Property="Width" Value="100"/>
</Style>
<Style TargetType="StackPanel">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
<Style TargetType="{x:Type RadioButton}" >
<Setter Property="Width" Value="100"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<BulletDecorator Background="White" Cursor="Hand">
<BulletDecorator.Bullet>
<Grid Height="16" Width="16">
<!--Define size of the Bullet-->
<!--The two borders-->
<Border Name="RadioOuter" Background="Transparent" BorderBrush="Gainsboro" BorderThickness="2" CornerRadius="2" />
<Border CornerRadius="0" Margin="4" Name="RadioMark" Background="#FFADADAD" Visibility="Hidden" />
</Grid>
</BulletDecorator.Bullet>
<!--Text element-->
<TextBlock Margin="3,1,0,0" Foreground="#FF3E3E3E" FontFamily="Calibri" FontSize="12">
<ContentPresenter />
</TextBlock>
</BulletDecorator>
<!--If item is checked, trigger the visibility of the mark-->
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<!--If item is checked, trigger the visibility of the mark and change the color of the selected bullet into a darker gray for better highlighting-->
<Setter TargetName="RadioMark" Property="Visibility" Value="Visible"/>
<Setter TargetName="RadioOuter" Property="BorderBrush" Value="#FFADADAD" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border>
<!--<Rectangle SnapsToDevicePixels="true" Margin="4" Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1"/>-->
<Rectangle Margin="2" StrokeThickness="1" Stroke="LightGray" StrokeDashArray="1 2" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="RoundedButton" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderThickness" Value="3"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="0,0,1,1"/>
<Setter Property="Height" Value="25"/>
<Setter Property="Width" Value="100"/>
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ControlTemplate.Resources>
<Storyboard x:Key="ShowShine">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Shine" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="HideShine">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Shine" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Border CornerRadius="5,5,5,5" BorderThickness="1,1,1,1" RenderTransformOrigin="0.5,0.5" x:Name="border" BorderBrush="Silver">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Border.RenderTransform>
<Border Background="{TemplateBinding Background}" CornerRadius="5,5,5,5" x:Name="border1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.5*"/>
<RowDefinition Height="0.5*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" CornerRadius="5,5,0,0">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#00FFFFFF" Offset="0"/>
<GradientStop Color="#7EFFFFFF" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
</Border>
<Border Grid.Row="1" Opacity="0" x:Name="Shine" Width="Auto" Height="Auto" CornerRadius="0,0,5,5" Margin="1,0,-1,0" Background="{TemplateBinding BorderBrush}"/>
<ContentPresenter VerticalAlignment="Center" Grid.Row="0" Grid.RowSpan="2" HorizontalAlignment="Center" x:Name="contentPresenter"/>
</Grid>
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" TargetName="border1" Value="0.5"/>
<Setter Property="Opacity" TargetName="border" Value="1"/>
<Setter Property="Opacity" TargetName="contentPresenter" Value="0.5"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="RenderTransform" TargetName="border">
<Setter.Value>
<TransformGroup>
<ScaleTransform ScaleX="0.9" ScaleY="0.9"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource HideShine}" x:Name="HideShine_BeginStoryboard"/>
</Trigger.ExitActions>
<Trigger.EnterActions>
<BeginStoryboard x:Name="ShowShine_BeginStoryboard" Storyboard="{StaticResource ShowShine}"/>
</Trigger.EnterActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="FontFamily" Value="Calibri"/>
<Setter Property="FontSize" Value="12"/>
</Style>
<ObjectDataProvider x:Key="CfcFilterData" MethodName="GetValues" ObjectType="{x:Type system:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="common:CFCFilter"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</ResourceDictionary>

View File

@@ -0,0 +1,83 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="CheckRadioFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="14,0,0,0" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="SliderCheckBox" TargetType="{x:Type CheckBox}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<ControlTemplate.Resources>
<Storyboard x:Key="StoryboardIsChecked">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="CheckFlag">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="14"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="StoryboardIsCheckedOff">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="CheckFlag">
<EasingDoubleKeyFrame KeyTime="0" Value="14"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<BulletDecorator Background="Transparent" SnapsToDevicePixels="true">
<BulletDecorator.Bullet>
<Border x:Name="ForegroundPanel" BorderThickness="1" Width="35" Height="20" CornerRadius="10">
<Canvas>
<Border Background="White" x:Name="CheckFlag" CornerRadius="10" VerticalAlignment="Center" BorderThickness="1" Width="19" Height="18" RenderTransformOrigin="0.5,0.5">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
<Border.Effect>
<DropShadowEffect ShadowDepth="1" Direction="180" />
</Border.Effect>
</Border>
</Canvas>
</Border>
</BulletDecorator.Bullet>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/>
</BulletDecorator>
<ControlTemplate.Triggers>
<Trigger Property="HasContent" Value="true">
<Setter Property="FocusVisualStyle" Value="{StaticResource CheckRadioFocusVisual}"/>
<Setter Property="Padding" Value="4,0,0,0"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="ForegroundPanel" Property="Background" Value="Lime" /> <!-- {DynamicResource Accent} -->
<Trigger.EnterActions>
<BeginStoryboard x:Name="BeginStoryboardCheckedTrue" Storyboard="{StaticResource StoryboardIsChecked}" />
<RemoveStoryboard BeginStoryboardName="BeginStoryboardCheckedFalse" />
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter TargetName="ForegroundPanel" Property="Background" Value="Green" />
<Trigger.EnterActions>
<BeginStoryboard x:Name="BeginStoryboardCheckedFalse" Storyboard="{StaticResource StoryboardIsCheckedOff}" />
<RemoveStoryboard BeginStoryboardName="BeginStoryboardCheckedTrue" />
</Trigger.EnterActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,180 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace DTS.Viewer.ChartOptions.Resources {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class StringResources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal StringResources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DTS.Viewer.ChartOptions.Resources.StringResources", typeof(StringResources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Chart Unit Type.
/// </summary>
internal static string ChartUnitType {
get {
return ResourceManager.GetString("ChartUnitType", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Display Filter.
/// </summary>
internal static string FilterOptions_Title {
get {
return ResourceManager.GetString("FilterOptions_Title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Lock T.
/// </summary>
internal static string LockT {
get {
return ResourceManager.GetString("LockT", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Max:.
/// </summary>
internal static string MaxT {
get {
return ResourceManager.GetString("MaxT", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Max:.
/// </summary>
internal static string MaxY {
get {
return ResourceManager.GetString("MaxY", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Min:.
/// </summary>
internal static string MinT {
get {
return ResourceManager.GetString("MinT", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Min:.
/// </summary>
internal static string MinY {
get {
return ResourceManager.GetString("MinY", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Range.
/// </summary>
internal static string Range {
get {
return ResourceManager.GetString("Range", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Reset All.
/// </summary>
internal static string ResetAll {
get {
return ResourceManager.GetString("ResetAll", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Reset T.
/// </summary>
internal static string ResetT {
get {
return ResourceManager.GetString("ResetT", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Save Chart.
/// </summary>
internal static string SaveChart {
get {
return ResourceManager.GetString("SaveChart", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Save to PDF.
/// </summary>
internal static string SaveToPDF {
get {
return ResourceManager.GetString("SaveToPDF", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Time Unit Type.
/// </summary>
internal static string TimeUnitType {
get {
return ResourceManager.GetString("TimeUnitType", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ChartUnitType" xml:space="preserve">
<value>Y軸の表示方法</value>
</data>
<data name="FilterOptions_Title" xml:space="preserve">
<value>表示用ソフトウエアフィルター</value>
</data>
<data name="LockT" xml:space="preserve">
<value>時間軸固定</value>
</data>
<data name="Range" xml:space="preserve">
<value>レンジ設定</value>
</data>
<data name="ResetAll" xml:space="preserve">
<value>全リセット</value>
</data>
<data name="ResetT" xml:space="preserve">
<value>時間軸リセット</value>
</data>
<data name="TimeUnitType" xml:space="preserve">
<value>時間の単位</value>
</data>
</root>

View File

@@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ChartUnitType" xml:space="preserve">
<value>Chart Unit Type</value>
</data>
<data name="FilterOptions_Title" xml:space="preserve">
<value>Display Filter</value>
<comment>Title for Display Filter Options GroupBox</comment>
</data>
<data name="LockT" xml:space="preserve">
<value>Lock T</value>
</data>
<data name="MaxT" xml:space="preserve">
<value>Max:</value>
</data>
<data name="MaxY" xml:space="preserve">
<value>Max:</value>
</data>
<data name="MinT" xml:space="preserve">
<value>Min:</value>
</data>
<data name="MinY" xml:space="preserve">
<value>Min:</value>
</data>
<data name="Range" xml:space="preserve">
<value>Range</value>
</data>
<data name="ResetAll" xml:space="preserve">
<value>Reset All</value>
</data>
<data name="ResetT" xml:space="preserve">
<value>Reset T</value>
</data>
<data name="SaveChart" xml:space="preserve">
<value>Save Chart</value>
</data>
<data name="SaveToPDF" xml:space="preserve">
<value>Save to PDF</value>
</data>
<data name="TimeUnitType" xml:space="preserve">
<value>Time Unit Type</value>
</data>
</root>

View File

@@ -0,0 +1,21 @@
using System;
using System.Windows.Markup;
using DTS.Viewer.ChartOptions.Resources;
namespace DTS.Viewer.ChartOptions
{
[MarkupExtensionReturnType(typeof(string))]
public class TranslateExtension : MarkupExtension
{
private readonly string _key;
public TranslateExtension(string key) { _key = key; }
private const string NotFound = "#stringnotfound#";
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (string.IsNullOrEmpty(_key)) { return NotFound; }
return StringResources.ResourceManager.GetString(_key) ?? NotFound + " " + _key;
}
}
}

View File

@@ -0,0 +1,221 @@
<base:BaseView x:Class="DTS.Viewer.ChartOptions.ChartOptionsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:base="clr-namespace:DTS.Common.Base;assembly=DTS.Common"
xmlns:converters="clr-namespace:DTS.Common.Converters;assembly=DTS.Common"
xmlns:c1="http://schemas.componentone.com/winfx/2006/xaml"
xmlns:viewer="clr-namespace:DTS.Common.Enums.Viewer;assembly=DTS.Common"
xmlns:strings="clr-namespace:DTS.Viewer.ChartOptions"
VerticalAlignment="Top" HorizontalAlignment="Right" x:Name="chartViewOptions">
<base:BaseView.Resources>
<ResourceDictionary>
<converters:InverseBooleanToOpacityConverter x:Key="InverseBooleanToOpacityConverter" />
<converters:BooleanToOpacityConverter x:Key="BooleanToOpacityConverter" />
<converters:EnumBooleanConverter x:Key="EnumBooleanConverter" />
<converters:InverseBooleanConverter x:Key="InverseBooleanConverter" />
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<converters:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter" />
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Resources/ChartOptionsResources.xaml"/>
<ResourceDictionary Source="../Resources/CheckBoxSlider.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</base:BaseView.Resources>
<StackPanel Orientation="Vertical" Width="300" Height="500" VerticalAlignment="Top" HorizontalAlignment="Right"
IsEnabled="{Binding Path=ChartOptionsVisability, Mode=TwoWay}"
Opacity="{Binding Path=ChartOptionsVisability, Converter={StaticResource InverseBooleanToOpacityConverter}, Mode=TwoWay}">
<GroupBox Header="{strings:TranslateExtension ChartUnitType}" Margin="5,0,5,0" AutomationProperties.AutomationId="ChartUnitTypeGrpBx">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<RadioButton GroupName="UnitTypeGroup" Content="{x:Static viewer:ChartUnitTypeEnum.EU}" Margin="0,5,0,5" Width="50" IsChecked="{Binding Path=Model.UnitType, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.EU}}" AutomationProperties.AutomationId="EURdoBtn"/>
<!-- Content="{x:Static viewer:ChartUnitTypeEnum.mV}" -->
<RadioButton GroupName="UnitTypeGroup" Content="{Binding Path=Model.MVOrV}" Margin="10,5,0,5" Width="50" IsChecked="{Binding Path=Model.UnitType, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.mV}}"
AutomationProperties.AutomationId="mVRdoBtn" IsEnabled="{Binding Path=Model.SupportsMV}" />
<RadioButton GroupName="UnitTypeGroup" Content="{x:Static viewer:ChartUnitTypeEnum.ADC}" Margin="10,5,0,5" Width="50" IsChecked="{Binding Path=Model.UnitType, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.ADC}}"
AutomationProperties.AutomationId="ADCRdoBtn" IsEnabled="{Binding Path=Model.SupportsADC}" />
<RadioButton GroupName="UnitTypeGroup" Content="{x:Static viewer:ChartUnitTypeEnum.FFT}" Margin="10,5,0,5" Width="50" IsChecked="{Binding Path=Model.UnitType, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.FFT}}"
AutomationProperties.AutomationId="FFTdoBtn" />
</StackPanel>
</GroupBox>
<GroupBox Header="{strings:TranslateExtension Range}" Margin="5" AutomationProperties.AutomationId="RangeGrpBx">
<StackPanel Orientation="Vertical" HorizontalAlignment="Left">
<Grid Margin="10,10,0,0">
<RadioButton GroupName="Yaxis" Margin="0,5,0,5" Content="{Binding Path= Model.UnitTypeDescription, Mode=OneWay}" ContentStringFormat="Auto Range {0}" HorizontalAlignment="Left"
IsChecked="{Binding Path=Model.YRange, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:YRangeScaleEnum.AutoRange}}"
AutomationProperties.AutomationId="AutoRangeRdoBtn">
<RadioButton.Style>
<Style TargetType="RadioButton" BasedOn="{StaticResource {x:Type RadioButton}}">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Model.UnitType, Mode=OneWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.FFT}}" Value="True">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</RadioButton.Style>
</RadioButton>
<Button Content="{strings:TranslateExtension ResetAll}" Margin="0,0,10,0" Command="{Binding Path=Model.ResetZoomCommand}" HorizontalAlignment="Right" AutomationProperties.AutomationId="ResetAllBtn" />
</Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="10,2,0,0">
<StackPanel.Style>
<Style TargetType="StackPanel" BasedOn="{StaticResource {x:Type StackPanel}}">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Model.UnitType, Mode=OneWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.FFT}}" Value="True">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<RadioButton x:Name="RadioButtonFullScale" GroupName="Yaxis" Margin="0,5,0,5" Content="{Binding Path= Model.UnitTypeDescription, Mode=OneWay}" ContentStringFormat="% Full Scale {0}"
IsChecked="{Binding Path=Model.YRange, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:YRangeScaleEnum.FullScale}}"
AutomationProperties.AutomationId="PerFullScaleRdoBtn"/>
<ComboBox ItemsSource="{Binding Path=Model.FullScaleValues, Mode=TwoWay}"
IsEnabled="{Binding ElementName=RadioButtonFullScale, Path=IsChecked, Mode=TwoWay}"
SelectedItem="{Binding Path=Model.SelectedFullScaleValue, Mode=TwoWay}"
Opacity="{Binding ElementName=RadioButtonFullScale, Path=IsChecked, Mode=TwoWay, Converter={StaticResource InverseBooleanToOpacityConverter}}"
HorizontalAlignment="Center" VerticalAlignment="Center" Margin="60,0,0,0" Width="90" AutomationProperties.AutomationId="PerFullScaleCboBx"/>
</StackPanel>
<StackPanel Orientation="Vertical" HorizontalAlignment="Left" Margin="10,2,0,0">
<StackPanel.Style>
<Style TargetType="StackPanel" BasedOn="{StaticResource {x:Type StackPanel}}">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Model.UnitType, Mode=OneWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.FFT}}" Value="True">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<RadioButton x:Name="RadioButtonFixed" GroupName="Yaxis" Margin="0,5,0,5" HorizontalAlignment="Left" Content="{Binding Path= Model.UnitTypeDescription, Mode=OneWay}" ContentStringFormat="Fixed {0}"
IsChecked="{Binding Path=Model.YRange, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:YRangeScaleEnum.Fixed}, Mode=TwoWay}"
AutomationProperties.AutomationId="FixedRdoBtn"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="10,0,0,0"
IsEnabled="{Binding ElementName=RadioButtonFixed, Path=IsChecked}"
Opacity="{Binding ElementName=RadioButtonFixed, Path=IsChecked, Converter={StaticResource InverseBooleanToOpacityConverter}, Mode=TwoWay}">
<StackPanel Orientation="Horizontal" Margin="0,0,0,0">
<TextBlock Text="{strings:TranslateExtension MinY}" VerticalAlignment="Center" />
<c1:C1NumericBox Format="N3" VerticalAlignment="Center" Margin="5" Width="90" Value="{Binding Path=Model.MinFixedY, Mode=TwoWay}" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10,0,0,0">
<TextBlock Text="{strings:TranslateExtension MaxY}" VerticalAlignment="Center" />
<c1:C1NumericBox Format="N3" VerticalAlignment="Center" Margin="5" Width="90" Value="{Binding Path=Model.MaxFixedY, Mode=TwoWay}"/>
</StackPanel>
</StackPanel>
</StackPanel>
<StackPanel Orientation="Vertical" HorizontalAlignment="Left">
<StackPanel.Style>
<Style TargetType="StackPanel" BasedOn="{StaticResource {x:Type StackPanel}}">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Model.UnitType, Mode=OneWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.FFT}}" Value="True">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<Grid>
<CheckBox x:Name="CheckBoxLockT" Content="{strings:TranslateExtension LockT}" Margin="10,10,0,0" IsChecked="{Binding Path=Model.LockedT, Mode=TwoWay}" HorizontalAlignment="Left" />
<Button Content="{strings:TranslateExtension ResetT}" Margin="0,0,10,0" Command="{Binding Path=Model.ResetTCommand}" HorizontalAlignment="Right" AutomationProperties.AutomationId="ResetTBtn"/>
</Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="10,0,0,0" >
<StackPanel Orientation="Horizontal" Margin="10,0,0,0" >
<TextBlock Text="{strings:TranslateExtension MinT}" VerticalAlignment="Center" />
<c1:C1NumericBox Format="N3" VerticalAlignment="Center" Margin="5" Width="90" Value="{Binding Path=Model.MinFixedT, Mode=TwoWay}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="20,0,0,0">
<TextBlock Text="{strings:TranslateExtension MaxT}" VerticalAlignment="Center" />
<c1:C1NumericBox Format="N3" VerticalAlignment="Center" Margin="5" Width="90" Value="{Binding Path=Model.MaxFixedT, Mode=TwoWay}"/>
</StackPanel>
</StackPanel>
</StackPanel>
</StackPanel>
</GroupBox>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" >
<StackPanel.Style>
<Style TargetType="StackPanel" BasedOn="{StaticResource {x:Type StackPanel}}">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Model.UnitType, Mode=OneWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.FFT}}" Value="True">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<GroupBox Header="{strings:TranslateExtension FilterOptions_Title}" Margin="5,0,5,0" Width="130" AutomationProperties.AutomationId="FilterGrpBx">
<GroupBox.Style>
<Style TargetType="GroupBox" BasedOn="{StaticResource {x:Type GroupBox}}">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Model.UnitType, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:ChartUnitTypeEnum.EU}}" Value="False">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=Model.IsDigitalChannel, Mode=TwoWay}" Value="True">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</GroupBox.Style>
<StackPanel Orientation="Vertical" >
<RadioButton Width="110" GroupName="FilterGroup" Margin="0,5,0,0" Content="{x:Static viewer:FilterOptionEnum.Unfiltered}" IsChecked="{Binding Path=Model.Filter, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:FilterOptionEnum.Unfiltered}}" AutomationProperties.AutomationId="UnfRdoBtn"/>
<RadioButton Width="110" GroupName="FilterGroup" Margin="0,5,0,0" Content="{x:Static viewer:FilterOptionEnum.TestSetupDefault}" IsChecked="{Binding Path=Model.Filter, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:FilterOptionEnum.TestSetupDefault}}" AutomationProperties.AutomationId="TestSetupDefRdoBtn"/>
<RadioButton Width="110" GroupName="FilterGroup" Margin="0,5,0,0" Content="{x:Static viewer:FilterOptionEnum.Custom}" x:Name="RbCustom" IsChecked="{Binding Path=Model.Filter, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:FilterOptionEnum.Custom}}"/>
<ComboBox DisplayMemberPath="FilterName" ItemsSource="{Binding ElementName=chartViewOptions, Path=AvailableCFC}" SelectedItem="{Binding Path=Model.SelectedFilter, Mode=TwoWay}"
IsEnabled="{Binding ElementName=RbCustom, Path=IsChecked, Mode=TwoWay}"
Opacity="{Binding ElementName=RbCustom, Path=IsChecked, Converter={StaticResource InverseBooleanToOpacityConverter}}"
AutomationProperties.AutomationId="CustomFilterCboBx"
HorizontalAlignment="Center"
Width="110"
Height="17"
VerticalAlignment="Center"
Margin="5" />
</StackPanel>
</GroupBox>
<GroupBox Header="{strings:TranslateExtension TimeUnitType}" Margin="5,0,5,0" Width="130" AutomationProperties.AutomationId="TimeUnitGrpBx">
<StackPanel Orientation="Vertical" HorizontalAlignment="Center">
<RadioButton GroupName="TimeUnitGroup" Content="{x:Static viewer:TimeUnitTypeEnum.MS}" Margin="0,5,0,5" Width="110" IsChecked="{Binding Path=Model.TimeUnitType, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:TimeUnitTypeEnum.MS}}" AutomationProperties.AutomationId="msRdoBtn"/>
<RadioButton GroupName="TimeUnitGroup" Content="{x:Static viewer:TimeUnitTypeEnum.Seconds}" Margin="0,5,0,5" Width="110" IsChecked="{Binding Path=Model.TimeUnitType, Mode=TwoWay, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static viewer:TimeUnitTypeEnum.Seconds}}" AutomationProperties.AutomationId="secRdoBtn"/>
</StackPanel>
</GroupBox>
</StackPanel>
<GroupBox Header="{strings:TranslateExtension SaveChart}" Margin="5" HorizontalAlignment="Left" AutomationProperties.AutomationId="SaveBx">
<StackPanel Orientation="Vertical" HorizontalAlignment="Left">
<Button Content="{strings:TranslateExtension SaveToPDF}" Margin="10" Padding="10, 5" Command="{Binding Path=Model.SaveToPDFCommand}" AutomationProperties.AutomationId="SaveToPDFBtn" />
</StackPanel>
</GroupBox>
</StackPanel>
</base:BaseView>

View File

@@ -0,0 +1,29 @@
using DTS.Common.Interface;
using DTS.Common.Interface.Sensors.SoftwareFilters;
using DTS.SensorDB;
using System.Collections.Generic;
namespace DTS.Viewer.ChartOptions
{
/// <summary>
/// Interaction logic for ChartOptionsView.xaml
/// </summary>
public partial class ChartOptionsView : IChartOptionsView
{
public ChartOptionsView()
{
InitializeComponent();
}
/// <summary>
/// FB 13120 Available filter classes
/// </summary>
public List<IFilterClass> AvailableCFC
{
get
{
return new AnalogSettingDefaults().FilterOptions;
}
}
}
}

View File

@@ -0,0 +1,244 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using DTS.Common.Base;
using Unity;
using DTS.Common.Enums.Viewer;
using DTS.Common.Events;
using DTS.Common.Interface;
using Prism.Events;
using Prism.Regions;
using DTS.Common.Interactivity;
using Prism.Commands;
// ReSharper disable UnassignedGetOnlyAutoProperty
// ReSharper disable InconsistentNaming
// ReSharper disable NotAccessedField.Local
// ReSharper disable UnusedAutoPropertyAccessor.Local
// ReSharper disable CheckNamespace
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Local
// ReSharper disable RedundantDefaultMemberInitializer
namespace DTS.Viewer.ChartOptions
{
public class ChartOptionsViewModel : BaseViewModel<IChartOptionsViewModel>, IChartOptionsViewModel
{
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; }
public IBaseView View { get; set; }
private IChartOptionsModel _model;
public new IChartOptionsModel Model { get => _model; set { _model = value; OnPropertyChanged("Model"); } }
/// <summary>
/// Creates a new instance of the TestSummaryViewModel.
/// </summary>
/// <param name="view">The TestListView 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 ChartOptionsViewModel(IChartOptionsView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)
: base(regionManager, eventAggregator, unityContainer)
{
View = view;
View.DataContext = this;
NotificationRequest = new InteractionRequest<Notification>();
ConfirmationRequest = new InteractionRequest<Confirmation>();
_eventAggregator = eventAggregator;
_unityContainer = unityContainer;
_eventAggregator.GetEvent<ChartAxisChangedEvent>().Subscribe(OnChartAxisChangedEvent);
//Model = _unityContainer.Resolve<IChartOptionsModel>();
//Model.Parent = this;
//View.DataContext = Model;
}
public override void Initialize()
{
}
private string chartType = string.Empty;
public override void Initialize(object parameter)
{
Subscribe();
Model = _unityContainer.Resolve<IChartOptionsModel>();
Model.Parent = this;
View.DataContext = Model;
if (parameter is IViewerMainViewModel)
{
Parent = (IBaseViewModel)parameter;
Model.DecimateData = true;
}
else if (parameter is Tuple<IBaseViewModel, string> tuParam && tuParam.Item1 is IPSDReportMainViewModel)
{
Parent = tuParam.Item1;
chartType = tuParam.Item2;
Model.CanPublishChanges = false;
if ("Graph" == chartType)
{
Model.UnitType = ChartUnitTypeEnum.PSD;
Model.YRange = YRangeScaleEnum.Fixed;
Model.MaxFixedY = 1;
Model.MinFixedY = 1e-12; //log scale, can't be 0
Model.DecimateData = false;
}
else
{
Model.DecimateData = true;
Model.Filter = FilterOptionEnum.Unfiltered;
}
Model.CanPublishChanges = true;
}
}
private void Subscribe()
{
_eventAggregator.GetEvent<CursorsAlailableChangedEvent>().Subscribe(OnCursorsAlailableChanged);
_eventAggregator.GetEvent<GraphSelectedChannelsNotification>().Subscribe(OnGraphSelectedChannelsChanged);
}
private string Directory { get; set; }
private void OnGraphSelectedChannelsChanged(GraphSelectedChannelsNotificationArg arg)
{
if (Parent != arg?.ParentVM) return;
var channels = arg.SelectedChannels;
Model.Parent = this;
Directory = channels.Count > 0 ? channels[0].BinaryFilePath : string.Empty;
ChartOptionsVisability = (channels.Count > 0);
//whenever channels change, check the status of mV/ADC buttons
//18256 Implement StackChannelScaleFactorsEUPerADC Arm/Event Command
if (AllChannelsSupportADC(channels))
{
Model.SupportsADC = true;
}
else
{
Model.SupportsADC = false;
if (Model.UnitType == ChartUnitTypeEnum.ADC)
{
Model.UnitType = ChartUnitTypeEnum.EU;
}
}
if (AllChannelsSupportmV(channels))
{
Model.SupportsMV = true;
}
else
{
Model.SupportsMV = false;
if (Model.UnitType == ChartUnitTypeEnum.mV)
{
Model.UnitType = ChartUnitTypeEnum.EU;
}
}
PublishChanges();
}
/// <summary>
/// returns true if all channels support ADC
/// for now this is determined by looking at the sensor serial number, but we
/// can be more sophisticated in the future, as there are other channels that won't support ADC meaningfully as well
/// (like calculated channels)
/// </summary>
private bool AllChannelsSupportADC(List<ITestChannel> channels)
{
return !channels.Exists(x => Common.Enums.Hardware.HardwareConstants.IsTSRAIRSerialNumber(x.ParentModule.BaseSerialNumber));
}
/// <summary>
/// returns true if all channels support mV
/// </summary>
private bool AllChannelsSupportmV(List<ITestChannel> channels)
{
return !channels.Exists(x => Common.Enums.Hardware.HardwareConstants.IsTSRAIRSerialNumber(x.ParentModule.BaseSerialNumber));
}
private void OnCursorsAlailableChanged(bool value)
{
Model.IsCursorsAvailable = value;
}
private void OnChartAxisChangedEvent(ChartAxisChangedEventArg args)
{
if (args?.ParentVM != Parent) return;
Model.CanPublishChanges = false;
switch (args.Axis)
{
case "Y":
Model.MinFixedY = args.MinValue;
Model.MaxFixedY = args.MaxValue;
break;
case "X":
Model.MinFixedT = args.MinValue;
Model.MaxFixedT = args.MaxValue;
break;
}
Model.CanPublishChanges = true;
}
#region Properties
public object ContextSearchRegion { get; set; }
public new bool IsMenuIncluded { get; set; }
public new bool IsNavigationIncluded { get; set; }
public new bool IsBusy { get; set; }
public new bool IsDirty { get; }
private bool _chartOptionsVisability = false;
public bool ChartOptionsVisability { get => _chartOptionsVisability; set { _chartOptionsVisability = value; OnPropertyChanged("ChartOptionsVisability"); } }
public new event PropertyChangedEventHandler PropertyChanged;
public new void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion Properties
#region Methods
public void ShowMinMaxCursor(bool value)
{
_eventAggregator.GetEvent<CursorShowMinMaxChangedEvent>().Publish(value);
}
public void ResetZoomMethod()
{
Model.YRange = YRangeScaleEnum.AutoRange;
_eventAggregator.GetEvent<ResetZoomChangedEvent>().Publish(true);
}
public void ResetTMethod()
{
_eventAggregator.GetEvent<ResetZoomChangedEvent>().Publish(false);
}
public void SaveToPDFMethod()
{
_eventAggregator.GetEvent<SaveToPDFRequestedEvent>().Publish(Directory);
}
public void PublishChanges()
{
_eventAggregator.GetEvent<ChartOptionsChangedEvent>().Publish(new ChartOptionsChangedEventArg() { ParentVM = Parent, Model = Model, ChartType = chartType });
}
public void ShowCusor(bool value)
{
_eventAggregator.GetEvent<CursorShowChangedEvent>().Publish(value);
}
#endregion Methods
#region Commands
private DelegateCommand _clearMarkersCommand;
public DelegateCommand ClearMarkersCommand => _clearMarkersCommand ?? (_clearMarkersCommand = new DelegateCommand(ClearMarkersMethod));
private void ClearMarkersMethod()
{
_eventAggregator.GetEvent<CursorsClearChangedEvent>().Publish(true);
}
#endregion
}
}

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.8", FrameworkDisplayName = "")]

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]

View File

@@ -0,0 +1 @@
12

View File

@@ -0,0 +1 @@
12

View File

@@ -0,0 +1,44 @@
<base:BaseView x:Class="DTS.Viewer.Filter.FilterView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:base="clr-namespace:DTS.Common.Base;assembly=DTS.Common"
xmlns:converters="clr-namespace:DTS.Common.Converters;assembly=DTS.Common">
<base:BaseView.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/DTS.Common;component/Themes/CommonStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="Button" BasedOn="{StaticResource PageContentButton}" />
<Style TargetType="TextBox" BasedOn="{StaticResource PageContentTextBoxStyle}">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<!-- ReSharper disable once Xaml.RedundantResource -->
</ResourceDictionary>
</base:BaseView.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox Text="{Binding Path=FilterParam, UpdateSourceTrigger=PropertyChanged}" AutomationProperties.AutomationId="ViewSearchTxtBx">
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotFocus">
<i:InvokeCommandAction Command="{Binding GotFocusActionCommand}" />
</i:EventTrigger>
<i:EventTrigger EventName="LostFocus">
<i:InvokeCommandAction Command="{Binding LostFocusActionCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<Button Grid.Column="1" Content="..." Visibility="{Binding Path=SearchButtonVisability, Converter={StaticResource BooleanToVisibilityConverter}}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding ClickedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Grid>
</base:BaseView>

View File

@@ -0,0 +1,72 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace DTS.Viewer.Filter.Resources {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class StringResources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal StringResources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DTS.Viewer.Filter.Resources.StringResources", typeof(StringResources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Search.
/// </summary>
internal static string Search {
get {
return ResourceManager.GetString("Search", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,146 @@
using System;
using System.Windows.Media.Imaging;
using DTS.Common;
using DTS.Common.Interface;
using DTS.Viewer.Filter;
using Prism.Ioc;
using Prism.Modularity;
using Unity;
// ReSharper disable UnusedParameter.Local
[assembly: FilterPropertiesName()]
[assembly: FilterPropertiesImage()]
namespace DTS.Viewer.Filter
{
[Module(ModuleName = "FilterProperties")]
public class FilterModule : IModule
{
/// <summary>
/// Injected unity container
/// </summary>
private readonly IUnityContainer _unityContainer;
/// <summary>
/// Initializes a new instance of the <see cref="FilterModule"/> class.
/// </summary>
/// <param name="unityContainer">Obtained reference of the unity container by using dependency injection.</param>
public FilterModule(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
public void Initialize()
{
// Register View & View-Model with Unity dependency injection container as a singleton.
_unityContainer.RegisterType<IFilterView, FilterView>();
_unityContainer.RegisterType<IFilterViewModel, FilterViewModel>();
}
public void OnInitialized(IContainerProvider containerProvider)
{
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
Initialize();
}
}
/// <summary>
/// Attribute class contains assembly name
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class FilterPropertiesNameAttribute : TextAttribute
{
private readonly string _assemblyName;
public FilterPropertiesNameAttribute() : this(null) { }
public FilterPropertiesNameAttribute(string s)
{
_assemblyName = AssemblyNames.Filter.ToString();
}
public override string AssemblyName => _assemblyName;
public override Type GetAttributeType()
{
return typeof(TextAttribute);
}
public override string GetAssemblyName()
{
return AssemblyName;
}
}
/// <summary>
/// Attribute class contains assembly image and name - used on the Main screen to display available components
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class FilterPropertiesImageAttribute : ImageAttribute
{
private BitmapImage _img;
public FilterPropertiesImageAttribute() : this(null) { }
public override BitmapImage AssemblyImage
{
get { _img = AssemblyInfo.GetImage(AssemblyNames.Filter.ToString()); return _img; }
}
public FilterPropertiesImageAttribute(string s)
{
_img = AssemblyInfo.GetImage(AssemblyNames.Filter.ToString());
}
public override Type GetAttributeType()
{
return typeof(ImageAttribute);
}
public override BitmapImage GetAssemblyImage()
{
return AssemblyImage;
}
public override string GetAssemblyName()
{
return AssemblyName;
}
public override eAssemblyRegion GetAssemblyRegion()
{
return AssemblyRegion;
}
public override string GetAssemblyGroup()
{
return AssemblyGroup;
}
private string _name;
public override string AssemblyName
{
get { _name = AssemblyNames.Filter.ToString(); return _name; }
}
private string _group;
public override string AssemblyGroup
{
get { _group = eAssemblyGroups.Viewer.ToString(); return _group; }
}
private eAssemblyRegion _region;
public override eAssemblyRegion AssemblyRegion
{
get { _region = eAssemblyRegion.FilterRegion; return _region; }
}
}
}

View File

@@ -0,0 +1,146 @@
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using DTS.Common.Base;
using DTS.Common.Events;
using DTS.Common.Interactivity;
using DTS.Common.Interface;
using Prism.Commands;
using Prism.Events;
using Prism.Regions;
using Unity;
// ReSharper disable CheckNamespace
// ReSharper disable InconsistentNaming
// ReSharper disable UnassignedGetOnlyAutoProperty
// ReSharper disable NotAccessedField.Local
// ReSharper disable RedundantDefaultMemberInitializer
// ReSharper disable UnusedAutoPropertyAccessor.Local
namespace DTS.Viewer.Filter
{
public class FilterViewModel : BaseViewModel<IFilterViewModel>, IFilterViewModel
{
public IBaseView 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 FilterViewModel.
/// </summary>
/// <param name="view">The Filter 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 Unity container.</param>
public FilterViewModel(IFilterView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)
: base(regionManager, eventAggregator, unityContainer)
{
View = view;
View.DataContext = this;
NotificationRequest = new InteractionRequest<Notification>();
ConfirmationRequest = new InteractionRequest<Confirmation>();
_eventAggregator = eventAggregator;
_unityContainer = unityContainer;
_searchButtonVisability = false;
_filterParam = FilterParamDefault;
eventAggregator.GetEvent<FilterParameterChangedEvent>().Subscribe(OnFilterParameterChanged);
}
#region Properties
private IBaseViewModel _requester;
public IBaseViewModel Requester { get => _requester; set { _requester = value; OnPropertyChanged("Requester"); } }
public new bool IsMenuIncluded { get; set; }
public new bool IsNavigationIncluded { get; set; }
public new bool IsBusy { get; set; }
public new bool IsDirty { get; }
public object ContextSearchRegion { get; set; }
private bool _searchButtonVisability = false;
public bool SearchButtonVisability { get => _searchButtonVisability; set { _searchButtonVisability = value; OnPropertyChanged("SearchButtonVisability"); } }
private readonly string FilterParamDefault = Resources.StringResources.Search;
private string _filterParam;
public string FilterParam
{
get => _filterParam;
set
{
var doFilter = !(_filterParam == FilterParamDefault && value == string.Empty || value == FilterParamDefault);
_filterParam = value; OnPropertyChanged("FilterParam");
if (doFilter)
{ _eventAggregator.GetEvent<FilterParameterChangedEvent>().Publish(new FilterParameterArgs { Param = _filterParam, Requester = _requester }); }
}
}
public new event PropertyChangedEventHandler PropertyChanged;
///<summary>
///Occurs when a property value changes.
///</summary>
private new void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion Properties
#region Methods
/// <summary>
/// handle filtering, there's only one case we care about thats
/// when it's part of the visiting the landing page again
/// for now we can determine this case when the requester is null
/// we can change that in the future if we need to
/// 15641 Previous search key word displayed on View Data landing page
/// </summary>
private void OnFilterParameterChanged(FilterParameterArgs args)
{
if (null != args.Requester)
{
return;
}
_filterParam = args.Param;
OnPropertyChanged("FilterParam");
}
public override void Initialize(object parameter)
{
Parent = (IBaseViewModel)parameter;
Requester = Parent;
}
#endregion Methods
#region Commands
//ClickedCommand
private DelegateCommand _clickedCommand;
public DelegateCommand ClickedCommand => _clickedCommand ?? (_clickedCommand = new DelegateCommand(ClickedCommandAction));
private void ClickedCommandAction()
{
}
private DelegateCommand _gotFocusActionCommand;
public DelegateCommand GotFocusActionCommand => _gotFocusActionCommand ?? (_gotFocusActionCommand = new DelegateCommand(GotFocusAction));
private void GotFocusAction()
{
if (FilterParam == FilterParamDefault)
FilterParam = string.Empty;
}
private DelegateCommand _lostFocusActionCommand;
public DelegateCommand LostFocusActionCommand => _lostFocusActionCommand ?? (_lostFocusActionCommand = new DelegateCommand(LostFocusAction));
private void LostFocusAction()
{
if (string.IsNullOrEmpty(FilterParam))
FilterParam = FilterParamDefault;
}
#endregion Commands
}
}

View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Search" xml:space="preserve">
<value>Search</value>
</data>
</root>

View File

@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{E958450A-4E86-46BD-8B9A-65FCF8326423}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DTS.Viewer.Filter</RootNamespace>
<AssemblyName>DTS.Viewer.Filter</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Practices.ServiceLocation">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Microsoft.Practices.ServiceLocation.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Xaml.Behaviors">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Microsoft.Xaml.Behaviors.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="Prism">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.dll</HintPath>
</Reference>
<Reference Include="Prism.Unity.Wpf">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.Unity.Wpf.dll</HintPath>
</Reference>
<Reference Include="Prism.Wpf">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.Wpf.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="Unity.Abstractions">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Unity.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Unity.Container">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Unity.Container.dll</HintPath>
</Reference>
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="FilterModule.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Resources\StringResources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>StringResources.resx</DependentUpon>
</Compile>
<Compile Include="Resources\TranslateExtension.cs" />
<Compile Include="ViewModel\FilterViewModel.cs" />
<Compile Include="View\FilterView.xaml.cs">
<DependentUpon>FilterView.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Images\search.png" />
<EmbeddedResource Include="Resources\StringResources.ja.resx" />
<EmbeddedResource Include="Resources\StringResources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>StringResources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Page Include="View\FilterView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Common\DTS.Common.Core\DTS.Common.Core.csproj">
<Project>{fab1f470-1574-4301-b56e-d3364aa93679}</Project>
<Name>DTS.Common.Core</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common\DTS.Common.csproj">
<Project>{114edc77-f3b5-4576-a91b-40818d503b55}</Project>
<Name>DTS.Common</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DTS.Viewer.Search")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DTS.Viewer.Search")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("e958450a-4e86-46bd-8b9a-65fcf8326423")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,21 @@
using System;
using System.Windows.Markup;
using DTS.Viewer.Filter.Resources;
namespace DTS.Viewer.Filter
{
[MarkupExtensionReturnType(typeof(string))]
public class TranslateExtension : MarkupExtension
{
private readonly string _key;
public TranslateExtension(string key) { _key = key; }
private const string NotFound = "#stringnotfound#";
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (string.IsNullOrEmpty(_key)) { return NotFound; }
return StringResources.ResourceManager.GetString(_key) ?? NotFound + " " + _key;
}
}
}

View File

@@ -0,0 +1,17 @@
using DTS.Common.Interface;
// ReSharper disable CheckNamespace
namespace DTS.Viewer.Filter
{
/// <summary>
/// Interaction logic for FilterView.xaml
/// </summary>
public partial class FilterView : IFilterView
{
public FilterView()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{E958450A-4E86-46BD-8B9A-65FCF8326423}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DTS.Viewer.Filter</RootNamespace>
<AssemblyName>DTS.Viewer.Filter</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Practices.ServiceLocation">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Microsoft.Practices.ServiceLocation.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Xaml.Behaviors">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Microsoft.Xaml.Behaviors.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="Prism">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.dll</HintPath>
</Reference>
<Reference Include="Prism.Unity.Wpf">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.Unity.Wpf.dll</HintPath>
</Reference>
<Reference Include="Prism.Wpf">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Prism.Wpf.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="Unity.Abstractions">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Unity.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Unity.Container">
<HintPath>..\..\..\Common\DTS.Common\lib\PrismLibrary\Unity.Container.dll</HintPath>
</Reference>
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="FilterModule.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Resources\StringResources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>StringResources.resx</DependentUpon>
</Compile>
<Compile Include="Resources\TranslateExtension.cs" />
<Compile Include="ViewModel\FilterViewModel.cs" />
<Compile Include="View\FilterView.xaml.cs">
<DependentUpon>FilterView.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Images\search.png" />
<EmbeddedResource Include="Resources\StringResources.ja.resx" />
<EmbeddedResource Include="Resources\StringResources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>StringResources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Page Include="View\FilterView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Common\DTS.Common.Core\DTS.Common.Core.csproj">
<Project>{fab1f470-1574-4301-b56e-d3364aa93679}</Project>
<Name>DTS.Common.Core</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Common\DTS.Common\DTS.Common.csproj">
<Project>{114edc77-f3b5-4576-a91b-40818d503b55}</Project>
<Name>DTS.Common</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,146 @@
using System;
using System.Windows.Media.Imaging;
using DTS.Common;
using DTS.Common.Interface;
using DTS.Viewer.Filter;
using Prism.Ioc;
using Prism.Modularity;
using Unity;
// ReSharper disable UnusedParameter.Local
[assembly: FilterPropertiesName()]
[assembly: FilterPropertiesImage()]
namespace DTS.Viewer.Filter
{
[Module(ModuleName = "FilterProperties")]
public class FilterModule : IModule
{
/// <summary>
/// Injected unity container
/// </summary>
private readonly IUnityContainer _unityContainer;
/// <summary>
/// Initializes a new instance of the <see cref="FilterModule"/> class.
/// </summary>
/// <param name="unityContainer">Obtained reference of the unity container by using dependency injection.</param>
public FilterModule(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
public void Initialize()
{
// Register View & View-Model with Unity dependency injection container as a singleton.
_unityContainer.RegisterType<IFilterView, FilterView>();
_unityContainer.RegisterType<IFilterViewModel, FilterViewModel>();
}
public void OnInitialized(IContainerProvider containerProvider)
{
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
Initialize();
}
}
/// <summary>
/// Attribute class contains assembly name
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class FilterPropertiesNameAttribute : TextAttribute
{
private readonly string _assemblyName;
public FilterPropertiesNameAttribute() : this(null) { }
public FilterPropertiesNameAttribute(string s)
{
_assemblyName = AssemblyNames.Filter.ToString();
}
public override string AssemblyName => _assemblyName;
public override Type GetAttributeType()
{
return typeof(TextAttribute);
}
public override string GetAssemblyName()
{
return AssemblyName;
}
}
/// <summary>
/// Attribute class contains assembly image and name - used on the Main screen to display available components
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class FilterPropertiesImageAttribute : ImageAttribute
{
private BitmapImage _img;
public FilterPropertiesImageAttribute() : this(null) { }
public override BitmapImage AssemblyImage
{
get { _img = AssemblyInfo.GetImage(AssemblyNames.Filter.ToString()); return _img; }
}
public FilterPropertiesImageAttribute(string s)
{
_img = AssemblyInfo.GetImage(AssemblyNames.Filter.ToString());
}
public override Type GetAttributeType()
{
return typeof(ImageAttribute);
}
public override BitmapImage GetAssemblyImage()
{
return AssemblyImage;
}
public override string GetAssemblyName()
{
return AssemblyName;
}
public override eAssemblyRegion GetAssemblyRegion()
{
return AssemblyRegion;
}
public override string GetAssemblyGroup()
{
return AssemblyGroup;
}
private string _name;
public override string AssemblyName
{
get { _name = AssemblyNames.Filter.ToString(); return _name; }
}
private string _group;
public override string AssemblyGroup
{
get { _group = eAssemblyGroups.Viewer.ToString(); return _group; }
}
private eAssemblyRegion _region;
public override eAssemblyRegion AssemblyRegion
{
get { _region = eAssemblyRegion.FilterRegion; return _region; }
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 B

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DTS.Viewer.Search")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DTS.Viewer.Search")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("e958450a-4e86-46bd-8b9a-65fcf8326423")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,72 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace DTS.Viewer.Filter.Resources {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class StringResources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal StringResources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DTS.Viewer.Filter.Resources.StringResources", typeof(StringResources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Search.
/// </summary>
internal static string Search {
get {
return ResourceManager.GetString("Search", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Search" xml:space="preserve">
<value>Search</value>
</data>
</root>

View File

@@ -0,0 +1,21 @@
using System;
using System.Windows.Markup;
using DTS.Viewer.Filter.Resources;
namespace DTS.Viewer.Filter
{
[MarkupExtensionReturnType(typeof(string))]
public class TranslateExtension : MarkupExtension
{
private readonly string _key;
public TranslateExtension(string key) { _key = key; }
private const string NotFound = "#stringnotfound#";
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (string.IsNullOrEmpty(_key)) { return NotFound; }
return StringResources.ResourceManager.GetString(_key) ?? NotFound + " " + _key;
}
}
}

View File

@@ -0,0 +1,44 @@
<base:BaseView x:Class="DTS.Viewer.Filter.FilterView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:base="clr-namespace:DTS.Common.Base;assembly=DTS.Common"
xmlns:converters="clr-namespace:DTS.Common.Converters;assembly=DTS.Common">
<base:BaseView.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/DTS.Common;component/Themes/CommonStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="Button" BasedOn="{StaticResource PageContentButton}" />
<Style TargetType="TextBox" BasedOn="{StaticResource PageContentTextBoxStyle}">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<!-- ReSharper disable once Xaml.RedundantResource -->
</ResourceDictionary>
</base:BaseView.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox Text="{Binding Path=FilterParam, UpdateSourceTrigger=PropertyChanged}" AutomationProperties.AutomationId="ViewSearchTxtBx">
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotFocus">
<i:InvokeCommandAction Command="{Binding GotFocusActionCommand}" />
</i:EventTrigger>
<i:EventTrigger EventName="LostFocus">
<i:InvokeCommandAction Command="{Binding LostFocusActionCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<Button Grid.Column="1" Content="..." Visibility="{Binding Path=SearchButtonVisability, Converter={StaticResource BooleanToVisibilityConverter}}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding ClickedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Grid>
</base:BaseView>

View File

@@ -0,0 +1,17 @@
using DTS.Common.Interface;
// ReSharper disable CheckNamespace
namespace DTS.Viewer.Filter
{
/// <summary>
/// Interaction logic for FilterView.xaml
/// </summary>
public partial class FilterView : IFilterView
{
public FilterView()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,146 @@
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using DTS.Common.Base;
using DTS.Common.Events;
using DTS.Common.Interactivity;
using DTS.Common.Interface;
using Prism.Commands;
using Prism.Events;
using Prism.Regions;
using Unity;
// ReSharper disable CheckNamespace
// ReSharper disable InconsistentNaming
// ReSharper disable UnassignedGetOnlyAutoProperty
// ReSharper disable NotAccessedField.Local
// ReSharper disable RedundantDefaultMemberInitializer
// ReSharper disable UnusedAutoPropertyAccessor.Local
namespace DTS.Viewer.Filter
{
public class FilterViewModel : BaseViewModel<IFilterViewModel>, IFilterViewModel
{
public IBaseView 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 FilterViewModel.
/// </summary>
/// <param name="view">The Filter 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 Unity container.</param>
public FilterViewModel(IFilterView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)
: base(regionManager, eventAggregator, unityContainer)
{
View = view;
View.DataContext = this;
NotificationRequest = new InteractionRequest<Notification>();
ConfirmationRequest = new InteractionRequest<Confirmation>();
_eventAggregator = eventAggregator;
_unityContainer = unityContainer;
_searchButtonVisability = false;
_filterParam = FilterParamDefault;
eventAggregator.GetEvent<FilterParameterChangedEvent>().Subscribe(OnFilterParameterChanged);
}
#region Properties
private IBaseViewModel _requester;
public IBaseViewModel Requester { get => _requester; set { _requester = value; OnPropertyChanged("Requester"); } }
public new bool IsMenuIncluded { get; set; }
public new bool IsNavigationIncluded { get; set; }
public new bool IsBusy { get; set; }
public new bool IsDirty { get; }
public object ContextSearchRegion { get; set; }
private bool _searchButtonVisability = false;
public bool SearchButtonVisability { get => _searchButtonVisability; set { _searchButtonVisability = value; OnPropertyChanged("SearchButtonVisability"); } }
private readonly string FilterParamDefault = Resources.StringResources.Search;
private string _filterParam;
public string FilterParam
{
get => _filterParam;
set
{
var doFilter = !(_filterParam == FilterParamDefault && value == string.Empty || value == FilterParamDefault);
_filterParam = value; OnPropertyChanged("FilterParam");
if (doFilter)
{ _eventAggregator.GetEvent<FilterParameterChangedEvent>().Publish(new FilterParameterArgs { Param = _filterParam, Requester = _requester }); }
}
}
public new event PropertyChangedEventHandler PropertyChanged;
///<summary>
///Occurs when a property value changes.
///</summary>
private new void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion Properties
#region Methods
/// <summary>
/// handle filtering, there's only one case we care about thats
/// when it's part of the visiting the landing page again
/// for now we can determine this case when the requester is null
/// we can change that in the future if we need to
/// 15641 Previous search key word displayed on View Data landing page
/// </summary>
private void OnFilterParameterChanged(FilterParameterArgs args)
{
if (null != args.Requester)
{
return;
}
_filterParam = args.Param;
OnPropertyChanged("FilterParam");
}
public override void Initialize(object parameter)
{
Parent = (IBaseViewModel)parameter;
Requester = Parent;
}
#endregion Methods
#region Commands
//ClickedCommand
private DelegateCommand _clickedCommand;
public DelegateCommand ClickedCommand => _clickedCommand ?? (_clickedCommand = new DelegateCommand(ClickedCommandAction));
private void ClickedCommandAction()
{
}
private DelegateCommand _gotFocusActionCommand;
public DelegateCommand GotFocusActionCommand => _gotFocusActionCommand ?? (_gotFocusActionCommand = new DelegateCommand(GotFocusAction));
private void GotFocusAction()
{
if (FilterParam == FilterParamDefault)
FilterParam = string.Empty;
}
private DelegateCommand _lostFocusActionCommand;
public DelegateCommand LostFocusActionCommand => _lostFocusActionCommand ?? (_lostFocusActionCommand = new DelegateCommand(LostFocusAction));
private void LostFocusAction()
{
if (string.IsNullOrEmpty(FilterParam))
FilterParam = FilterParamDefault;
}
#endregion Commands
}
}

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.8", FrameworkDisplayName = "")]

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]

View File

@@ -0,0 +1 @@
12

View File

@@ -0,0 +1 @@
12

View File

@@ -0,0 +1,306 @@
<base:BaseView x:Class="DTS.Viewer.Graph.TestDataSeriesView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:base="clr-namespace:DTS.Common.Base;assembly=DTS.Common"
xmlns:c1="http://schemas.componentone.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:converters="clr-namespace:DTS.Common.Converters;assembly=DTS.Common"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="800"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" x:Name="testDataSeriesView">
<base:BaseView.Resources>
<ResourceDictionary >
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Resources/CommonStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="TextBlock" x:Key="OverlayStyle">
<Setter Property="FontSize" Value="12"/>
<Setter Property="Foreground" Value="#D0000000"/>
</Style>
<converters:BooleanToVisibilityConverter x:Key="BoolToVisConverter" />
<converters:InverseBooleanToVisibilityConverter x:Key="InverseBoolToVisConverter" />
</ResourceDictionary>
</base:BaseView.Resources>
<Grid x:Name="GraphViewGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<c1:C1Chart x:Name="MainChart" Style="{DynamicResource LineChartStyle}" Margin="0"
MouseWheel="MainChart_OnMouseWheel" IsManipulationEnabled="True" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="ActionLeave">
<i:InvokeCommandAction Command="{Binding ActionLeaveCommand}" CommandParameter="{Binding ElementName=MainChart}"/>
</i:EventTrigger>
<i:EventTrigger EventName="ActionEnter">
<i:InvokeCommandAction Command="{Binding ActionEnterCommand}" CommandParameter="{Binding ElementName=MainChart}"/>
</i:EventTrigger>
<i:EventTrigger EventName="MouseUp">
<i:InvokeCommandAction Command="{Binding MouseUpCommand}" CommandParameter="{Binding ElementName=MainChart}"/>
</i:EventTrigger>
<i:EventTrigger EventName="MouseDown">
<i:InvokeCommandAction Command="{Binding MouseDownCommand}" CommandParameter="{Binding ElementName=MainChart}"/>
</i:EventTrigger>
<i:EventTrigger EventName="MouseMove">
<i:InvokeCommandAction Command="{Binding MouseMoveCommand}" CommandParameter="{Binding ElementName=MainChart}"/>
</i:EventTrigger>
<i:EventTrigger EventName="GotFocus">
<i:InvokeCommandAction Command="{Binding GotFocusCommand}" CommandParameter="{Binding ElementName=MainChart}"/>
</i:EventTrigger>
<i:EventTrigger EventName="KeyUp">
<i:InvokeCommandAction Command="{Binding ChartOnKeyUpCommand}" />
</i:EventTrigger>
<!--<i:EventTrigger EventName="KeyUp">
<ei:CallMethodAction MethodName="{Binding ChartOnKeyUpMethod}" TargetObject="{Binding}"/>
</i:EventTrigger>-->
</i:Interaction.Triggers>
<c1:LineAreaOptions.OptimizationRadius>5</c1:LineAreaOptions.OptimizationRadius>
<c1:C1Chart.Actions>
<c1:ZoomAction Fill="{StaticResource Brush_ChartZoomBackground}" Stroke="{x:Null}" Block.IsHyphenationEnabled="False"/>
<c1:TranslateAction Modifiers="Shift" />
<c1:ScaleAction Modifiers="Control" />
</c1:C1Chart.Actions>
<c1:C1Chart.View >
<c1:ChartView Focusable="True">
<c1:ChartView.AxisX>
<c1:Axis Style="{DynamicResource LineChartAxisStyle}" MajorGridStroke="#30000000" MajorGridStrokeThickness="1">
<c1:Axis.ScrollBar>
<c1:AxisScrollBar Margin="0,10,0,0" />
</c1:Axis.ScrollBar>
</c1:Axis>
</c1:ChartView.AxisX>
<c1:ChartView.AxisY>
<c1:Axis Style="{DynamicResource LineChartAxisStyle}" MajorGridStroke="#30000000" MajorGridStrokeThickness="1">
<c1:Axis.ScrollBar>
<c1:AxisScrollBar Margin="0,10,0,0"/>
</c1:Axis.ScrollBar>
</c1:Axis>
</c1:ChartView.AxisY>
<!-- Markers layer -->
<c1:ChartView.Layers>
<c1:ChartPanel Visibility="{Binding Path=MarkerVisibilty}" >
<!-- vertical line and dot markers -->
<c1:ChartPanelObject x:Name="Label"
Attach="DataX"
Action="MouseMove"
DataPoint="0,0"
HorizontalAlignment="Left"
VerticalAlignment="Bottom" RenderTransformOrigin="0.5,0.5">
<c1:ChartPanelObject.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform X="5"/>
<TranslateTransform Y="-5"/>
</TransformGroup>
</c1:ChartPanelObject.RenderTransform>
<Grid DataContext="{Binding RelativeSource={x:Static RelativeSource.Self},Path=Parent}">
<Rectangle Fill="Transparent" Opacity=".95" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
<StackPanel Margin="5,2" Orientation="Horizontal">
<!-- ReSharper disable once Xaml.BindingWithContextNotResolved -->
<TextBlock x:Name="LabelY" Text="{Binding DataPoint.Y, StringFormat=F3}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBlock Text=" @ " VerticalAlignment="Center" HorizontalAlignment="Center"/>
<!-- ReSharper disable once Xaml.BindingWithContextNotResolved -->
<TextBlock x:Name="LabelX" Text="{Binding DataPoint.X, StringFormat=F3}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBlock x:Name="LabelTimeUnits" Text="ms" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</StackPanel>
</Grid>
</c1:ChartPanelObject>
<c1:ChartPanelObject x:Name="Dot"
Attach="DataX"
Action="MouseMove"
DataPoint="0,0"
DataPointChanged="obj_DataPointChanged"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Ellipse Fill="#55FFFFFF" Stroke="Black" StrokeThickness=".5" Width="10" Height="10" />
</c1:ChartPanelObject>
</c1:ChartPanel>
</c1:ChartView.Layers>
</c1:ChartView>
</c1:C1Chart.View>
<c1:C1ChartLegend Grid.Row="1" x:Name="Legend" Visibility="Collapsed" Foreground="{DynamicResource Brush_ChartForeground}"/>
</c1:C1Chart>
<Grid HorizontalAlignment="Right" Background="#D0FFFFFF" VerticalAlignment="Top"
Margin="10" Visibility="{Binding OverlayVisibility}"
Width="300">
<Grid.Style>
<Style TargetType="Grid">
<Style.Triggers>
<EventTrigger RoutedEvent="Control.MouseEnter">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Duration="0:0:0.2" To="0" Storyboard.TargetProperty="Opacity"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Control.MouseLeave">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Duration="0:0:0.2" To="1" Storyboard.TargetProperty="Opacity"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Test Setup: " Style="{StaticResource OverlayStyle}"/>
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding TestSetupName}" Style="{StaticResource OverlayStyle}" TextWrapping="Wrap"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Test Id: " Style="{StaticResource OverlayStyle}"/>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding TestId}" Style="{StaticResource OverlayStyle}" TextWrapping="Wrap"/>
<TextBlock Grid.Row="2" Grid.Column="0" Text="Group Name: " Style="{StaticResource OverlayStyle}" Visibility="Collapsed"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding GroupName}" Style="{StaticResource OverlayStyle}" Visibility="Collapsed"/>
<TextBlock Grid.Row="3" Grid.Column="0" Text="Hardware Channel: " Style="{StaticResource OverlayStyle}"/>
<TextBlock Grid.Row="3" Grid.Column="1" Text="{Binding HardwareChannel}" Style="{StaticResource OverlayStyle}"/>
<TextBlock Grid.Row="4" Grid.Column="0" Text="Serial Number: " Style="{StaticResource OverlayStyle}"/>
<TextBlock Grid.Row="4" Grid.Column="1" Text="{Binding SensorSN}" Style="{StaticResource OverlayStyle}"/>
<TextBlock Grid.Row="5" Grid.Column="0" Text="Channel Description: " Style="{StaticResource OverlayStyle}"/>
<TextBlock Grid.Row="5" Grid.Column="1" Text="{Binding Description}" Style="{StaticResource OverlayStyle}" TextWrapping="Wrap"/>
<TextBlock Grid.Row="6" Grid.Column="0" Text="Channel User Code: " Style="{StaticResource OverlayStyle}" Visibility="{Binding UserVisibility}"/>
<TextBlock Grid.Row="6" Grid.Column="1" Text="{Binding UserCode}" Style="{StaticResource OverlayStyle}" TextWrapping="Wrap" Visibility="{Binding UserVisibility}"/>
<TextBlock Grid.Row="7" Grid.Column="0" Text="Channel User Name: " Style="{StaticResource OverlayStyle}" Visibility="{Binding UserVisibility}"/>
<TextBlock Grid.Row="7" Grid.Column="1" Text="{Binding UserChannelName}" Style="{StaticResource OverlayStyle}" TextWrapping="Wrap" Visibility="{Binding UserVisibility}"/>
<TextBlock Grid.Row="8" Grid.Column="0" Text="Channel ISO Code: " Style="{StaticResource OverlayStyle}" Visibility="{Binding ISOVisibility}"/>
<TextBlock Grid.Row="8" Grid.Column="1" Text="{Binding ISOCode}" Style="{StaticResource OverlayStyle}" TextWrapping="Wrap" Visibility="{Binding ISOVisibility}"/>
<TextBlock Grid.Row="9" Grid.Column="0" Text="Channel ISO Name: " Style="{StaticResource OverlayStyle}" Visibility="{Binding ISOVisibility}"/>
<TextBlock Grid.Row="9" Grid.Column="1" Text="{Binding ISOChannelName}" Style="{StaticResource OverlayStyle}" TextWrapping="Wrap" Visibility="{Binding ISOVisibility}"/>
<TextBlock Grid.Row="10" Grid.Column="0" Text="Channel Name: " Style="{StaticResource OverlayStyle}" Visibility="{Binding ChannelNameOnlyVisibility}"/>
<TextBlock Grid.Row="10" Grid.Column="1" Text="{Binding UserChannelName}" Style="{StaticResource OverlayStyle}" TextWrapping="Wrap" Visibility="{Binding ChannelNameOnlyVisibility}"/>
<TextBlock Grid.Row="11" Grid.Column="0" Text="Recording Mode: " Style="{StaticResource OverlayStyle}"/>
<TextBlock Grid.Row="11" Grid.Column="1" Text="{Binding RecordingMode}" Style="{StaticResource OverlayStyle}"/>
<TextBlock Grid.Row="12" Grid.Column="0" Text="Sample Rate (Hz): " Style="{StaticResource OverlayStyle}"/>
<TextBlock Grid.Row="12" Grid.Column="1" Text="{Binding SampleRate}" Style="{StaticResource OverlayStyle}"/>
<TextBlock Grid.Row="13" Grid.Column="0" Text="Hardware Filter (Hz): " Style="{StaticResource OverlayStyle}"/>
<TextBlock Grid.Row="13" Grid.Column="1" Text="{Binding HWAAF}" Style="{StaticResource OverlayStyle}"/>
<TextBlock Grid.Row="14" Grid.Column="0" Text="Software Filter Class: " Style="{StaticResource OverlayStyle}"/>
<TextBlock Grid.Row="14" Grid.Column="1" Text="{Binding SWAAF}" Style="{StaticResource OverlayStyle}"/>
<TextBlock Grid.Row="15" Grid.Column="0" Text="Excitation (V): " Style="{StaticResource OverlayStyle}"/>
<TextBlock Grid.Row="15" Grid.Column="1" Text="{Binding Excitation}" Style="{StaticResource OverlayStyle}"/>
<TextBlock Grid.Row="16" Grid.Column="0" Text="Polarity: " Style="{StaticResource OverlayStyle}" Visibility="{Binding PolarityVisibility}"/>
<TextBlock Grid.Row="16" Grid.Column="1" Text="{Binding Polarity}" Style="{StaticResource OverlayStyle}" Visibility="{Binding PolarityVisibility}"/>
<Rectangle Grid.Row="17" Grid.ColumnSpan="2" Fill="#60000000" StrokeDashArray="" Height="1" Margin="5"/>
<StackPanel Grid.Row="18" Grid.Column="0" Orientation="Horizontal">
<TextBlock Text="Min/Max (" Style="{StaticResource OverlayStyle}"/>
<TextBlock Text="{Binding TitleY}" Style="{StaticResource OverlayStyle}"/>
<TextBlock Text=") :" Style="{StaticResource OverlayStyle}"/>
</StackPanel>
<StackPanel Grid.Row="18" Grid.Column="1" Orientation="Horizontal">
<TextBlock Text="{Binding MinY}" Style="{StaticResource OverlayStyle}"/>
<TextBlock Text="/" Style="{StaticResource OverlayStyle}"/>
<TextBlock Text="{Binding MaxY}" Style="{StaticResource OverlayStyle}"/>
</StackPanel>
<StackPanel Grid.Row="19" Grid.Column="0" Orientation="Horizontal">
<TextBlock Text="Average (" Style="{StaticResource OverlayStyle}"/>
<TextBlock Text="{Binding TitleY}" Style="{StaticResource OverlayStyle}"/>
<TextBlock Text=") :" Style="{StaticResource OverlayStyle}"/>
</StackPanel>
<TextBlock Grid.Row="19" Grid.Column="1" Text="{Binding AvgY}" Style="{StaticResource OverlayStyle}"/>
<StackPanel Grid.Row="20" Grid.Column="0" Orientation="Horizontal">
<TextBlock Text="StdDev (" Style="{StaticResource OverlayStyle}"/>
<TextBlock Text="{Binding TitleY}" Style="{StaticResource OverlayStyle}"/>
<TextBlock Text=") :" Style="{StaticResource OverlayStyle}"/>
</StackPanel>
<TextBlock Grid.Row="20" Grid.Column="1" Text="{Binding StdDevY}" Style="{StaticResource OverlayStyle}"/>
<!-- T0 Value -->
<StackPanel Grid.Row="21" Grid.Column="0" Orientation="Horizontal" Visibility="{Binding FFT, Converter={StaticResource InverseBoolToVisConverter}}">
<TextBlock Text="Value @ T0 (" Style="{StaticResource OverlayStyle}"/>
<TextBlock Text="{Binding TitleY}" Style="{StaticResource OverlayStyle}" />
<TextBlock Text=") :" Style="{StaticResource OverlayStyle}" />
</StackPanel>
<TextBlock Grid.Row="21" Grid.Column="1" Text="{Binding T0EUValue}" Style="{StaticResource OverlayStyle}"
Visibility="{Binding FFT, Converter={StaticResource InverseBoolToVisConverter}}" />
<!-- Peek Frequency -->
<StackPanel Grid.Row="21" Grid.Column="0" Orientation="Horizontal" Visibility="{Binding FFT, Converter={StaticResource BoolToVisConverter}}">
<TextBlock Text="Peak Magnitude " Style="{StaticResource OverlayStyle}"/>
<TextBlock Text="{Binding PeakMagnitude,StringFormat=N2}" Style="{StaticResource OverlayStyle}" />
<TextBlock Text=" (dB) @ " />
</StackPanel>
<StackPanel Grid.Row="21" Grid.Column="1" Orientation="Horizontal" Visibility="{Binding FFT, Converter={StaticResource BoolToVisConverter}}">
<TextBlock Text="{Binding PeakFrequency,StringFormat=N2}" Style="{StaticResource OverlayStyle}" />
<TextBlock Text=" (Hz)" />
</StackPanel>
<!-- HIC Value -->
<StackPanel Grid.Row="22" Grid.Column="0" Orientation="Horizontal" Visibility="{Binding HIC, Converter={StaticResource BoolToVisConverter}}">
<TextBlock Text="HIC :" Style="{StaticResource OverlayStyle}" />
</StackPanel>
<TextBlock Grid.Row="22" Grid.Column="1" Text="{Binding HICValue}" Style="{StaticResource OverlayStyle}" Visibility="{Binding HIC, Converter={StaticResource BoolToVisConverter}}" />
<!-- T1 Value -->
<StackPanel Grid.Row="23" Grid.Column="0" Orientation="Horizontal" Visibility="{Binding HIC, Converter={StaticResource BoolToVisConverter}}">
<TextBlock Text="T1 (ms) :" Style="{StaticResource OverlayStyle}"/>
</StackPanel>
<TextBlock Grid.Row="23" Grid.Column="1" Text="{Binding T1Time}" Style="{StaticResource OverlayStyle}" Visibility="{Binding HIC, Converter={StaticResource BoolToVisConverter}}"/>
<!-- T2 Value -->
<StackPanel Grid.Row="24" Grid.Column="0" Orientation="Horizontal" Visibility="{Binding HIC, Converter={StaticResource BoolToVisConverter}}">
<TextBlock Text="T2 (ms) :" Style="{StaticResource OverlayStyle}"/>
</StackPanel>
<TextBlock Grid.Row="24" Grid.Column="1" Text="{Binding T2Time}" Style="{StaticResource OverlayStyle}" Visibility="{Binding HIC, Converter={StaticResource BoolToVisConverter}}"/>
</Grid>
</Grid>
</base:BaseView>

Some files were not shown because too many files have changed in this diff Show More