From de099bd3b50b8ea52b212b8d322626582c2648be Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Sun, 22 Apr 2018 13:35:22 +0300 Subject: Implemented new TangoIOC container & TangoMessenger. Got rid of MVVMLite libs ! Got rid of IShutdownRequestBlocker, IShutdownListener, IModuleRequestListener. Implemented IStudioViewModel & StudioViewModel. --- .../Tango.MachineStudio.UI/App.xaml.cs | 4 +- .../Tango.MachineStudio.UI/MainWindow.xaml.cs | 4 +- .../Modules/DefaultStudioModuleLoader.cs | 3 +- .../DefaultStudioApplicationManager.cs | 19 ++--- .../Tango.MachineStudio.UI.csproj | 14 +--- .../Tango.MachineStudio.UI/ViewModelLocator.cs | 97 ++++++++++------------ .../ViewModels/MainViewVM.cs | 30 +++---- .../ViewModels/UpdateViewVM.cs | 4 +- .../Tango.MachineStudio.UI/Views/MainView.xaml.cs | 8 +- .../Tango.MachineStudio.UI/packages.config | 3 +- 10 files changed, 81 insertions(+), 105 deletions(-) (limited to 'Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI') 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 1334a349d..d9c64b9e3 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs @@ -12,9 +12,9 @@ using Tango.BL.Entities; using Tango.Logging; using Tango.MachineStudio.UI.Windows; using Tango.Settings; -using Microsoft.Practices.ServiceLocation; using Tango.MachineStudio.Common.EventLogging; using Tango.BL.Enumerations; +using Tango.Core.DI; namespace Tango.MachineStudio.UI { @@ -72,7 +72,7 @@ namespace Tango.MachineStudio.UI try { - var eventLogger = ServiceLocator.Current.GetInstance(); + var eventLogger = TangoIOC.Default.GetInstance(); if (eventLogger != null) { eventLogger.Log(e.Exception, "Application Crashed!"); 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 8461a5d93..9901d3b80 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml.cs @@ -1,5 +1,4 @@ using MahApps.Metro.Controls; -using Microsoft.Practices.ServiceLocation; using System; using System.Collections.Generic; using System.Linq; @@ -16,6 +15,7 @@ using System.Windows.Media.Animation; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; +using Tango.Core.DI; using Tango.Core.Helpers; using Tango.Logging; using Tango.MachineStudio.Common.StudioApplication; @@ -90,7 +90,7 @@ namespace Tango.MachineStudio.UI private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) { e.Cancel = true; - ServiceLocator.Current.GetInstance().ShutDown(); + TangoIOC.Default.GetInstance().ShutDown(); } } } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Modules/DefaultStudioModuleLoader.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Modules/DefaultStudioModuleLoader.cs index d7035b57b..4afddae69 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Modules/DefaultStudioModuleLoader.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Modules/DefaultStudioModuleLoader.cs @@ -1,5 +1,4 @@ -using GalaSoft.MvvmLight.Ioc; -using System; +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; 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 52602e6de..0bbcfd313 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs @@ -1,5 +1,4 @@ -using Microsoft.Practices.ServiceLocation; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -8,7 +7,6 @@ using System.Threading.Tasks; using Tango.Core.Helpers; using Tango.MachineStudio.Common.StudioApplication; using Tango.MachineStudio.Common.Navigation; -using GalaSoft.MvvmLight.Ioc; using System.Reflection; using System.Collections; using Tango.Core; @@ -20,6 +18,7 @@ using System.Windows; using Tango.Integration.Services; using Tango.MachineStudio.Common.EventLogging; using Tango.BL.Enumerations; +using Tango.Core.DI; namespace Tango.MachineStudio.UI.StudioApplication { @@ -136,7 +135,7 @@ namespace Tango.MachineStudio.UI.StudioApplication await Task.Factory.StartNew(async () => { //Do Shutdown Procedures... - foreach (var vm in ServiceLocator.Current.GetAllInstancesByBase()) + foreach (var vm in TangoIOC.Default.GetAllInstancesByBase()) { try { @@ -153,7 +152,7 @@ namespace Tango.MachineStudio.UI.StudioApplication } } - foreach (var vm in ServiceLocator.Current.GetAllInstancesByBase()) + foreach (var vm in TangoIOC.Default.GetAllInstancesByBase()) { vm.OnShuttingDown(); } @@ -191,7 +190,7 @@ namespace Tango.MachineStudio.UI.StudioApplication LogManager.Log(ex, "Error disconnecting from machine."); } - var eventLogger = ServiceLocator.Current.GetInstance(); + var eventLogger = TangoIOC.Default.GetInstance(); if (eventLogger != null) { eventLogger.Log(EventTypes.ApplicationTerminated, "Application Terminated!"); @@ -210,18 +209,18 @@ namespace Tango.MachineStudio.UI.StudioApplication /// /// Name of the module. /// The arguments. - public void RequestModule(string moduleName, object args) + public void RequestModule(string moduleName, params object[] args) { IStudioModule module = _moduleLoader.UserModules.SingleOrDefault(x => x.Name == moduleName); if (module != null) { - ServiceLocator.Current.GetInstance().StartModule(module); + TangoIOC.Default.GetInstance().StartModule(module); //Notify request listeners. - foreach (var vm in ServiceLocator.Current.GetAllInstancesByBase()) + foreach (var vm in TangoIOC.Default.GetAllInstancesByBase()) { - vm.OnRequestModule(module, args); + vm.OnModuleRequest(module, args); } } else 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 eb4139936..722d37d77 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 @@ -54,15 +54,6 @@ ..\..\packages\FontAwesome.WPF.4.7.0.9\lib\net40\FontAwesome.WPF.dll - - ..\..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.dll - - - ..\..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.Extras.dll - - - ..\..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.Platform.dll - ..\..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll @@ -78,9 +69,6 @@ ..\..\packages\MaterialDesignThemes.2.3.1.953\lib\net45\MaterialDesignThemes.Wpf.dll - - ..\..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll - ..\..\packages\SimpleValidator.0.6.1.0\lib\net40\SimpleValidator.dll @@ -123,7 +111,7 @@ - ..\..\packages\MvvmLightLibs.5.3.0.0\lib\net45\System.Windows.Interactivity.dll + ..\..\packages\Expression.Blend.Sdk.1.0.2\lib\net45\System.Windows.Interactivity.dll diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs index fa3a38c5c..c4b8a1a59 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs @@ -1,7 +1,5 @@ -using GalaSoft.MvvmLight; -using GalaSoft.MvvmLight.Ioc; -using Microsoft.Practices.ServiceLocation; using System; +using Tango.Core.DI; using Tango.Integration.Services; using Tango.Logging; using Tango.MachineStudio.Common.Authentication; @@ -40,66 +38,63 @@ namespace Tango.MachineStudio.UI /// public ViewModelLocator() { - ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); - ////if (ViewModelBase.IsInDesignModeStatic) ////{ //// // Create design time view services and models - //// SimpleIoc.Default.Register(); + //// TangoIOC.Default.Register(); ////} ////else ////{ //// // Create run time view services and models - //// SimpleIoc.Default.Register(); + //// TangoIOC.Default.Register(); ////} - SimpleIoc.Default.Unregister(); - SimpleIoc.Default.Unregister(); - SimpleIoc.Default.Unregister(); - SimpleIoc.Default.Unregister(); - SimpleIoc.Default.Unregister(); - SimpleIoc.Default.Unregister(); - SimpleIoc.Default.Unregister(); - SimpleIoc.Default.Unregister(); - SimpleIoc.Default.Unregister(); - SimpleIoc.Default.Unregister(); - SimpleIoc.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); //Register View (Supervising Controller Pattern). - if (!ViewModelBase.IsInDesignModeStatic) - { - LogManager.Log(String.Format("Registering Supervising Controller {0}...", nameof(IMainView))); - SimpleIoc.Default.Register(() => (IMainView)MainView.Self); - } + //if (!ViewModelBase.IsInDesignModeStatic) + //{ + // LogManager.Log(String.Format("Registering Supervising Controller {0}...", nameof(IMainView))); + // TangoIOC.Default.Register(() => (IMainView)MainView.Self); + //} } public MainViewVM MainViewVM { get { - return ServiceLocator.Current.GetInstance(); + return TangoIOC.Default.GetInstance(); } } @@ -107,7 +102,7 @@ namespace Tango.MachineStudio.UI { get { - return ServiceLocator.Current.GetInstance(); + return TangoIOC.Default.GetInstance(); } } @@ -115,7 +110,7 @@ namespace Tango.MachineStudio.UI { get { - return ServiceLocator.Current.GetInstance(); + return TangoIOC.Default.GetInstance(); } } @@ -123,7 +118,7 @@ namespace Tango.MachineStudio.UI { get { - return ServiceLocator.Current.GetInstance(); + return TangoIOC.Default.GetInstance(); } } @@ -131,7 +126,7 @@ namespace Tango.MachineStudio.UI { get { - return ServiceLocator.Current.GetInstance(); + return TangoIOC.Default.GetInstance(); } } @@ -139,7 +134,7 @@ namespace Tango.MachineStudio.UI { get { - return ServiceLocator.Current.GetInstance(); + return TangoIOC.Default.GetInstance(); } } @@ -147,7 +142,7 @@ namespace Tango.MachineStudio.UI { get { - return ServiceLocator.Current.GetInstance(); + return TangoIOC.Default.GetInstance(); } } @@ -155,7 +150,7 @@ namespace Tango.MachineStudio.UI { get { - return ServiceLocator.Current.GetInstance(); + return TangoIOC.Default.GetInstance(); } } } 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 b97825d34..25346e94b 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs @@ -1,6 +1,4 @@ -using GalaSoft.MvvmLight.Ioc; -using GalaSoft.MvvmLight.Messaging; -using System; +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; @@ -14,6 +12,7 @@ using System.Windows.Controls; using System.Windows.Media; using Tango.BL.Entities; using Tango.Core.Commands; +using Tango.Core.DI; using Tango.Integration.Services; using Tango.Logging; using Tango.MachineStudio.Common; @@ -45,7 +44,7 @@ namespace Tango.MachineStudio.UI.ViewModels /// Represents the Machine Studio main view, view model. /// /// - public class MainViewVM : ViewModel + public class MainViewVM : ViewModel { private IStudioModule _currentModule; private INavigationManager _navigation; @@ -240,7 +239,6 @@ namespace Tango.MachineStudio.UI.ViewModels /// The application manager. /// The navigation manager. public MainViewVM( - IMainView view, IAuthenticationProvider authenticationProvider, IStudioModuleLoader studioModuleLoader, INotificationProvider notificationProvider, @@ -249,7 +247,7 @@ namespace Tango.MachineStudio.UI.ViewModels IEventLogger eventLogger, IDiagnosticsFrameProvider frameProvider, ISpeechProvider speechProvider, - IHtmlPresenter htmlPresenter) : base(view) + IHtmlPresenter htmlPresenter) : base() { _eventLogger = eventLogger; _navigation = navigationManager; @@ -508,9 +506,10 @@ namespace Tango.MachineStudio.UI.ViewModels } } - foreach (var m in StudioModuleLoader.AllModules.Where(x => x != module)) + foreach (var m in StudioModuleLoader.AllModules.Where(x => x != module && !x.InNewWindow)) { m.IsLoaded = false; + TangoIOC.Default.GetModuleViewModels(m).ToList().ForEach(x => x.OnNavigatedFrom()); } if (module != null) @@ -519,6 +518,8 @@ namespace Tango.MachineStudio.UI.ViewModels CurrentModule.IsLoaded = true; IsModuleLoaded = true; (MainView.Self as MainView).TransitionControl.NavigateTo(module.Name); + + TangoIOC.Default.GetModuleViewModels(module).ToList().ForEach(x => x.OnNavigatedTo()); } else { @@ -527,14 +528,6 @@ namespace Tango.MachineStudio.UI.ViewModels } } - /// - /// Called when the is loaded and attached. - /// - protected override void OnViewAttached() - { - base.OnViewAttached(); - } - /// /// Opens the module in a new window. /// @@ -545,10 +538,10 @@ namespace Tango.MachineStudio.UI.ViewModels try { - StartModule(null); - module.InNewWindow = true; + StartModule(null); + if (!(MainView.Self as MainView).TransitionControl.Elements.ToList().Exists(x => x.GetType() == module.MainViewType)) { FrameworkElement v = Activator.CreateInstance(module.MainViewType) as FrameworkElement; @@ -565,11 +558,14 @@ namespace Tango.MachineStudio.UI.ViewModels { window.grid.Children.Remove(view); module.InNewWindow = false; + TangoIOC.Default.GetModuleViewModels(module).ToList().ForEach(v => v.OnNavigatedFrom()); }; window.Owner = MainWindow.Instance; window.Show(); + TangoIOC.Default.GetModuleViewModels(module).ToList().ForEach(x => x.OnNavigatedTo()); + (_applicationManager as DefaultStudioApplicationManager).RegisterOpenedWindow(window); } catch (Exception ex) diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs index ab4fd8e0b..0f6ec8b98 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs @@ -1,6 +1,5 @@ using FluentFTP; using Ionic.Zip; -using Microsoft.Practices.ServiceLocation; using System; using System.Collections.Generic; using System.Diagnostics; @@ -12,6 +11,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using Tango.Core.Commands; +using Tango.Core.DI; using Tango.Core.Helpers; using Tango.Logging; using Tango.MachineStudio.Common.Authentication; @@ -256,7 +256,7 @@ namespace Tango.MachineStudio.UI.ViewModels } } - ServiceLocator.Current.GetInstance().DisableCheckForUpdates = true; + TangoIOC.Default.GetInstance().DisableCheckForUpdates = true; Status = UpdateStatus.UpdateCompleted; } catch (Exception ex) 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 df1f97f23..1e894f3f2 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 @@ -1,5 +1,4 @@ -using Microsoft.Practices.ServiceLocation; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -27,6 +26,7 @@ using Tango.Core.Helpers; using Tango.SharedUI.Helpers; using Tango.Logging; using static Tango.SharedUI.Controls.NavigationControl; +using Tango.Core.DI; namespace Tango.MachineStudio.UI.Views { @@ -41,7 +41,7 @@ namespace Tango.MachineStudio.UI.Views { InitializeComponent(); - _loader = ServiceLocator.Current.GetInstance() as DefaultStudioModuleLoader; + _loader = TangoIOC.Default.GetInstance() as DefaultStudioModuleLoader; _loader.ModulesLoaded += Loader_ModulesLoaded; } @@ -51,7 +51,7 @@ namespace Tango.MachineStudio.UI.Views { LogManager.Default.Log("Loading modules views..."); - var item = ServiceLocator.Current.GetInstance().PushTaskItem("Loading Modules..."); + var item = TangoIOC.Default.GetInstance().PushTaskItem("Loading Modules..."); var modules = _loader.UserModules.ToList(); diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/packages.config b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/packages.config index 5dcc330a7..9568f9f90 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/packages.config +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/packages.config @@ -3,6 +3,7 @@ + @@ -10,8 +11,6 @@ - - -- cgit v1.3.1 From fa5e1c45ab2da4e988cf256c0e5ec521288e537f Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Sun, 22 Apr 2018 15:58:38 +0300 Subject: Implemented some UI test automation for Job create/delete. --- Software/DB/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/Tango_log.ldf | Bin 1572864 -> 1572864 bytes .../Views/JobView.xaml | 13 +-- .../Views/MachineJobSelectionView.xaml | 9 +- .../Automation/Developer.cs | 22 +++++ .../Tango.MachineStudio.Common/Automation/UI.cs | 13 +++ .../Tango.MachineStudio.Common.csproj | 2 + .../Tango.MachineStudio.UI/Views/LoginView.xaml | 3 +- .../Tango.UnitTesting/DependencyInjection_TST.cs | 9 ++ .../Tango.UnitTesting/MachineStudio_TST.cs | 104 ++++++++++++++++++++- .../Tango.UnitTesting/Tango.UnitTesting.csproj | 4 + 11 files changed, 163 insertions(+), 16 deletions(-) create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Automation/Developer.cs create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Automation/UI.cs (limited to 'Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI') diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf index 285e43436..3cacb7854 100644 Binary files a/Software/DB/Tango.mdf and b/Software/DB/Tango.mdf differ diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf index 04cb5a2a6..b324efdb7 100644 Binary files a/Software/DB/Tango_log.ldf and b/Software/DB/Tango_log.ldf differ diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml index c575ef2a3..99b3a9712 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml @@ -6,6 +6,7 @@ xmlns:global="clr-namespace:Tango.MachineStudio.Developer" xmlns:dragAndDrop="clr-namespace:Tango.DragAndDrop;assembly=Tango.DragAndDrop" xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls" + xmlns:automation="clr-namespace:Tango.MachineStudio.Common.Automation;assembly=Tango.MachineStudio.Common" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:techViews="clr-namespace:Tango.MachineStudio.Technician.Views;assembly=Tango.MachineStudio.Technician" xmlns:colorPicker="clr-namespace:Tango;assembly=Tango.ColorPicker" @@ -233,7 +234,7 @@ Remove - diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml new file mode 100644 index 000000000..f2e3038b9 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + Report Issue + + + + + + + + + + + + Tags + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml.cs new file mode 100644 index 000000000..91a288d3e --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.MachineStudio.UI.Views +{ + /// + /// Interaction logic for ReportIssueView.xaml + /// + public partial class ReportIssueView : UserControl + { + public ReportIssueView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/Tango.CodeGeneration/Helper.cs b/Software/Visual_Studio/Tango.CodeGeneration/Helper.cs index dff85a011..dfbc893ee 100644 --- a/Software/Visual_Studio/Tango.CodeGeneration/Helper.cs +++ b/Software/Visual_Studio/Tango.CodeGeneration/Helper.cs @@ -13,7 +13,7 @@ namespace Tango.CodeGeneration /// /// Contains several code generation helper methods. /// - internal static class Helper + public static class Helper { /// /// Gets a code template by the code object type. @@ -55,6 +55,17 @@ namespace Tango.CodeGeneration return Engine.Razor.RunCompile(template, Guid.NewGuid().ToString(), model.GetType(), model).Replace("
", "").Replace("
", ""); } + /// + /// Parses the specified text. + /// + /// The text. + /// The model. + /// + public static String Parse(String text,object model) + { + return Engine.Razor.RunCompile(text, Guid.NewGuid().ToString(), model.GetType(), model); + } + /// /// Indents the c sharp code. /// diff --git a/Software/Visual_Studio/Tango.Core/ExtendedObject.cs b/Software/Visual_Studio/Tango.Core/ExtendedObject.cs index be6302a4b..8ed7c5ecd 100644 --- a/Software/Visual_Studio/Tango.Core/ExtendedObject.cs +++ b/Software/Visual_Studio/Tango.Core/ExtendedObject.cs @@ -1,4 +1,5 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations.Schema; @@ -28,6 +29,7 @@ namespace Tango.Core /// /// Gets the default log manager. /// + [JsonIgnore] public LogManager LogManager { get { return LogManager.Default; } @@ -82,6 +84,7 @@ namespace Tango.Core /// Gets a value indicating whether we are currently in VS design mode. ///
[NotMapped] + [JsonIgnore] public bool DesignMode { get { return (DesignerProperties.GetIsInDesignMode(new DependencyObject())); } diff --git a/Software/Visual_Studio/Tango.Core/ExtensionMethods/BitmapExtensions.cs b/Software/Visual_Studio/Tango.Core/ExtensionMethods/BitmapExtensions.cs new file mode 100644 index 000000000..3cca605e9 --- /dev/null +++ b/Software/Visual_Studio/Tango.Core/ExtensionMethods/BitmapExtensions.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.Linq; +using System.Threading.Tasks; + + +public static class BitmapExtensions +{ + /// + /// Saves the specified bitmap as a JPEG file with the specified quality (0-100). + /// + /// The bitmap. + /// The file path. + /// The quality. + public static void SaveJpeg(this Bitmap bitmap, String filePath, int quality) + { + var encoder = ImageCodecInfo.GetImageEncoders().First(c => c.FormatID == ImageFormat.Jpeg.Guid); + var encParams = new EncoderParameters() { Param = new[] { new EncoderParameter(Encoder.Quality, quality) } }; + bitmap.Save(filePath, encoder, encParams); + } +} + diff --git a/Software/Visual_Studio/Tango.Core/Tango.Core.csproj b/Software/Visual_Studio/Tango.Core/Tango.Core.csproj index e7172cc21..a9196237b 100644 --- a/Software/Visual_Studio/Tango.Core/Tango.Core.csproj +++ b/Software/Visual_Studio/Tango.Core/Tango.Core.csproj @@ -70,6 +70,7 @@ + diff --git a/Software/Visual_Studio/Tango.Logging/FileLogger.cs b/Software/Visual_Studio/Tango.Logging/FileLogger.cs index 215b1d9ac..4be7ab5c2 100644 --- a/Software/Visual_Studio/Tango.Logging/FileLogger.cs +++ b/Software/Visual_Studio/Tango.Logging/FileLogger.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Text; @@ -58,7 +59,14 @@ namespace Tango.Logging /// The output. public void OnLog(LogItemBase output) { - File.AppendAllText(LogFile, output.ToString() + Environment.NewLine); + try + { + File.AppendAllText(LogFile, output.ToString() + Environment.NewLine); + } + catch + { + Debug.WriteLine("Error Writing To Log File!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + } } private bool _isEnabled; diff --git a/Software/Visual_Studio/Tango.SharedUI/ExtensionMethods/FrameworkElementExtensions.cs b/Software/Visual_Studio/Tango.SharedUI/ExtensionMethods/FrameworkElementExtensions.cs new file mode 100644 index 000000000..422b078a4 --- /dev/null +++ b/Software/Visual_Studio/Tango.SharedUI/ExtensionMethods/FrameworkElementExtensions.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Drawing.Imaging; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media.Imaging; +using Tango.SharedUI.Rendering; + +public static class FrameworkElementExtensions +{ + public static void RenderToFile(this FrameworkElement element, String filePath, ImageFormat format, Size renderSize, int quality) + { + RenderWindow renderer = new RenderWindow(element); + renderer.RenderToFileSynced(new Size(element.Width, element.Height), renderSize, filePath, format, quality, null); + } +} diff --git a/Software/Visual_Studio/Tango.SharedUI/Rendering/RenderWindow.xaml b/Software/Visual_Studio/Tango.SharedUI/Rendering/RenderWindow.xaml new file mode 100644 index 000000000..51a8b78ea --- /dev/null +++ b/Software/Visual_Studio/Tango.SharedUI/Rendering/RenderWindow.xaml @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Software/Visual_Studio/Tango.SharedUI/Rendering/RenderWindow.xaml.cs b/Software/Visual_Studio/Tango.SharedUI/Rendering/RenderWindow.xaml.cs new file mode 100644 index 000000000..638bf7267 --- /dev/null +++ b/Software/Visual_Studio/Tango.SharedUI/Rendering/RenderWindow.xaml.cs @@ -0,0 +1,255 @@ +using System; +using System.Collections.Generic; +using System.Drawing.Imaging; +using System.IO; +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; + +namespace Tango.SharedUI.Rendering +{ + /// + /// Represents an on window chart renderer. + /// + public partial class RenderWindow : Window + { + private Action _fileCallback; + private Action _bitmapCallback; + private Size _renderSize; + private ImageFormat _format; + private int _quality; + private String _filePath; + private FrameworkElement _element; + private bool renderToFile; + + /// + /// Initializes a new instance of the class. + /// + /// The element. + public RenderWindow(FrameworkElement element) + { + InitializeComponent(); + element.HorizontalAlignment = System.Windows.HorizontalAlignment.Left; + element.VerticalAlignment = System.Windows.VerticalAlignment.Top; + _element = element; + grid.Children.Add(_element); + } + + /// + /// Occurs when the window is completely loaded. + /// + /// The sender. + /// The instance containing the event data. + private void RenderWindow_ContentRendered(object sender, EventArgs e) + { + RenderTargetBitmap bmp = CreateBitmap(grid, new Size(_renderSize.Width, _renderSize.Height)); + + if (renderToFile) + { + using (FileStream fs = new FileStream(_filePath, FileMode.Create)) + { + BitmapEncoder encoder = GetEncoderByImageFormat(_format, _quality); + + encoder.Frames.Add(BitmapFrame.Create(bmp)); + encoder.Save(fs); + } + + if (_fileCallback != null) + { + _fileCallback(_filePath); + } + } + else + { + if (_bitmapCallback != null) + { + _bitmapCallback(bmp); + } + } + + this.Close(); + } + + /// + /// Renders to file. + /// + /// Size of the design. + /// Size of the render. + /// The file path. + /// The format. + /// The ready callback. + public void RenderToFile(Size designSize, Size renderSize, String filePath, ImageFormat format, Action readyCallback = null) + { + renderToFile = true; + _renderSize = renderSize; + _filePath = filePath; + _format = format; + _fileCallback = readyCallback; + + double scaleX = renderSize.Width / designSize.Width; + double scaleY = scaleX; + + this.WindowStyle = WindowStyle.None; + this.AllowsTransparency = true; + this.Opacity = 0.001; + this.ShowInTaskbar = false; + this.ShowActivated = false; + this.Width = 1; + this.Height = 1; + _element.Width = designSize.Width; + _element.Height = designSize.Height; + + + grid.LayoutTransform = new ScaleTransform(scaleX, scaleY, 0, 0); + + this.ContentRendered += RenderWindow_ContentRendered; + + this.Show(); + } + + /// + /// Renders to file. + /// + /// Size of the design. + /// Size of the render. + /// The file path. + /// The format. + /// The ready callback. + public void RenderToFileSynced(Size designSize, Size renderSize, String filePath, ImageFormat format, int quality, Action readyCallback = null) + { + renderToFile = true; + _renderSize = renderSize; + _filePath = filePath; + _format = format; + _quality = quality; + _fileCallback = readyCallback; + + double scaleX = renderSize.Width / designSize.Width; + double scaleY = scaleX; + + this.WindowStyle = WindowStyle.None; + this.AllowsTransparency = true; + this.Opacity = 0.001; + this.ShowInTaskbar = false; + this.ShowActivated = false; + this.Width = 1; + this.Height = 1; + _element.Width = designSize.Width; + _element.Height = designSize.Height; + + + grid.LayoutTransform = new ScaleTransform(scaleX, scaleY, 0, 0); + + this.ContentRendered += RenderWindow_ContentRendered; + + this.ShowDialog(); + } + + /// + /// Renders to bitmap. + /// + /// Size of the design. + /// Size of the render. + /// The ready callback. + public void RenderToBitmap(Size designSize, Size renderSize, Action readyCallback = null) + { + _renderSize = renderSize; + _bitmapCallback = readyCallback; + + double scaleX = renderSize.Width / designSize.Width; + double scaleY = scaleX; + + this.WindowStyle = WindowStyle.None; + this.AllowsTransparency = true; + this.Opacity = 0.001; + this.ShowInTaskbar = false; + this.ShowActivated = false; + this.Width = 1; + this.Height = 1; + _element.Width = designSize.Width; + _element.Height = designSize.Height; + + + grid.LayoutTransform = new ScaleTransform(scaleX, scaleY, 0, 0); + + this.ContentRendered += RenderWindow_ContentRendered; + + this.Show(); + } + + /// + /// Creates the bitmap. + /// + /// The o visual. + /// Size of the o. + /// + private RenderTargetBitmap CreateBitmap(Visual oVisual, Size oSize) + { + int nWidth = (int)Math.Ceiling(oSize.Width); + int nHeight = (int)Math.Ceiling(oSize.Height); + + RenderTargetBitmap oTargetBitmap = new RenderTargetBitmap( + nWidth, + nHeight, + 96, + 96, + PixelFormats.Pbgra32 + ); + + DrawingVisual oDrawingVisual = new DrawingVisual(); + + using (DrawingContext oDrawingContext = oDrawingVisual.RenderOpen()) + { + VisualBrush oVisualBrush = new VisualBrush(oVisual) { Stretch = Stretch.Fill }; + + oDrawingContext.DrawRectangle( + oVisualBrush, + null, + new Rect( + new Point(), + new Size(nWidth, nHeight) + ) + ); + + oDrawingContext.Close(); + oTargetBitmap.Render(oDrawingVisual); + } + + return oTargetBitmap; + } + + /// + /// Gets the encoder by image format. + /// + /// The format. + /// + private static BitmapEncoder GetEncoderByImageFormat(ImageFormat format, int quality) + { + BitmapEncoder encoder = null; + + if (format == ImageFormat.Png) + { + encoder = new PngBitmapEncoder(); + } + else if (format == ImageFormat.Jpeg) + { + encoder = new JpegBitmapEncoder(); + (encoder as JpegBitmapEncoder).QualityLevel = quality; + } + else + { + encoder = new BmpBitmapEncoder(); + } + + return encoder; + } + } +} diff --git a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj index eeae87a91..fa5d02617 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj +++ b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj @@ -108,6 +108,7 @@ ParameterizedEditor.xaml + @@ -125,6 +126,9 @@ Settings.settings True + + RenderWindow.xaml + @@ -160,6 +164,10 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + diff --git a/Software/Visual_Studio/Tango.SharedUI/ViewModel.cs b/Software/Visual_Studio/Tango.SharedUI/ViewModel.cs index 13b9206cd..4418ca437 100644 --- a/Software/Visual_Studio/Tango.SharedUI/ViewModel.cs +++ b/Software/Visual_Studio/Tango.SharedUI/ViewModel.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; @@ -32,6 +33,16 @@ namespace Tango.SharedUI set { _hasErrors = value; RaisePropertyChangedAuto(); } } + private ObservableCollection _validationErrors; + /// + /// Gets or sets the validation errors. + /// + public ObservableCollection ValidationErrors + { + get { return _validationErrors; } + private set { _validationErrors = value; RaisePropertyChangedAuto(); } + } + /// /// Occurs when the validation errors have changed for a property or for the entire entity. /// @@ -69,6 +80,13 @@ namespace Tango.SharedUI HasErrors = false; _currentErrors.Clear(); + if (ValidationErrors == null) + { + ValidationErrors = new ObservableCollection(); + } + + ValidationErrors.Clear(); + foreach (var prop in this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) { foreach (var validation in prop.GetCustomAttributes()) @@ -77,6 +95,7 @@ namespace Tango.SharedUI { HasErrors = true; _currentErrors.Add(new KeyValuePair(prop.Name, validation.ErrorMessage)); + ValidationErrors.Add(validation.ErrorMessage); RaiseError(prop.Name); } } @@ -90,7 +109,7 @@ namespace Tango.SharedUI /// protected virtual void OnValidating() { - + } /// diff --git a/Software/Visual_Studio/Tango.TFS/ITeamFoundationServiceClient.cs b/Software/Visual_Studio/Tango.TFS/ITeamFoundationServiceClient.cs index 0f8ae5e82..51394f663 100644 --- a/Software/Visual_Studio/Tango.TFS/ITeamFoundationServiceClient.cs +++ b/Software/Visual_Studio/Tango.TFS/ITeamFoundationServiceClient.cs @@ -6,14 +6,40 @@ using System.Threading.Tasks; namespace Tango.TFS { + /// + /// Represents a VSTS (Visual Studio On-line) client implementation. + /// public interface ITeamFoundationServiceClient { + /// + /// Gets a team project by the specified name. + /// + /// The name. + /// Task GetProject(String name); + /// + /// Uploads a work item to the specified team project. + /// + /// The project. + /// The work item. + /// Task UploadWorkItem(Project project, WorkItem workItem); + /// + /// Gets a work item by the specified team project and work item id. + /// + /// The project. + /// The identifier. + /// Task GetWorkItem(Project project, int id); + /// + /// Deletes the specified work item. + /// + /// The project. + /// The identifier. + /// Task DeleteWorkItem(Project project, int id); } } diff --git a/Software/Visual_Studio/Tango.TFS/Priority.cs b/Software/Visual_Studio/Tango.TFS/Priority.cs index 88e2a0ca5..8a1e57b88 100644 --- a/Software/Visual_Studio/Tango.TFS/Priority.cs +++ b/Software/Visual_Studio/Tango.TFS/Priority.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -8,9 +9,13 @@ namespace Tango.TFS { public enum Priority { + [Description("Critical")] Priority1 = 1, + [Description("High")] Priority2 = 2, + [Description("Medium")] Priority3 = 3, + [Description("Low")] Priority4 = 4, } } diff --git a/Software/Visual_Studio/Tango.TFS/TeamFoundationServiceClient.cs b/Software/Visual_Studio/Tango.TFS/TeamFoundationServiceClient.cs index 6bcea336e..e6390260e 100644 --- a/Software/Visual_Studio/Tango.TFS/TeamFoundationServiceClient.cs +++ b/Software/Visual_Studio/Tango.TFS/TeamFoundationServiceClient.cs @@ -12,11 +12,18 @@ using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.Core; namespace Tango.TFS { - public class TeamFoundationServiceClient : ITeamFoundationServiceClient + /// + /// Represents a VSTS (Visual Studio On-line) client implementation. + /// + /// + public class TeamFoundationServiceClient : ExtendedObject, ITeamFoundationServiceClient { + #region Extension Fields Constants + private class ExtensionFields { public const String FOUND_IN_BUILD = "Microsoft.VSTS.Build.FoundIn"; @@ -26,12 +33,35 @@ namespace Tango.TFS public const String SYSTEM_INFO = "Microsoft.VSTS.TCM.SystemInfo"; } + #endregion + + #region Properties + + /// + /// Gets the default team collection URL. + /// public String CollectionURL { get; private set; } + /// + /// Gets the personal token used to authenticate against the service. https://docs.microsoft.com/en-us/vsts/accounts/use-personal-access-tokens-to-authenticate?view=vsts + /// public String PersonalToken { get; private set; } + /// + /// Gets the VSTS user name (optional). + /// public String UserName { get; private set; } + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The collection URL. + /// Name of the user. + /// The personal token. public TeamFoundationServiceClient(String collectionURL, String userName, String personalToken) { CollectionURL = collectionURL; @@ -39,6 +69,15 @@ namespace Tango.TFS PersonalToken = personalToken; } + #endregion + + #region Public Methods + + /// + /// Gets a team project by the specified name. + /// + /// The name. + /// public Task GetProject(string name) { return Task.Factory.StartNew(() => @@ -141,15 +180,18 @@ namespace Tango.TFS }); } + /// + /// Uploads a work item to the specified team project. + /// + /// The project. + /// The work item. + /// public Task UploadWorkItem(Project project, WorkItem workItem) { return Task.Factory.StartNew(() => { var connection = CreateConnection(); - //var projCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(CollectionURL)); - //WorkItemStore s = new WorkItemStore(projCollection, WorkItemStoreFlags.BypassRules); - WorkItemTrackingHttpClient witClient = connection.GetClient(); var patchDocument = new JsonPatchDocument(); @@ -157,56 +199,59 @@ namespace Tango.TFS patchDocument.Add(new JsonPatchOperation { Operation = Operation.Add, - Path = GetFieldNameForPut(CoreField.Title), + Path = GetFieldNameForWrite(CoreField.Title), Value = workItem.Title, }); - patchDocument.Add(new JsonPatchOperation + if (!String.IsNullOrWhiteSpace(workItem.Description)) { - Operation = Operation.Add, - Path = GetFieldNameForPut(CoreField.Description), - Value = workItem.Description, - }); + patchDocument.Add(new JsonPatchOperation + { + Operation = Operation.Add, + Path = GetFieldNameForWrite(CoreField.Description), + Value = workItem.Description, + }); + } patchDocument.Add(new JsonPatchOperation { Operation = Operation.Add, - Path = GetFieldNameForPut(CoreField.IterationPath), + Path = GetFieldNameForWrite(CoreField.IterationPath), Value = workItem.Iteration.Path, }); patchDocument.Add(new JsonPatchOperation { Operation = Operation.Add, - Path = GetFieldNameForPut(CoreField.AreaPath), + Path = GetFieldNameForWrite(CoreField.AreaPath), Value = workItem.Area.Path, }); patchDocument.Add(new JsonPatchOperation { Operation = Operation.Add, - Path = GetFieldNameForPut(CoreField.AssignedTo), + Path = GetFieldNameForWrite(CoreField.AssignedTo), Value = workItem.AssignedTo.AssignName, }); patchDocument.Add(new JsonPatchOperation { Operation = Operation.Add, - Path = GetFieldNameForPut(CoreField.CreatedBy), + Path = GetFieldNameForWrite(CoreField.CreatedBy), Value = workItem.CreatedBy.AssignName, }); patchDocument.Add(new JsonPatchOperation { Operation = Operation.Add, - Path = GetFieldNameForPut(CoreField.ChangedBy), + Path = GetFieldNameForWrite(CoreField.ChangedBy), Value = workItem.ChangedBy.AssignName, }); patchDocument.Add(new JsonPatchOperation { Operation = Operation.Add, - Path = GetFieldNameForPut(CoreField.AuthorizedAs), + Path = GetFieldNameForWrite(CoreField.AuthorizedAs), Value = workItem.AuthorizedAs.AssignName, }); @@ -250,7 +295,7 @@ namespace Tango.TFS patchDocument.Add(new JsonPatchOperation { Operation = Operation.Add, - Path = GetFieldNameForPut(CoreField.Tags), + Path = GetFieldNameForWrite(CoreField.Tags), Value = String.Join("; ", workItem.Tags.Select(x => x.Name)), }); } @@ -260,7 +305,7 @@ namespace Tango.TFS patchDocument.Add(new JsonPatchOperation { Operation = Operation.Add, - Path = GetExtensionFieldNameForPut(ExtensionFields.STEPS_TO_REP), + Path = GetExtensionFieldNameForWrite(ExtensionFields.STEPS_TO_REP), Value = workItem.StepsToReproduce, }); } @@ -270,7 +315,7 @@ namespace Tango.TFS patchDocument.Add(new JsonPatchOperation { Operation = Operation.Add, - Path = GetExtensionFieldNameForPut(ExtensionFields.FOUND_IN_BUILD), + Path = GetExtensionFieldNameForWrite(ExtensionFields.FOUND_IN_BUILD), Value = workItem.FoundInBuild, }); } @@ -278,28 +323,28 @@ namespace Tango.TFS patchDocument.Add(new JsonPatchOperation { Operation = Operation.Add, - Path = GetFieldNameForPut(CoreField.State), + Path = GetFieldNameForWrite(CoreField.State), Value = workItem.State.ToString(), }); patchDocument.Add(new JsonPatchOperation { Operation = Operation.Add, - Path = GetExtensionFieldNameForPut(ExtensionFields.SEVERITY), + Path = GetExtensionFieldNameForWrite(ExtensionFields.SEVERITY), Value = workItem.Severity.ToDescription(), }); patchDocument.Add(new JsonPatchOperation { Operation = Operation.Add, - Path = GetExtensionFieldNameForPut(ExtensionFields.PRIORITY), + Path = GetExtensionFieldNameForWrite(ExtensionFields.PRIORITY), Value = (int)workItem.Priority, }); patchDocument.Add(new JsonPatchOperation { Operation = Operation.Add, - Path = GetExtensionFieldNameForPut(ExtensionFields.SYSTEM_INFO), + Path = GetExtensionFieldNameForWrite(ExtensionFields.SYSTEM_INFO), Value = workItem.SystemInformation, }); @@ -312,27 +357,12 @@ namespace Tango.TFS }); } - private VssConnection CreateConnection() - { - VssConnection connection = new VssConnection(new Uri(CollectionURL), new VssBasicCredential(UserName, PersonalToken)); - return connection; - } - - private String GetFieldName(CoreField field) - { - return "System." + field.ToString(); - } - - private String GetFieldNameForPut(CoreField field) - { - return "/fields/System." + field.ToString(); - } - - private String GetExtensionFieldNameForPut(String extensionFieldName) - { - return "/fields/" + extensionFieldName; - } - + /// + /// Gets a work item by the specified team project and work item id. + /// + /// The project. + /// The identifier. + /// public Task GetWorkItem(Project project, int id) { return Task.Factory.StartNew(() => @@ -346,36 +376,36 @@ namespace Tango.TFS var item = witClient.GetWorkItemAsync(id, expand: Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models.WorkItemExpand.All).Result; workItem.ID = item.Id.Value; - workItem.Title = item.Fields[GetFieldName(CoreField.Title)].ToString(); - workItem.Description = TryGetField(item.Fields, GetFieldName(CoreField.Description)); + workItem.Title = item.Fields[GetFieldNameForRead(CoreField.Title)].ToString(); + workItem.Description = TryGetField(item.Fields, GetFieldNameForRead(CoreField.Description)); workItem.Area = new Area() { - Path = item.Fields[GetFieldName(CoreField.AreaPath)].ToString(), - Name = Path.GetFileName(item.Fields[GetFieldName(CoreField.AreaPath)].ToString()), + Path = item.Fields[GetFieldNameForRead(CoreField.AreaPath)].ToString(), + Name = Path.GetFileName(item.Fields[GetFieldNameForRead(CoreField.AreaPath)].ToString()), }; workItem.Iteration = new Iteration() { - Path = item.Fields[GetFieldName(CoreField.IterationPath)].ToString(), - Name = Path.GetFileName(item.Fields[GetFieldName(CoreField.IterationPath)].ToString()), + Path = item.Fields[GetFieldNameForRead(CoreField.IterationPath)].ToString(), + Name = Path.GetFileName(item.Fields[GetFieldNameForRead(CoreField.IterationPath)].ToString()), }; - workItem.AssignedTo = project.Members.SingleOrDefault(x => x.AssignName == TryGetField(item.Fields, GetFieldName(CoreField.AssignedTo))); - workItem.CreatedBy = project.Members.SingleOrDefault(x => x.AssignName == TryGetField(item.Fields, GetFieldName(CoreField.CreatedBy))); - workItem.ChangedBy = project.Members.SingleOrDefault(x => x.AssignName == TryGetField(item.Fields, GetFieldName(CoreField.ChangedBy))); - workItem.AuthorizedAs = project.Members.SingleOrDefault(x => x.AssignName == TryGetField(item.Fields, GetFieldName(CoreField.AuthorizedAs))); + workItem.AssignedTo = project.Members.SingleOrDefault(x => x.AssignName == TryGetField(item.Fields, GetFieldNameForRead(CoreField.AssignedTo))); + workItem.CreatedBy = project.Members.SingleOrDefault(x => x.AssignName == TryGetField(item.Fields, GetFieldNameForRead(CoreField.CreatedBy))); + workItem.ChangedBy = project.Members.SingleOrDefault(x => x.AssignName == TryGetField(item.Fields, GetFieldNameForRead(CoreField.ChangedBy))); + workItem.AuthorizedAs = project.Members.SingleOrDefault(x => x.AssignName == TryGetField(item.Fields, GetFieldNameForRead(CoreField.AuthorizedAs))); - workItem.Type = (WorkItemType)Enum.Parse(typeof(WorkItemType), item.Fields[GetFieldName(CoreField.WorkItemType)].ToString()); + workItem.Type = (WorkItemType)Enum.Parse(typeof(WorkItemType), item.Fields[GetFieldNameForRead(CoreField.WorkItemType)].ToString()); workItem.URL = item.Url; - if (item.Fields.ContainsKey(GetFieldName(CoreField.Tags))) + if (item.Fields.ContainsKey(GetFieldNameForRead(CoreField.Tags))) { - List tags = item.Fields[GetFieldName(CoreField.Tags)].ToString().Split(';').Select(x => x.Trim()).ToList(); + List tags = item.Fields[GetFieldNameForRead(CoreField.Tags)].ToString().Split(';').Select(x => x.Trim()).ToList(); workItem.Tags = tags.Select(x => new Tag() { Name = x }).ToList(); } workItem.FoundInBuild = item.Fields[ExtensionFields.FOUND_IN_BUILD].ToString(); - workItem.State = (State)Enum.Parse(typeof(State), item.Fields[GetFieldName(CoreField.State)].ToString()); + workItem.State = (State)Enum.Parse(typeof(State), item.Fields[GetFieldNameForRead(CoreField.State)].ToString()); workItem.Severity = ParseEnumByDescription(item.Fields[ExtensionFields.SEVERITY].ToString()); @@ -389,6 +419,12 @@ namespace Tango.TFS }); } + /// + /// Deletes the specified work item. + /// + /// The project. + /// The identifier. + /// public Task DeleteWorkItem(Project project, int id) { return Task.Factory.StartNew(() => @@ -400,6 +436,56 @@ namespace Tango.TFS }); } + #endregion + + #region Private Methods + + /// + /// Creates connection to VSTS. + /// + /// + private VssConnection CreateConnection() + { + VssConnection connection = new VssConnection(new Uri(CollectionURL), new VssBasicCredential(UserName, PersonalToken)); + return connection; + } + + /// + /// Creates a string representation of a VSTS field when reading. + /// + /// The field. + /// + private String GetFieldNameForRead(CoreField field) + { + return "System." + field.ToString(); + } + + /// + /// Creates a string representation of a VSTS field when writing. + /// + /// The field. + /// + private String GetFieldNameForWrite(CoreField field) + { + return "/fields/System." + field.ToString(); + } + + /// + /// Creates a string representation of a VSTS extension field when writing. + /// + /// The field. + /// + private String GetExtensionFieldNameForWrite(String extensionFieldName) + { + return "/fields/" + extensionFieldName; + } + + /// + /// Returns a value of the specified field key if found. Otherwise return an empty string. + /// + /// The fields. + /// The key. + /// private String TryGetField(IDictionary fields, String key) { if (fields.ContainsKey(key)) @@ -410,6 +496,12 @@ namespace Tango.TFS return String.Empty; } + /// + /// Returns the specified enum type value by it's [Description] attribute. + /// + /// + /// The description. + /// private T ParseEnumByDescription(String description) { Dictionary values = new Dictionary(); @@ -421,5 +513,7 @@ namespace Tango.TFS return values[description]; } + + #endregion } } diff --git a/Software/Visual_Studio/Tango.TFS/TeamMember.cs b/Software/Visual_Studio/Tango.TFS/TeamMember.cs index 0d8d402f8..747d550ca 100644 --- a/Software/Visual_Studio/Tango.TFS/TeamMember.cs +++ b/Software/Visual_Studio/Tango.TFS/TeamMember.cs @@ -19,5 +19,10 @@ namespace Tango.TFS get { return String.Format("{0} <{1}>", DisplayName, UniqueName); } } + public override string ToString() + { + return AssignName; + } + } } diff --git a/Software/Visual_Studio/Tango.TFS/WorkItem.cs b/Software/Visual_Studio/Tango.TFS/WorkItem.cs index 305f7d864..98ac05191 100644 --- a/Software/Visual_Studio/Tango.TFS/WorkItem.cs +++ b/Software/Visual_Studio/Tango.TFS/WorkItem.cs @@ -4,31 +4,141 @@ using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.Core; namespace Tango.TFS { - public class WorkItem + public class WorkItem : ExtendedObject { - public int ID { get; set; } - public String URL { get; set; } - public WorkItemType Type { get; set; } - public Area Area { get; set; } - public Iteration Iteration { get; set; } - public String Title { get; set; } - public String Description { get; set; } - public State State { get; set; } - public Severity Severity { get; set; } - public Priority Priority { get; set; } - public String StepsToReproduce { get; set; } - public String SystemInformation { get; set; } - public TeamMember AssignedTo { get; set; } - public TeamMember CreatedBy { get; set; } - public TeamMember ChangedBy { get; set; } - public TeamMember AuthorizedAs { get; set; } + private int _id; + public int ID + { + get { return _id; } + internal set { _id = value; RaisePropertyChangedAuto(); } + } + + private String _url; + public String URL + { + get { return _url; } + internal set { _url = value; RaisePropertyChangedAuto(); } + } + + private WorkItemType _type; + public WorkItemType Type + { + get { return _type; } + set { _type = value; RaisePropertyChangedAuto(); } + } + + private Area _area; + public Area Area + { + get { return _area; } + set { _area = value; RaisePropertyChangedAuto(); } + } + + private Iteration _iteration; + public Iteration Iteration + { + get { return _iteration; } + set { _iteration = value; RaisePropertyChangedAuto(); } + } + + private String _title; + public String Title + { + get { return _title; } + set { _title = value; RaisePropertyChangedAuto(); } + } + + private String _description; + public String Description + { + get { return _description; } + set { _description = value; RaisePropertyChangedAuto(); } + } + + private State _state; + public State State + { + get { return _state; } + set { _state = value; RaisePropertyChangedAuto(); } + } + + private Severity _severity; + public Severity Severity + { + get { return _severity; } + set { _severity = value; RaisePropertyChangedAuto(); } + } + + private Priority _priority; + public Priority Priority + { + get { return _priority; } + set { _priority = value; RaisePropertyChangedAuto(); } + } + + private String _stepsToReproduce; + public String StepsToReproduce + { + get { return _stepsToReproduce; } + set { _stepsToReproduce = value; RaisePropertyChangedAuto(); } + } + + private String _systemInformation; + public String SystemInformation + { + get { return _systemInformation; } + set { _systemInformation = value; RaisePropertyChangedAuto(); } + } + + private TeamMember _assignedTo; + public TeamMember AssignedTo + { + get { return _assignedTo; } + set { _assignedTo = value; RaisePropertyChangedAuto(); } + } + + private TeamMember _createdBy; + public TeamMember CreatedBy + { + get { return _createdBy; } + set { _createdBy = value; RaisePropertyChangedAuto(); } + } + + private TeamMember _changedBy; + public TeamMember ChangedBy + { + get { return _changedBy; } + set { _changedBy = value; RaisePropertyChangedAuto(); } + } + + private TeamMember _authorizedAs; + public TeamMember AuthorizedAs + { + get { return _authorizedAs; } + set { _authorizedAs = value; RaisePropertyChangedAuto(); } + } + public List Attachments { get; set; } + public List Tags { get; set; } - public WorkItem UserStory { get; set; } - public String FoundInBuild { get; set; } + + private WorkItem _userStory; + public WorkItem UserStory + { + get { return _userStory; } + set { _userStory = value; RaisePropertyChangedAuto(); } + } + + private String _foundInBuild; + public String FoundInBuild + { + get { return _foundInBuild; } + set { _foundInBuild = value; RaisePropertyChangedAuto(); } + } public WorkItem() { -- cgit v1.3.1