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,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;
}
}
}