diff options
| author | Roy <roy.mail.net@gmail.com> | 2017-12-22 13:28:53 +0200 |
|---|---|---|
| committer | Roy <roy.mail.net@gmail.com> | 2017-12-22 13:28:53 +0200 |
| commit | 6091da506db1083f6ca707c24e509ca3470f6a73 (patch) | |
| tree | b6d87616e70e8035762aedab4271aeee4955f3a2 /Software/Visual_Studio/MachineStudio | |
| parent | 9989238711695810324960c82b1bd85fc67c570e (diff) | |
| download | Tango-6091da506db1083f6ca707c24e509ca3470f6a73.tar.gz Tango-6091da506db1083f6ca707c24e509ca3470f6a73.zip | |
Implemented Remote To Local File Synchronization.
Diffstat (limited to 'Software/Visual_Studio/MachineStudio')
18 files changed, 823 insertions, 127 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 & 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" /> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/MaterialDesign.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/MaterialDesign.xaml index 482e852d6..58bb9ef34 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/MaterialDesign.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/MaterialDesign.xaml @@ -1,5 +1,7 @@ <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:converters="clr-namespace:MaterialDesignThemes.Wpf.Converters;assembly=MaterialDesignThemes.Wpf" + xmlns:editors="clr-namespace:Tango.AutoComplete.Editors;assembly=Tango.AutoComplete" xmlns:local="clr-namespace:Tango.MachineStudio.Common.Resources"> <ResourceDictionary.MergedDictionaries> <!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! --> @@ -61,5 +63,116 @@ <SolidColorBrush x:Key="IdealForegroundDisabledBrush" Color="{DynamicResource Primary500}" Opacity="0.4" /> </ResourceDictionary> + <!--Styles--> + <ResourceDictionary> + + <BooleanToVisibilityConverter x:Key="BoolToVisConverter" /> + <converters:TextFieldHintVisibilityConverter x:Key="TextFieldHintVisibilityConverter" /> + + <Style TargetType="editors:AutoCompleteTextBox" > + <Setter Property="Focusable" Value="True" /> + <Setter Property="BorderThickness" Value="0 0 0 1"/> + <Setter Property="BorderBrush" Value="{DynamicResource MaterialDesignTextBoxBorder}" /> + <Setter Property="Background" Value="Transparent"/> + <!--<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>--> + <Setter Property="HorizontalContentAlignment" Value="Left"/> + <Setter Property="VerticalContentAlignment" Value="Top"/> + <Setter Property="FocusVisualStyle" Value="{x:Null}"/> + <Setter Property="AllowDrop" Value="true"/> + <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/> + <Setter Property="Stylus.IsFlicksEnabled" Value="False"/> + <Setter Property="Validation.ErrorTemplate" Value="{DynamicResource MaterialDesignValidationErrorTemplate}"/> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="{x:Type editors:AutoCompleteTextBox}"> + <Grid> + <DockPanel> + <ContentPresenter ContentSource="Icon" + x:Name="PART_Icon" + Visibility="{TemplateBinding IconVisibility}" /> + <Grid> + <TextBlock x:Name="PART_Watermark" + Text="{TemplateBinding Watermark}" + Visibility="Collapsed" + VerticalAlignment="Center" + HorizontalAlignment="Left" + Focusable="False" + Foreground="Gray" + Margin="3,0" /> + <TextBox x:Name="PART_Editor" + Focusable="True" + HorizontalAlignment="Stretch" + VerticalAlignment="Center" + Style="{StaticResource ResourceKey=MaterialDesignTextBox}" + MaxLength="{Binding Path=MaxLength, RelativeSource={RelativeSource Mode=TemplatedParent}, Mode=TwoWay}" + CharacterCasing="{Binding Path=CharacterCasing, RelativeSource={RelativeSource Mode=TemplatedParent}, Mode=TwoWay}" + Text="{Binding Path=Text, RelativeSource={RelativeSource Mode=TemplatedParent}, Mode=TwoWay}" /> + </Grid> + </DockPanel> + <Popup x:Name="PART_Popup" + IsOpen="{Binding Path=IsDropDownOpen, RelativeSource={RelativeSource Mode=TemplatedParent},Mode=TwoWay}" + Width="{TemplateBinding ActualWidth}" + HorizontalOffset="0" + MinHeight="25" + MaxHeight="600" + AllowsTransparency="True" + PopupAnimation="Slide" + Focusable="False"> + <Border Background="White" + BorderThickness="1" + BorderBrush="#BDBDBD" + CornerRadius="0" + Padding="2"> + <Grid> + <ListBox x:Name="PART_Selector" + ItemTemplate="{TemplateBinding ItemTemplate}" + ItemTemplateSelector="{TemplateBinding ItemTemplateSelector}" + Focusable="False" + BorderThickness="0" + MaxHeight="{Binding Path=MaxPopupHeight, RelativeSource={RelativeSource Mode=TemplatedParent},Mode=TwoWay}" + ScrollViewer.HorizontalScrollBarVisibility="Auto" + ScrollViewer.VerticalScrollBarVisibility="Auto" + > + </ListBox> + <Border Visibility="{Binding Path=IsLoading, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource ResourceKey=BoolToVisConverter}}"> + <ContentPresenter ContentSource="LoadingContent"/> + </Border> + </Grid> + </Border> + </Popup> + + </Grid> + <!--</Border>--> + <ControlTemplate.Triggers> + <Trigger Property="Text" + Value="" + SourceName="PART_Editor"> + <Setter Property="Visibility" + Value="Visible" + TargetName="PART_Watermark" /> + </Trigger> + <Trigger Property="IconPlacement" + Value="Left"> + <Setter Property="DockPanel.Dock" + Value="Left" + TargetName="PART_Icon" /> + </Trigger> + <Trigger Property="IconPlacement" + Value="Right"> + <Setter Property="DockPanel.Dock" + Value="Right" + TargetName="PART_Icon" /> + </Trigger> + <Trigger Property="Validation.HasError" Value="True"> + <Setter Property="BorderBrush" + Value="Red"/> + </Trigger> + </ControlTemplate.Triggers> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + </ResourceDictionary> + </ResourceDictionary.MergedDictionaries> </ResourceDictionary>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IStudioApplicationManager.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IStudioApplicationManager.cs index 0ee27fbf6..740c257b9 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IStudioApplicationManager.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IStudioApplicationManager.cs @@ -8,6 +8,7 @@ namespace Tango.MachineStudio.Common.StudioApplication { public interface IStudioApplicationManager { + bool IsShuttingDown { get;} void ShutDown(); } } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj index 70962a2f7..32466e45a 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj @@ -126,6 +126,10 @@ </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> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config index 250f57a4d..b31d56717 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> - <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections> <startup> @@ -11,6 +10,15 @@ <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> + <system.data> + <DbProviderFactories> + <remove invariant="System.Data.SQLite.EF6" /> + <add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" /> + <remove invariant="System.Data.SQLite" /> + <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /> + </DbProviderFactories> + </system.data> </configuration>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml index 6974f54be..8e5876e79 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml @@ -9,64 +9,9 @@ <ResourceDictionary.MergedDictionaries> <!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! --> <!-- Accent and AppTheme setting --> - <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml"> - </ResourceDictionary> - <!--Material Design--> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/materialdesigncolor.lightblue.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/materialdesigncolor.yellow.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Button.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.CheckBox.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ListBox.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.PopupBox.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.RadioButton.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ToggleButton.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.TextBlock.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.Label.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.Slider.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.ProgressBar.xaml"/> - - - <!--MahApps Brushes--> - <ResourceDictionary> - <SolidColorBrush x:Key="HighlightBrush" Color="{DynamicResource Primary700}" /> - <SolidColorBrush x:Key="AccentColorBrush" Color="{DynamicResource Primary500}" /> - <SolidColorBrush x:Key="AccentColorBrush2" Color="{DynamicResource Primary400}" /> - <SolidColorBrush x:Key="AccentColorBrush3" Color="{DynamicResource Primary300}" /> - <SolidColorBrush x:Key="AccentColorBrush4" Color="{DynamicResource Primary200}" /> - <SolidColorBrush x:Key="WindowTitleColorBrush" Color="{DynamicResource Primary700}" /> - <SolidColorBrush x:Key="AccentSelectedColorBrush" Color="{DynamicResource Primary500Foreground}" /> - <LinearGradientBrush x:Key="ProgressBrush" EndPoint="0.001,0.5" StartPoint="1.002,0.5"> - <GradientStop Color="{DynamicResource Primary700}" Offset="0" /> - <GradientStop Color="{DynamicResource Primary300}" Offset="1" /> - </LinearGradientBrush> - <SolidColorBrush x:Key="CheckmarkFill" Color="{DynamicResource Primary500}" /> - <SolidColorBrush x:Key="RightArrowFill" Color="{DynamicResource Primary500}" /> - <SolidColorBrush x:Key="IdealForegroundColorBrush" Color="{DynamicResource Primary500Foreground}" /> - <SolidColorBrush x:Key="IdealForegroundDisabledBrush" Color="{DynamicResource Primary500}" Opacity="0.4" /> - </ResourceDictionary> + <ResourceDictionary Source="pack://application:,,,/Tango.MachineStudio.Common;component/Resources/MaterialDesign.xaml"></ResourceDictionary> - <!-- Include the Dragablz Material Design style --> + <!-- Include the Dragablz Material Design style --> <ResourceDictionary Source="pack://application:,,,/Dragablz;component/Themes/materialdesign.xaml"/> <ResourceDictionary> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Navigation/DefaultNavigationManager.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Navigation/DefaultNavigationManager.cs index 10314ae62..15f2fe422 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Navigation/DefaultNavigationManager.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Navigation/DefaultNavigationManager.cs @@ -11,7 +11,10 @@ namespace Tango.MachineStudio.UI.Navigation { public void NavigateTo(NavigationView view) { - MainWindow.Instance.TransitionControl.AutoNavigate(view.ToString()); + MainWindow.Instance.Dispatcher.Invoke(() => + { + MainWindow.Instance.TransitionControl.AutoNavigate(view.ToString()); + }); } } } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs index b95a74a3e..ea4234fd8 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs @@ -23,9 +23,13 @@ namespace Tango.MachineStudio.UI.StudioApplication _navigationManager = navigationManager; } + public bool IsShuttingDown { get; private set; } + public async void ShutDown() { - _navigationManager.NavigateTo(NavigationView.ShutdownView); + if (IsShuttingDown) return; + + IsShuttingDown = true; await Task.Factory.StartNew(async () => { @@ -36,14 +40,12 @@ namespace Tango.MachineStudio.UI.StudioApplication var result = await vm.OnShutdownRequest(); if (!result) { - ThreadsHelper.InvokeUI(() => - { - _navigationManager.NavigateTo(NavigationView.MainView); - }); + IsShuttingDown = false; return; } } + _navigationManager.NavigateTo(NavigationView.ShutdownView); Thread.Sleep(3000); Environment.Exit(0); |
