diff options
| author | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-11-12 20:38:57 +0200 |
|---|---|---|
| committer | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-11-12 20:38:57 +0200 |
| commit | 14e4bd850fa6730eecd7d15bd7044f364b41c986 (patch) | |
| tree | 4e1945a18def6d1c91f239b2b4dbf6e11c0d51db /Software/Visual_Studio | |
| parent | 775f0015321f91aa5be3aca079e289e89d4719f5 (diff) | |
| download | Tango-14e4bd850fa6730eecd7d15bd7044f364b41c986.tar.gz Tango-14e4bd850fa6730eecd7d15bd7044f364b41c986.zip | |
Working on data store view.
Diffstat (limited to 'Software/Visual_Studio')
47 files changed, 1831 insertions, 201 deletions
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Firmware/Tango.FSE.Firmware_0qifchtm_wpftmp.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Firmware/Tango.FSE.Firmware_0qifchtm_wpftmp.csproj new file mode 100644 index 000000000..8708fb9b0 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Firmware/Tango.FSE.Firmware_0qifchtm_wpftmp.csproj @@ -0,0 +1,203 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{7CB96D74-8B71-4A81-B4E1-6DE7BFCA6174}</ProjectGuid> + <OutputType>library</OutputType> + <RootNamespace>Tango.FSE.Firmware</RootNamespace> + <AssemblyName>Tango.FSE.Firmware</AssemblyName> + <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <WarningLevel>4</WarningLevel> + <Deterministic>true</Deterministic> + <NuGetPackageImportStamp> + </NuGetPackageImportStamp> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>..\..\..\Build\FSE\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>..\..\..\Build\FSE\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + <Compile Include="Contracts\ILogsView.cs" /> + <Compile Include="Dialogs\FirmwareUpdateView.xaml.cs"> + <DependentUpon>FirmwareUpdateView.xaml</DependentUpon> + </Compile> + <Compile Include="Dialogs\FirmwareUpdateViewVM.cs" /> + <Compile Include="Navigation\PeekLogsNavigationObject.cs" /> + <Compile Include="ViewModelLocator.cs" /> + <Compile Include="FirmwareModule.cs" /> + <Compile Include="ViewModels\FileSystemViewVM.cs" /> + <Compile Include="ViewModels\LogsViewVM.cs" /> + <Compile Include="ViewModels\MainViewVM.cs" /> + <Compile Include="ViewModels\UpdatesViewVM.cs" /> + <Compile Include="Views\FileSystemView.xaml.cs"> + <DependentUpon>FileSystemView.xaml</DependentUpon> + </Compile> + <Compile Include="Views\LogsView.xaml.cs"> + <DependentUpon>LogsView.xaml</DependentUpon> + </Compile> + <Compile Include="Views\MainView.xaml.cs"> + <DependentUpon>MainView.xaml</DependentUpon> + </Compile> + <Compile Include="Views\UpdatesView.xaml.cs"> + <DependentUpon>UpdatesView.xaml</DependentUpon> + </Compile> + </ItemGroup> + <ItemGroup> + <Compile Include="Properties\AssemblyInfo.cs"> + <SubType>Code</SubType> + </Compile> + <Compile Include="Properties\Resources.Designer.cs"> + <AutoGen>True</AutoGen> + <DesignTime>True</DesignTime> + <DependentUpon>Resources.resx</DependentUpon> + </Compile> + <Compile Include="Properties\Settings.Designer.cs"> + <AutoGen>True</AutoGen> + <DependentUpon>Settings.settings</DependentUpon> + <DesignTimeSharedInput>True</DesignTimeSharedInput> + </Compile> + <EmbeddedResource Include="Properties\Resources.resx"> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>Resources.Designer.cs</LastGenOutput> + </EmbeddedResource> + <None Include="app.config" /> + <None Include="packages.config" /> + <None Include="Properties\Settings.settings"> + <Generator>SettingsSingleFileGenerator</Generator> + <LastGenOutput>Settings.Designer.cs</LastGenOutput> + </None> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\..\PPC\Tango.PPC.Shared\Tango.PPC.Shared.csproj"> + <Project>{208C8BD8-72C6-4E3C-ACAA-351091A2ACC7}</Project> + <Name>Tango.PPC.Shared</Name> + </ProjectReference> + <ProjectReference Include="..\..\..\SideChains\Tango.AutoComplete\Tango.AutoComplete.csproj"> + <Project>{bb2abb74-ba58-4812-83aa-ec8171f42df4}</Project> + <Name>Tango.AutoComplete</Name> + </ProjectReference> + <ProjectReference Include="..\..\..\Tango.BL\Tango.BL.csproj"> + <Project>{f441feee-322a-4943-b566-110e12fd3b72}</Project> + <Name>Tango.BL</Name> + </ProjectReference> + <ProjectReference Include="..\..\..\Tango.Core\Tango.Core.csproj"> + <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project> + <Name>Tango.Core</Name> + </ProjectReference> + <ProjectReference Include="..\..\..\Tango.FileSystem\Tango.FileSystem.csproj"> + <Project>{c6ebbbbe-2123-44dc-aef7-a0d47d736ac0}</Project> + <Name>Tango.FileSystem</Name> + </ProjectReference> + <ProjectReference Include="..\..\..\Tango.Integration\Tango.Integration.csproj"> + <Project>{4206ac58-3b57-4699-8835-90bf6db01a61}</Project> + <Name>Tango.Integration</Name> + </ProjectReference> + <ProjectReference Include="..\..\..\Tango.Logging\Tango.Logging.csproj"> + <Project>{bc932dbd-7cdb-488c-99e4-f02cf441f55e}</Project> + <Name>Tango.Logging</Name> + </ProjectReference> + <ProjectReference Include="..\..\..\Tango.PMR\Tango.PMR.csproj"> + <Project>{e4927038-348d-4295-aaf4-861c58cb3943}</Project> + <Name>Tango.PMR</Name> + </ProjectReference> + <ProjectReference Include="..\..\..\Tango.Settings\Tango.Settings.csproj"> + <Project>{d8f1ad85-526a-4f50-b6dc-d437af63d8d8}</Project> + <Name>Tango.Settings</Name> + </ProjectReference> + <ProjectReference Include="..\..\..\Tango.SharedUI\Tango.SharedUI.csproj"> + <Project>{8491d07b-c1f6-4b62-a412-41b9fd2d6538}</Project> + <Name>Tango.SharedUI</Name> + </ProjectReference> + <ProjectReference Include="..\..\..\Tango.Transport\Tango.Transport.csproj"> + <Project>{74e700b0-1156-4126-be40-ee450d3c3026}</Project> + <Name>Tango.Transport</Name> + </ProjectReference> + <ProjectReference Include="..\..\Tango.FSE.BL\Tango.FSE.BL.csproj"> + <Project>{834c81c3-09b5-45d7-be12-e7d1e6655a7c}</Project> + <Name>Tango.FSE.BL</Name> + </ProjectReference> + <ProjectReference Include="..\..\Tango.FSE.Common\Tango.FSE.Common.csproj"> + <Project>{bc37cccb-7392-4f78-8d1c-e9629e6e046e}</Project> + <Name>Tango.FSE.Common</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <Import Project="..\..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets" Condition="Exists('..\..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets')" /> + <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> + <PropertyGroup> + <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> + </PropertyGroup> + <Error Condition="!Exists('..\..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets'))" /> + </Target> + <ItemGroup> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\ControlzEx.3.0.2.4\lib\net45\ControlzEx.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\MahApps.Metro.1.6.5\lib\net46\MahApps.Metro.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\MaterialDesignColors.1.2.2\lib\net45\MaterialDesignColors.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\MaterialDesignThemes.3.0.1\lib\net45\MaterialDesignThemes.Wpf.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Microsoft.CSharp.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\mscorlib.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\PresentationCore.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\PresentationFramework.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.ComponentModel.DataAnnotations.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Core.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Data.DataSetExtensions.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Data.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Net.Http.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\ControlzEx.3.0.2.4\lib\net45\System.Windows.Interactivity.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Xaml.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Xml.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Xml.Linq.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\SideChains\Tango.AutoComplete\bin\Debug\Tango.AutoComplete.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.BL.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.Core.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Tango.FileSystem\bin\Debug\Tango.FileSystem.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\FSE\Debug\Tango.FSE.BL.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\FSE\Debug\Tango.FSE.Common.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.Integration.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.Logging.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.PMR.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\PPC\Debug\Tango.PPC.Shared.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.Settings.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.SharedUI.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.Transport.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\WindowsBase.dll" /> + </ItemGroup> + <ItemGroup> + <Compile Include="C:\DATA\Development\Tango\Software\Visual_Studio\FSE\Modules\Tango.FSE.Firmware\obj\Debug\App.g.cs" /> + <Compile Include="C:\DATA\Development\Tango\Software\Visual_Studio\FSE\Modules\Tango.FSE.Firmware\obj\Debug\Dialogs\FirmwareUpdateView.g.cs" /> + <Compile Include="C:\DATA\Development\Tango\Software\Visual_Studio\FSE\Modules\Tango.FSE.Firmware\obj\Debug\Views\FileSystemView.g.cs" /> + <Compile Include="C:\DATA\Development\Tango\Software\Visual_Studio\FSE\Modules\Tango.FSE.Firmware\obj\Debug\Views\LogsView.g.cs" /> + <Compile Include="C:\DATA\Development\Tango\Software\Visual_Studio\FSE\Modules\Tango.FSE.Firmware\obj\Debug\Views\MainView.g.cs" /> + <Compile Include="C:\DATA\Development\Tango\Software\Visual_Studio\FSE\Modules\Tango.FSE.Firmware\obj\Debug\Views\UpdatesView.g.cs" /> + <Compile Include="C:\DATA\Development\Tango\Software\Visual_Studio\FSE\Modules\Tango.FSE.Firmware\obj\Debug\GeneratedInternalTypeHelper.g.cs" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Converters/DataStoreValueToStringConverter.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Converters/DataStoreValueToStringConverter.cs index 6b3c8e28c..4acf7fd8e 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Converters/DataStoreValueToStringConverter.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Converters/DataStoreValueToStringConverter.cs @@ -17,7 +17,7 @@ namespace Tango.FSE.MachineConfiguration.Converters { if (item != null) { - return DataStoreHelper.FormatDataStoreItem(item); + return DataStoreHelper.FormatDataStoreItem(item).ToOneLine().Ellipsis(100); } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogView.xaml new file mode 100644 index 000000000..2fd3b9cdf --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogView.xaml @@ -0,0 +1,53 @@ +<UserControl x:Class="Tango.FSE.MachineConfiguration.Dialogs.DataStoreItemEditDialogView" + 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:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:local="clr-namespace:Tango.FSE.MachineConfiguration.Dialogs" + xmlns:controls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common" + xmlns:sharedControls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + xmlns:datastore="clr-namespace:Tango.DataStore;assembly=Tango.DataStore" + xmlns:pmr="clr-namespace:Tango.PMR.Common;assembly=Tango.PMR" + mc:Ignorable="d" + Width="400" Height="500" d:DataContext="{d:DesignInstance Type=local:DataStoreItemEditDialogViewVM, IsDesignTimeCreatable=False}" Background="{StaticResource FSE_PrimaryBackgroundLightBrush}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}"> + <Grid Margin="10"> + <DockPanel> + <StackPanel DockPanel.Dock="Top" > + <StackPanel Orientation="Horizontal"> + <material:PackIcon Width="40" Height="40" Kind="Key" /> + <TextBlock Margin="10 0 0 0" FontSize="{StaticResource FSE_LargerFontSize}" VerticalAlignment="Center" Text="{Binding Item.Key}"></TextBlock> + </StackPanel> + </StackPanel> + + <StackPanel Margin="0 10 0 0" DockPanel.Dock="Top"> + <TextBlock FontSize="{StaticResource FSE_SmallerFontSize}" Foreground="{StaticResource FSE_GrayBrush}">Data Type</TextBlock> + + <DockPanel> + <Button Visibility="{Binding Type,Converter={StaticResource EnumToVisibilityConverter},ConverterParameter='Proto'}" DockPanel.Dock="Right" Style="{StaticResource FSE_RaisedButton_Dark_Hover_Accent_Foreground}" Margin="5 5 0 0" Padding="10 0" FontSize="{StaticResource FSE_SmallFontSize}" Height="20" VerticalAlignment="Center" Command="{Binding InitProtoCommand}" ToolTip="Create the basic structure for this proto message">Init</Button> + <Button Visibility="{Binding Type,Converter={StaticResource EnumToVisibilityConverter},ConverterParameter='Bytes'}" DockPanel.Dock="Right" Style="{StaticResource FSE_RaisedButton_Dark_Hover_Accent_Foreground}" Margin="5 5 0 0" Padding="10 0" FontSize="{StaticResource FSE_SmallFontSize}" Height="20" VerticalAlignment="Center" Command="{Binding LoadFileCommand}" ToolTip="Load bytes from file">Load File</Button> + <controls:FSERoundedCornersComboBox IsEnabled="{Binding EnableTypeChange}" FontSize="{StaticResource FSE_SmallFontSize}" Margin="0 5 0 0" ItemsSource="{Binding Source={x:Type datastore:DataType},Converter={StaticResource EnumToItemsSourceConverter}}" SelectedValue="{Binding Type,Mode=TwoWay}" SelectedValuePath="Value" DisplayMemberPath="DisplayName"></controls:FSERoundedCornersComboBox> + </DockPanel> + + <StackPanel Margin="0 10 0 0" Visibility="{Binding Type,Converter={StaticResource EnumToVisibilityConverter},ConverterParameter='Proto'}"> + <TextBlock Foreground="{StaticResource FSE_GrayBrush}" FontSize="{StaticResource FSE_SmallerFontSize}">Message Type</TextBlock> + <sharedControls:SearchComboBox IsEnabled="{Binding EnableTypeChange}" FontSize="{StaticResource FSE_SmallFontSize}" Margin="0 -5 5 0" ItemsSource="{Binding Source={x:Type pmr:MessageType},Converter={StaticResource EnumToItemsSourceConverter},ConverterParameter='false'}" SelectedItem="{Binding ProtoMessageType,Mode=TwoWay}"></sharedControls:SearchComboBox> + </StackPanel> + </StackPanel> + + <DockPanel DockPanel.Dock="Bottom" Margin="0 5 0 0" MinHeight="15"> + <DockPanel Visibility="{Binding HasError,Converter={StaticResource BooleanToVisibilityConverter}}"> + <material:PackIcon Margin="0 0 0 0" VerticalAlignment="Top" Kind="Alert" Foreground="{StaticResource FSE_ErrorBrush}" Width="12" Height="12" /> + <TextBlock Foreground="{StaticResource FSE_ErrorBrush}" Margin="5 0 0 0" Text="{Binding Error}" FontSize="{StaticResource FSE_SmallerFontSize}" TextWrapping="Wrap"></TextBlock> + </DockPanel> + </DockPanel> + + <Grid Margin="0 10 0 0"> + <TextBox Style="{StaticResource FSE_Rounded_Corners_TextBox_Multiline}" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" TextWrapping="NoWrap" Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}" FontSize="{StaticResource FSE_SmallFontSize}" Text="{Binding EditingValue,UpdateSourceTrigger=PropertyChanged}"> + + </TextBox> + </Grid> + + </DockPanel> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogView.xaml.cs new file mode 100644 index 000000000..b0f741759 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.FSE.MachineConfiguration.Dialogs +{ + /// <summary> + /// Interaction logic for DataStoreItemEditDialogView.xaml + /// </summary> + public partial class DataStoreItemEditDialogView : UserControl + { + public DataStoreItemEditDialogView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogViewVM.cs new file mode 100644 index 000000000..29ec03942 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Dialogs/DataStoreItemEditDialogViewVM.cs @@ -0,0 +1,173 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.Commands; +using Tango.Core.DI; +using Tango.Core.ExtensionMethods; +using Tango.Core.Helpers; +using Tango.DataStore; +using Tango.DataStore.Editing; +using Tango.FSE.Common; +using Tango.FSE.Common.Storage; +using Tango.PMR; +using Tango.PMR.Common; + +namespace Tango.FSE.MachineConfiguration.Dialogs +{ + public class DataStoreItemEditDialogViewVM : FSEDialogViewVM + { + private const int MAX_FILE_SIZE_KB = 100; + + [TangoInject] + private IStorageProvider StorageProvider { get; set; } + + [TangoInject] + private Common.Notifications.INotificationProvider NotificationProvider { get; set; } + + private DataStoreItemModel _item; + public DataStoreItemModel Item + { + get { return _item; } + set + { + _item = value; + RaisePropertyChangedAuto(); + + if (_item.IsGlobal) + { + Value = _item.GlobalItem.Value; + } + else + { + Value = _item.Value; + } + + Type = _item.Type; + + if (Type == DataType.Proto) + { + ProtoMessageType = (Value as DataStoreProtoObject).MessageType; + } + + if (_item.IsGlobal) + { + EditingValue = _item.GlobalItem.ToString(); + } + else + { + EditingValue = _item.ToString(); + } + } + } + + public bool EnableTypeChange { get; set; } + + private Object _value; + public Object Value + { + get { return _value; } + set { _value = value; RaisePropertyChangedAuto(); } + } + + private DataType _type; + public DataType Type + { + get { return _type; } + set { _type = value; RaisePropertyChangedAuto(); OnEditingValueChanged(); } + } + + private MessageType _protoMessageType; + public MessageType ProtoMessageType + { + get { return _protoMessageType; } + set { _protoMessageType = value; RaisePropertyChangedAuto(); OnEditingValueChanged(); } + } + + private String _editingValue; + public String EditingValue + { + get { return _editingValue; } + set { _editingValue = value; RaisePropertyChangedAuto(); OnEditingValueChanged(); } + } + + private String _error; + public String Error + { + get { return _error; } + set { _error = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(HasError)); InvalidateRelayCommands(); } + } + + public bool HasError + { + get { return Error != null; } + } + + public RelayCommand LoadFileCommand { get; set; } + + public RelayCommand InitProtoCommand { get; set; } + + public DataStoreItemEditDialogViewVM() + { + EnableTypeChange = true; + LoadFileCommand = new RelayCommand(LoadFile); + InitProtoCommand = new RelayCommand(InitProto); + TangoIOC.Default.Inject(this); + } + + private void InitProto() + { + if (Type == DataType.Proto) + { + var type = MessageFactory.GetPMRTypeFromMessageType(ProtoMessageType); + var instance = Activator.CreateInstance(type); + EditingValue = instance.ToJsonString(); + } + } + + private async void LoadFile() + { + if (Type == DataType.Bytes) + { + var result = await StorageProvider.OpenFile("Load a file"); + if (result) + { + if ((new FileInfo(result.SelectedItem).Length / 1024) > MAX_FILE_SIZE_KB) + { + await NotificationProvider.ShowError($"The selected file size exceeds the maximum {MAX_FILE_SIZE_KB}kb allowed."); + return; + } + + var bytes = File.ReadAllBytes(result.SelectedItem); + Value = bytes; + _editingValue = DataStoreHelper.GetByteArrayHexString(bytes); + RaisePropertyChanged(nameof(EditingValue)); + } + } + } + + private void OnEditingValueChanged() + { + if (EditingValue != null) + { + try + { + Value = DataStoreHelper.ParseDataStoreValue(Type, EditingValue, ProtoMessageType); + Error = null; + } + catch (Exception ex) + { + Error = ex.Message; + } + } + } + + protected override bool CanOK() + { + return base.CanOK() && !HasError; + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Images/data_collection.png b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Images/data_collection.png Binary files differnew file mode 100644 index 000000000..95163a226 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Images/data_collection.png diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj index af67b0d74..2e876db16 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Tango.FSE.MachineConfiguration.csproj @@ -80,6 +80,10 @@ <ItemGroup> <Compile Include="ConfigurationViewModel.cs" /> <Compile Include="Converters\DataStoreValueToStringConverter.cs" /> + <Compile Include="Dialogs\DataStoreItemEditDialogView.xaml.cs"> + <DependentUpon>DataStoreItemEditDialogView.xaml</DependentUpon> + </Compile> + <Compile Include="Dialogs\DataStoreItemEditDialogViewVM.cs" /> <Compile Include="Messages\EditingCompositionLoadedMessage.cs" /> <Compile Include="Navigation\ConfigurationNavigationManager.cs" /> <Compile Include="Navigation\ConfigurationView.cs" /> @@ -198,6 +202,10 @@ <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> </Page> + <Page Include="Dialogs\DataStoreItemEditDialogView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Views\ConfigurationView.xaml"> <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> @@ -222,6 +230,9 @@ <ItemGroup> <Resource Include="Images\configuration.png" /> </ItemGroup> + <ItemGroup> + <Resource Include="Images\data_collection.png" /> + </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="..\..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets" Condition="Exists('..\..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets')" /> <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/ConfigurationViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/ConfigurationViewVM.cs index 63e3f22d9..61eef2bdc 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/ConfigurationViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/ConfigurationViewVM.cs @@ -44,6 +44,8 @@ namespace Tango.FSE.MachineConfiguration.ViewModels using (NotificationProvider.PushTaskItem("Loading machine configuration...")) { EditingComposition = msg.EditingComposition; + EditingComposition.Machine.ForceVersionUpdateChanged += (x, value) => { if (value) EditingComposition.Machine.SuspendVersionUpdate = false; }; + EditingComposition.Machine.SuspendVersionUpdateChanged += (x, value) => { if (value) EditingComposition.Machine.ForceVersionUpdate = false; }; } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs index 4a75c137b..76aee9cde 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/ViewModels/DataStoreViewVM.cs @@ -1,12 +1,17 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Windows.Data; +using Tango.Core.Commands; using Tango.Core.DI; +using Tango.DataStore; using Tango.DataStore.Editing; using Tango.FSE.Common; using Tango.FSE.Common.DataStore; +using Tango.FSE.MachineConfiguration.Dialogs; using Tango.FSE.MachineConfiguration.Messages; using static Tango.SharedUI.Controls.NavigationControl; @@ -15,6 +20,8 @@ namespace Tango.FSE.MachineConfiguration.ViewModels public class DataStoreViewVM : FSEViewModel, INavigationViewModel { private String machineGuid; + private ICollectionView _selectedCollectionView; + private ICollectionView _collectionsView; [TangoInject] private IDataStoreProvider DataStoreProvider { get; set; } @@ -30,7 +37,7 @@ namespace Tango.FSE.MachineConfiguration.ViewModels public DataStoreCollectionModel SelectedCollection { get { return _selectedCollection; } - set { _selectedCollection = value; RaisePropertyChangedAuto(); } + set { _selectedCollection = value; RaisePropertyChangedAuto(); OnSelectedCollectionChanged(); } } private DataStoreItemModel _selectedItem; @@ -40,16 +47,134 @@ namespace Tango.FSE.MachineConfiguration.ViewModels set { _selectedItem = value; RaisePropertyChangedAuto(); } } - private bool _isLoading; - public bool IsLoading + private String _filter; + public String Filter { - get { return _isLoading; } - set { _isLoading = value; RaisePropertyChangedAuto(); } + get { return _filter; } + set { _filter = value; RaisePropertyChangedAuto(); _selectedCollectionView?.Refresh(); } } + public RelayCommand<DataStoreItemModel> RemoveItemCommand { get; set; } + public RelayCommand<DataStoreCollectionModel> RemoveCollectionCommand { get; set; } + public RelayCommand AddItemCommand { get; set; } + public RelayCommand AddCollectionCommand { get; set; } + public RelayCommand<DataStoreItemModel> EditItemCommand { get; set; } + public RelayCommand SaveCommand { get; set; } + public RelayCommand ReloadCommand { get; set; } + public DataStoreViewVM() { RegisterForMessage<EditingCompositionLoadedMessage>(OnEditingCompositionLoaded); + RemoveItemCommand = new RelayCommand<DataStoreItemModel>(RemoveItem); + RemoveCollectionCommand = new RelayCommand<DataStoreCollectionModel>(RemoveCollection); + AddItemCommand = new RelayCommand(AddItem); + AddCollectionCommand = new RelayCommand(AddCollection); + EditItemCommand = new RelayCommand<DataStoreItemModel>(EditItem); + SaveCommand = new RelayCommand(SaveModel); + ReloadCommand = new RelayCommand(ReloadDataStore); + } + + private async void ReloadDataStore() + { + if (DataStore != null) + { + if (DataStore.Collections.SelectMany(x => x.Items).Any(x => x.HasDifference)) + { + if (!await NotificationProvider.ShowWarningQuestion("Reloading the data store will discard all the current changes. Are you sure?", "RELOAD")) + { + return; + } + } + } + + await LoadDataStore(); + } + + private async void EditItem(DataStoreItemModel item) + { + var vm = await NotificationProvider.ShowDialog<DataStoreItemEditDialogViewVM>(new DataStoreItemEditDialogViewVM() { Item = item, EnableTypeChange = !item.IsGlobal }); + + if (vm.DialogResult) + { + item.IsDeleted = false; + item.IsGlobal = false; + item.Type = vm.Type; + item.Value = vm.Value; + } + } + + private async void AddCollection() + { + var result = await NotificationProvider.ShowInputBox("Add Collection", "Please enter the collection name", MaterialDesignThemes.Wpf.PackIconKind.Collection, null, null, 20, null, null, (input) => + { + if (DataStore.Collections.ToList().Exists(x => x.Name.ToLower() == input.ToLower())) + { + return "The specified collection already exists."; + } + + return null; + }); + + if (result.Confirmed) + { + if (DataStore.Collections.ToList().Exists(x => x.Name.ToLower() == result.Input.ToLower())) + { + await NotificationProvider.ShowError("The specified collection already exists."); + AddCollection(); + return; + } + + DataStore.Collections.Add(new DataStoreCollectionModel() + { + Name = result.Input + }); + + SelectedCollection = DataStore.Collections.Last(); + } + } + + private async void AddItem() + { + var result = await NotificationProvider.ShowInputBox("Add Item", "Please enter the item key", MaterialDesignThemes.Wpf.PackIconKind.KeyAdd, null, null, 20, null, null, (input) => + { + if (SelectedCollection.Items.ToList().Exists(x => x.Key.ToLower() == input.ToLower())) + { + return "The specified key already exists in the collection."; + } + + return null; + }); + + if (result.Confirmed) + { + if (SelectedCollection.Items.ToList().Exists(x => x.Key == result.Input)) + { + await NotificationProvider.ShowError("The specified key already exists in the collection."); + AddItem(); + return; + } + + SelectedCollection.Items.Add(new DataStoreItemModel() + { + Date = DateTime.UtcNow, + Guid = Guid.NewGuid().ToString(), + Key = result.Input, + Type = DataType.Int32, + Value = 10 + }); + } + } + + private void RemoveCollection(DataStoreCollectionModel collection) + { + collection.IsDeleted = true; + _collectionsView?.Refresh(); + } + + private void RemoveItem(DataStoreItemModel item) + { + item.IsDeleted = true; + _selectedCollectionView.Refresh(); } private void OnEditingCompositionLoaded(EditingCompositionLoadedMessage obj) @@ -58,28 +183,87 @@ namespace Tango.FSE.MachineConfiguration.ViewModels machineGuid = obj.EditingComposition.Machine.Guid; } - public async override void OnNavigatedTo() + private void OnSelectedCollectionChanged() { - base.OnNavigatedTo(); + if (SelectedCollection != null) + { + _selectedCollectionView = CollectionViewSource.GetDefaultView(SelectedCollection.Items); + _selectedCollectionView.Filter = (x) => FilterItems(x as DataStoreItemModel); + _selectedCollectionView.Refresh(); + } + } - if (DataStore == null) + private bool FilterItems(DataStoreItemModel itemModel) + { + return (!itemModel.IsDeleted || itemModel.GlobalItem != null) && (String.IsNullOrWhiteSpace(Filter) || itemModel.Key.ToLower().Contains(Filter.ToLower())); + } + + private async void SaveModel() + { + try { - try + using (NotificationProvider.PushTaskItem("Updating data store...")) { - IsLoading = true; - IsFree = false; - DataStore = await DataStoreProvider.GetDataStoreModel(machineGuid); + await DataStoreProvider.UpdateDataStoreModel(DataStore, machineGuid); } - catch (Exception ex) + + if (MachineProvider.IsPPCAvailable) { - LogManager.Log(ex, "Error loading data store."); + await NotificationProvider.ShowSuccess("The connected machine is now synchronized with the data store."); } - finally + else { - IsLoading = false; + await NotificationProvider.ShowInfo("Data store save successfully.\nThe machine will be updated on the next synchronization pass."); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error saving data store."); + await NotificationProvider.ShowError($"Error occurred while trying to save the data store.\n{ex.FlattenMessage()}"); + return; + } + + await LoadDataStore(); + } + + private async Task LoadDataStore() + { + try + { + using (NotificationProvider.PushTaskItem("Loading data store...")) + { + IsFree = false; + var dataStore = await DataStoreProvider.GetDataStoreModel(machineGuid); + + _collectionsView = CollectionViewSource.GetDefaultView(dataStore.Collections); + _collectionsView.Filter = (x) => { return !(x as DataStoreCollectionModel).IsDeleted; }; + _collectionsView.Refresh(); + + DataStore = dataStore; + SelectedCollection = DataStore.Collections.FirstOrDefault(); + IsFree = true; } } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading data store."); + if (await NotificationProvider.ShowWarningQuestion($"Error occurred while trying to load the data store.\n{ex.FlattenMessage()}", "RETRY", "CANCEL")) + { + await LoadDataStore(); + return; + } + } + } + + public async override void OnNavigatedTo() + { + base.OnNavigatedTo(); + + if (DataStore == null) + { + await LoadDataStore(); + } } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/ConfigurationView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/ConfigurationView.xaml index 9c8b2d878..ed24c3a67 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/ConfigurationView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/ConfigurationView.xaml @@ -114,18 +114,18 @@ <GroupBox Margin="0 20" Style="{StaticResource FSE_Game_GroupBox}" Header="Machine Update"> <StackPanel Margin="0 10 0 5"> - <DockPanel ToolTip="Perform or skip firmware upgrade when updating"> - <ToggleButton material:ToggleButtonAssist.SwitchTrackOnBackground="{StaticResource FSE_PrimaryBackgroundLighterBrush}" IsChecked="{Binding EditingComposition.Machine.SetupFirmware}" /> - <TextBlock VerticalAlignment="Center" Margin="10 0 0 0">Perform Firmware Upgrade</TextBlock> + <DockPanel ToolTip="Prevent firmware upgrade when updating"> + <ToggleButton material:ToggleButtonAssist.SwitchTrackOnBackground="{StaticResource FSE_PrimaryBackgroundLighterBrush}" IsChecked="{Binding EditingComposition.Machine.SetupFirmware,Converter={StaticResource BooleanInverseConverter}}" /> + <TextBlock VerticalAlignment="Center" Margin="10 0 0 0">Disable Firmware Upgrade</TextBlock> </DockPanel> <DockPanel Margin="0 20 0 0" ToolTip="Force the machine to perform an update even if there is no update available"> - <ToggleButton IsEnabled="{Binding EditingComposition.Machine.SuspendVersionUpdate,Converter={StaticResource BooleanInverseConverter}}" IsChecked="{Binding EditingComposition.Machine.ForceVersionUpdate}" /> + <ToggleButton IsChecked="{Binding EditingComposition.Machine.ForceVersionUpdate}" /> <TextBlock VerticalAlignment="Center" Margin="10 0 0 0">Force Version Update</TextBlock> </DockPanel> <DockPanel Margin="0 20 0 0" ToolTip="Prevent this machine from updating software"> - <ToggleButton IsEnabled="{Binding EditingComposition.Machine.ForceVersionUpdate,Converter={StaticResource BooleanInverseConverter}}" IsChecked="{Binding EditingComposition.Machine.SuspendVersionUpdate}" /> + <ToggleButton IsChecked="{Binding EditingComposition.Machine.SuspendVersionUpdate}" /> <TextBlock VerticalAlignment="Center" Margin="10 0 0 0">Suspend Version Update</TextBlock> </DockPanel> </StackPanel> diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/DataStoreView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/DataStoreView.xaml index f078efcee..f4029e30c 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/DataStoreView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/DataStoreView.xaml @@ -4,7 +4,9 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Tango.FSE.MachineConfiguration.Views" + xmlns:helpers="clr-namespace:Tango.SharedUI.Helpers;assembly=Tango.SharedUI" xmlns:global="clr-namespace:Tango.FSE.MachineConfiguration" + xmlns:controls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common" xmlns:vm="clr-namespace:Tango.FSE.MachineConfiguration.ViewModels" xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:commonControls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common" @@ -16,61 +18,213 @@ <UserControl.Resources> <converters:DataStoreValueToStringConverter x:Key="DataStoreValueToStringConverter" /> </UserControl.Resources> - - <Grid Margin="100"> - <DockPanel> - <ListBox ItemsSource="{Binding DataStore.Collections}" SelectedItem="{Binding SelectedCollection}" MinWidth="200"> - <ListBox.ItemTemplate> - <DataTemplate> + + <DockPanel Margin="0 10 0 0"> + + <DockPanel DockPanel.Dock="Top"> + <DockPanel DockPanel.Dock="Top" HorizontalAlignment="Left"> + <Image Source="../Images/data_collection.png" Stretch="Uniform" Width="40" RenderOptions.BitmapScalingMode="Fant" Opacity="0.5" /> + <DockPanel Margin="10 0 0 0" > + <TextBlock Margin="0 5 0 0" FontSize="{StaticResource FSE_SmallFontSize}" Foreground="{StaticResource FSE_GrayBrush}"> + <Run>The data store contains global and local (machine) configuration and calibration parameters.</Run> + <LineBreak/> + <Run>Updating the data store parameters will take effect on the next machine cloud synchronization pass.</Run> + <LineBreak/> + <Run>If this is the currently connected machine, updating the data store will take effect immediately.</Run> + </TextBlock> + </DockPanel> + </DockPanel> + </DockPanel> + + <DockPanel Margin="0 20 0 0"> + <DockPanel DockPanel.Dock="Bottom" > + + <Grid DockPanel.Dock="Left"> + <DockPanel VerticalAlignment="Center" Visibility="{Binding MachineProvider.IsPPCAvailable,Converter={StaticResource BooleanToVisibilityConverter}}"> + <material:PackIcon Kind="InfoCircleOutline" Foreground="{StaticResource FSE_GreenBrush}" /> + <TextBlock FontSize="{StaticResource FSE_SmallFontSize}" Foreground="{StaticResource FSE_GreenBrush}" VerticalAlignment="Center" Margin="5 2 0 0">Machine is connected, updating the data store will be take effect immediately.</TextBlock> + </DockPanel> + </Grid> + + <StackPanel DockPanel.Dock="Right" Orientation="Horizontal" Margin="0 10 0 5"> + <Button IsEnabled="{Binding IsFree}" ToolTip="Import a data store csv file" Width="120" VerticalAlignment="Center" Margin="0 0 10 0" Height="35" material:ButtonAssist.CornerRadius="18" Style="{StaticResource FSE_RaisedButton_Dark_Hover}" Command="{Binding ImportCommand}"> + <DockPanel> + <material:PackIcon Kind="Import" /> + <TextBlock Margin="5 0 0 0">IMPORT</TextBlock> + </DockPanel> + </Button> + <Button IsEnabled="{Binding IsFree}" ToolTip="Export this data store to a csv file" Width="120" VerticalAlignment="Center" Margin="0 0 10 0" Height="35" material:ButtonAssist.CornerRadius="18" Style="{StaticResource FSE_RaisedButton_Dark_Hover}" Command="{Binding ExportCommand}"> + <DockPanel> + <material:PackIcon Kind="Export" /> + <TextBlock Margin="5 0 0 0">EXPORT</TextBlock> + </DockPanel> + </Button> + <Button ToolTip="Apply the data store changes" IsEnabled="{Binding IsFree}" Width="200" Height="45" material:ButtonAssist.CornerRadius="25" Command="{Binding SaveCommand}"> <DockPanel> - <material:PackIcon Kind="Collection" /> - <TextBlock Margin="10 0 0 0" VerticalAlignment="Center" Text="{Binding Name}"></TextBlock> + <material:PackIcon Kind="ContentSaveAll" /> + <TextBlock Margin="5 0 0 0"> + <TextBlock.Style> + <Style TargetType="TextBlock"> + <Setter Property="Text" Value="UPDATE"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding MachineProvider.IsPPCAvailable}" Value="True"> + <Setter Property="Text" Value="UPDATE & SYNC"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </TextBlock.Style> + </TextBlock> </DockPanel> - </DataTemplate> - </ListBox.ItemTemplate> - </ListBox> + </Button> + </StackPanel> + + <Grid> + <!--FOOTER CENTER CONTENT--> + </Grid> + </DockPanel> + <Grid> + <DockPanel> + + <Grid DockPanel.Dock="Top" Panel.ZIndex="100"> + <!--TOP BAR--> + + <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0 0 5 -45"> + <DockPanel Margin="0 0 20 0" VerticalAlignment="Center"> + <material:PackIcon Kind="Search" resolution:ResolutionHelper.Mode="High" Foreground="{StaticResource FSE_PrimaryAccentBrush}" VerticalAlignment="Center" Width="24" Height="24" Margin="0 0 5 0" /> + <TextBox IsEnabled="{Binding IsFree}" material:HintAssist.Hint="Search" Text="{Binding Filter,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,Delay=500}" Background="{StaticResource FSE_PrimaryBackgroundBrush}" Width="250" Style="{StaticResource FSE_Rounded_Corners_TextBox}" Height="33"></TextBox> + </DockPanel> + <controls:TextIconButton IsEnabled="{Binding IsFree}" material:ButtonAssist.CornerRadius="15" Command="{Binding AddItemCommand}" Icon="Add" Width="150">ADD ITEM</controls:TextIconButton> + <commonControls:IconButton Margin="10 0 0 0" Icon="Refresh" Cursor="Hand" ToolTip="Reload the data store" Command="{Binding ReloadCommand}" /> + </StackPanel> + </Grid> + + <DockPanel> + <!--<TextBlock Margin="0 -25 0 0" DockPanel.Dock="Top" FontFamily="{StaticResource hand}" Foreground="{StaticResource FSE_PrimaryAccentBrush}" FontSize="{StaticResource FSE_LargerFontSize}">Collections</TextBlock>--> + + <DockPanel> + + <Border DockPanel.Dock="Bottom" Height="50" Background="#404040" CornerRadius="0 0 5 5"> + <controls:TextIconButton IsEnabled="{Binding IsFree}" material:ButtonAssist.CornerRadius="15" Command="{Binding AddCollectionCommand}" Icon="Add" Width="180">ADD COLLECTION</controls:TextIconButton> + </Border> + + <Border Padding="8" Background="{StaticResource FSE_PrimaryBackgroundMidBrush}" CornerRadius="5 5 0 0" BorderThickness="1" BorderBrush="{StaticResource FSE_PrimaryBackgroundLightBrush}"> + <ListBox IsEnabled="{Binding IsFree}" ItemsSource="{Binding DataStore.Collections}" SelectedItem="{Binding SelectedCollection}" MinWidth="200" HorizontalContentAlignment="Stretch"> + <ListBox.ItemTemplate> + <DataTemplate> + <DockPanel> + <material:PackIcon Kind="Collection" /> + <controls:IconButton DockPanel.Dock="Right" HorizontalAlignment="Right" ToolTip="Delete collection" Cursor="Hand" Width="20" Height="20" Padding="0" Icon="Close" Foreground="{StaticResource FSE_RedBrush}" Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.RemoveCollectionCommand}" CommandParameter="{Binding}" /> + <TextBlock Margin="10 0 0 0" VerticalAlignment="Center" Text="{Binding Name}"></TextBlock> + </DockPanel> + </DataTemplate> + </ListBox.ItemTemplate> + </ListBox> + </Border> + </DockPanel> + </DockPanel> + + <Grid Margin="10 0 0 0"> + <Border Background="#8B202020" Padding="0 0 0 5" CornerRadius="5" BorderThickness="1" BorderBrush="{StaticResource FSE_PrimaryBackgroundLightBrush}"> + <Grid> + <Border VerticalAlignment="Top" Background="{StaticResource FSE_PrimaryBackgroundLightBrush}" Height="47" CornerRadius="5 5 0 0"> - <Grid Margin="10 0 0 0"> - <DataGrid IsReadOnly="True" AutoGenerateColumns="False" Style="{StaticResource FSE_DataGrid}" CellStyle="{StaticResource FSE_DataGrid_Cell}" CanUserReorderColumns="False" CanUserSortColumns="False" ItemsSource="{Binding SelectedCollection.Items}" SelectedItem="{Binding SelectedItem}"> - <DataGrid.Columns> - <DataGridTemplateColumn> - <DataGridTemplateColumn.CellTemplate> - <DataTemplate> - <material:PackIcon Kind="Key" Width="32" /> - </DataTemplate> - </DataGridTemplateColumn.CellTemplate> - </DataGridTemplateColumn> - <DataGridTemplateColumn Header="KEY" Width="Auto"> - <DataGridTemplateColumn.CellTemplate> - <DataTemplate> - <TextBlock Text="{Binding Key}"></TextBlock> - </DataTemplate> - </DataGridTemplateColumn.CellTemplate> - </DataGridTemplateColumn> - <DataGridTemplateColumn Header="TYPE" Width="Auto"> - <DataGridTemplateColumn.CellTemplate> - <DataTemplate> - <TextBlock Text="{Binding Type}"></TextBlock> - </DataTemplate> - </DataGridTemplateColumn.CellTemplate> - </DataGridTemplateColumn> - <DataGridTemplateColumn Header="GLOBAL VALUE" Width="Auto"> - <DataGridTemplateColumn.CellTemplate> - <DataTemplate> - <TextBlock Text="{Binding GlobalItem,Converter={StaticResource DataStoreValueToStringConverter},TargetNullValue='N/A'}"></TextBlock> - </DataTemplate> - </DataGridTemplateColumn.CellTemplate> - </DataGridTemplateColumn> - <DataGridTemplateColumn Header="LOCAL VALUE" Width="1*"> - <DataGridTemplateColumn.CellTemplate> - <DataTemplate> - <TextBlock Text="{Binding Converter={StaticResource DataStoreValueToStringConverter},TargetNullValue='N/A'}"></TextBlock> - </DataTemplate> - </DataGridTemplateColumn.CellTemplate> - </DataGridTemplateColumn> - </DataGrid.Columns> - </DataGrid> + </Border> + <DataGrid IsEnabled="{Binding IsFree}" IsReadOnly="True" helpers:DataGridHelper.DoubleClickCommand="{Binding EditItemCommand}" AutoGenerateColumns="False" Style="{StaticResource FSE_DataGrid}" CellStyle="{StaticResource FSE_DataGrid_Cell}" CanUserReorderColumns="False" CanUserSortColumns="False" ItemsSource="{Binding SelectedCollection.Items}" SelectedItem="{Binding SelectedItem}"> + <DataGrid.Columns> + <DataGridTemplateColumn Width="50"> + <DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <material:PackIcon Kind="Key" Width="32" /> + </DataTemplate> + </DataGridTemplateColumn.CellTemplate> + </DataGridTemplateColumn> + <DataGridTemplateColumn Header="KEY" Width="Auto"> + <DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <TextBlock Text="{Binding Key}"></TextBlock> + </DataTemplate> + </DataGridTemplateColumn.CellTemplate> + </DataGridTemplateColumn> + <DataGridTemplateColumn Header="TYPE" Width="Auto"> + <DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <TextBlock Text="{Binding Type}"> + <TextBlock.Style> + <Style TargetType="TextBlock"> + <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryForegroundBrush}"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding Type}" Value="Boolean"> + <Setter Property="Foreground" Value="#FF9BFF"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Type}" Value="Bytes"> + <Setter Property="Foreground" Value="#FFFBA3"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Type}" Value="Double"> + <Setter Property="Foreground" Value="#85B1FF"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Type}" Value="Float"> + <Setter Property="Foreground" Value="#FFDCB8"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Type}" Value="Int32"> + <Setter Property="Foreground" Value="#FF858D "></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Type}" Value="String"> + <Setter Property="Foreground" Value="#B9FFA5"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Type}" Value="Proto"> + <Setter Property="Foreground" Value="#A5FFF9"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </TextBlock.Style> + </TextBlock> + </DataTemplate> + </DataGridTemplateColumn.CellTemplate> + </DataGridTemplateColumn> + <DataGridTemplateColumn Header="GLOBAL" Width="Auto"> + <DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <TextBlock Text="{Binding GlobalItem,Converter={StaticResource DataStoreValueToStringConverter},TargetNullValue='-'}"></TextBlock> + </DataTemplate> + </DataGridTemplateColumn.CellTemplate> + </DataGridTemplateColumn> + <DataGridTemplateColumn Header="LOCAL" Width="1*"> + <DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <TextBlock Text="{Binding FormattedValue,Converter={StaticResource StringToOneLineConverter},ConverterParameter='100',Mode=OneWay}" Visibility="{Binding IsDeleted,Converter={StaticResource BooleanToVisibilityInverseConverter}}"> + <TextBlock.Style> + <Style TargetType="TextBlock"> + <Setter Property="FontWeight" Value="Normal"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding HasDifference}" Value="True"> + <Setter Property="FontWeight" Value="Bold"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </TextBlock.Style> + </TextBlock> + </DataTemplate> + </DataGridTemplateColumn.CellTemplate> + </DataGridTemplateColumn> + <DataGridTemplateColumn Width="100"> + <DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <UniformGrid Columns="2"> + <controls:IconButton ToolTip="Edit local value" Cursor="Hand" Width="20" Padding="0" Height="20" Icon="Edit" Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.EditItemCommand}" CommandParameter="{Binding}" /> + <Grid IsEnabled="{Binding IsGlobal,Converter={StaticResource BooleanInverseConverter}}"> + <controls:IconButton ToolTip="Delete local" IsEnabled="{Binding IsDeleted,Converter={StaticResource BooleanInverseConverter}}" Cursor="Hand" Width="20" Height="20" Padding="0" Icon="Close" Foreground="{StaticResource FSE_RedBrush}" Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.RemoveItemCommand}" CommandParameter="{Binding}" /> + </Grid> + </UniformGrid> + </DataTemplate> + </DataGridTemplateColumn.CellTemplate> + </DataGridTemplateColumn> + </DataGrid.Columns> + </DataGrid> + </Grid> + </Border> + </Grid> + </DockPanel> </Grid> </DockPanel> - </Grid> + </DockPanel> </UserControl> diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/MachineView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/MachineView.xaml index 9f81f82e4..ca6470db3 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/MachineView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.MachineConfiguration/Views/MachineView.xaml @@ -12,14 +12,14 @@ d:DesignHeight="1080" d:DesignWidth="1920" d:DataContext="{d:DesignInstance Type=vm:MachineViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MachineViewVM}" d:DesignStyle="{StaticResource FSE_User_Control_Designer}"> <Grid> - <Grid Margin="10"> + <Grid Margin="0 20 0 0"> <Grid> <Grid.Style> <Style TargetType="Grid"> - <Setter Property="Margin" Value="100 40"></Setter> + <Setter Property="Margin" Value="100 0"></Setter> <Style.Triggers> <DataTrigger Binding="{Binding ResolutionService.IsLowResolution}" Value="True"> - <Setter Property="Margin" Value="20"></Setter> + <Setter Property="Margin" Value="10"></Setter> </DataTrigger> </Style.Triggers> </Style> diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Themes/Generic.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Themes/Generic.xaml index 3917368f2..0e055d730 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Themes/Generic.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Themes/Generic.xaml @@ -635,7 +635,6 @@ </Style.Triggers> </Style> - <Style x:Key="FSE_Debug_TextBoxStyle" TargetType="TextBox"> <Setter Property="Background" Value="Transparent"></Setter> <Setter Property="BorderBrush" Value="{StaticResource FSE_BorderBrush}"></Setter> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/DataStoreService.cs b/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/DataStoreService.cs index 41ab7725b..2dd29fdc4 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/DataStoreService.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/DataStoreService.cs @@ -28,7 +28,7 @@ namespace Tango.FSE.BL.Services { using (ObservablesContext db = ObservablesContext.CreateDefault()) { - return db.DataStoreItems.Where(x => x.MachineGuid == machineGuid).ToList().OrderBy(x => x.CollectionName).OrderBy(x => x.Key).ToList(); + return db.DataStoreItems.Where(x => x.MachineGuid == machineGuid && !x.IsDeleted).ToList().OrderBy(x => x.CollectionName).OrderBy(x => x.Key).ToList(); } }); } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/MachineConfigurationService.cs b/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/MachineConfigurationService.cs index e6798e197..a30198ff2 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/MachineConfigurationService.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/MachineConfigurationService.cs @@ -68,6 +68,8 @@ namespace Tango.FSE.BL.Services { return Task.Factory.StartNew<MachineEditingComposition>(() => { + composition.Machine.SetupFpga = composition.Machine.SetupFirmware; + composition.Context.SaveChanges(); composition.Context.Dispose(); return GetMachineEditingComposition(composition.Machine.Guid).Result; diff --git a/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/MachinesService.cs b/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/MachinesService.cs index 6f598a770..c03077a45 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/MachinesService.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/MachinesService.cs @@ -73,7 +73,6 @@ namespace Tango.FSE.BL.Services LogManager.Log("Machine retrieved successfully. Caching machine..."); var cachedMachine = CachedMachine.FromObservable<CachedMachine>(machine); - var m = cachedMachine.ToObservable(); //Store in memory cache. _machinesCache.Put(serialNumber, cachedMachine); @@ -271,12 +270,24 @@ namespace Tango.FSE.BL.Services List<CachedMachine> cachedMachines = new List<CachedMachine>(); - try + foreach (var machine in machines) { - foreach (var machine in machines) + try { var cachedMachine = CachedMachine.FromObservable<CachedMachine>(machine); - _machinesCache.Put(machine.SerialNumber, cachedMachine); + cachedMachines.Add(cachedMachine); + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error creating cached machine (partial) '{machine.SerialNumber}'."); + } + } + + try + { + foreach (var cachedMachine in cachedMachines) + { + _machinesCache.Put(cachedMachine.SerialNumber, cachedMachine); } } catch (Exception ex) @@ -292,7 +303,14 @@ namespace Tango.FSE.BL.Services foreach (var cachedMachine in cachedMachines) { - collection.Upsert(cachedMachine); + try + { + collection.Upsert(cachedMachine); + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error caching machine '{cachedMachine.SerialNumber}' (partial) to disk."); + } } } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/DataStore/IDataStoreProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/DataStore/IDataStoreProvider.cs index bab513e36..36e026317 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/DataStore/IDataStoreProvider.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/DataStore/IDataStoreProvider.cs @@ -10,5 +10,6 @@ namespace Tango.FSE.Common.DataStore public interface IDataStoreProvider { Task<DataStoreModel> GetDataStoreModel(String machineGuid); + Task<DataStoreModel> UpdateDataStoreModel(DataStoreModel model, String machineGuid); } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/INotificationProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/INotificationProvider.cs index 3c7350be7..027555022 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/INotificationProvider.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/INotificationProvider.cs @@ -138,7 +138,7 @@ namespace Tango.FSE.Common.Notifications /// <param name="okText">The ok text.</param> /// <param name="cancelText">The cancel text.</param> /// <returns></returns> - Task<InputBoxResult> ShowInputBox(String title, String message, PackIconKind icon = PackIconKind.InfoOutline, String defaultInput = null, String inputHint = null, int? maxChars = null, String okText = null, String cancelText = null); + Task<InputBoxResult> ShowInputBox(String title, String message, PackIconKind icon = PackIconKind.InfoOutline, String defaultInput = null, String inputHint = null, int? maxChars = null, String okText = null, String cancelText = null, Func<String, String> validationFunc = null); /// <summary> /// Shows a question message box. diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/InputBoxVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/InputBoxVM.cs index 7744d04d0..415c6cfc5 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/InputBoxVM.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Notifications/InputBoxVM.cs @@ -14,11 +14,45 @@ namespace Tango.FSE.Common.Notifications public int MaxCharacters { get; set; } + internal Func<String,String> ValidationFunction { get; set; } + private String _input; public String Input { get { return _input; } - set { _input = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + set + { + _input = value; + RaisePropertyChangedAuto(); + + if (_input.IsNotNullOrEmpty()) + { + if (ValidationFunction != null) + { + Error = ValidationFunction.Invoke(_input); + } + } + else + { + Error = null; + } + + RaisePropertyChanged(nameof(HasValidationError)); + + InvalidateRelayCommands(); + } + } + + public bool HasValidationError + { + get { return !String.IsNullOrWhiteSpace(Error); } + } + + private String _error; + public String Error + { + get { return _error; } + set { _error = value; RaisePropertyChangedAuto(); } } public InputBoxVM() : base() @@ -28,7 +62,7 @@ namespace Tango.FSE.Common.Notifications protected override bool CanOK() { - return base.CanOK() && Input.IsNotNullOrEmpty(); + return base.CanOK() && Input.IsNotNullOrEmpty() && !HasValidationError; } } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml index 2b7ea3640..4b5d8f8d2 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml @@ -896,7 +896,7 @@ </Border.Effect> <DockPanel> <TextBox x:Name="txt" KeyboardNavigation.DirectionalNavigation="Once" DockPanel.Dock="Top" Margin="10" Padding="0 5" Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=SearchFilter,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBox> - <ListBox x:Name="list" FocusVisualStyle="{x:Null}" ItemsSource="{TemplateBinding ListItemsSource}" ItemTemplate="{TemplateBinding ItemTemplate}" SelectedValue="{TemplateBinding SelectedValue}" SelectedValuePath="{TemplateBinding SelectedValuePath}" DisplayMemberPath="{TemplateBinding DisplayMemberPath}"> + <ListBox x:Name="list" FocusVisualStyle="{x:Null}" ItemsSource="{TemplateBinding ListItemsSource}" ItemTemplate="{TemplateBinding ItemTemplate}" DisplayMemberPath="{TemplateBinding DisplayMemberPath}"> </ListBox> </DockPanel> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Controls/NotificationsControl.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Controls/NotificationsControl.xaml index 4e6ada6b5..4a2510552 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Controls/NotificationsControl.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Controls/NotificationsControl.xaml @@ -336,10 +336,14 @@ <commonControls:IconButton Icon="Close" Padding="5" Cursor="Hand" Margin="0 0 5 0" Command="{Binding CloseCommand}" CommandParameter="{Binding}" HorizontalAlignment="Right" Width="{Binding RelativeSource={RelativeSource Self},Path=ActualHeight}"/> </Grid> - <StackPanel Grid.Row="1" Margin="40" VerticalAlignment="Top"> - <TextBlock Foreground="{StaticResource FSE_PrimaryForegroundBrush}" Text="{Binding Message}" TextWrapping="Wrap"></TextBlock> - <TextBox x:Name="txtInput" KeyDown="TxtInput_KeyDown" Margin="0 20 0 0" Text="{Binding Input,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" MaxLength="{Binding MaxCharacters}" material:HintAssist.Hint="{Binding InputHint}" /> - </StackPanel> + <Grid Grid.Row="1" Margin="40" VerticalAlignment="Top"> + <StackPanel> + <TextBlock Foreground="{StaticResource FSE_PrimaryForegroundBrush}" Text="{Binding Message}" TextWrapping="Wrap"></TextBlock> + <TextBox x:Name="txtInput" KeyDown="TxtInput_KeyDown" Margin="0 20 0 0" Text="{Binding Input,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" MaxLength="{Binding MaxCharacters}" material:HintAssist.Hint="{Binding InputHint}" /> + </StackPanel> + + <TextBlock VerticalAlignment="Bottom" Margin="0 0 0 -20" TextWrapping="Wrap" Foreground="{StaticResource FSE_ErrorBrush}" FontSize="{StaticResource FSE_SmallFontSize}" Text="{Binding Error}" Visibility="{Binding HasValidationError,Converter={StaticResource BooleanToVisibilityConverter}}"></TextBlock> + </Grid> <StackPanel HorizontalAlignment="Right" Grid.Row="2" Margin="10" Orientation="Horizontal"> <Button MinWidth="150" x:Name="btnInputCancel" Height="Auto" Style="{StaticResource FSE_RaisedButton_Dark_Hover}" Margin="0 0 10 0" Command="{Binding CloseCommand}" Visibility="{Binding HasCancel,Converter={StaticResource BooleanToVisibilityConverter}}" Content="{Binding CancelText}"></Button> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/DefaultDataStoreProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/DefaultDataStoreProvider.cs index 6239a33d9..8c22d8d36 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/DefaultDataStoreProvider.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/DefaultDataStoreProvider.cs @@ -3,10 +3,13 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.BL; +using Tango.BL.DTO; using Tango.BL.Entities; using Tango.Core.DI; using Tango.DataStore; using Tango.DataStore.Editing; +using Tango.DataStore.EF; using Tango.DataStore.Remote; using Tango.FSE.BL; using Tango.FSE.Common.Connection; @@ -75,9 +78,15 @@ namespace Tango.FSE.UI.DataStore { var localItem = collectionModel.Items.FirstOrDefault(x => x.Key == remoteItem.Key); + if (localItem != null) + { + localItem.ExistsOnMachine = true; + } + if (localItem != null && remoteItem.Date > localItem.Date) { localItem.Value = remoteItem.Value; + localItem.OriginalValue = remoteItem.Value; localItem.Type = remoteItem.Type; localItem.Date = remoteItem.Date; } @@ -91,6 +100,7 @@ namespace Tango.FSE.UI.DataStore } DataStoreItemModel itemModel = DataStoreItemModel.FromLocalDataStoreItem(remoteItem, globalItem?.ToDataStoreItem()); + itemModel.ExistsOnMachine = true; collectionModel.Items.Add(itemModel); } @@ -120,5 +130,135 @@ namespace Tango.FSE.UI.DataStore return model; }); } + + private class SaveModel + { + public String CollectionName { get; set; } + public DataStoreItemModel Item { get; set; } + } + + public Task<DataStoreModel> UpdateDataStoreModel(DataStoreModel model, String machineGuid) + { + return Task.Factory.StartNew<DataStoreModel>(() => + { + List<SaveModel> globals = new List<SaveModel>(); + List<SaveModel> locals = new List<SaveModel>(); + List<SaveModel> deleted = new List<SaveModel>(); + UpdateDataStoreRequest updateRequest = new UpdateDataStoreRequest(); + + foreach (var collection in model.Collections.Where(x => !x.IsDeleted)) + { + foreach (var item in collection.Items) + { + if (item.IsGlobal) + { + globals.Add(new SaveModel() { CollectionName = collection.Name, Item = item }); + } + else if (item.IsDeleted) + { + deleted.Add(new SaveModel() { CollectionName = collection.Name, Item = item }); + } + else if (item.HasDifference || (MachineProvider.IsPPCAvailable && !item.ExistsOnMachine)) + { + locals.Add(new SaveModel() { CollectionName = collection.Name, Item = item }); + } + } + } + + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + var allItems = db.DataStoreItems.Where(x => x.MachineGuid == machineGuid).ToList(); + + //Deleted collections + foreach (var deletedCollection in model.Collections.Where(x => x.IsDeleted)) + { + foreach (var itemDb in allItems.ToList()) + { + if (itemDb.CollectionName == deletedCollection.Name) + { + itemDb.IsDeleted = true; + itemDb.LastUpdated = DateTime.UtcNow; + itemDb.IsSynchronized = false; + updateRequest.ToDelete.Add(itemDb.Guid); + } + } + } + + //Deleted items + foreach (var item in deleted) + { + var itemDb = allItems.FirstOrDefault(x => x.CollectionName == item.CollectionName && x.Key == item.Item.Key); + if (itemDb != null) + { + itemDb.IsDeleted = true; + itemDb.LastUpdated = DateTime.UtcNow; + itemDb.IsSynchronized = false; + updateRequest.ToDelete.Add(itemDb.Guid); + } + } + + //locals + foreach (var item in locals) + { + DataStoreItem itemDb = allItems.FirstOrDefault(x => x.CollectionName == item.CollectionName && x.Key == item.Item.Key); + + if (itemDb == null) //new local item. + { + itemDb = new DataStoreItem(); + itemDb.MachineGuid = machineGuid; + itemDb.CollectionName = item.CollectionName; + itemDb.Key = item.Item.Key; + itemDb.LastUpdated = DateTime.UtcNow; + itemDb.DataType = (int)item.Item.Type; + itemDb.Value = EFDataStoreHelper.CreateBytes(item.Item.Type, item.Item.Value); + db.DataStoreItems.Add(itemDb); + updateRequest.ToUpsert.Add(DataStoreItemDTO.FromObservable(itemDb)); + } + else //update local item only if changed... + { + bool upsert = MachineProvider.IsPPCAvailable && !item.Item.ExistsOnMachine; + + if (itemDb.IsDeleted) //restore if item was deleted.. + { + itemDb.IsDeleted = false; + itemDb.LastUpdated = DateTime.UtcNow; + itemDb.IsSynchronized = false; + upsert = true; + } + + //update item only if it has difference although "locals" already contains only differences. + var bytes = EFDataStoreHelper.CreateBytes(item.Item.Type, item.Item.Value); + + if (itemDb.DataType != (int)item.Item.Type || !Enumerable.SequenceEqual(itemDb.Value, bytes)) + { + itemDb.DataType = (int)item.Item.Type; + itemDb.Value = bytes; + itemDb.LastUpdated = DateTime.UtcNow; + itemDb.IsSynchronized = false; + upsert = true; + } + + if (upsert) + { + updateRequest.ToUpsert.Add(DataStoreItemDTO.FromObservable(itemDb)); + } + } + } + + if (MachineProvider.IsPPCAvailable) + { + //Direct Sync Here. + //Make all items "IsSynchronized = true" if success. + var response = MachineProvider.MachineOperator.SendGenericRequest<UpdateDataStoreRequest, UpdateDataStoreResponse>(updateRequest, new Transport.TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(30) }).Result; + + allItems.ForEach(x => x.IsSynchronized = true); + } + + db.SaveChanges(); + } + + return GetDataStoreModel(machineGuid).Result; + }); + } } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Notifications/DefaultNotificationProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Notifications/DefaultNotificationProvider.cs index 4992953c2..7299a836d 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Notifications/DefaultNotificationProvider.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Notifications/DefaultNotificationProvider.cs @@ -340,7 +340,7 @@ namespace Tango.FSE.UI.Notifications return source.Task; } - public Task<InputBoxResult> ShowInputBox(string title, string message, PackIconKind icon = PackIconKind.InformationOutline, string defaultInput = null, string inputHint = null, int? maxChars = null, string okText = null, string cancelText = null) + public Task<InputBoxResult> ShowInputBox(string title, string message, PackIconKind icon = PackIconKind.InformationOutline, string defaultInput = null, string inputHint = null, int? maxChars = null, string okText = null, string cancelText = null, Func<String, String> validationFunc = null) { TaskCompletionSource<InputBoxResult> source = new TaskCompletionSource<InputBoxResult>(); @@ -350,6 +350,8 @@ namespace Tango.FSE.UI.Notifications vm.Icon = icon; vm.Input = defaultInput; vm.InputHint = inputHint; + vm.ValidationFunction = validationFunc; + if (maxChars != null) { vm.MaxCharacters = maxChars.Value; diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs index 7c8cf4158..6cae220aa 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs @@ -18,6 +18,8 @@ using Tango.Transport; using Tango.Core.ExtensionMethods; using Newtonsoft.Json.Linq; using Tango.BL; +using Tango.DataStore.Editing; +using Newtonsoft.Json; namespace Tango.PPC.Common.DataStore { @@ -25,11 +27,14 @@ namespace Tango.PPC.Common.DataStore public class DefaultDataStoreService : IDataStoreService, IExternalBridgeRequestHandler { private IDataStoreManager _manager; + private IMachineProvider _machineProvider; public DefaultDataStoreService(IPPCExternalBridgeService externalBridge, IMachineProvider machineProvider) { externalBridge.RegisterRequestHandler(this); + + _machineProvider = machineProvider; machineProvider.MachineOperator.RegisterRequestHandler<PutDataStoreItemRequest>(OnPutDataStoreItemRequest); machineProvider.MachineOperator.RegisterRequestHandler<GetDataStoreItemRequest>(OnGetDataStoreItemRequest); } @@ -134,13 +139,13 @@ namespace Tango.PPC.Common.DataStore } [ExternalBridgeRequestHandlerMethod(typeof(RemoteDataStoreGetAllItemsRequest), RequestHandlerLoggingMode.LogRequestName)] - public async Task RemoteDataStoreGetAllItemsRequest(RemoteDataStoreGetAllItemsRequest request, String token, ExternalBridgeReceiver receiver) + public async Task OnRemoteDataStoreGetAllItemsRequest(RemoteDataStoreGetAllItemsRequest request, String token, ExternalBridgeReceiver receiver) { List<RemoteDataStoreCollection> collections = new List<RemoteDataStoreCollection>(); using (ObservablesContext db = ObservablesContext.CreateDefault()) { - var items = db.DataStoreItems.ToList(); + var items = db.DataStoreItems.Where(x => !x.IsDeleted).ToList(); foreach (var itemsGroup in items.GroupBy(x => x.CollectionName)) { @@ -161,6 +166,72 @@ namespace Tango.PPC.Common.DataStore }, token); } + [ExternalBridgeRequestHandlerMethod(typeof(UpdateDataStoreRequest), RequestHandlerLoggingMode.LogRequestName)] + public async Task OnUpdateDataStoreRequest(UpdateDataStoreRequest request, String token, ExternalBridgeReceiver receiver) + { + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + var allItems = db.DataStoreItems.ToList(); + + foreach (var guid in request.ToDelete) + { + var item = allItems.FirstOrDefault(x => x.Guid == guid); + if (item != null) + { + item.IsDeleted = true; + item.IsSynchronized = true; + item.LastUpdated = DateTime.UtcNow; + } + } + + foreach (var item in request.ToUpsert) + { + var itemDb = allItems.FirstOrDefault(x => x.Guid == item.Guid); + + if (itemDb == null) + { + itemDb = new BL.Entities.DataStoreItem(); + itemDb.Guid = item.Guid; + db.DataStoreItems.Add(itemDb); + } + + itemDb.CollectionName = item.CollectionName; + itemDb.DataType = item.DataType; + itemDb.IsDeleted = item.IsDeleted; + itemDb.IsSynchronized = true; + itemDb.Key = item.Key; + itemDb.LastUpdated = item.LastUpdated; + itemDb.Value = item.Value; + } + + db.SaveChanges(); + + if (_machineProvider.IsConnected) + { + Core.Threading.ThreadFactory.StartNew(() => + { + foreach (var item in request.ToUpsert) + { + try + { + var response = _machineProvider.MachineOperator.SendRequest<DataStoreItemModifiedRequest, DataStoreItemModifiedResponse>(new DataStoreItemModifiedRequest() + { + Collection = item.CollectionName, + Key = item.Key + }).Result; + } + catch (Exception ex) + { + Logging.LogManager.Default.Log(ex, $"Error notifying firmware about data store item change '{item.CollectionName}.{item.Key}'."); + } + } + }); + } + } + + await receiver.SendGenericResponse(new UpdateDataStoreResponse(), token); + } + private RemoteDataStoreItem CreateRemoteItem(IDataStoreItem item) { RemoteDataStoreItem remote = new RemoteDataStoreItem(); diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj index 3d7f11809..2ed04c904 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj @@ -383,6 +383,10 @@ <Project>{58e8825f-0c96-449c-b320-1e82b0aa876b}</Project> <Name>Tango.CSV</Name> </ProjectReference> + <ProjectReference Include="..\..\Tango.DataStore.Editing\Tango.DataStore.Editing.csproj"> + <Project>{ee088ff7-04d1-41fb-9d6a-cedeee7a7b9c}</Project> + <Name>Tango.DataStore.Editing</Name> + </ProjectReference> <ProjectReference Include="..\..\Tango.DataStore.EF\Tango.DataStore.EF.csproj"> <Project>{88d9906b-8fc4-4fe0-b7eb-127a0a8fcee4}</Project> <Name>Tango.DataStore.EF</Name> @@ -511,7 +515,7 @@ </Target> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" /> + <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" /> </VisualStudio> </ProjectExtensions> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Connectivity/DefaultConnectivityProvider.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Connectivity/DefaultConnectivityProvider.cs index fb5b9796f..5218d9f70 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Connectivity/DefaultConnectivityProvider.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Connectivity/DefaultConnectivityProvider.cs @@ -182,7 +182,7 @@ namespace Tango.PPC.UI.Connectivity || net.NetworkInterfaceType == NetworkInterfaceType.Ethernet3Megabit || net.NetworkInterfaceType == NetworkInterfaceType.FastEthernetFx || net.NetworkInterfaceType == NetworkInterfaceType.FastEthernetT - || net.NetworkInterfaceType == NetworkInterfaceType.GigabitEthernet) && net.Name == "Ethernet" && net.OperationalStatus == OperationalStatus.Up) + || net.NetworkInterfaceType == NetworkInterfaceType.GigabitEthernet) && net.Name.ToStringOrEmpty().StartsWith("Ethernet") && net.OperationalStatus == OperationalStatus.Up) { IsLanConnected = true; return; diff --git a/Software/Visual_Studio/Tango.BL/DTO/DataStoreItemDTOBase.cs b/Software/Visual_Studio/Tango.BL/DTO/DataStoreItemDTOBase.cs index 8a6bfd7a4..9951338ec 100644 --- a/Software/Visual_Studio/Tango.BL/DTO/DataStoreItemDTOBase.cs +++ b/Software/Visual_Studio/Tango.BL/DTO/DataStoreItemDTOBase.cs @@ -62,6 +62,14 @@ namespace Tango.BL.DTO } /// <summary> + /// is deleted + /// </summary> + public Boolean IsDeleted + { + get; set; + } + + /// <summary> /// is synchronized /// </summary> public Boolean IsSynchronized diff --git a/Software/Visual_Studio/Tango.BL/Entities/DataStoreItemBase.cs b/Software/Visual_Studio/Tango.BL/Entities/DataStoreItemBase.cs index c9c433e02..6d393f6a2 100644 --- a/Software/Visual_Studio/Tango.BL/Entities/DataStoreItemBase.cs +++ b/Software/Visual_Studio/Tango.BL/Entities/DataStoreItemBase.cs @@ -35,6 +35,8 @@ namespace Tango.BL.Entities public event EventHandler<Byte[]> ValueChanged; + public event EventHandler<Boolean> IsDeletedChanged; + public event EventHandler<Boolean> IsSynchronizedChanged; public event EventHandler<Machine> MachineChanged; @@ -173,6 +175,33 @@ namespace Tango.BL.Entities } } + protected Boolean _isdeleted; + + /// <summary> + /// Gets or sets the datastoreitembase is deleted. + /// </summary> + + [Column("IS_DELETED")] + + public Boolean IsDeleted + { + get + { + return _isdeleted; + } + + set + { + if (_isdeleted != value) + { + _isdeleted = value; + + OnIsDeletedChanged(value); + + } + } + } + protected Boolean _issynchronized; /// <summary> @@ -269,6 +298,15 @@ namespace Tango.BL.Entities } /// <summary> + /// Called when the IsDeleted has changed. + /// </summary> + protected virtual void OnIsDeletedChanged(Boolean isdeleted) + { + IsDeletedChanged?.Invoke(this, isdeleted); + RaisePropertyChanged(nameof(IsDeleted)); + } + + /// <summary> /// Called when the IsSynchronized has changed. /// </summary> protected virtual void OnIsSynchronizedChanged(Boolean issynchronized) diff --git a/Software/Visual_Studio/Tango.Core/ExtensionMethods/StringExtensions.cs b/Software/Visual_Studio/Tango.Core/ExtensionMethods/StringExtensions.cs index 97c8773d6..5a12e16bb 100644 --- a/Software/Visual_Studio/Tango.Core/ExtensionMethods/StringExtensions.cs +++ b/Software/Visual_Studio/Tango.Core/ExtensionMethods/StringExtensions.cs @@ -261,6 +261,11 @@ public static class StringExtensions return !String.IsNullOrWhiteSpace(str); } + public static String ToOneLine(this String str) + { + return str.Replace(Environment.NewLine, " "); + } + public static List<T> ToEnumValues<T>(this String str, char splitChar) where T : struct { if (!String.IsNullOrWhiteSpace(str)) diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/DATA_STORE_ITEMS.cs b/Software/Visual_Studio/Tango.DAL.Remote/DB/DATA_STORE_ITEMS.cs index ad42a6db8..6fcfe6a86 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/DATA_STORE_ITEMS.cs +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/DATA_STORE_ITEMS.cs @@ -22,6 +22,7 @@ namespace Tango.DAL.Remote.DB public string KEY { get; set; } public int DATA_TYPE { get; set; } public byte[] VALUE { get; set; } + public bool IS_DELETED { get; set; } public bool IS_SYNCHRONIZED { get; set; } public virtual MACHINE MACHINE { get; set; } diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx index 3b471ca54..13b409e05 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx @@ -266,6 +266,7 @@ <Property Name="KEY" Type="nvarchar" MaxLength="50" Nullable="false" /> <Property Name="DATA_TYPE" Type="int" Nullable="false" /> <Property Name="VALUE" Type="image" Nullable="false" /> + <Property Name="IS_DELETED" Type="bit" Nullable="false" /> <Property Name="IS_SYNCHRONIZED" Type="bit" Nullable="false" /> </EntityType> <EntityType Name="DISPENSER_TYPES"> @@ -3671,6 +3672,7 @@ <Property Name="KEY" Type="String" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" /> <Property Name="DATA_TYPE" Type="Int32" Nullable="false" /> <Property Name="VALUE" Type="Binary" Nullable="false" MaxLength="Max" FixedLength="false" /> + <Property Name="IS_DELETED" Type="Boolean" Nullable="false" /> <Property Name="IS_SYNCHRONIZED" Type="Boolean" Nullable="false" /> <NavigationProperty Name="MACHINE" Relationship="RemoteModel.FK_DATA_STORES_MACHINES" FromRole="DATA_STORE_ITEMS" ToRole="MACHINE" /> </EntityType> @@ -6294,6 +6296,7 @@ <EntityTypeMapping TypeName="RemoteModel.DATA_STORE_ITEMS"> <MappingFragment StoreEntitySet="DATA_STORE_ITEMS"> <ScalarProperty Name="IS_SYNCHRONIZED" ColumnName="IS_SYNCHRONIZED" /> + <ScalarProperty Name="IS_DELETED" ColumnName="IS_DELETED" /> <ScalarProperty Name="VALUE" ColumnName="VALUE" /> <ScalarProperty Name="DATA_TYPE" ColumnName="DATA_TYPE" /> <ScalarProperty Name="KEY" ColumnName="KEY" /> diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram index 357b569f8..e1c915039 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram @@ -5,90 +5,90 @@ <!-- Diagram content (shape and connector positions) --> <edmx:Diagrams> <Diagram DiagramId="f9ae01d708754bbd997add25a4bacc79" Name="Diagram1" ZoomLevel="87"> - <EntityTypeShape EntityType="RemoteModel.ACTION_LOGS" Width="1.5" PointX="11.25" PointY="27.25" /> - <EntityTypeShape EntityType="RemoteModel.ADDRESS" Width="1.5" PointX="1.5" PointY="76" /> - <EntityTypeShape EntityType="RemoteModel.APPLICATION_DISPLAY_PANEL_VERSIONS" Width="1.5" PointX="1.5" PointY="62" /> - <EntityTypeShape EntityType="RemoteModel.APPLICATION_FIRMWARE_VERSIONS" Width="1.5" PointX="1.5" PointY="56.125" /> - <EntityTypeShape EntityType="RemoteModel.APPLICATION_OS_VERSIONS" Width="1.5" PointX="1.5" PointY="64.875" /> + <EntityTypeShape EntityType="RemoteModel.ACTION_LOGS" Width="1.5" PointX="11.25" PointY="49.875" /> + <EntityTypeShape EntityType="RemoteModel.ADDRESS" Width="1.5" PointX="1.5" PointY="1.75" /> + <EntityTypeShape EntityType="RemoteModel.APPLICATION_DISPLAY_PANEL_VERSIONS" Width="1.5" PointX="4.5" PointY="59.25" /> + <EntityTypeShape EntityType="RemoteModel.APPLICATION_FIRMWARE_VERSIONS" Width="1.5" PointX="4.5" PointY="68" /> + <EntityTypeShape EntityType="RemoteModel.APPLICATION_OS_VERSIONS" Width="1.5" PointX="4.5" PointY="62.125" /> <EntityTypeShape EntityType="RemoteModel.BRUSH_STOPS" Width="1.5" PointX="15.75" PointY="17" /> - <EntityTypeShape EntityType="RemoteModel.CARTRIDGE_TYPES" Width="1.5" PointX="3.75" PointY="43.5" /> - <EntityTypeShape EntityType="RemoteModel.CAT" Width="1.5" PointX="8.25" PointY="19.875" /> - <EntityTypeShape EntityType="RemoteModel.CCT" Width="1.5" PointX="0.75" PointY="15.75" /> - <EntityTypeShape EntityType="RemoteModel.COLOR_CATALOGS" Width="1.5" PointX="1.5" PointY="7.625" /> - <EntityTypeShape EntityType="RemoteModel.COLOR_CATALOGS_GROUPS" Width="1.5" PointX="3.75" PointY="8.125" /> - <EntityTypeShape EntityType="RemoteModel.COLOR_CATALOGS_ITEMS" Width="1.5" PointX="6" PointY="6.875" /> - <EntityTypeShape EntityType="RemoteModel.COLOR_CATALOGS_ITEMS_RECIPES" Width="1.5" PointX="8.25" PointY="15.75" /> - <EntityTypeShape EntityType="RemoteModel.COLOR_SPACES" Width="1.5" PointX="9" PointY="33.5" /> - <EntityTypeShape EntityType="RemoteModel.CONFIGURATION" Width="1.5" PointX="3.75" PointY="61.75" /> - <EntityTypeShape EntityType="RemoteModel.CONTACT" Width="1.5" PointX="1.5" PointY="72.125" /> - <EntityTypeShape EntityType="RemoteModel.CUSTOMER" Width="1.5" PointX="9" PointY="11.5" /> - <EntityTypeShape EntityType="RemoteModel.DATA_STORE_ITEMS" Width="1.5" PointX="8.25" PointY="76.25" /> - <EntityTypeShape EntityType="RemoteModel.DISPENSER_TYPES" Width="1.5" PointX="1.5" PointY="36.5" /> - <EntityTypeShape EntityType="RemoteModel.DISPENSER" Width="1.5" PointX="3.75" PointY="35.875" /> - <EntityTypeShape EntityType="RemoteModel.EMBEDDED_FIRMWARE_VERSIONS" Width="1.5" PointX="1.5" PointY="59.125" /> - <EntityTypeShape EntityType="RemoteModel.EVENT_TYPES" Width="1.5" PointX="9" PointY="40.75" /> + <EntityTypeShape EntityType="RemoteModel.CARTRIDGE_TYPES" Width="1.5" PointX="6.75" PointY="36.625" /> + <EntityTypeShape EntityType="RemoteModel.CAT" Width="1.5" PointX="5.25" PointY="23.875" /> + <EntityTypeShape EntityType="RemoteModel.CCT" Width="1.5" PointX="0.75" PointY="26.625" /> + <EntityTypeShape EntityType="RemoteModel.COLOR_CATALOGS" Width="1.5" PointX="1.5" PointY="40.625" /> + <EntityTypeShape EntityType="RemoteModel.COLOR_CATALOGS_GROUPS" Width="1.5" PointX="3.75" PointY="41.125" /> + <EntityTypeShape EntityType="RemoteModel.COLOR_CATALOGS_ITEMS" Width="1.5" PointX="6" PointY="39.875" /> + <EntityTypeShape EntityType="RemoteModel.COLOR_CATALOGS_ITEMS_RECIPES" Width="1.5" PointX="8.25" PointY="19.75" /> + <EntityTypeShape EntityType="RemoteModel.COLOR_SPACES" Width="1.5" PointX="9" PointY="10.625" /> + <EntityTypeShape EntityType="RemoteModel.CONFIGURATION" Width="1.5" PointX="6.75" PointY="64.75" /> + <EntityTypeShape EntityType="RemoteModel.CONTACT" Width="1.5" PointX="1.5" PointY="35.875" /> + <EntityTypeShape EntityType="RemoteModel.CUSTOMER" Width="1.5" PointX="9" PointY="7.5" /> + <EntityTypeShape EntityType="RemoteModel.DATA_STORE_ITEMS" Width="1.5" PointX="11.25" PointY="72" /> + <EntityTypeShape EntityType="RemoteModel.DISPENSER_TYPES" Width="1.5" PointX="4.5" PointY="29.125" /> + <EntityTypeShape EntityType="RemoteModel.DISPENSER" Width="1.5" PointX="6.75" PointY="28.5" /> + <EntityTypeShape EntityType="RemoteModel.EMBEDDED_FIRMWARE_VERSIONS" Width="1.5" PointX="4.5" PointY="65" /> + <EntityTypeShape EntityType="RemoteModel.EVENT_TYPES" Width="1.5" PointX="9" PointY="31.75" /> <EntityTypeShape EntityType="RemoteModel.FIBER_SHAPES" Width="1.5" PointX="0.75" PointY="20.25" /> - <EntityTypeShape EntityType="RemoteModel.FIBER_SYNTHS" Width="1.5" PointX="0.75" PointY="32.75" /> - <EntityTypeShape EntityType="RemoteModel.FSE_VERSIONS" Width="1.5" PointX="11.25" PointY="42.625" /> - <EntityTypeShape EntityType="RemoteModel.GLOBAL_DATA_STORE_ITEMS" Width="1.5" PointX="10.75" PointY="0.75" /> - <EntityTypeShape EntityType="RemoteModel.HARDWARE_BLOWER_TYPES" Width="1.5" PointX="4.5" PointY="58.375" /> - <EntityTypeShape EntityType="RemoteModel.HARDWARE_BLOWERS" Width="1.5" PointX="6.75" PointY="60" /> - <EntityTypeShape EntityType="RemoteModel.HARDWARE_BREAK_SENSOR_TYPES" Width="1.5" PointX="6.5" PointY="80.375" /> - <EntityTypeShape EntityType="RemoteModel.HARDWARE_BREAK_SENSORS" Width="1.5" PointX="8.75" PointY="64.125" /> - <EntityTypeShape EntityType="RemoteModel.HARDWARE_DANCER_TYPES" Width="1.5" PointX="1.5" PointY="80.375" /> - <EntityTypeShape EntityType="RemoteModel.HARDWARE_DANCERS" Width="1.5" PointX="3.75" PointY="67.375" /> - <EntityTypeShape EntityType="RemoteModel.HARDWARE_MOTOR_TYPES" Width="1.5" PointX="9.5" PointY="59.375" /> - <EntityTypeShape EntityType="RemoteModel.HARDWARE_MOTORS" Width="1.5" PointX="11.75" PointY="56" /> - <EntityTypeShape EntityType="RemoteModel.HARDWARE_PID_CONTROL_TYPES" Width="1.5" PointX="9.5" PointY="80.375" /> - <EntityTypeShape EntityType="RemoteModel.HARDWARE_PID_CONTROLS" Width="1.5" PointX="11.75" PointY="66.5" /> - <EntityTypeShape EntityType="RemoteModel.HARDWARE_SPEED_SENSOR_TYPES" Width="1.5" PointX="6.5" PointY="88.375" /> - <EntityTypeShape EntityType="RemoteModel.HARDWARE_SPEED_SENSORS" Width="1.5" PointX="8.75" PointY="72.125" /> - <EntityTypeShape EntityType="RemoteModel.HARDWARE_VERSIONS" Width="1.5" PointX="1.5" PointY="67.875" /> - <EntityTypeShape EntityType="RemoteModel.HARDWARE_WINDER_TYPES" Width="1.5" PointX="6.5" PointY="84.375" /> - <EntityTypeShape EntityType="RemoteModel.HARDWARE_WINDERS" Width="1.5" PointX="8.75" PointY="68.25" /> - <EntityTypeShape EntityType="RemoteModel.IDS_PACK_FORMULAS" Width="1.5" PointX="3.75" PointY="40.125" /> - <EntityTypeShape EntityType="RemoteModel.IDS_PACKS" Width="1.5" PointX="6" PointY="32.125" /> - <EntityTypeShape EntityType="RemoteModel.JOB_RUNS" Width="1.5" PointX="14.75" PointY="0.75" /> + <EntityTypeShape EntityType="RemoteModel.FIBER_SYNTHS" Width="1.5" PointX="0.75" PointY="23.625" /> + <EntityTypeShape EntityType="RemoteModel.FSE_VERSIONS" Width="1.5" PointX="11.25" PointY="27.625" /> + <EntityTypeShape EntityType="RemoteModel.GLOBAL_DATA_STORE_ITEMS" Width="1.5" PointX="3.75" PointY="0.75" /> + <EntityTypeShape EntityType="RemoteModel.HARDWARE_BLOWER_TYPES" Width="1.5" PointX="7.5" PointY="84.5" /> + <EntityTypeShape EntityType="RemoteModel.HARDWARE_BLOWERS" Width="1.5" PointX="9.75" PointY="76.125" /> + <EntityTypeShape EntityType="RemoteModel.HARDWARE_BREAK_SENSOR_TYPES" Width="1.5" PointX="9.5" PointY="80.5" /> + <EntityTypeShape EntityType="RemoteModel.HARDWARE_BREAK_SENSORS" Width="1.5" PointX="11.75" PointY="68.25" /> + <EntityTypeShape EntityType="RemoteModel.HARDWARE_DANCER_TYPES" Width="1.5" PointX="9.5" PointY="57.5" /> + <EntityTypeShape EntityType="RemoteModel.HARDWARE_DANCERS" Width="1.5" PointX="11.75" PointY="62.375" /> + <EntityTypeShape EntityType="RemoteModel.HARDWARE_MOTOR_TYPES" Width="1.5" PointX="11.5" PointY="84.375" /> + <EntityTypeShape EntityType="RemoteModel.HARDWARE_MOTORS" Width="1.5" PointX="13.75" PointY="72.125" /> + <EntityTypeShape EntityType="RemoteModel.HARDWARE_PID_CONTROL_TYPES" Width="1.5" PointX="12.5" PointY="58.5" /> + <EntityTypeShape EntityType="RemoteModel.HARDWARE_PID_CONTROLS" Width="1.5" PointX="14.75" PointY="64.5" /> + <EntityTypeShape EntityType="RemoteModel.HARDWARE_SPEED_SENSOR_TYPES" Width="1.5" PointX="4.5" PointY="75.5" /> + <EntityTypeShape EntityType="RemoteModel.HARDWARE_SPEED_SENSORS" Width="1.5" PointX="6.75" PointY="71.25" /> + <EntityTypeShape EntityType="RemoteModel.HARDWARE_VERSIONS" Width="1.5" PointX="4.5" PointY="70.875" /> + <EntityTypeShape EntityType="RemoteModel.HARDWARE_WINDER_TYPES" Width="1.5" PointX="4.5" PointY="79.5" /> + <EntityTypeShape EntityType="RemoteModel.HARDWARE_WINDERS" Width="1.5" PointX="6.75" PointY="75.25" /> + <EntityTypeShape EntityType="RemoteModel.IDS_PACK_FORMULAS" Width="1.5" PointX="6.75" PointY="33.375" /> + <EntityTypeShape EntityType="RemoteModel.IDS_PACKS" Width="1.5" PointX="9" PointY="37.625" /> + <EntityTypeShape EntityType="RemoteModel.JOB_RUNS" Width="1.5" PointX="5.75" PointY="0.75" /> <EntityTypeShape EntityType="RemoteModel.JOB" Width="1.5" PointX="11.25" PointY="16.375" /> - <EntityTypeShape EntityType="RemoteModel.LINEAR_MASS_DENSITY_UNITS" Width="1.5" PointX="0.75" PointY="27" /> - <EntityTypeShape EntityType="RemoteModel.LIQUID_TYPES" Width="1.5" PointX="3" PointY="2.625" /> - <EntityTypeShape EntityType="RemoteModel.LIQUID_TYPES_RMLS" Width="1.5" PointX="5.25" PointY="16" /> - <EntityTypeShape EntityType="RemoteModel.MACHINE_STUDIO_VERSIONS" Width="1.5" PointX="11.25" PointY="31" /> - <EntityTypeShape EntityType="RemoteModel.MACHINE_VERSIONS" Width="1.5" PointX="3.75" PointY="80.125" /> - <EntityTypeShape EntityType="RemoteModel.MACHINE" Width="1.5" PointX="6" PointY="64.875" /> - <EntityTypeShape EntityType="RemoteModel.MACHINES_EVENTS" Width="1.5" PointX="11.25" PointY="49.125" /> - <EntityTypeShape EntityType="RemoteModel.MEDIA_CONDITIONS" Width="1.5" PointX="0.75" PointY="24" /> - <EntityTypeShape EntityType="RemoteModel.MEDIA_MATERIALS" Width="1.5" PointX="0.75" PointY="12.75" /> - <EntityTypeShape EntityType="RemoteModel.MEDIA_PURPOSES" Width="1.5" PointX="0.75" PointY="29.875" /> - <EntityTypeShape EntityType="RemoteModel.MID_TANK_TYPES" Width="1.5" PointX="3.75" PointY="32.75" /> - <EntityTypeShape EntityType="RemoteModel.ORGANIZATION" Width="1.5" PointX="3.75" PointY="74" /> - <EntityTypeShape EntityType="RemoteModel.PERMISSION" Width="1.5" PointX="12" PointY="5.125" /> + <EntityTypeShape EntityType="RemoteModel.LINEAR_MASS_DENSITY_UNITS" Width="1.5" PointX="0.75" PointY="12.75" /> + <EntityTypeShape EntityType="RemoteModel.LIQUID_TYPES" Width="1.5" PointX="3" PointY="10.625" /> + <EntityTypeShape EntityType="RemoteModel.LIQUID_TYPES_RMLS" Width="1.5" PointX="5.25" PointY="20" /> + <EntityTypeShape EntityType="RemoteModel.MACHINE_STUDIO_VERSIONS" Width="1.5" PointX="11.25" PointY="32.375" /> + <EntityTypeShape EntityType="RemoteModel.MACHINE_VERSIONS" Width="1.5" PointX="6.75" PointY="55.875" /> + <EntityTypeShape EntityType="RemoteModel.MACHINE" Width="1.5" PointX="9" PointY="60.625" /> + <EntityTypeShape EntityType="RemoteModel.MACHINES_EVENTS" Width="1.5" PointX="11.25" PointY="45.125" /> + <EntityTypeShape EntityType="RemoteModel.MEDIA_CONDITIONS" Width="1.5" PointX="0.75" PointY="29.875" /> + <EntityTypeShape EntityType="RemoteModel.MEDIA_MATERIALS" Width="1.5" PointX="0.75" PointY="15.75" /> + <EntityTypeShape EntityType="RemoteModel.MEDIA_PURPOSES" Width="1.5" PointX="0.75" PointY="32.75" /> + <EntityTypeShape EntityType="RemoteModel.MID_TANK_TYPES" Width="1.5" PointX="6.75" PointY="59.875" /> + <EntityTypeShape EntityType="RemoteModel.ORGANIZATION" Width="1.5" PointX="0.75" PointY="6.75" /> + <EntityTypeShape EntityType="RemoteModel.PERMISSION" Width="1.5" PointX="12" PointY="8.5" /> <EntityTypeShape EntityType="RemoteModel.PROCESS_PARAMETERS_TABLES" Width="1.5" PointX="7.5" PointY="46.625" /> <EntityTypeShape EntityType="RemoteModel.PROCESS_PARAMETERS_TABLES_GROUPS" Width="1.5" PointX="5.25" PointY="49.25" /> - <EntityTypeShape EntityType="RemoteModel.PUBLISHED_PROCEDURE_PROJECTS" Width="1.5" PointX="5.75" PointY="1" /> - <EntityTypeShape EntityType="RemoteModel.PUBLISHED_PROCEDURE_PROJECTS_VERSIONS" Width="1.5" PointX="8" PointY="1.125" /> + <EntityTypeShape EntityType="RemoteModel.PUBLISHED_PROCEDURE_PROJECTS" Width="1.5" PointX="11.75" PointY="1" /> + <EntityTypeShape EntityType="RemoteModel.PUBLISHED_PROCEDURE_PROJECTS_VERSIONS" Width="1.5" PointX="14" PointY="1.125" /> <EntityTypeShape EntityType="RemoteModel.RML" Width="1.5" PointX="3" PointY="15" /> - <EntityTypeShape EntityType="RemoteModel.RMLS_SPOOLS" Width="1.5" PointX="5.25" PointY="23.875" /> - <EntityTypeShape EntityType="RemoteModel.ROLE" Width="1.5" PointX="12" PointY="9" /> - <EntityTypeShape EntityType="RemoteModel.ROLES_PERMISSIONS" Width="1.5" PointX="14.25" PointY="9.125" /> + <EntityTypeShape EntityType="RemoteModel.RMLS_SPOOLS" Width="1.5" PointX="8.25" PointY="15.875" /> + <EntityTypeShape EntityType="RemoteModel.ROLE" Width="1.5" PointX="12" PointY="12.375" /> + <EntityTypeShape EntityType="RemoteModel.ROLES_PERMISSIONS" Width="1.5" PointX="14.25" PointY="12.5" /> <EntityTypeShape EntityType="RemoteModel.SEGMENT" Width="1.5" PointX="13.5" PointY="20" /> - <EntityTypeShape EntityType="RemoteModel.SITE" Width="1.5" PointX="3" PointY="29" /> - <EntityTypeShape EntityType="RemoteModel.SITES_CATALOGS" Width="1.5" PointX="11.25" PointY="12.5" /> - <EntityTypeShape EntityType="RemoteModel.SITES_RMLS" Width="1.5" PointX="5.25" PointY="20.25" /> - <EntityTypeShape EntityType="RemoteModel.SPOOL_TYPES" Width="1.5" PointX="9" PointY="5.625" /> - <EntityTypeShape EntityType="RemoteModel.SPOOL" Width="1.5" PointX="11.25" PointY="38.125" /> - <EntityTypeShape EntityType="RemoteModel.sysdiagram" Width="1.5" PointX="5.75" PointY="12.75" /> - <EntityTypeShape EntityType="RemoteModel.TANGO_UPDATES" Width="1.5" PointX="13.75" PointY="12.75" /> - <EntityTypeShape EntityType="RemoteModel.TANGO_VERSIONS" Width="1.5" PointX="14.25" PointY="53.5" /> - <EntityTypeShape EntityType="RemoteModel.TECH_CONTROLLERS" Width="1.5" PointX="15.75" PointY="12.75" /> + <EntityTypeShape EntityType="RemoteModel.SITE" Width="1.5" PointX="3" PointY="7" /> + <EntityTypeShape EntityType="RemoteModel.SITES_CATALOGS" Width="1.5" PointX="14.25" PointY="27.375" /> + <EntityTypeShape EntityType="RemoteModel.SITES_RMLS" Width="1.5" PointX="5.25" PointY="16.25" /> + <EntityTypeShape EntityType="RemoteModel.SPOOL_TYPES" Width="1.5" PointX="6" PointY="10.25" /> + <EntityTypeShape EntityType="RemoteModel.SPOOL" Width="1.5" PointX="11.25" PointY="38.375" /> + <EntityTypeShape EntityType="RemoteModel.sysdiagram" Width="1.5" PointX="7.75" PointY="0.75" /> + <EntityTypeShape EntityType="RemoteModel.TANGO_UPDATES" Width="1.5" PointX="14.75" PointY="4.75" /> + <EntityTypeShape EntityType="RemoteModel.TANGO_VERSIONS" Width="1.5" PointX="14.25" PointY="39.625" /> + <EntityTypeShape EntityType="RemoteModel.TECH_CONTROLLERS" Width="1.5" PointX="11.75" PointY="4.75" /> <EntityTypeShape EntityType="RemoteModel.TECH_DISPENSERS" Width="1.5" PointX="16.75" PointY="0.75" /> <EntityTypeShape EntityType="RemoteModel.TECH_HEATERS" Width="1.5" PointX="16.75" PointY="3.75" /> <EntityTypeShape EntityType="RemoteModel.TECH_IOS" Width="1.5" PointX="16.75" PointY="6.75" /> - <EntityTypeShape EntityType="RemoteModel.TECH_MONITORS" Width="1.5" PointX="17.75" PointY="11.75" /> + <EntityTypeShape EntityType="RemoteModel.TECH_MONITORS" Width="1.5" PointX="16.75" PointY="11.75" /> <EntityTypeShape EntityType="RemoteModel.TECH_VALVES" Width="1.5" PointX="17.75" PointY="16.75" /> - <EntityTypeShape EntityType="RemoteModel.USER" Width="1.5" PointX="9" PointY="27.75" /> - <EntityTypeShape EntityType="RemoteModel.USERS_ROLES" Width="1.5" PointX="14.25" PointY="29.125" /> - <EntityTypeShape EntityType="RemoteModel.WINDING_METHODS" Width="1.5" PointX="9" PointY="24.625" /> + <EntityTypeShape EntityType="RemoteModel.USER" Width="1.5" PointX="9" PointY="24.125" /> + <EntityTypeShape EntityType="RemoteModel.USERS_ROLES" Width="1.5" PointX="14.25" PointY="31.5" /> + <EntityTypeShape EntityType="RemoteModel.WINDING_METHODS" Width="1.5" PointX="9" PointY="4.375" /> <AssociationConnector Association="RemoteModel.FK_ACTION_LOGS_USERS" /> <AssociationConnector Association="RemoteModel.FK_ORGANIZATIONS_ADDRESSES" /> <AssociationConnector Association="RemoteModel.FK_USERS_ADDRESSES" /> diff --git a/Software/Visual_Studio/Tango.DataStore.Editing/DataStoreCollectionModel.cs b/Software/Visual_Studio/Tango.DataStore.Editing/DataStoreCollectionModel.cs index a5c9ba4a7..00094e945 100644 --- a/Software/Visual_Studio/Tango.DataStore.Editing/DataStoreCollectionModel.cs +++ b/Software/Visual_Studio/Tango.DataStore.Editing/DataStoreCollectionModel.cs @@ -12,6 +12,7 @@ namespace Tango.DataStore.Editing { public String Name { get; set; } public ObservableCollection<DataStoreItemModel> Items { get; set; } + public bool IsDeleted { get; set; } public DataStoreCollectionModel() { diff --git a/Software/Visual_Studio/Tango.DataStore.Editing/DataStoreItemModel.cs b/Software/Visual_Studio/Tango.DataStore.Editing/DataStoreItemModel.cs index 36dd44f22..1298cbc57 100644 --- a/Software/Visual_Studio/Tango.DataStore.Editing/DataStoreItemModel.cs +++ b/Software/Visual_Studio/Tango.DataStore.Editing/DataStoreItemModel.cs @@ -11,44 +11,74 @@ namespace Tango.DataStore.Editing { public IDataStoreItem GlobalItem { get; set; } + public DataType OriginalType { get; set; } + public Object OriginalValue { get; set; } + private Object _value; public Object Value { get { return _value; } - set { _value = value; RaisePropertyChangedAuto(); EditingValue = value; } + set { _value = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(HasDifference)); RaisePropertyChanged(nameof(FormattedValue)); } } - private Object _editingValue; - public Object EditingValue + public bool HasDifference { - get { return _editingValue; } - set { _editingValue = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(HasDifference)); } + get + { + if (OriginalType != Type) + { + return true; + } + + if (OriginalType == DataType.Bytes && Type == DataType.Bytes) + { + if (OriginalValue != null && Value != null) + { + return !Enumerable.SequenceEqual(OriginalValue as byte[], Value as byte[]); + } + } + + if (Value == null && OriginalValue == null) return false; + + return !OriginalValue.ToStringSafe().Equals(Value.ToStringSafe()) || (IsGlobal && GlobalItem.Value != Value); + } } - public bool HasDifference + public String FormattedValue { - get { return EditingValue != Value || (IsGlobal && GlobalItem.Value != Value); } + get { return this.ToString().ToOneLine(); } } public string Guid { get; set; } public string Key { get; set; } public DataType Type { get; set; } public DateTime Date { get; set; } - public bool IsGlobal { get; set; } public bool IsSynchronized { get; set; } + public bool ExistsOnMachine { get; set; } + + private bool _isGlobal; + public bool IsGlobal + { + get { return _isGlobal; } + set { _isGlobal = value; RaisePropertyChangedAuto(); } + } - public void Apply() + private bool _isDeleted; + public bool IsDeleted { - Value = EditingValue; + get { return _isDeleted; } + set { _isDeleted = value; RaisePropertyChangedAuto(); } } public static DataStoreItemModel FromLocalDataStoreItem(IDataStoreItem local, IDataStoreItem globalItem) { DataStoreItemModel model = new DataStoreItemModel(); + model.OriginalValue = local.Value; model.Value = local.Value; model.Guid = local.Guid; model.Key = local.Key; + model.OriginalType = local.Type; model.Type = local.Type; model.Date = local.Date; model.IsGlobal = false; @@ -67,6 +97,7 @@ namespace Tango.DataStore.Editing model.Guid = global.Guid; model.Key = global.Key; model.Type = global.Type; + model.OriginalType = global.Type; model.Date = global.Date; model.IsGlobal = true; model.IsSynchronized = global.IsSynchronized; @@ -76,7 +107,7 @@ namespace Tango.DataStore.Editing public override string ToString() { - if (!IsGlobal) + if (this.Value != null) { return DataStoreHelper.FormatDataStoreItem(this); } diff --git a/Software/Visual_Studio/Tango.DataStore.Editing/Tango.DataStore.Editing.csproj b/Software/Visual_Studio/Tango.DataStore.Editing/Tango.DataStore.Editing.csproj index 98df18ac3..4707dca0b 100644 --- a/Software/Visual_Studio/Tango.DataStore.Editing/Tango.DataStore.Editing.csproj +++ b/Software/Visual_Studio/Tango.DataStore.Editing/Tango.DataStore.Editing.csproj @@ -48,6 +48,8 @@ <Reference Include="PresentationFramework" /> </ItemGroup> <ItemGroup> + <Compile Include="UpdateDataStoreRequest.cs" /> + <Compile Include="UpdateDataStoreResponse.cs" /> <Page Include="Themes\Generic.xaml"> <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> @@ -83,6 +85,10 @@ </None> </ItemGroup> <ItemGroup> + <ProjectReference Include="..\Tango.BL\Tango.BL.csproj"> + <Project>{f441feee-322a-4943-b566-110e12fd3b72}</Project> + <Name>Tango.BL</Name> + </ProjectReference> <ProjectReference Include="..\Tango.Core\Tango.Core.csproj"> <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project> <Name>Tango.Core</Name> diff --git a/Software/Visual_Studio/Tango.DataStore.Editing/UpdateDataStoreRequest.cs b/Software/Visual_Studio/Tango.DataStore.Editing/UpdateDataStoreRequest.cs new file mode 100644 index 000000000..dc95ea6ae --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.Editing/UpdateDataStoreRequest.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.DTO; + +namespace Tango.DataStore.Editing +{ + public class UpdateDataStoreRequest + { + public List<String> ToDelete { get; set; } + public List<DataStoreItemDTO> ToUpsert { get; set; } + + public UpdateDataStoreRequest() + { + ToDelete = new List<string>(); + ToUpsert = new List<DataStoreItemDTO>(); + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.Editing/UpdateDataStoreResponse.cs b/Software/Visual_Studio/Tango.DataStore.Editing/UpdateDataStoreResponse.cs new file mode 100644 index 000000000..697ae341d --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.Editing/UpdateDataStoreResponse.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.DataStore.Editing +{ + public class UpdateDataStoreResponse + { + + } +} diff --git a/Software/Visual_Studio/Tango.DataStore/DataStoreHelper.cs b/Software/Visual_Studio/Tango.DataStore/DataStoreHelper.cs index 7167648b4..0ca8e484e 100644 --- a/Software/Visual_Studio/Tango.DataStore/DataStoreHelper.cs +++ b/Software/Visual_Studio/Tango.DataStore/DataStoreHelper.cs @@ -84,23 +84,77 @@ namespace Tango.DataStore { if (item.Type == DataType.Bytes) { - byte[] bytes = (byte[])item.Value; - - StringBuilder hex = new StringBuilder(); - foreach (byte b in bytes) - { - hex.AppendFormat("{0:x2} ", b); - } - return hex.ToString(); + return GetByteArrayHexString((byte[])item.Value); } else if (item.Type == DataType.Proto) { - return (item.Value as DataStoreProtoObject).Message.ToString(); + return (item.Value as DataStoreProtoObject).Message.ToJsonString(); } else { return item.Value.ToStringSafe(); } } + + /// <summary> + /// Returns a byte array string representation in hex format. + /// </summary> + /// <param name="data">The data.</param> + /// <returns></returns> + public static String GetByteArrayHexString(byte[] data) + { + StringBuilder hex = new StringBuilder(); + foreach (byte b in data) + { + hex.Append(b.ToString("X2") + " "); + } + return hex.ToString(); + } + + /// <summary> + /// Parses a data store value from a string. + /// </summary> + /// <param name="type">The type.</param> + /// <param name="text">The string.</param> + /// <param name="protoMessageType">Type of the proto message (if type is Proto).</param> + /// <returns></returns> + /// <exception cref="ArgumentNullException">No PMR message type specified.</exception> + /// <exception cref="NotSupportedException">The specified data store type is not supported.</exception> + public static Object ParseDataStoreValue(DataType type, String text, MessageType? protoMessageType = null) + { + switch (type) + { + case DataType.String: + return text; + case DataType.Int32: + return int.Parse(text); + case DataType.Float: + return float.Parse(text); + case DataType.Double: + return double.Parse(text); + case DataType.Boolean: + return bool.Parse(text); + case DataType.Proto: + if (protoMessageType == null) throw new ArgumentNullException("No PMR message type specified."); + var messageType = MessageFactory.GetPMRTypeFromMessageType(protoMessageType.Value); + var instance = Activator.CreateInstance(messageType) as IMessage; + instance = instance.GetParser().ParseJson(text); + return DataStoreProtoObject.FromMessage(instance); + case DataType.Bytes: + string[] hexValuesSplit = text.Split(' '); + List<byte> bytes = new List<byte>(); + foreach (string hex in hexValuesSplit) + { + if (hex.IsNotNullOrEmpty()) + { + byte b = (byte)Convert.ToInt32(hex.Trim(), 16); + bytes.Add(b); + } + } + return bytes.ToArray(); + } + + throw new NotSupportedException("The specified data store type is not supported."); + } } } diff --git a/Software/Visual_Studio/Tango.DataStore/DataStoreProtoObject.cs b/Software/Visual_Studio/Tango.DataStore/DataStoreProtoObject.cs index 6661c2017..5aa7c5342 100644 --- a/Software/Visual_Studio/Tango.DataStore/DataStoreProtoObject.cs +++ b/Software/Visual_Studio/Tango.DataStore/DataStoreProtoObject.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.Core.Bson; +using Tango.Core.ExtensionMethods; using Tango.PMR; using Tango.PMR.Common; using Tango.PMR.DataStore; @@ -73,5 +74,10 @@ namespace Tango.DataStore proto.Data = item.BytesValue.ToByteArray(); return proto; } + + public override string ToString() + { + return Message?.ToJsonString(); + } } } diff --git a/Software/Visual_Studio/Tango.PMR/Common/MessageType.cs b/Software/Visual_Studio/Tango.PMR/Common/MessageType.cs index 2ef40336c..8e0b93863 100644 --- a/Software/Visual_Studio/Tango.PMR/Common/MessageType.cs +++ b/Software/Visual_Studio/Tango.PMR/Common/MessageType.cs @@ -22,7 +22,7 @@ namespace Tango.PMR.Common { static MessageTypeReflection() { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( - "ChFNZXNzYWdlVHlwZS5wcm90bxIQVGFuZ28uUE1SLkNvbW1vbircPQoLTWVz", + "ChFNZXNzYWdlVHlwZS5wcm90bxIQVGFuZ28uUE1SLkNvbW1vbiqjPgoLTWVz", "c2FnZVR5cGUSCAoETm9uZRAAEhEKDUVycm9yUmVzcG9uc2UQARIUChBDYWxj", "dWxhdGVSZXF1ZXN0EAMSFQoRQ2FsY3VsYXRlUmVzcG9uc2UQBBITCg9Qcm9n", "cmVzc1JlcXVlc3QQBRIUChBQcm9ncmVzc1Jlc3BvbnNlEAYSHAoYU3R1YkNh", @@ -198,8 +198,9 @@ namespace Tango.PMR.Common { "HVN0YXJ0SW5rRmlsbGluZ1N0YXR1c1Jlc3BvbnNlEOFdEhwKF1B1dERhdGFT", "dG9yZUl0ZW1SZXF1ZXN0EMhlEh0KGFB1dERhdGFTdG9yZUl0ZW1SZXNwb25z", "ZRDJZRIcChdHZXREYXRhU3RvcmVJdGVtUmVxdWVzdBDKZRIdChhHZXREYXRh", - "U3RvcmVJdGVtUmVzcG9uc2UQy2VCHAoaY29tLnR3aW5lLnRhbmdvLnBtci5j", - "b21tb25iBnByb3RvMw==")); + "U3RvcmVJdGVtUmVzcG9uc2UQy2USIQocRGF0YVN0b3JlSXRlbU1vZGlmaWVk", + "UmVxdWVzdBDMZRIiCh1EYXRhU3RvcmVJdGVtTW9kaWZpZWRSZXNwb25zZRDN", + "ZUIcChpjb20udHdpbmUudGFuZ28ucG1yLmNvbW1vbmIGcHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Tango.PMR.Common.MessageType), }, null)); @@ -529,6 +530,8 @@ namespace Tango.PMR.Common { [pbr::OriginalName("PutDataStoreItemResponse")] PutDataStoreItemResponse = 13001, [pbr::OriginalName("GetDataStoreItemRequest")] GetDataStoreItemRequest = 13002, [pbr::OriginalName("GetDataStoreItemResponse")] GetDataStoreItemResponse = 13003, + [pbr::OriginalName("DataStoreItemModifiedRequest")] DataStoreItemModifiedRequest = 13004, + [pbr::OriginalName("DataStoreItemModifiedResponse")] DataStoreItemModifiedResponse = 13005, } #endregion diff --git a/Software/Visual_Studio/Tango.PMR/DataStore/DataStoreItemModifiedRequest.cs b/Software/Visual_Studio/Tango.PMR/DataStore/DataStoreItemModifiedRequest.cs new file mode 100644 index 000000000..c4a8163fd --- /dev/null +++ b/Software/Visual_Studio/Tango.PMR/DataStore/DataStoreItemModifiedRequest.cs @@ -0,0 +1,188 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: DataStoreItemModifiedRequest.proto +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace Tango.PMR.DataStore { + + /// <summary>Holder for reflection information generated from DataStoreItemModifiedRequest.proto</summary> + public static partial class DataStoreItemModifiedRequestReflection { + + #region Descriptor + /// <summary>File descriptor for DataStoreItemModifiedRequest.proto</summary> + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static DataStoreItemModifiedRequestReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "CiJEYXRhU3RvcmVJdGVtTW9kaWZpZWRSZXF1ZXN0LnByb3RvEhNUYW5nby5Q", + "TVIuRGF0YVN0b3JlIj8KHERhdGFTdG9yZUl0ZW1Nb2RpZmllZFJlcXVlc3QS", + "EgoKQ29sbGVjdGlvbhgBIAEoCRILCgNLZXkYAiABKAlCHwodY29tLnR3aW5l", + "LnRhbmdvLnBtci5kYXRhc3RvcmViBnByb3RvMw==")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { }, + new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.DataStore.DataStoreItemModifiedRequest), global::Tango.PMR.DataStore.DataStoreItemModifiedRequest.Parser, new[]{ "Collection", "Key" }, null, null, null) + })); + } + #endregion + + } + #region Messages + public sealed partial class DataStoreItemModifiedRequest : pb::IMessage<DataStoreItemModifiedRequest> { + private static readonly pb::MessageParser<DataStoreItemModifiedRequest> _parser = new pb::MessageParser<DataStoreItemModifiedRequest>(() => new DataStoreItemModifiedRequest()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser<DataStoreItemModifiedRequest> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Tango.PMR.DataStore.DataStoreItemModifiedRequestReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public DataStoreItemModifiedRequest() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public DataStoreItemModifiedRequest(DataStoreItemModifiedRequest other) : this() { + collection_ = other.collection_; + key_ = other.key_; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public DataStoreItemModifiedRequest Clone() { + return new DataStoreItemModifiedRequest(this); + } + + /// <summary>Field number for the "Collection" field.</summary> + public const int CollectionFieldNumber = 1; + private string collection_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string Collection { + get { return collection_; } + set { + collection_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// <summary>Field number for the "Key" field.</summary> + public const int KeyFieldNumber = 2; + private string key_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string Key { + get { return key_; } + set { + key_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as DataStoreItemModifiedRequest); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(DataStoreItemModifiedRequest other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Collection != other.Collection) return false; + if (Key != other.Key) return false; + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (Collection.Length != 0) hash ^= Collection.GetHashCode(); + if (Key.Length != 0) hash ^= Key.GetHashCode(); + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + if (Collection.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Collection); + } + if (Key.Length != 0) { + output.WriteRawTag(18); + output.WriteString(Key); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (Collection.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Collection); + } + if (Key.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Key); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(DataStoreItemModifiedRequest other) { + if (other == null) { + return; + } + if (other.Collection.Length != 0) { + Collection = other.Collection; + } + if (other.Key.Length != 0) { + Key = other.Key; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 10: { + Collection = input.ReadString(); + break; + } + case 18: { + Key = input.ReadString(); + break; + } + } + } + } + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/Software/Visual_Studio/Tango.PMR/DataStore/DataStoreItemModifiedResponse.cs b/Software/Visual_Studio/Tango.PMR/DataStore/DataStoreItemModifiedResponse.cs new file mode 100644 index 000000000..fc70186aa --- /dev/null +++ b/Software/Visual_Studio/Tango.PMR/DataStore/DataStoreItemModifiedResponse.cs @@ -0,0 +1,131 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: DataStoreItemModifiedResponse.proto +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace Tango.PMR.DataStore { + + /// <summary>Holder for reflection information generated from DataStoreItemModifiedResponse.proto</summary> + public static partial class DataStoreItemModifiedResponseReflection { + + #region Descriptor + /// <summary>File descriptor for DataStoreItemModifiedResponse.proto</summary> + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static DataStoreItemModifiedResponseReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "CiNEYXRhU3RvcmVJdGVtTW9kaWZpZWRSZXNwb25zZS5wcm90bxITVGFuZ28u", + "UE1SLkRhdGFTdG9yZSIfCh1EYXRhU3RvcmVJdGVtTW9kaWZpZWRSZXNwb25z", + "ZUIfCh1jb20udHdpbmUudGFuZ28ucG1yLmRhdGFzdG9yZWIGcHJvdG8z")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { }, + new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.DataStore.DataStoreItemModifiedResponse), global::Tango.PMR.DataStore.DataStoreItemModifiedResponse.Parser, null, null, null, null) + })); + } + #endregion + + } + #region Messages + public sealed partial class DataStoreItemModifiedResponse : pb::IMessage<DataStoreItemModifiedResponse> { + private static readonly pb::MessageParser<DataStoreItemModifiedResponse> _parser = new pb::MessageParser<DataStoreItemModifiedResponse>(() => new DataStoreItemModifiedResponse()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser<DataStoreItemModifiedResponse> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Tango.PMR.DataStore.DataStoreItemModifiedResponseReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public DataStoreItemModifiedResponse() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public DataStoreItemModifiedResponse(DataStoreItemModifiedResponse other) : this() { + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public DataStoreItemModifiedResponse Clone() { + return new DataStoreItemModifiedResponse(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as DataStoreItemModifiedResponse); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(DataStoreItemModifiedResponse other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(DataStoreItemModifiedResponse other) { + if (other == null) { + return; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + } + } + } + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj b/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj index bb44ef591..7efe8d3f0 100644 --- a/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj +++ b/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj @@ -79,6 +79,8 @@ <Compile Include="Connection\KeepAliveRequest.cs" /> <Compile Include="Connection\KeepAliveResponse.cs" /> <Compile Include="DataStore\DataStoreItem.cs" /> + <Compile Include="DataStore\DataStoreItemModifiedRequest.cs" /> + <Compile Include="DataStore\DataStoreItemModifiedResponse.cs" /> <Compile Include="DataStore\DataType.cs" /> <Compile Include="DataStore\GetDataStoreItemRequest.cs" /> <Compile Include="DataStore\GetDataStoreItemResponse.cs" /> @@ -483,7 +485,7 @@ </PropertyGroup> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" /> + <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" /> </VisualStudio> </ProjectExtensions> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs index 583d7b810..1f2856a32 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs +++ b/Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs @@ -12,6 +12,7 @@ using System.Windows.Input; using System.Linq; using System.Windows.Media; using System.Windows.Threading; +using Tango.Core.ExtensionMethods; namespace Tango.SharedUI.Controls { @@ -73,6 +74,11 @@ namespace Tango.SharedUI.Controls { IsOpened = false; SelectedItem = _listBox.SelectedItem; + + if (SelectedValuePath.IsNotNullOrEmpty() && SelectedItem != null) + { + SelectedValue = SelectedItem.GetPropertyValueByPath(SelectedValuePath); + } } else if (e.Key == Key.Up && _listBox.SelectedIndex == 0) { @@ -120,6 +126,11 @@ namespace Tango.SharedUI.Controls { IsOpened = false; SelectedItem = _listBox.SelectedItem; + + if (SelectedValuePath.IsNotNullOrEmpty() && SelectedItem != null) + { + SelectedValue = SelectedItem.GetPropertyValueByPath(SelectedValuePath); + } } } } @@ -152,12 +163,17 @@ namespace Tango.SharedUI.Controls if (x != null) { - var prop = x.GetType().GetProperty(SearchProperty, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); - if (prop != null) + if (!String.IsNullOrWhiteSpace(SearchProperty)) { - String propValue = prop.GetValue(x).ToString(); - return propValue.ToLower().Contains(SearchFilter.ToLower()); + var prop = x.GetType().GetProperty(SearchProperty, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); + if (prop != null) + { + String propValue = prop.GetValue(x).ToString(); + return propValue.ToLower().Contains(SearchFilter.ToLower()); + } } + + return x.ToStringSafe().ToLower().Contains(SearchFilter.ToLower()); } return false; diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/EnumToItemsSourceConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/EnumToItemsSourceConverter.cs index c551f7d49..5c725e524 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Converters/EnumToItemsSourceConverter.cs +++ b/Software/Visual_Studio/Tango.SharedUI/Converters/EnumToItemsSourceConverter.cs @@ -10,6 +10,17 @@ namespace Tango.SharedUI.Converters { public class EnumToItemsSourceConverter : IValueConverter { + public class EnumValue + { + public Object Value { get; set; } + public String DisplayName { get; set; } + + public override string ToString() + { + return DisplayName; + } + } + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { Type result = value as Type; @@ -20,7 +31,7 @@ namespace Tango.SharedUI.Converters } else { - return Enum.GetValues(result).Cast<object>().Select(e => new { Value = e, DisplayName = (e as Enum).ToDescription() }).ToList(); + return Enum.GetValues(result).Cast<object>().Select(e => new EnumValue() { Value = e, DisplayName = (e as Enum).ToDescription() }).ToList(); } } diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs index fbc4f8a0a..0e96c14c8 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs @@ -186,6 +186,15 @@ namespace Tango.MachineService.Controllers LogManager.Log(ex, $"Error resetting synchronized job runs for machine '{machine.SerialNumber}'."); } + try + { + b.DataStoreItems.Where(x => x.MachineGuid == machine.Guid).Update(x => new DataStoreItem() { IsSynchronized = false }); + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error resetting synchronized data store items for machine '{machine.SerialNumber}'."); + } + //Reset Events. //b.MachinesEvents.Where(x => x.MachineGuid == machine.Guid).Update(x => new MachinesEvent() { IsSynchronized = false }); //Reset Jobs. @@ -755,7 +764,7 @@ namespace Tango.MachineService.Controllers //Send DataStore Items if (request.RequestDataStoreItems) { - var dataStoreItems = db.DataStoreItems.Where(x => x.MachineGuid == machine.Guid && !x.IsSynchronized).Take(request.MaxDataStoreItems).OrderByDescending(x => x.LastUpdated).ToList(); + var dataStoreItems = db.DataStoreItems.Where(x => x.MachineGuid == machine.Guid && !x.IsSynchronized & !x.IsDeleted).Take(request.MaxDataStoreItems).OrderByDescending(x => x.LastUpdated).ToList(); foreach (var item in dataStoreItems) { diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs index 41fa77771..601098814 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs @@ -24,4 +24,4 @@ using System.Runtime.InteropServices; // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("3.0.6.0")] +[assembly: AssemblyVersion("3.0.7.0")] |
