aboutsummaryrefslogtreecommitdiffstats
path: root/Software
diff options
context:
space:
mode:
Diffstat (limited to 'Software')
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/FileSystemViewVM.cs80
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/FileSystemView.xaml73
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/FileSystemControl.xaml34
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs7
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/FileSystemHandler.cs85
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/FileSystemHandlerStatus.cs18
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/FileSystemHandlerType.cs17
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/IFileSystemProvider.cs19
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj4
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs72
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj5
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs4
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/FileSystem/DefaultFileSystemService.cs202
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/FileSystem/IFileSystemService.cs13
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj8
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs3
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/FileSystemDataGrid.cs30
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/FileSystemDataGridRow.cs40
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/FileSystemItem.cs5
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/FileSystemManager.cs23
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/Network/AbortOperationRequest.cs13
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/Network/AbortOperationResponse.cs12
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/Network/ChunkDownloadRequest.cs15
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/Network/ChunkDownloadResponse.cs (renamed from Software/Visual_Studio/Tango.FileSystem/Network/StartFileDownloadResponse.cs)4
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/Network/ChunkUploadRequest.cs14
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/Network/ChunkUploadResponse.cs13
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/Network/FileDownloadRequest.cs (renamed from Software/Visual_Studio/Tango.FileSystem/Network/StartFileDownloadRequest.cs)2
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/Network/FileDownloadResponse.cs (renamed from Software/Visual_Studio/Tango.FileSystem/Network/StartFolderDownloadResponse.cs)5
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/Network/FileUploadRequest.cs1
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/Network/FileUploadResponse.cs2
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/Network/FolderDownloadRequest.cs (renamed from Software/Visual_Studio/Tango.FileSystem/Network/StartFolderDownloadRequest.cs)2
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/Network/FolderDownloadResponse.cs14
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/Network/GetFileSystemItemRequest.cs2
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/Tango.FileSystem.csproj16
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/Themes/Generic.xaml32
35 files changed, 802 insertions, 87 deletions
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/FileSystemViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/FileSystemViewVM.cs
index 44bd03c39..f9eff7e6f 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/FileSystemViewVM.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/FileSystemViewVM.cs
@@ -1,15 +1,19 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using System.Windows.Input;
using Tango.Core.Commands;
using Tango.FileSystem;
using Tango.FSE.Common;
+using Tango.FSE.Common.Connection;
+using static Tango.SharedUI.Controls.NavigationControl;
namespace Tango.FSE.PPCConsole.ViewModels
{
- public class FileSystemViewVM : FSEViewModel
+ public class FileSystemViewVM : FSEViewModel, INavigationViewModel
{
private FileSystemItem _currentItem;
public FileSystemItem CurrentItem
@@ -26,32 +30,92 @@ namespace Tango.FSE.PPCConsole.ViewModels
}
public RelayCommand NavigateCommand { get; set; }
+ public RelayCommand<FileSystemItem> OpenItemCommand { get; set; }
+ public RelayCommand BackCommand { get; set; }
public FileSystemViewVM()
{
- NavigateCommand = new RelayCommand(Navigate);
+ NavigateCommand = new RelayCommand(NavigateToCurrentPath);
+ OpenItemCommand = new RelayCommand<FileSystemItem>(OpenFileSystemItem);
+ BackCommand = new RelayCommand(NavigateBack, () => !(CurrentItem is FolderItem) || !(CurrentItem as FolderItem).IsRoot);
+ }
+
+ private async void NavigateBack()
+ {
+ if (CurrentItem.Path.Length == 3)
+ {
+ await Navigate(null);
+ }
+ else
+ {
+ String parent = Path.GetDirectoryName(CurrentItem.Path);
+ await Navigate(parent);
+ }
+ }
+
+ public override void OnApplicationStarted()
+ {
+ base.OnApplicationStarted();
+ MachineProvider.MachineConnected += MachineProvider_MachineConnected;
}
public override void OnApplicationReady()
{
base.OnApplicationReady();
+ }
+
+ private async void MachineProvider_MachineConnected(object sender, MachineConnectedEventArgs e)
+ {
+ await Navigate(null);
+ }
+
+ private async void NavigateToCurrentPath()
+ {
+ await Navigate(CurrentPath);
+ }
- FileSystemManager manager = new FileSystemManager();
- CurrentItem = FileSystemItem.FromDTO(manager.GetFolder(@"C:\"));
+ private async void OpenFileSystemItem(FileSystemItem item)
+ {
+ if (item != null)
+ {
+ await Navigate(item.Path);
+ }
}
- private void Navigate()
+ private async Task Navigate(String path)
{
- if (CurrentPath.IsNotNullOrEmpty())
+ try
+ {
+ IsFree = false;
+
+ Mouse.OverrideCursor = Cursors.AppStarting;
+
+ if (path != null)
+ {
+ CurrentItem = await FileSystemProvider.GetFolder(path) as FileSystemItem;
+ }
+ else
+ {
+ CurrentItem = await FileSystemProvider.GetThisPC() as FileSystemItem;
+ }
+ }
+ catch (Exception ex)
+ {
+ IsFree = true;
+ Mouse.OverrideCursor = null;
+ await NotificationProvider.ShowError($"Error navigating to the specified path.\n{ex.FlattenMessage()}");
+ }
+ finally
{
- FileSystemManager manager = new FileSystemManager();
- CurrentItem = FileSystemItem.FromDTO(manager.GetFolder(CurrentPath));
+ IsFree = true;
+ Mouse.OverrideCursor = null;
}
}
private void OnCurrentItemChanged()
{
CurrentPath = CurrentItem.Path;
+ InvalidateRelayCommands();
}
}
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/FileSystemView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/FileSystemView.xaml
index ad503c7de..fc23ca42c 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/FileSystemView.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/FileSystemView.xaml
@@ -10,7 +10,7 @@
xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:FileSystemViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.FileSystemViewVM}">
- <Grid>
+ <Grid IsEnabled="{Binding IsFree}">
<Grid Margin="0 20 0 0">
<Grid.RowDefinitions>
<RowDefinition Height="30" />
@@ -36,7 +36,7 @@
</Button>
</StackPanel>
<StackPanel DockPanel.Dock="Left" Orientation="Horizontal">
- <Button material:ButtonAssist.CornerRadius="3 0 0 3" Style="{StaticResource FSE_RaisedButton_Dark_Hover}" Padding="0" Width="60" Height="Auto">
+ <Button Command="{Binding BackCommand}" material:ButtonAssist.CornerRadius="3 0 0 3" Style="{StaticResource FSE_RaisedButton_Dark_Hover}" Padding="0" Width="60" Height="Auto">
<material:PackIcon Kind="ChevronLeft" Width="Auto" Height="20" />
</Button>
</StackPanel>
@@ -45,17 +45,74 @@
<Border.Effect>
<DropShadowEffect BlurRadius="2" ShadowDepth="2" Opacity="0.3" Direction="270" />
</Border.Effect>
- <TextBox Padding="5 0 0 0" Text="{Binding CurrentPath,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}" CaretBrush="{StaticResource FSE_PrimaryForegroundBrush}" Background="Transparent" BorderThickness="0" VerticalContentAlignment="Center" Style="{x:Null}">
- <TextBox.InputBindings>
- <KeyBinding Key="Return" Command="{Binding NavigateCommand}" />
- </TextBox.InputBindings>
- </TextBox>
+ <Border IsHitTestVisible="False" Visibility="{Binding IsBusy,Converter={StaticResource BooleanToVisibilityConverter}}">
+ <Border.Background>
+ <LinearGradientBrush>
+ <GradientStop Offset="0" Color="Transparent" />
+ <GradientStop Offset="0.5" Color="#6303A9F4" />
+ <GradientStop Offset="1" Color="Transparent" />
+ </LinearGradientBrush>
+ </Border.Background>
+ <Border.Style>
+ <Style TargetType="Border">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding IsBusy}" Value="True">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard Name="loadingStory">
+ <Storyboard>
+ <DoubleAnimation Storyboard.TargetProperty="Background.GradientStops[1].Offset" From="0" To="1" AutoReverse="True" RepeatBehavior="Forever" />
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ <DataTrigger.ExitActions>
+ <RemoveStoryboard BeginStoryboardName="loadingStory" />
+ </DataTrigger.ExitActions>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Border.Style>
+
+ <TextBox Padding="5 0 0 0" Text="{Binding CurrentPath,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}" CaretBrush="{StaticResource FSE_PrimaryForegroundBrush}" Background="Transparent" BorderThickness="0" VerticalContentAlignment="Center" Style="{x:Null}">
+ <TextBox.InputBindings>
+ <KeyBinding Key="Return" Command="{Binding NavigateCommand}" />
+ </TextBox.InputBindings>
+ </TextBox>
+ </Border>
</Border>
</Border>
</DockPanel>
</DockPanel>
- <controls:FileSystemControl Margin="0 10 0 0" CurrentItem="{Binding CurrentItem}" Grid.Row="1" Mode="{Binding ElementName=listView,Path=SelectedItem.Tag}" />
+ <Grid Grid.Row="1" Margin="0 10 0 0">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="200" />
+ <ColumnDefinition Width="5" />
+ <ColumnDefinition Width="1*" />
+ </Grid.ColumnDefinitions>
+
+ <Border Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}" BorderBrush="{StaticResource FSE_PrimaryBackgroundLightBrush}" BorderThickness="3" CornerRadius="3" Padding="10 5">
+ <StackPanel>
+ <controls:TextIconButton HorizontalContentAlignment="Left" Padding="5" Icon="Computer" Background="Transparent" BorderThickness="0" FocusVisualStyle="{x:Null}">Devices</controls:TextIconButton>
+ <StackPanel Margin="30 0 0 0">
+ <controls:TextIconButton HorizontalContentAlignment="Left" Padding="5" Icon="Harddisk" Background="Transparent" BorderThickness="0" FocusVisualStyle="{x:Null}">Local Disk 1</controls:TextIconButton>
+ <controls:TextIconButton HorizontalContentAlignment="Left" Padding="5" Icon="Harddisk" Background="Transparent" BorderThickness="0" FocusVisualStyle="{x:Null}">Local Disk 2</controls:TextIconButton>
+ </StackPanel>
+
+ <controls:TextIconButton HorizontalContentAlignment="Left" Padding="5" Icon="Computer" Background="Transparent" BorderThickness="0" FocusVisualStyle="{x:Null}">Computer</controls:TextIconButton>
+ <StackPanel Margin="30 0 0 0">
+ <controls:TextIconButton HorizontalContentAlignment="Left" Padding="5" Icon="DesktopMac" Background="Transparent" BorderThickness="0" FocusVisualStyle="{x:Null}">Desktop</controls:TextIconButton>
+ <controls:TextIconButton HorizontalContentAlignment="Left" Padding="5" Icon="Downloads" Background="Transparent" BorderThickness="0" FocusVisualStyle="{x:Null}">Downloads</controls:TextIconButton>
+ <controls:TextIconButton HorizontalContentAlignment="Left" Padding="5" Icon="FileDocument" Background="Transparent" BorderThickness="0" FocusVisualStyle="{x:Null}">Documents</controls:TextIconButton>
+ <controls:TextIconButton HorizontalContentAlignment="Left" Padding="5" Icon="Application" Background="Transparent" BorderThickness="0" FocusVisualStyle="{x:Null}">Tango</controls:TextIconButton>
+ </StackPanel>
+ </StackPanel>
+ </Border>
+
+ <controls:FileSystemControl Margin="10 0 0 0" Grid.Column="2"
+ CurrentItem="{Binding CurrentItem}"
+ Mode="{Binding ElementName=listView,Path=SelectedItem.Tag}"
+ ItemDoubleClickedCommand="{Binding OpenItemCommand}"/>
+ </Grid>
</Grid>
</Grid>
</UserControl>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/FileSystemControl.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/FileSystemControl.xaml
index ec490e893..7230d97fb 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/FileSystemControl.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/FileSystemControl.xaml
@@ -7,6 +7,14 @@
<converters:ByteArrayToFileSizeConverter x:Key="ByteArrayToFileSizeConverter" />
<converters:DateTimeUtcToLocalDateTime x:Key="DateTimeUtcToLocalDateTime" />
+ <Style TargetType="{x:Type local:FileSystemDataGridRow}" BasedOn="{StaticResource {x:Type DataGridRow}}">
+ <Setter Property="DoubleClickCommand" Value="{Binding RelativeSource={RelativeSource AncestorType=local:FileExplorerControl},Path=ItemDoubleClickedCommand}"></Setter>
+ </Style>
+
+ <Style TargetType="{x:Type local:FileSystemDataGrid}" BasedOn="{StaticResource {x:Type DataGrid}}">
+
+ </Style>
+
<Style x:Key="FileSystemCellStyle" TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
@@ -92,7 +100,7 @@
</Style.Triggers>
</Style>
</Grid.Style>
- <DataGrid x:Name="PART_datagrid" ItemsSource="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=CurrentItem.Items}" CellStyle="{StaticResource FileSystemCellStyle}">
+ <local:FileSystemDataGrid x:Name="PART_datagrid" ItemsSource="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=CurrentItem.Items}" CellStyle="{StaticResource FileSystemCellStyle}">
<DataGrid.Style>
<Style TargetType="DataGrid" BasedOn="{StaticResource {x:Type DataGrid}}">
<Setter Property="Background" Value="Transparent"></Setter>
@@ -119,11 +127,6 @@
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DockPanel Background="Transparent">
- <DockPanel.InputBindings>
- <MouseBinding MouseAction="LeftDoubleClick"
- Command="{Binding RelativeSource={RelativeSource AncestorType=local:FileExplorerControl},Path=ItemDoubleClickedCommand}"
- CommandParameter="{Binding}" />
- </DockPanel.InputBindings>
<Image Width="18" Height="18" RenderOptions.BitmapScalingMode="Fant" Stretch="Uniform" HorizontalAlignment="Center" VerticalAlignment="Center">
<Image.Style>
<Style TargetType="Image">
@@ -150,11 +153,6 @@
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DockPanel Background="Transparent">
- <DockPanel.InputBindings>
- <MouseBinding MouseAction="LeftDoubleClick"
- Command="{Binding RelativeSource={RelativeSource AncestorType=local:FileExplorerControl},Path=ItemDoubleClickedCommand}"
- CommandParameter="{Binding}" />
- </DockPanel.InputBindings>
<TextBlock Text="{Binding DateModified,Converter={StaticResource DateTimeUtcToLocalDateTime}}" VerticalAlignment="Center"></TextBlock>
</DockPanel>
</DataTemplate>
@@ -164,11 +162,6 @@
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DockPanel Background="Transparent">
- <DockPanel.InputBindings>
- <MouseBinding MouseAction="LeftDoubleClick"
- Command="{Binding RelativeSource={RelativeSource AncestorType=local:FileExplorerControl},Path=ItemDoubleClickedCommand}"
- CommandParameter="{Binding}" />
- </DockPanel.InputBindings>
<TextBlock Text="{Binding Description}" VerticalAlignment="Center"></TextBlock>
</DockPanel>
</DataTemplate>
@@ -178,11 +171,6 @@
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DockPanel Background="Transparent">
- <DockPanel.InputBindings>
- <MouseBinding MouseAction="LeftDoubleClick"
- Command="{Binding RelativeSource={RelativeSource AncestorType=local:FileExplorerControl},Path=ItemDoubleClickedCommand}"
- CommandParameter="{Binding}" />
- </DockPanel.InputBindings>
<TextBlock Text="{Binding Size,Converter={StaticResource ByteArrayToFileSizeConverter}}" VerticalAlignment="Center">
<TextBlock.Style>
<Style TargetType="TextBlock">
@@ -200,7 +188,7 @@
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
- </DataGrid>
+ </local:FileSystemDataGrid>
</Grid>
</Grid>
</Border>
@@ -208,5 +196,5 @@
</Setter.Value>
</Setter>
</Style>
-
+
</ResourceDictionary> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs
index 997eca676..b3e832b58 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs
@@ -17,6 +17,7 @@ using Tango.FSE.BL;
using Tango.FSE.Common.Authentication;
using Tango.FSE.Common.Connection;
using Tango.FSE.Common.Diagnostics;
+using Tango.FSE.Common.FileSystem;
using Tango.FSE.Common.FSEApplication;
using Tango.FSE.Common.Gateway;
using Tango.FSE.Common.Logging;
@@ -119,6 +120,12 @@ namespace Tango.FSE.Common
public IResolutionService ResolutionService { get; set; }
/// <summary>
+ /// Gets or sets the file system provider.
+ /// </summary>
+ [TangoInject]
+ public IFileSystemProvider FileSystemProvider { get; set; }
+
+ /// <summary>
/// Gets or sets the FSE service.
/// </summary>
[TangoInject]
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/FileSystemHandler.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/FileSystemHandler.cs
new file mode 100644
index 000000000..1b1e5f747
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/FileSystemHandler.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+
+namespace Tango.FSE.Common.FileSystem
+{
+ public class FileSystemHandler : ExtendedObject
+ {
+ private Action _abortAction;
+
+ public FileSystemHandlerType Type { get; set; }
+
+ private FileSystemHandlerStatus _status;
+ public FileSystemHandlerStatus Status
+ {
+ get { return _status; }
+ set
+ {
+ if (_status != value)
+ {
+ _status = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+ }
+
+ private double _position;
+ public double Position
+ {
+ get { return _position; }
+ set { _position = value; RaisePropertyChangedAuto(); }
+ }
+
+ private double _length;
+ public double Length
+ {
+ get { return _length; }
+ set { _length = value; RaisePropertyChangedAuto(); }
+ }
+
+ private Exception _failedException;
+ public Exception FailedException
+ {
+ get { return _failedException; }
+ set { _failedException = value; RaisePropertyChangedAuto(); }
+ }
+
+ public String Name { get; set; }
+ public String Destination { get; set; }
+
+ public FileSystemHandler(String name, String destination, Action abortAction)
+ {
+ Name = name;
+ Destination = destination;
+ _abortAction = abortAction;
+ }
+
+ internal void InvalidateProgress(double position, double length)
+ {
+ Position = position;
+ Length = length;
+ Status = (Type == FileSystemHandlerType.FileDownload || Type == FileSystemHandlerType.FolderDownload) ? FileSystemHandlerStatus.Downloading : FileSystemHandlerStatus.Uploading;
+ }
+
+ internal void RaiseFailed(Exception exception)
+ {
+ Status = FileSystemHandlerStatus.Failed;
+ FailedException = exception;
+ }
+
+ internal void RaiseCompleted()
+ {
+ Status = FileSystemHandlerStatus.Completed;
+ }
+
+ public void Abort()
+ {
+ Status = FileSystemHandlerStatus.Aborted;
+ _abortAction?.Invoke();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/FileSystemHandlerStatus.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/FileSystemHandlerStatus.cs
new file mode 100644
index 000000000..fe3a030a1
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/FileSystemHandlerStatus.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Common.FileSystem
+{
+ public enum FileSystemHandlerStatus
+ {
+ Pending,
+ Downloading,
+ Uploading,
+ Failed,
+ Aborted,
+ Completed
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/FileSystemHandlerType.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/FileSystemHandlerType.cs
new file mode 100644
index 000000000..4c60cb828
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/FileSystemHandlerType.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Common.FileSystem
+{
+ public enum FileSystemHandlerType
+ {
+ FileDownload,
+ FileUpload,
+ FolderDownload,
+ FolderUpload
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/IFileSystemProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/IFileSystemProvider.cs
new file mode 100644
index 000000000..16099963b
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/IFileSystemProvider.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.FileSystem;
+using static System.Environment;
+
+namespace Tango.FSE.Common.FileSystem
+{
+ public interface IFileSystemProvider
+ {
+ Task<IFileSystemContainer> GetFolder(String path);
+ Task<IFileSystemContainer> GetSpecialFolder(SpecialFolder specialFolder);
+ Task<IFileSystemContainer> GetThisPC();
+ Task<FileSystemHandler> Download(FileSystemItem item, String targetFolderPath);
+ Task<FileSystemHandler> Upload(String sourcePath, String targetPath);
+ }
+}
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 f61b59da3..8690b742a 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
@@ -105,6 +105,10 @@
<Compile Include="EventTriggerActions\SetterAction.cs" />
<Compile Include="ExtensionMethods\IExternalBridgeClientExtensions.cs" />
<Compile Include="ExtensionMethods\ViewModelExtensionMethods.cs" />
+ <Compile Include="FileSystem\FileSystemHandler.cs" />
+ <Compile Include="FileSystem\FileSystemHandlerStatus.cs" />
+ <Compile Include="FileSystem\FileSystemHandlerType.cs" />
+ <Compile Include="FileSystem\IFileSystemProvider.cs" />
<Compile Include="FSEApplication\IFSEApplicationManager.cs" />
<Compile Include="FSEDialogViewVM.cs" />
<Compile Include="FSEModuleAttribute.cs" />
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs
new file mode 100644
index 000000000..48da65f16
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.FileSystem;
+using Tango.FileSystem.Network;
+using Tango.FSE.Common.Connection;
+using Tango.FSE.Common.FileSystem;
+using Tango.Transport;
+
+namespace Tango.FSE.UI.FileSystem
+{
+ public class DefaultFileSystemProvider : IFileSystemProvider
+ {
+ private IMachineProvider _machineProvider;
+
+ public DefaultFileSystemProvider(IMachineProvider machineProvider)
+ {
+ _machineProvider = machineProvider;
+ }
+
+ public async Task<IFileSystemContainer> GetFolder(string path)
+ {
+ var response = await _machineProvider.MachineOperator.SendGenericRequest<GetFileSystemItemRequest, GetFileSystemItemResponse>(new GetFileSystemItemRequest()
+ {
+ Path = path
+ }, new TransportRequestConfig()
+ {
+ Timeout = TimeSpan.FromSeconds(30),
+ });
+
+ return FileSystemItem.FromDTO(response.FileSystemItem) as IFileSystemContainer;
+ }
+
+ public async Task<IFileSystemContainer> GetSpecialFolder(Environment.SpecialFolder specialFolder)
+ {
+ var response = await _machineProvider.MachineOperator.SendGenericRequest<GetFileSystemItemRequest, GetFileSystemItemResponse>(new GetFileSystemItemRequest()
+ {
+ SpecialFolder = specialFolder
+ }, new TransportRequestConfig()
+ {
+ Timeout = TimeSpan.FromSeconds(30),
+ });
+
+ return FileSystemItem.FromDTO(response.FileSystemItem) as IFileSystemContainer;
+ }
+
+ public async Task<IFileSystemContainer> GetThisPC()
+ {
+ var response = await _machineProvider.MachineOperator.SendGenericRequest<GetFileSystemItemRequest, GetFileSystemItemResponse>(new GetFileSystemItemRequest()
+ {
+ //No parameters at all
+ }, new TransportRequestConfig()
+ {
+ Timeout = TimeSpan.FromSeconds(30),
+ });
+
+ return FileSystemItem.FromDTO(response.FileSystemItem) as IFileSystemContainer;
+ }
+
+ public Task<FileSystemHandler> Download(FileSystemItem item, string targetFolderPath)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<FileSystemHandler> Upload(string sourcePath, string targetPath)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj
index 61f0f2e70..a1bdda00f 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj
@@ -133,6 +133,7 @@
<Compile Include="Dialogs\MachineConnectionUsbViewVM.cs" />
<Compile Include="Dialogs\MachineConnectionSignalRViewVM.cs" />
<Compile Include="Dialogs\MachineConnectionWifiViewVM.cs" />
+ <Compile Include="FileSystem\DefaultFileSystemProvider.cs" />
<Compile Include="Gateway\DefaultGatewayService.cs" />
<Compile Include="InternalModule.cs" />
<Compile Include="Logging\DefaultLoggingProvider.cs" />
@@ -324,6 +325,10 @@
<Project>{63561e19-ff5a-414b-a5ef-e30711543e1d}</Project>
<Name>Tango.Emulations</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Tango.FileSystem\Tango.FileSystem.csproj">
+ <Project>{c6ebbbbe-2123-44dc-aef7-a0d47d736ac0}</Project>
+ <Name>Tango.FileSystem</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Tango.Integration\Tango.Integration.csproj">
<Project>{4206AC58-3B57-4699-8835-90BF6DB01A61}</Project>
<Name>Tango.Integration</Name>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs
index f24a0cf99..6a3cf610a 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs
@@ -10,6 +10,7 @@ using Tango.FSE.Common.Authentication;
using Tango.FSE.Common.Connection;
using Tango.FSE.Common.Console;
using Tango.FSE.Common.Diagnostics;
+using Tango.FSE.Common.FileSystem;
using Tango.FSE.Common.FSEApplication;
using Tango.FSE.Common.Gateway;
using Tango.FSE.Common.Logging;
@@ -26,6 +27,7 @@ using Tango.FSE.UI.Authentication;
using Tango.FSE.UI.Connection;
using Tango.FSE.UI.Console;
using Tango.FSE.UI.Diagnostics;
+using Tango.FSE.UI.FileSystem;
using Tango.FSE.UI.FSEApplication;
using Tango.FSE.UI.Gateway;
using Tango.FSE.UI.Logging;
@@ -61,6 +63,7 @@ namespace Tango.FSE.UI
TangoIOC.Default.Unregister<IPerformanceProvider>();
TangoIOC.Default.Unregister<ISystemInfoProvider>();
TangoIOC.Default.Unregister<ILoggingProvider>();
+ TangoIOC.Default.Unregister<IFileSystemProvider>();
//TangoIOC.Default.Unregister<ExternalBridgeScanner>();
//TangoIOC.Default.Unregister<IDiagnosticsFrameProvider>();
//TangoIOC.Default.Unregister<IEventLogger>();
@@ -85,6 +88,7 @@ namespace Tango.FSE.UI
TangoIOC.Default.Register<IPerformanceProvider, DefaultPerformanceProvider>();
TangoIOC.Default.Register<ISystemInfoProvider, DefaultSystemInfoProvider>();
TangoIOC.Default.Register<ILoggingProvider, DefaultLoggingProvider>();
+ TangoIOC.Default.Register<IFileSystemProvider, DefaultFileSystemProvider>();
TangoIOC.Default.Register<MainWindowVM>();
TangoIOC.Default.Register<MainViewVM>();
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/FileSystem/DefaultFileSystemService.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/FileSystem/DefaultFileSystemService.cs
new file mode 100644
index 000000000..ffbba2e7a
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/FileSystem/DefaultFileSystemService.cs
@@ -0,0 +1,202 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.IO.Compression;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.Core.DI;
+using Tango.FileSystem;
+using Tango.FileSystem.Network;
+using Tango.Integration.ExternalBridge;
+using Tango.PPC.Common.ExternalBridge;
+using Tango.Transport;
+
+namespace Tango.PPC.Common.FileSystem
+{
+ [TangoCreateWhenRegistered]
+ public class DefaultFileSystemService : ExtendedObject, IFileSystemService, IExternalBridgeRequestHandler
+ {
+ private enum FileSystemOperationMode
+ {
+ Upload,
+ Download
+ }
+
+ private class FileSystemOperation
+ {
+ public FileSystemOperationMode Mode { get; set; }
+ public String Id { get; set; }
+ public String Path { get; set; }
+
+ public FileSystemOperation(FileSystemOperationMode mode, String path)
+ {
+ Mode = mode;
+ Id = Guid.NewGuid().ToString();
+ Path = path;
+ }
+ }
+
+ private FileSystemManager _manager;
+ private Dictionary<String, FileSystemOperation> _operations;
+
+ public bool Enabled { get; set; } = true;
+
+ public DefaultFileSystemService(IPPCExternalBridgeService externalBridge)
+ {
+ _manager = new FileSystemManager();
+ _operations = new Dictionary<string, FileSystemOperation>();
+ externalBridge.RegisterRequestHandler(this);
+ }
+
+ [ExternalBridgeRequestHandlerMethod(typeof(GetFileSystemItemRequest))]
+ public async void OnGetFileSystemItemRequest(GetFileSystemItemRequest request, String token, ExternalBridgeReceiver receiver)
+ {
+ try
+ {
+ FileSystemItemDTO dto = _manager.GetFolder(request);
+ await receiver.SendGenericResponse(new GetFileSystemItemResponse() { FileSystemItem = dto }, token);
+ }
+ catch (Exception ex)
+ {
+ await receiver.SendErrorResponse(ex, token);
+ }
+ }
+
+ [ExternalBridgeRequestHandlerMethod(typeof(FileUploadRequest))]
+ public async void OnFileUploadRequest(FileUploadRequest request, String token, ExternalBridgeReceiver receiver)
+ {
+ try
+ {
+ using (var stream = new FileStream(request.Path, FileMode.Create)) { }
+
+ FileSystemOperation operation = new FileSystemOperation(FileSystemOperationMode.Upload, request.Path);
+ _operations.Add(operation.Id, operation);
+
+ await receiver.SendGenericResponse(new FileUploadResponse() { OperationId = operation.Id }, token);
+ }
+ catch (Exception ex)
+ {
+ await receiver.SendErrorResponse(ex, token);
+ }
+ }
+
+ [ExternalBridgeRequestHandlerMethod(typeof(FileDownloadRequest))]
+ public async void OnFileDownloadRequest(FileDownloadRequest request, String token, ExternalBridgeReceiver receiver)
+ {
+ try
+ {
+ if (!File.Exists(request.Path))
+ {
+ await receiver.SendErrorResponse(new FileNotFoundException("Could not find the specified file."), token);
+ return;
+ }
+
+ FileSystemOperation operation = new FileSystemOperation(FileSystemOperationMode.Download, request.Path);
+
+ _operations.Add(operation.Id, operation);
+
+ await receiver.SendGenericResponse(new FileDownloadResponse()
+ {
+ OperationId = operation.Id,
+ Length = new FileInfo(request.Path).Length
+ }, token);
+ }
+ catch (Exception ex)
+ {
+ await receiver.SendErrorResponse(ex, token);
+ }
+ }
+
+ [ExternalBridgeRequestHandlerMethod(typeof(ChunkUploadRequest))]
+ public async void OnChunkUploadRequest(ChunkUploadRequest request, String token, ExternalBridgeReceiver receiver)
+ {
+ try
+ {
+ FileSystemOperation operation;
+ _operations.TryGetValue(request.OperationId, out operation);
+
+ if (operation == null)
+ {
+ await receiver.SendErrorResponse(new ArgumentException("Invalid operation id."), token);
+ return;
+ }
+
+ using (var stream = new FileStream(operation.Path, FileMode.Append))
+ {
+ stream.Write(request.Data, 0, request.Data.Length);
+ }
+
+ await receiver.SendGenericResponse(new ChunkUploadResponse(), token);
+ }
+ catch (Exception ex)
+ {
+ await receiver.SendErrorResponse(ex, token);
+ }
+ }
+
+ [ExternalBridgeRequestHandlerMethod(typeof(ChunkDownloadRequest))]
+ public async void OnChunkDownloadRequest(ChunkDownloadRequest request, String token, ExternalBridgeReceiver receiver)
+ {
+ FileSystemOperation operation;
+ _operations.TryGetValue(request.OperationId, out operation);
+
+ if (operation == null)
+ {
+ await receiver.SendErrorResponse(new ArgumentException("Invalid operation id."), token);
+ return;
+ }
+
+ using (FileStream stream = new FileStream(operation.Path, FileMode.Open))
+ {
+ stream.Position = request.Position;
+ byte[] data = new byte[Math.Min(request.MaxChunkSize, stream.Length - stream.Position)];
+ await stream.ReadAsync(data, 0, data.Length);
+ await receiver.SendGenericResponse(new ChunkDownloadResponse()
+ {
+ Data = data
+ }, token);
+ }
+ }
+
+ [ExternalBridgeRequestHandlerMethod(typeof(AbortOperationRequest))]
+ public async void OnAbortOperationRequest(AbortOperationRequest request, String token, ExternalBridgeReceiver receiver)
+ {
+ FileSystemOperation operation;
+ _operations.TryGetValue(request.OperationId, out operation);
+
+ if (operation == null)
+ {
+ await receiver.SendErrorResponse(new ArgumentException("Invalid operation id."), token);
+ return;
+ }
+
+ try
+ {
+ if (operation.Mode == FileSystemOperationMode.Upload)
+ {
+ if (File.Exists(operation.Path))
+ {
+ File.Delete(operation.Path);
+ }
+ else if (Directory.Exists(operation.Path))
+ {
+ Directory.Delete(operation.Path, true);
+ }
+ }
+
+ await receiver.SendGenericResponse(new AbortOperationResponse(), token);
+ }
+ catch (Exception ex)
+ {
+ await receiver.SendErrorResponse(ex, token);
+ }
+ }
+
+ public void OnReceiverDisconnected(ExternalBridgeReceiver receiver)
+ {
+
+ }
+ }
+}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/FileSystem/IFileSystemService.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/FileSystem/IFileSystemService.cs
new file mode 100644
index 000000000..050bb1cd6
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/FileSystem/IFileSystemService.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.PPC.Common.FileSystem
+{
+ public interface IFileSystemService
+ {
+ bool Enabled { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj
index 4551fe427..664e9e228 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj
@@ -152,6 +152,8 @@
<Compile Include="ExtensionMethods\ObservableCollectionExtensions.cs" />
<Compile Include="ExternalBridge\IPPCExternalBridgeService.cs" />
<Compile Include="ExternalBridge\PPCExternalBridgeService.cs" />
+ <Compile Include="FileSystem\DefaultFileSystemService.cs" />
+ <Compile Include="FileSystem\IFileSystemService.cs" />
<Compile Include="Helpers\KeyboardHelper.cs" />
<Compile Include="HotSpot\DefaultHotSpotProvider.cs" />
<Compile Include="HotSpot\IHotSpotProvider.cs" />
@@ -368,6 +370,10 @@
<Project>{4399AF76-DB52-4CFB-8020-6F85BDB29FD5}</Project>
<Name>Tango.Explorer</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Tango.FileSystem\Tango.FileSystem.csproj">
+ <Project>{c6ebbbbe-2123-44dc-aef7-a0d47d736ac0}</Project>
+ <Name>Tango.FileSystem</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Tango.Integration\Tango.Integration.csproj">
<Project>{4206ac58-3b57-4699-8835-90bf6db01a61}</Project>
<Name>Tango.Integration</Name>
@@ -446,7 +452,7 @@
</Target>
<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
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs
index 9e150221d..edc9cb1cd 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs
@@ -13,6 +13,7 @@ using Tango.PPC.Common.Console;
using Tango.PPC.Common.Diagnostics;
using Tango.PPC.Common.EventLogging;
using Tango.PPC.Common.ExternalBridge;
+using Tango.PPC.Common.FileSystem;
using Tango.PPC.Common.HotSpot;
using Tango.PPC.Common.MachineSetup;
using Tango.PPC.Common.MachineUpdate;
@@ -86,6 +87,7 @@ namespace Tango.PPC.UI
TangoIOC.Default.Unregister<IRemoteDesktopService>();
TangoIOC.Default.Unregister<IPerformanceService>();
TangoIOC.Default.Unregister<ISystemInfoService>();
+ TangoIOC.Default.Unregister<IFileSystemService>();
if (App.StartupArgs.Contains("-webDebug"))
{
@@ -123,6 +125,7 @@ namespace Tango.PPC.UI
TangoIOC.Default.Register<IBackupManager, DefaultBackupManager>();
TangoIOC.Default.Register<IPerformanceService, DefaultPerformanceService>();
TangoIOC.Default.Register<ISystemInfoService, DefaultSystemInfoService>();
+ TangoIOC.Default.Register<IFileSystemService, DefaultFileSystemService>();
TangoIOC.Default.Register<LoadingViewVM>();
TangoIOC.Default.Register<MainViewVM>();
diff --git a/Software/Visual_Studio/Tango.FileSystem/FileSystemDataGrid.cs b/Software/Visual_Studio/Tango.FileSystem/FileSystemDataGrid.cs
new file mode 100644
index 000000000..c1c31cf95
--- /dev/null
+++ b/Software/Visual_Studio/Tango.FileSystem/FileSystemDataGrid.cs
@@ -0,0 +1,30 @@
+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.FileSystem
+{
+ public class FileSystemDataGrid : DataGrid
+ {
+ static FileSystemDataGrid()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(FileSystemDataGrid), new FrameworkPropertyMetadata(typeof(FileSystemDataGrid)));
+ }
+
+ protected override DependencyObject GetContainerForItemOverride()
+ {
+ return new FileSystemDataGridRow();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.FileSystem/FileSystemDataGridRow.cs b/Software/Visual_Studio/Tango.FileSystem/FileSystemDataGridRow.cs
new file mode 100644
index 000000000..4cc67f888
--- /dev/null
+++ b/Software/Visual_Studio/Tango.FileSystem/FileSystemDataGridRow.cs
@@ -0,0 +1,40 @@
+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.FileSystem
+{
+ public class FileSystemDataGridRow : DataGridRow
+ {
+ public ICommand DoubleClickCommand
+ {
+ get { return (ICommand)GetValue(DoubleClickCommandProperty); }
+ set { SetValue(DoubleClickCommandProperty, value); }
+ }
+ public static readonly DependencyProperty DoubleClickCommandProperty =
+ DependencyProperty.Register("DoubleClickCommand", typeof(ICommand), typeof(FileSystemDataGridRow), new PropertyMetadata(null));
+
+ protected override void OnPreviewMouseDoubleClick(MouseButtonEventArgs e)
+ {
+ base.OnPreviewMouseDoubleClick(e);
+
+ DoubleClickCommand?.Execute(DataContext);
+ }
+
+ static FileSystemDataGridRow()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(FileSystemDataGridRow), new FrameworkPropertyMetadata(typeof(FileSystemDataGridRow)));
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.FileSystem/FileSystemItem.cs b/Software/Visual_Studio/Tango.FileSystem/FileSystemItem.cs
index 6f8190f6c..536409f63 100644
--- a/Software/Visual_Studio/Tango.FileSystem/FileSystemItem.cs
+++ b/Software/Visual_Studio/Tango.FileSystem/FileSystemItem.cs
@@ -52,14 +52,15 @@ namespace Tango.FileSystem
{
DriveType = dto.DriveType,
Label = dto.DriveLabel,
- Items = dto.Items.Select(x => FromDTO(x)).ToObservableCollection()
+ Items = dto.Items?.Select(x => FromDTO(x)).ToObservableCollection()
};
}
else if (dto.Type == FileSystemItemType.Folder)
{
item = new FolderItem()
{
- Items = dto.Items.Select(x => FromDTO(x)).ToObservableCollection()
+ Items = dto.Items?.Select(x => FromDTO(x)).ToObservableCollection(),
+ IsRoot = dto.IsRoot,
};
}
else if (dto.Type == FileSystemItemType.File)
diff --git a/Software/Visual_Studio/Tango.FileSystem/FileSystemManager.cs b/Software/Visual_Studio/Tango.FileSystem/FileSystemManager.cs
index 9a051793d..f0b86becf 100644
--- a/Software/Visual_Studio/Tango.FileSystem/FileSystemManager.cs
+++ b/Software/Visual_Studio/Tango.FileSystem/FileSystemManager.cs
@@ -16,7 +16,7 @@ namespace Tango.FileSystem
folder.Path = "This PC";
folder.IsRoot = true;
folder.Type = FileSystemItemType.Folder;
- folder.Items = DriveInfo.GetDrives().Select(x => new FileSystemItemDTO()
+ folder.Items = DriveInfo.GetDrives().Where(x => x.DriveType == DriveType.Fixed || x.DriveType == DriveType.Removable || x.DriveType == DriveType.Network).Select(x => new FileSystemItemDTO()
{
Path = x.RootDirectory.FullName,
DriveType = x.DriveType,
@@ -27,21 +27,26 @@ namespace Tango.FileSystem
return folder;
}
- public FileSystemItemDTO GetFolder(String path)
+ public FileSystemItemDTO GetFolder(GetFileSystemItemRequest request)
{
List<FileSystemItemDTO> items = new List<FileSystemItemDTO>();
- if (String.IsNullOrWhiteSpace(path))
+ if (request.SpecialFolder.HasValue)
+ {
+ request.Path = Environment.GetFolderPath(request.SpecialFolder.Value);
+ }
+
+ if (String.IsNullOrWhiteSpace(request.Path))
{
return GetRoot();
}
- if (!Directory.Exists(path))
+ if (!Directory.Exists(request.Path))
{
throw new DirectoryNotFoundException("The specified directory could not be located.");
}
- foreach (var directory in Directory.GetDirectories(path))
+ foreach (var directory in Directory.GetDirectories(request.Path))
{
items.Add(new FileSystemItemDTO()
{
@@ -51,7 +56,7 @@ namespace Tango.FileSystem
});
}
- foreach (var file in Directory.GetFiles(path))
+ foreach (var file in Directory.GetFiles(request.Path))
{
items.Add(new FileSystemItemDTO()
{
@@ -64,8 +69,8 @@ namespace Tango.FileSystem
return new FileSystemItemDTO()
{
- Path = path,
- Type = path.Length == 3 ? FileSystemItemType.Drive : FileSystemItemType.Folder,
+ Path = request.Path,
+ Type = request.Path.Length == 3 ? FileSystemItemType.Drive : FileSystemItemType.Folder,
Items = items
};
}
@@ -74,7 +79,7 @@ namespace Tango.FileSystem
{
if (Directory.Exists(path))
{
- Directory.Delete(path);
+ Directory.Delete(path, true);
}
else if (File.Exists(path))
{
diff --git a/Software/Visual_Studio/Tango.FileSystem/Network/AbortOperationRequest.cs b/Software/Visual_Studio/Tango.FileSystem/Network/AbortOperationRequest.cs
new file mode 100644
index 000000000..3e912b9f0
--- /dev/null
+++ b/Software/Visual_Studio/Tango.FileSystem/Network/AbortOperationRequest.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FileSystem.Network
+{
+ public class AbortOperationRequest
+ {
+ public String OperationId { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.FileSystem/Network/AbortOperationResponse.cs b/Software/Visual_Studio/Tango.FileSystem/Network/AbortOperationResponse.cs
new file mode 100644
index 000000000..c5669ad48
--- /dev/null
+++ b/Software/Visual_Studio/Tango.FileSystem/Network/AbortOperationResponse.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FileSystem.Network
+{
+ public class AbortOperationResponse
+ {
+ }
+}
diff --git a/Software/Visual_Studio/Tango.FileSystem/Network/ChunkDownloadRequest.cs b/Software/Visual_Studio/Tango.FileSystem/Network/ChunkDownloadRequest.cs
new file mode 100644
index 000000000..16951930e
--- /dev/null
+++ b/Software/Visual_Studio/Tango.FileSystem/Network/ChunkDownloadRequest.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FileSystem.Network
+{
+ public class ChunkDownloadRequest
+ {
+ public String OperationId { get; set; }
+ public long Position { get; set; }
+ public long MaxChunkSize { get; set; } = 1024 * 1024;
+ }
+}
diff --git a/Software/Visual_Studio/Tango.FileSystem/Network/StartFileDownloadResponse.cs b/Software/Visual_Studio/Tango.FileSystem/Network/ChunkDownloadResponse.cs
index 187d15254..df72e193f 100644
--- a/Software/Visual_Studio/Tango.FileSystem/Network/StartFileDownloadResponse.cs
+++ b/Software/Visual_Studio/Tango.FileSystem/Network/ChunkDownloadResponse.cs
@@ -6,10 +6,8 @@ using System.Threading.Tasks;
namespace Tango.FileSystem.Network
{
- public class StartFileDownloadResponse
+ public class ChunkDownloadResponse
{
public byte[] Data { get; set; }
- public long Position { get; set; }
- public long Length { get; set; }
}
}
diff --git a/Software/Visual_Studio/Tango.FileSystem/Network/ChunkUploadRequest.cs b/Software/Visual_Studio/Tango.FileSystem/Network/ChunkUploadRequest.cs
new file mode 100644
index 000000000..98a27efd2
--- /dev/null
+++ b/Software/Visual_Studio/Tango.FileSystem/Network/ChunkUploadRequest.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FileSystem.Network
+{
+ public class ChunkUploadRequest
+ {
+ public String OperationId { get; set; }
+ public byte[] Data { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.FileSystem/Network/ChunkUploadResponse.cs b/Software/Visual_Studio/Tango.FileSystem/Network/ChunkUploadResponse.cs
new file mode 100644
index 000000000..5cd6a3f80
--- /dev/null
+++ b/Software/Visual_Studio/Tango.FileSystem/Network/ChunkUploadResponse.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FileSystem.Network
+{
+ public class ChunkUploadResponse
+ {
+
+ }
+}
diff --git a/Software/Visual_Studio/Tango.FileSystem/Network/StartFileDownloadRequest.cs b/Software/Visual_Studio/Tango.FileSystem/Network/FileDownloadRequest.cs
index aac03af38..b63937f8b 100644
--- a/Software/Visual_Studio/Tango.FileSystem/Network/StartFileDownloadRequest.cs
+++ b/Software/Visual_Studio/Tango.FileSystem/Network/FileDownloadRequest.cs
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace Tango.FileSystem.Network
{
- public class StartFileDownloadRequest
+ public class FileDownloadRequest
{
public String Path { get; set; }
}
diff --git a/Software/Visual_Studio/Tango.FileSystem/Network/StartFolderDownloadResponse.cs b/Software/Visual_Studio/Tango.FileSystem/Network/FileDownloadResponse.cs
index c48d4c04c..c57a9bad6 100644
--- a/Software/Visual_Studio/Tango.FileSystem/Network/StartFolderDownloadResponse.cs
+++ b/Software/Visual_Studio/Tango.FileSystem/Network/FileDownloadResponse.cs
@@ -6,10 +6,9 @@ using System.Threading.Tasks;
namespace Tango.FileSystem.Network
{
- public class StartFolderDownloadResponse
+ public class FileDownloadResponse
{
- public byte[] ZipData { get; set; }
- public long Position { get; set; }
public long Length { get; set; }
+ public String OperationId { get; set; }
}
}
diff --git a/Software/Visual_Studio/Tango.FileSystem/Network/FileUploadRequest.cs b/Software/Visual_Studio/Tango.FileSystem/Network/FileUploadRequest.cs
index 50c35c584..f3cbc2d54 100644
--- a/Software/Visual_Studio/Tango.FileSystem/Network/FileUploadRequest.cs
+++ b/Software/Visual_Studio/Tango.FileSystem/Network/FileUploadRequest.cs
@@ -9,6 +9,5 @@ namespace Tango.FileSystem.Network
public class FileUploadRequest
{
public String Path { get; set; }
- public byte[] Data { get; set; }
}
}
diff --git a/Software/Visual_Studio/Tango.FileSystem/Network/FileUploadResponse.cs b/Software/Visual_Studio/Tango.FileSystem/Network/FileUploadResponse.cs
index 4f4bc0d52..c0af1a797 100644
--- a/Software/Visual_Studio/Tango.FileSystem/Network/FileUploadResponse.cs
+++ b/Software/Visual_Studio/Tango.FileSystem/Network/FileUploadResponse.cs
@@ -8,6 +8,6 @@ namespace Tango.FileSystem.Network
{
public class FileUploadResponse
{
-
+ public String OperationId { get; set; }
}
}
diff --git a/Software/Visual_Studio/Tango.FileSystem/Network/StartFolderDownloadRequest.cs b/Software/Visual_Studio/Tango.FileSystem/Network/FolderDownloadRequest.cs
index e7989bd98..cb65a8942 100644
--- a/Software/Visual_Studio/Tango.FileSystem/Network/StartFolderDownloadRequest.cs
+++ b/Software/Visual_Studio/Tango.FileSystem/Network/FolderDownloadRequest.cs
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace Tango.FileSystem.Network
{
- public class StartFolderDownloadRequest
+ public class FolderDownloadRequest
{
public String Path { get; set; }
}
diff --git a/Software/Visual_Studio/Tango.FileSystem/Network/FolderDownloadResponse.cs b/Software/Visual_Studio/Tango.FileSystem/Network/FolderDownloadResponse.cs
new file mode 100644
index 000000000..239ff2e59
--- /dev/null
+++ b/Software/Visual_Studio/Tango.FileSystem/Network/FolderDownloadResponse.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FileSystem.Network
+{
+ public class FolderDownloadResponse
+ {
+ public long Length { get; set; }
+ public String OperationId { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.FileSystem/Network/GetFileSystemItemRequest.cs b/Software/Visual_Studio/Tango.FileSystem/Network/GetFileSystemItemRequest.cs
index f69c7bd98..1ed6c19e4 100644
--- a/Software/Visual_Studio/Tango.FileSystem/Network/GetFileSystemItemRequest.cs
+++ b/Software/Visual_Studio/Tango.FileSystem/Network/GetFileSystemItemRequest.cs
@@ -3,11 +3,13 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using static System.Environment;
namespace Tango.FileSystem.Network
{
public class GetFileSystemItemRequest
{
public String Path { get; set; }
+ public SpecialFolder? SpecialFolder { get; set; }
}
}
diff --git a/Software/Visual_Studio/Tango.FileSystem/Tango.FileSystem.csproj b/Software/Visual_Studio/Tango.FileSystem/Tango.FileSystem.csproj
index 90dfd78d2..733493f02 100644
--- a/Software/Visual_Studio/Tango.FileSystem/Tango.FileSystem.csproj
+++ b/Software/Visual_Studio/Tango.FileSystem/Tango.FileSystem.csproj
@@ -50,6 +50,14 @@
</ItemGroup>
<ItemGroup>
<Compile Include="DragItem.cs" />
+ <Compile Include="FileSystemDataGrid.cs" />
+ <Compile Include="FileSystemDataGridRow.cs" />
+ <Compile Include="Network\AbortOperationRequest.cs" />
+ <Compile Include="Network\AbortOperationResponse.cs" />
+ <Compile Include="Network\ChunkUploadRequest.cs" />
+ <Compile Include="Network\ChunkUploadResponse.cs" />
+ <Compile Include="Network\ChunkDownloadRequest.cs" />
+ <Compile Include="Network\ChunkDownloadResponse.cs" />
<Compile Include="VirtualFileDataObject.cs" />
<Page Include="Themes\Generic.xaml">
<Generator>MSBuild:Compile</Generator>
@@ -73,10 +81,10 @@
<Compile Include="Network\FileUploadResponse.cs" />
<Compile Include="Network\GetFileSystemItemRequest.cs" />
<Compile Include="Network\GetFileSystemItemResponse.cs" />
- <Compile Include="Network\StartFileDownloadRequest.cs" />
- <Compile Include="Network\StartFileDownloadResponse.cs" />
- <Compile Include="Network\StartFolderDownloadRequest.cs" />
- <Compile Include="Network\StartFolderDownloadResponse.cs" />
+ <Compile Include="Network\FileDownloadRequest.cs" />
+ <Compile Include="Network\FileDownloadResponse.cs" />
+ <Compile Include="Network\FolderDownloadRequest.cs" />
+ <Compile Include="Network\FolderDownloadResponse.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
diff --git a/Software/Visual_Studio/Tango.FileSystem/Themes/Generic.xaml b/Software/Visual_Studio/Tango.FileSystem/Themes/Generic.xaml
index c9e561e29..f793be947 100644
--- a/Software/Visual_Studio/Tango.FileSystem/Themes/Generic.xaml
+++ b/Software/Visual_Studio/Tango.FileSystem/Themes/Generic.xaml
@@ -7,6 +7,14 @@
<converters:ByteArrayToFileSizeConverter x:Key="ByteArrayToFileSizeConverter" />
<converters:DateTimeUtcToLocalDateTime x:Key="DateTimeUtcToLocalDateTime" />
+ <Style TargetType="{x:Type local:FileSystemDataGridRow}" BasedOn="{StaticResource {x:Type DataGridRow}}">
+ <Setter Property="DoubleClickCommand" Value="{Binding RelativeSource={RelativeSource AncestorType=local:FileExplorerControl},Path=ItemDoubleClickedCommand}"></Setter>
+ </Style>
+
+ <Style TargetType="{x:Type local:FileSystemDataGrid}" BasedOn="{StaticResource {x:Type DataGrid}}">
+
+ </Style>
+
<Style x:Key="FileSystemCellStyle" TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
@@ -92,7 +100,7 @@
</Style.Triggers>
</Style>
</Grid.Style>
- <DataGrid x:Name="PART_datagrid" ItemsSource="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=CurrentItem.Items}" CellStyle="{StaticResource FileSystemCellStyle}">
+ <local:FileSystemDataGrid x:Name="PART_datagrid" ItemsSource="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=CurrentItem.Items}" CellStyle="{StaticResource FileSystemCellStyle}">
<DataGrid.Style>
<Style TargetType="DataGrid" BasedOn="{StaticResource {x:Type DataGrid}}">
<Setter Property="Background" Value="Transparent"></Setter>
@@ -119,11 +127,6 @@
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DockPanel Background="Transparent">
- <DockPanel.InputBindings>
- <MouseBinding MouseAction="LeftDoubleClick"
- Command="{Binding RelativeSource={RelativeSource AncestorType=local:FileExplorerControl},Path=ItemDoubleClickedCommand}"
- CommandParameter="{Binding}" />
- </DockPanel.InputBindings>
<Image Width="18" Height="18" RenderOptions.BitmapScalingMode="Fant" Stretch="Uniform" HorizontalAlignment="Center" VerticalAlignment="Center">
<Image.Style>
<Style TargetType="Image">
@@ -150,11 +153,6 @@
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DockPanel Background="Transparent">
- <DockPanel.InputBindings>
- <MouseBinding MouseAction="LeftDoubleClick"
- Command="{Binding RelativeSource={RelativeSource AncestorType=local:FileExplorerControl},Path=ItemDoubleClickedCommand}"
- CommandParameter="{Binding}" />
- </DockPanel.InputBindings>
<TextBlock Text="{Binding DateModified,Converter={StaticResource DateTimeUtcToLocalDateTime}}" VerticalAlignment="Center"></TextBlock>
</DockPanel>
</DataTemplate>
@@ -164,11 +162,6 @@
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DockPanel Background="Transparent">
- <DockPanel.InputBindings>
- <MouseBinding MouseAction="LeftDoubleClick"
- Command="{Binding RelativeSource={RelativeSource AncestorType=local:FileExplorerControl},Path=ItemDoubleClickedCommand}"
- CommandParameter="{Binding}" />
- </DockPanel.InputBindings>
<TextBlock Text="{Binding Description}" VerticalAlignment="Center"></TextBlock>
</DockPanel>
</DataTemplate>
@@ -178,11 +171,6 @@
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DockPanel Background="Transparent">
- <DockPanel.InputBindings>
- <MouseBinding MouseAction="LeftDoubleClick"
- Command="{Binding RelativeSource={RelativeSource AncestorType=local:FileExplorerControl},Path=ItemDoubleClickedCommand}"
- CommandParameter="{Binding}" />
- </DockPanel.InputBindings>
<TextBlock Text="{Binding Size,Converter={StaticResource ByteArrayToFileSizeConverter}}" VerticalAlignment="Center">
<TextBlock.Style>
<Style TargetType="TextBlock">
@@ -200,7 +188,7 @@
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
- </DataGrid>
+ </local:FileSystemDataGrid>
</Grid>
</Grid>
</Border>