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 @@
12

View File

@@ -0,0 +1 @@
12

View File

@@ -0,0 +1,36 @@
using System.Collections.Generic;
using DTS.Common.Interface.Groups;
using GroupImport.Resources;
namespace GroupImport
{
/// <summary>
/// Interaction logic for GroupImportOptionsView.xaml
/// </summary>
public partial class GroupImportOptionsView : IGroupImportOptionsView
{
public GroupImportOptionsView()
{
InitializeComponent();
}
/// <summary>
/// controls whether it is possible to continue to preview or not
/// it is not possible to continue to preview if no files are selected
/// and you automatically advance to preview if you select a file
/// </summary>
/// <param name="errors"></param>
/// <param name="warnings"></param>
/// <returns></returns>
public bool Validate(out List<string> errors, out List<string> warnings)
{
errors = new List<string>();
warnings = new List<string>();
var vm = (GroupImportViewModel)DataContext;
if (null != vm.SourceFiles && vm.SourceFiles.Length >= 1) return true;
errors.Add(StringResources.Preview_NoFilesSelected);
return false;
}
}
}

View File

@@ -0,0 +1,101 @@
<?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>
</root>

View File

@@ -0,0 +1,16 @@
using DTS.Common.Interface.Groups;
namespace GroupImport
{
/// <summary>
/// Interaction logic for GroupImportImportView.xaml
/// </summary>
public partial class GroupImportImportView : IGroupImportImportView
{
public GroupImportImportView()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,54 @@
<base:BaseView x:Class="GroupImport.GroupImportOptionsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:root="clr-namespace:DBImportExport.Resources"
xmlns:base="clr-namespace:DTS.Common.Base;assembly=DTS.Common"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
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>
<converters:FilePathsToShortStringConverter x:Key="filesToStringConverter" />
<Style TargetType="TextBlock" BasedOn="{StaticResource PageContentTextStyle}" >
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Margin" Value="5" />
</Style>
<Style TargetType="TextBox">
<Setter Property="Margin" Value="0,2,0,2" />
</Style>
<Style TargetType="Button">
<Setter Property="Margin" Value="5" />
</Style>
</ResourceDictionary>
</base:BaseView.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="150" />
<ColumnDefinition Width="200" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- for now hide since there's only one import format currently...
<TextBlock Grid.Row="0" Grid.Column="0" Text="{root:TranslateExtension Options_Format}" />
<ComboBox Grid.Row="0" Grid.Column="1" VerticalAlignment="Center"/>
-->
<TextBlock Grid.Row="1" Grid.Column="0" Text="{root:TranslateExtension Options_Files}" />
<TextBox IsEnabled="False" IsReadOnly="True" Grid.Row="1" Grid.Column="1" Text="{Binding SourceFiles, Converter={StaticResource ResourceKey=filesToStringConverter}}"/>
<Button Grid.Row="1" Grid.Column="2" Content="{root:TranslateExtension Options_Browse}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding ImportBrowseCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Grid>
</base:BaseView>

View File

@@ -0,0 +1,792 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Threading.Tasks;
using DTS.Common.Events;
using DTS.Common.Utils;
using DTS.Common.Classes.Groups;
using System.Linq;
using System.Text;
using System.Windows;
using DTS.Common.Enums.Groups;
using DTS.Common.Interface.Groups;
using GroupImport.Resources;
using DTS.Common.Storage;
using System.Windows.Media;
using Prism.Regions;
using DTS.Common.Interactivity;
using Unity;
using Prism.Events;
using Prism.Commands;
// ReSharper disable CheckNamespace
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable InconsistentNaming
namespace GroupImport
{
/// <summary>
/// this class handles Group/TestObject import functionality
/// </summary>
[Export(typeof(IGroupImportOptionsView))]
[Export(typeof(IGroupImportPreviewView))]
[Export(typeof(IGroupImportImportView))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class GroupImportViewModel : IGroupImportViewModel
{
#region views
/// <summary>
/// the import view
/// </summary>
public IGroupImportOptionsView ImportOptionsView { get; set; }
/// <summary>
/// the preview view
/// </summary>
public IGroupImportPreviewView ImportPreviewView { get; set; }
/// <summary>
/// the import view
/// </summary>
public IGroupImportImportView ImportView { get; set; }
#endregion
private IEventAggregator _eventAggregator { get; set; }
private IRegionManager _regionManager;
private IUnityContainer UnityContainer { get; set; }
public InteractionRequest<Notification> NotificationRequest { get; private set; }
public InteractionRequest<Confirmation> ConfirmationRequest { get; private set; }
/// <summary>
/// Creates a new instance of the TechnologyDomainEditViewModel.
/// </summary>
/// <param name="previewView"></param>
/// <param name="importView"></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>
/// <param name="optionsView"></param>
public GroupImportViewModel(IGroupImportOptionsView optionsView, IGroupImportPreviewView previewView,
IGroupImportImportView importView, IRegionManager regionManager, IEventAggregator eventAggregator,
IUnityContainer unityContainer)
{
ImportView = importView;
ImportView.DataContext = this;
ImportOptionsView = optionsView;
ImportOptionsView.DataContext = this;
ImportPreviewView = previewView;
ImportPreviewView.DataContext = this;
NotificationRequest = new InteractionRequest<Notification>();
ConfirmationRequest = new InteractionRequest<Confirmation>();
_eventAggregator = eventAggregator;
UnityContainer = unityContainer;
_regionManager = regionManager;
_eventAggregator.GetEvent<RaiseNotification>().Subscribe(OnRaiseNotification);
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>()
.Subscribe(OnBusyIndicatorNotification, ThreadOption.PublisherThread, true);
}
#region Methods
/// <summary>
/// reads .grp files, parsing out groups and channels
/// </summary>
public void ParseSourceFiles(string userTags)
{
var groups = new List<GroupGRPImportGroup>();
foreach (var file in SourceFiles)
{
var group = new GroupGRPImportGroup { SourceFile = file };
try
{
var lines = System.IO.File.ReadAllLines(file);
var fi = new System.IO.FileInfo(file);
var groupName = fi.Name.Replace(fi.Extension, "");
if (groupName.EndsWith("."))
{
groupName = groupName.Substring(0, groupName.Length - 1);
}
group.GroupName = groupName;
group.GroupTags = userTags;
group.ImportingUserTags = userTags;
if (lines.Any())
{
group.GroupErrors = new GroupGRPImportError[0];
var channels = new List<GroupGRPImportChannel>();
for (var i = 0; i < lines.Length; i++)
{
var line = lines[i];
if (string.IsNullOrWhiteSpace(line)) { continue; }
var fields = Parse(line);
var sensorSerialNumber = fields[0];
var channel = new GroupGRPImportChannel { SensorSerialNumber = sensorSerialNumber, ParentGroup = group };
if (null != CheckSensorExists && !CheckSensorExists.Invoke(sensorSerialNumber) &&
//FB13753 .grp import should allow empty sensor
!string.Empty.Equals(sensorSerialNumber))
{
channel.Error = new GroupGRPImportError
{
ErrorCode = GroupGRPImportError.Errors.SensorNotFound,
ExtraInfo = StringResources.Preview_SensorNotFound,
File = file,
Line = i
};
}
if (5 == fields.Length)
{
channel.DisplayName = fields[1];
channel.ISOCode = fields[2];
switch (fields[3].ToLower())
{
case "no":
channel.Invert = false;
break;
case "yes":
channel.Invert = true;
break;
default:
if (!bool.TryParse(fields[3], out var invert))
{
channel.Error = new GroupGRPImportError
{
ErrorCode = GroupGRPImportError.Errors.InvalidInvertInput,
ExtraInfo = StringResources.Preview_InvalidInvert,
File = file,
Line = i
};
continue;
}
channel.Invert = invert;
break;
}
double capacity;
if (!double.TryParse(fields[4], out capacity))
{
channel.Error = new GroupGRPImportError
{
ErrorCode = GroupGRPImportError.Errors.InvalidFullScaleInput,
ExtraInfo = StringResources.Preview_InvalidFullScaleCapacity
};
continue;
}
channel.FullScale = capacity;
}
else
{
channel.Error = new GroupGRPImportError
{
ErrorCode = GroupGRPImportError.Errors.InvalidSensorInput,
ExtraInfo = StringResources.Preview_InvalidNumberOfFields,
File = file,
Line = i
};
}
channels.Add(channel);
}
group.Channels = channels.ToArray();
if (!channels.Any())
{
group.GroupErrors = new[]
{
new GroupGRPImportError
{
ErrorCode = GroupGRPImportError.Errors.FileEmpty,
ExtraInfo = StringResources.Preview_EmptyFile,
File = file,
Line = 0
}
};
}
}
else
{
group.GroupErrors = new[]
{
new GroupGRPImportError
{
File = file,
ErrorCode = GroupGRPImportError.Errors.FileEmpty,
Line = 0,
ExtraInfo = StringResources.Preview_EmptyFile
}
};
}
}
catch (Exception ex)
{
group.GroupErrors = new[]
{
new GroupGRPImportError
{
File = file,
Line = 0,
ExtraInfo = ex.Message,
ErrorCode = GroupGRPImportError.Errors.FileEmpty
}
};
LogMessage(ex);
}
groups.Add(group);
}
Groups = groups.ToArray();
ProcessChannels();
}
/// <summary>
/// starts the process of creating and commiting groups and channels on a background thread
/// </summary>
public void Import()
{
System.Threading.ThreadPool.QueueUserWorkItem(ImportFunc);
}
/// <summary>
/// the actual thread writing groups and channels
/// </summary>
/// <param name="o"></param>
private void ImportFunc(object o)
{
var channelDefaults = DbOperations.GetChannelSettingDefaults();
ImportProgressValue = 0;
ImportProgressBarVisibility = Visibility.Visible;
ImportProgressColor = DTS.Common.BrushesAndColors.Brush_ApplicationStatus_Busy.Color;
DisableUI?.Invoke();
var done = 0;
var allChannels = Groups.Where(g => g.Included).SelectMany(g => g.Channels).Count();
var groups = new List<string>();
foreach (var g in Groups)
{
if (!g.Included) { continue; }
CreateGroup(g.GroupName, g.GroupTags);
foreach (var ch in g.Channels)
{
done++;
//ImportProgressText = string.Format(StringResources.Import_Importing, g.GroupName, ch.DisplayName);
//ImportProgressValue = Convert.ToInt32(100D * done / allChannels);
if (null != ch.Error)
{
switch (ch.Error.ErrorCode)
{
case GroupGRPImportError.Errors.FileEmpty:
case GroupGRPImportError.Errors.InvalidSensorInput:
case GroupGRPImportError.Errors.SensorNotFound:
continue;//don't add
}
}
double? capacity = null;
if (null == ch.Error || ch.Error.ErrorCode != GroupGRPImportError.Errors.InvalidFullScaleInput)
{
capacity = ch.FullScale;
}
bool? invert = null;
if (null == ch.Error || ch.Error.ErrorCode != GroupGRPImportError.Errors.InvalidInvertInput)
{
invert = ch.Invert;
}
AddChannel(g.GroupName, ch.DisplayName, ch.SensorSerialNumber, capacity, invert, ch.ISOCode, channelDefaults);
}
groups.Add(g.GroupName);
//CommitGroup(g.GroupName);
}
CommitGroups(groups.ToArray());
//ImportProgressColor = DTS.Common.BrushesAndColors.Brush_ApplicationStatus_Complete.Color;
//ImportProgressBarVisibility = Visibility.Collapsed;
//EnableUI?.Invoke();
}
public void SetStatus(string message, Color color)
{
ImportProgressColor = color;
ImportProgressBarVisibility = Visibility.Collapsed;
ImportProgressText = message;
EnableUI?.Invoke();
}
/// <summary>
/// re-initializes the group view model
/// right now we don't create a new group view model, we appear to reuse the existing one, so it has to be reset
/// </summary>
public void Reset()
{
SourceFiles = new string[0];
Channels = new GroupGRPImportChannel[0];
Groups = new GroupGRPImportGroup[0];
ImportProgressBarVisibility = Visibility.Collapsed;
ImportProgressColor = DTS.Common.BrushesAndColors.Brush_ApplicationStatus_Idle.Color;
ImportProgressText = string.Empty;
ImportProgressValue = 0;
}
/// <summary>
/// parses a single line in a GRP file
/// this line may use () to escape values, like "this(,)is all one field" will only return one string
/// </summary>
/// <param name="line"></param>
/// <returns></returns>
private static string[] Parse(string line)
{
var strings = new List<string>();
var currentString = new StringBuilder();
var currentCharacter = 0;
var leftParenCount = 0;
while (currentCharacter < line.Length)
{
var ch = line[currentCharacter];
switch (ch)
{
case '(':
currentString.Append("(");
leftParenCount++;
break;
case ')':
currentString.Append(")");
leftParenCount--;
break;
case ',':
if (leftParenCount > 0)
{
currentString.Append(",");
}
else
{
strings.Add(currentString.ToString());
currentString.Clear();
}
break;
default:
currentString.Append(ch);
break;
}
currentCharacter++;
}
if (currentString.Length > 0)
{
strings.Add(currentString.ToString());
}
return strings.ToArray();
}
/// <summary>
/// checks whether a group name is valid
/// a group name is invalid if it exists more than once in the import or if it already exists in the
/// application and overwrite is false
/// </summary>
public void CheckGroupName()
{
var groupNameLookup = new Dictionary<string, List<GroupGRPImportGroup>>();
foreach (var g in Groups)
{
if (!groupNameLookup.ContainsKey(g.GroupName))
{
groupNameLookup.Add(g.GroupName, new List<GroupGRPImportGroup>());
}
groupNameLookup[g.GroupName].Add(g);
}
foreach (var g in Groups)
{
if (groupNameLookup[g.GroupName].Count > 1)
{
g.GroupNameHasError = true;
}
else
{
if (CheckGroupExists(g.GroupName) && !g.Overwrite)
{
g.GroupNameHasError = true;
}
else { g.GroupNameHasError = false; }
}
}
}
/// <summary>
/// log a message
/// </summary>
/// <param name="parms"></param>
private void LogMessage(params object[] parms)
{
Logger?.Invoke(parms);
}
/// <summary>
/// separates channels out of groups into valid and invalid channels
/// popuplates IncompleteChannels and CompleteChannels
/// </summary>
private void ProcessChannels()
{
var channels = new List<GroupGRPImportChannel>();
foreach (var g in Groups)
{
channels.AddRange(g.Channels);
}
Channels = channels.ToArray();
}
public void Cleanup()
{
}
public Task CleanupAsync()
{
return Task.CompletedTask;
}
public void Initialize()
{
}
public void Initialize(object parameter)
{
}
public void Initialize(object parameter, object model)
{
}
public Task InitializeAsync()
{
return Task.CompletedTask;
}
public Task InitializeAsync(object parameter)
{
return Task.CompletedTask;
}
public void Activated()
{
}
/// <summary>
/// Private Event handler for RaiseNotification event.
/// </summary>
private void OnBusyIndicatorNotification(bool eventArg)
{
IsBusy = eventArg;
}
/// <summary>
/// Private Event handler for RaiseNotification event.
/// </summary>
private void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)
{
// The NotificationRequest.Raise triggers the Invoke() method of the PopupWindowAction object to show the NotificationWindow window
// Notification object expects a NotificationContentEventArgsWithoutTitle object and a Title string.
var eventArgsWithoutTitle =
new NotificationContentEventArgs(eventArgsWithTitle.Message, "", eventArgsWithTitle.Image,
string.Empty);
NotificationRequest.Raise(new Notification
{
Content = eventArgsWithoutTitle,
Title = eventArgsWithTitle.Title
});
}
#endregion
#region Properties
public bool IsDirty { get; private set; }
private bool _isBusy;
public bool IsBusy
{
get => _isBusy;
set
{
_isBusy = value;
OnPropertyChanged("IsBusy");
}
}
private bool _isMenuIncluded;
public bool IsMenuIncluded
{
get => _isMenuIncluded;
set
{
_isMenuIncluded = value;
OnPropertyChanged("IsMenuIncluded");
}
}
private bool _isNavigationIncluded;
public bool IsNavigationIncluded
{
get => _isNavigationIncluded;
set
{
_isNavigationIncluded = value;
OnPropertyChanged("IsNavigationIncluded");
}
}
/// <summary>
/// Gets the HeaderInfo.
/// </summary>
public string HeaderInfo => "MainRegion";
#endregion Properties
#region Commands
/// <summary>
/// browse to a file to import, should be xml, maybe needs a few other criteria
/// </summary>
private DelegateCommand _importBrowseCommand;
public DelegateCommand ImportBrowseCommand => _importBrowseCommand ?? (_importBrowseCommand = new DelegateCommand(ImportBrowseMethod));
private void ImportBrowseMethod()
{
using (var dlg = new System.Windows.Forms.OpenFileDialog())
{
dlg.CheckFileExists = true;
dlg.CheckPathExists = true;
dlg.Multiselect = true;
dlg.Filter = StringResources.ImportFileFilter;
dlg.FilterIndex = 0;
if (dlg.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
SourceFiles = dlg.FileNames;
BrowseOk = true;
SwitchNavSteps?.Invoke(GroupImportEnums.Steps.Preview);
}
}
#endregion
#region properties
private string _importProgressText;
/// <summary>
/// current status text for import progress bar
/// </summary>
public string ImportProgressText
{
get => _importProgressText;
set
{
_importProgressText = value;
OnPropertyChanged("ImportProgressText");
}
}
private System.Windows.Media.Color _importProgressColor;
/// <summary>
/// The current color of the import progress bar
/// </summary>
public System.Windows.Media.Color ImportProgressColor
{
get => _importProgressColor;
set
{
_importProgressColor = value;
OnPropertyChanged("ImportProgressColor");
}
}
public Visibility _importProgressBarVisibility;
/// <summary>
/// whether the progress bar is visible or not
/// </summary>
public Visibility ImportProgressBarVisibility
{
get => _importProgressBarVisibility;
set
{
_importProgressBarVisibility = value;
OnPropertyChanged("ImportProgressBarVisibility");
}
}
private double _importProgressValue;
/// <summary>
/// percentage complete of import process
/// </summary>
public double ImportProgressValue
{
get => _importProgressValue;
set
{
_importProgressValue = value;
OnPropertyChanged("ImportProgressValue");
}
}
private string[] _sourceFiles = new string[0];
/// <summary>
/// .GRP files to parse
/// </summary>
public string[] SourceFiles
{
get => _sourceFiles;
set
{
_sourceFiles = value;
OnPropertyChanged("SourceFiles");
}
}
public bool BrowseOk { get; set; } = false;
private GroupGRPImportGroup[] _groups = new GroupGRPImportGroup[0];
/// <summary>
/// All groups that have been read in and parsed
/// </summary>
public GroupGRPImportGroup[] Groups
{
get => _groups;
set
{
_groups = value;
OnPropertyChanged("Groups");
}
}
private GroupGRPImportChannel[] _channels = new GroupGRPImportChannel[0];
/// <summary>
/// Channels which are invalid but are in groups included in import
/// </summary>
public GroupGRPImportChannel[] Channels
{
get => _channels;
set
{
_channels = value;
InvalidateChannels();
}
}
public void InvalidateChannels()
{
OnPropertyChanged("IncompleteChannels");
OnPropertyChanged("CompleteChannels");
}
/// <summary>
/// these are channels which will not be imported
/// </summary>
public GroupGRPImportChannel[] IncompleteChannels
{
get
{
var channels = new List<GroupGRPImportChannel>();
foreach (var g in Groups)
{
if (!g.Included) { continue; }
foreach (var ch in g.Channels)
{
if (null == ch.Error) { continue; }
else
{
switch (ch.Error.ErrorCode)
{
case GroupGRPImportError.Errors.InvalidFullScaleInput:
case GroupGRPImportError.Errors.InvalidInvertInput:
continue;
default:
channels.Add(ch);
break;
}
}
}
}
return channels.ToArray();
}
}
/// <summary>
/// these are channels which will be imported
/// </summary>
public GroupGRPImportChannel[] CompleteChannels
{
get
{
var channels = new List<GroupGRPImportChannel>();
foreach (var g in Groups)
{
if (!g.Included) { continue; }
foreach (var ch in g.Channels)
{
if (null == ch.Error)
{
channels.Add(ch);
}
else
{
switch (ch.Error.ErrorCode)
{
case GroupGRPImportError.Errors.InvalidFullScaleInput:
case GroupGRPImportError.Errors.InvalidInvertInput:
channels.Add(ch);
break;
}
}
}
}
return channels.ToArray();
}
}
/// <summary>
/// the logging facility to use
/// if null no logging is performed
/// </summary>
public FileUtils.LogDelegate Logger { get; set; } = null;
/// <summary>
/// the command for switching current nav step
/// </summary>
public SwitchNavStepsDelegate SwitchNavSteps { get; set; } = null;
/// <summary>
/// the command for checking if a group already exists in the application
/// </summary>
public CheckGroupExistsDelegate CheckGroupExists { get; set; } = null;
/// <summary>
/// the command for checking if a sensor exists in the application
/// </summary>
public CheckSensorExistsDelegate CheckSensorExists { get; set; } = null;
/// <summary>
/// the command for creating a group
/// </summary>
public CreateGroupDelegate CreateGroup { get; set; } = null;
/// <summary>
/// the command for adding a channel to a group
/// </summary>
public AddChannelToGroupDelegate AddChannel { get; set; } = null;
/// <summary>
/// the command for commiting a group to the db
/// </summary>
public CommitGroupsDelegate CommitGroups { get; set; } = null;
/// <summary>
/// the command for disabling the UI
/// </summary>
public Disable_UIDelegate DisableUI { get; set; }
/// <summary>
/// the command for enabling the UI
/// </summary>
public Enable_UIDelegate EnableUI { get; set; }
#endregion
///<summary>
///Occurs when a property value changes.
///</summary>
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

View File

@@ -0,0 +1,31 @@
<base:BaseView x:Class="GroupImport.GroupImportImportView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:CommonCtrl="clr-namespace:DTS.Common.Controls;assembly=DTS.Common"
xmlns:base="clr-namespace:DTS.Common.Base;assembly=DTS.Common">
<base:BaseView.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/DTS.Common;component/Themes/CommonStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="TextBlock" BasedOn="{StaticResource PageContentTextStyle}" >
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Margin" Value="5" />
</Style>
<Style TargetType="TextBox">
<Setter Property="Margin" Value="5" />
</Style>
<Style TargetType="Button">
<Setter Property="Margin" Value="5" />
</Style>
</ResourceDictionary>
</base:BaseView.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<CommonCtrl:CommonStatusRibbon x:Name="CtrlStatusRibbon" Grid.Row="0" AggregateStatusText="{Binding ImportProgressText}" AggregateStatusColor="{Binding ImportProgressColor}" ProgressBarVisibility="{Binding ImportProgressBarVisibility}" ProgressBarValue="{Binding ImportProgressValue}"/>
</Grid>
</base:BaseView>

View File

@@ -0,0 +1,21 @@
using System;
using System.Windows.Markup;
using GroupImport.Resources;
namespace DBImportExport.Resources
{
[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,231 @@
<?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="ImportFileFilter" xml:space="preserve">
<value>TDAS group file (*.grp)|*.grp|All Files (*.*)|*.*</value>
</data>
<data name="Options_Browse" xml:space="preserve">
<value>Browse</value>
</data>
<data name="Options_Files" xml:space="preserve">
<value>File(s)</value>
</data>
<data name="Options_Format" xml:space="preserve">
<value>Format</value>
</data>
<data name="PreviewGroupsTable_File" xml:space="preserve">
<value>File</value>
</data>
<data name="PreviewGroupsTable_GroupName" xml:space="preserve">
<value>Group name</value>
</data>
<data name="PreviewGroupsTable_Included" xml:space="preserve">
<value>Included</value>
</data>
<data name="PreviewGroupsTable_Overwrite" xml:space="preserve">
<value>Overwrite</value>
</data>
<data name="PreviewGroups_DisplayName" xml:space="preserve">
<value>Display name</value>
</data>
<data name="PreviewGroups_FullScale" xml:space="preserve">
<value>Full scale</value>
</data>
<data name="PreviewGroups_Invert" xml:space="preserve">
<value>Invert</value>
</data>
<data name="PreviewGroups_ISOCode" xml:space="preserve">
<value>ISOCode</value>
</data>
<data name="PreviewGroups_Issue" xml:space="preserve">
<value>Issue</value>
</data>
<data name="PreviewGroups_SensorSerialNumber" xml:space="preserve">
<value>Sensor serial number</value>
</data>
<data name="Preview_CompleteGroupChannels" xml:space="preserve">
<value>Channels that will be imported</value>
</data>
<data name="Preview_Groups" xml:space="preserve">
<value>Groups</value>
</data>
<data name="Preview_IncompleteGroupChannels" xml:space="preserve">
<value>Channels that will not be imported</value>
</data>
<data name="Importing_Done" xml:space="preserve">
<value>Done</value>
</data>
<data name="Import_Importing" xml:space="preserve">
<value>Importing {0}:{1}</value>
</data>
<data name="Preview_EmptyFile" xml:space="preserve">
<value>Empty file</value>
</data>
<data name="Preview_InvalidFullScaleCapacity" xml:space="preserve">
<value>Invalid full scale capacity</value>
</data>
<data name="Preview_InvalidFullScaleInput" xml:space="preserve">
<value>Invalid desired range for {0}::{1}, the sensor capacity will be used instead</value>
</data>
<data name="Preview_InvalidInvert" xml:space="preserve">
<value>Invalid Invert</value>
</data>
<data name="Preview_InvalidName" xml:space="preserve">
<value>Group name '{0}' is duplicate or invalid</value>
</data>
<data name="Preview_InvalidNumberOfFields" xml:space="preserve">
<value>Invalid number of fields</value>
</data>
<data name="Preview_InvalidRow" xml:space="preserve">
<value>Group {0} contains some lines which are invalid. The invalid lines won't be imported.</value>
</data>
<data name="Preview_InvalidSensor" xml:space="preserve">
<value>Sensor not found for {0}::{1}, this channel will not be imported.</value>
</data>
<data name="Preview_InvalidSensorInput" xml:space="preserve">
<value>Invalid sensor invert for {0}::{1}, the sensor invert setting will be used instead</value>
</data>
<data name="Preview_NoFilesSelected" xml:space="preserve">
<value>No files selected for import</value>
</data>
<data name="Preview_NoGroupsToImport" xml:space="preserve">
<value>Nothing to import</value>
</data>
<data name="Preview_SensorNotFound" xml:space="preserve">
<value>Sensor not found</value>
</data>
<data name="PreviewGroups_Warnings" xml:space="preserve">
<value>Warnings</value>
</data>
<data name="PreviewGroupsTable_GroupTags" xml:space="preserve">
<value>Tags</value>
</data>
<data name="GroupTags" xml:space="preserve">
<value>Group Tag(s): </value>
</data>
<data name="None" xml:space="preserve">
<value>(None)</value>
</data>
<data name="PreviewGroups_WontSaveWithIncompatibleTags" xml:space="preserve">
<value>This Group is not compatible with your Tags (see below) and will not be saved.</value>
</data>
<data name="UserTags" xml:space="preserve">
<value>User Tag(s): </value>
</data>
</root>

View File

@@ -0,0 +1,200 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using DTS.Common.Classes.Groups;
using DTS.Common.Interface.Groups;
using DTS.Common.Strings;
using GroupImport.Resources;
namespace GroupImport
{
/// <summary>
/// Interaction logic for GroupImportOptionsView.xaml
/// </summary>
public partial class GroupImportPreviewView : IGroupImportPreviewView
{
public GroupImportPreviewView()
{
InitializeComponent();
}
/// <summary>
/// handles when tb group name changes
/// in this case the UI needs to be notified and the validity of the group name may change
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void GroupName_Changed(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
var tb = (TextBox)sender;
var group = (GroupGRPImportGroup)tb.DataContext;
group.GroupName = tb.Text;
foreach (var ch in group.Channels)
{
ch.GroupNameInvalidate();
}
var vm = (GroupImportViewModel)DataContext;
vm.CheckGroupName();
}
/// <summary>
/// handles when tb group tag changes
/// in this case the UI needs to be notified and the validity of the group tag may change
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void GroupTags_Changed(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
var tb = (TextBox)sender;
var group = (GroupGRPImportGroup)tb.DataContext;
group.GroupTags = tb.Text;
}
/// <summary>
/// handles included checkbox being checked for a group
/// in this case the channels for the group should be added to the UI
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void IncludedChecked(object sender, System.Windows.RoutedEventArgs e)
{
var vm = (GroupImportViewModel)DataContext;
vm.InvalidateChannels();
}
/// <summary>
/// handles the included checkbox being unchecked for a group
/// in this case the channels for the group should be removed from the UI
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void IncludedUnchecked(object sender, System.Windows.RoutedEventArgs e)
{
var vm = (GroupImportViewModel)DataContext;
vm.InvalidateChannels();
}
/// <summary>
/// checks whether it is okay to proceed to import,
/// checks the validity of the selected channels and groups
/// </summary>
/// <param name="userIsAdmin">whether or not the user has Administrator privileges</param>
/// <param name="errors">any fatal errors that would prevent importing</param>
/// <param name="warnings">any non fatal errors that the user needs to be warned about (but that don't prevent importing)</param>
/// <returns>true if it is okay to proceed to import</returns>
public bool Validate(bool userIsAdmin, out List<string> errors, out List<string> warnings)
{
errors = new List<string>();
warnings = new List<string>();
var bValid = true;
var vm = (GroupImportViewModel)DataContext;
var bAnyValidChannels = false;
if (vm.Groups.Any())
{
foreach (var g in vm.Groups)
{
if (!g.Included) { continue; }
if (!string.IsNullOrWhiteSpace(g.GroupTags) && !userIsAdmin)
{
foreach (var userTag in g.ImportingUserTags.Split())
{
if (g.GroupTags.Split().Contains(userTag)) continue;
var sb = new StringBuilder();
sb.Append(string.Format(StringResources.PreviewGroups_WontSaveWithIncompatibleTags, userTag, g.GroupTags));
sb.Append($"\r\n{StringResources.UserTags}");
sb.Append(g.ImportingUserTags.Length == 0 ? StringResources.None : g.ImportingUserTags);
//The static group in question will always have at least 1 Tag, otherwise there would be no problem
sb.Append($"\r\n{StringResources.GroupTags}");
sb.Append(g.GroupTags);
errors.Add(sb.ToString());
return false;
}
}
if (g.GroupNameHasError)
{
var msg = string.Format(StringResources.Preview_InvalidName, g.GroupName);
if (!errors.Contains(msg))
{
errors.Add(msg);
}
return false;
}
if (null != g.GroupErrors && g.GroupErrors.Any())
{
foreach (var error in g.GroupErrors)
{
if (!errors.Contains(error.ExtraInfo))
{
errors.Add(error.ExtraInfo);
}
}
return false;
}
if (vm.CheckGroupExists(g.GroupName) && !g.Overwrite)
{
var msg = string.Format(StringResources.Preview_InvalidName, g.GroupName);
if (!errors.Contains(msg)) { errors.Add(msg); }
return false;
}
bValid = false;
foreach (var ch in g.Channels)
{
if (null != ch.Error)
{
switch (ch.Error.ErrorCode)
{
case GroupGRPImportError.Errors.FileEmpty:
case GroupGRPImportError.Errors.InvalidISOCodeInput:
bAnyValidChannels = true;
break;
case GroupGRPImportError.Errors.InvalidFullScaleInput:
warnings.Add(string.Format(StringResources.Preview_InvalidFullScaleInput,
g.GroupName, ch.DisplayName));
bAnyValidChannels = true;
break;
case GroupGRPImportError.Errors.InvalidInvertInput:
warnings.Add(string.Format(StringResources.Preview_InvalidSensorInput,
g.GroupName,
ch.DisplayName));
bAnyValidChannels = true;
break;
case GroupGRPImportError.Errors.InvalidSensorInput:
var msg = string.Format(StringResources.Preview_InvalidRow, g.GroupName);
if (!warnings.Contains(msg))
{
warnings.Add(msg);
}
break;
case GroupGRPImportError.Errors.SensorNotFound:
warnings.Add(string.Format(StringResources.Preview_InvalidSensor, g.GroupName,
ch.DisplayName));
break;
default:
throw new ArgumentOutOfRangeException();
}
}
else
{
bValid = true;
bAnyValidChannels = true;
}
}
}
if (!bAnyValidChannels)
{
errors.Add(StringResources.Preview_NoGroupsToImport);
}
return bValid;
}
errors.Add(StringResources.Preview_NoGroupsToImport);
return false;
}
}
}

View File

@@ -0,0 +1,229 @@
<base:BaseView x:Class="GroupImport.GroupImportPreviewView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:root="clr-namespace:DBImportExport.Resources"
xmlns:base="clr-namespace:DTS.Common.Base;assembly=DTS.Common" >
<base:BaseView.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/DTS.Common;component/Themes/CommonStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="TextBlock" BasedOn="{StaticResource PageContentTextStyle}" >
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Margin" Value="5" />
</Style>
<Style TargetType="TextBox">
<Setter Property="Margin" Value="5" />
</Style>
<Style TargetType="Button">
<Setter Property="Margin" Value="5" />
</Style>
</ResourceDictionary>
</base:BaseView.Resources>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Vertical" Grid.Row="0">
<TextBlock Text="{root:TranslateExtension Preview_Groups}" />
<ListView HorizontalAlignment="Left" ItemsSource="{Binding Groups}"
AlternationCount="2" Margin="3,0,3,0">
<ListView.View>
<GridView>
<GridViewColumn Header="{root:TranslateExtension PreviewGroupsTable_Included}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Style="{x:Null}" IsChecked="{Binding Included}" Checked="IncludedChecked" Unchecked="IncludedUnchecked" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroupsTable_Overwrite}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Style="{x:Null}" IsChecked="{Binding Overwrite}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroupsTable_GroupName}" Width="220">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Style="{x:Null}" Text="{Binding GroupName}" MinWidth="200" TextChanged="GroupName_Changed">
<TextBox.Resources>
<Style TargetType="TextBox">
<Style.Triggers>
<MultiDataTrigger></MultiDataTrigger>
<DataTrigger Binding="{Binding GroupNameHasError}" Value="True">
<Setter Property="BorderBrush" Value="Red" />
<Setter Property="BorderThickness" Value="2" />
</DataTrigger>
<DataTrigger Binding="{Binding GroupNameHasError}" Value="false">
<Setter Property="BorderBrush" Value="Purple" />
<Setter Property="BorderThickness" Value="1" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Resources>
</TextBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroupsTable_GroupTags}" Width="220">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Style="{x:Null}" Text="{Binding GroupTags}" MinWidth="200" TextChanged="GroupTags_Changed">
<TextBox.Resources>
<Style TargetType="TextBox">
<Style.Triggers>
<MultiDataTrigger></MultiDataTrigger>
<DataTrigger Binding="{Binding GroupTagsHasError}" Value="True">
<Setter Property="BorderBrush" Value="Red" />
<Setter Property="BorderThickness" Value="2" />
</DataTrigger>
<DataTrigger Binding="{Binding GroupTagsHasError}" Value="false">
<Setter Property="BorderBrush" Value="Purple" />
<Setter Property="BorderThickness" Value="1" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Resources>
</TextBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroupsTable_File}" Width="625">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Style="{x:Null}" Text="{Binding SourceFile}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Row="1">
<TextBlock Text="{root:TranslateExtension Preview_CompleteGroupChannels}" />
<ListView HorizontalAlignment="Left" ItemsSource="{Binding CompleteChannels}"
AlternationCount="2" Margin="3,0,3,0">
<ListView.View>
<GridView>
<GridViewColumn Header="{root:TranslateExtension PreviewGroupsTable_GroupName}" Width="250">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding GroupName}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_DisplayName}" Width="250">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding DisplayName}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_SensorSerialNumber}" Width="150">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding SensorSerialNumber}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<!--<GridViewColumn Header="{root:TranslateExtension PreviewGroups_ISOCode}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding ISOCode}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>-->
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_FullScale}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding FullScale}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_Invert}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsEnabled="False" IsChecked="{Binding Invert}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_Warnings}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Error}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Row="2">
<TextBlock Text="{root:TranslateExtension Preview_IncompleteGroupChannels}" />
<ListView HorizontalAlignment="Left" ItemsSource="{Binding IncompleteChannels}"
AlternationCount="2" Margin="3,0,3,0">
<ListView.View>
<GridView>
<GridViewColumn Header="{root:TranslateExtension PreviewGroupsTable_GroupName}" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding GroupName}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_DisplayName}" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding DisplayName}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_SensorSerialNumber}" Width="150">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding SensorSerialNumber}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<!--<GridViewColumn Header="{root:TranslateExtension PreviewGroups_ISOCode}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding ISOCode}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>-->
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_FullScale}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding FullScale}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_Invert}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsEnabled="False" IsChecked="{Binding Invert}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_Issue}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Error}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
</Grid>
</ScrollViewer>
</base:BaseView>

View File

@@ -0,0 +1,103 @@
using System;
using System.ComponentModel.Composition;
using System.Windows.Media.Imaging;
using DTS.Common;
using DTS.Common.Interface;
using DTS.Common.Interface.Groups;
using Prism.Ioc;
using Prism.Modularity;
using Unity;
namespace GroupImport
{
[Export(typeof(IModule))]
[Module(ModuleName = "GroupImportModule")]
public class GroupImportModule : IModule
{
/// <summary>
/// Injected unity container
/// </summary>
private readonly IUnityContainer _unityContainer;
/// <summary>
/// Initializes a new instance of the <see cref="GroupImportModule"/> class.
/// </summary>
/// <param name="unityContainer">Obtained reference of the unity container by using dependency injection.</param>
public GroupImportModule(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
public void Initialize()
{
// Register View & View-Model with Unity dependency injection container as a singleton.
_unityContainer.RegisterType<IGroupImportImportView, GroupImportImportView>();
_unityContainer.RegisterType<IGroupImportOptionsView, GroupImportOptionsView>();
_unityContainer.RegisterType<IGroupImportPreviewView, GroupImportPreviewView>();
_unityContainer.RegisterType<IGroupImportViewModel, GroupImportViewModel>();
}
public void OnInitialized(IContainerProvider containerProvider)
{
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
Initialize();
}
}
/// <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 GroupImageAttribute : ImageAttribute
{
private BitmapImage _img;
public GroupImageAttribute() : this(null) { }
public override eAssemblyRegion AssemblyRegion => throw new NotImplementedException();
public override BitmapImage AssemblyImage
{
get { _img = AssemblyInfo.GetImage(AssemblyNames.GroupImport.ToString()); return _img; }
}
public GroupImageAttribute(string s)
{
_img = AssemblyInfo.GetImage(AssemblyNames.GroupImport.ToString());
}
public override Type GetAttributeType()
{
return typeof(ImageAttribute);
}
public override BitmapImage GetAssemblyImage()
{
return AssemblyImage;
}
private string _name;
public override string AssemblyName
{
get { _name = AssemblyNames.GroupImport.ToString(); return _name; }
}
public override string GetAssemblyName()
{
return AssemblyName;
}
public override eAssemblyRegion GetAssemblyRegion()
{
throw new NotImplementedException();
}
private string _group;
public override string AssemblyGroup
{
get { _group = eAssemblyGroups.Prepare.ToString(); return _group; }
}
public override string GetAssemblyGroup()
{
return AssemblyGroup;
}
}
}

View File

@@ -0,0 +1,396 @@
//------------------------------------------------------------------------------
// <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 GroupImport.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("GroupImport.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 Group Tag(s): .
/// </summary>
internal static string GroupTags {
get {
return ResourceManager.GetString("GroupTags", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Importing {0}:{1}.
/// </summary>
internal static string Import_Importing {
get {
return ResourceManager.GetString("Import_Importing", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to TDAS group file (*.grp)|*.grp|All Files (*.*)|*.*.
/// </summary>
internal static string ImportFileFilter {
get {
return ResourceManager.GetString("ImportFileFilter", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Done.
/// </summary>
internal static string Importing_Done {
get {
return ResourceManager.GetString("Importing_Done", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to (None).
/// </summary>
internal static string None {
get {
return ResourceManager.GetString("None", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Browse.
/// </summary>
internal static string Options_Browse {
get {
return ResourceManager.GetString("Options_Browse", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to File(s).
/// </summary>
internal static string Options_Files {
get {
return ResourceManager.GetString("Options_Files", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Format.
/// </summary>
internal static string Options_Format {
get {
return ResourceManager.GetString("Options_Format", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Channels that will be imported.
/// </summary>
internal static string Preview_CompleteGroupChannels {
get {
return ResourceManager.GetString("Preview_CompleteGroupChannels", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Empty file.
/// </summary>
internal static string Preview_EmptyFile {
get {
return ResourceManager.GetString("Preview_EmptyFile", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Groups.
/// </summary>
internal static string Preview_Groups {
get {
return ResourceManager.GetString("Preview_Groups", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Channels that will not be imported.
/// </summary>
internal static string Preview_IncompleteGroupChannels {
get {
return ResourceManager.GetString("Preview_IncompleteGroupChannels", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invalid full scale capacity.
/// </summary>
internal static string Preview_InvalidFullScaleCapacity {
get {
return ResourceManager.GetString("Preview_InvalidFullScaleCapacity", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invalid desired range for {0}::{1}, the sensor capacity will be used instead.
/// </summary>
internal static string Preview_InvalidFullScaleInput {
get {
return ResourceManager.GetString("Preview_InvalidFullScaleInput", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invalid Invert.
/// </summary>
internal static string Preview_InvalidInvert {
get {
return ResourceManager.GetString("Preview_InvalidInvert", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Group name &apos;{0}&apos; is duplicate or invalid.
/// </summary>
internal static string Preview_InvalidName {
get {
return ResourceManager.GetString("Preview_InvalidName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invalid number of fields.
/// </summary>
internal static string Preview_InvalidNumberOfFields {
get {
return ResourceManager.GetString("Preview_InvalidNumberOfFields", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Group {0} contains some lines which are invalid. The invalid lines won&apos;t be imported..
/// </summary>
internal static string Preview_InvalidRow {
get {
return ResourceManager.GetString("Preview_InvalidRow", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sensor not found for {0}::{1}, this channel will not be imported..
/// </summary>
internal static string Preview_InvalidSensor {
get {
return ResourceManager.GetString("Preview_InvalidSensor", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invalid sensor invert for {0}::{1}, the sensor invert setting will be used instead.
/// </summary>
internal static string Preview_InvalidSensorInput {
get {
return ResourceManager.GetString("Preview_InvalidSensorInput", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to No files selected for import.
/// </summary>
internal static string Preview_NoFilesSelected {
get {
return ResourceManager.GetString("Preview_NoFilesSelected", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Nothing to import.
/// </summary>
internal static string Preview_NoGroupsToImport {
get {
return ResourceManager.GetString("Preview_NoGroupsToImport", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sensor not found.
/// </summary>
internal static string Preview_SensorNotFound {
get {
return ResourceManager.GetString("Preview_SensorNotFound", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Display name.
/// </summary>
internal static string PreviewGroups_DisplayName {
get {
return ResourceManager.GetString("PreviewGroups_DisplayName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Full scale.
/// </summary>
internal static string PreviewGroups_FullScale {
get {
return ResourceManager.GetString("PreviewGroups_FullScale", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invert.
/// </summary>
internal static string PreviewGroups_Invert {
get {
return ResourceManager.GetString("PreviewGroups_Invert", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to ISOCode.
/// </summary>
internal static string PreviewGroups_ISOCode {
get {
return ResourceManager.GetString("PreviewGroups_ISOCode", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Issue.
/// </summary>
internal static string PreviewGroups_Issue {
get {
return ResourceManager.GetString("PreviewGroups_Issue", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sensor serial number.
/// </summary>
internal static string PreviewGroups_SensorSerialNumber {
get {
return ResourceManager.GetString("PreviewGroups_SensorSerialNumber", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Warnings.
/// </summary>
internal static string PreviewGroups_Warnings {
get {
return ResourceManager.GetString("PreviewGroups_Warnings", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This Group is not compatible with your Tags (see below) and will not be saved..
/// </summary>
internal static string PreviewGroups_WontSaveWithIncompatibleTags {
get {
return ResourceManager.GetString("PreviewGroups_WontSaveWithIncompatibleTags", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to File.
/// </summary>
internal static string PreviewGroupsTable_File {
get {
return ResourceManager.GetString("PreviewGroupsTable_File", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Group name.
/// </summary>
internal static string PreviewGroupsTable_GroupName {
get {
return ResourceManager.GetString("PreviewGroupsTable_GroupName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Tags.
/// </summary>
internal static string PreviewGroupsTable_GroupTags {
get {
return ResourceManager.GetString("PreviewGroupsTable_GroupTags", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Included.
/// </summary>
internal static string PreviewGroupsTable_Included {
get {
return ResourceManager.GetString("PreviewGroupsTable_Included", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Overwrite.
/// </summary>
internal static string PreviewGroupsTable_Overwrite {
get {
return ResourceManager.GetString("PreviewGroupsTable_Overwrite", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to User Tag(s): .
/// </summary>
internal static string UserTags {
get {
return ResourceManager.GetString("UserTags", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,163 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" 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>{F3E176EF-8EAF-4277-95F2-C8546C254248}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>GroupImport</RootNamespace>
<AssemblyName>GroupImport</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<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>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<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.Drawing" />
<Reference Include="System.Windows.Forms" />
<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.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="GroupImportModule.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Resources\StringResources.Designer.cs">
<DependentUpon>StringResources.resx</DependentUpon>
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
</Compile>
<Compile Include="Resources\TranslateExtension.cs" />
<Compile Include="ViewModel\GroupImportViewModel.cs" />
<Compile Include="View\GroupImportImportView.xaml.cs">
<DependentUpon>GroupImportImportView.xaml</DependentUpon>
</Compile>
<Compile Include="View\GroupImportPreviewView.xaml.cs">
<DependentUpon>GroupImportPreviewView.xaml</DependentUpon>
</Compile>
<Compile Include="View\GroupImportOptionsView.xaml.cs">
<DependentUpon>GroupImportOptionsView.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Page Include="View\GroupImportImportView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="View\GroupImportPreviewView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="View\GroupImportOptionsView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\StringResources.de.resx" />
<EmbeddedResource Include="Resources\StringResources.es.resx" />
<EmbeddedResource Include="Resources\StringResources.fr.resx" />
<EmbeddedResource Include="Resources\StringResources.ja.resx" />
<EmbeddedResource Include="Resources\StringResources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>StringResources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Resources\StringResources.ru.resx" />
</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.Storage\DTS.Common.Storage.csproj">
<Project>{E3BE457C-0AC7-4A9C-BC81-EAFEB3217878}</Project>
<Name>DTS.Common.Storage</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>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</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("GroupImportModule")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GroupImportModule")]
[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("f3e176ef-8eaf-4277-95f2-c8546c254248")]
// 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")]

Binary file not shown.

View File

@@ -0,0 +1,163 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" 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>{F3E176EF-8EAF-4277-95F2-C8546C254248}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>GroupImport</RootNamespace>
<AssemblyName>GroupImport</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<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>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<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.Drawing" />
<Reference Include="System.Windows.Forms" />
<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.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="GroupImportModule.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Resources\StringResources.Designer.cs">
<DependentUpon>StringResources.resx</DependentUpon>
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
</Compile>
<Compile Include="Resources\TranslateExtension.cs" />
<Compile Include="ViewModel\GroupImportViewModel.cs" />
<Compile Include="View\GroupImportImportView.xaml.cs">
<DependentUpon>GroupImportImportView.xaml</DependentUpon>
</Compile>
<Compile Include="View\GroupImportPreviewView.xaml.cs">
<DependentUpon>GroupImportPreviewView.xaml</DependentUpon>
</Compile>
<Compile Include="View\GroupImportOptionsView.xaml.cs">
<DependentUpon>GroupImportOptionsView.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Page Include="View\GroupImportImportView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="View\GroupImportPreviewView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="View\GroupImportOptionsView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\StringResources.de.resx" />
<EmbeddedResource Include="Resources\StringResources.es.resx" />
<EmbeddedResource Include="Resources\StringResources.fr.resx" />
<EmbeddedResource Include="Resources\StringResources.ja.resx" />
<EmbeddedResource Include="Resources\StringResources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>StringResources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Resources\StringResources.ru.resx" />
</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.Storage\DTS.Common.Storage.csproj">
<Project>{E3BE457C-0AC7-4A9C-BC81-EAFEB3217878}</Project>
<Name>DTS.Common.Storage</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>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,103 @@
using System;
using System.ComponentModel.Composition;
using System.Windows.Media.Imaging;
using DTS.Common;
using DTS.Common.Interface;
using DTS.Common.Interface.Groups;
using Prism.Ioc;
using Prism.Modularity;
using Unity;
namespace GroupImport
{
[Export(typeof(IModule))]
[Module(ModuleName = "GroupImportModule")]
public class GroupImportModule : IModule
{
/// <summary>
/// Injected unity container
/// </summary>
private readonly IUnityContainer _unityContainer;
/// <summary>
/// Initializes a new instance of the <see cref="GroupImportModule"/> class.
/// </summary>
/// <param name="unityContainer">Obtained reference of the unity container by using dependency injection.</param>
public GroupImportModule(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
public void Initialize()
{
// Register View & View-Model with Unity dependency injection container as a singleton.
_unityContainer.RegisterType<IGroupImportImportView, GroupImportImportView>();
_unityContainer.RegisterType<IGroupImportOptionsView, GroupImportOptionsView>();
_unityContainer.RegisterType<IGroupImportPreviewView, GroupImportPreviewView>();
_unityContainer.RegisterType<IGroupImportViewModel, GroupImportViewModel>();
}
public void OnInitialized(IContainerProvider containerProvider)
{
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
Initialize();
}
}
/// <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 GroupImageAttribute : ImageAttribute
{
private BitmapImage _img;
public GroupImageAttribute() : this(null) { }
public override eAssemblyRegion AssemblyRegion => throw new NotImplementedException();
public override BitmapImage AssemblyImage
{
get { _img = AssemblyInfo.GetImage(AssemblyNames.GroupImport.ToString()); return _img; }
}
public GroupImageAttribute(string s)
{
_img = AssemblyInfo.GetImage(AssemblyNames.GroupImport.ToString());
}
public override Type GetAttributeType()
{
return typeof(ImageAttribute);
}
public override BitmapImage GetAssemblyImage()
{
return AssemblyImage;
}
private string _name;
public override string AssemblyName
{
get { _name = AssemblyNames.GroupImport.ToString(); return _name; }
}
public override string GetAssemblyName()
{
return AssemblyName;
}
public override eAssemblyRegion GetAssemblyRegion()
{
throw new NotImplementedException();
}
private string _group;
public override string AssemblyGroup
{
get { _group = eAssemblyGroups.Prepare.ToString(); return _group; }
}
public override string GetAssemblyGroup()
{
return AssemblyGroup;
}
}
}

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("GroupImportModule")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GroupImportModule")]
[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("f3e176ef-8eaf-4277-95f2-c8546c254248")]
// 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,396 @@
//------------------------------------------------------------------------------
// <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 GroupImport.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("GroupImport.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 Group Tag(s): .
/// </summary>
internal static string GroupTags {
get {
return ResourceManager.GetString("GroupTags", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Importing {0}:{1}.
/// </summary>
internal static string Import_Importing {
get {
return ResourceManager.GetString("Import_Importing", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to TDAS group file (*.grp)|*.grp|All Files (*.*)|*.*.
/// </summary>
internal static string ImportFileFilter {
get {
return ResourceManager.GetString("ImportFileFilter", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Done.
/// </summary>
internal static string Importing_Done {
get {
return ResourceManager.GetString("Importing_Done", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to (None).
/// </summary>
internal static string None {
get {
return ResourceManager.GetString("None", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Browse.
/// </summary>
internal static string Options_Browse {
get {
return ResourceManager.GetString("Options_Browse", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to File(s).
/// </summary>
internal static string Options_Files {
get {
return ResourceManager.GetString("Options_Files", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Format.
/// </summary>
internal static string Options_Format {
get {
return ResourceManager.GetString("Options_Format", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Channels that will be imported.
/// </summary>
internal static string Preview_CompleteGroupChannels {
get {
return ResourceManager.GetString("Preview_CompleteGroupChannels", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Empty file.
/// </summary>
internal static string Preview_EmptyFile {
get {
return ResourceManager.GetString("Preview_EmptyFile", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Groups.
/// </summary>
internal static string Preview_Groups {
get {
return ResourceManager.GetString("Preview_Groups", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Channels that will not be imported.
/// </summary>
internal static string Preview_IncompleteGroupChannels {
get {
return ResourceManager.GetString("Preview_IncompleteGroupChannels", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invalid full scale capacity.
/// </summary>
internal static string Preview_InvalidFullScaleCapacity {
get {
return ResourceManager.GetString("Preview_InvalidFullScaleCapacity", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invalid desired range for {0}::{1}, the sensor capacity will be used instead.
/// </summary>
internal static string Preview_InvalidFullScaleInput {
get {
return ResourceManager.GetString("Preview_InvalidFullScaleInput", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invalid Invert.
/// </summary>
internal static string Preview_InvalidInvert {
get {
return ResourceManager.GetString("Preview_InvalidInvert", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Group name &apos;{0}&apos; is duplicate or invalid.
/// </summary>
internal static string Preview_InvalidName {
get {
return ResourceManager.GetString("Preview_InvalidName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invalid number of fields.
/// </summary>
internal static string Preview_InvalidNumberOfFields {
get {
return ResourceManager.GetString("Preview_InvalidNumberOfFields", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Group {0} contains some lines which are invalid. The invalid lines won&apos;t be imported..
/// </summary>
internal static string Preview_InvalidRow {
get {
return ResourceManager.GetString("Preview_InvalidRow", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sensor not found for {0}::{1}, this channel will not be imported..
/// </summary>
internal static string Preview_InvalidSensor {
get {
return ResourceManager.GetString("Preview_InvalidSensor", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invalid sensor invert for {0}::{1}, the sensor invert setting will be used instead.
/// </summary>
internal static string Preview_InvalidSensorInput {
get {
return ResourceManager.GetString("Preview_InvalidSensorInput", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to No files selected for import.
/// </summary>
internal static string Preview_NoFilesSelected {
get {
return ResourceManager.GetString("Preview_NoFilesSelected", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Nothing to import.
/// </summary>
internal static string Preview_NoGroupsToImport {
get {
return ResourceManager.GetString("Preview_NoGroupsToImport", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sensor not found.
/// </summary>
internal static string Preview_SensorNotFound {
get {
return ResourceManager.GetString("Preview_SensorNotFound", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Display name.
/// </summary>
internal static string PreviewGroups_DisplayName {
get {
return ResourceManager.GetString("PreviewGroups_DisplayName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Full scale.
/// </summary>
internal static string PreviewGroups_FullScale {
get {
return ResourceManager.GetString("PreviewGroups_FullScale", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invert.
/// </summary>
internal static string PreviewGroups_Invert {
get {
return ResourceManager.GetString("PreviewGroups_Invert", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to ISOCode.
/// </summary>
internal static string PreviewGroups_ISOCode {
get {
return ResourceManager.GetString("PreviewGroups_ISOCode", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Issue.
/// </summary>
internal static string PreviewGroups_Issue {
get {
return ResourceManager.GetString("PreviewGroups_Issue", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sensor serial number.
/// </summary>
internal static string PreviewGroups_SensorSerialNumber {
get {
return ResourceManager.GetString("PreviewGroups_SensorSerialNumber", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Warnings.
/// </summary>
internal static string PreviewGroups_Warnings {
get {
return ResourceManager.GetString("PreviewGroups_Warnings", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This Group is not compatible with your Tags (see below) and will not be saved..
/// </summary>
internal static string PreviewGroups_WontSaveWithIncompatibleTags {
get {
return ResourceManager.GetString("PreviewGroups_WontSaveWithIncompatibleTags", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to File.
/// </summary>
internal static string PreviewGroupsTable_File {
get {
return ResourceManager.GetString("PreviewGroupsTable_File", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Group name.
/// </summary>
internal static string PreviewGroupsTable_GroupName {
get {
return ResourceManager.GetString("PreviewGroupsTable_GroupName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Tags.
/// </summary>
internal static string PreviewGroupsTable_GroupTags {
get {
return ResourceManager.GetString("PreviewGroupsTable_GroupTags", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Included.
/// </summary>
internal static string PreviewGroupsTable_Included {
get {
return ResourceManager.GetString("PreviewGroupsTable_Included", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Overwrite.
/// </summary>
internal static string PreviewGroupsTable_Overwrite {
get {
return ResourceManager.GetString("PreviewGroupsTable_Overwrite", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to User Tag(s): .
/// </summary>
internal static string UserTags {
get {
return ResourceManager.GetString("UserTags", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,101 @@
<?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>
</root>

View File

@@ -0,0 +1,101 @@
<?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>
</root>

View File

@@ -0,0 +1,101 @@
<?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>
</root>

View File

@@ -0,0 +1,101 @@
<?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>
</root>

View File

@@ -0,0 +1,231 @@
<?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="ImportFileFilter" xml:space="preserve">
<value>TDAS group file (*.grp)|*.grp|All Files (*.*)|*.*</value>
</data>
<data name="Options_Browse" xml:space="preserve">
<value>Browse</value>
</data>
<data name="Options_Files" xml:space="preserve">
<value>File(s)</value>
</data>
<data name="Options_Format" xml:space="preserve">
<value>Format</value>
</data>
<data name="PreviewGroupsTable_File" xml:space="preserve">
<value>File</value>
</data>
<data name="PreviewGroupsTable_GroupName" xml:space="preserve">
<value>Group name</value>
</data>
<data name="PreviewGroupsTable_Included" xml:space="preserve">
<value>Included</value>
</data>
<data name="PreviewGroupsTable_Overwrite" xml:space="preserve">
<value>Overwrite</value>
</data>
<data name="PreviewGroups_DisplayName" xml:space="preserve">
<value>Display name</value>
</data>
<data name="PreviewGroups_FullScale" xml:space="preserve">
<value>Full scale</value>
</data>
<data name="PreviewGroups_Invert" xml:space="preserve">
<value>Invert</value>
</data>
<data name="PreviewGroups_ISOCode" xml:space="preserve">
<value>ISOCode</value>
</data>
<data name="PreviewGroups_Issue" xml:space="preserve">
<value>Issue</value>
</data>
<data name="PreviewGroups_SensorSerialNumber" xml:space="preserve">
<value>Sensor serial number</value>
</data>
<data name="Preview_CompleteGroupChannels" xml:space="preserve">
<value>Channels that will be imported</value>
</data>
<data name="Preview_Groups" xml:space="preserve">
<value>Groups</value>
</data>
<data name="Preview_IncompleteGroupChannels" xml:space="preserve">
<value>Channels that will not be imported</value>
</data>
<data name="Importing_Done" xml:space="preserve">
<value>Done</value>
</data>
<data name="Import_Importing" xml:space="preserve">
<value>Importing {0}:{1}</value>
</data>
<data name="Preview_EmptyFile" xml:space="preserve">
<value>Empty file</value>
</data>
<data name="Preview_InvalidFullScaleCapacity" xml:space="preserve">
<value>Invalid full scale capacity</value>
</data>
<data name="Preview_InvalidFullScaleInput" xml:space="preserve">
<value>Invalid desired range for {0}::{1}, the sensor capacity will be used instead</value>
</data>
<data name="Preview_InvalidInvert" xml:space="preserve">
<value>Invalid Invert</value>
</data>
<data name="Preview_InvalidName" xml:space="preserve">
<value>Group name '{0}' is duplicate or invalid</value>
</data>
<data name="Preview_InvalidNumberOfFields" xml:space="preserve">
<value>Invalid number of fields</value>
</data>
<data name="Preview_InvalidRow" xml:space="preserve">
<value>Group {0} contains some lines which are invalid. The invalid lines won't be imported.</value>
</data>
<data name="Preview_InvalidSensor" xml:space="preserve">
<value>Sensor not found for {0}::{1}, this channel will not be imported.</value>
</data>
<data name="Preview_InvalidSensorInput" xml:space="preserve">
<value>Invalid sensor invert for {0}::{1}, the sensor invert setting will be used instead</value>
</data>
<data name="Preview_NoFilesSelected" xml:space="preserve">
<value>No files selected for import</value>
</data>
<data name="Preview_NoGroupsToImport" xml:space="preserve">
<value>Nothing to import</value>
</data>
<data name="Preview_SensorNotFound" xml:space="preserve">
<value>Sensor not found</value>
</data>
<data name="PreviewGroups_Warnings" xml:space="preserve">
<value>Warnings</value>
</data>
<data name="PreviewGroupsTable_GroupTags" xml:space="preserve">
<value>Tags</value>
</data>
<data name="GroupTags" xml:space="preserve">
<value>Group Tag(s): </value>
</data>
<data name="None" xml:space="preserve">
<value>(None)</value>
</data>
<data name="PreviewGroups_WontSaveWithIncompatibleTags" xml:space="preserve">
<value>This Group is not compatible with your Tags (see below) and will not be saved.</value>
</data>
<data name="UserTags" xml:space="preserve">
<value>User Tag(s): </value>
</data>
</root>

View File

@@ -0,0 +1,101 @@
<?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>
</root>

View File

@@ -0,0 +1,21 @@
using System;
using System.Windows.Markup;
using GroupImport.Resources;
namespace DBImportExport.Resources
{
[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,31 @@
<base:BaseView x:Class="GroupImport.GroupImportImportView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:CommonCtrl="clr-namespace:DTS.Common.Controls;assembly=DTS.Common"
xmlns:base="clr-namespace:DTS.Common.Base;assembly=DTS.Common">
<base:BaseView.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/DTS.Common;component/Themes/CommonStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="TextBlock" BasedOn="{StaticResource PageContentTextStyle}" >
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Margin" Value="5" />
</Style>
<Style TargetType="TextBox">
<Setter Property="Margin" Value="5" />
</Style>
<Style TargetType="Button">
<Setter Property="Margin" Value="5" />
</Style>
</ResourceDictionary>
</base:BaseView.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<CommonCtrl:CommonStatusRibbon x:Name="CtrlStatusRibbon" Grid.Row="0" AggregateStatusText="{Binding ImportProgressText}" AggregateStatusColor="{Binding ImportProgressColor}" ProgressBarVisibility="{Binding ImportProgressBarVisibility}" ProgressBarValue="{Binding ImportProgressValue}"/>
</Grid>
</base:BaseView>

View File

@@ -0,0 +1,16 @@
using DTS.Common.Interface.Groups;
namespace GroupImport
{
/// <summary>
/// Interaction logic for GroupImportImportView.xaml
/// </summary>
public partial class GroupImportImportView : IGroupImportImportView
{
public GroupImportImportView()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,54 @@
<base:BaseView x:Class="GroupImport.GroupImportOptionsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:root="clr-namespace:DBImportExport.Resources"
xmlns:base="clr-namespace:DTS.Common.Base;assembly=DTS.Common"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
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>
<converters:FilePathsToShortStringConverter x:Key="filesToStringConverter" />
<Style TargetType="TextBlock" BasedOn="{StaticResource PageContentTextStyle}" >
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Margin" Value="5" />
</Style>
<Style TargetType="TextBox">
<Setter Property="Margin" Value="0,2,0,2" />
</Style>
<Style TargetType="Button">
<Setter Property="Margin" Value="5" />
</Style>
</ResourceDictionary>
</base:BaseView.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="150" />
<ColumnDefinition Width="200" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- for now hide since there's only one import format currently...
<TextBlock Grid.Row="0" Grid.Column="0" Text="{root:TranslateExtension Options_Format}" />
<ComboBox Grid.Row="0" Grid.Column="1" VerticalAlignment="Center"/>
-->
<TextBlock Grid.Row="1" Grid.Column="0" Text="{root:TranslateExtension Options_Files}" />
<TextBox IsEnabled="False" IsReadOnly="True" Grid.Row="1" Grid.Column="1" Text="{Binding SourceFiles, Converter={StaticResource ResourceKey=filesToStringConverter}}"/>
<Button Grid.Row="1" Grid.Column="2" Content="{root:TranslateExtension Options_Browse}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding ImportBrowseCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Grid>
</base:BaseView>

View File

@@ -0,0 +1,36 @@
using System.Collections.Generic;
using DTS.Common.Interface.Groups;
using GroupImport.Resources;
namespace GroupImport
{
/// <summary>
/// Interaction logic for GroupImportOptionsView.xaml
/// </summary>
public partial class GroupImportOptionsView : IGroupImportOptionsView
{
public GroupImportOptionsView()
{
InitializeComponent();
}
/// <summary>
/// controls whether it is possible to continue to preview or not
/// it is not possible to continue to preview if no files are selected
/// and you automatically advance to preview if you select a file
/// </summary>
/// <param name="errors"></param>
/// <param name="warnings"></param>
/// <returns></returns>
public bool Validate(out List<string> errors, out List<string> warnings)
{
errors = new List<string>();
warnings = new List<string>();
var vm = (GroupImportViewModel)DataContext;
if (null != vm.SourceFiles && vm.SourceFiles.Length >= 1) return true;
errors.Add(StringResources.Preview_NoFilesSelected);
return false;
}
}
}

View File

@@ -0,0 +1,229 @@
<base:BaseView x:Class="GroupImport.GroupImportPreviewView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:root="clr-namespace:DBImportExport.Resources"
xmlns:base="clr-namespace:DTS.Common.Base;assembly=DTS.Common" >
<base:BaseView.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/DTS.Common;component/Themes/CommonStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="TextBlock" BasedOn="{StaticResource PageContentTextStyle}" >
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Margin" Value="5" />
</Style>
<Style TargetType="TextBox">
<Setter Property="Margin" Value="5" />
</Style>
<Style TargetType="Button">
<Setter Property="Margin" Value="5" />
</Style>
</ResourceDictionary>
</base:BaseView.Resources>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Vertical" Grid.Row="0">
<TextBlock Text="{root:TranslateExtension Preview_Groups}" />
<ListView HorizontalAlignment="Left" ItemsSource="{Binding Groups}"
AlternationCount="2" Margin="3,0,3,0">
<ListView.View>
<GridView>
<GridViewColumn Header="{root:TranslateExtension PreviewGroupsTable_Included}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Style="{x:Null}" IsChecked="{Binding Included}" Checked="IncludedChecked" Unchecked="IncludedUnchecked" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroupsTable_Overwrite}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Style="{x:Null}" IsChecked="{Binding Overwrite}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroupsTable_GroupName}" Width="220">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Style="{x:Null}" Text="{Binding GroupName}" MinWidth="200" TextChanged="GroupName_Changed">
<TextBox.Resources>
<Style TargetType="TextBox">
<Style.Triggers>
<MultiDataTrigger></MultiDataTrigger>
<DataTrigger Binding="{Binding GroupNameHasError}" Value="True">
<Setter Property="BorderBrush" Value="Red" />
<Setter Property="BorderThickness" Value="2" />
</DataTrigger>
<DataTrigger Binding="{Binding GroupNameHasError}" Value="false">
<Setter Property="BorderBrush" Value="Purple" />
<Setter Property="BorderThickness" Value="1" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Resources>
</TextBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroupsTable_GroupTags}" Width="220">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Style="{x:Null}" Text="{Binding GroupTags}" MinWidth="200" TextChanged="GroupTags_Changed">
<TextBox.Resources>
<Style TargetType="TextBox">
<Style.Triggers>
<MultiDataTrigger></MultiDataTrigger>
<DataTrigger Binding="{Binding GroupTagsHasError}" Value="True">
<Setter Property="BorderBrush" Value="Red" />
<Setter Property="BorderThickness" Value="2" />
</DataTrigger>
<DataTrigger Binding="{Binding GroupTagsHasError}" Value="false">
<Setter Property="BorderBrush" Value="Purple" />
<Setter Property="BorderThickness" Value="1" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Resources>
</TextBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroupsTable_File}" Width="625">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Style="{x:Null}" Text="{Binding SourceFile}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Row="1">
<TextBlock Text="{root:TranslateExtension Preview_CompleteGroupChannels}" />
<ListView HorizontalAlignment="Left" ItemsSource="{Binding CompleteChannels}"
AlternationCount="2" Margin="3,0,3,0">
<ListView.View>
<GridView>
<GridViewColumn Header="{root:TranslateExtension PreviewGroupsTable_GroupName}" Width="250">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding GroupName}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_DisplayName}" Width="250">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding DisplayName}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_SensorSerialNumber}" Width="150">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding SensorSerialNumber}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<!--<GridViewColumn Header="{root:TranslateExtension PreviewGroups_ISOCode}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding ISOCode}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>-->
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_FullScale}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding FullScale}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_Invert}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsEnabled="False" IsChecked="{Binding Invert}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_Warnings}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Error}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Row="2">
<TextBlock Text="{root:TranslateExtension Preview_IncompleteGroupChannels}" />
<ListView HorizontalAlignment="Left" ItemsSource="{Binding IncompleteChannels}"
AlternationCount="2" Margin="3,0,3,0">
<ListView.View>
<GridView>
<GridViewColumn Header="{root:TranslateExtension PreviewGroupsTable_GroupName}" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding GroupName}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_DisplayName}" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding DisplayName}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_SensorSerialNumber}" Width="150">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding SensorSerialNumber}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<!--<GridViewColumn Header="{root:TranslateExtension PreviewGroups_ISOCode}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding ISOCode}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>-->
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_FullScale}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding FullScale}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_Invert}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsEnabled="False" IsChecked="{Binding Invert}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{root:TranslateExtension PreviewGroups_Issue}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Error}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
</Grid>
</ScrollViewer>
</base:BaseView>

View File

@@ -0,0 +1,200 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using DTS.Common.Classes.Groups;
using DTS.Common.Interface.Groups;
using DTS.Common.Strings;
using GroupImport.Resources;
namespace GroupImport
{
/// <summary>
/// Interaction logic for GroupImportOptionsView.xaml
/// </summary>
public partial class GroupImportPreviewView : IGroupImportPreviewView
{
public GroupImportPreviewView()
{
InitializeComponent();
}
/// <summary>
/// handles when tb group name changes
/// in this case the UI needs to be notified and the validity of the group name may change
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void GroupName_Changed(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
var tb = (TextBox)sender;
var group = (GroupGRPImportGroup)tb.DataContext;
group.GroupName = tb.Text;
foreach (var ch in group.Channels)
{
ch.GroupNameInvalidate();
}
var vm = (GroupImportViewModel)DataContext;
vm.CheckGroupName();
}
/// <summary>
/// handles when tb group tag changes
/// in this case the UI needs to be notified and the validity of the group tag may change
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void GroupTags_Changed(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
var tb = (TextBox)sender;
var group = (GroupGRPImportGroup)tb.DataContext;
group.GroupTags = tb.Text;
}
/// <summary>
/// handles included checkbox being checked for a group
/// in this case the channels for the group should be added to the UI
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void IncludedChecked(object sender, System.Windows.RoutedEventArgs e)
{
var vm = (GroupImportViewModel)DataContext;
vm.InvalidateChannels();
}
/// <summary>
/// handles the included checkbox being unchecked for a group
/// in this case the channels for the group should be removed from the UI
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void IncludedUnchecked(object sender, System.Windows.RoutedEventArgs e)
{
var vm = (GroupImportViewModel)DataContext;
vm.InvalidateChannels();
}
/// <summary>
/// checks whether it is okay to proceed to import,
/// checks the validity of the selected channels and groups
/// </summary>
/// <param name="userIsAdmin">whether or not the user has Administrator privileges</param>
/// <param name="errors">any fatal errors that would prevent importing</param>
/// <param name="warnings">any non fatal errors that the user needs to be warned about (but that don't prevent importing)</param>
/// <returns>true if it is okay to proceed to import</returns>
public bool Validate(bool userIsAdmin, out List<string> errors, out List<string> warnings)
{
errors = new List<string>();
warnings = new List<string>();
var bValid = true;
var vm = (GroupImportViewModel)DataContext;
var bAnyValidChannels = false;
if (vm.Groups.Any())
{
foreach (var g in vm.Groups)
{
if (!g.Included) { continue; }
if (!string.IsNullOrWhiteSpace(g.GroupTags) && !userIsAdmin)
{
foreach (var userTag in g.ImportingUserTags.Split())
{
if (g.GroupTags.Split().Contains(userTag)) continue;
var sb = new StringBuilder();
sb.Append(string.Format(StringResources.PreviewGroups_WontSaveWithIncompatibleTags, userTag, g.GroupTags));
sb.Append($"\r\n{StringResources.UserTags}");
sb.Append(g.ImportingUserTags.Length == 0 ? StringResources.None : g.ImportingUserTags);
//The static group in question will always have at least 1 Tag, otherwise there would be no problem
sb.Append($"\r\n{StringResources.GroupTags}");
sb.Append(g.GroupTags);
errors.Add(sb.ToString());
return false;
}
}
if (g.GroupNameHasError)
{
var msg = string.Format(StringResources.Preview_InvalidName, g.GroupName);
if (!errors.Contains(msg))
{
errors.Add(msg);
}
return false;
}
if (null != g.GroupErrors && g.GroupErrors.Any())
{
foreach (var error in g.GroupErrors)
{
if (!errors.Contains(error.ExtraInfo))
{
errors.Add(error.ExtraInfo);
}
}
return false;
}
if (vm.CheckGroupExists(g.GroupName) && !g.Overwrite)
{
var msg = string.Format(StringResources.Preview_InvalidName, g.GroupName);
if (!errors.Contains(msg)) { errors.Add(msg); }
return false;
}
bValid = false;
foreach (var ch in g.Channels)
{
if (null != ch.Error)
{
switch (ch.Error.ErrorCode)
{
case GroupGRPImportError.Errors.FileEmpty:
case GroupGRPImportError.Errors.InvalidISOCodeInput:
bAnyValidChannels = true;
break;
case GroupGRPImportError.Errors.InvalidFullScaleInput:
warnings.Add(string.Format(StringResources.Preview_InvalidFullScaleInput,
g.GroupName, ch.DisplayName));
bAnyValidChannels = true;
break;
case GroupGRPImportError.Errors.InvalidInvertInput:
warnings.Add(string.Format(StringResources.Preview_InvalidSensorInput,
g.GroupName,
ch.DisplayName));
bAnyValidChannels = true;
break;
case GroupGRPImportError.Errors.InvalidSensorInput:
var msg = string.Format(StringResources.Preview_InvalidRow, g.GroupName);
if (!warnings.Contains(msg))
{
warnings.Add(msg);
}
break;
case GroupGRPImportError.Errors.SensorNotFound:
warnings.Add(string.Format(StringResources.Preview_InvalidSensor, g.GroupName,
ch.DisplayName));
break;
default:
throw new ArgumentOutOfRangeException();
}
}
else
{
bValid = true;
bAnyValidChannels = true;
}
}
}
if (!bAnyValidChannels)
{
errors.Add(StringResources.Preview_NoGroupsToImport);
}
return bValid;
}
errors.Add(StringResources.Preview_NoGroupsToImport);
return false;
}
}
}

View File

@@ -0,0 +1,792 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Threading.Tasks;
using DTS.Common.Events;
using DTS.Common.Utils;
using DTS.Common.Classes.Groups;
using System.Linq;
using System.Text;
using System.Windows;
using DTS.Common.Enums.Groups;
using DTS.Common.Interface.Groups;
using GroupImport.Resources;
using DTS.Common.Storage;
using System.Windows.Media;
using Prism.Regions;
using DTS.Common.Interactivity;
using Unity;
using Prism.Events;
using Prism.Commands;
// ReSharper disable CheckNamespace
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable InconsistentNaming
namespace GroupImport
{
/// <summary>
/// this class handles Group/TestObject import functionality
/// </summary>
[Export(typeof(IGroupImportOptionsView))]
[Export(typeof(IGroupImportPreviewView))]
[Export(typeof(IGroupImportImportView))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class GroupImportViewModel : IGroupImportViewModel
{
#region views
/// <summary>
/// the import view
/// </summary>
public IGroupImportOptionsView ImportOptionsView { get; set; }
/// <summary>
/// the preview view
/// </summary>
public IGroupImportPreviewView ImportPreviewView { get; set; }
/// <summary>
/// the import view
/// </summary>
public IGroupImportImportView ImportView { get; set; }
#endregion
private IEventAggregator _eventAggregator { get; set; }
private IRegionManager _regionManager;
private IUnityContainer UnityContainer { get; set; }
public InteractionRequest<Notification> NotificationRequest { get; private set; }
public InteractionRequest<Confirmation> ConfirmationRequest { get; private set; }
/// <summary>
/// Creates a new instance of the TechnologyDomainEditViewModel.
/// </summary>
/// <param name="previewView"></param>
/// <param name="importView"></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>
/// <param name="optionsView"></param>
public GroupImportViewModel(IGroupImportOptionsView optionsView, IGroupImportPreviewView previewView,
IGroupImportImportView importView, IRegionManager regionManager, IEventAggregator eventAggregator,
IUnityContainer unityContainer)
{
ImportView = importView;
ImportView.DataContext = this;
ImportOptionsView = optionsView;
ImportOptionsView.DataContext = this;
ImportPreviewView = previewView;
ImportPreviewView.DataContext = this;
NotificationRequest = new InteractionRequest<Notification>();
ConfirmationRequest = new InteractionRequest<Confirmation>();
_eventAggregator = eventAggregator;
UnityContainer = unityContainer;
_regionManager = regionManager;
_eventAggregator.GetEvent<RaiseNotification>().Subscribe(OnRaiseNotification);
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>()
.Subscribe(OnBusyIndicatorNotification, ThreadOption.PublisherThread, true);
}
#region Methods
/// <summary>
/// reads .grp files, parsing out groups and channels
/// </summary>
public void ParseSourceFiles(string userTags)
{
var groups = new List<GroupGRPImportGroup>();
foreach (var file in SourceFiles)
{
var group = new GroupGRPImportGroup { SourceFile = file };
try
{
var lines = System.IO.File.ReadAllLines(file);
var fi = new System.IO.FileInfo(file);
var groupName = fi.Name.Replace(fi.Extension, "");
if (groupName.EndsWith("."))
{
groupName = groupName.Substring(0, groupName.Length - 1);
}
group.GroupName = groupName;
group.GroupTags = userTags;
group.ImportingUserTags = userTags;
if (lines.Any())
{
group.GroupErrors = new GroupGRPImportError[0];
var channels = new List<GroupGRPImportChannel>();
for (var i = 0; i < lines.Length; i++)
{
var line = lines[i];
if (string.IsNullOrWhiteSpace(line)) { continue; }
var fields = Parse(line);
var sensorSerialNumber = fields[0];
var channel = new GroupGRPImportChannel { SensorSerialNumber = sensorSerialNumber, ParentGroup = group };
if (null != CheckSensorExists && !CheckSensorExists.Invoke(sensorSerialNumber) &&
//FB13753 .grp import should allow empty sensor
!string.Empty.Equals(sensorSerialNumber))
{
channel.Error = new GroupGRPImportError
{
ErrorCode = GroupGRPImportError.Errors.SensorNotFound,
ExtraInfo = StringResources.Preview_SensorNotFound,
File = file,
Line = i
};
}
if (5 == fields.Length)
{
channel.DisplayName = fields[1];
channel.ISOCode = fields[2];
switch (fields[3].ToLower())
{
case "no":
channel.Invert = false;
break;
case "yes":
channel.Invert = true;
break;
default:
if (!bool.TryParse(fields[3], out var invert))
{
channel.Error = new GroupGRPImportError
{
ErrorCode = GroupGRPImportError.Errors.InvalidInvertInput,
ExtraInfo = StringResources.Preview_InvalidInvert,
File = file,
Line = i
};
continue;
}
channel.Invert = invert;
break;
}
double capacity;
if (!double.TryParse(fields[4], out capacity))
{
channel.Error = new GroupGRPImportError
{
ErrorCode = GroupGRPImportError.Errors.InvalidFullScaleInput,
ExtraInfo = StringResources.Preview_InvalidFullScaleCapacity
};
continue;
}
channel.FullScale = capacity;
}
else
{
channel.Error = new GroupGRPImportError
{
ErrorCode = GroupGRPImportError.Errors.InvalidSensorInput,
ExtraInfo = StringResources.Preview_InvalidNumberOfFields,
File = file,
Line = i
};
}
channels.Add(channel);
}
group.Channels = channels.ToArray();
if (!channels.Any())
{
group.GroupErrors = new[]
{
new GroupGRPImportError
{
ErrorCode = GroupGRPImportError.Errors.FileEmpty,
ExtraInfo = StringResources.Preview_EmptyFile,
File = file,
Line = 0
}
};
}
}
else
{
group.GroupErrors = new[]
{
new GroupGRPImportError
{
File = file,
ErrorCode = GroupGRPImportError.Errors.FileEmpty,
Line = 0,
ExtraInfo = StringResources.Preview_EmptyFile
}
};
}
}
catch (Exception ex)
{
group.GroupErrors = new[]
{
new GroupGRPImportError
{
File = file,
Line = 0,
ExtraInfo = ex.Message,
ErrorCode = GroupGRPImportError.Errors.FileEmpty
}
};
LogMessage(ex);
}
groups.Add(group);
}
Groups = groups.ToArray();
ProcessChannels();
}
/// <summary>
/// starts the process of creating and commiting groups and channels on a background thread
/// </summary>
public void Import()
{
System.Threading.ThreadPool.QueueUserWorkItem(ImportFunc);
}
/// <summary>
/// the actual thread writing groups and channels
/// </summary>
/// <param name="o"></param>
private void ImportFunc(object o)
{
var channelDefaults = DbOperations.GetChannelSettingDefaults();
ImportProgressValue = 0;
ImportProgressBarVisibility = Visibility.Visible;
ImportProgressColor = DTS.Common.BrushesAndColors.Brush_ApplicationStatus_Busy.Color;
DisableUI?.Invoke();
var done = 0;
var allChannels = Groups.Where(g => g.Included).SelectMany(g => g.Channels).Count();
var groups = new List<string>();
foreach (var g in Groups)
{
if (!g.Included) { continue; }
CreateGroup(g.GroupName, g.GroupTags);
foreach (var ch in g.Channels)
{
done++;
//ImportProgressText = string.Format(StringResources.Import_Importing, g.GroupName, ch.DisplayName);
//ImportProgressValue = Convert.ToInt32(100D * done / allChannels);
if (null != ch.Error)
{
switch (ch.Error.ErrorCode)
{
case GroupGRPImportError.Errors.FileEmpty:
case GroupGRPImportError.Errors.InvalidSensorInput:
case GroupGRPImportError.Errors.SensorNotFound:
continue;//don't add
}
}
double? capacity = null;
if (null == ch.Error || ch.Error.ErrorCode != GroupGRPImportError.Errors.InvalidFullScaleInput)
{
capacity = ch.FullScale;
}
bool? invert = null;
if (null == ch.Error || ch.Error.ErrorCode != GroupGRPImportError.Errors.InvalidInvertInput)
{
invert = ch.Invert;
}
AddChannel(g.GroupName, ch.DisplayName, ch.SensorSerialNumber, capacity, invert, ch.ISOCode, channelDefaults);
}
groups.Add(g.GroupName);
//CommitGroup(g.GroupName);
}
CommitGroups(groups.ToArray());
//ImportProgressColor = DTS.Common.BrushesAndColors.Brush_ApplicationStatus_Complete.Color;
//ImportProgressBarVisibility = Visibility.Collapsed;
//EnableUI?.Invoke();
}
public void SetStatus(string message, Color color)
{
ImportProgressColor = color;
ImportProgressBarVisibility = Visibility.Collapsed;
ImportProgressText = message;
EnableUI?.Invoke();
}
/// <summary>
/// re-initializes the group view model
/// right now we don't create a new group view model, we appear to reuse the existing one, so it has to be reset
/// </summary>
public void Reset()
{
SourceFiles = new string[0];
Channels = new GroupGRPImportChannel[0];
Groups = new GroupGRPImportGroup[0];
ImportProgressBarVisibility = Visibility.Collapsed;
ImportProgressColor = DTS.Common.BrushesAndColors.Brush_ApplicationStatus_Idle.Color;
ImportProgressText = string.Empty;
ImportProgressValue = 0;
}
/// <summary>
/// parses a single line in a GRP file
/// this line may use () to escape values, like "this(,)is all one field" will only return one string
/// </summary>
/// <param name="line"></param>
/// <returns></returns>
private static string[] Parse(string line)
{
var strings = new List<string>();
var currentString = new StringBuilder();
var currentCharacter = 0;
var leftParenCount = 0;
while (currentCharacter < line.Length)
{
var ch = line[currentCharacter];
switch (ch)
{
case '(':
currentString.Append("(");
leftParenCount++;
break;
case ')':
currentString.Append(")");
leftParenCount--;
break;
case ',':
if (leftParenCount > 0)
{
currentString.Append(",");
}
else
{
strings.Add(currentString.ToString());
currentString.Clear();
}
break;
default:
currentString.Append(ch);
break;
}
currentCharacter++;
}
if (currentString.Length > 0)
{
strings.Add(currentString.ToString());
}
return strings.ToArray();
}
/// <summary>
/// checks whether a group name is valid
/// a group name is invalid if it exists more than once in the import or if it already exists in the
/// application and overwrite is false
/// </summary>
public void CheckGroupName()
{
var groupNameLookup = new Dictionary<string, List<GroupGRPImportGroup>>();
foreach (var g in Groups)
{
if (!groupNameLookup.ContainsKey(g.GroupName))
{
groupNameLookup.Add(g.GroupName, new List<GroupGRPImportGroup>());
}
groupNameLookup[g.GroupName].Add(g);
}
foreach (var g in Groups)
{
if (groupNameLookup[g.GroupName].Count > 1)
{
g.GroupNameHasError = true;
}
else
{
if (CheckGroupExists(g.GroupName) && !g.Overwrite)
{
g.GroupNameHasError = true;
}
else { g.GroupNameHasError = false; }
}
}
}
/// <summary>
/// log a message
/// </summary>
/// <param name="parms"></param>
private void LogMessage(params object[] parms)
{
Logger?.Invoke(parms);
}
/// <summary>
/// separates channels out of groups into valid and invalid channels
/// popuplates IncompleteChannels and CompleteChannels
/// </summary>
private void ProcessChannels()
{
var channels = new List<GroupGRPImportChannel>();
foreach (var g in Groups)
{
channels.AddRange(g.Channels);
}
Channels = channels.ToArray();
}
public void Cleanup()
{
}
public Task CleanupAsync()
{
return Task.CompletedTask;
}
public void Initialize()
{
}
public void Initialize(object parameter)
{
}
public void Initialize(object parameter, object model)
{
}
public Task InitializeAsync()
{
return Task.CompletedTask;
}
public Task InitializeAsync(object parameter)
{
return Task.CompletedTask;
}
public void Activated()
{
}
/// <summary>
/// Private Event handler for RaiseNotification event.
/// </summary>
private void OnBusyIndicatorNotification(bool eventArg)
{
IsBusy = eventArg;
}
/// <summary>
/// Private Event handler for RaiseNotification event.
/// </summary>
private void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)
{
// The NotificationRequest.Raise triggers the Invoke() method of the PopupWindowAction object to show the NotificationWindow window
// Notification object expects a NotificationContentEventArgsWithoutTitle object and a Title string.
var eventArgsWithoutTitle =
new NotificationContentEventArgs(eventArgsWithTitle.Message, "", eventArgsWithTitle.Image,
string.Empty);
NotificationRequest.Raise(new Notification
{
Content = eventArgsWithoutTitle,
Title = eventArgsWithTitle.Title
});
}
#endregion
#region Properties
public bool IsDirty { get; private set; }
private bool _isBusy;
public bool IsBusy
{
get => _isBusy;
set
{
_isBusy = value;
OnPropertyChanged("IsBusy");
}
}
private bool _isMenuIncluded;
public bool IsMenuIncluded
{
get => _isMenuIncluded;
set
{
_isMenuIncluded = value;
OnPropertyChanged("IsMenuIncluded");
}
}
private bool _isNavigationIncluded;
public bool IsNavigationIncluded
{
get => _isNavigationIncluded;
set
{
_isNavigationIncluded = value;
OnPropertyChanged("IsNavigationIncluded");
}
}
/// <summary>
/// Gets the HeaderInfo.
/// </summary>
public string HeaderInfo => "MainRegion";
#endregion Properties
#region Commands
/// <summary>
/// browse to a file to import, should be xml, maybe needs a few other criteria
/// </summary>
private DelegateCommand _importBrowseCommand;
public DelegateCommand ImportBrowseCommand => _importBrowseCommand ?? (_importBrowseCommand = new DelegateCommand(ImportBrowseMethod));
private void ImportBrowseMethod()
{
using (var dlg = new System.Windows.Forms.OpenFileDialog())
{
dlg.CheckFileExists = true;
dlg.CheckPathExists = true;
dlg.Multiselect = true;
dlg.Filter = StringResources.ImportFileFilter;
dlg.FilterIndex = 0;
if (dlg.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
SourceFiles = dlg.FileNames;
BrowseOk = true;
SwitchNavSteps?.Invoke(GroupImportEnums.Steps.Preview);
}
}
#endregion
#region properties
private string _importProgressText;
/// <summary>
/// current status text for import progress bar
/// </summary>
public string ImportProgressText
{
get => _importProgressText;
set
{
_importProgressText = value;
OnPropertyChanged("ImportProgressText");
}
}
private System.Windows.Media.Color _importProgressColor;
/// <summary>
/// The current color of the import progress bar
/// </summary>
public System.Windows.Media.Color ImportProgressColor
{
get => _importProgressColor;
set
{
_importProgressColor = value;
OnPropertyChanged("ImportProgressColor");
}
}
public Visibility _importProgressBarVisibility;
/// <summary>
/// whether the progress bar is visible or not
/// </summary>
public Visibility ImportProgressBarVisibility
{
get => _importProgressBarVisibility;
set
{
_importProgressBarVisibility = value;
OnPropertyChanged("ImportProgressBarVisibility");
}
}
private double _importProgressValue;
/// <summary>
/// percentage complete of import process
/// </summary>
public double ImportProgressValue
{
get => _importProgressValue;
set
{
_importProgressValue = value;
OnPropertyChanged("ImportProgressValue");
}
}
private string[] _sourceFiles = new string[0];
/// <summary>
/// .GRP files to parse
/// </summary>
public string[] SourceFiles
{
get => _sourceFiles;
set
{
_sourceFiles = value;
OnPropertyChanged("SourceFiles");
}
}
public bool BrowseOk { get; set; } = false;
private GroupGRPImportGroup[] _groups = new GroupGRPImportGroup[0];
/// <summary>
/// All groups that have been read in and parsed
/// </summary>
public GroupGRPImportGroup[] Groups
{
get => _groups;
set
{
_groups = value;
OnPropertyChanged("Groups");
}
}
private GroupGRPImportChannel[] _channels = new GroupGRPImportChannel[0];
/// <summary>
/// Channels which are invalid but are in groups included in import
/// </summary>
public GroupGRPImportChannel[] Channels
{
get => _channels;
set
{
_channels = value;
InvalidateChannels();
}
}
public void InvalidateChannels()
{
OnPropertyChanged("IncompleteChannels");
OnPropertyChanged("CompleteChannels");
}
/// <summary>
/// these are channels which will not be imported
/// </summary>
public GroupGRPImportChannel[] IncompleteChannels
{
get
{
var channels = new List<GroupGRPImportChannel>();
foreach (var g in Groups)
{
if (!g.Included) { continue; }
foreach (var ch in g.Channels)
{
if (null == ch.Error) { continue; }
else
{
switch (ch.Error.ErrorCode)
{
case GroupGRPImportError.Errors.InvalidFullScaleInput:
case GroupGRPImportError.Errors.InvalidInvertInput:
continue;
default:
channels.Add(ch);
break;
}
}
}
}
return channels.ToArray();
}
}
/// <summary>
/// these are channels which will be imported
/// </summary>
public GroupGRPImportChannel[] CompleteChannels
{
get
{
var channels = new List<GroupGRPImportChannel>();
foreach (var g in Groups)
{
if (!g.Included) { continue; }
foreach (var ch in g.Channels)
{
if (null == ch.Error)
{
channels.Add(ch);
}
else
{
switch (ch.Error.ErrorCode)
{
case GroupGRPImportError.Errors.InvalidFullScaleInput:
case GroupGRPImportError.Errors.InvalidInvertInput:
channels.Add(ch);
break;
}
}
}
}
return channels.ToArray();
}
}
/// <summary>
/// the logging facility to use
/// if null no logging is performed
/// </summary>
public FileUtils.LogDelegate Logger { get; set; } = null;
/// <summary>
/// the command for switching current nav step
/// </summary>
public SwitchNavStepsDelegate SwitchNavSteps { get; set; } = null;
/// <summary>
/// the command for checking if a group already exists in the application
/// </summary>
public CheckGroupExistsDelegate CheckGroupExists { get; set; } = null;
/// <summary>
/// the command for checking if a sensor exists in the application
/// </summary>
public CheckSensorExistsDelegate CheckSensorExists { get; set; } = null;
/// <summary>
/// the command for creating a group
/// </summary>
public CreateGroupDelegate CreateGroup { get; set; } = null;
/// <summary>
/// the command for adding a channel to a group
/// </summary>
public AddChannelToGroupDelegate AddChannel { get; set; } = null;
/// <summary>
/// the command for commiting a group to the db
/// </summary>
public CommitGroupsDelegate CommitGroups { get; set; } = null;
/// <summary>
/// the command for disabling the UI
/// </summary>
public Disable_UIDelegate DisableUI { get; set; }
/// <summary>
/// the command for enabling the UI
/// </summary>
public Enable_UIDelegate EnableUI { get; set; }
#endregion
///<summary>
///Occurs when a property value changes.
///</summary>
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

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")]