aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Ben Shabat <Roy.mail.net@gmail.com>2020-04-10 15:06:42 +0300
committerRoy Ben Shabat <Roy.mail.net@gmail.com>2020-04-10 15:06:42 +0300
commitb4682a3abfe299c19b24752b2fb1ce2477611ec3 (patch)
tree1d7c87eb5c3eba0d4bf7103fa8717ba62faaccc2
parentd03741164872fc4d849407ed877b6ea00220cc67 (diff)
downloadTango-b4682a3abfe299c19b24752b2fb1ce2477611ec3.tar.gz
Tango-b4682a3abfe299c19b24752b2fb1ce2477611ec3.zip
Implemented FSE/PPC Logs.
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Tango.FSE.PPCConsole.csproj8
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModelLocator.cs9
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/LogsViewVM.cs288
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs1
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/LogsView.xaml225
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/LogsView.xaml.cs28
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/MainView.xaml5
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/UpdatesView.xaml2
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/ApplicationLogItemView.xaml4
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/FirmwareLogItemView.xaml (renamed from Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/MachineLogItemView.xaml)8
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/FirmwareLogItemView.xaml.cs (renamed from Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/MachineLogItemView.xaml.cs)4
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/FirmwareLogItemViewVM.cs (renamed from Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/MachineLogItemViewVM.cs)4
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Logging/ILoggingProvider.cs37
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Logging/RemoteLogFileModel.cs128
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Logging/RemoteLogFileStatus.cs19
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj10
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Connection/DefaultMachineProvider.cs5
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Logging/DefaultLoggingProvider.cs89
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Panes/LogViewerPane.xaml12
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Panes/LogViewerPaneVM.cs84
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs2
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/FileSystem/DefaultFileSystemService.cs46
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Shared/Logs/GetLogFilesRequest.cs13
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Shared/Logs/GetLogFilesResponse.cs18
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Shared/Logs/RemoteLogFile.cs17
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Shared/Logs/RemoteLogFileType.cs14
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj4
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/FileSystemItem.cs3
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/FileSystemManager.cs2
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/Network/FileSystemItemDTO.cs2
-rw-r--r--Software/Visual_Studio/Tango.Integration/Logging/EmbeddedLogFileParser.cs7
-rw-r--r--Software/Visual_Studio/Tango.Logging/ApplicationLogFileParser.cs7
-rw-r--r--Software/Visual_Studio/Tango.Logging/ILogFileParser.cs2
-rw-r--r--Software/Visual_Studio/Tango.Logging/LogFile.cs1
-rw-r--r--Software/Visual_Studio/Tango.Logging/LogItemBase.cs8
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Components/BindingProxy.cs31
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Converters/StringToOneLineConverter.cs4
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj3
38 files changed, 1076 insertions, 78 deletions
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Tango.FSE.PPCConsole.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Tango.FSE.PPCConsole.csproj
index 783dfa9fe..287273015 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Tango.FSE.PPCConsole.csproj
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Tango.FSE.PPCConsole.csproj
@@ -113,10 +113,14 @@
<Compile Include="PPCConsoleModule.cs" />
<Compile Include="ViewModels\ConsoleViewVM.cs" />
<Compile Include="ViewModels\FileSystemViewVM.cs" />
+ <Compile Include="ViewModels\LogsViewVM.cs" />
<Compile Include="ViewModels\MainViewVM.cs" />
<Compile Include="ViewModels\MonitoringViewVM.cs" />
<Compile Include="ViewModels\RemoteDesktopViewVM.cs" />
<Compile Include="ViewModels\UpdatesViewVM.cs" />
+ <Compile Include="Views\LogsView.xaml.cs">
+ <DependentUpon>LogsView.xaml</DependentUpon>
+ </Compile>
<Compile Include="Views\UpdatesView.xaml.cs">
<DependentUpon>UpdatesView.xaml</DependentUpon>
</Compile>
@@ -252,6 +256,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
+ <Page Include="Views\LogsView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Views\UpdatesView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModelLocator.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModelLocator.cs
index 4faa72e8e..a3b800b22 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModelLocator.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModelLocator.cs
@@ -18,6 +18,7 @@ namespace Tango.FSE.PPCConsole
TangoIOC.Default.Register<MonitoringViewVM>();
TangoIOC.Default.Register<FileSystemViewVM>();
TangoIOC.Default.Register<UpdatesViewVM>();
+ TangoIOC.Default.Register<LogsViewVM>();
}
public static MainViewVM MainViewVM
@@ -67,5 +68,13 @@ namespace Tango.FSE.PPCConsole
return TangoIOC.Default.GetInstance<UpdatesViewVM>();
}
}
+
+ public static LogsViewVM LogsViewVM
+ {
+ get
+ {
+ return TangoIOC.Default.GetInstance<LogsViewVM>();
+ }
+ }
}
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/LogsViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/LogsViewVM.cs
new file mode 100644
index 000000000..52955e18a
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/LogsViewVM.cs
@@ -0,0 +1,288 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+using Tango.Core;
+using Tango.Core.Commands;
+using Tango.Core.Helpers;
+using Tango.FSE.Common;
+using Tango.FSE.Common.Connection;
+using Tango.FSE.Common.Dialogs;
+using Tango.FSE.Common.FileSystem;
+using Tango.FSE.Common.Logging;
+using Tango.Logging;
+using Tango.PPC.Shared.Logs;
+using Tango.SharedUI.Components;
+using static Tango.SharedUI.Controls.NavigationControl;
+
+namespace Tango.FSE.PPCConsole.ViewModels
+{
+ public class LogsViewVM : FSEViewModel, INavigationViewModel
+ {
+ private bool _loaded;
+
+ private List<RemoteLogFileModel<LogItemBase>> _logFiles;
+ /// <summary>
+ /// Gets or sets the remote log files.
+ /// </summary>
+ public List<RemoteLogFileModel<LogItemBase>> LogFiles
+ {
+ get { return _logFiles; }
+ set { _logFiles = value; RaisePropertyChangedAuto(); }
+ }
+
+ private RemoteLogFileModel<LogItemBase> _selectedLogFile;
+ /// <summary>
+ /// Gets or sets the selected remote log file.
+ /// </summary>
+ public RemoteLogFileModel<LogItemBase> SelectedLogFile
+ {
+ get { return _selectedLogFile; }
+ set { _selectedLogFile = value; RaisePropertyChangedAuto(); OnSelectedLogFileChanged(); }
+ }
+
+ /// <summary>
+ /// Gets or sets the application logs.
+ /// </summary>
+ public ObservableCollection<LogItemBase> ApplicationLogs { get; set; }
+
+ /// <summary>
+ /// Gets or sets the application logs view.
+ /// </summary>
+ public ICollectionView ApplicationLogsView { get; set; }
+
+ /// <summary>
+ /// Gets or sets the selected application logs categories.
+ /// </summary>
+ public SelectedObjectCollection<LogCategory> SelectedApplicationLogsCategories { get; set; }
+
+ private String _applicationLogsFilter;
+ /// <summary>
+ /// Gets or sets the application logs filter.
+ /// </summary>
+ public String ApplicationLogsFilter
+ {
+ get { return _applicationLogsFilter; }
+ set { _applicationLogsFilter = value; RaisePropertyChangedAuto(); ApplicationLogsView.Refresh(); }
+ }
+
+ /// <summary>
+ /// Opens the detailed application log dialog.
+ /// </summary>
+ public RelayCommand<LogItemBase> OpenApplicationLogItemCommand { get; set; }
+
+ /// <summary>
+ /// Exports the selected log file to local disk.
+ /// </summary>
+ public RelayCommand ExportLogFileCommand { get; set; }
+
+ /// <summary>
+ /// Exports all the downloaded log files to disk.
+ /// </summary>
+ public RelayCommand ExportAllDownloadedLogFilesCommand { get; set; }
+
+ /// <summary>
+ /// Downloads all the available log files.
+ /// </summary>
+ public RelayCommand DownloadAllLogFilesCommand { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="LogsViewVM"/> class.
+ /// </summary>
+ public LogsViewVM()
+ {
+ ApplicationLogs = new ObservableCollection<LogItemBase>();
+ ApplicationLogsView = CollectionViewSource.GetDefaultView(ApplicationLogs);
+ ApplicationLogsView.Filter = FilterApplicationLogs;
+ SelectedApplicationLogsCategories = new SelectedObjectCollection<LogCategory>(new ObservableCollection<LogCategory>()
+ {
+ LogCategory.Info,
+ LogCategory.Warning,
+ LogCategory.Error,
+ LogCategory.Critical,
+ }, new ObservableCollection<LogCategory>()
+ {
+ LogCategory.Info,
+ LogCategory.Warning,
+ LogCategory.Error,
+ LogCategory.Critical,
+ });
+
+ SelectedApplicationLogsCategories.SynchedSource.CollectionChanged += (_, __) => ApplicationLogsView.Refresh();
+
+ OpenApplicationLogItemCommand = new RelayCommand<LogItemBase>(OpenApplicationLogItem);
+
+ ExportLogFileCommand = new RelayCommand(ExportSelectedLogFile);
+ ExportAllDownloadedLogFilesCommand = new RelayCommand(ExportAllDownloadedLogFiles);
+ DownloadAllLogFilesCommand = new RelayCommand(DownloadAllLogFiles);
+ }
+
+ public override void OnApplicationStarted()
+ {
+ base.OnApplicationStarted();
+ MachineProvider.MachineConnected += MachineProvider_MachineConnected;
+ }
+
+ private void MachineProvider_MachineConnected(object sender, MachineConnectedEventArgs e)
+ {
+ if (e.DifferentFromPrevious)
+ {
+ _loaded = false;
+
+ if (MachineProvider.ConnectionType.IsRemote() && IsVisible)
+ {
+ LoadLogFiles();
+ }
+ }
+ }
+
+ public override void OnNavigatedTo()
+ {
+ base.OnNavigatedTo();
+
+ if (!_loaded)
+ {
+ LoadLogFiles();
+ }
+ }
+
+ private async void LoadLogFiles()
+ {
+ if (!MachineProvider.ConnectionType.IsRemote() || !IsFree) return;
+
+ try
+ {
+ IsFree = false;
+ var logFiles = await LoggingProvider.GetApplicationLogFiles();
+ LogFiles = logFiles.Select(x =>
+ {
+
+ var model = new RemoteLogFileModel<LogItemBase>(new ApplicationLogFileParser());
+ model.RemoteLogFile = x;
+ model.DownloadCompleted += OnRemoteLogFileDownloadCompleted;
+ return model;
+
+ }).ToList();
+ SelectedLogFile = LogFiles.FirstOrDefault();
+ _loaded = true;
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error loading log files.");
+ }
+ finally
+ {
+ IsFree = true;
+ }
+ }
+
+ private void OnRemoteLogFileDownloadCompleted(object sender, EventArgs e)
+ {
+ if (SelectedLogFile == sender)
+ {
+ OnSelectedLogFileChanged();
+ }
+ }
+
+ private void OnSelectedLogFileChanged()
+ {
+ if (SelectedLogFile == null) return;
+
+ InvokeUI(() =>
+ {
+ ApplicationLogs.Clear();
+ foreach (var logItem in SelectedLogFile.LogItems)
+ {
+ ApplicationLogs.Add(logItem);
+ }
+
+ ApplicationLogsView.Refresh();
+ });
+ }
+
+ private async void OpenApplicationLogItem(LogItemBase logItem)
+ {
+ await NotificationProvider.ShowDialog(new ApplicationLogItemViewVM() { LogItem = logItem });
+ }
+
+ private bool FilterApplicationLogs(object obj)
+ {
+ var log = obj as LogItemBase;
+ return SelectedApplicationLogsCategories.SynchedSource.Contains(log.Category) && (String.IsNullOrWhiteSpace(ApplicationLogsFilter) || log.Message.ToLower().Contains(ApplicationLogsFilter.ToLower()));
+ }
+
+ private async void ExportSelectedLogFile()
+ {
+ if (SelectedLogFile != null && SelectedLogFile.Status == RemoteLogFileStatus.Downloaded)
+ {
+ var result = await StorageProvider.SaveFile("Export Log File", "Application Log Files|*.log", SelectedLogFile.RemoteLogFile.Name, ".log");
+ if (result)
+ {
+ using (NotificationProvider.PushTaskItem("Exporting log file..."))
+ {
+ try
+ {
+ File.Copy(SelectedLogFile.TemporaryFile, result.SelectedItem, true);
+ await NotificationProvider.ShowSuccess("Log file exported successfully.");
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error exporting application log file.");
+ await NotificationProvider.ShowError($"Could not export the log file.\n{ex.FlattenMessage()}");
+ }
+ }
+ }
+ }
+ }
+
+ private async void ExportAllDownloadedLogFiles()
+ {
+ var result = await StorageProvider.SelectFolder("Export Log Files");
+ if (result)
+ {
+ var toExport = LogFiles.Where(x => x.Status == RemoteLogFileStatus.Downloaded).ToList();
+ var count = toExport.Count;
+
+ using (var task = NotificationProvider.PushTaskItem("Exporting log files..."))
+ {
+ foreach (var logFile in toExport.ToList())
+ {
+ try
+ {
+ await Task.Delay(500);
+ File.Copy(logFile.TemporaryFile, Path.Combine(result.SelectedItem, logFile.RemoteLogFile.Name), true);
+ toExport.Remove(logFile);
+ task.UpdateProgress("Exporting log files...", count - toExport.Count, count, false);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error exporting application log file '{logFile.RemoteLogFile.Name}'.");
+ await NotificationProvider.ShowError($"Could not export '{logFile.RemoteLogFile.Name}'.\n{ex.FlattenMessage()}");
+ }
+ }
+ }
+
+ await NotificationProvider.ShowSuccess($"Successfully exported {count - toExport.Count} out of {count} log files.");
+ }
+ }
+
+ private async void DownloadAllLogFiles()
+ {
+ var toDownload = LogFiles.Where(x => x.Status == RemoteLogFileStatus.None);
+ var totalSize = FileHelper.GetFriendlyFileSize(toDownload.Select(x => x.RemoteLogFile.Length).Sum());
+
+ if (await NotificationProvider.ShowWarningQuestion($"Are you sure you wish to download the entire history of log files?\nTotal size: {totalSize}", "DOWNLOAD", "CANCEL"))
+ {
+ foreach (var logFile in toDownload)
+ {
+ logFile.DownloadLogFile();
+ }
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs
index e18a75ef6..f4614ccf1 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs
@@ -20,6 +20,7 @@ namespace Tango.FSE.PPCConsole.ViewModels
MonitoringView,
FileSystemView,
UpdatesView,
+ LogsView,
}
private NavigationView _selectedView;
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/LogsView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/LogsView.xaml
new file mode 100644
index 000000000..81258e971
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/LogsView.xaml
@@ -0,0 +1,225 @@
+<UserControl x:Class="Tango.FSE.PPCConsole.Views.LogsView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:global="clr-namespace:Tango.FSE.PPCConsole"
+ xmlns:helpers="clr-namespace:Tango.SharedUI.Helpers;assembly=Tango.SharedUI"
+ xmlns:vm="clr-namespace:Tango.FSE.PPCConsole.ViewModels"
+ xmlns:components="clr-namespace:Tango.SharedUI.Components;assembly=Tango.SharedUI"
+ xmlns:controls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common"
+ xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:local="clr-namespace:Tango.FSE.PPCConsole.Views"
+ mc:Ignorable="d"
+ d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:LogsViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.LogsViewVM}" x:Name="control">
+
+ <UserControl.Resources>
+
+ <Style x:Key="LogsGridCellStyle" TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}">
+ <Setter Property="BorderThickness" Value="0"/>
+ <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
+ <Setter Property="VerticalContentAlignment" Value="Center"></Setter>
+ </Style>
+
+ <Style x:Key="LogsGridStyle" TargetType="DataGrid" BasedOn="{StaticResource {x:Type DataGrid}}">
+ <Setter Property="Background" Value="Transparent"></Setter>
+ <Setter Property="Foreground" Value="{StaticResource FSE_GrayBrush}"></Setter>
+ <Setter Property="AutoGenerateColumns" Value="False"></Setter>
+ <Setter Property="CanUserAddRows" Value="False"></Setter>
+ <Setter Property="CanUserDeleteRows" Value="False"></Setter>
+ <Setter Property="CanUserReorderColumns" Value="False"></Setter>
+ <Setter Property="CanUserResizeColumns" Value="False"></Setter>
+ <Setter Property="CanUserResizeRows" Value="False"></Setter>
+ <Setter Property="CanUserSortColumns" Value="False"></Setter>
+ <Setter Property="IsReadOnly" Value="True"></Setter>
+ <Setter Property="SelectionMode" Value="Single"></Setter>
+ <Setter Property="SelectionUnit" Value="FullRow"></Setter>
+ <Setter Property="RowHeight" Value="35"></Setter>
+ <Setter Property="HorizontalGridLinesBrush" Value="{StaticResource FSE_PrimaryBackgroundBrush}"></Setter>
+ <Setter Property="HorizontalScrollBarVisibility" Value="Disabled"></Setter>
+ <Setter Property="CellStyle" Value="{StaticResource LogsGridCellStyle}" />
+ </Style>
+ </UserControl.Resources>
+
+ <Grid IsEnabled="{Binding IsFree}">
+ <Grid Margin="0 20 0 0">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="270"/>
+ <ColumnDefinition Width="303*"/>
+ </Grid.ColumnDefinitions>
+
+ <Grid>
+ <Border Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}" BorderBrush="{StaticResource FSE_PrimaryBackgroundLightBrush}" BorderThickness="3" CornerRadius="3" Padding="5 5">
+ <ListBox Background="Transparent" BorderThickness="0" ItemsSource="{Binding LogFiles}" SelectedItem="{Binding SelectedLogFile}">
+ <ListBox.InputBindings>
+ <KeyBinding Key="Return" Command="{Binding SelectedLogFile.DownloadCommand}" />
+ </ListBox.InputBindings>
+ <ListBox.ItemTemplate>
+ <DataTemplate>
+ <DockPanel>
+ <DockPanel.Style>
+ <Style TargetType="DockPanel">
+ <Setter Property="Opacity" Value="0.6"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Status}" Value="Downloaded">
+ <Setter Property="Opacity" Value="1"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </DockPanel.Style>
+ <material:PackIcon Kind="FileDocument" Width="Auto" Height="35" />
+ <StackPanel Margin="5 0 0 0">
+ <TextBlock Text="{Binding RemoteLogFile.DateCreated,Converter={StaticResource DateTimeUtcToLocalDateTime},StringFormat='MM/dd/yyyy HH:mm'}"></TextBlock>
+ <TextBlock Margin="0 5 0 0" Foreground="{StaticResource FSE_GrayBrush}" FontSize="{StaticResource FSE_SmallFontSize}">
+ <Run Text="{Binding RemoteLogFile.Length,Converter={StaticResource ByteArrayToFileSizeConverter}}"></Run>
+ <Run>|</Run>
+ <Run Text="{Binding Duration,Mode=OneWay,StringFormat='hh\\:mm'}"></Run>
+ </TextBlock>
+ </StackPanel>
+ </DockPanel>
+ </DataTemplate>
+ </ListBox.ItemTemplate>
+ </ListBox>
+ </Border>
+ </Grid>
+
+ <Border Grid.Column="1" Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}" BorderBrush="{StaticResource FSE_PrimaryBackgroundLightBrush}" BorderThickness="3" CornerRadius="3" Padding="2" Margin="10 0 0 0">
+ <Grid>
+ <Grid>
+ <DockPanel Margin="10 0 10 10">
+ <Grid DockPanel.Dock="Top" Margin="12 10 0 0" Panel.ZIndex="100">
+ <TextBlock Foreground="{StaticResource FSE_PrimaryAccentBrush}" FontWeight="SemiBold">
+ <Run Text="{Binding SelectedLogFile.RemoteLogFile.DateCreated,Converter={StaticResource DateTimeUtcToLocalDateTime},StringFormat='MM/dd/yyyy HH:mm'}"></Run>
+ <Run>-</Run>
+ <Run Text="{Binding SelectedLogFile.RemoteLogFile.DateModified,Converter={StaticResource DateTimeUtcToLocalDateTime},StringFormat='HH:mm'}"></Run>
+ </TextBlock>
+ <StackPanel Margin="0 0 0 -70" HorizontalAlignment="Right" >
+ <StackPanel Margin="0 30 0 0" Orientation="Horizontal">
+ <ItemsControl VerticalAlignment="Center" ItemsSource="{Binding SelectedApplicationLogsCategories}" Visibility="{Binding ResolutionService.IsHighResolution,Converter={StaticResource BooleanToVisibilityConverter}}">
+ <ItemsControl.ItemsPanel>
+ <ItemsPanelTemplate>
+ <StackPanel Orientation="Horizontal" />
+ </ItemsPanelTemplate>
+ </ItemsControl.ItemsPanel>
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <StackPanel Orientation="Horizontal" Margin="10 0 0 0">
+ <CheckBox FocusVisualStyle="{x:Null}" IsChecked="{Binding IsSelected,Delay=200}" VerticalAlignment="Center">
+ <CheckBox.Content>
+ <TextBlock Text="{Binding Data}" VerticalAlignment="Center"></TextBlock>
+ </CheckBox.Content>
+ </CheckBox>
+ </StackPanel>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+
+ <DockPanel Margin="20 0 0 0" VerticalAlignment="Center">
+ <material:PackIcon Kind="Search" VerticalAlignment="Center" Width="18" Height="18" />
+ <TextBox Margin="5 0 0 0" Style="{StaticResource FSE_Rounded_Corners_TextBox}" Background="{StaticResource FSE_PrimaryBackgroundBrush}" FontSize="{StaticResource FSE_SmallFontSize}" material:HintAssist.Hint="filter" material:TextFieldAssist.RippleOnFocusEnabled="True" Text="{Binding ApplicationLogsFilter,UpdateSourceTrigger=PropertyChanged,Delay=1000}" Width="200"/>
+ </DockPanel>
+ </StackPanel>
+ </StackPanel>
+ </Grid>
+
+ <DataGrid Margin="0 5 0 0" Style="{StaticResource LogsGridStyle}" ItemsSource="{Binding ApplicationLogs}" CellStyle="{StaticResource LogsGridCellStyle}" helpers:DataGridHelper.DoubleClickCommand="{Binding OpenApplicationLogItemCommand}">
+ <DataGrid.Resources>
+ <components:BindingProxy x:Key="proxy" Data="{Binding}" />
+ </DataGrid.Resources>
+ <DataGrid.Columns>
+ <DataGridTemplateColumn Header="#" Width="40" CellTemplate="{StaticResource FSE_LogIcon_Cell}"/>
+ <DataGridTextColumn Header="DATE TIME" Binding="{Binding TimeStamp,StringFormat='HH:mm:ss.ff'}" Width="100" />
+ <DataGridTextColumn Visibility="{Binding Source={StaticResource proxy},Path=Data.ResolutionService.IsHighResolution,Converter={StaticResource BooleanToVisibilityConverter}}" Header="SERVICE" Binding="{Binding ClassName}" Width="200" />
+ <DataGridTemplateColumn Header="MESSAGE" Width="1*" >
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <TextBlock TextWrapping="NoWrap" Text="{Binding Message,Converter={StaticResource StringToOneLineConverter},ConverterParameter='120'}"></TextBlock>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ </DataGrid.Columns>
+ </DataGrid>
+ </DockPanel>
+ </Grid>
+
+ <Grid Background="{StaticResource FSE_SemiTransparentBrush}">
+ <Grid.Style>
+ <Style TargetType="Grid">
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding SelectedLogFile.Status}" Value="Downloaded">
+ <Setter Property="Visibility" Value="Hidden"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Grid.Style>
+
+ <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
+ <StackPanel.Style>
+ <Style TargetType="StackPanel">
+ <Setter Property="Visibility" Value="Hidden"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding SelectedLogFile.Status}" Value="None">
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </StackPanel.Style>
+ <material:PackIcon Kind="FileDocument" Width="100" Height="100" HorizontalAlignment="Center" />
+ <TextBlock Margin="0 20 0 0">Download this log file from the remote machine in order to display its content</TextBlock>
+ <controls:TextIconButton Style="{StaticResource FSE_TextIconButton_Dark}" Margin="0 100 0 0" Height="45" Icon="Download" HorizontalAlignment="Center" Width="180" Command="{Binding SelectedLogFile.DownloadCommand}">DOWNLOAD</controls:TextIconButton>
+ </StackPanel>
+
+ <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
+ <StackPanel.Style>
+ <Style TargetType="StackPanel">
+ <Setter Property="Visibility" Value="Hidden"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding SelectedLogFile.Status}" Value="Failed">
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </StackPanel.Style>
+ <material:PackIcon Kind="AlertOutline" Width="100" Height="100" HorizontalAlignment="Center" Foreground="{StaticResource FSE_ErrorBrush}" />
+ <TextBlock Margin="0 20 0 0">Error occurred while trying to download this log file</TextBlock>
+ <controls:TextIconButton Style="{StaticResource FSE_TextIconButton_Dark}" Margin="0 100 0 0" Height="45" Icon="Download" HorizontalAlignment="Center" Width="180" Command="{Binding SelectedLogFile.DownloadCommand}">TRY AGAIN</controls:TextIconButton>
+ </StackPanel>
+
+ <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
+ <StackPanel.Style>
+ <Style TargetType="StackPanel">
+ <Setter Property="Visibility" Value="Hidden"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding SelectedLogFile.Status}" Value="Downloading">
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </StackPanel.Style>
+ <material:PackIcon Kind="FileDownload" Width="100" Height="100" HorizontalAlignment="Center" />
+ <TextBlock Margin="0 20 0 0" HorizontalAlignment="Center">Downloading log file, please wait...</TextBlock>
+ <ProgressBar Margin="0 140 0 0" Width="600" Height="5" Minimum="0" Maximum="{Binding SelectedLogFile.Handler.Length}" Value="{Binding SelectedLogFile.Handler.Position}"></ProgressBar>
+ </StackPanel>
+ </Grid>
+
+ <StackPanel Margin="0 0 40 20" HorizontalAlignment="Right" VerticalAlignment="Bottom">
+ <material:PopupBox PopupMode="Click" Style="{StaticResource MaterialDesignMultiFloatingActionPopupBox}" PlacementMode="TopAndAlignCentres" FocusVisualStyle="{x:Null}">
+ <StackPanel>
+ <Button ToolTip="Download all log files" Command="{Binding DownloadAllLogFilesCommand}">
+ <material:PackIcon Kind="DownloadMultiple" />
+ </Button>
+ <Button ToolTip="Export all downloaded log files" Command="{Binding ExportAllDownloadedLogFilesCommand}">
+ <material:PackIcon Kind="DatabaseExport" />
+ </Button>
+ <Button ToolTip="Export selected log file" Command="{Binding ExportLogFileCommand}">
+ <material:PackIcon Kind="FileExportOutline" />
+ </Button>
+ </StackPanel>
+ </material:PopupBox>
+ </StackPanel>
+ </Grid>
+ </Border>
+ </Grid>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/LogsView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/LogsView.xaml.cs
new file mode 100644
index 000000000..d08f18326
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/LogsView.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.FSE.PPCConsole.Views
+{
+ /// <summary>
+ /// Interaction logic for LogsView.xaml
+ /// </summary>
+ public partial class LogsView : UserControl
+ {
+ public LogsView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/MainView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/MainView.xaml
index 1efc0516f..b8932be95 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/MainView.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/MainView.xaml
@@ -29,19 +29,20 @@
</Style.Triggers>
</Style>
</Grid.Style>
- <commonControls:FSETabControl TabsWidth="900" x:Name="tabs" SelectedObject="{Binding SelectedView,Mode=TwoWay}">
+ <commonControls:FSETabControl TabsWidth="1000" x:Name="tabs" SelectedObject="{Binding SelectedView,Mode=TwoWay}">
<local:MonitoringView Tag="MONITORING" />
<local:RemoteDesktopView Tag="REMOTE DESKTOP" />
<local:ConsoleView Tag="COMMAND PROMPT" />
<local:FileSystemView Tag="FILE SYSTEM" />
<local:UpdatesView Tag="UPDATES" />
+ <local:LogsView Tag="LOGS" />
</commonControls:FSETabControl>
<TextBlock resolution:ResolutionHelper.MinWidth="1500" Margin="10 0 0 0" FontFamily="{StaticResource hand}" FontSize="{StaticResource FSE_ModuleHeaderFontSize}" Foreground="{StaticResource FSE_PrimaryAccentDarkBrush}" VerticalAlignment="Top" HorizontalAlignment="Left" Text="{Binding ElementName=tabs,Path=SelectedElement.Tag,Converter={StaticResource StringToTitleCaseConverter}}"></TextBlock>
</Grid>
</Grid>
- <Grid Background="#DE202020" Visibility="{Binding MachineProvider.IsPPCAvailable,Converter={StaticResource BooleanToVisibilityInverseConverter}}">
+ <Grid Background="#DE202020" Visibility="{Binding MachineProvider.IsPPCAvailable,Converter={StaticResource BooleanToVisibilityInverseConverter},FallbackValue='Visible',TargetNullValue='Visible'}">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<material:PackIcon HorizontalAlignment="Center" Kind="AlertOutline" Width="100" Height="100" />
<TextBlock Margin="0 20 0 0" HorizontalAlignment="Center" FontSize="{StaticResource FSE_LargeFontSize}">
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/UpdatesView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/UpdatesView.xaml
index 037fa6d96..8a8e6546e 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/UpdatesView.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/UpdatesView.xaml
@@ -60,7 +60,7 @@
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
- <DataGridTextColumn Header="STARTED" Binding="{Binding StartDate,Converter={StaticResource DateTimeUTCToShortDateTimeConverter}}" Width="Auto" />
+ <DataGridTextColumn Header="STARTED" Binding="{Binding StartDate,Converter={StaticResource DateTimeUTCToShortDateTimeConverter}}" Width="120" />
<DataGridTextColumn Header="APPLICATION" Binding="{Binding ApplicationVersion}" Width="Auto" />
<DataGridTextColumn Header="FIRMWARE" Binding="{Binding FirmwareVersion}" Width="Auto" />
<DataGridTextColumn Header="ENDED" Binding="{Binding EndDate,TargetNullValue='Never',FallbackValue='Never',Converter={StaticResource DateTimeUTCToShortDateTimeConverter}}" Width="Auto" />
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/ApplicationLogItemView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/ApplicationLogItemView.xaml
index 844bdc992..6abda9b6d 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/ApplicationLogItemView.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/ApplicationLogItemView.xaml
@@ -11,14 +11,14 @@
<DockPanel Margin="10">
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
- <material:PackIcon Width="42" Height="42" VerticalAlignment="Center" Style="{StaticResource FSE_LogIcon}" />
+ <material:PackIcon DataContext="{Binding LogItem}" Width="42" Height="42" VerticalAlignment="Center" Style="{StaticResource FSE_LogIcon}" />
<TextBlock VerticalAlignment="Center" Text="{Binding LogItem.Message}" TextWrapping="NoWrap" Height="22" TextTrimming="CharacterEllipsis" Width="700" Margin="10 0 0 0" FontSize="{StaticResource FSE_LargeFontSize}"></TextBlock>
</StackPanel>
<Grid Margin="0 10 0 0" DockPanel.Dock="Top">
<controls:TableGrid RowHeight="30">
<TextBlock Text="Time Stamp:" FontWeight="SemiBold" />
- <TextBlock Text="{Binding LogItem.TimeStamp,Converter={StaticResource DateTimeUTCToStringConverter},ConverterParameter='MM/dd/yyyy HH:mm:ss.fff'}"></TextBlock>
+ <TextBlock Text="{Binding LogItem.TimeStamp,StringFormat='HH:mm:ss.fff'}"></TextBlock>
<TextBlock Text="Category:" FontWeight="SemiBold" />
<TextBlock Text="{Binding LogItem.Category}"></TextBlock>
<TextBlock Text="File:" FontWeight="SemiBold" />
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/MachineLogItemView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/FirmwareLogItemView.xaml
index 776e6d893..49d67f205 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/MachineLogItemView.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/FirmwareLogItemView.xaml
@@ -1,4 +1,4 @@
-<UserControl x:Class="Tango.FSE.Common.Dialogs.MachineLogItemView"
+<UserControl x:Class="Tango.FSE.Common.Dialogs.FirmwareLogItemView"
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"
@@ -7,18 +7,18 @@
xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
xmlns:local="clr-namespace:Tango.FSE.Common.Dialogs"
mc:Ignorable="d"
- Width="800" Height="500" d:DataContext="{d:DesignInstance Type=local:MachineLogItemViewVM, IsDesignTimeCreatable=False}" Background="{StaticResource FSE_PrimaryBackgroundLightBrush}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}">
+ Width="800" Height="500" d:DataContext="{d:DesignInstance Type=local:FirmwareLogItemViewVM, IsDesignTimeCreatable=False}" Background="{StaticResource FSE_PrimaryBackgroundLightBrush}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}">
<DockPanel Margin="10">
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
- <material:PackIcon Width="42" Height="42" VerticalAlignment="Center" Style="{StaticResource FSE_LogIcon}" />
+ <material:PackIcon DataContext="{Binding LogItem}" Width="42" Height="42" VerticalAlignment="Center" Style="{StaticResource FSE_LogIcon}" />
<TextBlock VerticalAlignment="Center" Text="{Binding LogItem.Message}" TextWrapping="NoWrap" Height="22" TextTrimming="CharacterEllipsis" Width="700" Margin="10 0 0 0" FontSize="{StaticResource FSE_LargeFontSize}"></TextBlock>
</StackPanel>
<Grid Margin="0 10 0 0" DockPanel.Dock="Top">
<controls:TableGrid RowHeight="30">
<TextBlock Text="Time Stamp:" FontWeight="SemiBold" />
- <TextBlock Text="{Binding LogItem.TimeStamp,Converter={StaticResource DateTimeUTCToStringConverter},ConverterParameter='MM/dd/yyyy HH:mm:ss.fff'}"></TextBlock>
+ <TextBlock Text="{Binding LogItem.TimeStamp,StringFormat='HH:mm:ss.fff'}"></TextBlock>
<TextBlock Text="Category:" FontWeight="SemiBold" />
<TextBlock Text="{Binding LogItem.Category}"></TextBlock>
<TextBlock Text="File:" FontWeight="SemiBold" />
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/MachineLogItemView.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/FirmwareLogItemView.xaml.cs
index 97103c34e..6e7556c40 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/MachineLogItemView.xaml.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/FirmwareLogItemView.xaml.cs
@@ -18,9 +18,9 @@ namespace Tango.FSE.Common.Dialogs
/// <summary>
/// Interaction logic for ApplicationLogItemView.xaml
/// </summary>
- public partial class MachineLogItemView : UserControl
+ public partial class FirmwareLogItemView : UserControl
{
- public MachineLogItemView()
+ public FirmwareLogItemView()
{
InitializeComponent();
}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/MachineLogItemViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/FirmwareLogItemViewVM.cs
index 2ac7a7b3a..1ee76e381 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/MachineLogItemViewVM.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Dialogs/FirmwareLogItemViewVM.cs
@@ -7,11 +7,11 @@ using Tango.Integration.Logging;
namespace Tango.FSE.Common.Dialogs
{
- public class MachineLogItemViewVM : FSEDialogViewVM
+ public class FirmwareLogItemViewVM : FSEDialogViewVM
{
public EmbeddedLogItem LogItem { get; set; }
- public MachineLogItemViewVM()
+ public FirmwareLogItemViewVM()
{
CanClose = false;
OKText = "CLOSE";
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Logging/ILoggingProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Logging/ILoggingProvider.cs
index d49f8b21d..68c288e60 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Logging/ILoggingProvider.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Logging/ILoggingProvider.cs
@@ -1,10 +1,13 @@
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using Tango.FSE.Common.FileSystem;
using Tango.Integration.Logging;
using Tango.Logging;
+using Tango.PPC.Shared.Logs;
namespace Tango.FSE.Common.Logging
{
@@ -14,13 +17,43 @@ namespace Tango.FSE.Common.Logging
public interface ILoggingProvider
{
/// <summary>
+ /// Gets the last retrieved history of the application log files.
+ /// </summary>
+ ObservableCollection<RemoteLogFile> ApplicationLogFiles { get; }
+
+ /// <summary>
+ /// Gets the last retrieved history of the embedded firmware log files.
+ /// </summary>
+ ObservableCollection<RemoteLogFile> FirmwareLogFiles { get; }
+
+ /// <summary>
+ /// Gets the history of application log files.
+ /// </summary>
+ /// <returns></returns>
+ Task<List<RemoteLogFile>> GetApplicationLogFiles();
+
+ /// <summary>
+ /// Gets the history of the embedded firmware log files.
+ /// </summary>
+ /// <returns></returns>
+ Task<List<RemoteLogFile>> GetFirmwareLogFiles();
+
+ /// <summary>
+ /// Downloads the specified remote log file.
+ /// </summary>
+ /// <param name="logFile">The log file.</param>
+ /// <param name="targetFolder">Target folder.</param>
+ /// <returns></returns>
+ Task<FileSystemHandler> DownloadLogFile(RemoteLogFile logFile, String targetFolder);
+
+ /// <summary>
/// Occurs when a new PPC application log is available.
/// </summary>
event EventHandler<LogItemBase> ApplicationLogAvailable;
/// <summary>
- /// Occurs when a new embedded log is available.
+ /// Occurs when a new embedded firmware log is available.
/// </summary>
- event EventHandler<EmbeddedLogItem> EmbeddedLogAvailable;
+ event EventHandler<EmbeddedLogItem> FirmwareLogAvailable;
}
}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Logging/RemoteLogFileModel.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Logging/RemoteLogFileModel.cs
new file mode 100644
index 000000000..cf71ed270
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Logging/RemoteLogFileModel.cs
@@ -0,0 +1,128 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+using Tango.Core;
+using Tango.Core.Commands;
+using Tango.Core.DI;
+using Tango.FSE.Common.FileSystem;
+using Tango.Logging;
+using Tango.PPC.Shared.Logs;
+using Tango.SharedUI.Components;
+
+namespace Tango.FSE.Common.Logging
+{
+ /// <summary>
+ /// Represents a remote log file model.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <seealso cref="Tango.Core.ExtendedObject" />
+ public class RemoteLogFileModel<T> : ExtendedObject where T : LogItemBase
+ {
+ private ILogFileParser<T> _parser;
+
+ /// <summary>
+ /// Occurs when the remote log file has downloaded successfully.
+ /// </summary>
+ public event EventHandler DownloadCompleted;
+
+ [TangoInject]
+ private ILoggingProvider LoggingProvider { get; set; }
+
+ /// <summary>
+ /// Gets or sets the remote log file.
+ /// </summary>
+ public RemoteLogFile RemoteLogFile { get; set; }
+
+ /// <summary>
+ /// Gets the duration of the remote log file.
+ /// </summary>
+ public TimeSpan Duration
+ {
+ get { return RemoteLogFile.DateModified - RemoteLogFile.DateCreated; }
+ }
+
+ private RemoteLogFileStatus _status;
+ /// <summary>
+ /// Gets or sets the remote log file status.
+ /// </summary>
+ public RemoteLogFileStatus Status
+ {
+ get { return _status; }
+ set { _status = value; RaisePropertyChangedAuto(); }
+ }
+
+ private FileSystemHandler _handler;
+ /// <summary>
+ /// Gets or sets the remote log file download handler.
+ /// </summary>
+ public FileSystemHandler Handler
+ {
+ get { return _handler; }
+ set { _handler = value; RaisePropertyChangedAuto(); }
+ }
+
+ /// <summary>
+ /// Gets or sets the temporary file (where the actual log file is stored locally).
+ /// </summary>
+ public String TemporaryFile { get; set; }
+
+ private ObservableCollection<LogItemBase> _logItems;
+ /// <summary>
+ /// Gets or sets the log items.
+ /// </summary>
+ public ObservableCollection<LogItemBase> LogItems
+ {
+ get { return _logItems; }
+ set { _logItems = value; RaisePropertyChangedAuto(); }
+ }
+
+ /// <summary>
+ /// Gets or sets the download command.
+ /// </summary>
+ public RelayCommand DownloadCommand { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="RemoteLogFileModel{T}"/> class.
+ /// </summary>
+ /// <param name="parser">The parser.</param>
+ public RemoteLogFileModel(ILogFileParser<T> parser)
+ {
+ TangoIOC.Default.Inject(this);
+ _parser = parser;
+ LogItems = new ObservableCollection<LogItemBase>();
+ DownloadCommand = new RelayCommand(DownloadLogFile);
+ }
+
+ /// <summary>
+ /// Downloads the log file.
+ /// </summary>
+ public async void DownloadLogFile()
+ {
+ if (Status == RemoteLogFileStatus.None || Status == RemoteLogFileStatus.Failed)
+ {
+ Status = RemoteLogFileStatus.Downloading;
+ String tempLogFile = TemporaryManager.CreateImaginaryFile(".log");
+ Handler = await LoggingProvider.DownloadLogFile(RemoteLogFile, tempLogFile);
+ Handler.StatusChanged += (x, status) =>
+ {
+ if (status == FileSystemHandlerStatus.Completed)
+ {
+ TemporaryFile = tempLogFile;
+ LogItems = new ObservableCollection<LogItemBase>(_parser.Parse(tempLogFile, RemoteLogFile.DateCreated.ToLocalTime()));
+ Status = RemoteLogFileStatus.Downloaded;
+ DownloadCompleted?.Invoke(this, new EventArgs());
+ }
+ else if (status == FileSystemHandlerStatus.Failed)
+ {
+ Status = RemoteLogFileStatus.Failed;
+ }
+ };
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Logging/RemoteLogFileStatus.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Logging/RemoteLogFileStatus.cs
new file mode 100644
index 000000000..25f3f4eac
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Logging/RemoteLogFileStatus.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Common.Logging
+{
+ /// <summary>
+ /// Represents the remote log file statuses.
+ /// </summary>
+ public enum RemoteLogFileStatus
+ {
+ None,
+ Downloading,
+ Downloaded,
+ Failed,
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj b/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj
index 7134dbcbb..1581bd25b 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj
@@ -108,14 +108,14 @@
<Compile Include="Diagnostics\DiagnosticsFrameReceivedEventArgs.cs" />
<Compile Include="Diagnostics\DiagnosticsThrottlingMode.cs" />
<Compile Include="Diagnostics\IDiagnosticsProvider.cs" />
- <Compile Include="Dialogs\MachineLogItemView.xaml.cs">
- <DependentUpon>MachineLogItemView.xaml</DependentUpon>
+ <Compile Include="Dialogs\FirmwareLogItemView.xaml.cs">
+ <DependentUpon>FirmwareLogItemView.xaml</DependentUpon>
</Compile>
<Compile Include="Dialogs\ApplicationLogItemView.xaml.cs">
<DependentUpon>ApplicationLogItemView.xaml</DependentUpon>
</Compile>
<Compile Include="Dialogs\ApplicationLogItemViewVM.cs" />
- <Compile Include="Dialogs\MachineLogItemViewVM.cs" />
+ <Compile Include="Dialogs\FirmwareLogItemViewVM.cs" />
<Compile Include="EventTriggerActions\SetterAction.cs" />
<Compile Include="ExtensionMethods\IExternalBridgeClientExtensions.cs" />
<Compile Include="ExtensionMethods\ViewModelExtensionMethods.cs" />
@@ -132,6 +132,8 @@
<Compile Include="Helpers\DesignModeHelper.cs" />
<Compile Include="Helpers\EncryptionHelper.cs" />
<Compile Include="Logging\ILoggingProvider.cs" />
+ <Compile Include="Logging\RemoteLogFileModel.cs" />
+ <Compile Include="Logging\RemoteLogFileStatus.cs" />
<Compile Include="Modules\IFSEModuleLoader.cs" />
<Compile Include="Navigation\NavigationMenuItem.cs" />
<Compile Include="Notifications\AppBarItem.cs" />
@@ -194,7 +196,7 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
- <Page Include="Dialogs\MachineLogItemView.xaml">
+ <Page Include="Dialogs\FirmwareLogItemView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Connection/DefaultMachineProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Connection/DefaultMachineProvider.cs
index 3a43e71f0..4837fd100 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Connection/DefaultMachineProvider.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Connection/DefaultMachineProvider.cs
@@ -457,11 +457,12 @@ namespace Tango.FSE.UI.Connection
MachineOperator.RequestTimeout = TimeSpan.FromSeconds(5);
MachineOperator.ContinuousRequestTimeout = TimeSpan.FromSeconds(5);
- if (MachineOperator is ExternalBridgeTcpClient)
+ if (ConnectionType.IsRemote())
{
- ExternalBridgeTcpClient tcpClient = MachineOperator as ExternalBridgeTcpClient;
+ ExternalBridgeTcpClient tcpClient = MachineOperator.As<ExternalBridgeTcpClient>();
tcpClient.EnableApplicationLogs = true;
tcpClient.InjectApplicationLogsToDefaultLogManager = false;
+ tcpClient.LogEmbeddedDebuggingToFile = false;
}
}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Logging/DefaultLoggingProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Logging/DefaultLoggingProvider.cs
index b3a2d4051..4570589b6 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Logging/DefaultLoggingProvider.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Logging/DefaultLoggingProvider.cs
@@ -1,13 +1,19 @@
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using Tango.Core;
+using Tango.FileSystem;
using Tango.FSE.Common.Connection;
+using Tango.FSE.Common.FileSystem;
using Tango.FSE.Common.Logging;
using Tango.Integration.ExternalBridge;
using Tango.Integration.Logging;
using Tango.Logging;
+using Tango.PPC.Shared.Logs;
namespace Tango.FSE.UI.Logging
{
@@ -15,8 +21,11 @@ namespace Tango.FSE.UI.Logging
/// Represents the <see cref="ILoggingProvider"/> default implementation.
/// </summary>
/// <seealso cref="Tango.FSE.Common.Logging.ILoggingProvider" />
- public class DefaultLoggingProvider : ILoggingProvider
+ public class DefaultLoggingProvider : ExtendedObject, ILoggingProvider
{
+ private IFileSystemProvider _fileSystemProvider;
+ private IMachineProvider _machineProvider;
+
/// <summary>
/// Occurs when a new PPC application log is available.
/// </summary>
@@ -25,14 +34,30 @@ namespace Tango.FSE.UI.Logging
/// <summary>
/// Occurs when a new embedded log is available.
/// </summary>
- public event EventHandler<EmbeddedLogItem> EmbeddedLogAvailable;
+ public event EventHandler<EmbeddedLogItem> FirmwareLogAvailable;
+
+ /// <summary>
+ /// Gets the last retrieved history of the application log files.
+ /// </summary>
+ public ObservableCollection<RemoteLogFile> ApplicationLogFiles { get; private set; }
+
+ /// <summary>
+ /// Gets the last retrieved history of the embedded firmware log files.
+ /// </summary>
+ public ObservableCollection<RemoteLogFile> FirmwareLogFiles { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="DefaultLoggingProvider"/> class.
/// </summary>
/// <param name="machineProvider">The machine provider.</param>
- public DefaultLoggingProvider(IMachineProvider machineProvider)
+ public DefaultLoggingProvider(IMachineProvider machineProvider, IFileSystemProvider fileSystemProvider)
{
+ ApplicationLogFiles = new ObservableCollection<RemoteLogFile>();
+ FirmwareLogFiles = new ObservableCollection<RemoteLogFile>();
+
+ _machineProvider = machineProvider;
+ _fileSystemProvider = fileSystemProvider;
+
if (machineProvider.MachineOperator is ExternalBridgeTcpClient)
{
(machineProvider.MachineOperator as ExternalBridgeTcpClient).ApplicationLogAvailable += DefaultLoggingProvider_ApplicationLogAvailable;
@@ -41,6 +66,62 @@ namespace Tango.FSE.UI.Logging
machineProvider.MachineOperator.DebugLogAvailable += MachineOperator_DebugLogAvailable;
}
+ /// <summary>
+ /// Gets the history of application log files.
+ /// </summary>
+ /// <returns></returns>
+ public async Task<List<RemoteLogFile>> GetApplicationLogFiles()
+ {
+ var response = await _machineProvider.MachineOperator.SendGenericRequest<GetLogFilesRequest, GetLogFilesResponse>(new GetLogFilesRequest() { LogFileType = RemoteLogFileType.Application });
+
+ ApplicationLogFiles.Clear();
+
+ foreach (var item in response.LogFiles)
+ {
+ ApplicationLogFiles.Add(item);
+ }
+
+ return response.LogFiles;
+ }
+
+ /// <summary>
+ /// Gets the history of the embedded firmware log files.
+ /// </summary>
+ /// <returns></returns>
+ public async Task<List<RemoteLogFile>> GetFirmwareLogFiles()
+ {
+ var response = await _machineProvider.MachineOperator.SendGenericRequest<GetLogFilesRequest, GetLogFilesResponse>(new GetLogFilesRequest() { LogFileType = RemoteLogFileType.Firmware });
+
+ FirmwareLogFiles.Clear();
+
+ foreach (var item in response.LogFiles)
+ {
+ FirmwareLogFiles.Add(item);
+ }
+
+ return response.LogFiles;
+ }
+
+ /// <summary>
+ /// Downloads the specified remote log file.
+ /// </summary>
+ /// <param name="logFile">The log file.</param>
+ /// <param name="targetFolder">Target local folder.</param>
+ /// <returns></returns>
+ public async Task<FileSystemHandler> DownloadLogFile(RemoteLogFile logFile, String targetFolder)
+ {
+ var tempFolder = TemporaryManager.CreateFolder();
+ var handler = await _fileSystemProvider.Download(new FileItem() { Path = logFile.Path }, tempFolder);
+ handler.StatusChanged += (x, status) =>
+ {
+ if (status == FileSystemHandlerStatus.Completed)
+ {
+ File.Move(Path.Combine(tempFolder, logFile.Name), targetFolder);
+ }
+ };
+ return handler;
+ }
+
private void DefaultLoggingProvider_ApplicationLogAvailable(object sender, LogItemBase log)
{
ApplicationLogAvailable?.Invoke(this, log);
@@ -48,7 +129,7 @@ namespace Tango.FSE.UI.Logging
private void MachineOperator_DebugLogAvailable(object sender, PMR.Debugging.StartDebugLogResponse log)
{
- EmbeddedLogAvailable?.Invoke(this, new EmbeddedLogItem(log) { TimeStamp = DateTime.Now});
+ FirmwareLogAvailable?.Invoke(this, new EmbeddedLogItem(log) { TimeStamp = DateTime.Now });
}
}
}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Panes/LogViewerPane.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Panes/LogViewerPane.xaml
index d3ece6db1..50faea56c 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Panes/LogViewerPane.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Panes/LogViewerPane.xaml
@@ -97,14 +97,14 @@
<DockPanel Grid.Column="1" Margin="10">
<Grid DockPanel.Dock="Top" Margin="55 5 0 0" Panel.ZIndex="100">
- <TextBlock Foreground="{StaticResource FSE_PrimaryAccentBrush}" FontWeight="SemiBold">MACHINE LOGS</TextBlock>
+ <TextBlock Foreground="{StaticResource FSE_PrimaryAccentBrush}" FontWeight="SemiBold">FIRMWARE LOGS</TextBlock>
<StackPanel Margin="0 0 0 -70" HorizontalAlignment="Right" >
<StackPanel Margin="8 0 0 0" HorizontalAlignment="Left" Orientation="Horizontal">
- <controls:ToggleIconButton ToolTip="Pause/Resume machine logs" CheckedIcon="Play" UncheckedIcon="Pause" Width="24" Height="24" IsChecked="{Binding MachineLogsPaused}" />
- <controls:IconButton Icon="CircleArrows" ToolTip="Clear machine logs" Width="24" Height="24" Command="{Binding ClearMachineLogsCommand}" />
+ <controls:ToggleIconButton ToolTip="Pause/Resume firmware logs" CheckedIcon="Play" UncheckedIcon="Pause" Width="24" Height="24" IsChecked="{Binding FirmwareLogsPaused}" />
+ <controls:IconButton Icon="CircleArrows" ToolTip="Clear firmware logs" Width="24" Height="24" Command="{Binding ClearFirmwareLogsCommand}" />
</StackPanel>
<StackPanel Margin="0 8 0 0" Orientation="Horizontal">
- <ItemsControl VerticalAlignment="Center" ItemsSource="{Binding SelectedMachineLogsCategories}" Visibility="{Binding ResolutionService.IsHighResolution,Converter={StaticResource BooleanToVisibilityConverter}}">
+ <ItemsControl VerticalAlignment="Center" ItemsSource="{Binding SelectedFirmwareLogsCategories}" Visibility="{Binding ResolutionService.IsHighResolution,Converter={StaticResource BooleanToVisibilityConverter}}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
@@ -125,13 +125,13 @@
<DockPanel Margin="20 0 0 0" VerticalAlignment="Center">
<material:PackIcon Kind="Search" VerticalAlignment="Center" Width="18" Height="18" />
- <TextBox Margin="5 0 0 0" Style="{StaticResource FSE_Rounded_Corners_TextBox}" Background="{StaticResource FSE_PrimaryBackgroundBrush}" FontSize="{StaticResource FSE_SmallFontSize}" material:HintAssist.Hint="filter" material:TextFieldAssist.RippleOnFocusEnabled="True" Text="{Binding MachineLogsFilter,UpdateSourceTrigger=PropertyChanged,Delay=1000}" Width="200"/>
+ <TextBox Margin="5 0 0 0" Style="{StaticResource FSE_Rounded_Corners_TextBox}" Background="{StaticResource FSE_PrimaryBackgroundBrush}" FontSize="{StaticResource FSE_SmallFontSize}" material:HintAssist.Hint="filter" material:TextFieldAssist.RippleOnFocusEnabled="True" Text="{Binding FirmwareLogsFilter,UpdateSourceTrigger=PropertyChanged,Delay=1000}" Width="200"/>
</DockPanel>
</StackPanel>
</StackPanel>
</Grid>
- <DataGrid Margin="0 5 0 0" Style="{StaticResource LogsGridStyle}" ItemsSource="{Binding MachineLogs}" CellStyle="{StaticResource LogsGridCellStyle}" helpers:DataGridHelper.DoubleClickCommand="{Binding OpenMachineLogItemCommand}">
+ <DataGrid Margin="0 5 0 0" Style="{StaticResource LogsGridStyle}" ItemsSource="{Binding FirmwareLogs}" CellStyle="{StaticResource LogsGridCellStyle}" helpers:DataGridHelper.DoubleClickCommand="{Binding OpenFirmareLogItemCommand}">
<DataGrid.Columns>
<DataGridTemplateColumn Header="#" Width="40" CellTemplate="{StaticResource FSE_LogIcon_Cell}"/>
<DataGridTextColumn Header="DATE TIME" Binding="{Binding TimeStamp,StringFormat='HH:mm:ss.ff'}" Width="100" />
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Panes/LogViewerPaneVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Panes/LogViewerPaneVM.cs
index 1a4083f28..cb0ea0229 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Panes/LogViewerPaneVM.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Panes/LogViewerPaneVM.cs
@@ -23,7 +23,7 @@ namespace Tango.FSE.UI.Panes
public class LogViewerPaneVM : FSEViewModel
{
private List<LogItemBase> _pausedApplicationLogs;
- private List<EmbeddedLogItem> _pausedMachineLogs;
+ private List<EmbeddedLogItem> _pausedFirmwareLogs;
/// <summary>
/// Gets or sets the application logs.
@@ -31,9 +31,9 @@ namespace Tango.FSE.UI.Panes
public ObservableCollection<LogItemBase> ApplicationLogs { get; set; }
/// <summary>
- /// Gets or sets the machine logs.
+ /// Gets or sets the firmware logs.
/// </summary>
- public ObservableCollection<EmbeddedLogItem> MachineLogs { get; set; }
+ public ObservableCollection<EmbeddedLogItem> FirmwareLogs { get; set; }
/// <summary>
/// Gets or sets the application logs view.
@@ -41,9 +41,9 @@ namespace Tango.FSE.UI.Panes
public ICollectionView ApplicationLogsView { get; set; }
/// <summary>
- /// Gets or sets the machine logs view.
+ /// Gets or sets the firmware logs view.
/// </summary>
- public ICollectionView MachineLogsView { get; set; }
+ public ICollectionView FirmwareLogsView { get; set; }
/// <summary>
/// Gets or sets the selected application logs categories.
@@ -51,9 +51,9 @@ namespace Tango.FSE.UI.Panes
public SelectedObjectCollection<LogCategory> SelectedApplicationLogsCategories { get; set; }
/// <summary>
- /// Gets or sets the selected machine logs categories.
+ /// Gets or sets the selected firmware logs categories.
/// </summary>
- public SelectedObjectCollection<LogCategory> SelectedMachineLogsCategories { get; set; }
+ public SelectedObjectCollection<LogCategory> SelectedFirmwareLogsCategories { get; set; }
/// <summary>
/// Gets or sets a value indicating whether to pause the insertion of application logs.
@@ -61,9 +61,9 @@ namespace Tango.FSE.UI.Panes
public bool ApplicationLogsPaused { get; set; }
/// <summary>
- /// Gets or sets a value indicating whether to pause the insertion of machine logs.
+ /// Gets or sets a value indicating whether to pause the insertion of firmware logs.
/// </summary>
- public bool MachineLogsPaused { get; set; }
+ public bool FirmwareLogsPaused { get; set; }
private String _applicationLogsFilter;
/// <summary>
@@ -75,14 +75,14 @@ namespace Tango.FSE.UI.Panes
set { _applicationLogsFilter = value; RaisePropertyChangedAuto(); ApplicationLogsView.Refresh(); }
}
- private String _machineLogsFilter;
+ private String _firmwareLogsFilter;
/// <summary>
- /// Gets or sets the machine logs filter.
+ /// Gets or sets the firmware logs filter.
/// </summary>
- public String MachineLogsFilter
+ public String FirmwareLogsFilter
{
- get { return _machineLogsFilter; }
- set { _machineLogsFilter = value; RaisePropertyChangedAuto(); MachineLogsView.Refresh(); }
+ get { return _firmwareLogsFilter; }
+ set { _firmwareLogsFilter = value; RaisePropertyChangedAuto(); FirmwareLogsView.Refresh(); }
}
/// <summary>
@@ -91,9 +91,9 @@ namespace Tango.FSE.UI.Panes
public RelayCommand ClearApplicationLogsCommand { get; set; }
/// <summary>
- /// Clears the machine logs.
+ /// Clears the firmware logs.
/// </summary>
- public RelayCommand ClearMachineLogsCommand { get; set; }
+ public RelayCommand ClearFirmwareLogsCommand { get; set; }
/// <summary>
/// Opens the detailed application log dialog.
@@ -101,9 +101,9 @@ namespace Tango.FSE.UI.Panes
public RelayCommand<LogItemBase> OpenApplicationLogItemCommand { get; set; }
/// <summary>
- /// Opens the detailed machine log dialog.
+ /// Opens the detailed firmware log dialog.
/// </summary>
- public RelayCommand<EmbeddedLogItem> OpenMachineLogItemCommand { get; set; }
+ public RelayCommand<EmbeddedLogItem> OpenFirmareLogItemCommand { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="LogViewerPaneVM"/> class.
@@ -111,15 +111,15 @@ namespace Tango.FSE.UI.Panes
public LogViewerPaneVM()
{
_pausedApplicationLogs = new List<LogItemBase>();
- _pausedMachineLogs = new List<EmbeddedLogItem>();
+ _pausedFirmwareLogs = new List<EmbeddedLogItem>();
ApplicationLogs = new ObservableCollection<LogItemBase>();
- MachineLogs = new ObservableCollection<EmbeddedLogItem>();
+ FirmwareLogs = new ObservableCollection<EmbeddedLogItem>();
ApplicationLogsView = CollectionViewSource.GetDefaultView(ApplicationLogs);
- MachineLogsView = CollectionViewSource.GetDefaultView(MachineLogs);
+ FirmwareLogsView = CollectionViewSource.GetDefaultView(FirmwareLogs);
ApplicationLogsView.Filter = FilterApplicationLogs;
- MachineLogsView.Filter = FilterMachineLogs;
+ FirmwareLogsView.Filter = FilterFirmwareLogs;
SelectedApplicationLogsCategories = new SelectedObjectCollection<LogCategory>(new ObservableCollection<LogCategory>()
{
@@ -135,7 +135,7 @@ namespace Tango.FSE.UI.Panes
LogCategory.Critical,
});
- SelectedMachineLogsCategories = new SelectedObjectCollection<LogCategory>(new ObservableCollection<LogCategory>()
+ SelectedFirmwareLogsCategories = new SelectedObjectCollection<LogCategory>(new ObservableCollection<LogCategory>()
{
LogCategory.Info,
LogCategory.Warning,
@@ -152,18 +152,18 @@ namespace Tango.FSE.UI.Panes
});
SelectedApplicationLogsCategories.SynchedSource.CollectionChanged += (_, __) => ApplicationLogsView.Refresh();
- SelectedMachineLogsCategories.SynchedSource.CollectionChanged += (_, __) => MachineLogsView.Refresh();
+ SelectedFirmwareLogsCategories.SynchedSource.CollectionChanged += (_, __) => FirmwareLogsView.Refresh();
ClearApplicationLogsCommand = new RelayCommand(ClearApplicationLogs);
- ClearMachineLogsCommand = new RelayCommand(ClearMachineLogs);
+ ClearFirmwareLogsCommand = new RelayCommand(ClearFirmwareLogs);
TangoIOC.Default.Inject(this);
LoggingProvider.ApplicationLogAvailable += LoggingProvider_ApplicationLogAvailable;
- LoggingProvider.EmbeddedLogAvailable += LoggingProvider_EmbeddedLogAvailable;
+ LoggingProvider.FirmwareLogAvailable += LoggingProvider_FirmwareLogAvailable;
OpenApplicationLogItemCommand = new RelayCommand<LogItemBase>(OpenApplicationLogItem);
- OpenMachineLogItemCommand = new RelayCommand<EmbeddedLogItem>(OpenMachineLogItem);
+ OpenFirmareLogItemCommand = new RelayCommand<EmbeddedLogItem>(OpenFirmwareLogItem);
}
private async void OpenApplicationLogItem(LogItemBase logItem)
@@ -171,9 +171,9 @@ namespace Tango.FSE.UI.Panes
await NotificationProvider.ShowDialog(new ApplicationLogItemViewVM() { LogItem = logItem });
}
- private async void OpenMachineLogItem(EmbeddedLogItem logItem)
+ private async void OpenFirmwareLogItem(EmbeddedLogItem logItem)
{
- await NotificationProvider.ShowDialog(new MachineLogItemViewVM() { LogItem = logItem });
+ await NotificationProvider.ShowDialog(new FirmwareLogItemViewVM() { LogItem = logItem });
}
private bool FilterApplicationLogs(object obj)
@@ -182,10 +182,10 @@ namespace Tango.FSE.UI.Panes
return SelectedApplicationLogsCategories.SynchedSource.Contains(log.Category) && (String.IsNullOrWhiteSpace(ApplicationLogsFilter) || log.Message.ToLower().Contains(ApplicationLogsFilter.ToLower()));
}
- private bool FilterMachineLogs(object obj)
+ private bool FilterFirmwareLogs(object obj)
{
var log = obj as EmbeddedLogItem;
- return SelectedMachineLogsCategories.SynchedSource.Contains(log.Category) && (String.IsNullOrWhiteSpace(MachineLogsFilter) || log.Message.ToLower().Contains(MachineLogsFilter.ToLower()));
+ return SelectedFirmwareLogsCategories.SynchedSource.Contains(log.Category) && (String.IsNullOrWhiteSpace(FirmwareLogsFilter) || log.Message.ToLower().Contains(FirmwareLogsFilter.ToLower()));
}
private void ClearApplicationLogs()
@@ -194,10 +194,10 @@ namespace Tango.FSE.UI.Panes
ApplicationLogs.Clear();
}
- private void ClearMachineLogs()
+ private void ClearFirmwareLogs()
{
- _pausedMachineLogs.Clear();
- MachineLogs.Clear();
+ _pausedFirmwareLogs.Clear();
+ FirmwareLogs.Clear();
}
private void LoggingProvider_ApplicationLogAvailable(object sender, LogItemBase logItem)
@@ -225,27 +225,27 @@ namespace Tango.FSE.UI.Panes
}
}
- private void LoggingProvider_EmbeddedLogAvailable(object sender, EmbeddedLogItem logItem)
+ private void LoggingProvider_FirmwareLogAvailable(object sender, EmbeddedLogItem logItem)
{
- if (MachineLogsPaused)
+ if (FirmwareLogsPaused)
{
- _pausedMachineLogs.Add(logItem);
+ _pausedFirmwareLogs.Add(logItem);
}
else
{
InvokeUI(() =>
{
- if (_pausedMachineLogs.Count > 0)
+ if (_pausedFirmwareLogs.Count > 0)
{
- foreach (var pausedItem in _pausedMachineLogs)
+ foreach (var pausedItem in _pausedFirmwareLogs)
{
- MachineLogs.Insert(0, pausedItem);
+ FirmwareLogs.Insert(0, pausedItem);
}
- _pausedMachineLogs.Clear();
+ _pausedFirmwareLogs.Clear();
}
- MachineLogs.Insert(0, logItem);
+ FirmwareLogs.Insert(0, logItem);
});
}
}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs
index 5d5463d1b..f89c2010f 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs
@@ -93,8 +93,8 @@ namespace Tango.FSE.UI
TangoIOC.Default.Register<IConsolProvider, DefaultConsoleProvider>();
TangoIOC.Default.Register<IPerformanceProvider, DefaultPerformanceProvider>();
TangoIOC.Default.Register<ISystemInfoProvider, DefaultSystemInfoProvider>();
- TangoIOC.Default.Register<ILoggingProvider, DefaultLoggingProvider>();
TangoIOC.Default.Register<IFileSystemProvider, DefaultFileSystemProvider>();
+ TangoIOC.Default.Register<ILoggingProvider, DefaultLoggingProvider>();
TangoIOC.Default.Register<IStorageProvider, DefaultStorageProvider>();
TangoIOC.Default.Register<IMachineUpdatesProvider, DefaultMachineUpdatesProvider>();
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/FileSystem/DefaultFileSystemService.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/FileSystem/DefaultFileSystemService.cs
index 02975a2b3..86506abcf 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/FileSystem/DefaultFileSystemService.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/FileSystem/DefaultFileSystemService.cs
@@ -11,7 +11,10 @@ using Tango.Core.IO;
using Tango.FileSystem;
using Tango.FileSystem.Network;
using Tango.Integration.ExternalBridge;
+using Tango.Integration.Operation;
+using Tango.Logging;
using Tango.PPC.Common.ExternalBridge;
+using Tango.PPC.Shared.Logs;
using Tango.Transport;
using Tango.Transport.Transporters;
using Tango.WebRTC;
@@ -360,6 +363,49 @@ namespace Tango.PPC.Common.FileSystem
await receiver.SendGenericResponse(new PerformDiskSpaceOptimizationResponse() { DeletedBytes = deletedBytes }, token);
}
+ [ExternalBridgeRequestHandlerMethod(typeof(GetLogFilesRequest), RequestHandlerLoggingMode.LogRequestNameAndContent)]
+ public async Task OnGetLogFilesRequest(GetLogFilesRequest request, String token, ExternalBridgeReceiver receiver)
+ {
+ FolderItem folder = null;
+
+ if (request.LogFileType == RemoteLogFileType.Application)
+ {
+ var fileLogger = LogManager.RegisteredLoggers.SingleOrDefault(x => x.GetType() == typeof(FileLogger)) as FileLogger;
+
+ if (fileLogger == null)
+ {
+ throw new InvalidOperationException("Could not locate the application file logger.");
+ }
+
+ folder = await _manager.GetFolder(fileLogger.Folder, false, "*.log") as FolderItem;
+ }
+ else
+ {
+ if (MachineOperator.EmbeddedLogsFolder == null)
+ {
+ throw new InvalidOperationException("The firmware file logger folder could not be read.");
+ }
+
+ folder = await _manager.GetFolder(MachineOperator.EmbeddedLogsFolder, false, "*.log") as FolderItem;
+ }
+
+ GetLogFilesResponse response = new GetLogFilesResponse();
+
+ foreach (var file in folder.Items.OfType<FileItem>().OrderByDescending(x => x.DateCreated).DistinctBy(x => x.Name))
+ {
+ response.LogFiles.Add(new RemoteLogFile()
+ {
+ DateModified = file.DateModified,
+ DateCreated = file.DateCreated,
+ Name = file.Name,
+ Path = file.Path,
+ Length = new FileInfo(file.Path).Length
+ });
+ }
+
+ await receiver.SendGenericResponse(response, token);
+ }
+
public void OnReceiverDisconnected(ExternalBridgeReceiver receiver)
{
if (_webRtcClients.ContainsKey(receiver))
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Logs/GetLogFilesRequest.cs b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Logs/GetLogFilesRequest.cs
new file mode 100644
index 000000000..bb5d21837
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Logs/GetLogFilesRequest.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.PPC.Shared.Logs
+{
+ public class GetLogFilesRequest
+ {
+ public RemoteLogFileType LogFileType { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Logs/GetLogFilesResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Logs/GetLogFilesResponse.cs
new file mode 100644
index 000000000..cf5d59726
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Logs/GetLogFilesResponse.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.PPC.Shared.Logs
+{
+ public class GetLogFilesResponse
+ {
+ public List<RemoteLogFile> LogFiles { get; set; }
+
+ public GetLogFilesResponse()
+ {
+ LogFiles = new List<RemoteLogFile>();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Logs/RemoteLogFile.cs b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Logs/RemoteLogFile.cs
new file mode 100644
index 000000000..fc2ba88c4
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Logs/RemoteLogFile.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.PPC.Shared.Logs
+{
+ public class RemoteLogFile
+ {
+ public String Name { get; set; }
+ public DateTime DateModified { get; set; }
+ public DateTime DateCreated { get; set; }
+ public String Path { get; set; }
+ public long Length { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Logs/RemoteLogFileType.cs b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Logs/RemoteLogFileType.cs
new file mode 100644
index 000000000..958b4c195
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Logs/RemoteLogFileType.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.PPC.Shared.Logs
+{
+ public enum RemoteLogFileType
+ {
+ Application,
+ Firmware
+ }
+}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj
index 2ae1c7575..96c18129a 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj
@@ -60,6 +60,10 @@
<Compile Include="Information\GetMachineInformationRequest.cs" />
<Compile Include="Information\GetMachineInformationResponse.cs" />
<Compile Include="Information\InformationPackage.cs" />
+ <Compile Include="Logs\GetLogFilesRequest.cs" />
+ <Compile Include="Logs\GetLogFilesResponse.cs" />
+ <Compile Include="Logs\RemoteLogFile.cs" />
+ <Compile Include="Logs\RemoteLogFileType.cs" />
<Compile Include="Performance\PerformancePackage.cs" />
<Compile Include="Performance\StartPerformanceUpdatesRequest.cs" />
<Compile Include="Performance\StartPerformanceUpdatesResponse.cs" />
diff --git a/Software/Visual_Studio/Tango.FileSystem/FileSystemItem.cs b/Software/Visual_Studio/Tango.FileSystem/FileSystemItem.cs
index c8b2fce32..558251f3c 100644
--- a/Software/Visual_Studio/Tango.FileSystem/FileSystemItem.cs
+++ b/Software/Visual_Studio/Tango.FileSystem/FileSystemItem.cs
@@ -25,6 +25,8 @@ namespace Tango.FileSystem
public DateTime DateModified { get; set; }
+ public DateTime DateCreated { get; set; }
+
public long Size { get; set; }
public String Name
@@ -75,6 +77,7 @@ namespace Tango.FileSystem
}
item.DateModified = dto.DateModified;
+ item.DateCreated = dto.DateCreated;
item.Path = dto.Path;
item.Size = dto.Size;
item.Type = dto.Type;
diff --git a/Software/Visual_Studio/Tango.FileSystem/FileSystemManager.cs b/Software/Visual_Studio/Tango.FileSystem/FileSystemManager.cs
index c08304ca8..dc8efa7dd 100644
--- a/Software/Visual_Studio/Tango.FileSystem/FileSystemManager.cs
+++ b/Software/Visual_Studio/Tango.FileSystem/FileSystemManager.cs
@@ -71,6 +71,7 @@ namespace Tango.FileSystem
Path = directory,
Type = FileSystemItemType.Folder,
DateModified = Directory.GetLastWriteTimeUtc(directory),
+ DateCreated = Directory.GetCreationTimeUtc(directory),
});
}
@@ -83,6 +84,7 @@ namespace Tango.FileSystem
Path = file,
Type = FileSystemItemType.File,
DateModified = File.GetLastWriteTimeUtc(file),
+ DateCreated = File.GetCreationTimeUtc(file),
Size = new FileInfo(file).Length
});
}
diff --git a/Software/Visual_Studio/Tango.FileSystem/Network/FileSystemItemDTO.cs b/Software/Visual_Studio/Tango.FileSystem/Network/FileSystemItemDTO.cs
index 900ba0628..43467f227 100644
--- a/Software/Visual_Studio/Tango.FileSystem/Network/FileSystemItemDTO.cs
+++ b/Software/Visual_Studio/Tango.FileSystem/Network/FileSystemItemDTO.cs
@@ -19,6 +19,8 @@ namespace Tango.FileSystem.Network
public DateTime DateModified { get; set; }
+ public DateTime DateCreated { get; set; }
+
public long Size { get; set; }
public bool IsRoot { get; set; }
diff --git a/Software/Visual_Studio/Tango.Integration/Logging/EmbeddedLogFileParser.cs b/Software/Visual_Studio/Tango.Integration/Logging/EmbeddedLogFileParser.cs
index 72e55bbfd..bfe1cebcc 100644
--- a/Software/Visual_Studio/Tango.Integration/Logging/EmbeddedLogFileParser.cs
+++ b/Software/Visual_Studio/Tango.Integration/Logging/EmbeddedLogFileParser.cs
@@ -115,5 +115,12 @@ namespace Tango.Integration.Logging
}
}
}
+
+ public List<EmbeddedLogItem> Parse(string file, DateTime fileDate)
+ {
+ List<EmbeddedLogItem> logs = new List<EmbeddedLogItem>();
+ Parse(file, fileDate, ref logs);
+ return logs;
+ }
}
}
diff --git a/Software/Visual_Studio/Tango.Logging/ApplicationLogFileParser.cs b/Software/Visual_Studio/Tango.Logging/ApplicationLogFileParser.cs
index 85f82d04e..1530c4d27 100644
--- a/Software/Visual_Studio/Tango.Logging/ApplicationLogFileParser.cs
+++ b/Software/Visual_Studio/Tango.Logging/ApplicationLogFileParser.cs
@@ -75,6 +75,13 @@ namespace Tango.Logging
return logItems;
}
+ public List<LogItemBase> Parse(String file, DateTime fileDate)
+ {
+ List<LogItemBase> logs = new List<LogItemBase>();
+ Parse(file, fileDate, ref logs);
+ return logs;
+ }
+
private void Parse(string file, DateTime datetime, ref List<LogItemBase> logItems)
{
String text = File.ReadAllText(file);
diff --git a/Software/Visual_Studio/Tango.Logging/ILogFileParser.cs b/Software/Visual_Studio/Tango.Logging/ILogFileParser.cs
index bc43c7cd0..64b4c7206 100644
--- a/Software/Visual_Studio/Tango.Logging/ILogFileParser.cs
+++ b/Software/Visual_Studio/Tango.Logging/ILogFileParser.cs
@@ -10,6 +10,8 @@ namespace Tango.Logging
{
List<T> Parse(LogFile logFile);
+ List<T> Parse(String file, DateTime fileDate);
+
List<LogFile> GetLogFiles();
}
}
diff --git a/Software/Visual_Studio/Tango.Logging/LogFile.cs b/Software/Visual_Studio/Tango.Logging/LogFile.cs
index c86ec1792..f727b96f4 100644
--- a/Software/Visual_Studio/Tango.Logging/LogFile.cs
+++ b/Software/Visual_Studio/Tango.Logging/LogFile.cs
@@ -28,7 +28,6 @@ namespace Tango.Logging
/// </summary>
public bool PartOfSet { get; set; }
-
/// <summary>
/// Gets or sets the start index of the set.
/// </summary>
diff --git a/Software/Visual_Studio/Tango.Logging/LogItemBase.cs b/Software/Visual_Studio/Tango.Logging/LogItemBase.cs
index f89b73b40..01d520f6a 100644
--- a/Software/Visual_Studio/Tango.Logging/LogItemBase.cs
+++ b/Software/Visual_Studio/Tango.Logging/LogItemBase.cs
@@ -47,6 +47,14 @@ namespace Tango.Logging
}
/// <summary>
+ /// Gets the name of the caller file class.
+ /// </summary>
+ public String ClassName
+ {
+ get { return RelativeCallerFile.Split('\\').LastOrDefault()?.Split('.').FirstOrDefault(); }
+ }
+
+ /// <summary>
/// Gets or sets the caller line number.
/// </summary>
public int CallerLineNumber { get; set; }
diff --git a/Software/Visual_Studio/Tango.SharedUI/Components/BindingProxy.cs b/Software/Visual_Studio/Tango.SharedUI/Components/BindingProxy.cs
new file mode 100644
index 000000000..e13436900
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Components/BindingProxy.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace Tango.SharedUI.Components
+{
+ public class BindingProxy : Freezable
+ {
+ #region Overrides of Freezable
+
+ protected override Freezable CreateInstanceCore()
+ {
+ return new BindingProxy();
+ }
+
+ #endregion
+
+ public object Data
+ {
+ get { return (object)GetValue(DataProperty); }
+ set { SetValue(DataProperty, value); }
+ }
+
+ public static readonly DependencyProperty DataProperty =
+ DependencyProperty.Register("Data", typeof(object),
+ typeof(BindingProxy));
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/StringToOneLineConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/StringToOneLineConverter.cs
index d130ebaaf..e1255ef13 100644
--- a/Software/Visual_Studio/Tango.SharedUI/Converters/StringToOneLineConverter.cs
+++ b/Software/Visual_Studio/Tango.SharedUI/Converters/StringToOneLineConverter.cs
@@ -15,11 +15,11 @@ namespace Tango.SharedUI.Converters
if (value != null)
{
string str = value.ToString();
- int newLineIndex = str.IndexOf(Environment.NewLine);
+ int newLineIndex = str.IndexOf("\n");
if (newLineIndex == -1)
{
- newLineIndex = str.IndexOf("\n");
+ newLineIndex = str.IndexOf(Environment.NewLine);
}
string firstline = str;
diff --git a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj
index 000a4e5d7..a649d0c1a 100644
--- a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj
+++ b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj
@@ -67,6 +67,7 @@
<Compile Include="Binding\BindingEventArgs.cs" />
<Compile Include="Binding\BindingEventContainer.cs" />
<Compile Include="Binding\BindingProperty.cs" />
+ <Compile Include="Components\BindingProxy.cs" />
<Compile Include="Components\SelectedObject.cs" />
<Compile Include="Components\SelectedObjectCollection.cs" />
<Compile Include="Components\TextController.cs" />
@@ -255,7 +256,7 @@
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
- <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" />
+ <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" />
</VisualStudio>
</ProjectExtensions>
</Project> \ No newline at end of file