aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Software/DB/Tango.mdfbin75497472 -> 75497472 bytes
-rw-r--r--Software/DB/Tango_log.ldfbin1572864 -> 1572864 bytes
-rw-r--r--Software/PMR/Messages/Connection/ConnectResponse.proto4
-rw-r--r--Software/PMR/Messages/Connection/DeviceInformation.proto11
-rw-r--r--Software/PMR/Messages/Diagnostics/PushDiagnosticsResponse.proto5
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/Views/MachineTechView.xaml6
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Converters/PermissionToVisibilityConverter.cs38
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/IStudioViewModel.cs5
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IStudioApplicationManager.cs8
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioViewModel.cs89
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj4
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs51
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/CodeTemplate.cs23
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleManager.cs39
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleOnExecuteParameters.cs26
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleWindow.xaml223
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleWindow.xaml.cs43
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleWindowVM.cs257
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/bug-resolved.pngbin0 -> 6496 bytes
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs21
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationModel.cs2
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationTemplate.cshtml25
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs103
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/WorkItemValidationAttribute.cs10
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj24
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs12
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs8
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs84
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ResolvedIssuesViewVM.cs61
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml48
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml110
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml89
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml.cs28
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionResolutions.cs3
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml12
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml.cs7
-rw-r--r--Software/Visual_Studio/Tango.BL/Enumerations/Permissions.cs6
-rw-r--r--Software/Visual_Studio/Tango.CodeGeneration/CustomResolver.cs20
-rw-r--r--Software/Visual_Studio/Tango.CodeGeneration/Helper.cs7
-rw-r--r--Software/Visual_Studio/Tango.CodeGeneration/Tango.CodeGeneration.csproj1
-rw-r--r--Software/Visual_Studio/Tango.Core/ExtensionMethods/ObjectExtensions.cs25
-rw-r--r--Software/Visual_Studio/Tango.Core/Helpers/EmbeddedResourceHelper.cs10
-rw-r--r--Software/Visual_Studio/Tango.Core/Json/DynamicContractResolver.cs30
-rw-r--r--Software/Visual_Studio/Tango.Core/Json/HtmlContractResolver.cs39
-rw-r--r--Software/Visual_Studio/Tango.Core/Tango.Core.csproj2
-rw-r--r--Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs14
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/IMachineOperator.cs15
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/MachineOperator.cs46
-rw-r--r--Software/Visual_Studio/Tango.PMR/Connection/ConnectResponse.cs44
-rw-r--r--Software/Visual_Studio/Tango.PMR/Connection/DeviceInformation.cs216
-rw-r--r--Software/Visual_Studio/Tango.PMR/Diagnostics/PushDiagnosticsResponse.cs97
-rw-r--r--Software/Visual_Studio/Tango.PMR/ExtensionMethods.cs2
-rw-r--r--Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj1
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Controls/ScriptEditorControl.xaml.cs4
-rw-r--r--Software/Visual_Studio/Tango.TFS/ITeamFoundationServiceClient.cs36
-rw-r--r--Software/Visual_Studio/Tango.TFS/ResolvedReason.cs27
-rw-r--r--Software/Visual_Studio/Tango.TFS/Tango.TFS.csproj5
-rw-r--r--Software/Visual_Studio/Tango.TFS/TeamFoundationServiceClient.cs248
-rw-r--r--Software/Visual_Studio/Tango.TFS/WorkItem.cs52
-rw-r--r--Software/Visual_Studio/Tango.UnitTesting/TFS_TST.cs52
60 files changed, 2258 insertions, 220 deletions
diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf
index ebd7dc607..7eccbdff2 100644
--- a/Software/DB/Tango.mdf
+++ b/Software/DB/Tango.mdf
Binary files differ
diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf
index 9f1c3dcfe..9e5f0e2af 100644
--- a/Software/DB/Tango_log.ldf
+++ b/Software/DB/Tango_log.ldf
Binary files differ
diff --git a/Software/PMR/Messages/Connection/ConnectResponse.proto b/Software/PMR/Messages/Connection/ConnectResponse.proto
index 8f3be5c20..e6c178083 100644
--- a/Software/PMR/Messages/Connection/ConnectResponse.proto
+++ b/Software/PMR/Messages/Connection/ConnectResponse.proto
@@ -1,9 +1,11 @@
syntax = "proto3";
+import "DeviceInformation.proto";
+
package Tango.PMR.Connection;
option java_package = "com.twine.tango.pmr.connection";
message ConnectResponse
{
-
+ DeviceInformation DeviceInformation = 1;
} \ No newline at end of file
diff --git a/Software/PMR/Messages/Connection/DeviceInformation.proto b/Software/PMR/Messages/Connection/DeviceInformation.proto
new file mode 100644
index 000000000..bc217c799
--- /dev/null
+++ b/Software/PMR/Messages/Connection/DeviceInformation.proto
@@ -0,0 +1,11 @@
+syntax = "proto3";
+
+package Tango.PMR.Connection;
+option java_package = "com.twine.tango.pmr.connection";
+
+message DeviceInformation
+{
+ string Name = 1;
+ string Version = 2;
+ string BuildDate = 3;
+} \ No newline at end of file
diff --git a/Software/PMR/Messages/Diagnostics/PushDiagnosticsResponse.proto b/Software/PMR/Messages/Diagnostics/PushDiagnosticsResponse.proto
index 3fdeaf40f..6c18586a5 100644
--- a/Software/PMR/Messages/Diagnostics/PushDiagnosticsResponse.proto
+++ b/Software/PMR/Messages/Diagnostics/PushDiagnosticsResponse.proto
@@ -21,9 +21,4 @@ message PushDiagnosticsResponse
//Hardware Errors & Warnings
repeated Event Events = 4;
-
- //Software Information
- string Version = 5;
- string VersionName = 6;
- string VersionBuildDate = 7;
} \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/Views/MachineTechView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/Views/MachineTechView.xaml
index 3d4ecdac1..53fcafb8f 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/Views/MachineTechView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/Views/MachineTechView.xaml
@@ -220,9 +220,9 @@
<Border HorizontalAlignment="Right" Width="220" Margin="10 0 5 8" BorderBrush="Gainsboro" BorderThickness="1 0 1 1" Padding="5">
<Grid>
<StackPanel TextElement.FontSize="10" VerticalAlignment="Center" TextElement.Foreground="Gray">
- <TextBlock HorizontalAlignment="Center"><Run FontWeight="SemiBold" FontStyle="Italic">Version Name:</Run> <Run Text="{Binding CurrentDiagnosticsResponse.VersionName,FallbackValue='N/A'}"></Run></TextBlock>
- <TextBlock HorizontalAlignment="Center" Margin="0 2 0 0"><Run FontWeight="SemiBold" FontStyle="Italic">Version Number:</Run> <Run Text="{Binding CurrentDiagnosticsResponse.Version,FallbackValue='N/A'}"></Run></TextBlock>
- <TextBlock HorizontalAlignment="Center" Margin="0 2 0 0"><Run FontWeight="SemiBold" FontStyle="Italic">Build Date:</Run> <Run Text="{Binding CurrentDiagnosticsResponse.VersionBuildDate,FallbackValue='N/A'}"></Run></TextBlock>
+ <TextBlock HorizontalAlignment="Center"><Run FontWeight="SemiBold" FontStyle="Italic">Version Name:</Run> <Run Text="{Binding MachineOperator.DeviceInformation.Name,FallbackValue='N/A'}"></Run></TextBlock>
+ <TextBlock HorizontalAlignment="Center" Margin="0 2 0 0"><Run FontWeight="SemiBold" FontStyle="Italic">Version Number:</Run> <Run Text="{Binding MachineOperator.DeviceInformation.Version,FallbackValue='N/A'}"></Run></TextBlock>
+ <TextBlock HorizontalAlignment="Center" Margin="0 2 0 0"><Run FontWeight="SemiBold" FontStyle="Italic">Build Date:</Run> <Run Text="{Binding MachineOperator.DeviceInformation.BuildDate,FallbackValue='N/A'}"></Run></TextBlock>
<TextBlock HorizontalAlignment="Center" Margin="0 2 0 0"><Run FontWeight="SemiBold" FontStyle="Italic">Diagnostics Frame Size:</Run> <Run Text="{Binding CurrentDiagnosticsResponseSize,Converter={StaticResource NumberToFileSizeConverter},FallbackValue='N/A'}"></Run></TextBlock>
</StackPanel>
</Grid>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Converters/PermissionToVisibilityConverter.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Converters/PermissionToVisibilityConverter.cs
new file mode 100644
index 000000000..08e7d1c12
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Converters/PermissionToVisibilityConverter.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Data;
+using Tango.BL.Entities;
+using Tango.BL.Enumerations;
+using Tango.Core.DI;
+using Tango.MachineStudio.Common.Authentication;
+
+namespace Tango.MachineStudio.Common.Converters
+{
+ public class PermissionToVisibilityConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ User user = value as User;
+
+ if (user != null)
+ {
+ if (user.HasPermission((Permissions)parameter))
+ {
+ return Visibility.Visible;
+ }
+ }
+
+ return Visibility.Collapsed;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/IStudioViewModel.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/IStudioViewModel.cs
index 35ed50cd9..4203a1e8b 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/IStudioViewModel.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/IStudioViewModel.cs
@@ -38,5 +38,10 @@ namespace Tango.MachineStudio.Common
/// </summary>
/// <param name="args">The arguments.</param>
void OnModuleRequest(params object[] args);
+
+ /// <summary>
+ /// Called when the application has been started
+ /// </summary>
+ void OnApplicationStarted();
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IStudioApplicationManager.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IStudioApplicationManager.cs
index be793ac81..1de18ac94 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IStudioApplicationManager.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IStudioApplicationManager.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using System.Windows;
using Tango.Integration.Services;
namespace Tango.MachineStudio.Common.StudioApplication
@@ -53,5 +54,12 @@ namespace Tango.MachineStudio.Common.StudioApplication
/// Gets the machine studio application version.
/// </summary>
String Version { get; }
+
+ /// <summary>
+ /// Notify the application manager about an external opened window.
+ /// When application exists. All registered windows will be closed.
+ /// </summary>
+ /// <param name="window">The window.</param>
+ void RegisterOpenedWindow(Window window);
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioViewModel.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioViewModel.cs
index 9c7e52d23..77fad1fc6 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioViewModel.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioViewModel.cs
@@ -13,6 +13,79 @@ namespace Tango.MachineStudio.Common
/// <typeparam name="Module">The type of the module.</typeparam>
/// <seealso cref="Tango.SharedUI.ViewModel" />
/// <seealso cref="Tango.MachineStudio.Common.IStudioViewModel" />
+ public abstract class StudioViewModelInternal : ViewModel, IStudioViewModel
+ {
+ /// <summary>
+ /// Gets or sets a value indicating whether this view model studio module is currently loaded.
+ /// </summary>
+ public bool IsModuleLoaded { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="StudioViewModel{Module}"/> class.
+ /// </summary>
+ public StudioViewModelInternal() : base()
+ {
+
+ }
+
+ /// <summary>
+ /// Called when another module has wants to navigate to this module with some arguments.
+ /// </summary>
+ /// <param name="args">The arguments.</param>
+ public virtual void OnModuleRequest(params object[] args)
+ {
+
+ }
+
+ /// <summary>
+ /// Called when the user has navigated out of the module.
+ /// </summary>
+ public virtual void OnNavigatedFrom()
+ {
+ IsModuleLoaded = false;
+ }
+
+ /// <summary>
+ /// Called when the user has navigated in to the module.
+ /// </summary>
+ public virtual void OnNavigatedTo()
+ {
+ IsModuleLoaded = true;
+ }
+
+ /// <summary>
+ /// Called before the application is shutting down.
+ /// Return false to cancel the shutdown in case an important process is in progress.
+ /// </summary>
+ /// <returns></returns>
+ public virtual Task<bool> OnShutdownRequest()
+ {
+ return Task.FromResult(true);
+ }
+
+ /// <summary>
+ /// Called when application is shutting down.
+ /// </summary>
+ public virtual void OnShuttingDown()
+ {
+
+ }
+
+ /// <summary>
+ /// Called when the application has been started
+ /// </summary>
+ public virtual void OnApplicationStarted()
+ {
+
+ }
+ }
+
+ /// <summary>
+ /// Represents a Machine Studio view model
+ /// </summary>
+ /// <typeparam name="Module">The type of the module.</typeparam>
+ /// <seealso cref="Tango.SharedUI.ViewModel" />
+ /// <seealso cref="Tango.MachineStudio.Common.IStudioViewModel" />
public abstract class StudioViewModel<Module> : ViewModel, IStudioViewModel where Module : IStudioModule
{
/// <summary>
@@ -70,6 +143,14 @@ namespace Tango.MachineStudio.Common
{
}
+
+ /// <summary>
+ /// Called when the application has been started
+ /// </summary>
+ public virtual void OnApplicationStarted()
+ {
+
+ }
}
/// <summary>
@@ -91,6 +172,14 @@ namespace Tango.MachineStudio.Common
}
/// <summary>
+ /// Called when the application has been started
+ /// </summary>
+ public virtual void OnApplicationStarted()
+ {
+
+ }
+
+ /// <summary>
/// Called when another module has wants to navigate to this module with some arguments.
/// </summary>
/// <param name="args">The arguments.</param>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj
index e4a2720b9..ac6f84618 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj
@@ -89,6 +89,7 @@
<DependentUpon>RealTimeGraphControl.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\TableGrid.cs" />
+ <Compile Include="Converters\PermissionToVisibilityConverter.cs" />
<Compile Include="Converters\SecondsToGraphPointsConverter.cs" />
<Compile Include="Diagnostics\DefaultDiagnosticsFrameProvider.cs" />
<Compile Include="Diagnostics\IDiagnosticsFrameProvider.cs" />
@@ -287,5 +288,8 @@
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
+ <ItemGroup>
+ <Folder Include="MarkupExtensions\" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> \ No newline at end of file
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 d9c64b9e3..f124ebb54 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs
@@ -15,6 +15,11 @@ using Tango.Settings;
using Tango.MachineStudio.Common.EventLogging;
using Tango.BL.Enumerations;
using Tango.Core.DI;
+using Tango.MachineStudio.UI.TFS;
+using Tango.TFS;
+using Tango.MachineStudio.Common.Notifications;
+using Tango.MachineStudio.UI.ViewModels;
+using Tango.MachineStudio.UI.Views;
namespace Tango.MachineStudio.UI
{
@@ -82,7 +87,26 @@ namespace Tango.MachineStudio.UI
Application.Current.Dispatcher.Invoke(() =>
{
- ExceptionWindow exWin = new ExceptionWindow(e.Exception);
+ WorkItem bug = null;
+ TeamFoundationServiceExtendedClient tfsClient = null;
+ INotificationProvider notification = null;
+
+ try
+ {
+ tfsClient = TangoIOC.Default.GetInstance<TeamFoundationServiceExtendedClient>();
+ notification = TangoIOC.Default.GetInstance<INotificationProvider>();
+
+ if (tfsClient != null && tfsClient.IsInitialized)
+ {
+ bug = tfsClient.CreateBug();
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine(ex.ToString());
+ }
+
+ ExceptionWindow exWin = new ExceptionWindow(e.Exception, bug != null);
exWin.ShowDialog();
switch (exWin.Resolution)
@@ -101,6 +125,31 @@ namespace Tango.MachineStudio.UI
LogManager.Log("User selection was to shutdown the application. Restarting...");
Environment.Exit(0);
break;
+ case ExceptionResolutions.Report:
+ e.TryRecover = true;
+ LogManager.Log("User selection was to report the issue.");
+
+ if (bug != null)
+ {
+ notification.ShowModalDialog<ReportIssueViewVM, ReportIssueView>(new ReportIssueViewVM(tfsClient.Project, bug), async (vm) =>
+ {
+ using (notification.PushTaskItem("Uploading bug report..."))
+ {
+ try
+ {
+ tfsClient.FinalizeBug(vm.WorkItem);
+ await tfsClient.UploadWorkItem(vm.WorkItem);
+ }
+ catch (Exception ex)
+ {
+ notification.ShowError("An error occurred while trying to create the issue." + Environment.NewLine + ex.Message);
+ }
+ }
+
+ }, null);
+ }
+
+ break;
}
});
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/CodeTemplate.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/CodeTemplate.cs
new file mode 100644
index 000000000..4b307051f
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/CodeTemplate.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Text;
+using System.Linq;
+using System.Drawing;
+using System.Diagnostics;
+using System.Windows.Forms;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Collections.Generic;
+using Tango.MachineStudio.Common.Notifications;
+using Tango.MachineStudio.UI.Console;
+
+public void OnExecute(ConsoleManager manager)
+{
+ manager.InvokeUI(() =>
+ {
+
+ var notification = manager.TangoIOC.GetInstance<INotificationProvider>();
+ notification.ShowInfo("Hello world!");
+
+ });
+}
+
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleManager.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleManager.cs
new file mode 100644
index 000000000..e2d525d95
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleManager.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core.DI;
+using Tango.MachineStudio.Common.Modules;
+
+namespace Tango.MachineStudio.UI.Console
+{
+ public class ConsoleManager
+ {
+ public TangoIOC TangoIOC { get; set; }
+ private Action<String> _writeLine;
+
+ public ConsoleManager(Action<String> writeLine)
+ {
+ _writeLine = writeLine;
+ TangoIOC = TangoIOC.Default;
+ }
+
+ public void WriteLine(String text)
+ {
+ _writeLine(text);
+ }
+
+ public void InvokeUI(Action action)
+ {
+ Core.Helpers.ThreadsHelper.InvokeUI(action);
+ }
+
+ public void StartModule(String name)
+ {
+ IStudioModuleLoader loader = TangoIOC.Default.GetInstance<IStudioModuleLoader>();
+ var module = loader.AllModules.SingleOrDefault(x => x.Name == name);
+ TangoIOC.Default.GetInstance<ViewModels.MainViewVM>().StartModule(module);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleOnExecuteParameters.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleOnExecuteParameters.cs
new file mode 100644
index 000000000..b06637ccd
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleOnExecuteParameters.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Scripting;
+
+namespace Tango.MachineStudio.UI.Console
+{
+ public class ConsoleOnExecuteParameters : OnExecuteParameters
+ {
+ /// <summary>
+ /// Provides access to the script stub manager.
+ /// </summary>
+ public ConsoleManager manager;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="StubOnExecuteParameters"/> class.
+ /// </summary>
+ /// <param name="manager">The manager.</param>
+ public ConsoleOnExecuteParameters(ConsoleManager manager)
+ {
+ this.manager = manager;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleWindow.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleWindow.xaml
new file mode 100644
index 000000000..22338fea7
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleWindow.xaml
@@ -0,0 +1,223 @@
+<mahapps:MetroWindow x:Class="Tango.MachineStudio.UI.Console.ConsoleWindow"
+ 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: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:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
+ xmlns:views="clr-namespace:Tango.MachineStudio.UI.Views"
+ xmlns:fa="http://schemas.fontawesome.io/icons/"
+ xmlns:sharedControls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
+ xmlns:console="clr-namespace:Tango.MachineStudio.UI.Console"
+ xmlns:local="clr-namespace:Tango.MachineStudio.UI.Console"
+ mc:Ignorable="d"
+ Title="Developer Console" Height="800" Width="1280" BorderThickness="1" BorderBrush="#ADADAD" d:DataContext="{d:DesignInstance Type=console:ConsoleWindowVM, IsDesignTimeCreatable=False}" DataContext="{Binding ConsoleWindowVM, Source={StaticResource Locator}}" Foreground="Gainsboro">
+
+ <Window.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/FlatButton.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/VS/Colors.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/VS/Styles.xaml" />
+ <ResourceDictionary>
+ <converters:StringEllipsisConverter x:Key="StringEllipsisConverter" />
+ </ResourceDictionary>
+ </ResourceDictionary.MergedDictionaries>
+ </ResourceDictionary>
+ </Window.Resources>
+
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="742*"/>
+ </Grid.RowDefinitions>
+
+ <Menu IsMainMenu="True" BorderThickness="0">
+ <MenuItem Header="File">
+ <MenuItem Header="New" Command="{Binding NewCommand}">
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="FileOutline" Width="12" Foreground="Gainsboro" Margin="2" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <Separator/>
+ <MenuItem Header="Open" MinWidth="150" Command="{Binding OpenCommand}">
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="FolderOutline" Width="12" Foreground="Gainsboro" Margin="2" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <Separator/>
+ <MenuItem Header="Save" Command="{Binding SaveCommand}">
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="Save" Width="12" Foreground="Gainsboro" Margin="2" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <MenuItem Header="Save as" Command="{Binding SaveAsCommand}">
+ <MenuItem.Icon>
+ <Grid>
+ <fa:ImageAwesome Icon="Save" Width="10" Foreground="Gainsboro" Margin="2" />
+ <fa:ImageAwesome Icon="Save" Width="10" Foreground="Gainsboro" Margin="2 -5 -5 2" />
+ </Grid>
+ </MenuItem.Icon>
+ </MenuItem>
+ </MenuItem>
+ <MenuItem Header="Edit">
+ <MenuItem Header="Cut" MinWidth="150" Command="Cut">
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="Cut" Width="12" Foreground="Gainsboro" Margin="2" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <Separator/>
+ <MenuItem Header="Copy" Command="Copy">
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="Copy" Width="12" Foreground="Gainsboro" Margin="2" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <MenuItem Header="Paste" Command="Paste">
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="Paste" Width="12" Foreground="Gainsboro" Margin="2" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <Separator/>
+ <MenuItem Header="Undo" Command="Undo">
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="Undo" Width="12" Foreground="Gainsboro" Margin="2" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <MenuItem Header="Redo" Command="Redo">
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="Repeat" Width="12" Foreground="Gainsboro" Margin="2" />
+ </MenuItem.Icon>
+ </MenuItem>
+ </MenuItem>
+ <MenuItem Header="Debug">
+ <MenuItem Header="Run (F5)" MinWidth="150" Command="{Binding RunCommand}" >
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="Play" Width="12" Margin="2">
+ <fa:ImageAwesome.Style>
+ <Style TargetType="fa:ImageAwesome">
+ <Setter Property="Foreground" Value="#8DD28A"></Setter>
+ <Style.Triggers>
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter Property="Foreground" Value="Gray"></Setter>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </fa:ImageAwesome.Style>
+ </fa:ImageAwesome>
+ </MenuItem.Icon>
+ </MenuItem>
+ <MenuItem Header="Stop" Command="{Binding StopCommand}" IsEnabled="False">
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="Stop" Width="12" Margin="2">
+ <fa:ImageAwesome.Style>
+ <Style TargetType="fa:ImageAwesome">
+ <Setter Property="Foreground" Value="#F38B76"></Setter>
+ <Style.Triggers>
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter Property="Foreground" Value="Gray"></Setter>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </fa:ImageAwesome.Style>
+ </fa:ImageAwesome>
+ </MenuItem.Icon>
+ </MenuItem>
+ </MenuItem>
+ </Menu>
+
+ <DockPanel Grid.Row="1">
+ <materialDesign:ColorZone Background="#2E2E2E" 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.RowDefinitions>
+ <RowDefinition Height="467*"/>
+ <RowDefinition Height="5"/>
+ <RowDefinition Height="200*"/>
+ </Grid.RowDefinitions>
+
+ <controls:ScriptEditorControl BorderThickness="0 1 0 0" BorderBrush="#616161" Text="{Binding Code,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" RunCommand="{Binding RunCommand}" StopCommand="{Binding StopCommand}" HighlightTypes="{Binding HighlightTypes}" IntellisenseTypes="{Binding IntellisenseTypes}"></controls:ScriptEditorControl>
+
+ <GridSplitter Grid.Row="1" Background="#101010" Foreground="#202020" BorderBrush="#202020" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
+
+
+ <Grid Grid.Row="2" Background="#1B1B1B">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="20"/>
+ <RowDefinition Height="57*"/>
+ </Grid.RowDefinitions>
+
+ <Border BorderThickness="0 0 0 1" BorderBrush="#595959">
+ <TextBlock Margin="2" HorizontalAlignment="Center">LOG</TextBlock>
+ </Border>
+
+ <TextBox x:Name="txtLog" TextChanged="TextBox_TextChanged" FontFamily="Lucida Console" Background="#202020" BorderThickness="0" AcceptsReturn="True" VerticalScrollBarVisibility="Visible" Padding="5" IsReadOnly="True" TextWrapping="Wrap" FontSize="11" Foreground="Gainsboro" Grid.Row="2"></TextBox>
+ </Grid>
+ </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>
+</mahapps:MetroWindow>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleWindow.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleWindow.xaml.cs
new file mode 100644
index 000000000..de2c728b0
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleWindow.xaml.cs
@@ -0,0 +1,43 @@
+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;
+
+namespace Tango.MachineStudio.UI.Console
+{
+ /// <summary>
+ /// Interaction logic for ConsoleWindow.xaml
+ /// </summary>
+ public partial class ConsoleWindow : MetroWindow
+ {
+ private ConsoleWindowVM _vm;
+
+ public ConsoleWindow()
+ {
+ InitializeComponent();
+
+ this.Loaded += (_, __) =>
+ {
+ _vm = this.DataContext as ConsoleWindowVM;
+ _vm.SetLogTextBox(txtLog);
+ };
+ }
+
+ //Auto scroll to bottom of response log each time it is changed.
+ private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ txtLog.SelectionStart = txtLog.Text.Length;
+ txtLog.ScrollToEnd();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleWindowVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleWindowVM.cs
new file mode 100644
index 000000000..a3a0a734e
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Console/ConsoleWindowVM.cs
@@ -0,0 +1,257 @@
+using Microsoft.Win32;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+using System.Windows.Threading;
+using Tango.Core.Commands;
+using Tango.Core.Helpers;
+using Tango.MachineStudio.Common.Modules;
+using Tango.MachineStudio.Common.Notifications;
+using Tango.Scripting;
+using Tango.SharedUI;
+
+namespace Tango.MachineStudio.UI.Console
+{
+ public class ConsoleWindowVM : ViewModel
+ {
+ private IStudioModuleLoader _moduleLoader;
+ private INotificationProvider _notificatrion;
+ private TextBox _txtLog;
+ private String _currentFile;
+
+
+ /// <summary>
+ /// Gets or sets the additional highlight C# types.
+ /// </summary>
+ public ObservableCollection<KeyValuePair<String, Type>> HighlightTypes { get; set; }
+
+ internal void SetLogTextBox(TextBox txtLog)
+ {
+ _txtLog = txtLog;
+ }
+
+ /// <summary>
+ /// Gets or sets the intellisense types.
+ /// </summary>
+ public ObservableCollection<KeyValuePair<String, Type>> IntellisenseTypes { get; set; }
+
+ private String _code;
+ /// <summary>
+ /// Gets or sets the code.
+ /// </summary>
+ public String Code
+ {
+ get { return _code; }
+ set { _code = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _isRunning;
+ /// <summary>
+ /// Gets or sets a value indicating whether a stub is currently running.
+ /// </summary>
+ public bool IsRunning
+ {
+ get { return _isRunning; }
+ set { _isRunning = value; RaisePropertyChanged(nameof(IsRunning)); InvalidateRelayCommands(); }
+ }
+
+ /// <summary>
+ /// Gets or sets the run command.
+ /// </summary>
+ public RelayCommand RunCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the stop command.
+ /// </summary>
+ public RelayCommand StopCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the clear command.
+ /// </summary>
+ public RelayCommand ClearCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the new command.
+ /// </summary>
+ public RelayCommand NewCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the open command.
+ /// </summary>
+ public RelayCommand OpenCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the save command.
+ /// </summary>
+ public RelayCommand SaveCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the save as command.
+ /// </summary>
+ public RelayCommand SaveAsCommand { get; set; }
+
+ public ConsoleWindowVM(IStudioModuleLoader moduleLoader, INotificationProvider notification)
+ {
+ _moduleLoader = moduleLoader;
+ _notificatrion = notification;
+
+ RunCommand = new RelayCommand(Run);
+ StopCommand = new RelayCommand(Stop);
+
+ HighlightTypes = new ObservableCollection<KeyValuePair<string, Type>>();
+ IntellisenseTypes = new ObservableCollection<KeyValuePair<string, Type>>();
+
+ IntellisenseTypes.Add(new KeyValuePair<string, Type>("manager", typeof(ConsoleManager)));
+
+ foreach (var moduleType in moduleLoader.UserModules.SelectMany(x => x.MainViewType.Assembly.GetTypes()))
+ {
+ if (!moduleType.FullName.Contains("<") && !moduleType.FullName.Contains(">"))
+ {
+ HighlightTypes.Add(new KeyValuePair<string, Type>(moduleType.FullName, moduleType));
+ }
+ }
+
+ foreach (var type in this.GetType().Assembly.GetTypes())
+ {
+ if (!type.FullName.Contains("<") && !type.FullName.Contains(">"))
+ {
+ HighlightTypes.Add(new KeyValuePair<string, Type>(type.Name, type));
+ }
+ }
+
+ foreach (var type in typeof(INotificationProvider).Assembly.GetTypes())
+ {
+ if (!type.FullName.Contains("<") && !type.FullName.Contains(">"))
+ {
+ HighlightTypes.Add(new KeyValuePair<string, Type>(type.Name, type));
+ }
+ }
+
+ HighlightTypes.Add(new KeyValuePair<string, Type>("Thread", typeof(Thread)));
+ HighlightTypes.Add(new KeyValuePair<string, Type>("DateTime", typeof(DateTime)));
+ HighlightTypes.Add(new KeyValuePair<string, Type>("TimeSpan", typeof(TimeSpan)));
+ HighlightTypes.Add(new KeyValuePair<string, Type>("Dispatcher", typeof(Dispatcher)));
+ HighlightTypes.Add(new KeyValuePair<string, Type>("Task", typeof(Task)));
+ HighlightTypes.Add(new KeyValuePair<string, Type>("List", typeof(IList<Object>)));
+ HighlightTypes.Add(new KeyValuePair<string, Type>("int", typeof(Int32)));
+ HighlightTypes.Add(new KeyValuePair<string, Type>("double", typeof(Double)));
+ HighlightTypes.Add(new KeyValuePair<string, Type>("String", typeof(String)));
+ HighlightTypes.Add(new KeyValuePair<string, Type>("string", typeof(String)));
+
+ foreach (var item in HighlightTypes)
+ {
+ IntellisenseTypes.Add(item);
+ }
+
+ Code = EmbeddedResourceHelper.GetEmbeddedResourceText("Tango.MachineStudio.UI.Console.CodeTemplate.cs");
+
+ NewCommand = new RelayCommand(CreateNew);
+ OpenCommand = new RelayCommand(OpenFile);
+ SaveCommand = new RelayCommand(SaveFile);
+ SaveAsCommand = new RelayCommand(SaveAsFile);
+ ClearCommand = new RelayCommand(ClearLog);
+ }
+
+ private void Stop()
+ {
+
+ }
+
+ private async void Run()
+ {
+ ScriptEngine engine = new ScriptEngine(new ConsoleOnExecuteParameters(new ConsoleManager(WriteLine)));
+ engine.Stop();
+ engine.ReferencedAssemblies.Add(this.GetType());
+ engine.ReferencedAssemblies.Add(typeof(INotificationProvider));
+
+ foreach (var module in _moduleLoader.AllModules)
+ {
+ engine.ReferencedAssemblies.Add(module.GetType());
+ }
+
+ await engine.Run(Code);
+ }
+
+ private void WriteLine(String text)
+ {
+ InvokeUI(() =>
+ {
+ _txtLog.AppendText(text);
+ });
+ }
+
+ /// <summary>
+ /// Clears the log.
+ /// </summary>
+ private void ClearLog()
+ {
+ _txtLog.Clear();
+ }
+
+ /// <summary>
+ /// Saves the selected script file.
+ /// </summary>
+ private void SaveFile()
+ {
+ if (_currentFile == null)
+ {
+ SaveAsFile();
+ }
+ else
+ {
+ File.WriteAllText(_currentFile, Code);
+ }
+ }
+
+ /// <summary>
+ /// Saves the selected script file.
+ /// </summary>
+ private void SaveAsFile()
+ {
+ SaveFileDialog dlg = new SaveFileDialog();
+ dlg.Filter = "C# Script Files|*.cs";
+ dlg.DefaultExt = ".cs";
+ if (dlg.ShowDialog().Value)
+ {
+ File.WriteAllText(dlg.FileName, Code);
+ _currentFile = dlg.FileName;
+ }
+ }
+
+ /// <summary>
+ /// Opens a script from HD.
+ /// </summary>
+ private void OpenFile()
+ {
+ OpenFileDialog dlg = new OpenFileDialog();
+ dlg.Filter = "C# Script Files|*.cs";
+ if (dlg.ShowDialog().Value)
+ {
+ OpenFile(dlg.FileName);
+ }
+ }
+
+ /// <summary>
+ /// Opens the file.
+ /// </summary>
+ /// <param name="file">The file.</param>
+ private void OpenFile(String file)
+ {
+ Code = File.ReadAllText(file);
+ _currentFile = file;
+ }
+
+ private void CreateNew()
+ {
+ _txtLog.Clear();
+ _currentFile = null;
+ Code = String.Empty;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/bug-resolved.png b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/bug-resolved.png
new file mode 100644
index 000000000..e49f62923
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/bug-resolved.png
Binary files differ
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 0bbcfd313..4c02be2b2 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs
@@ -42,6 +42,22 @@ namespace Tango.MachineStudio.UI.StudioApplication
_moduleLoader = moduleLoader;
_navigationManager = navigationManager;
_openedWindows = new List<Window>();
+
+ Task.Factory.StartNew(() =>
+ {
+ while (MainWindow.Instance == null)
+ {
+ Thread.Sleep(100);
+ }
+
+ InvokeUI(() =>
+ {
+ MainWindow.Instance.ContentRendered += (_, __) =>
+ {
+ TangoIOC.Default.GetAllInstancesByBase<IStudioViewModel>().ToList().ForEach(x => x.OnApplicationStarted());
+ };
+ });
+ });
}
/// <summary>
@@ -229,6 +245,11 @@ namespace Tango.MachineStudio.UI.StudioApplication
}
}
+ /// <summary>
+ /// Notify the application manager about an external opened window.
+ /// When application exists. All registered windows will be closed.
+ /// </summary>
+ /// <param name="window">The window.</param>
public void RegisterOpenedWindow(Window window)
{
_openedWindows.Add(window);
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationModel.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationModel.cs
index eb9ef8012..5dde73744 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationModel.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationModel.cs
@@ -15,5 +15,7 @@ namespace Tango.MachineStudio.UI.TFS
public String HostName { get; set; }
public Machine Machine { get; set; }
public String ConfigurationString { get; set; }
+ public String LoadedHardwareConfigurationString { get; set; }
+ public String LoadedProcessParametersString { get; set; }
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationTemplate.cshtml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationTemplate.cshtml
index 7b0c4a896..54db28e32 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationTemplate.cshtml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/SystemInformationTemplate.cshtml
@@ -60,11 +60,32 @@
</tbody>
</table>
- <div style="font-size:20pt;text-decoration:underline;margin-top:10px">Configuration</div>
+ <div style="font-size:20pt;text-decoration:underline;margin-top:10px">Machine Configuration</div>
<div style="white-space:pre;margin-top:10px;font-size:8pt">@vm.ConfigurationString</div>
+
+ <div style="font-size:20pt;text-decoration:underline;margin-top:10px">Hardware Configuration</div>
+ if (vm.LoadedHardwareConfigurationString != null)
+ {
+ <div style="white-space:pre;margin-top:10px;font-size:8pt">@vm.LoadedHardwareConfigurationString</div>
+ }
+ else
+ {
+ <div style="color:Red;margin-top:10px">NOT SET</div>
+ }
+
+ <div style="font-size:20pt;text-decoration:underline;margin-top:10px">Process Parameters</div>
+
+ if (vm.LoadedProcessParametersString != null)
+ {
+ <div style="white-space:pre;margin-top:10px;font-size:8pt">@vm.LoadedProcessParametersString</div>
+ }
+ else
+ {
+ <div style="color:Red;margin-top:10px">NOT SET</div>
+ }
}
else
{
- <div style="color:Red;margin-top:10px">Not Connected</div>
+ <div style="color:Red;margin-top:10px">NOT CONNECTED</div>
}
</div> \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs
index 27b257e61..79572eb71 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs
@@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
+using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using Tango.BL.Entities;
@@ -21,6 +23,13 @@ namespace Tango.MachineStudio.UI.TFS
{
public Project Project { get; private set; }
+ private ObservableCollection<WorkItem> _resolvedWorkItems;
+ public ObservableCollection<WorkItem> ResolvedWorkItems
+ {
+ get { return _resolvedWorkItems; }
+ set { _resolvedWorkItems = value; RaisePropertyChangedAuto(); }
+ }
+
private bool _isInitialized;
public bool IsInitialized
{
@@ -30,7 +39,20 @@ namespace Tango.MachineStudio.UI.TFS
public TeamFoundationServiceExtendedClient(string collectionURL, string userName, string personalToken) : base(collectionURL, userName, personalToken)
{
+ ResolvedWorkItems = new ObservableCollection<WorkItem>();
+ TangoIOC.Default.GetInstance<IAuthenticationProvider>().CurrentUserChanged += TeamFoundationServiceExtendedClient_CurrentUserChanged;
+ }
+ private void TeamFoundationServiceExtendedClient_CurrentUserChanged(object sender, User user)
+ {
+ if (user != null)
+ {
+ Task.Factory.StartNew(async () =>
+ {
+ Thread.Sleep(5000);
+ await UpdateCurrentUserResolvedWorkItems();
+ });
+ }
}
public Task<WorkItem> UploadWorkItem(WorkItem workItem)
@@ -38,14 +60,53 @@ namespace Tango.MachineStudio.UI.TFS
return UploadWorkItem(Project, workItem);
}
+ public async Task UpdateCurrentUserResolvedWorkItems()
+ {
+ try
+ {
+ IStudioApplicationManager app = TangoIOC.Default.GetInstance<IStudioApplicationManager>();
+ var items = await GetWorkItemsCreatedBy(Project, GetUserTeamMember());
+ items.Where(x => x.StepsToReproduce != null).ToList().ForEach(x => x.StepsToReproduce = x.StepsToReproduce.Replace("<div style=\"white-space:pre;\">", "").Replace("</div>", ""));
+ ResolvedWorkItems = items.Where(x => x.State == State.Resolved && x.ResolvedReason == ResolvedReason.Fixed && x.IsBuildVersionValid && x.FoundInBuildVersion < Version.Parse(app.Version)).ToObservableCollection();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error getting the current user resolved work items.");
+ }
+ }
+
+ public async Task<WorkItem> CloseWorkItem(WorkItem workItem)
+ {
+ await SetWorkItemState(Project, workItem, State.Closed);
+ var updated = await AddWorkItemComment(Project, workItem, GetUserTeamMember(), "Bug has been verified and closed by " + GetUserTeamMember().DisplayName + " (via Tango Software).");
+ ResolvedWorkItems.Remove(workItem);
+ return updated;
+ }
+
+ public async Task<WorkItem> ReactivateWorkItem(WorkItem workItem)
+ {
+ await SetWorkItemState(Project, workItem, State.New);
+ var updated = await AddWorkItemComment(Project, workItem, GetUserTeamMember(), "Bug has been reactivated by " + GetUserTeamMember().DisplayName + " (via Tango Software).");
+ updated = await SetWorkItemAssignment(Project, updated, workItem.ResolvedBy);
+ ResolvedWorkItems.Remove(workItem);
+ return updated;
+ }
+
public void Initialize()
{
Task.Factory.StartNew(() =>
{
if (!IsInitialized)
{
- Project = GetProject("Tango").Result;
- IsInitialized = true;
+ try
+ {
+ Project = GetProject("Tango").Result;
+ IsInitialized = true;
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error initializing the Team Foundation Service client.");
+ }
}
});
}
@@ -60,7 +121,7 @@ namespace Tango.MachineStudio.UI.TFS
item.Area = Project.Areas.FirstOrDefault();
item.Iteration = Project.Iterations.FirstOrDefault();
- TeamMember currentUser = Project.Members.SingleOrDefault(x => x.UniqueName.ToLower().Contains(auth.CurrentUser.Email.ToLower()));
+ TeamMember currentUser = GetUserTeamMember();
item.CreatedBy = currentUser;
item.ChangedBy = currentUser;
item.AuthorizedAs = currentUser;
@@ -82,6 +143,14 @@ namespace Tango.MachineStudio.UI.TFS
Name = "Screen Capture.jpg",
});
+ return item;
+ }
+
+ public void FinalizeBug(WorkItem item)
+ {
+ IAuthenticationProvider auth = TangoIOC.Default.GetInstance<IAuthenticationProvider>();
+ IStudioApplicationManager app = TangoIOC.Default.GetInstance<IStudioApplicationManager>();
+
FileLogger appFileLogger = LogManager.Default.RegisteredLoggers.FirstOrDefault(x => x.GetType() == typeof(FileLogger)) as FileLogger;
FileLogger embeddedFileLogger = MachineOperator.EmbeddedLogManager.RegisteredLoggers.FirstOrDefault(x => x.GetType() == typeof(FileLogger)) as FileLogger;
@@ -113,7 +182,7 @@ namespace Tango.MachineStudio.UI.TFS
SystemInformationModel sysModel = new SystemInformationModel();
sysModel.ApplicationVersion = app.Version;
- sysModel.EmbeddedVersion = "Fake Version";
+ sysModel.EmbeddedVersion = "N/A";
sysModel.HostName = Environment.MachineName;
sysModel.UserName = auth.CurrentUser.Contact.FullName;
@@ -122,17 +191,18 @@ namespace Tango.MachineStudio.UI.TFS
Machine machine = app.ConnectedMachine.Machine;
sysModel.Machine = machine;
+ sysModel.EmbeddedVersion = app.ConnectedMachine.DeviceInformation.Version;
MachineDesigner.Views.MainView machineView = new MachineDesigner.Views.MainView();
machineView.Width = 1280;
machineView.Height = 1100;
- machineView.PanelColumnDefinition.Width = new System.Windows.GridLength(0);
+ machineView.PanelColumnDefinition.Width = new GridLength(0);
machineView.stackHeader.Visibility = Visibility.Collapsed;
machineView.Background = System.Windows.Media.Brushes.White;
machineView.DataContext = new MachineDesigner.ViewModels.MainViewVM() { SelectedMachine = machine, Configuration = machine.Configuration };
String configImageFile = PathHelper.GetTempFilePath();
- machineView.RenderToFile(configImageFile, System.Drawing.Imaging.ImageFormat.Jpeg, new System.Windows.Size(machineView.Width, machineView.Height), 100);
+ machineView.RenderToFile(configImageFile, System.Drawing.Imaging.ImageFormat.Jpeg, new Size(machineView.Width, machineView.Height), 100);
item.Attachments.Add(new Attachment()
{
@@ -141,7 +211,17 @@ namespace Tango.MachineStudio.UI.TFS
Name = "Machine Configuration.jpg"
});
- sysModel.ConfigurationString = machine.Configuration.CloneConfiguration().ToJsonString();
+ sysModel.ConfigurationString = machine.Configuration.CloneConfiguration().ToJsonString(nameof(Configuration.MachinesConfigurations), nameof(Configuration.MachineVersions));
+
+ if (app.ConnectedMachine.CurrentProcessParameters != null)
+ {
+ sysModel.LoadedProcessParametersString = app.ConnectedMachine.CurrentProcessParameters.ToJsonString(nameof(ProcessParametersTable.ProcessParametersTablesGroup));
+ }
+
+ if (app.ConnectedMachine.CurrentHardwareConfiguration != null)
+ {
+ sysModel.LoadedHardwareConfigurationString = app.ConnectedMachine.CurrentHardwareConfiguration.ToJsonString();
+ }
}
String html = String.Empty;
@@ -154,7 +234,14 @@ namespace Tango.MachineStudio.UI.TFS
item.SystemInformation = CodeGeneration.Helper.Parse(html, sysModel);
- return item;
+ item.StepsToReproduce = String.Format("<div style=\"white-space:pre\">{0}</div>", item.StepsToReproduce);
+ }
+
+ private TeamMember GetUserTeamMember()
+ {
+ IAuthenticationProvider auth = TangoIOC.Default.GetInstance<IAuthenticationProvider>();
+ TeamMember currentUser = Project.Members.SingleOrDefault(x => x.UniqueName.ToLower().Contains(auth.CurrentUser.Email.ToLower()));
+ return currentUser;
}
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/WorkItemValidationAttribute.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/WorkItemValidationAttribute.cs
index 1418d0576..3e85f91b4 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/WorkItemValidationAttribute.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/WorkItemValidationAttribute.cs
@@ -16,13 +16,19 @@ namespace Tango.MachineStudio.UI.TFS
if (String.IsNullOrWhiteSpace(item.Title))
{
- ErrorMessage = "Title is empty";
+ ErrorMessage = "Title is required.";
return false;
}
if (item.AssignedTo == null)
{
- ErrorMessage = "Assigned To is empty";
+ ErrorMessage = "Assigned To field is required.";
+ return false;
+ }
+
+ if (String.IsNullOrWhiteSpace(item.StepsToReproduce))
+ {
+ ErrorMessage = "Please enter steps to reproduce.";
return false;
}
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 8ab6bb188..5d685c112 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
@@ -131,6 +131,13 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
+ <EmbeddedResource Include="Console\CodeTemplate.cs" />
+ <Compile Include="Console\ConsoleManager.cs" />
+ <Compile Include="Console\ConsoleOnExecuteParameters.cs" />
+ <Compile Include="Console\ConsoleWindow.xaml.cs">
+ <DependentUpon>ConsoleWindow.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Console\ConsoleWindowVM.cs" />
<Compile Include="Html\DefaultHtmlPresenter.cs" />
<Compile Include="Html\HtmlWindow.xaml.cs">
<DependentUpon>HtmlWindow.xaml</DependentUpon>
@@ -161,6 +168,7 @@
<Compile Include="ViewModelLocator.cs" />
<Compile Include="ViewModels\ModuleWindowVM.cs" />
<Compile Include="ViewModels\ReportIssueViewVM.cs" />
+ <Compile Include="ViewModels\ResolvedIssuesViewVM.cs" />
<Compile Include="ViewModels\ShutdownViewVM.cs" />
<Compile Include="ViewModels\UpdateViewVM.cs" />
<Compile Include="Views\ConnectedMachineView.xaml.cs">
@@ -190,6 +198,9 @@
<Compile Include="Views\ReportIssueView.xaml.cs">
<DependentUpon>ReportIssueView.xaml</DependentUpon>
</Compile>
+ <Compile Include="Views\ResolvedIssuesView.xaml.cs">
+ <DependentUpon>ResolvedIssuesView.xaml</DependentUpon>
+ </Compile>
<Compile Include="Views\ShutdownView.xaml.cs">
<DependentUpon>ShutdownView.xaml</DependentUpon>
</Compile>
@@ -203,6 +214,10 @@
<Compile Include="Windows\ModuleWindow.xaml.cs">
<DependentUpon>ModuleWindow.xaml</DependentUpon>
</Compile>
+ <Page Include="Console\ConsoleWindow.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Html\HtmlWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@@ -270,6 +285,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
+ <Page Include="Views\ResolvedIssuesView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Views\ShutdownView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -355,6 +374,10 @@
<Project>{e4927038-348d-4295-aaf4-861c58cb3943}</Project>
<Name>Tango.PMR</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Tango.Scripting\Tango.Scripting.csproj">
+ <Project>{401989E7-AE1E-4002-B0EE-9A9F63740B97}</Project>
+ <Name>Tango.Scripting</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Tango.Settings\Tango.Settings.csproj">
<Project>{d8f1ad85-526a-4f50-b6dc-d437af63d8d8}</Project>
<Name>Tango.Settings</Name>
@@ -460,6 +483,7 @@
</ItemGroup>
<ItemGroup>
<Content Include="Html\HTML Templates\Thread Break.html" />
+ <Resource Include="Images\bug-resolved.png" />
<EmbeddedResource Include="TFS\SystemInformationTemplate.cshtml" />
<Resource Include="Images\bug.png" />
</ItemGroup>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs
index 8e6f11452..931130a05 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs
@@ -13,6 +13,7 @@ using Tango.MachineStudio.Common.Speech;
using Tango.MachineStudio.Common.StudioApplication;
using Tango.MachineStudio.Common.Video;
using Tango.MachineStudio.UI.Authentication;
+using Tango.MachineStudio.UI.Console;
using Tango.MachineStudio.UI.Html;
using Tango.MachineStudio.UI.Modules;
using Tango.MachineStudio.UI.Navigation;
@@ -64,7 +65,6 @@ namespace Tango.MachineStudio.UI
TangoIOC.Default.Unregister<IHtmlPresenter>();
TangoIOC.Default.Unregister<ITeamFoundationServiceClient>();
- TangoIOC.Default.Register<TeamFoundationServiceExtendedClient>(new TeamFoundationServiceExtendedClient("https://twinetfs.visualstudio.com/DefaultCollection", "Roy", "szzfokrceo4rhd4eqi5qpmxn3pa5iwl3q7tlqd36l2m7smz2ynoa"));
TangoIOC.Default.Register<INotificationProvider, DefaultNotificationProvider>();
TangoIOC.Default.Register<IAuthenticationProvider, DefaultAuthenticationProvider>();
TangoIOC.Default.Register<INavigationManager, DefaultNavigationManager>();
@@ -76,6 +76,7 @@ namespace Tango.MachineStudio.UI
TangoIOC.Default.Register<IEventLogger, DefaultEventLogger>();
TangoIOC.Default.Register<ISpeechProvider, DefaultSpeechProvider>();
TangoIOC.Default.Register<IHtmlPresenter, DefaultHtmlPresenter>();
+ TangoIOC.Default.Register<TeamFoundationServiceExtendedClient>(new TeamFoundationServiceExtendedClient("https://twinetfs.visualstudio.com", String.Empty, "szzfokrceo4rhd4eqi5qpmxn3pa5iwl3q7tlqd36l2m7smz2ynoa"));
TangoIOC.Default.Register<MainViewVM>();
TangoIOC.Default.Register<LoadingViewVM>();
@@ -85,6 +86,7 @@ namespace Tango.MachineStudio.UI
TangoIOC.Default.Register<ConnectedMachineViewVM>();
TangoIOC.Default.Register<MachineLoginViewVM>();
TangoIOC.Default.Register<UpdateViewVM>();
+ TangoIOC.Default.Register<ConsoleWindowVM>();
//Register View (Supervising Controller Pattern).
//if (!ViewModelBase.IsInDesignModeStatic)
@@ -157,5 +159,13 @@ namespace Tango.MachineStudio.UI
return TangoIOC.Default.GetInstance<UpdateViewVM>();
}
}
+
+ public ConsoleWindowVM ConsoleWindowVM
+ {
+ get
+ {
+ return TangoIOC.Default.GetInstance<ConsoleWindowVM>();
+ }
+ }
}
} \ 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 2b2b442f7..29f9102ac 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs
@@ -16,6 +16,7 @@ using Tango.BL;
using Tango.MachineStudio.Common.EventLogging;
using Tango.BL.Enumerations;
using Tango.MachineStudio.UI.TFS;
+using Tango.MachineStudio.Common;
namespace Tango.MachineStudio.UI.ViewModels
{
@@ -23,7 +24,7 @@ namespace Tango.MachineStudio.UI.ViewModels
/// Represents the Machine Studio loading view, view model.
/// </summary>
/// <seealso cref="Tango.SharedUI.ViewModel" />
- public class LoadingViewVM : ViewModel
+ public class LoadingViewVM : StudioViewModelInternal
{
private INotificationProvider _notificationProvider;
private TeamFoundationServiceExtendedClient _tfs;
@@ -55,6 +56,11 @@ namespace Tango.MachineStudio.UI.ViewModels
_navigationManager = navigationManager;
_studioModuleLoader = studioModuleLoader;
_notificationProvider = notificationProvider;
+ }
+
+ public override void OnApplicationStarted()
+ {
+ base.OnApplicationStarted();
Load();
}
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 0882267e8..04b973f23 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs
@@ -148,6 +148,16 @@ namespace Tango.MachineStudio.UI.ViewModels
/// </summary>
public RelayCommand ReportIssueCommand { get; set; }
+ /// <summary>
+ /// Gets or sets the open resolved bugs.
+ /// </summary>
+ public RelayCommand OpenResolvedBugsCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the open developer console command.
+ /// </summary>
+ public RelayCommand OpenDeveloperConsoleCommand { get; set; }
+
private IAuthenticationProvider _authenticationProvider;
/// <summary>
/// Gets or sets the authentication provider.
@@ -302,6 +312,8 @@ namespace Tango.MachineStudio.UI.ViewModels
ResolveMachineEventCommand = new RelayCommand<MachinesEvent>(ResolveMachineEvent);
ReportIssueCommand = new RelayCommand(ReportIssue);
+ OpenResolvedBugsCommand = new RelayCommand(OpenResolvedBugs);
+ OpenDeveloperConsoleCommand = new RelayCommand(OpenDeveloperConsole);
}
private void MachineEventsStateProvider_EventsResolved(object sender, IEnumerable<MachinesEvent> e)
@@ -321,7 +333,7 @@ namespace Tango.MachineStudio.UI.ViewModels
{
while (!DisableCheckForUpdates)
{
- Thread.Sleep(TimeSpan.FromMinutes(1));
+ Thread.Sleep(TimeSpan.FromMinutes(0.2));
try
{
@@ -649,10 +661,78 @@ namespace Tango.MachineStudio.UI.ViewModels
{
using (_notificationProvider.PushTaskItem("Uploading bug report..."))
{
- await TFSClient.UploadWorkItem(vm.WorkItem);
+ try
+ {
+ TFSClient.FinalizeBug(vm.WorkItem);
+ await TFSClient.UploadWorkItem(vm.WorkItem);
+ }
+ catch (Exception ex)
+ {
+ _notificationProvider.ShowError("An error occurred while trying to create the issue." + Environment.NewLine + ex.Message);
+ }
}
}, null);
}
+
+ private void OpenResolvedBugs()
+ {
+ ResolvedIssuesViewVM vm = null;
+
+ vm = new ResolvedIssuesViewVM(TFSClient, async (item) =>
+ {
+ //Approve
+ using (_notificationProvider.PushTaskItem("Approving issue..."))
+ {
+ vm.IsAvailable = false;
+ try
+ {
+ await TFSClient.CloseWorkItem(item);
+ }
+ catch (Exception ex)
+ {
+ _notificationProvider.ShowError("An error occurred while trying to update the issue." + Environment.NewLine + ex.Message);
+ }
+ vm.IsAvailable = true;
+
+ if (TFSClient.ResolvedWorkItems.Count == 0)
+ {
+ vm.Close();
+ }
+ }
+ }, async (item) =>
+ {
+ //Decline
+ using (_notificationProvider.PushTaskItem("Reactivating issue..."))
+ {
+ vm.IsAvailable = false;
+ try
+ {
+ await TFSClient.ReactivateWorkItem(item);
+ }
+ catch (Exception ex)
+ {
+ _notificationProvider.ShowError("An error occurred while trying to update the issue." + Environment.NewLine + ex.Message);
+ }
+
+ vm.IsAvailable = true;
+
+ if (TFSClient.ResolvedWorkItems.Count == 0)
+ {
+ vm.Close();
+ }
+ }
+ });
+
+ _notificationProvider.ShowModalDialog<ResolvedIssuesViewVM, ResolvedIssuesView>(vm, (_) => { }, null);
+ }
+
+ private void OpenDeveloperConsole()
+ {
+ Console.ConsoleWindow console = new Console.ConsoleWindow();
+ ApplicationManager.RegisterOpenedWindow(console);
+ console.Owner = MainWindow.Instance;
+ console.Show();
+ }
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ResolvedIssuesViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ResolvedIssuesViewVM.cs
new file mode 100644
index 000000000..552880792
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ResolvedIssuesViewVM.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core.Commands;
+using Tango.MachineStudio.Common.Notifications;
+using Tango.MachineStudio.UI.TFS;
+using Tango.TFS;
+
+namespace Tango.MachineStudio.UI.ViewModels
+{
+ public class ResolvedIssuesViewVM : DialogViewVM
+ {
+ private Action<WorkItem> _onApprove;
+ private Action<WorkItem> _onDecline;
+
+ public TeamFoundationServiceExtendedClient TFSClient { get; set; }
+
+ public RelayCommand<WorkItem> ApproveCommand { get; set; }
+
+ public RelayCommand<WorkItem> DeclineCommand { get; set; }
+
+ private bool _isAvailable;
+
+ public bool IsAvailable
+ {
+ get { return _isAvailable; }
+ set { _isAvailable = value; RaisePropertyChangedAuto(); }
+ }
+
+ public ResolvedIssuesViewVM() : base()
+ {
+ IsAvailable = true;
+ ApproveCommand = new RelayCommand<WorkItem>(ApproveIssue);
+ DeclineCommand = new RelayCommand<WorkItem>(DeclineIssue);
+ }
+
+ public ResolvedIssuesViewVM(TeamFoundationServiceExtendedClient tfsClient, Action<WorkItem> onApprove, Action<WorkItem> onDecline) : this()
+ {
+ TFSClient = tfsClient;
+ _onApprove = onApprove;
+ _onDecline = onDecline;
+ }
+
+ private void DeclineIssue(WorkItem workItem)
+ {
+ _onDecline(workItem);
+ }
+
+ private void ApproveIssue(WorkItem workItem)
+ {
+ _onApprove(workItem);
+ }
+
+ public void Close()
+ {
+ Accept();
+ }
+ }
+}
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 86723479b..8417c70c8 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml
@@ -10,9 +10,11 @@
xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:entities="clr-namespace:Tango.BL.Entities;assembly=Tango.BL"
+ xmlns:enumerations="clr-namespace:Tango.BL.Enumerations;assembly=Tango.BL"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:db="clr-namespace:Tango.MachineStudio.DB.Views;assembly=Tango.MachineStudio.DB"
xmlns:local="clr-namespace:Tango.MachineStudio.UI.Views"
+ xmlns:commonConverters="clr-namespace:Tango.MachineStudio.Common.Converters;assembly=Tango.MachineStudio.Common"
mc:Ignorable="d"
d:DesignHeight="720" d:DesignWidth="1270" Background="Transparent" DataContext="{Binding MainViewVM, Source={StaticResource Locator}}">
@@ -22,6 +24,7 @@
<converters:NullObjectToBooleanConverter x:Key="NullObjectToBooleanConverter" />
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<converters:StringToWordsConverter x:Key="StringToWordsConverter" />
+ <commonConverters:PermissionToVisibilityConverter x:Key="PermissionToVisibilityConverter" />
</UserControl.Resources>
<Grid>
@@ -189,7 +192,16 @@
<TextBlock Margin="5 0 0 0" VerticalAlignment="Center">Speech</TextBlock>
</StackPanel>
</Button>
- <Separator/>
+ <StackPanel Visibility="{Binding AuthenticationProvider.CurrentUser,Converter={StaticResource PermissionToVisibilityConverter},ConverterParameter={x:Static enumerations:Permissions.RunDeveloperConsole}}">
+ <Separator/>
+ <Button Command="{Binding OpenDeveloperConsoleCommand}">
+ <StackPanel Orientation="Horizontal">
+ <materialDesign:PackIcon Kind="Console" Width="24" Height="24" />
+ <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">Developer Console</TextBlock>
+ </StackPanel>
+ </Button>
+ <Separator/>
+ </StackPanel>
<Button Command="{Binding ExitCommand}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="CloseCircleOutline" Width="24" Height="24" />
@@ -320,7 +332,7 @@
<Button Cursor="Hand" Command="{Binding ReportIssueCommand}" IsEnabled="{Binding TFSClient.IsInitialized}">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource emptyButton}">
- <Setter Property="ToolTip" Value="Report and issue"></Setter>
+ <Setter Property="ToolTip" Value="Report issue"></Setter>
<Setter Property="Opacity" Value="1"></Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
@@ -332,6 +344,38 @@
</Button.Style>
<Image Margin="10 0 0 0" Source="/Images/bug.png" Width="24" RenderOptions.BitmapScalingMode="Fant" />
</Button>
+ <Button Cursor="Hand" Command="{Binding OpenResolvedBugsCommand}">
+ <Button.Style>
+ <Style TargetType="Button" BasedOn="{StaticResource emptyButton}">
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ <Style.Triggers>
+ <EventTrigger RoutedEvent="Loaded">
+ <EventTrigger.Actions>
+ <BeginStoryboard>
+ <Storyboard>
+ <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Duration="00:00:01" RepeatBehavior="Forever">
+ <DiscreteDoubleKeyFrame KeyTime="00:00:00" Value="1" />
+ <DiscreteDoubleKeyFrame KeyTime="00:00:0.5" Value="0" />
+ </DoubleAnimationUsingKeyFrames>
+ </Storyboard>
+ </BeginStoryboard>
+ </EventTrigger.Actions>
+ </EventTrigger>
+ <DataTrigger Binding="{Binding TFSClient.ResolvedWorkItems.Count}" Value="0">
+ <Setter Property="Visibility" Value="Collapsed"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ <Button.ToolTip>
+ <TextBlock>
+ <Run>There are</Run>
+ <Run Text="{Binding TFSClient.ResolvedWorkItems.Count,Mode=OneWay}"></Run>
+ <Run>issues waiting for your approval</Run>
+ </TextBlock>
+ </Button.ToolTip>
+ <Image Margin="10 0 0 0" Source="/Images/bug-resolved.png" Width="24" RenderOptions.BitmapScalingMode="Fant" />
+ </Button>
</StackPanel>
</Grid>
</Grid>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml
index f2e3038b9..37cd0b793 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml
@@ -12,7 +12,7 @@
xmlns:tfs="clr-namespace:Tango.TFS;assembly=Tango.TFS"
xmlns:tfss="clr-namespace:Tango.MachineStudio.UI.TFS"
xmlns:local="clr-namespace:Tango.MachineStudio.UI.Views"
- mc:Ignorable="d" Width="530" Height="650" Background="White" d:DataContext="{d:DesignInstance Type=vm:ReportIssueViewVM, IsDesignTimeCreatable=False}">
+ mc:Ignorable="d" Width="530" Height="680" Background="White" d:DataContext="{d:DesignInstance Type=vm:ReportIssueViewVM, IsDesignTimeCreatable=False}">
<UserControl.Resources>
<converters:EnumToItemsSourceConverter x:Key="EnumToItemsSourceConverter" />
@@ -36,53 +36,85 @@
</Grid>
<Grid Grid.Row="1">
- <StackPanel>
- <TextBox materialDesign:HintAssist.Hint="Title" materialDesign:HintAssist.IsFloating="True" FontSize="16" Text="{Binding WorkItem.Title}"></TextBox>
+ <DockPanel>
+ <StackPanel DockPanel.Dock="Top">
+ <DockPanel>
+ <materialDesign:PackIcon Kind="Pencil" Width="24" Height="24" VerticalAlignment="Center" Margin="0 0 10 0" />
+ <TextBox materialDesign:HintAssist.Hint="Title" materialDesign:HintAssist.IsFloating="True" FontSize="16" Text="{Binding WorkItem.Title}"></TextBox>
+ </DockPanel>
- <autoComplete:AutoCompleteTextBox Provider="{StaticResource TeamMembersProvider}" SelectedItem="{Binding WorkItem.AssignedTo,Mode=TwoWay}" DisplayMember="DisplayName" Margin="0 10 0 0" materialDesign:HintAssist.Hint="Assigned To" materialDesign:HintAssist.IsFloating="True"></autoComplete:AutoCompleteTextBox>
- <ComboBox Margin="0 10 0 0" materialDesign:HintAssist.Hint="Area" materialDesign:HintAssist.IsFloating="True" ItemsSource="{Binding Project.Areas}" SelectedItem="{Binding WorkItem.Area}" DisplayMemberPath="Name"></ComboBox>
- <ComboBox Margin="0 10 0 0" materialDesign:HintAssist.Hint="Severity" materialDesign:HintAssist.IsFloating="True" ItemsSource="{Binding Source={x:Type tfs:Severity},Converter={StaticResource EnumToItemsSourceConverter}}" SelectedValue="{Binding WorkItem.Severity}" SelectedValuePath="Value" DisplayMemberPath="DisplayName"></ComboBox>
+ <DockPanel Margin="0 10 0 0">
+ <materialDesign:PackIcon Kind="Account" Width="24" Height="24" VerticalAlignment="Center" Margin="0 0 10 0" />
+ <autoComplete:AutoCompleteTextBox Provider="{StaticResource TeamMembersProvider}" SelectedItem="{Binding WorkItem.AssignedTo,Mode=TwoWay}" DisplayMember="DisplayName" materialDesign:HintAssist.Hint="Assigned To" materialDesign:HintAssist.IsFloating="True"></autoComplete:AutoCompleteTextBox>
+ </DockPanel>
- <TextBlock Margin="0 10 0 0">Tags</TextBlock>
- <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Height="120">
- <ItemsControl ItemsSource="{Binding SelectedTags}">
- <ItemsControl.ItemsPanel>
- <ItemsPanelTemplate>
- <WrapPanel IsItemsHost="True" Orientation="Horizontal" />
- </ItemsPanelTemplate>
- </ItemsControl.ItemsPanel>
- <ItemsControl.ItemTemplate>
- <DataTemplate>
- <ToggleButton Style="{StaticResource emptyToggleButton}" IsChecked="{Binding IsSelected}" Cursor="Hand">
- <Border CornerRadius="5" Margin="0 5 5 5" Padding="5" BorderThickness="1" BorderBrush="DimGray">
- <Border.Style>
- <Style TargetType="Border">
- <Setter Property="Background" Value="Silver"></Setter>
- <Style.Triggers>
- <DataTrigger Binding="{Binding IsSelected}" Value="True">
- <Setter Property="Background" Value="{StaticResource AccentColorBrush}"></Setter>
- <Setter Property="TextElement.Foreground" Value="White"></Setter>
- </DataTrigger>
- </Style.Triggers>
- </Style>
- </Border.Style>
- <TextBlock Text="{Binding Data.Name}" FontSize="11"></TextBlock>
- </Border>
- </ToggleButton>
- </DataTemplate>
- </ItemsControl.ItemTemplate>
- </ItemsControl>
- </ScrollViewer>
- </StackPanel>
+ <DockPanel Margin="0 10 0 0">
+ <materialDesign:PackIcon Kind="Star" Width="24" Height="24" VerticalAlignment="Center" Margin="0 0 10 0" />
+ <ComboBox materialDesign:HintAssist.Hint="Area" materialDesign:HintAssist.IsFloating="True" ItemsSource="{Binding Project.Areas}" SelectedItem="{Binding WorkItem.Area}" DisplayMemberPath="Name"></ComboBox>
+ </DockPanel>
+
+ <DockPanel Margin="0 10 0 0">
+ <materialDesign:PackIcon Kind="CommentAlertOutline" Width="24" Height="24" VerticalAlignment="Center" Margin="0 0 10 0" />
+ <ComboBox materialDesign:HintAssist.Hint="Severity" materialDesign:HintAssist.IsFloating="True" ItemsSource="{Binding Source={x:Type tfs:Severity},Converter={StaticResource EnumToItemsSourceConverter}}" SelectedValue="{Binding WorkItem.Severity}" SelectedValuePath="Value" DisplayMemberPath="DisplayName"></ComboBox>
+ </DockPanel>
+
+ <DockPanel Margin="0 20 0 0">
+ <materialDesign:PackIcon Kind="Tag" Width="24" Height="24" VerticalAlignment="Center" Margin="0 0 10 0" />
+ <TextBlock VerticalAlignment="Center"><Run>Tags</Run> <Run FontSize="10" Foreground="Gray">(highlight selected tags)</Run></TextBlock>
+ </DockPanel>
+ <ScrollViewer Margin="30 0 0 0" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Height="120">
+ <ItemsControl ItemsSource="{Binding SelectedTags}">
+ <ItemsControl.ItemsPanel>
+ <ItemsPanelTemplate>
+ <WrapPanel IsItemsHost="True" Orientation="Horizontal" />
+ </ItemsPanelTemplate>
+ </ItemsControl.ItemsPanel>
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <ToggleButton Style="{StaticResource emptyToggleButton}" IsChecked="{Binding IsSelected}" Cursor="Hand">
+ <Border CornerRadius="5" Margin="0 5 5 5" Padding="5" BorderThickness="1" BorderBrush="DimGray">
+ <Border.Style>
+ <Style TargetType="Border">
+ <Setter Property="Background" Value="Silver"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding IsSelected}" Value="True">
+ <Setter Property="Background" Value="{StaticResource AccentColorBrush}"></Setter>
+ <Setter Property="TextElement.Foreground" Value="White"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Border.Style>
+ <TextBlock Text="{Binding Data.Name}" FontSize="11"></TextBlock>
+ </Border>
+ </ToggleButton>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+ </ScrollViewer>
+ </StackPanel>
+
+ <Grid>
+ <DockPanel>
+ <DockPanel Margin="0 10 0 0" DockPanel.Dock="Top">
+ <materialDesign:PackIcon Kind="ChartTimeline" Width="24" Height="24" VerticalAlignment="Center" Margin="0 0 10 0" />
+ <TextBlock VerticalAlignment="Center">Steps To Reproduce</TextBlock>
+ </DockPanel>
+
+ <Grid Margin="30 0 0 0">
+ <TextBox Margin="0 5 0 0" Style="{x:Null}" BorderBrush="Silver" AcceptsReturn="True" TextWrapping="Wrap" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Text="{Binding WorkItem.StepsToReproduce}"></TextBox>
+ </Grid>
+ </DockPanel>
+ </Grid>
+ </DockPanel>
</Grid>
<Grid Grid.Row="2">
- <Button HorizontalAlignment="Right" Width="140" Command="{Binding OKCommand}">SUBMIT</Button>
+ <Button HorizontalAlignment="Right" Height="40" Width="140" Command="{Binding OKCommand}" Background="#FF6262" BorderBrush="#FF6262" IsDefault="True">SUBMIT</Button>
<ItemsControl ItemsSource="{Binding ValidationErrors}" HorizontalAlignment="Left" Margin="5" VerticalAlignment="Center" Visibility="Visible">
<ItemsControl.ItemTemplate>
<DataTemplate>
- <TextBlock Foreground="#FF4C4C" Margin="0 2 0 0"><Run>*</Run> <Run Text="{Binding}"></Run></TextBlock>
+ <TextBlock Foreground="#FF4C4C" Margin="0 2 0 0"><Run>*</Run> <Run Text="{Binding Path=*,Mode=OneWay}"></Run></TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml
new file mode 100644
index 000000000..4fb457f87
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml
@@ -0,0 +1,89 @@
+<UserControl x:Class="Tango.MachineStudio.UI.Views.ResolvedIssuesView"
+ 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:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:autoComplete="clr-namespace:Tango.AutoComplete.Editors;assembly=Tango.AutoComplete"
+ xmlns:integration="clr-namespace:Tango.Integration.Services;assembly=Tango.Integration"
+ xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI"
+ xmlns:vm="clr-namespace:Tango.MachineStudio.UI.ViewModels"
+ xmlns:tfs="clr-namespace:Tango.TFS;assembly=Tango.TFS"
+ xmlns:tfss="clr-namespace:Tango.MachineStudio.UI.TFS"
+ xmlns:local="clr-namespace:Tango.MachineStudio.UI.Views"
+ mc:Ignorable="d" Width="530" Height="580" Background="White" d:DataContext="{d:DesignInstance Type=vm:ResolvedIssuesViewVM, IsDesignTimeCreatable=False}">
+ <Grid>
+ <Grid IsEnabled="{Binding IsAvailable}">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="130"/>
+ <RowDefinition Height="1*"/>
+ <RowDefinition Height="200"/>
+ </Grid.RowDefinitions>
+
+ <Grid>
+ <StackPanel Margin="10">
+ <StackPanel Orientation="Horizontal">
+ <Image Source="/Images/bug-resolved.png" Width="48" RenderOptions.BitmapScalingMode="Fant"></Image>
+ <TextBlock VerticalAlignment="Center" Margin="10 0 0 0" FontSize="20">Resolved Issues</TextBlock>
+ </StackPanel>
+
+ <TextBlock HorizontalAlignment="Left" Margin="10" TextWrapping="Wrap">
+ Below you can find issues reported by you that have been flagged as resolved by the development team.
+ Please verify each one and report back by pressing 'FIXED' or 'NOT FIXED'.
+ </TextBlock>
+ </StackPanel>
+ </Grid>
+
+ <Grid Grid.Row="1">
+ <ListBox x:Name="list" ItemsSource="{Binding TFSClient.ResolvedWorkItems}" HorizontalContentAlignment="Stretch">
+ <ListBox.ItemTemplate>
+ <DataTemplate>
+ <Border BorderBrush="#E6E6E6" BorderThickness="0 0 0 1" Padding="5">
+ <DockPanel>
+ <StackPanel Orientation="Horizontal">
+ <Image Source="/Images/bug.png" Width="24" RenderOptions.BitmapScalingMode="Fant"></Image>
+ <StackPanel Margin="5 0 0 0">
+ <TextBlock Text="{Binding Title}" FontWeight="SemiBold" TextTrimming="CharacterEllipsis"></TextBlock>
+ <TextBlock Text="{Binding Comment,TargetNullValue='Comment',FallbackValue='Comment'}" Foreground="Gray" FontSize="10"></TextBlock>
+ </StackPanel>
+ </StackPanel>
+
+ <StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
+ <Button Background="#FF8282" BorderBrush="#FF8282" Padding="0" Width="90" Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.DeclineCommand}" CommandParameter="{Binding}">
+ <StackPanel Orientation="Horizontal">
+ <materialDesign:PackIcon VerticalAlignment="Center" Kind="Close" />
+ <TextBlock Margin="10 0 0 0" FontSize="11" VerticalAlignment="Center">NOT FIXED</TextBlock>
+ </StackPanel>
+ </Button>
+ <Button Background="#91D66D" BorderBrush="#91D66D" Padding="0" Width="90" Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.ApproveCommand}" CommandParameter="{Binding}">
+ <StackPanel Orientation="Horizontal">
+ <materialDesign:PackIcon VerticalAlignment="Center" Kind="Check" />
+ <TextBlock Margin="10 0 0 0" FontSize="11" VerticalAlignment="Center">FIXED</TextBlock>
+ </StackPanel>
+ </Button>
+ </StackPanel>
+ </DockPanel>
+ </Border>
+ </DataTemplate>
+ </ListBox.ItemTemplate>
+ </ListBox>
+ </Grid>
+
+ <Grid Grid.Row="2">
+ <Border BorderBrush="#FFA5A5" BorderThickness="0 1 0 0" Margin="5">
+ <DockPanel>
+ <DockPanel Margin="0 10 0 0" DockPanel.Dock="Top">
+ <materialDesign:PackIcon Kind="ChartTimeline" Width="24" Height="24" VerticalAlignment="Center" Margin="0 0 10 0" />
+ <TextBlock VerticalAlignment="Center" FontSize="16">Steps To Reproduce</TextBlock>
+ </DockPanel>
+
+ <Grid>
+ <TextBox Margin="5 10 10 10" Style="{x:Null}" BorderThickness="0" AcceptsReturn="True" TextWrapping="Wrap" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Text="{Binding ElementName=list,Path=SelectedItem.StepsToReproduce}" IsReadOnly="True"></TextBox>
+ </Grid>
+ </DockPanel>
+ </Border>
+ </Grid>
+ </Grid>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml.cs
new file mode 100644
index 000000000..7825bf587
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.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
+{
+ /// <summary>
+ /// Interaction logic for ResolvedBugsView.xaml
+ /// </summary>
+ public partial class ResolvedIssuesView : UserControl
+ {
+ public ResolvedIssuesView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionResolutions.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionResolutions.cs
index 2e7327559..e27a84c3b 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionResolutions.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionResolutions.cs
@@ -10,6 +10,7 @@ namespace Tango.MachineStudio.UI.Windows
{
Shutdown,
Restart,
- Ignore
+ Ignore,
+ Report
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml
index 892e4944f..147b40892 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml
@@ -5,7 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Tango.MachineStudio.UI.Windows"
mc:Ignorable="d"
- WindowStyle="None" ResizeMode="NoResize" Topmost="True" AllowsTransparency="True" WindowStartupLocation="CenterScreen" d:DesignHeight="300" d:DesignWidth="300" Width="610" Height="410" Background="Transparent" d:DataContext="{d:DesignInstance Type=local:ExceptionWindow, IsDesignTimeCreatable=False}">
+ WindowStyle="None" ResizeMode="NoResize" Topmost="True" AllowsTransparency="True" WindowStartupLocation="CenterScreen" Width="800" Height="600" Background="Transparent" d:DataContext="{d:DesignInstance Type=local:ExceptionWindow, IsDesignTimeCreatable=False}">
<Grid>
<Border BorderThickness="1" BorderBrush="DodgerBlue" Background="White" Margin="10" CornerRadius="10">
<Border.Effect>
@@ -48,8 +48,16 @@
</Grid>
<Grid Grid.Row="1">
- <Button HorizontalAlignment="Left" Width="140" Command="{Binding ResolveCommand}" CommandParameter="{x:Static local:ExceptionResolutions.Ignore}">Ignore</Button>
+ <StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
+ <Button Width="140" Command="{Binding ResolveCommand}" CommandParameter="{x:Static local:ExceptionResolutions.Ignore}">Ignore</Button>
+ </StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
+ <Button x:Name="btnReport" Style="{StaticResource MaterialDesignFlatButton}" Width="150" Command="{Binding ResolveCommand}" CommandParameter="{x:Static local:ExceptionResolutions.Report}">
+ <StackPanel Orientation="Horizontal">
+ <Image Source="/Images/bug.png" RenderOptions.BitmapScalingMode="Fant"></Image>
+ <TextBlock Foreground="#FF5C5C" Margin="10 0 0 0" VerticalAlignment="Center">Report Issue</TextBlock>
+ </StackPanel>
+ </Button>
<Button Margin="5 0 0 0" Width="140" Command="{Binding ResolveCommand}" CommandParameter="{x:Static local:ExceptionResolutions.Shutdown}">Shutdown</Button>
<Button Margin="5 0 0 0" Width="140" Command="{Binding ResolveCommand}" CommandParameter="{x:Static local:ExceptionResolutions.Restart}">Restart</Button>
</StackPanel>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml.cs
index 0f74fee17..0a6f2de39 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml.cs
@@ -33,10 +33,15 @@ namespace Tango.MachineStudio.UI.Windows
DataContext = this;
}
- public ExceptionWindow(Exception ex) : this()
+ public ExceptionWindow(Exception ex, bool canReport) : this()
{
Exception = ex.FlattenException();
ResolveCommand = new RelayCommand<ExceptionResolutions>(Resolve);
+
+ if (!canReport)
+ {
+ btnReport.Visibility = Visibility.Collapsed;
+ }
}
private void Resolve(ExceptionResolutions resolution)
diff --git a/Software/Visual_Studio/Tango.BL/Enumerations/Permissions.cs b/Software/Visual_Studio/Tango.BL/Enumerations/Permissions.cs
index ee77c6f0f..a727bf5e8 100644
--- a/Software/Visual_Studio/Tango.BL/Enumerations/Permissions.cs
+++ b/Software/Visual_Studio/Tango.BL/Enumerations/Permissions.cs
@@ -75,5 +75,11 @@ namespace Tango.BL.Enumerations
[Description("Allows loading the Users & Roles module in machine studio")]
RunUsersAndRolesModule = 10,
+ /// <summary>
+ /// (Allows openning the machine studio developer console)
+ /// </summary>
+ [Description("Allows openning the machine studio developer console")]
+ RunDeveloperConsole = 11,
+
}
}
diff --git a/Software/Visual_Studio/Tango.CodeGeneration/CustomResolver.cs b/Software/Visual_Studio/Tango.CodeGeneration/CustomResolver.cs
new file mode 100644
index 000000000..ee1acccae
--- /dev/null
+++ b/Software/Visual_Studio/Tango.CodeGeneration/CustomResolver.cs
@@ -0,0 +1,20 @@
+using RazorEngine.Compilation;
+using RazorEngine.Compilation.ReferenceResolver;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.CodeGeneration
+{
+ internal class CustomResolver : IReferenceResolver
+ {
+ public IEnumerable<CompilerReference> GetReferences(TypeContext context, IEnumerable<CompilerReference> includeAssemblies)
+ {
+ return new UseCurrentAssembliesReferenceResolver()
+ .GetReferences(context, includeAssemblies)
+ .Where(f => !f.GetFile().EndsWith(".winmd"));
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.CodeGeneration/Helper.cs b/Software/Visual_Studio/Tango.CodeGeneration/Helper.cs
index dfbc893ee..af617fe3e 100644
--- a/Software/Visual_Studio/Tango.CodeGeneration/Helper.cs
+++ b/Software/Visual_Studio/Tango.CodeGeneration/Helper.cs
@@ -1,4 +1,5 @@
using RazorEngine;
+using RazorEngine.Configuration;
using RazorEngine.Templating;
using System;
using System.Collections.Generic;
@@ -15,6 +16,12 @@ namespace Tango.CodeGeneration
/// </summary>
public static class Helper
{
+ static Helper()
+ {
+ var config = new TemplateServiceConfiguration { Debug = true, ReferenceResolver = new CustomResolver() };
+ Engine.Razor = RazorEngineService.Create(config);
+ }
+
/// <summary>
/// Gets a code template by the code object type.
/// </summary>
diff --git a/Software/Visual_Studio/Tango.CodeGeneration/Tango.CodeGeneration.csproj b/Software/Visual_Studio/Tango.CodeGeneration/Tango.CodeGeneration.csproj
index db77d9f20..ff83f8ce4 100644
--- a/Software/Visual_Studio/Tango.CodeGeneration/Tango.CodeGeneration.csproj
+++ b/Software/Visual_Studio/Tango.CodeGeneration/Tango.CodeGeneration.csproj
@@ -63,6 +63,7 @@
<Compile Include="Class.cs" />
<Compile Include="CodeFile.cs" />
<Compile Include="CodeObject.cs" />
+ <Compile Include="CustomResolver.cs" />
<Compile Include="DpProperty.cs" />
<Compile Include="EntityCodeFileJavaExtension.cs" />
<Compile Include="EntityCodeFileJava.cs" />
diff --git a/Software/Visual_Studio/Tango.Core/ExtensionMethods/ObjectExtensions.cs b/Software/Visual_Studio/Tango.Core/ExtensionMethods/ObjectExtensions.cs
index 87f410542..9d17bd198 100644
--- a/Software/Visual_Studio/Tango.Core/ExtensionMethods/ObjectExtensions.cs
+++ b/Software/Visual_Studio/Tango.Core/ExtensionMethods/ObjectExtensions.cs
@@ -7,6 +7,7 @@ using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
+using Tango.Core.Json;
using Tango.Serialization;
/// <summary>
@@ -93,4 +94,28 @@ public static class ObjectExtensions
return JsonConvert.SerializeObject(obj, Formatting.Indented);
}
+
+ /// <summary>
+ /// Serializes the specified object to indented json string.
+ /// </summary>
+ /// <param name="obj">The object.</param>
+ /// <returns></returns>
+ public static String ToJsonString(this Object obj, params String[] ignoreProperties)
+ {
+ var settings = new JsonSerializerSettings() { ContractResolver = new DynamicContractResolver(ignoreProperties) };
+ settings.Converters.Add(new StringEnumConverter { CamelCaseText = false });
+ return JsonConvert.SerializeObject(obj, Formatting.Indented, settings);
+ }
+
+ /// <summary>
+ /// Serializes the specified object to indented json html string.
+ /// </summary>
+ /// <param name="obj">The object.</param>
+ /// <returns></returns>
+ public static String ToHtmlJsonString(this Object obj, params String[] ignoreProperties)
+ {
+ var settings = new JsonSerializerSettings() { ContractResolver = new HtmlContractResolver(ignoreProperties) };
+ settings.Converters.Add(new StringEnumConverter { CamelCaseText = false });
+ return JsonConvert.SerializeObject(obj, Formatting.Indented, settings);
+ }
}
diff --git a/Software/Visual_Studio/Tango.Core/Helpers/EmbeddedResourceHelper.cs b/Software/Visual_Studio/Tango.Core/Helpers/EmbeddedResourceHelper.cs
index d1d556296..bdf2cb684 100644
--- a/Software/Visual_Studio/Tango.Core/Helpers/EmbeddedResourceHelper.cs
+++ b/Software/Visual_Studio/Tango.Core/Helpers/EmbeddedResourceHelper.cs
@@ -15,5 +15,15 @@ namespace Tango.Core.Helpers
Assembly asm = Assembly.GetCallingAssembly();
return asm.GetManifestResourceStream(relativePath);
}
+
+ public static String GetEmbeddedResourceText(String relativePath)
+ {
+ Assembly asm = Assembly.GetCallingAssembly();
+ using (Stream st = asm.GetManifestResourceStream(relativePath))
+ {
+ StreamReader reader = new StreamReader(st);
+ return reader.ReadToEnd();
+ }
+ }
}
}
diff --git a/Software/Visual_Studio/Tango.Core/Json/DynamicContractResolver.cs b/Software/Visual_Studio/Tango.Core/Json/DynamicContractResolver.cs
new file mode 100644
index 000000000..293b6947f
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Core/Json/DynamicContractResolver.cs
@@ -0,0 +1,30 @@
+using Newtonsoft.Json.Serialization;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using System.Reflection;
+
+namespace Tango.Core.Json
+{
+ public class DynamicContractResolver : DefaultContractResolver
+ {
+ private List<String> _ignoreProperties;
+
+ public DynamicContractResolver(params String[] ignoreProperties)
+ {
+ _ignoreProperties = ignoreProperties.ToList();
+ }
+
+ protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
+ {
+ JsonProperty property = base.CreateProperty(member, memberSerialization);
+
+ property.ShouldSerialize = (x) => !_ignoreProperties.Contains(property.PropertyName);
+
+ return property;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Core/Json/HtmlContractResolver.cs b/Software/Visual_Studio/Tango.Core/Json/HtmlContractResolver.cs
new file mode 100644
index 000000000..c4affd3ad
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Core/Json/HtmlContractResolver.cs
@@ -0,0 +1,39 @@
+using Newtonsoft.Json.Serialization;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using System.Reflection;
+
+namespace Tango.Core.Json
+{
+ public class HtmlContractResolver : DefaultContractResolver
+ {
+ private List<String> _ignoreProperties;
+
+ public HtmlContractResolver(params String[] ignoreProperties)
+ {
+ if (ignoreProperties != null)
+ {
+ _ignoreProperties = ignoreProperties.ToList();
+ }
+ else
+ {
+ _ignoreProperties = new List<string>();
+ }
+ }
+
+ protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
+ {
+ JsonProperty property = base.CreateProperty(member, memberSerialization);
+
+ property.ShouldSerialize = (x) => !_ignoreProperties.Contains(property.PropertyName);
+
+ property.PropertyName = "<b>" + property.PropertyName.Replace("\"", "") + "<b/>";
+
+ return property;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Core/Tango.Core.csproj b/Software/Visual_Studio/Tango.Core/Tango.Core.csproj
index a9196237b..648137190 100644
--- a/Software/Visual_Studio/Tango.Core/Tango.Core.csproj
+++ b/Software/Visual_Studio/Tango.Core/Tango.Core.csproj
@@ -91,6 +91,8 @@
<Compile Include="Helpers\PathHelper.cs" />
<Compile Include="Helpers\ThreadsHelper.cs" />
<Compile Include="IParameterized.cs" />
+ <Compile Include="Json\HtmlContractResolver.cs" />
+ <Compile Include="Json\DynamicContractResolver.cs" />
<Compile Include="ParameterIgnoreAttribute.cs" />
<Compile Include="ParameterItem.cs" />
<Compile Include="ParameterItemAttribute.cs" />
diff --git a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs
index a2c53f7b3..0b7ddc9ef 100644
--- a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs
+++ b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs
@@ -301,10 +301,6 @@ namespace Tango.Emulations.Emulators
res.Events.AddRange(EventsStates.Where(x => x.IsActive).Select(x => new Event() { Type = x.EventType, Message = "Generated by Tango Embedded Emulator" }));
- res.Version = "1.0.0.0";
- res.VersionBuildDate = DateTime.Now.ToString();
- res.VersionName = "Embedded Emulator";
-
Transporter.SendResponse<PushDiagnosticsResponse>(res, request.Container.Token);
Thread.Sleep(10);
}
@@ -648,7 +644,15 @@ namespace Tango.Emulations.Emulators
_continousResponseTokens.Clear();
- Transporter.SendResponse<ConnectResponse>(new ConnectResponse(), request.Container.Token, null, request.Message.Password == "1234" ? ErrorCode.None : ErrorCode.UnauthorizedConnection);
+ Transporter.SendResponse<ConnectResponse>(new ConnectResponse()
+ {
+ DeviceInformation = new DeviceInformation()
+ {
+ Version = "1.0.0.0",
+ BuildDate = DateTime.Now.ToString(),
+ Name = "Machine Emulator",
+ },
+ }, request.Container.Token, null, request.Message.Password == "1234" ? ErrorCode.None : ErrorCode.UnauthorizedConnection);
}
#endregion
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/IMachineOperator.cs b/Software/Visual_Studio/Tango.Integration/Operation/IMachineOperator.cs
index 861935e83..efe4fe7af 100644
--- a/Software/Visual_Studio/Tango.Integration/Operation/IMachineOperator.cs
+++ b/Software/Visual_Studio/Tango.Integration/Operation/IMachineOperator.cs
@@ -64,6 +64,21 @@ namespace Tango.Integration.Operation
bool EnableEmbeddedDebugging { get; set; }
/// <summary>
+ /// Gets the last process parameters table sent to the embedded device.
+ /// </summary>
+ ProcessParametersTable CurrentProcessParameters { get; }
+
+ /// <summary>
+ /// Gets the last hardware configuration sent to the embedded device.
+ /// </summary>
+ HardwareConfiguration CurrentHardwareConfiguration { get; }
+
+ /// <summary>
+ /// Gets or sets the embedded device information.
+ /// </summary>
+ DeviceInformation DeviceInformation { get; }
+
+ /// <summary>
/// Gets or sets the machine events state provider used to get notifications about current machine events and errors.
/// </summary>
IMachineEventsStateProvider MachineEventsStateProvider { get; set; }
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/MachineOperator.cs b/Software/Visual_Studio/Tango.Integration/Operation/MachineOperator.cs
index f7b447843..118bbc38a 100644
--- a/Software/Visual_Studio/Tango.Integration/Operation/MachineOperator.cs
+++ b/Software/Visual_Studio/Tango.Integration/Operation/MachineOperator.cs
@@ -49,6 +49,7 @@ namespace Tango.Integration.Operation
public MachineOperator() : base()
{
+ DeviceInformation = new DeviceInformation();
MachineEventsStateProvider = new DefaultMachineEventsStateProvider();
EnableEmbeddedDebugging = true;
LogEmbeddedDebuggingToFile = true;
@@ -154,6 +155,27 @@ namespace Tango.Integration.Operation
/// </summary>
public IMachineEventsStateProvider MachineEventsStateProvider { get; set; }
+ /// <summary>
+ /// Gets the last process parameters table sent to the embedded device.
+ /// </summary>
+ public ProcessParametersTable CurrentProcessParameters { get; private set; }
+
+ /// <summary>
+ /// Gets the last hardware configuration sent to the embedded device.
+ /// </summary>
+ public HardwareConfiguration CurrentHardwareConfiguration { get; private set; }
+
+ private DeviceInformation _deviceInformation;
+ /// <summary>
+ /// Gets or sets the embedded device information.
+ /// </summary>
+ public DeviceInformation DeviceInformation
+ {
+ get { return _deviceInformation; }
+ set { _deviceInformation = value; RaisePropertyChangedAuto(); }
+ }
+
+
#endregion
#region Virtual Methods
@@ -367,6 +389,8 @@ namespace Tango.Integration.Operation
var response = await SendRequest<ConnectRequest, ConnectResponse>(request);
LogResponseReceived(response.Message);
+ DeviceInformation = response.Message.DeviceInformation;
+
OnEnableDiagnosticsChanged(EnableDiagnostics);
OnEnableEmbeddedDebuggingChanged(EnableEmbeddedDebugging);
}
@@ -391,6 +415,8 @@ namespace Tango.Integration.Operation
/// <returns></returns>
public JobHandler Print(Job job, ProcessParametersTable processParameters)
{
+ CurrentProcessParameters = processParameters;
+
JobRequest request = new JobRequest();
JobTicket ticket = new JobTicket();
@@ -508,6 +534,7 @@ namespace Tango.Integration.Operation
try
{
+ CurrentProcessParameters = processParameters;
LogRequestSent(request);
response = await SendRequest<UploadProcessParametersRequest, UploadProcessParametersResponse>(request);
LogResponseReceived(response);
@@ -530,8 +557,23 @@ namespace Tango.Integration.Operation
{
UploadHardwareConfigurationRequest request = new UploadHardwareConfigurationRequest();
request.HardwareConfiguration = hardwareConfiguration;
- LogRequestSent(request);
- return await SendRequest<UploadHardwareConfigurationRequest, UploadHardwareConfigurationResponse>(request);
+
+ UploadHardwareConfigurationResponse response = null;
+
+ try
+ {
+ CurrentHardwareConfiguration = hardwareConfiguration;
+ LogRequestSent(request);
+ response = await SendRequest<UploadHardwareConfigurationRequest, UploadHardwareConfigurationResponse>(request);
+ LogResponseReceived(response);
+ }
+ catch (Exception ex)
+ {
+ LogRequestFailed(request, ex);
+ throw ex;
+ }
+
+ return response;
}
/// <summary>
diff --git a/Software/Visual_Studio/Tango.PMR/Connection/ConnectResponse.cs b/Software/Visual_Studio/Tango.PMR/Connection/ConnectResponse.cs
index 1e5562f11..3ff3c91c1 100644
--- a/Software/Visual_Studio/Tango.PMR/Connection/ConnectResponse.cs
+++ b/Software/Visual_Studio/Tango.PMR/Connection/ConnectResponse.cs
@@ -23,12 +23,14 @@ namespace Tango.PMR.Connection {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"ChVDb25uZWN0UmVzcG9uc2UucHJvdG8SFFRhbmdvLlBNUi5Db25uZWN0aW9u",
- "IhEKD0Nvbm5lY3RSZXNwb25zZUIgCh5jb20udHdpbmUudGFuZ28ucG1yLmNv",
- "bm5lY3Rpb25iBnByb3RvMw=="));
+ "GhdEZXZpY2VJbmZvcm1hdGlvbi5wcm90byJVCg9Db25uZWN0UmVzcG9uc2US",
+ "QgoRRGV2aWNlSW5mb3JtYXRpb24YASABKAsyJy5UYW5nby5QTVIuQ29ubmVj",
+ "dGlvbi5EZXZpY2VJbmZvcm1hdGlvbkIgCh5jb20udHdpbmUudGFuZ28ucG1y",
+ "LmNvbm5lY3Rpb25iBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
- new pbr::FileDescriptor[] { },
+ new pbr::FileDescriptor[] { global::Tango.PMR.Connection.DeviceInformationReflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
- new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Connection.ConnectResponse), global::Tango.PMR.Connection.ConnectResponse.Parser, null, null, null, null)
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Connection.ConnectResponse), global::Tango.PMR.Connection.ConnectResponse.Parser, new[]{ "DeviceInformation" }, null, null, null)
}));
}
#endregion
@@ -59,6 +61,7 @@ namespace Tango.PMR.Connection {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ConnectResponse(ConnectResponse other) : this() {
+ DeviceInformation = other.deviceInformation_ != null ? other.DeviceInformation.Clone() : null;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -66,6 +69,17 @@ namespace Tango.PMR.Connection {
return new ConnectResponse(this);
}
+ /// <summary>Field number for the "DeviceInformation" field.</summary>
+ public const int DeviceInformationFieldNumber = 1;
+ private global::Tango.PMR.Connection.DeviceInformation deviceInformation_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Tango.PMR.Connection.DeviceInformation DeviceInformation {
+ get { return deviceInformation_; }
+ set {
+ deviceInformation_ = value;
+ }
+ }
+
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ConnectResponse);
@@ -79,12 +93,14 @@ namespace Tango.PMR.Connection {
if (ReferenceEquals(other, this)) {
return true;
}
+ if (!object.Equals(DeviceInformation, other.DeviceInformation)) return false;
return true;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
+ if (deviceInformation_ != null) hash ^= DeviceInformation.GetHashCode();
return hash;
}
@@ -95,11 +111,18 @@ namespace Tango.PMR.Connection {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
+ if (deviceInformation_ != null) {
+ output.WriteRawTag(10);
+ output.WriteMessage(DeviceInformation);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
+ if (deviceInformation_ != null) {
+ size += 1 + pb::CodedOutputStream.ComputeMessageSize(DeviceInformation);
+ }
return size;
}
@@ -108,6 +131,12 @@ namespace Tango.PMR.Connection {
if (other == null) {
return;
}
+ if (other.deviceInformation_ != null) {
+ if (deviceInformation_ == null) {
+ deviceInformation_ = new global::Tango.PMR.Connection.DeviceInformation();
+ }
+ DeviceInformation.MergeFrom(other.DeviceInformation);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -118,6 +147,13 @@ namespace Tango.PMR.Connection {
default:
input.SkipLastField();
break;
+ case 10: {
+ if (deviceInformation_ == null) {
+ deviceInformation_ = new global::Tango.PMR.Connection.DeviceInformation();
+ }
+ input.ReadMessage(deviceInformation_);
+ break;
+ }
}
}
}
diff --git a/Software/Visual_Studio/Tango.PMR/Connection/DeviceInformation.cs b/Software/Visual_Studio/Tango.PMR/Connection/DeviceInformation.cs
new file mode 100644
index 000000000..0fec71b8b
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/Connection/DeviceInformation.cs
@@ -0,0 +1,216 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: DeviceInformation.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Tango.PMR.Connection {
+
+ /// <summary>Holder for reflection information generated from DeviceInformation.proto</summary>
+ public static partial class DeviceInformationReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for DeviceInformation.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static DeviceInformationReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "ChdEZXZpY2VJbmZvcm1hdGlvbi5wcm90bxIUVGFuZ28uUE1SLkNvbm5lY3Rp",
+ "b24iRQoRRGV2aWNlSW5mb3JtYXRpb24SDAoETmFtZRgBIAEoCRIPCgdWZXJz",
+ "aW9uGAIgASgJEhEKCUJ1aWxkRGF0ZRgDIAEoCUIgCh5jb20udHdpbmUudGFu",
+ "Z28ucG1yLmNvbm5lY3Rpb25iBnByb3RvMw=="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Connection.DeviceInformation), global::Tango.PMR.Connection.DeviceInformation.Parser, new[]{ "Name", "Version", "BuildDate" }, null, null, null)
+ }));
+ }
+ #endregion
+
+ }
+ #region Messages
+ public sealed partial class DeviceInformation : pb::IMessage<DeviceInformation> {
+ private static readonly pb::MessageParser<DeviceInformation> _parser = new pb::MessageParser<DeviceInformation>(() => new DeviceInformation());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<DeviceInformation> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Tango.PMR.Connection.DeviceInformationReflection.Descriptor.MessageTypes[0]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public DeviceInformation() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public DeviceInformation(DeviceInformation other) : this() {
+ name_ = other.name_;
+ version_ = other.version_;
+ buildDate_ = other.buildDate_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public DeviceInformation Clone() {
+ return new DeviceInformation(this);
+ }
+
+ /// <summary>Field number for the "Name" field.</summary>
+ public const int NameFieldNumber = 1;
+ private string name_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string Name {
+ get { return name_; }
+ set {
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "Version" field.</summary>
+ public const int VersionFieldNumber = 2;
+ private string version_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string Version {
+ get { return version_; }
+ set {
+ version_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "BuildDate" field.</summary>
+ public const int BuildDateFieldNumber = 3;
+ private string buildDate_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string BuildDate {
+ get { return buildDate_; }
+ set {
+ buildDate_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as DeviceInformation);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(DeviceInformation other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Name != other.Name) return false;
+ if (Version != other.Version) return false;
+ if (BuildDate != other.BuildDate) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Name.Length != 0) hash ^= Name.GetHashCode();
+ if (Version.Length != 0) hash ^= Version.GetHashCode();
+ if (BuildDate.Length != 0) hash ^= BuildDate.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (Name.Length != 0) {
+ output.WriteRawTag(10);
+ output.WriteString(Name);
+ }
+ if (Version.Length != 0) {
+ output.WriteRawTag(18);
+ output.WriteString(Version);
+ }
+ if (BuildDate.Length != 0) {
+ output.WriteRawTag(26);
+ output.WriteString(BuildDate);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (Name.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
+ }
+ if (Version.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Version);
+ }
+ if (BuildDate.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(BuildDate);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(DeviceInformation other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Name.Length != 0) {
+ Name = other.Name;
+ }
+ if (other.Version.Length != 0) {
+ Version = other.Version;
+ }
+ if (other.BuildDate.Length != 0) {
+ BuildDate = other.BuildDate;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ Name = input.ReadString();
+ break;
+ }
+ case 18: {
+ Version = input.ReadString();
+ break;
+ }
+ case 26: {
+ BuildDate = input.ReadString();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/Software/Visual_Studio/Tango.PMR/Diagnostics/PushDiagnosticsResponse.cs b/Software/Visual_Studio/Tango.PMR/Diagnostics/PushDiagnosticsResponse.cs
index c266bb0a8..db4479cf6 100644
--- a/Software/Visual_Studio/Tango.PMR/Diagnostics/PushDiagnosticsResponse.cs
+++ b/Software/Visual_Studio/Tango.PMR/Diagnostics/PushDiagnosticsResponse.cs
@@ -25,19 +25,17 @@ namespace Tango.PMR.Diagnostics {
"Ch1QdXNoRGlhZ25vc3RpY3NSZXNwb25zZS5wcm90bxIVVGFuZ28uUE1SLkRp",
"YWdub3N0aWNzGhBEaWdpdGFsUGluLnByb3RvGhlWYWx1ZUNvbXBvbmVudFN0",
"YXRlLnByb3RvGhlEaWFnbm9zdGljc01vbml0b3JzLnByb3RvGgtFdmVudC5w",
- "cm90byLDAgoXUHVzaERpYWdub3N0aWNzUmVzcG9uc2USPAoITW9uaXRvcnMY",
+ "cm90byKDAgoXUHVzaERpYWdub3N0aWNzUmVzcG9uc2USPAoITW9uaXRvcnMY",
"ASABKAsyKi5UYW5nby5QTVIuRGlhZ25vc3RpY3MuRGlhZ25vc3RpY3NNb25p",
"dG9ycxI2CgtEaWdpdGFsUGlucxgCIAMoCzIhLlRhbmdvLlBNUi5EaWFnbm9z",
"dGljcy5EaWdpdGFsUGluEkQKEENvbXBvbmVudHNTdGF0ZXMYAyADKAsyKi5U",
"YW5nby5QTVIuRGlhZ25vc3RpY3MuVmFsdWVDb21wb25lbnRTdGF0ZRIsCgZF",
- "dmVudHMYBCADKAsyHC5UYW5nby5QTVIuRGlhZ25vc3RpY3MuRXZlbnQSDwoH",
- "VmVyc2lvbhgFIAEoCRITCgtWZXJzaW9uTmFtZRgGIAEoCRIYChBWZXJzaW9u",
- "QnVpbGREYXRlGAcgASgJQiEKH2NvbS50d2luZS50YW5nby5wbXIuZGlhZ25v",
- "c3RpY3NiBnByb3RvMw=="));
+ "dmVudHMYBCADKAsyHC5UYW5nby5QTVIuRGlhZ25vc3RpY3MuRXZlbnRCIQof",
+ "Y29tLnR3aW5lLnRhbmdvLnBtci5kaWFnbm9zdGljc2IGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Tango.PMR.Diagnostics.DigitalPinReflection.Descriptor, global::Tango.PMR.Diagnostics.ValueComponentStateReflection.Descriptor, global::Tango.PMR.Diagnostics.DiagnosticsMonitorsReflection.Descriptor, global::Tango.PMR.Diagnostics.EventReflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
- new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Diagnostics.PushDiagnosticsResponse), global::Tango.PMR.Diagnostics.PushDiagnosticsResponse.Parser, new[]{ "Monitors", "DigitalPins", "ComponentsStates", "Events", "Version", "VersionName", "VersionBuildDate" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Diagnostics.PushDiagnosticsResponse), global::Tango.PMR.Diagnostics.PushDiagnosticsResponse.Parser, new[]{ "Monitors", "DigitalPins", "ComponentsStates", "Events" }, null, null, null)
}));
}
#endregion
@@ -72,9 +70,6 @@ namespace Tango.PMR.Diagnostics {
digitalPins_ = other.digitalPins_.Clone();
componentsStates_ = other.componentsStates_.Clone();
events_ = other.events_.Clone();
- version_ = other.version_;
- versionName_ = other.versionName_;
- versionBuildDate_ = other.versionBuildDate_;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -135,42 +130,6 @@ namespace Tango.PMR.Diagnostics {
get { return events_; }
}
- /// <summary>Field number for the "Version" field.</summary>
- public const int VersionFieldNumber = 5;
- private string version_ = "";
- /// <summary>
- ///Software Information
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public string Version {
- get { return version_; }
- set {
- version_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
- }
- }
-
- /// <summary>Field number for the "VersionName" field.</summary>
- public const int VersionNameFieldNumber = 6;
- private string versionName_ = "";
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public string VersionName {
- get { return versionName_; }
- set {
- versionName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
- }
- }
-
- /// <summary>Field number for the "VersionBuildDate" field.</summary>
- public const int VersionBuildDateFieldNumber = 7;
- private string versionBuildDate_ = "";
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public string VersionBuildDate {
- get { return versionBuildDate_; }
- set {
- versionBuildDate_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
- }
- }
-
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as PushDiagnosticsResponse);
@@ -188,9 +147,6 @@ namespace Tango.PMR.Diagnostics {
if(!digitalPins_.Equals(other.digitalPins_)) return false;
if(!componentsStates_.Equals(other.componentsStates_)) return false;
if(!events_.Equals(other.events_)) return false;
- if (Version != other.Version) return false;
- if (VersionName != other.VersionName) return false;
- if (VersionBuildDate != other.VersionBuildDate) return false;
return true;
}
@@ -201,9 +157,6 @@ namespace Tango.PMR.Diagnostics {
hash ^= digitalPins_.GetHashCode();
hash ^= componentsStates_.GetHashCode();
hash ^= events_.GetHashCode();
- if (Version.Length != 0) hash ^= Version.GetHashCode();
- if (VersionName.Length != 0) hash ^= VersionName.GetHashCode();
- if (VersionBuildDate.Length != 0) hash ^= VersionBuildDate.GetHashCode();
return hash;
}
@@ -221,18 +174,6 @@ namespace Tango.PMR.Diagnostics {
digitalPins_.WriteTo(output, _repeated_digitalPins_codec);
componentsStates_.WriteTo(output, _repeated_componentsStates_codec);
events_.WriteTo(output, _repeated_events_codec);
- if (Version.Length != 0) {
- output.WriteRawTag(42);
- output.WriteString(Version);
- }
- if (VersionName.Length != 0) {
- output.WriteRawTag(50);
- output.WriteString(VersionName);
- }
- if (VersionBuildDate.Length != 0) {
- output.WriteRawTag(58);
- output.WriteString(VersionBuildDate);
- }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -244,15 +185,6 @@ namespace Tango.PMR.Diagnostics {
size += digitalPins_.CalculateSize(_repeated_digitalPins_codec);
size += componentsStates_.CalculateSize(_repeated_componentsStates_codec);
size += events_.CalculateSize(_repeated_events_codec);
- if (Version.Length != 0) {
- size += 1 + pb::CodedOutputStream.ComputeStringSize(Version);
- }
- if (VersionName.Length != 0) {
- size += 1 + pb::CodedOutputStream.ComputeStringSize(VersionName);
- }
- if (VersionBuildDate.Length != 0) {
- size += 1 + pb::CodedOutputStream.ComputeStringSize(VersionBuildDate);
- }
return size;
}
@@ -270,15 +202,6 @@ namespace Tango.PMR.Diagnostics {
digitalPins_.Add(other.digitalPins_);
componentsStates_.Add(other.componentsStates_);
events_.Add(other.events_);
- if (other.Version.Length != 0) {
- Version = other.Version;
- }
- if (other.VersionName.Length != 0) {
- VersionName = other.VersionName;
- }
- if (other.VersionBuildDate.Length != 0) {
- VersionBuildDate = other.VersionBuildDate;
- }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -308,18 +231,6 @@ namespace Tango.PMR.Diagnostics {
events_.AddEntriesFrom(input, _repeated_events_codec);
break;
}
- case 42: {
- Version = input.ReadString();
- break;
- }
- case 50: {
- VersionName = input.ReadString();
- break;
- }
- case 58: {
- VersionBuildDate = input.ReadString();
- break;
- }
}
}
}
diff --git a/Software/Visual_Studio/Tango.PMR/ExtensionMethods.cs b/Software/Visual_Studio/Tango.PMR/ExtensionMethods.cs
index 9707399d9..3a255480d 100644
--- a/Software/Visual_Studio/Tango.PMR/ExtensionMethods.cs
+++ b/Software/Visual_Studio/Tango.PMR/ExtensionMethods.cs
@@ -13,7 +13,7 @@ namespace Tango.PMR
/// <summary>
/// Contains PMR extension methods.
/// </summary>
- public static class ExtensionMethods
+ public static class ExtensionMethods
{
/// <summary>
/// Gets the protobuf <see cref="OriginalNameAttribute"/> attribute value from the message type.
diff --git a/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj b/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj
index bab99641a..07098b09f 100644
--- a/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj
+++ b/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj
@@ -59,6 +59,7 @@
<Compile Include="ColorLab\OutputLiquid.cs" />
<Compile Include="Connection\ConnectRequest.cs" />
<Compile Include="Connection\ConnectResponse.cs" />
+ <Compile Include="Connection\DeviceInformation.cs" />
<Compile Include="Connection\DisconnectRequest.cs" />
<Compile Include="Connection\DisconnectResponse.cs" />
<Compile Include="Connection\KeepAliveRequest.cs" />
diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/ScriptEditorControl.xaml.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/ScriptEditorControl.xaml.cs
index a74e649c0..3fe87c7e2 100644
--- a/Software/Visual_Studio/Tango.SharedUI/Controls/ScriptEditorControl.xaml.cs
+++ b/Software/Visual_Studio/Tango.SharedUI/Controls/ScriptEditorControl.xaml.cs
@@ -182,7 +182,7 @@ namespace Tango.SharedUI.Controls
foreach (var v in variables)
{
- var hT = IntellisenseTypes.SingleOrDefault(x => x.Value.Name == v.Type);
+ var hT = IntellisenseTypes.SingleOrDefault(x => x.Key == v.Type);
if (hT.Value != null)
{
@@ -259,7 +259,7 @@ namespace Tango.SharedUI.Controls
- foreach (var name in HighlightTypes.Select(x => x.Value).Select(x => x.Name))
+ foreach (var name in HighlightTypes.Select(x => x.Key))
{
code += String.Format("<Word>{0}</Word>", name) + Environment.NewLine;
}
diff --git a/Software/Visual_Studio/Tango.TFS/ITeamFoundationServiceClient.cs b/Software/Visual_Studio/Tango.TFS/ITeamFoundationServiceClient.cs
index 51394f663..1fe169218 100644
--- a/Software/Visual_Studio/Tango.TFS/ITeamFoundationServiceClient.cs
+++ b/Software/Visual_Studio/Tango.TFS/ITeamFoundationServiceClient.cs
@@ -35,6 +35,42 @@ namespace Tango.TFS
Task<WorkItem> GetWorkItem(Project project, int id);
/// <summary>
+ /// Gets all the work items created by the specified team member.
+ /// </summary>
+ /// <param name="project">The project.</param>
+ /// <param name="member">The member.</param>
+ /// <returns></returns>
+ Task<List<WorkItem>> GetWorkItemsCreatedBy(Project project, TeamMember member);
+
+ /// <summary>
+ /// Sets the state of the work item.
+ /// </summary>
+ /// <param name="project">The project.</param>
+ /// <param name="item">The item.</param>
+ /// <param name="state">The state.</param>
+ /// <returns></returns>
+ Task<WorkItem> SetWorkItemState(Project project, WorkItem item, State state);
+
+ /// <summary>
+ /// Sets the work item assignment.
+ /// </summary>
+ /// <param name="project">The project.</param>
+ /// <param name="item">The item.</param>
+ /// <param name="member">The member.</param>
+ /// <returns></returns>
+ Task<WorkItem> SetWorkItemAssignment(Project project, WorkItem item, TeamMember member);
+
+ /// <summary>
+ /// Adds a comment to the work item discussion.
+ /// </summary>
+ /// <param name="project">The project.</param>
+ /// <param name="item">The item.</param>
+ /// <param name="teamMember">Team member</param>
+ /// <param name="comment">The comment.</param>
+ /// <returns></returns>
+ Task<WorkItem> AddWorkItemComment(Project project, WorkItem item, TeamMember teamMember, String comment);
+
+ /// <summary>
/// Deletes the specified work item.
/// </summary>
/// <param name="project">The project.</param>
diff --git a/Software/Visual_Studio/Tango.TFS/ResolvedReason.cs b/Software/Visual_Studio/Tango.TFS/ResolvedReason.cs
new file mode 100644
index 000000000..e1af689a2
--- /dev/null
+++ b/Software/Visual_Studio/Tango.TFS/ResolvedReason.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.TFS
+{
+ public enum ResolvedReason
+ {
+ [Description("As Designed")]
+ AsDesigned,
+ [Description("Cannot Reproduce")]
+ CannotReproduce,
+ [Description("Copied To Backlog")]
+ CopiedToBacklog,
+ [Description("Deferred")]
+ Deferred,
+ [Description("Duplicate")]
+ Duplicate,
+ [Description("Fixed")]
+ Fixed,
+ [Description("Obsolete")]
+ Obsolete,
+ }
+}
diff --git a/Software/Visual_Studio/Tango.TFS/Tango.TFS.csproj b/Software/Visual_Studio/Tango.TFS/Tango.TFS.csproj
index 00c9171c3..cf15c2e9e 100644
--- a/Software/Visual_Studio/Tango.TFS/Tango.TFS.csproj
+++ b/Software/Visual_Studio/Tango.TFS/Tango.TFS.csproj
@@ -204,6 +204,7 @@
<Compile Include="Iteration.cs" />
<Compile Include="Priority.cs" />
<Compile Include="Project.cs" />
+ <Compile Include="ResolvedReason.cs" />
<Compile Include="Severity.cs" />
<Compile Include="State.cs" />
<Compile Include="Tag.cs" />
@@ -244,6 +245,10 @@
<Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
<Name>Tango.Core</Name>
</ProjectReference>
+ <ProjectReference Include="..\Tango.Logging\Tango.Logging.csproj">
+ <Project>{bc932dbd-7cdb-488c-99e4-f02cf441f55e}</Project>
+ <Name>Tango.Logging</Name>
+ </ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Microsoft.TeamFoundationServer.ExtendedClient.15.112.1\build\Microsoft.TeamFoundationServer.ExtendedClient.targets" Condition="Exists('..\packages\Microsoft.TeamFoundationServer.ExtendedClient.15.112.1\build\Microsoft.TeamFoundationServer.ExtendedClient.targets')" />
diff --git a/Software/Visual_Studio/Tango.TFS/TeamFoundationServiceClient.cs b/Software/Visual_Studio/Tango.TFS/TeamFoundationServiceClient.cs
index e6390260e..6eef1ef92 100644
--- a/Software/Visual_Studio/Tango.TFS/TeamFoundationServiceClient.cs
+++ b/Software/Visual_Studio/Tango.TFS/TeamFoundationServiceClient.cs
@@ -31,6 +31,9 @@ namespace Tango.TFS
public const String PRIORITY = "Microsoft.VSTS.Common.Priority";
public const String STEPS_TO_REP = "Microsoft.VSTS.TCM.ReproSteps";
public const String SYSTEM_INFO = "Microsoft.VSTS.TCM.SystemInfo";
+ public const String RESOLVED_BY = "Microsoft.VSTS.Common.ResolvedBy";
+ public const String RESOLVED_DATE = "Microsoft.VSTS.Common.ResolvedDate";
+ public const String RESOLVED_REASON = "Microsoft.VSTS.Common.ResolvedReason";
}
#endregion
@@ -86,14 +89,17 @@ namespace Tango.TFS
VssConnection connection = CreateConnection();
+ LogManager.Log("Retrieving project " + name + " details...");
ProjectHttpClient projectClient = connection.GetClient<ProjectHttpClient>();
- TeamProjectReference project = projectClient.GetProjects(null).Result.FirstOrDefault(x => x.Name == name);
+ TeamProjectReference project = projectClient.GetProjects().Result.FirstOrDefault(x => x.Name == name);
if (project == null)
{
- throw new ArgumentException(String.Format("Project '{0}' could not be found.", name));
+ throw LogManager.Log(new ArgumentException(String.Format("Project '{0}' could not be found.", name)));
}
+ LogManager.Log("Project details successfully retrieved.");
+
p.Name = project.Name;
p.ID = project.Id;
p.URL = project.Url;
@@ -128,7 +134,7 @@ namespace Tango.TFS
});
}
- var projCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(CollectionURL));
+ var projCollection = new TfsTeamProjectCollection(new Uri(CollectionURL), connection.Credentials);
var store = projCollection.GetService<WorkItemStore>();
WorkItemCollection queryResults = store.Query("Select [State], [Title] " + "From WorkItems " + "Where [Work Item Type] = 'User Story'");
@@ -213,6 +219,17 @@ namespace Tango.TFS
});
}
+ if (!String.IsNullOrWhiteSpace(workItem.Comment))
+ {
+ patchDocument.Add(new JsonPatchOperation
+ {
+ Operation = Operation.Add,
+ Path = GetFieldNameForWrite(CoreField.History),
+ Value = workItem.Comment,
+ From = workItem.CreatedBy.AssignName
+ });
+ }
+
patchDocument.Add(new JsonPatchOperation
{
Operation = Operation.Add,
@@ -367,72 +384,150 @@ namespace Tango.TFS
{
return Task.Factory.StartNew<WorkItem>(() =>
{
- WorkItem workItem = new WorkItem();
-
var connection = CreateConnection();
WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>();
var item = witClient.GetWorkItemAsync(id, expand: Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models.WorkItemExpand.All).Result;
- workItem.ID = item.Id.Value;
- workItem.Title = item.Fields[GetFieldNameForRead(CoreField.Title)].ToString();
- workItem.Description = TryGetField(item.Fields, GetFieldNameForRead(CoreField.Description));
- workItem.Area = new Area()
- {
- Path = item.Fields[GetFieldNameForRead(CoreField.AreaPath)].ToString(),
- Name = Path.GetFileName(item.Fields[GetFieldNameForRead(CoreField.AreaPath)].ToString()),
- };
- workItem.Iteration = new Iteration()
- {
- Path = item.Fields[GetFieldNameForRead(CoreField.IterationPath)].ToString(),
- Name = Path.GetFileName(item.Fields[GetFieldNameForRead(CoreField.IterationPath)].ToString()),
- };
+ return ConvertToWorkItem(project, item);
+ });
+ }
- 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)));
+ /// <summary>
+ /// Deletes the specified work item.
+ /// </summary>
+ /// <param name="project">The project.</param>
+ /// <param name="id">The identifier.</param>
+ /// <returns></returns>
+ public Task DeleteWorkItem(Project project, int id)
+ {
+ return Task.Factory.StartNew(() =>
+ {
+ var connection = CreateConnection();
- workItem.Type = (WorkItemType)Enum.Parse(typeof(WorkItemType), item.Fields[GetFieldNameForRead(CoreField.WorkItemType)].ToString());
- workItem.URL = item.Url;
+ WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>();
+ var result = witClient.DeleteWorkItemAsync(id, true).Result;
+ });
+ }
- if (item.Fields.ContainsKey(GetFieldNameForRead(CoreField.Tags)))
+ /// <summary>
+ /// Gets all the work items created by the specified team member.
+ /// </summary>
+ /// <param name="project">The project.</param>
+ /// <param name="member">The member.</param>
+ /// <returns></returns>
+ public Task<List<WorkItem>> GetWorkItemsCreatedBy(Project project, TeamMember member)
+ {
+ return Task.Factory.StartNew<List<WorkItem>>(() =>
+ {
+ var connection = CreateConnection();
+
+ var projCollection = new TfsTeamProjectCollection(new Uri(CollectionURL), connection.Credentials);
+ var store = projCollection.GetService<WorkItemStore>();
+
+ WorkItemCollection queryResults = store.Query(String.Format("Select [Id]" + "From WorkItems " + "Where [Created By] = '{0}' And [Work Item Type] = 'Bug'", member.AssignName));
+ var ids = queryResults.OfType<Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem>().Where(x => x.Project.Name == project.Name).ToList().Select(x => x.Id).ToList();
+
+ if (ids.Count == 0) return new List<WorkItem>();
+
+ WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>();
+
+ var items = witClient.GetWorkItemsAsync(ids).Result;
+
+ return items.Select(x => ConvertToWorkItem(project, x)).ToList();
+ });
+ }
+
+ /// <summary>
+ /// Sets the state of the work item.
+ /// </summary>
+ /// <param name="project">The project.</param>
+ /// <param name="item">The item.</param>
+ /// <param name="state">The state.</param>
+ /// <returns></returns>
+ public Task<WorkItem> SetWorkItemState(Project project, WorkItem item, State state)
+ {
+ return Task.Factory.StartNew<WorkItem>(() =>
+ {
+ var connection = CreateConnection();
+
+ WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>();
+
+ var patchDocument = new JsonPatchDocument();
+
+ patchDocument.Add(new JsonPatchOperation
{
- List<String> tags = item.Fields[GetFieldNameForRead(CoreField.Tags)].ToString().Split(';').Select(x => x.Trim()).ToList();
- workItem.Tags = tags.Select(x => new Tag() { Name = x }).ToList();
- }
+ Operation = Operation.Replace,
+ Path = GetFieldNameForWrite(CoreField.State),
+ Value = state.ToString(),
+ });
- workItem.FoundInBuild = item.Fields[ExtensionFields.FOUND_IN_BUILD].ToString();
+ var updatedItem = witClient.UpdateWorkItemAsync(patchDocument, item.ID).Result;
- workItem.State = (State)Enum.Parse(typeof(State), item.Fields[GetFieldNameForRead(CoreField.State)].ToString());
+ return ConvertToWorkItem(project, updatedItem);
+ });
+ }
- workItem.Severity = ParseEnumByDescription<Severity>(item.Fields[ExtensionFields.SEVERITY].ToString());
+ /// <summary>
+ /// Adds a comment to the work item discussion.
+ /// </summary>
+ /// <param name="project">The project.</param>
+ /// <param name="item">The item.</param>
+ /// <param name="teamMember">Team member</param>
+ /// <param name="comment">The comment.</param>
+ /// <returns></returns>
+ public Task<WorkItem> AddWorkItemComment(Project project, WorkItem item, TeamMember teamMember, String comment)
+ {
+ return Task.Factory.StartNew<WorkItem>(() =>
+ {
+ var connection = CreateConnection();
- workItem.Priority = (Priority)int.Parse(item.Fields[ExtensionFields.PRIORITY].ToString());
+ WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>();
- workItem.StepsToReproduce = item.Fields[ExtensionFields.STEPS_TO_REP].ToString();
+ var patchDocument = new JsonPatchDocument();
- workItem.SystemInformation = item.Fields[ExtensionFields.SYSTEM_INFO].ToString();
+ patchDocument.Add(new JsonPatchOperation
+ {
+ Operation = Operation.Add,
+ Path = GetFieldNameForWrite(CoreField.History),
+ Value = comment,
+ From = teamMember.AssignName
+ });
- return workItem;
+ var updatedItem = witClient.UpdateWorkItemAsync(patchDocument, item.ID).Result;
+
+ return ConvertToWorkItem(project, updatedItem);
});
}
/// <summary>
- /// Deletes the specified work item.
+ /// Sets the work item assignment.
/// </summary>
/// <param name="project">The project.</param>
- /// <param name="id">The identifier.</param>
+ /// <param name="item">The item.</param>
+ /// <param name="member">The member.</param>
/// <returns></returns>
- public Task DeleteWorkItem(Project project, int id)
+ public Task<WorkItem> SetWorkItemAssignment(Project project, WorkItem item, TeamMember member)
{
- return Task.Factory.StartNew(() =>
+ return Task.Factory.StartNew<WorkItem>(() =>
{
var connection = CreateConnection();
WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>();
- var result = witClient.DeleteWorkItemAsync(id, true).Result;
+
+ var patchDocument = new JsonPatchDocument();
+
+ patchDocument.Add(new JsonPatchOperation
+ {
+ Operation = Operation.Replace,
+ Path = GetFieldNameForWrite(CoreField.AssignedTo),
+ Value = member.AssignName,
+ });
+
+ var updatedItem = witClient.UpdateWorkItemAsync(patchDocument, item.ID).Result;
+
+ return ConvertToWorkItem(project, updatedItem);
});
}
@@ -446,7 +541,19 @@ namespace Tango.TFS
/// <returns></returns>
private VssConnection CreateConnection()
{
- VssConnection connection = new VssConnection(new Uri(CollectionURL), new VssBasicCredential(UserName, PersonalToken));
+ LogManager.Log("Generating VSTS connection using personal token " + PersonalToken);
+ VssConnection connection = new VssConnection(new Uri(CollectionURL), new VssBasicCredential(String.Empty, PersonalToken));
+ connection.Credentials.PromptType = CredentialPromptType.DoNotPrompt;
+ connection.ConnectAsync(VssConnectMode.User).SyncResult();
+ LogManager.Log("VSS Connection established...");
+
+ LogManager.Log("Authenticated: " + connection.HasAuthenticated);
+
+ if (connection.HasAuthenticated)
+ {
+ LogManager.Log("Authenticated Identity: " + connection.AuthorizedIdentity.DisplayName);
+ }
+
return connection;
}
@@ -514,6 +621,65 @@ namespace Tango.TFS
return values[description];
}
+ private WorkItem ConvertToWorkItem(Project project, Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models.WorkItem item)
+ {
+ WorkItem workItem = new WorkItem();
+
+
+ workItem.ID = item.Id.Value;
+ workItem.Title = item.Fields[GetFieldNameForRead(CoreField.Title)].ToString();
+ workItem.CreatedDate = DateTime.Parse(item.Fields[GetFieldNameForRead(CoreField.CreatedDate)].ToString());
+ workItem.Description = TryGetField(item.Fields, GetFieldNameForRead(CoreField.Description));
+ workItem.Area = new Area()
+ {
+ Path = item.Fields[GetFieldNameForRead(CoreField.AreaPath)].ToString(),
+ Name = Path.GetFileName(item.Fields[GetFieldNameForRead(CoreField.AreaPath)].ToString()),
+ };
+ workItem.Iteration = new Iteration()
+ {
+ 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, 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.ResolvedBy = project.Members.SingleOrDefault(x => x.AssignName == TryGetField(item.Fields, ExtensionFields.RESOLVED_BY));
+
+ if (item.Fields.ContainsKey(ExtensionFields.RESOLVED_REASON))
+ {
+ workItem.ResolvedReason = ParseEnumByDescription<ResolvedReason>(item.Fields[ExtensionFields.RESOLVED_REASON].ToString());
+ workItem.ResolvedDate = DateTime.Parse(item.Fields[ExtensionFields.RESOLVED_DATE].ToString());
+ }
+
+ workItem.Type = (WorkItemType)Enum.Parse(typeof(WorkItemType), item.Fields[GetFieldNameForRead(CoreField.WorkItemType)].ToString());
+ workItem.URL = item.Url;
+
+ if (item.Fields.ContainsKey(GetFieldNameForRead(CoreField.Tags)))
+ {
+ List<String> 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 = TryGetField(item.Fields, ExtensionFields.FOUND_IN_BUILD).ToString();
+
+ workItem.State = (State)Enum.Parse(typeof(State), item.Fields[GetFieldNameForRead(CoreField.State)].ToString());
+
+ workItem.Severity = ParseEnumByDescription<Severity>(item.Fields[ExtensionFields.SEVERITY].ToString());
+
+ workItem.Priority = (Priority)int.Parse(item.Fields[ExtensionFields.PRIORITY].ToString());
+
+ workItem.StepsToReproduce = TryGetField(item.Fields, ExtensionFields.STEPS_TO_REP).ToString();
+
+ workItem.SystemInformation = TryGetField(item.Fields, ExtensionFields.SYSTEM_INFO).ToString();
+
+ workItem.Comment = TryGetField(item.Fields, GetFieldNameForRead(CoreField.History)).ToString();
+
+ return workItem;
+ }
+
#endregion
}
}
diff --git a/Software/Visual_Studio/Tango.TFS/WorkItem.cs b/Software/Visual_Studio/Tango.TFS/WorkItem.cs
index 98ac05191..59f277f2e 100644
--- a/Software/Visual_Studio/Tango.TFS/WorkItem.cs
+++ b/Software/Visual_Studio/Tango.TFS/WorkItem.cs
@@ -101,6 +101,13 @@ namespace Tango.TFS
set { _assignedTo = value; RaisePropertyChangedAuto(); }
}
+ private DateTime _createdDate;
+ public DateTime CreatedDate
+ {
+ get { return _createdDate; }
+ set { _createdDate = value; RaisePropertyChangedAuto(); }
+ }
+
private TeamMember _createdBy;
public TeamMember CreatedBy
{
@@ -115,6 +122,27 @@ namespace Tango.TFS
set { _changedBy = value; RaisePropertyChangedAuto(); }
}
+ private TeamMember _resolvedBy;
+ public TeamMember ResolvedBy
+ {
+ get { return _resolvedBy; }
+ set { _resolvedBy = value; RaisePropertyChangedAuto(); }
+ }
+
+ private DateTime _resolvedDate;
+ public DateTime ResolvedDate
+ {
+ get { return _resolvedDate; }
+ set { _resolvedDate = value; RaisePropertyChangedAuto(); }
+ }
+
+ private ResolvedReason _resolvedReason;
+ public ResolvedReason ResolvedReason
+ {
+ get { return _resolvedReason; }
+ set { _resolvedReason = value; RaisePropertyChangedAuto(); }
+ }
+
private TeamMember _authorizedAs;
public TeamMember AuthorizedAs
{
@@ -140,6 +168,30 @@ namespace Tango.TFS
set { _foundInBuild = value; RaisePropertyChangedAuto(); }
}
+ private String _comment;
+ public String Comment
+ {
+ get { return _comment; }
+ set { _comment = value; RaisePropertyChangedAuto(); }
+ }
+
+ public bool IsBuildVersionValid
+ {
+ get
+ {
+ Version v = null;
+ return Version.TryParse(FoundInBuild, out v);
+ }
+ }
+
+ public Version FoundInBuildVersion
+ {
+ get
+ {
+ return Version.Parse(FoundInBuild);
+ }
+ }
+
public WorkItem()
{
Attachments = new List<Attachment>();
diff --git a/Software/Visual_Studio/Tango.UnitTesting/TFS_TST.cs b/Software/Visual_Studio/Tango.UnitTesting/TFS_TST.cs
index 2727ad00e..3fff8daae 100644
--- a/Software/Visual_Studio/Tango.UnitTesting/TFS_TST.cs
+++ b/Software/Visual_Studio/Tango.UnitTesting/TFS_TST.cs
@@ -43,12 +43,62 @@ namespace Tango.UnitTesting
Assert.IsNotNull(project);
- var workItem = client.GetWorkItem(project, 153).Result;
+ var workItem = client.GetWorkItem(project, 168).Result;
Assert.IsNotNull(workItem);
}
[TestMethod]
+ public void Get_Work_Items_Created_By()
+ {
+ ITeamFoundationServiceClient client = CreateClient();
+
+ var project = client.GetProject("Tango").Result;
+
+ Assert.IsNotNull(project);
+
+ var workItems = client.GetWorkItemsCreatedBy(project, project.Members.SingleOrDefault(x => x.AssignName.ToLower().Contains("roy"))).Result;
+
+ Assert.IsTrue(workItems.Count > 0);
+ }
+
+ [TestMethod]
+ public void Set_Work_Item_State()
+ {
+ ITeamFoundationServiceClient client = CreateClient();
+
+ var project = client.GetProject("Tango").Result;
+
+ Assert.IsNotNull(project);
+
+ var workItem = client.GetWorkItem(project, 164).Result;
+
+ Assert.IsNotNull(workItem);
+
+ var updated = client.SetWorkItemState(project, workItem, State.Active).Result;
+
+ Assert.IsTrue(updated.State == State.Active);
+ }
+
+ [TestMethod]
+ public void Add_Work_Item_Comment()
+ {
+ ITeamFoundationServiceClient client = CreateClient();
+
+ var project = client.GetProject("Tango").Result;
+
+ Assert.IsNotNull(project);
+
+ var workItem = client.GetWorkItem(project, 165).Result;
+
+ Assert.IsNotNull(workItem);
+
+ var updated = client.AddWorkItemComment(project, workItem, project.Members.SingleOrDefault(x => x.AssignName.ToLower().Contains("roy")), "Test Comment").Result;
+
+ Assert.AreEqual(updated.Comment, "Test Comment");
+ }
+
+ [TestMethod]
public void Upload_Work_Item()
{
ITeamFoundationServiceClient client = CreateClient();