diff options
| author | Avi Levkovich <avi@twine-s.com> | 2018-02-26 16:30:42 +0200 |
|---|---|---|
| committer | Avi Levkovich <avi@twine-s.com> | 2018-02-26 16:30:42 +0200 |
| commit | 5942bb7a13e5ad26c720a1b95ae4ea766eeeda25 (patch) | |
| tree | 2a855ce1065c875e615f5b040f984cb3fb84e518 /Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI | |
| parent | 4c052df707280abd208b03aa88cf904e0eb6b9bf (diff) | |
| parent | 6549d8672a93893599e921d9f1938af7dcabb8bf (diff) | |
| download | Tango-5942bb7a13e5ad26c720a1b95ae4ea766eeeda25.tar.gz Tango-5942bb7a13e5ad26c720a1b95ae4ea766eeeda25.zip | |
MERGE!
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI')
23 files changed, 1128 insertions, 41 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config index d38c3ed69..1a0e57043 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config @@ -6,6 +6,8 @@ <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" /> </startup> + + <entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" /> <providers> @@ -17,9 +19,7 @@ <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> + <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> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs index c15a87980..b6a131d22 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs @@ -22,6 +22,8 @@ namespace Tango.MachineStudio.UI protected override void OnStartup(StartupEventArgs e) { + LogManager.Log("Application Started..."); + base.OnStartup(e); LogManager.Categories.Clear(); diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs index 82aba268d..110e4d148 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs @@ -50,7 +50,12 @@ namespace Tango.MachineStudio.UI.Authentication if (user == null) { - throw new AuthenticationException("Login failed for user " + email); + throw new AuthenticationException("Invalid credentials for " + email); + } + + if (!user.HasPermission(Permissions.RunMachineStudio)) + { + throw new AuthenticationException("It seems like you do not have sufficient privileges to run Machine Studio. Please contact your administrator."); } CurrentUser = user; diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/new-version.png b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/new-version.png Binary files differnew file mode 100644 index 000000000..eab60ef03 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/new-version.png diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/update.png b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/update.png Binary files differnew file mode 100644 index 000000000..a82777414 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/update.png diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml index e0f0b1f4f..63b2b3f6a 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml @@ -31,6 +31,9 @@ <ContentControl Tag="ShutdownView"> <views:ShutdownView></views:ShutdownView> </ContentControl> + <ContentControl Tag="UpdateView"> + <views:UpdateView></views:UpdateView> + </ContentControl> </sharedControls:MultiTransitionControl.Controls> </sharedControls:MultiTransitionControl> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml.cs index dfbc0eb77..15c8abcde 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml.cs @@ -15,6 +15,7 @@ using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using Tango.Core.Helpers; +using Tango.Logging; using Tango.MachineStudio.Common.StudioApplication; namespace Tango.MachineStudio.UI @@ -28,11 +29,18 @@ namespace Tango.MachineStudio.UI public MainWindow() { - InitializeComponent(); - Instance = this; - ThreadsHelper.SetDisptacher(Dispatcher); + try + { + InitializeComponent(); + Instance = this; + ThreadsHelper.SetDisptacher(Dispatcher); - this.Closing += MainWindow_Closing; + this.Closing += MainWindow_Closing; + } + catch (Exception ex) + { + LogManager.Log(ex); + } } private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DefaultNotificationProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DefaultNotificationProvider.cs index 1ea22c587..4dd17b500 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DefaultNotificationProvider.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DefaultNotificationProvider.cs @@ -225,7 +225,7 @@ namespace Tango.MachineStudio.UI.Notifications /// <param name="message">The message.</param> public void ShowError(string message) { - ShowMessageBox(PackIconKind.Exclamation, Brushes.Red, message, false); + ShowMessageBox(PackIconKind.AlertOctagon, Brushes.Red, message, false); } /// <summary> @@ -234,7 +234,7 @@ namespace Tango.MachineStudio.UI.Notifications /// <param name="message">The message.</param> public void ShowInfo(string message) { - ShowMessageBox(PackIconKind.Information, Brushes.Black, message, false); + ShowMessageBox(PackIconKind.CommentAlertOutline, Brushes.Black, message, false); } /// <summary> @@ -253,7 +253,7 @@ namespace Tango.MachineStudio.UI.Notifications /// <param name="message">The message.</param> public void ShowWarning(string message) { - ShowMessageBox(PackIconKind.Exclamation, Brushes.DarkOrange, message, false); + ShowMessageBox(PackIconKind.AlertOutline, Brushes.DarkOrange, message, false); } /// <summary> 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 886985c92..9538c59af 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs @@ -17,6 +17,7 @@ using Tango.Logging; using Tango.MachineStudio.Common.Modules; using Tango.MachineStudio.Common; using Tango.Settings; +using System.Windows; namespace Tango.MachineStudio.UI.StudioApplication { @@ -29,6 +30,7 @@ namespace Tango.MachineStudio.UI.StudioApplication { private INavigationManager _navigationManager; private IStudioModuleLoader _moduleLoader; + private List<Window> _openedWindows; /// <summary> /// Initializes a new instance of the <see cref="DefaultStudioApplicationManager" /> class. @@ -38,6 +40,7 @@ namespace Tango.MachineStudio.UI.StudioApplication { _moduleLoader = moduleLoader; _navigationManager = navigationManager; + _openedWindows = new List<Window>(); } /// <summary> @@ -109,6 +112,17 @@ namespace Tango.MachineStudio.UI.StudioApplication } /// <summary> + /// Gets the machine studio application version. + /// </summary> + public string Version + { + get + { + return typeof(DefaultStudioApplicationManager).Assembly.GetName().Version.ToString(); + } + } + + /// <summary> /// Shutdown the application. /// </summary> public async void ShutDown() @@ -137,35 +151,45 @@ namespace Tango.MachineStudio.UI.StudioApplication } } + foreach (var vm in ServiceLocator.Current.GetAllInstancesByBase<IShutdownListener>()) + { + vm.OnShuttingDown(); + } + try { - if (ConnectedMachine != null) - { - ConnectedMachine.Disconnect().Wait(); - } + SettingsManager.SaveDefaultSettings(); } catch (Exception ex) { - LogManager.Log(ex, "Error disconnecting from machine."); + LogManager.Log(ex, "Error saving settings."); } - foreach (var vm in ServiceLocator.Current.GetAllInstancesByBase<IShutdownListener>()) + _navigationManager.NavigateTo(NavigationView.ShutdownView); + + Thread.Sleep(1500); + + foreach (var window in _openedWindows) { - vm.OnShuttingDown(); + ThreadsHelper.InvokeUI(() => + { + window.Close(); + }); } try { - SettingsManager.SaveDefaultSettings(); + if (ConnectedMachine != null) + { + ConnectedMachine.Disconnect().Wait(); + } } catch (Exception ex) { - LogManager.Log(ex, "Error saving settings."); + LogManager.Log(ex, "Error disconnecting from machine."); } - _navigationManager.NavigateTo(NavigationView.ShutdownView); - - Thread.Sleep(3000); + Thread.Sleep(1500); Environment.Exit(0); @@ -196,5 +220,12 @@ namespace Tango.MachineStudio.UI.StudioApplication throw new InvalidOperationException("The module was not found or you do not have sufficient privileges."); } } + + public void RegisterOpenedWindow(Window window) + { + _openedWindows.Add(window); + + window.Closed += (x, y) => { _openedWindows.Remove(window); }; + } } } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj index f48561e40..4cfa99a9b 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj @@ -13,6 +13,8 @@ <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <WarningLevel>4</WarningLevel> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> + <NuGetPackageImportStamp> + </NuGetPackageImportStamp> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PlatformTarget>AnyCPU</PlatformTarget> @@ -46,6 +48,9 @@ <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="FluentFTP, Version=19.1.2.0, Culture=neutral, PublicKeyToken=f4af092b1d8df44f, processorArchitecture=MSIL"> + <HintPath>..\..\packages\FluentFTP.19.1.2\lib\net45\FluentFTP.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> @@ -61,6 +66,9 @@ <Reference Include="Google.Protobuf, Version=3.4.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL"> <HintPath>..\..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll</HintPath> </Reference> + <Reference Include="Ionic.Zip, Version=1.9.1.8, Culture=neutral, PublicKeyToken=edbe51ad942a3f5c, processorArchitecture=MSIL"> + <HintPath>..\..\packages\Ionic.Zip.1.9.1.8\lib\Ionic.Zip.dll</HintPath> + </Reference> <Reference Include="MahApps.Metro, Version=1.5.0.23, Culture=neutral, PublicKeyToken=f4fb5a3c4d1e5b4f, processorArchitecture=MSIL"> <HintPath>..\..\packages\MahApps.Metro.1.5.0\lib\net45\MahApps.Metro.dll</HintPath> </Reference> @@ -80,7 +88,19 @@ <Reference Include="System.ComponentModel.Composition" /> <Reference Include="System.ComponentModel.DataAnnotations" /> <Reference Include="System.Data" /> + <Reference Include="System.Data.SQLite, Version=1.0.106.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL"> + <HintPath>..\..\packages\System.Data.SQLite.Core.1.0.106.0\lib\net46\System.Data.SQLite.dll</HintPath> + </Reference> + <Reference Include="System.Data.SQLite.EF6, Version=1.0.106.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL"> + <HintPath>..\..\packages\System.Data.SQLite.EF6.1.0.106.0\lib\net46\System.Data.SQLite.EF6.dll</HintPath> + <Private>True</Private> + </Reference> + <Reference Include="System.Data.SQLite.Linq, Version=1.0.106.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL"> + <HintPath>..\..\packages\System.Data.SQLite.Linq.1.0.106.0\lib\net46\System.Data.SQLite.Linq.dll</HintPath> + <Private>True</Private> + </Reference> <Reference Include="System.Drawing" /> + <Reference Include="System.IO.Compression.FileSystem" /> <Reference Include="System.Numerics" /> <Reference Include="System.Reactive.Core, Version=3.0.3000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> <HintPath>..\..\packages\System.Reactive.Core.3.1.1\lib\net46\System.Reactive.Core.dll</HintPath> @@ -97,6 +117,9 @@ <Reference Include="System.Reactive.Windows.Threading, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> <HintPath>..\..\packages\System.Reactive.Windows.Threading.3.1.1\lib\net45\System.Reactive.Windows.Threading.dll</HintPath> </Reference> + <Reference Include="System.Runtime.Serialization" /> + <Reference Include="System.ServiceModel" /> + <Reference Include="System.Web" /> <Reference Include="System.Windows" /> <Reference Include="System.Windows.Forms" /> <Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> @@ -120,12 +143,12 @@ <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> </ApplicationDefinition> + <Compile Include="Modules\DefaultStudioModuleLoader.cs" /> <Compile Include="Notifications\TextInputBoxWindow.xaml.cs"> <DependentUpon>TextInputBoxWindow.xaml</DependentUpon> </Compile> <Compile Include="StudioApplication\DefaultStudioApplicationManager.cs" /> <Compile Include="Authentication\DefaultAuthenticationProvider.cs" /> - <Compile Include="Modules\DefaultStudioModuleLoader.cs" /> <Compile Include="Navigation\DefaultNavigationManager.cs" /> <Compile Include="Notifications\DefaultNotificationProvider.cs" /> <Compile Include="Notifications\MessageBoxWindow.xaml.cs"> @@ -138,7 +161,9 @@ <Compile Include="ViewModels\MachineLoginViewVM.cs" /> <Compile Include="ViewModels\MainViewVM.cs" /> <Compile Include="ViewModelLocator.cs" /> + <Compile Include="ViewModels\ModuleWindowVM.cs" /> <Compile Include="ViewModels\ShutdownViewVM.cs" /> + <Compile Include="ViewModels\UpdateViewVM.cs" /> <Compile Include="Views\LoadingView.xaml.cs"> <DependentUpon>LoadingView.xaml</DependentUpon> </Compile> @@ -160,10 +185,16 @@ <Compile Include="Views\ShutdownView.xaml.cs"> <DependentUpon>ShutdownView.xaml</DependentUpon> </Compile> + <Compile Include="Views\UpdateView.xaml.cs"> + <DependentUpon>UpdateView.xaml</DependentUpon> + </Compile> <Compile Include="Windows\ExceptionResolutions.cs" /> <Compile Include="Windows\ExceptionWindow.xaml.cs"> <DependentUpon>ExceptionWindow.xaml</DependentUpon> </Compile> + <Compile Include="Windows\ModuleWindow.xaml.cs"> + <DependentUpon>ModuleWindow.xaml</DependentUpon> + </Compile> <Page Include="MainWindow.xaml"> <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> @@ -219,10 +250,18 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Views\UpdateView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Windows\ExceptionWindow.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Windows\ModuleWindow.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> </ItemGroup> <ItemGroup> <Compile Include="Properties\AssemblyInfo.cs"> @@ -324,6 +363,10 @@ <Project>{cb0b0aa2-bb24-4bca-a720-45e397684e12}</Project> <Name>Tango.MachineStudio.Common</Name> </ProjectReference> + <ProjectReference Include="..\Tango.MachineStudio.Updater\Tango.MachineStudio.Updater.csproj"> + <Project>{844787ce-f409-4f18-bccc-f3809ecb86f3}</Project> + <Name>Tango.MachineStudio.Updater</Name> + </ProjectReference> </ItemGroup> <ItemGroup> <Resource Include="Images\design.png" /> @@ -344,6 +387,12 @@ <ItemGroup> <Resource Include="Images\exception.png" /> </ItemGroup> + <ItemGroup> + <Resource Include="Images\update.png" /> + </ItemGroup> + <ItemGroup> + <Resource Include="Images\new-version.png" /> + </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <PropertyGroup> <PostBuildEvent>$(TargetDir)linkgen.exe -s "$(TargetPath)" -d "$(TargetDir)Utilities\Machine Studio.lnk" @@ -393,4 +442,11 @@ RD /S /Q "$(TargetDir)bg\" RD /S /Q "$(TargetDir)bn-BD\" RD /S /Q "$(TargetDir)nb-NO\"</PostBuildEvent> </PropertyGroup> + <Import Project="..\..\packages\System.Data.SQLite.Core.1.0.106.0\build\net46\System.Data.SQLite.Core.targets" Condition="Exists('..\..\packages\System.Data.SQLite.Core.1.0.106.0\build\net46\System.Data.SQLite.Core.targets')" /> + <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> + <PropertyGroup> + <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> + </PropertyGroup> + <Error Condition="!Exists('..\..\packages\System.Data.SQLite.Core.1.0.106.0\build\net46\System.Data.SQLite.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\System.Data.SQLite.Core.1.0.106.0\build\net46\System.Data.SQLite.Core.targets'))" /> + </Target> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs index 1907074c0..330bcd6eb 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs @@ -71,6 +71,7 @@ namespace Tango.MachineStudio.UI SimpleIoc.Default.Register<LoginViewVM>(); SimpleIoc.Default.Register<MachineConnectionViewVM>(); SimpleIoc.Default.Register<MachineLoginViewVM>(); + SimpleIoc.Default.Register<UpdateViewVM>(); //Register View (Supervising Controller Pattern). if (!ViewModelBase.IsInDesignModeStatic) @@ -127,5 +128,13 @@ namespace Tango.MachineStudio.UI return ServiceLocator.Current.GetInstance<MachineLoginViewVM>(); } } + + public UpdateViewVM UpdateViewVM + { + get + { + return ServiceLocator.Current.GetInstance<UpdateViewVM>(); + } + } } }
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs index 55a54e8aa..9acf26afd 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs @@ -6,9 +6,11 @@ using System.Threading; using System.Threading.Tasks; using Tango.Core.Helpers; using Tango.Integration.Observables; +using Tango.Logging; using Tango.MachineStudio.Common.Modules; using Tango.MachineStudio.Common.Navigation; using Tango.MachineStudio.Common.Notifications; +using Tango.MachineStudio.Common.StudioApplication; using Tango.SharedUI; namespace Tango.MachineStudio.UI.ViewModels @@ -23,14 +25,17 @@ namespace Tango.MachineStudio.UI.ViewModels private INavigationManager _navigationManager; private IStudioModuleLoader _studioModuleLoader; + public IStudioApplicationManager ApplicationManager { get; set; } + /// <summary> /// Initializes a new instance of the <see cref="LoadingViewVM"/> class. /// </summary> /// <param name="navigationManager">The navigation manager.</param> /// <param name="studioModuleLoader">The studio module loader.</param> /// <param name="notificationProvider">The notification provider.</param> - public LoadingViewVM(INavigationManager navigationManager, IStudioModuleLoader studioModuleLoader, INotificationProvider notificationProvider) + public LoadingViewVM(IStudioApplicationManager applicationManager, INavigationManager navigationManager, IStudioModuleLoader studioModuleLoader, INotificationProvider notificationProvider) { + ApplicationManager = applicationManager; _navigationManager = navigationManager; _studioModuleLoader = studioModuleLoader; _notificationProvider = notificationProvider; @@ -55,6 +60,8 @@ namespace Tango.MachineStudio.UI.ViewModels } catch (Exception ex) { + LogManager.Log(ex); + InvokeUINow(() => { if (_notificationProvider.ShowQuestion("An error occurred while trying to connect to Twine database." + Environment.NewLine + "Would you like to try again?")) diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs index 679ba5ff3..fb2cd5c82 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs @@ -6,7 +6,11 @@ using System.IO; using System.Linq; using System.Reflection; using System.Text; +using System.Threading; using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; using Tango.Core.Commands; using Tango.Integration.Services; using Tango.Logging; @@ -16,10 +20,14 @@ using Tango.MachineStudio.Common.Modules; using Tango.MachineStudio.Common.Navigation; using Tango.MachineStudio.Common.Notifications; using Tango.MachineStudio.Common.StudioApplication; +using Tango.MachineStudio.Common.Update; +using Tango.MachineStudio.UI.StudioApplication; using Tango.MachineStudio.UI.SupervisingController; using Tango.MachineStudio.UI.Views; +using Tango.MachineStudio.UI.Windows; using Tango.PMR.Stubs; using Tango.SharedUI; +using Tango.SharedUI.Helpers; using Tango.Transport.Adapters; namespace Tango.MachineStudio.UI.ViewModels @@ -33,6 +41,7 @@ namespace Tango.MachineStudio.UI.ViewModels private IStudioModule _currentModule; private INavigationManager _navigation; private bool _isDisconnecting; + private Thread _updateCheckThread; /// <summary> /// Gets or sets the current loaded module. @@ -69,6 +78,11 @@ namespace Tango.MachineStudio.UI.ViewModels public RelayCommand<IStudioModule> StartModuleCommand { get; set; } /// <summary> + /// Gets or sets the open module in window command. + /// </summary> + public RelayCommand<IStudioModule> OpenModuleInWindowCommand { get; set; } + + /// <summary> /// Gets or sets the home command. /// </summary> public RelayCommand HomeCommand { get; set; } @@ -88,6 +102,16 @@ namespace Tango.MachineStudio.UI.ViewModels /// </summary> public RelayCommand SignoutCommand { get; set; } + /// <summary> + /// Gets or sets the exit command. + /// </summary> + public RelayCommand ExitCommand { get; set; } + + /// <summary> + /// Gets or sets the update center command. + /// </summary> + public RelayCommand UpdateCenterCommand { get; set; } + private IAuthenticationProvider _authenticationProvider; /// <summary> /// Gets or sets the authentication provider. @@ -128,6 +152,38 @@ namespace Tango.MachineStudio.UI.ViewModels set { _applicationManager = value; RaisePropertyChangedAuto(); } } + private bool _isUpdateAvailable; + /// <summary> + /// Gets or sets a value indicating whether a new version update is available. + /// </summary> + public bool IsUpdateAvailable + { + get { return _isUpdateAvailable; } + set { _isUpdateAvailable = value; RaisePropertyChangedAuto(); } + } + + private String _latestVersion; + /// <summary> + /// Gets or sets the latest version. + /// </summary> + public String LatestVersion + { + get { return _latestVersion; } + set { _latestVersion = value; RaisePropertyChangedAuto(); } + } + + + private bool _disableCheckForUpdates; + /// <summary> + /// Gets or sets a value indicating whether [disable check for updates]. + /// </summary> + public bool DisableCheckForUpdates + { + get { return _disableCheckForUpdates; } + set { _disableCheckForUpdates = value; RaisePropertyChangedAuto(); } + } + + /// <summary> /// Initializes a new instance of the <see cref="MainViewVM"/> class. /// </summary> @@ -157,6 +213,46 @@ namespace Tango.MachineStudio.UI.ViewModels ConnectCommand = new RelayCommand(ConnectToMachine); SignoutCommand = new RelayCommand(SignOut); DisconnectCommand = new RelayCommand(DisconnectFromMachine, (x) => ApplicationManager.IsMachineConnected && !_isDisconnecting); + OpenModuleInWindowCommand = new RelayCommand<IStudioModule>(OpenModuleInWindow); + ExitCommand = new RelayCommand(ExitApplication); + UpdateCenterCommand = new RelayCommand(NavigateToUpdateCenter); + + _updateCheckThread = new Thread(UpdateCheckThreadMethod); + _updateCheckThread.IsBackground = true; + _updateCheckThread.Start(); + } + + private void UpdateCheckThreadMethod() + { + while (!DisableCheckForUpdates) + { + Thread.Sleep(TimeSpan.FromMinutes(1)); + + try + { + if (_authenticationProvider.CurrentUser != null) + { + var service = UpdateServiceHelper.GetUpdateServiceChannel(); + var client = service.CreateChannel(); + + CheckForUpdatesResponse response = client.CheckForUpdates(new CheckForUpdatesRequest() + { + Email = _authenticationProvider.CurrentUser.Email, + Password = _authenticationProvider.CurrentUser.Password, + Version = _applicationManager.Version, + }); + + IsUpdateAvailable = response.IsUpdateAvailable; + LatestVersion = response.Version; + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error in version update periodic check..."); + } + + Thread.Sleep(TimeSpan.FromMinutes(4)); + } } /// <summary> @@ -302,5 +398,62 @@ namespace Tango.MachineStudio.UI.ViewModels { base.OnViewAttached(); } + + /// <summary> + /// Opens the module in a new window. + /// </summary> + /// <param name="module">The module.</param> + private void OpenModuleInWindow(IStudioModule module) + { + if (module == null) return; + + try + { + StartModule(null); + + module.InNewWindow = true; + + var parent = (MainView.Self as MainView).TransitionControl.Controls.SingleOrDefault(x => x.Tag.ToString() == module.Name).Content as Grid; + + var view = parent.Children[0] as FrameworkElement; + parent.Children.Remove(view); + + ModuleWindowVM vm = new ModuleWindowVM(module, parent); + ModuleWindow window = new ModuleWindow(this, vm, view); + + window.Closing += (x, y) => + { + window.grid.Children.Remove(view); + parent.Children.Add(view); + module.InNewWindow = false; + }; + + window.Owner = MainWindow.Instance; + window.Show(); + + (_applicationManager as DefaultStudioApplicationManager).RegisterOpenedWindow(window); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error popping out module " + module.Name); + _notificationProvider.ShowError("Error popping out module " + module.Name); + } + } + + /// <summary> + /// Navigates to update center. + /// </summary> + private void NavigateToUpdateCenter() + { + _navigation.NavigateTo(NavigationView.UpdateView); + } + + /// <summary> + /// Exits the application. + /// </summary> + private void ExitApplication() + { + _applicationManager.ShutDown(); + } } } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ModuleWindowVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ModuleWindowVM.cs new file mode 100644 index 000000000..a5b737b59 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ModuleWindowVM.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Controls; +using Tango.MachineStudio.Common; +using Tango.SharedUI; + +namespace Tango.MachineStudio.UI.ViewModels +{ + public class ModuleWindowVM : ViewModel + { + private IStudioModule _module; + + public IStudioModule Module + { + get { return _module; } + set { _module = value; RaisePropertyChangedAuto(); } + } + + public Grid Parent { get; set; } + + public ModuleWindowVM(IStudioModule module, Grid parent) + { + Parent = parent; + Module = module; + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs new file mode 100644 index 000000000..6be4ba4ca --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs @@ -0,0 +1,305 @@ +using FluentFTP; +using Ionic.Zip; +using Microsoft.Practices.ServiceLocation; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using System.ServiceModel; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Tango.Core.Commands; +using Tango.Core.Helpers; +using Tango.Logging; +using Tango.MachineStudio.Common.Authentication; +using Tango.MachineStudio.Common.Navigation; +using Tango.MachineStudio.Common.Notifications; +using Tango.MachineStudio.Common.StudioApplication; +using Tango.MachineStudio.Common.Update; +using Tango.SharedUI; + +namespace Tango.MachineStudio.UI.ViewModels +{ + public enum UpdateStatus + { + None, + CheckingForUpdate, + UpToDate, + UpdateAvailable, + Downloading, + Updating, + UpdateCompleted, + Error, + } + + public class UpdateViewVM : ViewModel + { + private String _appPath = AppDomain.CurrentDomain.BaseDirectory; + + private INotificationProvider _notification; + private INavigationManager _navigation; + private IStudioApplicationManager _application; + private IAuthenticationProvider _authentication; + private CheckForUpdatesResponse _updateInfo; + private String _newPackageTempFolder; + + private UpdateStatus _status; + public UpdateStatus Status + { + get { return _status; } + set { _status = value; RaisePropertyChangedAuto(); } + } + + private String _latestVersion; + public String LatestVersion + { + get { return _latestVersion; } + set { _latestVersion = value; RaisePropertyChangedAuto(); } + } + + private double _downloadProgress; + + public double DownloadProgress + { + get { return _downloadProgress; } + set { _downloadProgress = value; RaisePropertyChangedAuto(); } + } + + private double _updateProgress; + + public double UpdateProgress + { + get { return _updateProgress; } + set { _updateProgress = value; RaisePropertyChangedAuto(); } + } + + private String _currentUpdateFile; + + public String CurrentUpdateFile + { + get { return _currentUpdateFile; } + set { _currentUpdateFile = value; RaisePropertyChanged(nameof(CurrentUpdateFile)); } + } + + public RelayCommand UpdateCommand { get; set; } + + public RelayCommand BackCommand { get; set; } + + public RelayCommand RestartCommand { get; set; } + + public RelayCommand TryAgainCommand { get; set; } + + public UpdateViewVM(INotificationProvider notification, IAuthenticationProvider authentication, INavigationManager navigation, IStudioApplicationManager application) + { + _notification = notification; + _navigation = navigation; + _application = application; + _authentication = authentication; + + LatestVersion = "1.0.0.2"; + Status = UpdateStatus.CheckingForUpdate; + UpdateCommand = new RelayCommand(StartUpdate, () => Status == UpdateStatus.UpdateAvailable); + BackCommand = new RelayCommand(BackToApplication, () => Status != UpdateStatus.Updating); + RestartCommand = new RelayCommand(RestartApplication, () => Status == UpdateStatus.UpdateCompleted); + TryAgainCommand = new RelayCommand(TryAgain, () => Status == UpdateStatus.Error); + } + + public void OnNavigatedInto() + { + CheckForUpdates(); + } + + private void CheckForUpdates() + { + Status = UpdateStatus.CheckingForUpdate; + + ChannelFactory<IMachineStudioUpdateService> service = null; + + Task.Factory.StartNew(() => + { + try + { + Thread.Sleep(2000); + + service = UpdateServiceHelper.GetUpdateServiceChannel(); + var client = service.CreateChannel(); + + CheckForUpdatesResponse response = client.CheckForUpdates(new CheckForUpdatesRequest() + { + Email = _authentication.CurrentUser.Email, + Password = _authentication.CurrentUser.Password, + Version = _application.Version, + }); + + if (response.IsUpdateAvailable) + { + _updateInfo = response; + Status = UpdateStatus.UpdateAvailable; + LatestVersion = response.Version; + } + else + { + Status = UpdateStatus.UpToDate; + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error while checking for version update!"); + Status = UpdateStatus.Error; + } + finally + { + if (service != null) + { + service.Close(); + } + } + }); + } + + private void BackToApplication() + { + if (Status == UpdateStatus.Downloading) + { + if (!_notification.ShowQuestion("This will abort all update operations. Are you sure?")) + { + return; + } + } + + _navigation.NavigateTo(NavigationView.MainView); + Status = UpdateStatus.None; + } + + private void StartUpdate() + { + DownloadProgress = 0; + UpdateProgress = 0; + + Status = UpdateStatus.Downloading; + + Task.Factory.StartNew(() => + { + var tempFile = PathHelper.GetTempFilePath() + ".zip"; + + try + { + LogManager.Log("Creating temporary file " + tempFile); + + int fileSize = 0; + + using (FileStreamWrapper fs = new FileStreamWrapper(tempFile, FileMode.Create, (current) => + { + InvokeUINow(() => + { + Thread.Sleep(10); + DownloadProgress = ((double)current / (double)fileSize) * 100d; + }); + })) + { + using (FtpClient ftp = new FtpClient(_updateInfo.FtpHost, _updateInfo.UserName, _updateInfo.Password)) + { + LogManager.Log("Connecting to FTP site: " + _updateInfo.FtpHost); + ftp.ConnectAsync().Wait(); + LogManager.Log("Retrieving download size..."); + fileSize = (int)ftp.GetFileSize(_updateInfo.FilePath); + LogManager.Log("Download size: " + fileSize + " bytes."); + LogManager.Log("Starting download..."); + ftp.DownloadAsync(fs, _updateInfo.FilePath).Wait(); + } + } + + + Status = UpdateStatus.Updating; + + _newPackageTempFolder = PathHelper.GetTempFolderPath(); + + using (ZipFile zip = ZipFile.Read(tempFile)) + { + int currentEntry = 0; + + zip.ExtractProgress += (x, args) => + { + if (args.EventType == ZipProgressEventType.Extracting_AfterExtractEntry) + { + LogManager.Log("Extracting " + Path.GetFileName(args.CurrentEntry.FileName)); + UpdateProgress = ((double)(currentEntry++) / (double)zip.Entries.Count) * 100d; + } + }; + + foreach (ZipEntry entry in zip) + { + Thread.Sleep(10); + + string newPath = Path.Combine(_newPackageTempFolder, entry.FileName); + + try + { + if (entry.IsDirectory) + { + Directory.CreateDirectory(newPath); + } + else + { + CurrentUpdateFile = Path.GetFileName(entry.FileName); + entry.Extract(_newPackageTempFolder, ExtractExistingFileAction.OverwriteSilently); + } + } + catch + { + LogManager.Log("Could not extract file " + entry.FileName); + } + } + } + + ServiceLocator.Current.GetInstance<MainViewVM>().DisableCheckForUpdates = true; + Status = UpdateStatus.UpdateCompleted; + } + catch (Exception ex) + { + LogManager.Log(ex, "Error while extracting update package."); + Status = UpdateStatus.Error; + } + finally + { + PathHelper.TryDeleteFile(tempFile); + } + }); + } + + private void TryAgain() + { + CheckForUpdates(); + } + + private void RestartApplication() + { + try + { + Process p = new Process(); + p.StartInfo.FileName = _appPath + "\\Tango.MachineStudio.Updater.exe"; + p.StartInfo.UseShellExecute = true; + p.StartInfo.Arguments = _newPackageTempFolder; + p.Start(); + } + catch (Exception ex) + { + if (ex.Message == "The operation was canceled by the user") + { + _notification.ShowWarning("It seems like you refused to invoke our update utility. This prevents Machine Studio from completing the update process!"); + return; + } + } + Environment.Exit(0); + } + + protected override void RaisePropertyChangedAuto([CallerMemberName] string caller = null) + { + base.RaisePropertyChangedAuto(caller); + InvalidateRelayCommands(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoadingView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoadingView.xaml index 2478c1155..5f65100df 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoadingView.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoadingView.xaml @@ -19,5 +19,11 @@ <TextBlock HorizontalAlignment="Center" FontSize="18" FontStyle="Italic">Loading, please wait...</TextBlock> </StackPanel> </Grid> + + + <TextBlock Foreground="Gray" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="40" FontSize="20" FontWeight="SemiBold" FontStyle="Italic"> + <Run>v</Run> + <Run Text="{Binding ApplicationManager.Version,Mode=OneWay}"></Run> + </TextBlock> </Grid> </UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml index 479052cc5..f2c9ddba5 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml @@ -17,6 +17,9 @@ <UserControl.Resources> <converters:StringEllipsisConverter x:Key="StringEllipsisConverter" /> + <converters:BooleanToVisibilityInverseConverter x:Key="BooleanToVisibilityInverseConverter" /> + <converters:NullObjectToBooleanConverter x:Key="NullObjectToBooleanConverter" /> + <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> </UserControl.Resources> <Grid> @@ -44,7 +47,25 @@ <StackPanel Margin="5 0 0 0" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center"> <Image Source="/Images/account.png" RenderOptions.BitmapScalingMode="Fant" VerticalAlignment="Center" Width="50" Height="50"></Image> + <StackPanel Margin="0 5 0 0"> <TextBlock FontSize="16" TextTrimming="CharacterEllipsis" MaxWidth="170" FontStyle="Italic" FontWeight="Bold" Margin="10 0 0 0" VerticalAlignment="Center" Text="{Binding AuthenticationProvider.CurrentUser.Contact.FullName}"></TextBlock> + <TextBlock FontSize="12" TextTrimming="CharacterEllipsis" MaxWidth="170" FontStyle="Italic" Margin="10 5 0 0" VerticalAlignment="Center"> + <Run Text="{Binding AuthenticationProvider.CurrentUser.Organization.Name}"></Run> + , + <Run Text="{Binding AuthenticationProvider.CurrentUser.Roles[0]}"> + <Run.ToolTip> + <ItemsControl ItemsSource="{Binding AuthenticationProvider.CurrentUser.Roles}"> + <ItemsControl.ItemTemplate> + <DataTemplate> + <TextBlock Text="{Binding Name}"></TextBlock> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + </Run.ToolTip> + </Run> + <Run>...</Run> + </TextBlock> + </StackPanel> </StackPanel> </Grid> <StackPanel Margin="0 16 0 0"> @@ -69,6 +90,7 @@ <Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}"> <Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter> <Setter Property="VerticalContentAlignment" Value="Stretch"></Setter> + <Setter Property="Visibility" Value="{Binding InNewWindow,Converter={StaticResource BooleanToVisibilityInverseConverter}}"></Setter> </Style> </ListBox.ItemContainerStyle> <ListBox.ItemTemplate> @@ -118,10 +140,39 @@ x:Name="MenuToggleButton"/> <materialDesign:PopupBox DockPanel.Dock="Right" PlacementMode="BottomAndAlignRightEdges" StaysOpen="False"> <StackPanel> - <Button Content="Machine Connection" Command="{Binding ConnectCommand}" /> - <Button Content="Disconnect Machine" Command="{Binding DisconnectCommand}" /> + <Button Command="{Binding ConnectCommand}"> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Kind="LanConnect" Width="24" Height="24" /> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">Machine Connection</TextBlock> + </StackPanel> + </Button> + <Button Command="{Binding DisconnectCommand}"> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Kind="LanDisconnect" Width="24" Height="24" /> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">Disconnect Machine</TextBlock> + </StackPanel> + </Button> + <Separator/> + <Button IsEnabled="{Binding IsModuleLoaded}" Command="{Binding OpenModuleInWindowCommand}" CommandParameter="{Binding CurrentModule}"> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Kind="ArrowTopRight" Width="24" Height="24" /> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">Open Module In New Window</TextBlock> + </StackPanel> + </Button> + <Separator/> + <Button Command="{Binding UpdateCenterCommand}"> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Kind="Download" Width="24" Height="24" /> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">Update Center</TextBlock> + </StackPanel> + </Button> <Separator/> - <Button Content="Exit" /> + <Button Command="{Binding ExitCommand}"> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Kind="CloseCircleOutline" Width="24" Height="24" /> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">Exit</TextBlock> + </StackPanel> + </Button> </StackPanel> </materialDesign:PopupBox> <Grid> @@ -146,14 +197,8 @@ </ItemsControl.ItemTemplate> </ItemsControl> </Grid> - + <Button VerticalAlignment="Center" Margin="10 0 0 0" Style="{StaticResource MaterialDesignFlatButton}" FontSize="12" ToolTip="Connect to machine on the local network" BorderThickness="0" Command="{Binding ConnectCommand}"> - <!--<Button.Background> - <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> - <GradientStop Color="White" Offset="0.4" /> - <GradientStop Color="#75E0FA" Offset="1"/> - </LinearGradientBrush> - </Button.Background>--> <StackPanel Orientation="Horizontal"> <Grid> <StackPanel Orientation="Horizontal" VerticalAlignment="Center"> @@ -176,6 +221,37 @@ </Grid> </StackPanel> </Button> + + <Button Style="{StaticResource emptyButton}" Cursor="Hand" Command="{Binding UpdateCenterCommand}" Visibility="{Binding IsUpdateAvailable,Converter={StaticResource BooleanToVisibilityConverter}}"> + <Button.ToolTip> + <TextBlock> + <Run>Version</Run> + <Run Text="{Binding LatestVersion}"></Run> + <Run>is available !</Run> + </TextBlock> + </Button.ToolTip> + <Image Source="/Images/update.png" Width="32" RenderTransformOrigin="0.5,0.5" RenderOptions.BitmapScalingMode="Fant"> + <Image.RenderTransform> + <ScaleTransform ScaleX="1" ScaleY="1" /> + </Image.RenderTransform> + <Image.Style> + <Style TargetType="Image"> + <Style.Triggers> + <EventTrigger RoutedEvent="Loaded"> + <EventTrigger.Actions> + <BeginStoryboard> + <Storyboard> + <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" From="0.9" To="1.1" Duration="00:00:0.5" RepeatBehavior="Forever" AutoReverse="True"></DoubleAnimation> + <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" From="0.9" To="1.1" Duration="00:00:0.5" RepeatBehavior="Forever" AutoReverse="True"></DoubleAnimation> + </Storyboard> + </BeginStoryboard> + </EventTrigger.Actions> + </EventTrigger> + </Style.Triggers> + </Style> + </Image.Style> + </Image> + </Button> </StackPanel> </Grid> </Grid> @@ -200,8 +276,8 @@ </Grid.RowDefinitions> <Grid> <StackPanel Margin="30 20" HorizontalAlignment="Left"> - <TextBlock Style="{StaticResource MaterialDesignDisplay1TextBlock}">Welcome to Machine Studio</TextBlock> - <TextBlock HorizontalAlignment="Right" Margin="0 5 -130 0" FontStyle="Italic" Style="{StaticResource MaterialDesignSubheadingTextBlock}" Foreground="{StaticResource AccentColorBrush}">Select Your Studio Module...</TextBlock> + <TextBlock FontSize="35">Welcome to Machine Studio</TextBlock> + <TextBlock HorizontalAlignment="Left" Margin="350 5 0 0" FontStyle="Italic" FontSize="16">The below modules are displayed according to your user roles and permissions.</TextBlock> </StackPanel> </Grid> @@ -216,7 +292,7 @@ <ItemsControl.ItemTemplate> <DataTemplate> - <materialDesign:Card Width="300" Margin="10" Height="400"> + <materialDesign:Card Width="300" Margin="10" Height="400" Visibility="{Binding InNewWindow,Converter={StaticResource BooleanToVisibilityInverseConverter}}"> <Grid > <Grid.RowDefinitions> <RowDefinition Height="180" /> @@ -234,8 +310,18 @@ <StackPanel Grid.Row="2" Margin="8" HorizontalAlignment="Right" Orientation="Horizontal"> <materialDesign:PopupBox Padding="2,0,2,0" Style="{StaticResource MaterialDesignToolPopupBox}"> <StackPanel> - <Button Content="More" /> - <Button Content="Options" /> + <Button Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.OpenModuleInWindowCommand}" CommandParameter="{Binding}"> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Kind="ArrowTopRight" Width="24" Height="24" /> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">Start in new window</TextBlock> + </StackPanel> + </Button> + <Button> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Kind="Settings" Width="24" Height="24" /> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">Settings</TextBlock> + </StackPanel> + </Button> </StackPanel> </materialDesign:PopupBox> </StackPanel> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml.cs index e6e1557f3..c40904173 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml.cs @@ -69,10 +69,13 @@ namespace Tango.MachineStudio.UI.Views { ThreadsHelper.InvokeUI(() => { + Grid grid = new Grid(); + grid.Children.Add(module.MainView); + TransitionControl.Controls.Add(new ContentControl() { Tag = module.Name, - Content = module.MainView + Content = grid, }); _loader.UserModules.Add(module); diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/UpdateView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/UpdateView.xaml new file mode 100644 index 000000000..dabbaab94 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/UpdateView.xaml @@ -0,0 +1,194 @@ +<UserControl x:Class="Tango.MachineStudio.UI.Views.UpdateView" + 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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:vm="clr-namespace:Tango.MachineStudio.UI.ViewModels" + xmlns:mahApps="http://metro.mahapps.com/winfx/xaml/controls" + xmlns:local="clr-namespace:Tango.MachineStudio.UI.Views" + mc:Ignorable="d" + d:DesignHeight="1080" d:DesignWidth="1920" DataContext="{Binding UpdateViewVM, Source={StaticResource Locator}}" Background="White" FontSize="20"> + <Grid> + <Grid.Background> + <ImageBrush ImageSource="/Images/White-Abstract.png" /> + </Grid.Background> + <Grid MaxWidth="1200" MaxHeight="700"> + <DockPanel> + <Grid DockPanel.Dock="Top" HorizontalAlignment="Center"> + <Grid.Effect> + <DropShadowEffect BlurRadius="200" ShadowDepth="0" Opacity="0.5" /> + </Grid.Effect> + <StackPanel Orientation="Horizontal"> + <Image Source="/Images/update.png" Width="100" /> + <TextBlock Margin="10 0 0 0" VerticalAlignment="Center" FontSize="70">Update Center</TextBlock> + </StackPanel> + </Grid> + + <Grid DockPanel.Dock="Bottom"> + <StackPanel Orientation="Horizontal" HorizontalAlignment="Right"> + <Button MinWidth="140" Height="40" Style="{StaticResource MaterialDesignFlatButton}" Command="{Binding BackCommand}"> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Kind="KeyboardBackspace" Width="24" Height="24" /> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">BACK TO APPLICATION</TextBlock> + </StackPanel> + </Button> + </StackPanel> + </Grid> + + <Grid> + <Border Margin="0 10 0 10" BorderThickness="0 0 0 2" BorderBrush="DimGray"> + <ContentControl> + <ContentControl.Style> + <Style TargetType="ContentControl"> + <Setter Property="Content"> + <Setter.Value> + <Grid> + + </Grid> + </Setter.Value> + </Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding Status}" Value="{x:Static vm:UpdateStatus.CheckingForUpdate}"> + <Setter Property="Content"> + <Setter.Value> + <Grid> + <StackPanel VerticalAlignment="Center"> + <mahApps:ProgressRing Width="120" Height="120" Foreground="DimGray" /> + <TextBlock HorizontalAlignment="Center" Margin="0 30 0 0">Checking for updates...</TextBlock> + </StackPanel> + </Grid> + </Setter.Value> + </Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Status}" Value="{x:Static vm:UpdateStatus.UpdateAvailable}"> + <Setter Property="Content"> + <Setter.Value> + <Grid> + <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> + <Image Source="/Images/new-version.png" Width="64"></Image> + <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> + <TextBlock VerticalAlignment="Center" Margin="0 20 0 0"> + <Run>Version</Run> + <Run Text="{Binding LatestVersion}" FontWeight="SemiBold" Foreground="{StaticResource AccentColorBrush}"></Run> + <Run>is available!</Run> + </TextBlock> + </StackPanel> + <TextBlock FontSize="12" TextAlignment="Center" Padding="20" Margin="0 0 0 40"> + <Run>A new version of Machine Studio is available for download</Run> + <LineBreak/> + <Run>Click 'Update' to start the update process.</Run> + </TextBlock> + <Button MinWidth="140" Height="40" Margin="0 0 0 0" Width="200" Command="{Binding UpdateCommand}"> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Kind="Download" Width="24" Height="24" /> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">UPDATE</TextBlock> + </StackPanel> + </Button> + </StackPanel> + </Grid> + </Setter.Value> + </Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Status}" Value="{x:Static vm:UpdateStatus.Downloading}"> + <Setter Property="Content"> + <Setter.Value> + <Grid> + <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> + <TextBlock HorizontalAlignment="Center"> + <Run>Downloading version</Run> + <Run Text="{Binding LatestVersion,FallbackValue='0.0.0.0'}"></Run> + <Run>, please wait...</Run> + </TextBlock> + <ProgressBar Height="10" Foreground="DimGray" Margin="0 20 0 0" Maximum="100" Value="{Binding DownloadProgress}"></ProgressBar> + </StackPanel> + </Grid> + </Setter.Value> + </Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Status}" Value="{x:Static vm:UpdateStatus.Updating}"> + <Setter Property="Content"> + <Setter.Value> + <Grid> + <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> + <TextBlock HorizontalAlignment="Center"> + <Run>Updating Machine Studio, please wait...</Run> + </TextBlock> + <ProgressBar Height="10" Foreground="DimGray" Margin="0 20 0 0" Maximum="100" Value="{Binding UpdateProgress}"></ProgressBar> + + <TextBlock TextTrimming="CharacterEllipsis" Text="{Binding CurrentUpdateFile}" FontSize="10" Margin="0 10 0 0" TextAlignment="Center" Foreground="DimGray"></TextBlock> + </StackPanel> + </Grid> + </Setter.Value> + </Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Status}" Value="{x:Static vm:UpdateStatus.UpdateCompleted}"> + <Setter Property="Content"> + <Setter.Value> + <Grid> + <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> + <materialDesign:PackIcon Kind="Check" Width="100" Height="100" Foreground="#1CBB1C" HorizontalAlignment="Center" /> + <StackPanel Orientation="Horizontal"> + <TextBlock VerticalAlignment="Center" Margin="0 20 0 0">Your version of Machine Studio is up to date!</TextBlock> + </StackPanel> + + <TextBlock HorizontalAlignment="Center" Margin="0 10 0 0" FontSize="12">Please restart Machine Studio in order to apply the changes.</TextBlock> + + <Button MinWidth="140" Height="40" Margin="0 50 0 0" Width="200" Command="{Binding RestartCommand}"> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Kind="BackupRestore" Width="24" Height="24" /> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">RESTART</TextBlock> + </StackPanel> + </Button> + </StackPanel> + </Grid> + </Setter.Value> + </Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Status}" Value="{x:Static vm:UpdateStatus.UpToDate}"> + <Setter Property="Content"> + <Setter.Value> + <Grid> + <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> + <materialDesign:PackIcon Kind="Check" Width="100" Height="100" Foreground="#1CBB1C" HorizontalAlignment="Center" /> + <StackPanel Orientation="Horizontal"> + <TextBlock VerticalAlignment="Center" Margin="0 20 0 0">Your version of Machine Studio is up to date!</TextBlock> + </StackPanel> + </StackPanel> + </Grid> + </Setter.Value> + </Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Status}" Value="{x:Static vm:UpdateStatus.Error}"> + <Setter Property="Content"> + <Setter.Value> + <Grid> + <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> + <materialDesign:PackIcon Kind="Alert" Width="100" Height="100" Foreground="#FF5F5F" HorizontalAlignment="Center" /> + <TextBlock VerticalAlignment="Center" Margin="0 20 0 0" HorizontalAlignment="Center">Error updating machine studio</TextBlock> + <TextBlock HorizontalAlignment="Center" Margin="0 10 0 0" FontSize="12" TextAlignment="Center"> + <Run>An error occurred while updating your software.</Run> + <LineBreak/> + <Run>press 'Try Again' to give it another try.</Run> + </TextBlock> + <Button MinWidth="140" Height="40" Margin="0 50 0 0" Width="200" Command="{Binding TryAgainCommand}"> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Kind="BackupRestore" Width="24" Height="24" /> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">TRY AGAIN</TextBlock> + </StackPanel> + </Button> + </StackPanel> + </Grid> + </Setter.Value> + </Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </ContentControl.Style> + </ContentControl> + </Border> + </Grid> + </DockPanel> + </Grid> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/UpdateView.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/UpdateView.xaml.cs new file mode 100644 index 000000000..75b74f65d --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/UpdateView.xaml.cs @@ -0,0 +1,42 @@ +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; +using Tango.MachineStudio.UI.ViewModels; +using static Tango.SharedUI.Controls.MultiTransitionControl; + +namespace Tango.MachineStudio.UI.Views +{ + /// <summary> + /// Interaction logic for UpdateView.xaml + /// </summary> + public partial class UpdateView : UserControl, ITransitionView + { + private UpdateViewVM _vm; + + public UpdateView() + { + InitializeComponent(); + + this.Loaded += (x, y) => + { + _vm = DataContext as UpdateViewVM; + }; + } + + public void OnTransitionCompleted() + { + _vm.OnNavigatedInto(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml new file mode 100644 index 000000000..8721cfd6a --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml @@ -0,0 +1,97 @@ +<mahapps:MetroWindow x:Class="Tango.MachineStudio.UI.Windows.ModuleWindow" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:local="clr-namespace:Tango.MachineStudio.UI.Windows" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" + xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls" + xmlns:views="clr-namespace:Tango.MachineStudio.UI.Views" + xmlns:sharedControls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + mc:Ignorable="d" + Title="{Binding RelativeSource={RelativeSource Self},Path=ModuleContext.Module.Name}" Height="800" Width="1280" WindowStartupLocation="CenterOwner" WindowState="Maximized" Foreground="#494949" BorderThickness="1" BorderBrush="{StaticResource AccentColorBrush}"> + + <Window.Resources> + <converters:StringEllipsisConverter x:Key="StringEllipsisConverter" /> + </Window.Resources> + + <Grid> + <Grid.Background> + <ImageBrush ImageSource="/Images/White-Abstract.png" Stretch="Fill"></ImageBrush> + </Grid.Background> + <Viewbox Stretch="Fill" UseLayoutRounding="True" SnapsToDevicePixels="True"> + <Grid Width="1920" Height="1145"> + <Grid> + <DockPanel> + <materialDesign:ColorZone Padding="16" materialDesign:ShadowAssist.ShadowDepth="Depth2" + Mode="PrimaryMid" DockPanel.Dock="Top"> + <DockPanel> + <Grid> + <StackPanel Orientation="Horizontal" VerticalAlignment="Center" Height="60" HorizontalAlignment="Center"> + <Image Source="/Images/machine-trans.png" RenderOptions.BitmapScalingMode="Fant"></Image> + <TextBlock Text="Machine Studio" VerticalAlignment="Center" Margin="20 0 0 0" FontSize="36"/> + </StackPanel> + </Grid> + </DockPanel> + </materialDesign:ColorZone> + + <Grid> + <Grid> + <Grid.RowDefinitions> + <RowDefinition Height="Auto"/> + <RowDefinition Height="1*"/> + </Grid.RowDefinitions> + + <Grid Grid.Row="1" x:Name="grid"> + + </Grid> + </Grid> + + <Border HorizontalAlignment="Right" Margin="0 -1 10 0" VerticalAlignment="Top" Width="300" Height="40" Padding="5" CornerRadius="0 0 30 30" BorderThickness="1 0 1 1" BorderBrush="DimGray"> + <Border.Style> + <Style TargetType="Border"> + <Setter Property="RenderTransform"> + <Setter.Value> + <ScaleTransform ScaleX="1" ScaleY="0"></ScaleTransform> + </Setter.Value> + </Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding NotificationProvider.HasTaskItems}" Value="True"> + <DataTrigger.EnterActions> + <BeginStoryboard HandoffBehavior="Compose"> + <Storyboard> + <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" FillBehavior="HoldEnd" To="1" Duration="00:00:0.2"></DoubleAnimation> + </Storyboard> + </BeginStoryboard> + </DataTrigger.EnterActions> + <DataTrigger.ExitActions> + <BeginStoryboard HandoffBehavior="Compose"> + <Storyboard> + <DoubleAnimation BeginTime="00:00:02" FillBehavior="HoldEnd" Storyboard.TargetProperty="RenderTransform.ScaleY" To="0" From="1" Duration="00:00:0.5"></DoubleAnimation> + </Storyboard> + </BeginStoryboard> + </DataTrigger.ExitActions> + </DataTrigger> + </Style.Triggers> + </Style> + </Border.Style> + <Border.Background> + <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> + <GradientStop Color="#03A9F4"/> + <GradientStop Color="#0081BB" Offset="1"/> + </LinearGradientBrush> + </Border.Background> + + <StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="20 0 0 0"> + <mahapps:ProgressRing Width="24" Height="24" Foreground="White"></mahapps:ProgressRing> + <TextBlock Text="{Binding NotificationProvider.CurrentTaskItem.Message,Converter={StaticResource StringEllipsisConverter},ConverterParameter=35}" Foreground="White" VerticalAlignment="Center" Margin="10 0 0 0" TextWrapping="Wrap"></TextBlock> + </StackPanel> + </Border> + </Grid> + </DockPanel> + </Grid> + </Grid> + </Viewbox> + </Grid> +</mahapps:MetroWindow> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml.cs new file mode 100644 index 000000000..7ca062645 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml.cs @@ -0,0 +1,44 @@ +using MahApps.Metro.Controls; +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.Shapes; +using Tango.MachineStudio.UI.ViewModels; + +namespace Tango.MachineStudio.UI.Windows +{ + /// <summary> + /// Interaction logic for ModuleWindow.xaml + /// </summary> + public partial class ModuleWindow : MetroWindow + { + public ModuleWindowVM ModuleContext + { + get { return (ModuleWindowVM)GetValue(ModuleContextProperty); } + set { SetValue(ModuleContextProperty, value); } + } + public static readonly DependencyProperty ModuleContextProperty = + DependencyProperty.Register("ModuleContext", typeof(ModuleWindowVM), typeof(ModuleWindow), new PropertyMetadata(null)); + + public ModuleWindow() + { + InitializeComponent(); + } + + public ModuleWindow(MainViewVM mainViewVM, ModuleWindowVM moduleVM, FrameworkElement view) : this() + { + DataContext = mainViewVM; + ModuleContext = moduleVM; + grid.Children.Add(view); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/packages.config b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/packages.config index ae67b1d1c..5dcc330a7 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/packages.config +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/packages.config @@ -3,14 +3,20 @@ <package id="CommonServiceLocator" version="1.3" targetFramework="net46" /> <package id="Dragablz" version="0.0.3.197" targetFramework="net46" /> <package id="EntityFramework" version="6.0.0" targetFramework="net46" /> + <package id="FluentFTP" version="19.1.2" targetFramework="net46" /> <package id="FontAwesome.WPF" version="4.7.0.9" targetFramework="net46" /> <package id="Google.Protobuf" version="3.4.1" targetFramework="net46" /> + <package id="Ionic.Zip" version="1.9.1.8" targetFramework="net46" /> <package id="MahApps.Metro" version="1.5.0" targetFramework="net46" /> <package id="MaterialDesignColors" version="1.1.2" targetFramework="net46" /> <package id="MaterialDesignThemes" version="2.3.1.953" targetFramework="net46" /> <package id="MvvmLight" version="5.3.0.0" targetFramework="net46" /> <package id="MvvmLightLibs" version="5.3.0.0" targetFramework="net46" /> <package id="SimpleValidator" version="0.6.1.0" targetFramework="net46" /> + <package id="System.Data.SQLite" version="1.0.106.0" targetFramework="net46" /> + <package id="System.Data.SQLite.Core" version="1.0.106.0" targetFramework="net46" /> + <package id="System.Data.SQLite.EF6" version="1.0.106.0" targetFramework="net46" /> + <package id="System.Data.SQLite.Linq" version="1.0.106.0" targetFramework="net46" /> <package id="System.Reactive" version="3.1.1" targetFramework="net46" /> <package id="System.Reactive.Core" version="3.1.1" targetFramework="net46" /> <package id="System.Reactive.Interfaces" version="3.1.1" targetFramework="net46" /> |
