diff options
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> |
