aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Modules
diff options
context:
space:
mode:
authorRoy <roy.mail.net@gmail.com>2017-12-22 13:28:53 +0200
committerRoy <roy.mail.net@gmail.com>2017-12-22 13:28:53 +0200
commit6091da506db1083f6ca707c24e509ca3470f6a73 (patch)
treeb6d87616e70e8035762aedab4271aeee4955f3a2 /Software/Visual_Studio/MachineStudio/Modules
parent9989238711695810324960c82b1bd85fc67c570e (diff)
downloadTango-6091da506db1083f6ca707c24e509ca3470f6a73.tar.gz
Tango-6091da506db1083f6ca707c24e509ca3470f6a73.zip
Implemented Remote To Local File Synchronization.
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Modules')
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/App.config15
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/AutoComplete/MachinesProvider.cs19
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/Tango.MachineStudio.Synchronization.csproj32
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/UserControl1.xaml12
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/UserControl1.xaml.cs28
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModelLocator.cs9
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModels/LocalSynchronizationViewVM.cs81
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModels/RemoteSynchronizationViewVM.cs372
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/Views/LocalSynchronizationView.xaml13
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/Views/RemoteSynchronizationView.xaml164
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/packages.config1
11 files changed, 683 insertions, 63 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/App.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/App.config
new file mode 100644
index 000000000..00d1c3941
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/App.config
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <configSections>
+ <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
+ <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
+ </configSections>
+ <entityFramework>
+ <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
+ <providers>
+ <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
+ <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
+ </providers>
+ </entityFramework>
+
+</configuration> \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/AutoComplete/MachinesProvider.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/AutoComplete/MachinesProvider.cs
new file mode 100644
index 000000000..887cb842d
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/AutoComplete/MachinesProvider.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.AutoComplete.Editors;
+using Tango.DAL.Observables;
+
+namespace Tango.MachineStudio.Synchronization.AutoComplete
+{
+ public class MachinesProvider : ISuggestionProvider
+ {
+ public IEnumerable GetSuggestions(string filter)
+ {
+ return ObservablesEntitiesAdapter.Instance.Machines.Where(x => x.SerialNumber.StartsWith(filter, StringComparison.CurrentCultureIgnoreCase)).ToList();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/Tango.MachineStudio.Synchronization.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/Tango.MachineStudio.Synchronization.csproj
index 8b2f0ae82..12323ff91 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/Tango.MachineStudio.Synchronization.csproj
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/Tango.MachineStudio.Synchronization.csproj
@@ -12,6 +12,8 @@
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
+ <NuGetPackageImportStamp>
+ </NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -31,6 +33,12 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
+ <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.dll</HintPath>
+ </Reference>
+ <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
+ </Reference>
<Reference Include="FontAwesome.WPF, Version=4.7.0.37774, Culture=neutral, PublicKeyToken=0758b07a11a4f466, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\FontAwesome.WPF.4.7.0.9\lib\net40\FontAwesome.WPF.dll</HintPath>
</Reference>
@@ -56,6 +64,7 @@
<HintPath>..\..\..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll</HintPath>
</Reference>
<Reference Include="System" />
+ <Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Data" />
<Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\MvvmLightLibs.5.3.0.0\lib\net45\System.Windows.Interactivity.dll</HintPath>
@@ -74,12 +83,14 @@
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="AutoComplete\MachinesProvider.cs" />
<Compile Include="Navigation\NavigationView.cs" />
<Compile Include="Navigation\SyncNavigationManager.cs" />
<Compile Include="ViewModelLocator.cs" />
<Compile Include="ViewModels\LocalSynchronizationViewVM.cs" />
<Compile Include="ViewModels\MainViewVM.cs" />
<Compile Include="ViewModels\MenuViewVM.cs" />
+ <Compile Include="ViewModels\RemoteSynchronizationViewVM.cs" />
<Compile Include="Views\RemoteSynchronizationView.xaml.cs">
<DependentUpon>RemoteSynchronizationView.xaml</DependentUpon>
</Compile>
@@ -92,18 +103,10 @@
<Compile Include="Views\MenuView.xaml.cs">
<DependentUpon>MenuView.xaml</DependentUpon>
</Compile>
- <Page Include="UserControl1.xaml">
- <Generator>MSBuild:Compile</Generator>
- <SubType>Designer</SubType>
- </Page>
<Compile Include="..\..\..\Versioning\GlobalVersionInfo.cs">
<Link>GlobalVersionInfo.cs</Link>
</Compile>
<Compile Include="SynchronizationModule.cs" />
- <Compile Include="UserControl1.xaml.cs">
- <DependentUpon>UserControl1.xaml</DependentUpon>
- <SubType>Code</SubType>
- </Compile>
<Page Include="Views\RemoteSynchronizationView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@@ -139,6 +142,7 @@
<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>
@@ -146,14 +150,26 @@
</None>
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\..\..\SideChains\Tango.AutoComplete\Tango.AutoComplete.csproj">
+ <Project>{bb2abb74-ba58-4812-83aa-ec8171f42df4}</Project>
+ <Name>Tango.AutoComplete</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\..\Tango.Core\Tango.Core.csproj">
<Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
<Name>Tango.Core</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\..\Tango.DAL.Local\Tango.DAL.Local.csproj">
+ <Project>{0e0eef3e-8f4e-4f23-9d19-479fd8d76c12}</Project>
+ <Name>Tango.DAL.Local</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\..\Tango.DAL.Observables\Tango.DAL.Observables.csproj">
<Project>{0ecd6da8-7aa6-48d9-8b65-279d176ad9af}</Project>
<Name>Tango.DAL.Observables</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\..\Tango.DAL.Remote\Tango.DAL.Remote.csproj">
+ <Project>{38197109-8610-4d3f-92b9-16d48df94d7c}</Project>
+ <Name>Tango.DAL.Remote</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\..\Tango.Logging\Tango.Logging.csproj">
<Project>{bc932dbd-7cdb-488c-99e4-f02cf441f55e}</Project>
<Name>Tango.Logging</Name>
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/UserControl1.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/UserControl1.xaml
deleted file mode 100644
index 50afe7e4e..000000000
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/UserControl1.xaml
+++ /dev/null
@@ -1,12 +0,0 @@
-<UserControl x:Class="Tango.MachineStudio.Synchronization.UserControl1"
- 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:local="clr-namespace:Tango.MachineStudio.Synchronization"
- mc:Ignorable="d"
- d:DesignHeight="300" d:DesignWidth="300">
- <Grid>
-
- </Grid>
-</UserControl>
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/UserControl1.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/UserControl1.xaml.cs
deleted file mode 100644
index 16186b6bd..000000000
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/UserControl1.xaml.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-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.MachineStudio.Synchronization
-{
- /// <summary>
- /// Interaction logic for UserControl1.xaml
- /// </summary>
- public partial class UserControl1 : UserControl
- {
- public UserControl1()
- {
- InitializeComponent();
- }
- }
-}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModelLocator.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModelLocator.cs
index 8eac609c2..a58ffe64b 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModelLocator.cs
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModelLocator.cs
@@ -21,6 +21,7 @@ namespace Tango.MachineStudio.Synchronization
SimpleIoc.Default.Register<MainViewVM>();
SimpleIoc.Default.Register<MenuViewVM>();
SimpleIoc.Default.Register<LocalSynchronizationViewVM>();
+ SimpleIoc.Default.Register<RemoteSynchronizationViewVM>();
SimpleIoc.Default.Unregister<SyncNavigationManager>();
@@ -50,5 +51,13 @@ namespace Tango.MachineStudio.Synchronization
return ServiceLocator.Current.GetInstance<LocalSynchronizationViewVM>();
}
}
+
+ public static RemoteSynchronizationViewVM RemoteSynchronizationViewVM
+ {
+ get
+ {
+ return ServiceLocator.Current.GetInstance<RemoteSynchronizationViewVM>();
+ }
+ }
}
} \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModels/LocalSynchronizationViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModels/LocalSynchronizationViewVM.cs
index 773080813..9c805cca4 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModels/LocalSynchronizationViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModels/LocalSynchronizationViewVM.cs
@@ -46,20 +46,21 @@ namespace Tango.MachineStudio.Synchronization.ViewModels
BrowseMasterDBCommand = new RelayCommand(BrowseMasterDB, (x) => !_isWorking);
BrowseSlaveDBCommand = new RelayCommand(BrowseSlaveDB, (x) => !_isWorking);
- CompareCommand = new RelayCommand(Compare, (x) => _masterDBFile != null && _slaveDBFile != null && !_isWorking);
+ CompareCommand = new RelayCommand(Compare, (x) => MasterDBFile != null && SlaveDBFile != null && !_isWorking);
CommitCommand = new RelayCommand(Commit, (x) => SelectedDifference != null && !_isWorking);
CommitAllCommand = new RelayCommand(CommitAll, (x) => Differences.Count > 0 && !_isWorking);
+ CleanCommand = new RelayCommand(CleanSlave, (x) => !_isWorking && SlaveDBFile != null);
if (File.Exists(SettingsManager.Default.MachineStudio.SynchronizationModule.LocalMasterDBFile))
{
- _masterDBFile = SettingsManager.Default.MachineStudio.SynchronizationModule.LocalMasterDBFile;
- MasterDBName = Path.GetFileName(_masterDBFile);
+ MasterDBFile = SettingsManager.Default.MachineStudio.SynchronizationModule.LocalMasterDBFile;
+ MasterDBName = Path.GetFileName(MasterDBFile);
}
if (File.Exists(SettingsManager.Default.MachineStudio.SynchronizationModule.LocalSlaveDBFile))
{
- _slaveDBFile = SettingsManager.Default.MachineStudio.SynchronizationModule.LocalSlaveDBFile;
- SlaveDBName = Path.GetFileName(_slaveDBFile);
+ SlaveDBFile = SettingsManager.Default.MachineStudio.SynchronizationModule.LocalSlaveDBFile;
+ SlaveDBName = Path.GetFileName(SlaveDBFile);
}
}
@@ -96,6 +97,11 @@ namespace Tango.MachineStudio.Synchronization.ViewModels
/// Gets or sets the commit all command.
/// </summary>
public RelayCommand CommitAllCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the clean command.
+ /// </summary>
+ public RelayCommand CleanCommand { get; set; }
#endregion
#region Properties
@@ -140,13 +146,68 @@ namespace Tango.MachineStudio.Synchronization.ViewModels
set { _slaveDBName = value; RaisePropertyChanged(nameof(SlaveDBName)); }
}
+ /// <summary>
+ /// Gets or sets the slave database file.
+ /// </summary>
+ public String SlaveDBFile
+ {
+ get { return _slaveDBFile; }
+ set { _slaveDBFile = value; RaisePropertyChangedAuto(); }
+ }
+
+ /// <summary>
+ /// Gets or sets the master database file.
+ /// </summary>
+ public String MasterDBFile
+ {
+ get { return _masterDBFile; }
+ set { _masterDBFile = value; RaisePropertyChangedAuto(); }
+ }
+
#endregion
#region Private Methods
+ private async void CleanSlave()
+ {
+ if (_notification.ShowQuestion("Are you sure you want to erase all data on slave database?"))
+ {
+ using (_notification.PushTaskItem("Clearing database..."))
+ {
+ try
+ {
+ _isWorking = true;
+ await Task.Factory.StartNew(() =>
+ {
+ SQLiteDataBase localDB = new SQLiteDataBase(SlaveDBFile);
+ localDB.LoadTables();
+ localDB.ClearDataBase();
+ try
+ {
+ localDB.Dispose();
+ }
+ catch { }
+ });
+
+ Differences.Clear();
+ }
+ catch (Exception ex)
+ {
+ ShowError(LogManager.Log(ex).Message);
+ }
+ finally
+ {
+ _isWorking = false;
+ InvalidateRelayCommands();
+ SelectedDifference = null;
+ }
+ }
+ }
+ }
+
private void Compare()
{
- _comparer = new LocalDBComparer(new SQLiteDataBase(_masterDBFile), new SQLiteDataBase(_slaveDBFile));
+ _comparer = new LocalDBComparer(new SQLiteDataBase(MasterDBFile), new SQLiteDataBase(SlaveDBFile));
Task.Factory.StartNew(() =>
{
@@ -179,8 +240,8 @@ namespace Tango.MachineStudio.Synchronization.ViewModels
SelectedDifference = null;
InvalidateRelayCommands();
- SettingsManager.Default.MachineStudio.SynchronizationModule.LocalMasterDBFile = _masterDBFile;
- SettingsManager.Default.MachineStudio.SynchronizationModule.LocalSlaveDBFile = _slaveDBFile;
+ SettingsManager.Default.MachineStudio.SynchronizationModule.LocalMasterDBFile = MasterDBFile;
+ SettingsManager.Default.MachineStudio.SynchronizationModule.LocalSlaveDBFile = SlaveDBFile;
SettingsManager.SaveDefaultSettings();
}
}
@@ -258,7 +319,7 @@ namespace Tango.MachineStudio.Synchronization.ViewModels
String file = BrowseForFilePath();
if (file != null)
{
- _slaveDBFile = file;
+ SlaveDBFile = file;
SlaveDBName = Path.GetFileName(file);
InvalidateRelayCommands();
}
@@ -269,7 +330,7 @@ namespace Tango.MachineStudio.Synchronization.ViewModels
String file = BrowseForFilePath();
if (file != null)
{
- _masterDBFile = file;
+ MasterDBFile = file;
MasterDBName = Path.GetFileName(file);
InvalidateRelayCommands();
}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModels/RemoteSynchronizationViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModels/RemoteSynchronizationViewVM.cs
new file mode 100644
index 000000000..e14b0ffb9
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModels/RemoteSynchronizationViewVM.cs
@@ -0,0 +1,372 @@
+using Microsoft.Win32;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Data.Entity.Validation;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Tango.Core.Commands;
+using Tango.DAL.Local.DB;
+using Tango.DAL.Observables;
+using Tango.DAL.Remote.DB;
+using Tango.Logging;
+using Tango.MachineStudio.Common.Notifications;
+using Tango.MachineStudio.Common.StudioApplication;
+using Tango.MachineStudio.Synchronization.Navigation;
+using Tango.Settings;
+using Tango.SharedUI;
+using Tango.Synchronization;
+using Tango.Synchronization.Local;
+using Tango.Synchronization.Remote;
+
+namespace Tango.MachineStudio.Synchronization.ViewModels
+{
+ public class RemoteSynchronizationViewVM : ViewModel, IShutdownRequestBlocker
+ {
+ private SyncNavigationManager _navigation;
+ private String _slaveDBFile;
+ private INotificationProvider _notification;
+ private bool _isWorking;
+ private RemoteDBComparer _comparer;
+ private RemoteDB _remoteDB;
+ private LocalDB _localDB;
+
+ #region Constructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="LocalSynchronizationViewVM"/> class.
+ /// </summary>
+ /// <param name="navigation">The navigation.</param>
+ /// <param name="notification">The notification.</param>
+ public RemoteSynchronizationViewVM(SyncNavigationManager navigation, INotificationProvider notification)
+ {
+ _navigation = navigation;
+ _notification = notification;
+
+ BackCommand = new RelayCommand(() => _navigation.NavigateTo(NavigationView.MenuView));
+
+ Differences = new ObservableCollection<Diff>();
+
+ BrowseSlaveDBCommand = new RelayCommand(BrowseSlaveDB, (x) => !_isWorking);
+ CompareCommand = new RelayCommand(Compare, (x) => SlaveDBFile != null && !_isWorking && SelectedMachine != null);
+ CommitCommand = new RelayCommand(Commit, (x) => SelectedDifference != null && !_isWorking && SelectedMachine != null);
+ CommitAllCommand = new RelayCommand(CommitAll, (x) => Differences.Count > 0 && !_isWorking && SelectedMachine != null);
+ CleanCommand = new RelayCommand(CleanSlave, (x) => !_isWorking && SlaveDBFile != null);
+
+ if (File.Exists(SettingsManager.Default.MachineStudio.SynchronizationModule.RemoteSQLiteFile))
+ {
+ SlaveDBFile = SettingsManager.Default.MachineStudio.SynchronizationModule.RemoteSQLiteFile;
+ SlaveDBName = Path.GetFileName(SlaveDBFile);
+ }
+ }
+
+ #endregion
+
+ #region Commands
+
+ /// <summary>
+ /// Gets or sets the back command.
+ /// </summary>
+ public RelayCommand BackCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the browse master database command.
+ /// </summary>
+ public RelayCommand BrowseMasterDBCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the browse slave database command.
+ /// </summary>
+ public RelayCommand BrowseSlaveDBCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the compare command.
+ /// </summary>
+ public RelayCommand CompareCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the commit command.
+ /// </summary>
+ public RelayCommand CommitCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the commit all command.
+ /// </summary>
+ public RelayCommand CommitAllCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the clean command.
+ /// </summary>
+ public RelayCommand CleanCommand { get; set; }
+
+ #endregion
+
+ #region Properties
+
+ private ObservableCollection<Diff> _differences;
+ /// <summary>
+ /// Gets or sets the differences.
+ /// </summary>
+ public ObservableCollection<Diff> Differences
+ {
+ get { return _differences; }
+ set { _differences = value; RaisePropertyChanged(nameof(Differences)); }
+ }
+
+ private Diff _selectedDifference;
+ /// <summary>
+ /// Gets or sets the selected difference.
+ /// </summary>
+ public Diff SelectedDifference
+ {
+ get { return _selectedDifference; }
+ set { _selectedDifference = value; RaisePropertyChanged(nameof(SelectedDifference)); InvalidateRelayCommands(); }
+ }
+
+ private String _slaveDBName;
+ /// <summary>
+ /// Gets or sets the name of the slave database.
+ /// </summary>
+ public String SlaveDBName
+ {
+ get { return _slaveDBName; }
+ set { _slaveDBName = value; RaisePropertyChanged(nameof(SlaveDBName)); }
+ }
+
+ private Machine _selectedMachine;
+ /// <summary>
+ /// Gets or sets the selected machine.
+ /// </summary>
+ public Machine SelectedMachine
+ {
+ get { return _selectedMachine; }
+ set { _selectedMachine = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
+ }
+
+ /// <summary>
+ /// Gets or sets the slave database file.
+ /// </summary>
+ public String SlaveDBFile
+ {
+ get { return _slaveDBFile; }
+ set { _slaveDBFile = value; RaisePropertyChangedAuto(); }
+ }
+ #endregion
+
+ #region Private Methods
+
+ private async void CleanSlave()
+ {
+ if (_notification.ShowQuestion("Are you sure you want to erase all data on slave database?"))
+ {
+ using (_notification.PushTaskItem("Clearing database..."))
+ {
+ try
+ {
+ _isWorking = true;
+ await Task.Factory.StartNew(() =>
+ {
+ SQLiteDataBase localDB = new SQLiteDataBase(SlaveDBFile);
+ localDB.LoadTables();
+ localDB.ClearDataBase();
+ try
+ {
+ localDB.Dispose();
+ }
+ catch{ }
+ });
+
+ Differences.Clear();
+ }
+ catch (Exception ex)
+ {
+ ShowError(LogManager.Log(ex).Message);
+ }
+ finally
+ {
+ _isWorking = false;
+ InvalidateRelayCommands();
+ SelectedDifference = null;
+ }
+ }
+ }
+ }
+
+ private void Compare()
+ {
+ Task.Factory.StartNew(() =>
+ {
+ using (_notification.PushTaskItem("Comparing Databases..."))
+ {
+ try
+ {
+ if (_comparer != null)
+ {
+ _comparer.Dispose();
+ }
+
+ _remoteDB = RemoteDB.CreateDefault();
+ _localDB = new LocalDB(SlaveDBFile);
+ _comparer = new RemoteDBComparer(_remoteDB, _localDB, SelectedMachine.SerialNumber);
+ _isWorking = true;
+ InvalidateRelayCommands();
+ Thread.Sleep(1500);
+ var diffs = _comparer.Compare();
+ Differences = new ObservableCollection<Diff>(diffs);
+
+ if (diffs.Where(x => x.Action != DiffAction.ReplaceTableDataInSlave).Count() > 0)
+ {
+ ShowInfo("Found " + Differences.Where(x => x.Action != DiffAction.ReplaceTableDataInSlave).Count() + " differences.");
+ }
+ else
+ {
+ ShowInfo("The master and slave databases are synchronized.");
+ }
+ }
+ catch (Exception ex)
+ {
+ ShowError(ex.Message);
+ }
+ finally
+ {
+ _isWorking = false;
+ SelectedDifference = null;
+ InvalidateRelayCommands();
+
+ SettingsManager.Default.MachineStudio.SynchronizationModule.RemoteSQLiteFile = SlaveDBFile;
+ SettingsManager.SaveDefaultSettings();
+ }
+ }
+ });
+ }
+
+ private void Commit()
+ {
+ Task.Factory.StartNew(() =>
+ {
+ using (_notification.PushTaskItem("Committing difference..."))
+ {
+ try
+ {
+ _isWorking = true;
+ InvalidateRelayCommands();
+ Thread.Sleep(1500);
+ SelectedDifference.Commit();
+ _remoteDB.SaveChanges();
+ _localDB.SaveChanges();
+
+ InvokeUINow(() => Differences.Remove(SelectedDifference));
+ }
+ catch (Exception ex)
+ {
+ ShowError(ex.Message);
+ }
+ finally
+ {
+ _isWorking = false;
+ SelectedDifference = null;
+ InvalidateRelayCommands();
+ }
+ }
+ });
+ }
+
+ private void CommitAll()
+ {
+ Task.Factory.StartNew(() =>
+ {
+ using (_notification.PushTaskItem("Committing all differences..."))
+ {
+ try
+ {
+ _isWorking = true;
+ InvalidateRelayCommands();
+ Thread.Sleep(1500);
+
+ for (int i = 0; i < Differences.Count; i++)
+ {
+ var diff = Differences[i];
+ using (_notification.PushTaskItem("Committing difference " + (Differences.IndexOf(diff) + 1) + "..."))
+ {
+ diff.Commit();
+ InvokeUINow(() => Differences.Remove(diff));
+ i--;
+ }
+ }
+
+ _remoteDB.SaveChanges();
+ _localDB.SaveChanges();
+ }
+ catch (DbEntityValidationException ex)
+ {
+ String message = "The following validation errors occurred while trying to update the database." + Environment.NewLine + Environment.NewLine;
+
+ foreach (var error in ex.EntityValidationErrors.SelectMany(x => x.ValidationErrors).ToList())
+ {
+ message += error.ErrorMessage + Environment.NewLine;
+ }
+
+ ShowError(message);
+ }
+ catch (Exception ex)
+ {
+ ShowError(ex.Message);
+ }
+ finally
+ {
+ _isWorking = false;
+ SelectedDifference = null;
+ InvalidateRelayCommands();
+ }
+ }
+ });
+ }
+
+ private void BrowseSlaveDB()
+ {
+ String file = BrowseForFilePath();
+ if (file != null)
+ {
+ SlaveDBFile = file;
+ SlaveDBName = Path.GetFileName(file);
+ InvalidateRelayCommands();
+ }
+ }
+
+ private String BrowseForFilePath()
+ {
+ OpenFileDialog dlg = new OpenFileDialog();
+ dlg.Title = "Select SQLite Database File";
+ dlg.Filter = "SQLite Database|*.db";
+ if (dlg.ShowDialog().Value)
+ {
+ return dlg.FileName;
+ }
+ return null;
+ }
+
+ private void ShowError(String message)
+ {
+ InvokeUINow(() => _notification.ShowError(message));
+ }
+
+ private void ShowInfo(String message)
+ {
+ InvokeUINow(() => _notification.ShowInfo(message));
+ }
+
+ public Task<bool> OnShutdownRequest()
+ {
+ if (_comparer != null)
+ {
+ _comparer.Dispose();
+ }
+ return Task.FromResult(true);
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/Views/LocalSynchronizationView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/Views/LocalSynchronizationView.xaml
index e52a8bfc1..72297e2cb 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/Views/LocalSynchronizationView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/Views/LocalSynchronizationView.xaml
@@ -75,7 +75,7 @@
<Image Source="../Images/sqlite.png" Width="100" Margin="10" Opacity="0.8" HorizontalAlignment="Left" RenderOptions.BitmapScalingMode="Fant"></Image>
<TextBlock Background="{StaticResource badgeBackground}" Padding="5" Width="200" FontSize="14" HorizontalAlignment="Left">Master Database</TextBlock>
<StackPanel Orientation="Horizontal" Margin="0 5 0 0">
- <TextBox IsReadOnly="True" Width="130" BorderBrush="#4E4E4E" Text="{Binding MasterDBName}"></TextBox>
+ <TextBox IsReadOnly="True" Width="130" BorderBrush="#4E4E4E" Text="{Binding MasterDBName}" ToolTip="{Binding MasterDBFile}"></TextBox>
<Button Margin="5 0 0 0" Cursor="Hand" VerticalAlignment="Center" Style="{DynamicResource MetroCircleButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding BrowseMasterDBCommand}" ToolTip="Browse for master database file">
<fa:ImageAwesome Icon="FolderOpen" Width="24" Foreground="Gray"></fa:ImageAwesome>
</Button>
@@ -86,7 +86,7 @@
<Image Source="../Images/sqlite.png" Width="80" Margin="10" Opacity="0.8" HorizontalAlignment="Left" RenderOptions.BitmapScalingMode="Fant"></Image>
<TextBlock Background="{StaticResource badgeBackground}" Padding="5" Width="200" FontSize="14" HorizontalAlignment="Left">Slave Database</TextBlock>
<StackPanel Orientation="Horizontal" Margin="0 5 0 0">
- <TextBox IsReadOnly="True" Width="130" BorderBrush="#4E4E4E" Text="{Binding SlaveDBName}"></TextBox>
+ <TextBox IsReadOnly="True" Width="130" BorderBrush="#4E4E4E" Text="{Binding SlaveDBName}" ToolTip="{Binding SlaveDBFile}"></TextBox>
<Button Margin="5 0 0 0" Cursor="Hand" VerticalAlignment="Center" Style="{DynamicResource MetroCircleButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding BrowseSlaveDBCommand}" ToolTip="Browse for slave database file">
<fa:ImageAwesome Icon="FolderOpen" Width="24" Foreground="Gray"></fa:ImageAwesome>
</Button>
@@ -101,7 +101,7 @@
</StackPanel>
</Button>
- <Grid Grid.Column="1" Grid.RowSpan="2">
+ <Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="205*"/>
@@ -131,6 +131,13 @@
</ListBox.ItemTemplate>
</ListBox>
</Grid>
+
+ <Button Margin="10 10" Grid.Column="1" Grid.Row="1" Width="160" Height="40" Background="#FF4F4F" BorderBrush="#FF4F4F" HorizontalAlignment="Right" Command="{Binding CleanCommand}">
+ <StackPanel Orientation="Horizontal">
+ <TextBlock VerticalAlignment="Center" Margin="10 0 10 0">CLEAN SLAVE</TextBlock>
+ <fa:ImageAwesome Icon="TrashOutline" VerticalAlignment="Center" Foreground="{Binding RelativeSource={RelativeSource AncestorType=Button},Path=Foreground}" Width="16"></fa:ImageAwesome>
+ </StackPanel>
+ </Button>
</Grid>
</GroupBox>
</Grid>
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/Views/RemoteSynchronizationView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/Views/RemoteSynchronizationView.xaml
index 92c8fa674..2487aab64 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/Views/RemoteSynchronizationView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/Views/RemoteSynchronizationView.xaml
@@ -3,10 +3,170 @@
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:providers="clr-namespace:Tango.MachineStudio.Synchronization.AutoComplete"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:synchronization="clr-namespace:Tango.Synchronization;assembly=Tango.Synchronization"
+ xmlns:autoComplete="clr-namespace:Tango.AutoComplete.Editors;assembly=Tango.AutoComplete"
+ xmlns:global="clr-namespace:Tango.MachineStudio.Synchronization"
+
xmlns:local="clr-namespace:Tango.MachineStudio.Synchronization.Views"
+ xmlns:fa="http://schemas.fontawesome.io/icons/"
mc:Ignorable="d"
- d:DesignHeight="720" d:DesignWidth="1280" Background="White">
+ d:DesignHeight="720" d:DesignWidth="1280" Background="White" DataContext="{x:Static global:ViewModelLocator.RemoteSynchronizationViewVM}">
+ <UserControl.Resources>
+
+ <providers:MachinesProvider x:Key="MachinesProvider"></providers:MachinesProvider>
+
+ <VisualBrush x:Key="badgeBackground">
+ <VisualBrush.Visual>
+ <Border>
+ <Path Stretch="Fill" RenderTransformOrigin="0.5,0.5">
+ <Path.RenderTransform>
+ <ScaleTransform ScaleX="-1"></ScaleTransform>
+ </Path.RenderTransform>
+ <Path.Fill>
+ <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
+ <GradientStop Color="#EEEEEE" Offset="0.4" />
+ <GradientStop Color="White" Offset="1"/>
+ </LinearGradientBrush>
+ </Path.Fill>
+ <Path.Data>
+ <PathGeometry Figures="M 53.868 43.913 H 19.511 c -0.444 0 -0.875 -0.151 -1.221 -0.428 L 0.734 29.439 c -0.978 -0.783 -0.978 -2.271 0 -3.053 L 18.29 12.341 c 0.347 -0.277 0.777 -0.428 1.221 -0.428 h 34.356 c 1.081 0 1.958 0.877 1.958 1.958 v 28.084 c 0 1.081 -0.876 1.958 -1.957 1.958 z" FillRule="NonZero"/>
+ </Path.Data>
+ </Path>
+ </Border>
+ </VisualBrush.Visual>
+ </VisualBrush>
+ </UserControl.Resources>
+
<Grid>
- <TextBlock>Remote Sync</TextBlock>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="100"/>
+ <RowDefinition Height="*"/>
+ </Grid.RowDefinitions>
+ <Grid>
+ <StackPanel Orientation="Horizontal" Margin="20">
+ <Button Style="{StaticResource MaterialDesignFlatButton}" Padding="0" Margin="0 5 0 0" VerticalAlignment="Center" Command="{Binding BackCommand}">
+ <materialDesign:PackIcon Kind="Backburger" Foreground="#303030" ToolTip="Back" VerticalAlignment="Center" Width="40" Height="40"></materialDesign:PackIcon>
+ </Button>
+ <TextBlock VerticalAlignment="Center" Margin="10 0 0 0" FontSize="30">Local Database Synchronization</TextBlock>
+ </StackPanel>
+ </Grid>
+ <Grid Grid.Row="1">
+ <Grid Margin="20">
+ <GroupBox Header="Compare &amp; Synchronize">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="57*"/>
+ <RowDefinition Height="Auto"/>
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition MaxWidth="250" />
+ <ColumnDefinition/>
+ </Grid.ColumnDefinitions>
+
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+
+ <StackPanel HorizontalAlignment="Left" VerticalAlignment="Center" Margin="20 0 0 0">
+ <Image Source="../Images/remote-db.png" Width="100" Margin="10" Opacity="0.8" HorizontalAlignment="Left" RenderOptions.BitmapScalingMode="Fant"></Image>
+ <TextBlock Background="{StaticResource badgeBackground}" Padding="5" Width="200" FontSize="14" HorizontalAlignment="Left">Remote Database</TextBlock>
+ <StackPanel Orientation="Horizontal" Margin="0 5 0 0">
+ <fa:ImageAwesome Icon="Key" Width="16" Height="16"></fa:ImageAwesome>
+ <autoComplete:AutoCompleteTextBox Margin="5 0 0 0" Width="170" materialDesign:HintAssist.Hint="Enter machine serial number" DisplayMember="SerialNumber" Provider="{StaticResource ResourceKey=MachinesProvider}" SelectedItem="{Binding SelectedMachine,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
+ <autoComplete:AutoCompleteTextBox.ItemTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding SerialNumber}"></TextBlock>
+ </DataTemplate>
+ </autoComplete:AutoCompleteTextBox.ItemTemplate>
+ <autoComplete:AutoCompleteTextBox.LoadingContent>
+ <TextBlock Text="Loading..." Margin="5" FontSize="14" />
+ </autoComplete:AutoCompleteTextBox.LoadingContent>
+ </autoComplete:AutoCompleteTextBox>
+ </StackPanel>
+ </StackPanel>
+
+ <StackPanel HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="1" Margin="20 0 0 0">
+ <Image Source="../Images/sqlite.png" Width="80" Margin="10" Opacity="0.8" HorizontalAlignment="Left" RenderOptions.BitmapScalingMode="Fant"></Image>
+ <TextBlock Background="{StaticResource badgeBackground}" Padding="5" Width="200" FontSize="14" HorizontalAlignment="Left">SQLite Database</TextBlock>
+ <StackPanel Orientation="Horizontal" Margin="0 5 0 0">
+ <TextBox IsReadOnly="True" Width="130" BorderBrush="#4E4E4E" Text="{Binding SlaveDBName}" ToolTip="{Binding SlaveDBFile}"></TextBox>
+ <Button Margin="5 0 0 0" Cursor="Hand" VerticalAlignment="Center" Style="{DynamicResource MetroCircleButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding BrowseSlaveDBCommand}" ToolTip="Browse for slave database file">
+ <fa:ImageAwesome Icon="FolderOpen" Width="24" Foreground="Gray"></fa:ImageAwesome>
+ </Button>
+ </StackPanel>
+ </StackPanel>
+ </Grid>
+
+ <Button Margin="20 10" Grid.Row="1" Width="160" Height="40" HorizontalAlignment="Left" Command="{Binding CompareCommand}">
+ <StackPanel Orientation="Horizontal">
+ <TextBlock VerticalAlignment="Center" Margin="10 0 10 0">COMPARE</TextBlock>
+ <fa:ImageAwesome Icon="LongArrowRight" VerticalAlignment="Center" Foreground="{Binding RelativeSource={RelativeSource AncestorType=Button},Path=Foreground}" Width="16"></fa:ImageAwesome>
+ </StackPanel>
+ </Button>
+
+ <Grid Grid.Column="1">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="20"/>
+ <RowDefinition Height="205*"/>
+ </Grid.RowDefinitions>
+ <TextBlock Margin="10 5 0 0" FontSize="14">Differences</TextBlock>
+ <ListBox Margin="10" Background="#F1F1F1" Grid.Row="1" ItemsSource="{Binding Differences}" SelectedItem="{Binding SelectedDifference,Mode=TwoWay}">
+ <ListBox.ItemTemplate>
+ <DataTemplate>
+ <Border Padding="10">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Cog" Width="20" Height="20" Foreground="Gray"></fa:ImageAwesome>
+ <TextBlock VerticalAlignment="Center" Margin="10 0 0 0" Text="{Binding Description}">
+ <TextBlock.Style>
+ <Style TargetType="TextBlock">
+ <Setter Property="Foreground" Value="Red"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Action}" Value="ReplaceTableDataInSlave">
+ <Setter Property="Foreground" Value="#404040"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </TextBlock.Style>
+ </TextBlock>
+ </StackPanel>
+ </Border>
+ </DataTemplate>
+ </ListBox.ItemTemplate>
+ </ListBox>
+ </Grid>
+
+ <Grid Grid.Row="1" Grid.Column="1">
+ <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
+ <Button Margin="10 10" Grid.Row="1" Width="240" Height="40" Background="#FF4F4F" BorderBrush="#FF4F4F" HorizontalAlignment="Right" Command="{Binding CleanCommand}">
+ <StackPanel Orientation="Horizontal">
+ <TextBlock VerticalAlignment="Center" Margin="10 0 10 0">CLEAN SQLITE DATABASE</TextBlock>
+ <fa:ImageAwesome Icon="TrashOutline" VerticalAlignment="Center" Foreground="{Binding RelativeSource={RelativeSource AncestorType=Button},Path=Foreground}" Width="16"></fa:ImageAwesome>
+ </StackPanel>
+ </Button>
+ <Button Margin="10 10" Grid.Row="1" Width="160" Height="40" HorizontalAlignment="Right" Command="{Binding CommitCommand}">
+ <StackPanel Orientation="Horizontal">
+ <TextBlock VerticalAlignment="Center" Margin="10 0 10 0">COMMIT</TextBlock>
+ <fa:ImageAwesome Icon="Bolt" VerticalAlignment="Center" Foreground="{Binding RelativeSource={RelativeSource AncestorType=Button},Path=Foreground}" Width="16"></fa:ImageAwesome>
+ </StackPanel>
+ </Button>
+ <Button Margin="10 10" Grid.Row="1" Width="160" Height="40" HorizontalAlignment="Right" Command="{Binding CommitAllCommand}">
+ <StackPanel Orientation="Horizontal">
+ <TextBlock VerticalAlignment="Center" Margin="10 0 10 0">COMMIT ALL</TextBlock>
+ <fa:ImageAwesome Icon="SortAmountAsc" VerticalAlignment="Center" Foreground="{Binding RelativeSource={RelativeSource AncestorType=Button},Path=Foreground}" Width="16"></fa:ImageAwesome>
+ </StackPanel>
+ </Button>
+ </StackPanel>
+ </Grid>
+ </Grid>
+ </GroupBox>
+ </Grid>
+
+
+ </Grid>
</Grid>
</UserControl>
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/packages.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/packages.config
index 42945b407..8d8f972d1 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/packages.config
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/packages.config
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CommonServiceLocator" version="1.3" targetFramework="net46" />
+ <package id="EntityFramework" version="6.0.0" targetFramework="net46" />
<package id="FontAwesome.WPF" version="4.7.0.9" targetFramework="net46" />
<package id="MahApps.Metro" version="1.5.0" targetFramework="net46" />
<package id="MaterialDesignColors" version="1.1.2" targetFramework="net46" />