aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Ben Shabat <Roy.mail.net@gmail.com>2020-03-22 14:53:04 +0200
committerRoy Ben Shabat <Roy.mail.net@gmail.com>2020-03-22 14:53:04 +0200
commit5a5b63afd5c4ff1d6a1dbd6996ed0a5a494387d0 (patch)
tree365313831f036950a1878a8ccd92ab938a7bfabb
parentd48b2d23515d06a21ad241380986bf8f31773195 (diff)
downloadTango-5a5b63afd5c4ff1d6a1dbd6996ed0a5a494387d0.tar.gz
Tango-5a5b63afd5c4ff1d6a1dbd6996ed0a5a494387d0.zip
Working on storage provider.
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/FileSystemViewVM.cs8
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/FileSystemControl.xaml4
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs7
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Storage/IStorageProvider.cs36
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Storage/IStorageResult.cs13
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Storage/MultiStorageResult.cs24
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Storage/SingleStorageResult.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/Storage/DefaultStorageProvider.cs389
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj8
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs4
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoginViewVM.cs5
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Views/MainView.xaml178
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Views/MainView.xaml.cs13
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/packages.config2
-rw-r--r--Software/Visual_Studio/Tango.FileSystem/FileSystemManager.cs22
16 files changed, 732 insertions, 4 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 f074294b2..4e2ca1882 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
@@ -336,9 +336,13 @@ namespace Tango.FSE.PPCConsole.ViewModels
}
}
- private void DownloadSelectedItems(List<FileSystemItem> items)
+ private async void DownloadSelectedItems(List<FileSystemItem> items)
{
-
+ var result = await StorageProvider.SelectFolder("Select download destination folder");
+ if (result)
+ {
+ Debug.WriteLine($"Download to {result.SelectedItem}");
+ }
}
private async void RenameFileSystemItem(FileSystemItem item)
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 62de7cf48..fcea26001 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/FileSystemControl.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/FileSystemControl.xaml
@@ -93,7 +93,7 @@
</Border.ContextMenu>
<Grid Background="Transparent">
- <ListBox x:Name="PART_listbox" Background="Transparent" SelectionMode="Extended" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto" ItemsSource="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=CurrentItem.Items}" SelectedItem="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=SelectedItem,Mode=TwoWay}">
+ <ListBox x:Name="PART_listbox" IsTextSearchEnabled="True" TextSearch.TextPath="Name" Background="Transparent" SelectionMode="Extended" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto" ItemsSource="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=CurrentItem.Items}" SelectedItem="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=SelectedItem,Mode=TwoWay}">
<ListBox.Style>
<Style TargetType="ListBox" BasedOn="{StaticResource {x:Type ListBox}}">
<Setter Property="Visibility" Value="Collapsed"></Setter>
@@ -164,7 +164,7 @@
</Style.Triggers>
</Style>
</Grid.Style>
- <local:FileSystemDataGrid x:Name="PART_datagrid" ItemsSource="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=CurrentItem.Items}" CellStyle="{StaticResource FileSystemCellStyle}">
+ <local:FileSystemDataGrid x:Name="PART_datagrid" IsTextSearchEnabled="True" TextSearch.TextPath="Name" 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>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs
index b3e832b58..232d1bd45 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs
@@ -26,6 +26,7 @@ using Tango.FSE.Common.Notifications;
using Tango.FSE.Common.Performance;
using Tango.FSE.Common.RemoteDesktop;
using Tango.FSE.Common.Resolution;
+using Tango.FSE.Common.Storage;
using Tango.FSE.Common.SystemInfo;
using Tango.Settings;
using Tango.SharedUI;
@@ -126,6 +127,12 @@ namespace Tango.FSE.Common
public IFileSystemProvider FileSystemProvider { get; set; }
/// <summary>
+ /// Gets or sets the storage provider.
+ /// </summary>
+ [TangoInject]
+ public IStorageProvider StorageProvider { get; set; }
+
+ /// <summary>
/// Gets or sets the FSE service.
/// </summary>
[TangoInject]
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Storage/IStorageProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Storage/IStorageProvider.cs
new file mode 100644
index 000000000..00ec312a5
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Storage/IStorageProvider.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core.Commands;
+using Tango.FileSystem;
+
+namespace Tango.FSE.Common.Storage
+{
+ public interface IStorageProvider
+ {
+ bool UseNativeDialogs { get; set; }
+ bool IsOpened { get; }
+ bool IsBusy { get; }
+ String Title { get; }
+ String FileName { get; set; }
+ FileSystemItem CurrentItem { get; set; }
+ String CurrentPath { get; set; }
+ ObservableCollection<FileSystemItem> SelectedItems { get; set; }
+ List<DriveItem> Drives { get; }
+ RelayCommand OKCommand { get; }
+ RelayCommand CancelCommand { get; }
+ RelayCommand BackCommand { get; }
+ RelayCommand NavigateCommand { get; }
+ RelayCommand<FileSystemItem> OpenCommand { get; }
+ RelayCommand<String> NavigateSpecialFolderCommand { get; set; }
+ RelayCommand<String> NavigateToFolderCommand { get; set; }
+
+ Task<SingleStorageResult> OpenFile(String title, String filter = null, String initialFolder = null);
+ Task<MultiStorageResult> OpenFiles(String title, String filter = null, String initialFolder = null);
+ Task<SingleStorageResult> SaveFile(String title, String filter = null, String defaultFileName = null, String defaultExtension = null, String initialFolder = null);
+ Task<SingleStorageResult> SelectFolder(String title, String initialFolder = null);
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Storage/IStorageResult.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Storage/IStorageResult.cs
new file mode 100644
index 000000000..f3c7ddb15
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Storage/IStorageResult.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Common.Storage
+{
+ public interface IStorageResult
+ {
+ bool Confirmed { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Storage/MultiStorageResult.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Storage/MultiStorageResult.cs
new file mode 100644
index 000000000..0331d021b
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Storage/MultiStorageResult.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Common.Storage
+{
+ public class MultiStorageResult : IStorageResult
+ {
+ public bool Confirmed { get; set; }
+ public List<String> SelectedItems { get; set; }
+
+ public MultiStorageResult()
+ {
+ SelectedItems = new List<string>();
+ }
+
+ public static implicit operator bool(MultiStorageResult result)
+ {
+ return result.SelectedItems != null && result.SelectedItems.Count > 0 && result.Confirmed;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Storage/SingleStorageResult.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Storage/SingleStorageResult.cs
new file mode 100644
index 000000000..0b63aa030
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Storage/SingleStorageResult.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Common.Storage
+{
+ public class SingleStorageResult : IStorageResult
+ {
+ public String SelectedItem { get; set; }
+ public bool Confirmed { get; set; }
+
+ public static implicit operator bool(SingleStorageResult result)
+ {
+ return result.SelectedItem != null && result.Confirmed;
+ }
+ }
+}
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 02df7140f..11a308e3e 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
@@ -140,6 +140,10 @@
<Compile Include="Resolution\IResolutionService.cs" />
<Compile Include="Resolution\ResolutionHelper.cs" />
<Compile Include="Resolution\ResolutionMode.cs" />
+ <Compile Include="Storage\IStorageProvider.cs" />
+ <Compile Include="Storage\IStorageResult.cs" />
+ <Compile Include="Storage\SingleStorageResult.cs" />
+ <Compile Include="Storage\MultiStorageResult.cs" />
<Compile Include="SystemInfo\ISystemInfoProvider.cs" />
<Compile Include="Threading\IDispatcherProvider.cs" />
<Compile Include="Web\FSEWebClient.cs" />
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Storage/DefaultStorageProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Storage/DefaultStorageProvider.cs
new file mode 100644
index 000000000..c37400cf6
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Storage/DefaultStorageProvider.cs
@@ -0,0 +1,389 @@
+using Microsoft.Win32;
+using Microsoft.WindowsAPICodePack.Dialogs;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Input;
+using Tango.Core;
+using Tango.Core.Commands;
+using Tango.Core.DI;
+using Tango.FileSystem;
+using Tango.FileSystem.Network;
+using Tango.FSE.Common.Notifications;
+using Tango.FSE.Common.Storage;
+
+namespace Tango.FSE.UI.Storage
+{
+ public class DefaultStorageProvider : ExtendedObject, IStorageProvider
+ {
+ private FileSystemManager _manager;
+ private Action _okCompletionAction;
+ private Action _cancelCompletionAction;
+
+ [TangoInject(Mode = TangoInjectMode.WhenAvailable)]
+ private INotificationProvider NotificationProvider { get; set; }
+
+ public bool UseNativeDialogs { get; set; } = false;
+
+ private bool _isOpened;
+ public bool IsOpened
+ {
+ get { return _isOpened; }
+ private set { _isOpened = value; RaisePropertyChangedAuto(); }
+ }
+
+ private String _title;
+ public String Title
+ {
+ get { return _title; }
+ private set { _title = value; RaisePropertyChangedAuto(); }
+ }
+
+ private String _fileName;
+ public String FileName
+ {
+ get { return _fileName; }
+ set { _fileName = value; RaisePropertyChangedAuto(); }
+ }
+
+ private FileSystemItem _currentItem;
+ public FileSystemItem CurrentItem
+ {
+ get { return _currentItem; }
+ set { _currentItem = value; RaisePropertyChangedAuto(); OnCurrentItemChanged(); }
+ }
+
+ private String _currentPath;
+ public String CurrentPath
+ {
+ get { return _currentPath; }
+ set { _currentPath = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _isBusy;
+ public bool IsBusy
+ {
+ get { return _isBusy; }
+ private set { _isBusy = value; RaisePropertyChangedAuto(); }
+ }
+
+ private List<DriveItem> _drives;
+ public List<DriveItem> Drives
+ {
+ get { return _drives; }
+ set { _drives = value; RaisePropertyChangedAuto(); }
+ }
+
+ public ObservableCollection<FileSystemItem> SelectedItems { get; set; }
+
+ public RelayCommand OKCommand { get; }
+ public RelayCommand CancelCommand { get; }
+ public RelayCommand BackCommand { get; set; }
+ public RelayCommand NavigateCommand { get; set; }
+ public RelayCommand<FileSystemItem> OpenCommand { get; set; }
+ public RelayCommand<String> NavigateSpecialFolderCommand { get; set; }
+ public RelayCommand<String> NavigateToFolderCommand { get; set; }
+
+ public DefaultStorageProvider()
+ {
+ _manager = new FileSystemManager();
+ SelectedItems = new ObservableCollection<FileSystemItem>();
+
+ NavigateCommand = new RelayCommand(NavigateToCurrentPath);
+ OpenCommand = new RelayCommand<FileSystemItem>(OpenFileSystemItem);
+ BackCommand = new RelayCommand(NavigateBack, () => !(CurrentItem is FolderItem) || !(CurrentItem as FolderItem).IsRoot);
+ NavigateSpecialFolderCommand = new RelayCommand<string>(NavigateToSpecialFolder);
+ NavigateToFolderCommand = new RelayCommand<string>(async (x) => await Navigate(x));
+ OKCommand = new RelayCommand(OnAccept);
+ CancelCommand = new RelayCommand(OnCancel);
+ }
+
+ public Task<SingleStorageResult> OpenFile(string title, string filter = null, string initialFolder = null)
+ {
+ if (UseNativeDialogs)
+ {
+ return OpenFileNative(title, filter, initialFolder);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public Task<MultiStorageResult> OpenFiles(string title, string filter = null, string initialFolder = null)
+ {
+ if (UseNativeDialogs)
+ {
+ return OpenFilesNative(title, filter, initialFolder);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public Task<SingleStorageResult> SaveFile(string title, string filter = null, string defaultFileName = null, string defaultExtension = null, string initialFolder = null)
+ {
+ if (UseNativeDialogs)
+ {
+ return SaveFileNative(title, filter, defaultFileName, defaultExtension, initialFolder);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public async Task<SingleStorageResult> SelectFolder(string title, string initialFolder = null)
+ {
+ if (UseNativeDialogs)
+ {
+ return await SelectFolderNative(title, initialFolder);
+ }
+ else
+ {
+ var _completionSource = new TaskCompletionSource<SingleStorageResult>();
+
+ var root = await _manager.GetFolder(String.Empty);
+ Drives = (root as IFileSystemContainer).Items.Cast<DriveItem>().ToList();
+
+ CurrentItem = await _manager.GetFolder(Environment.CurrentDirectory);
+ IsOpened = true;
+
+ _okCompletionAction = () =>
+ {
+ SingleStorageResult result = new SingleStorageResult()
+ {
+ Confirmed = true,
+ SelectedItem = SelectedItems.First().Path,
+ };
+
+ _completionSource.SetResult(result);
+ };
+
+ _cancelCompletionAction = () =>
+ {
+ _completionSource.SetResult(new SingleStorageResult());
+ };
+
+ return await _completionSource.Task;
+ }
+ }
+
+ #region Private Methods
+
+ private void OnAccept()
+ {
+ IsOpened = false;
+ _okCompletionAction?.Invoke();
+ }
+
+ private void OnCancel()
+ {
+ IsOpened = false;
+ _cancelCompletionAction?.Invoke();
+ }
+
+ private async void NavigateToSpecialFolder(string folder)
+ {
+ Environment.SpecialFolder specialFolder = (Environment.SpecialFolder)Enum.Parse(typeof(Environment.SpecialFolder), folder);
+ await Navigate(null, specialFolder);
+ }
+
+ private async void NavigateBack()
+ {
+ if (CurrentItem.Path.Length == 3)
+ {
+ await Navigate(null);
+ }
+ else
+ {
+ String parent = Path.GetDirectoryName(CurrentItem.Path);
+ await Navigate(parent);
+ }
+ }
+
+ private async void NavigateToCurrentPath()
+ {
+ await Navigate(CurrentPath);
+ }
+
+ private async void OpenFileSystemItem(FileSystemItem item)
+ {
+ if (item == null) return;
+
+ if (item.Type == FileSystemItemType.Folder || item.Type == FileSystemItemType.Drive)
+ {
+ await Navigate(item.Path);
+ }
+ else if (item.Type == FileSystemItemType.File)
+ {
+ //TODO: Download/Open file?...
+ }
+ }
+
+ private async Task Navigate(String path, Environment.SpecialFolder? specialFolder = null)
+ {
+ try
+ {
+ IsBusy = true;
+
+ Mouse.OverrideCursor = Cursors.AppStarting;
+
+ if (path != null)
+ {
+ CurrentItem = await _manager.GetFolder(path) as FileSystemItem;
+ }
+ else if (specialFolder != null)
+ {
+ CurrentItem = await _manager.GetFolder(specialFolder.Value) as FileSystemItem;
+ }
+ else
+ {
+ CurrentItem = await _manager.GetFolder(String.Empty) as FileSystemItem;
+ }
+ }
+ catch (Exception ex)
+ {
+ IsBusy = false;
+ Mouse.OverrideCursor = null;
+ await NotificationProvider.ShowError($"Error navigating to the specified path.\n{ex.FlattenMessage()}");
+ }
+ finally
+ {
+ IsBusy = false;
+ Mouse.OverrideCursor = null;
+ }
+ }
+
+ private void OnCurrentItemChanged()
+ {
+ CurrentPath = CurrentItem.Path;
+ InvalidateRelayCommands();
+ }
+
+ #endregion
+
+ #region Native
+
+ public Task<SingleStorageResult> OpenFileNative(string title, string filter = null, string initialFolder = null)
+ {
+ SingleStorageResult result = new SingleStorageResult();
+
+ OpenFileDialog dlg = new OpenFileDialog();
+ dlg.Multiselect = false;
+ dlg.Title = title;
+
+ if (filter != null)
+ {
+ dlg.Filter = filter;
+ }
+
+ if (initialFolder != null)
+ {
+ dlg.InitialDirectory = initialFolder;
+ }
+
+ if (dlg.ShowDialog(Application.Current.MainWindow).Value)
+ {
+ result.Confirmed = true;
+ result.SelectedItem = dlg.FileName;
+ }
+
+ return Task.FromResult(result);
+ }
+
+ public Task<MultiStorageResult> OpenFilesNative(string title, string filter = null, string initialFolder = null)
+ {
+ MultiStorageResult result = new MultiStorageResult();
+
+ OpenFileDialog dlg = new OpenFileDialog();
+ dlg.Multiselect = false;
+ dlg.Title = title;
+ dlg.Multiselect = true;
+
+ if (filter != null)
+ {
+ dlg.Filter = filter;
+ }
+
+ if (initialFolder != null)
+ {
+ dlg.InitialDirectory = initialFolder;
+ }
+
+ if (dlg.ShowDialog(Application.Current.MainWindow).Value)
+ {
+ result.Confirmed = true;
+ result.SelectedItems = dlg.FileNames.ToList();
+ }
+
+ return Task.FromResult(result);
+ }
+
+ public Task<SingleStorageResult> SaveFileNative(string title, string filter = null, string defaultFileName = null, string defaultExtension = null, string initialFolder = null)
+ {
+ SingleStorageResult result = new SingleStorageResult();
+
+ SaveFileDialog dlg = new SaveFileDialog();
+ dlg.Title = title;
+
+ if (defaultFileName != null)
+ {
+ dlg.FileName = defaultFileName;
+ }
+
+ if (defaultExtension != null)
+ {
+ dlg.DefaultExt = defaultExtension;
+ }
+
+ if (filter != null)
+ {
+ dlg.Filter = filter;
+ }
+
+ if (initialFolder != null)
+ {
+ dlg.InitialDirectory = initialFolder;
+ }
+
+ if (dlg.ShowDialog(Application.Current.MainWindow).Value)
+ {
+ result.Confirmed = true;
+ result.SelectedItem = dlg.FileName;
+ }
+
+ return Task.FromResult(result);
+ }
+
+ public Task<SingleStorageResult> SelectFolderNative(string title, string initialFolder = null)
+ {
+ SingleStorageResult result = new SingleStorageResult();
+
+ CommonOpenFileDialog dlg = new CommonOpenFileDialog();
+ dlg.Title = title;
+ dlg.IsFolderPicker = true;
+
+ if (initialFolder != null)
+ {
+ dlg.InitialDirectory = initialFolder;
+ }
+
+ if (dlg.ShowDialog(Application.Current.MainWindow) == CommonFileDialogResult.Ok)
+ {
+ result.Confirmed = true;
+ result.SelectedItem = dlg.FileName;
+ }
+
+ return Task.FromResult(result);
+ }
+
+ #endregion
+ }
+}
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 5a73dba99..ef32b02e5 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
@@ -26,6 +26,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
+ <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -61,6 +62,12 @@
<Reference Include="MaterialDesignThemes.Wpf, Version=3.0.1.920, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\MaterialDesignThemes.3.0.1\lib\net45\MaterialDesignThemes.Wpf.dll</HintPath>
</Reference>
+ <Reference Include="Microsoft.WindowsAPICodePack, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\WindowsAPICodePack-Core.1.1.1\lib\Microsoft.WindowsAPICodePack.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.WindowsAPICodePack.Shell, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\WindowsAPICodePack-Shell.1.1.1\lib\Microsoft.WindowsAPICodePack.Shell.dll</HintPath>
+ </Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
@@ -161,6 +168,7 @@
<Compile Include="Performance\DefaultPerformanceProvider.cs" />
<Compile Include="RemoteDesktop\DefaultRemoteDesktopProvider.cs" />
<Compile Include="Resolution\DefaultResolutionService.cs" />
+ <Compile Include="Storage\DefaultStorageProvider.cs" />
<Compile Include="SystemInfo\DefaultSystemInfoProvider.cs" />
<Compile Include="Threading\DefaultDispatcherProvider.cs" />
<Compile Include="ViewModelLocator.cs" />
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs
index 6a3cf610a..b7edc40a8 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs
@@ -20,6 +20,7 @@ using Tango.FSE.Common.Notifications;
using Tango.FSE.Common.Performance;
using Tango.FSE.Common.RemoteDesktop;
using Tango.FSE.Common.Resolution;
+using Tango.FSE.Common.Storage;
using Tango.FSE.Common.SystemInfo;
using Tango.FSE.Common.Threading;
using Tango.FSE.Common.Web;
@@ -37,6 +38,7 @@ using Tango.FSE.UI.Notifications;
using Tango.FSE.UI.Performance;
using Tango.FSE.UI.RemoteDesktop;
using Tango.FSE.UI.Resolution;
+using Tango.FSE.UI.Storage;
using Tango.FSE.UI.SystemInfo;
using Tango.FSE.UI.Threading;
using Tango.FSE.UI.ViewModels;
@@ -64,6 +66,7 @@ namespace Tango.FSE.UI
TangoIOC.Default.Unregister<ISystemInfoProvider>();
TangoIOC.Default.Unregister<ILoggingProvider>();
TangoIOC.Default.Unregister<IFileSystemProvider>();
+ TangoIOC.Default.Unregister<IStorageProvider>();
//TangoIOC.Default.Unregister<ExternalBridgeScanner>();
//TangoIOC.Default.Unregister<IDiagnosticsFrameProvider>();
//TangoIOC.Default.Unregister<IEventLogger>();
@@ -89,6 +92,7 @@ namespace Tango.FSE.UI
TangoIOC.Default.Register<ISystemInfoProvider, DefaultSystemInfoProvider>();
TangoIOC.Default.Register<ILoggingProvider, DefaultLoggingProvider>();
TangoIOC.Default.Register<IFileSystemProvider, DefaultFileSystemProvider>();
+ TangoIOC.Default.Register<IStorageProvider, DefaultStorageProvider>();
TangoIOC.Default.Register<MainWindowVM>();
TangoIOC.Default.Register<MainViewVM>();
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoginViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoginViewVM.cs
index 4472bbf1b..1c6a0b5a8 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoginViewVM.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoginViewVM.cs
@@ -130,6 +130,11 @@ namespace Tango.FSE.UI.ViewModels
{
try
{
+
+ var s = await StorageProvider.SelectFolder("Select download destination folder");
+
+ return;
+
if (!Validate())
{
return;
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/MainView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/MainView.xaml
index 07f40d18c..6a386947f 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/MainView.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/MainView.xaml
@@ -180,6 +180,184 @@
</Grid>
<!--DIALOGS-->
+ <!--STORAGE-->
+ <Grid x:Name="gridStorage" Background="{StaticResource FSE_SemiTransparentBrush}" Visibility="{Binding StorageProvider.IsOpened,Converter={StaticResource BooleanToVisibilityConverter}}">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="1*" />
+ <ColumnDefinition Width="10*" />
+ <ColumnDefinition Width="1*" />
+ </Grid.ColumnDefinitions>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="1*" />
+ <RowDefinition Height="10*" />
+ <RowDefinition Height="1*" />
+ </Grid.RowDefinitions>
+ <Grid RenderTransformOrigin="0.5,0.5" Grid.Column="1" Grid.Row="1">
+ <Grid.Style>
+ <Style TargetType="Grid">
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <ScaleTransform ScaleX="0" ScaleY="0" />
+ </Setter.Value>
+ </Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding StorageProvider.IsOpened}" Value="True">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" From="0" To="1" Duration="00:00:0.1" />
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" From="0" To="1" Duration="00:00:0.1" />
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ <DataTrigger.ExitActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" From="1" To="0" Duration="00:00:0.1" />
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" From="1" To="0" Duration="00:00:0.1" />
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.ExitActions>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Grid.Style>
+
+ <Border Background="{StaticResource FSE_PrimaryBackgroundBrush}" CornerRadius="5" Margin="10">
+ <Border.Effect>
+ <DropShadowEffect BlurRadius="10" />
+ </Border.Effect>
+ <Grid ClipToBounds="True">
+ <Grid>
+ <DockPanel>
+ <Grid DockPanel.Dock="Bottom">
+ <Border Background="{StaticResource FSE_PrimaryBackgroundBrush}" CornerRadius="0 0 5 5" Padding="10">
+ <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
+ <Button Height="40" MinWidth="150" Margin="0 0 5 0" Style="{StaticResource FSE_RaisedButton_Dark_Hover}" Command="{Binding StorageProvider.CancelCommand}" Visibility="{Binding DataContext.CanClose,Converter={StaticResource BooleanToVisibilityConverter}}">CANCEL</Button>
+ <Button Height="40" MinWidth="150" Style="{StaticResource FSE_RaisedButton_Dark_Hover}" Command="{Binding StorageProvider.OKCommand}">OK</Button>
+ </StackPanel>
+ </Border>
+ <Rectangle VerticalAlignment="Top" DockPanel.Dock="Bottom" Stroke="{StaticResource FSE_BorderBrush}" StrokeThickness="1" StrokeDashArray="5" />
+ </Grid>
+
+ <!--FILE SYSTEM CONTROL HERE-->
+ <DockPanel Margin="40 40 40 20">
+
+ <DockPanel DockPanel.Dock="Top" Height="30">
+ <ListBox x:Name="listView" SelectedIndex="1" Background="{StaticResource FSE_PrimaryBackgroundLightBrush}" SelectionChanged="ListView_SelectionChanged" Style="{StaticResource MaterialDesignToolToggleListBox}" Margin="50 0 0 0" DockPanel.Dock="Right">
+ <ListBox.Resources>
+ <SolidColorBrush x:Key="MaterialDesignDivider" Color="{StaticResource FSE_PrimaryBackgroundDarkColor}"/>
+ </ListBox.Resources>
+ <ListBoxItem Width="60" HorizontalContentAlignment="Center" Tag="Large">
+ <material:PackIcon Kind="ViewList" Width="Auto" Height="20" />
+ </ListBoxItem>
+ <ListBoxItem Width="60" HorizontalContentAlignment="Center" Tag="Details">
+ <material:PackIcon Kind="FormatListBulleted" Width="Auto" Height="20" />
+ </ListBoxItem>
+ </ListBox>
+ <DockPanel>
+ <StackPanel DockPanel.Dock="Right" Orientation="Horizontal">
+ <Button Command="{Binding StorageProvider.NavigateCommand}" material:ButtonAssist.CornerRadius="0 3 3 0" Style="{StaticResource FSE_RaisedButton_Dark_Hover}" Padding="0" Width="60" Height="Auto">
+ <material:PackIcon Kind="Refresh" Width="Auto" Height="20" />
+ </Button>
+ </StackPanel>
+ <StackPanel DockPanel.Dock="Left" Orientation="Horizontal">
+ <Button Command="{Binding StorageProvider.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>
+ <Border>
+ <Border BorderThickness="3" BorderBrush="{StaticResource FSE_PrimaryBackgroundLightBrush}" Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}">
+ <Border.Effect>
+ <DropShadowEffect BlurRadius="2" ShadowDepth="2" Opacity="0.3" Direction="270" />
+ </Border.Effect>
+ <Grid>
+ <Border IsHitTestVisible="False" Visibility="{Binding StorageProvider.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 StorageProvider.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>
+ </Border>
+
+ <TextBox IsEnabled="{Binding StorageProvider.IsBusy,Converter={StaticResource BooleanInverseConverter}}" Padding="5 0 0 0" Text="{Binding StorageProvider.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 StorageProvider.NavigateCommand}" />
+ </TextBox.InputBindings>
+ </TextBox>
+ </Grid>
+ </Border>
+ </Border>
+ </DockPanel>
+ </DockPanel>
+
+ <DockPanel Margin="0 10 0 0">
+
+ <Border Margin="0 15 20 0" Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}" BorderBrush="{StaticResource FSE_PrimaryBackgroundLightBrush}" BorderThickness="3" CornerRadius="3" Padding="10 5">
+ <StackPanel>
+ <commonControls:TextIconButton HorizontalContentAlignment="Left" Padding="5" Icon="Computer" Background="Transparent" BorderThickness="0" FocusVisualStyle="{x:Null}">Devices</commonControls:TextIconButton>
+ <StackPanel Margin="30 0 0 0">
+ <ItemsControl ItemsSource="{Binding StorageProvider.Drives}">
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <commonControls:TextIconButton HorizontalContentAlignment="Left" Padding="5" Icon="Harddisk" Background="Transparent" BorderThickness="0" FocusVisualStyle="{x:Null}" Content="{Binding Label}" Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.StorageProvider.NavigateToFolderCommand}" CommandParameter="{Binding Path}"></commonControls:TextIconButton>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+ </StackPanel>
+
+ <commonControls:TextIconButton HorizontalContentAlignment="Left" Padding="5" Icon="Computer" Background="Transparent" BorderThickness="0" FocusVisualStyle="{x:Null}">Computer</commonControls:TextIconButton>
+ <StackPanel Margin="30 0 0 0">
+ <commonControls:TextIconButton HorizontalContentAlignment="Left" Padding="5" Icon="DesktopMac" Background="Transparent" BorderThickness="0" FocusVisualStyle="{x:Null}" Command="{Binding StorageProvider.NavigateSpecialFolderCommand}" CommandParameter="DesktopDirectory">Desktop</commonControls:TextIconButton>
+ <commonControls:TextIconButton HorizontalContentAlignment="Left" Padding="5" Icon="FileDocument" Background="Transparent" BorderThickness="0" FocusVisualStyle="{x:Null}" Command="{Binding StorageProvider.NavigateSpecialFolderCommand}" CommandParameter="MyDocuments">Documents</commonControls:TextIconButton>
+ <commonControls:TextIconButton HorizontalContentAlignment="Left" Padding="5" Icon="Application" Background="Transparent" BorderThickness="0" FocusVisualStyle="{x:Null}" Command="{Binding StorageProvider.NavigateToFolderCommand}" CommandParameter='%appdata%\Twine\Tango'>Application Data</commonControls:TextIconButton>
+ </StackPanel>
+ </StackPanel>
+ </Border>
+
+ <commonControls:FileSystemControl
+ AllowDrag="False"
+ AllowDrop="False"
+ Mode="{Binding ElementName=listView,Path=SelectedItem.Tag}"
+ CurrentItem="{Binding StorageProvider.CurrentItem,Mode=TwoWay}"
+ SelectedItems="{Binding StorageProvider.SelectedItems}"
+ BackCommand="{Binding StorageProvider.BackCommand}"
+ ItemDoubleClickedCommand="{Binding StorageProvider.OpenCommand}"
+ OpenCommand="{Binding StorageProvider.OpenCommand}"/>
+ </DockPanel>
+ </DockPanel>
+ </DockPanel>
+
+ <Grid HorizontalAlignment="Right" VerticalAlignment="Top">
+ <commonControls:IconButton Icon="Close" Padding="8" Margin="0 0 5 0" Command="{Binding StorageProvider.CancelCommand}" Width="{Binding RelativeSource={RelativeSource Self},Path=ActualHeight}"/>
+ </Grid>
+ </Grid>
+ </Grid>
+ </Border>
+ </Grid>
+ </Grid>
+ <!--STORAGE-->
+
<!--TASK ITEMS-->
<Grid x:Name="gridTaskItems" Cursor="AppStarting" Background="{StaticResource FSE_SemiTransparentBrush}">
<Grid.Style>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/MainView.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/MainView.xaml.cs
index 3d29032b1..b98ad1a52 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/MainView.xaml.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/MainView.xaml.cs
@@ -21,6 +21,7 @@ namespace Tango.FSE.UI.Views
public partial class MainView : UserControl
{
private UIElement _previousFocusedElement;
+ private object _lastSelectedItem;
public static MainView Instance { get; set; }
@@ -105,5 +106,17 @@ namespace Tango.FSE.UI.Views
e.Handled = true;
}
}
+
+ private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (listView.SelectedItem != null)
+ {
+ _lastSelectedItem = listView.SelectedItem;
+ }
+ else
+ {
+ listView.SelectedItem = _lastSelectedItem;
+ }
+ }
}
}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/packages.config b/Software/Visual_Studio/FSE/Tango.FSE.UI/packages.config
index c795da787..fda2f4d3f 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/packages.config
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/packages.config
@@ -14,4 +14,6 @@
<package id="System.Reactive.Linq" version="3.1.1" targetFramework="net461" />
<package id="System.Reactive.PlatformServices" version="3.1.1" targetFramework="net461" />
<package id="System.Reactive.Windows.Threading" version="3.1.1" targetFramework="net461" />
+ <package id="WindowsAPICodePack-Core" version="1.1.1" targetFramework="net461" />
+ <package id="WindowsAPICodePack-Shell" version="1.1.1" targetFramework="net461" />
</packages> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.FileSystem/FileSystemManager.cs b/Software/Visual_Studio/Tango.FileSystem/FileSystemManager.cs
index b8e59c322..c18df97c9 100644
--- a/Software/Visual_Studio/Tango.FileSystem/FileSystemManager.cs
+++ b/Software/Visual_Studio/Tango.FileSystem/FileSystemManager.cs
@@ -92,6 +92,28 @@ namespace Tango.FileSystem
};
}
+ public Task<FileSystemItem> GetFolder(String path)
+ {
+ return Task.Factory.StartNew<FileSystemItem>(() =>
+ {
+ return FileSystemItem.FromDTO(GetFolder(new GetFileSystemItemRequest()
+ {
+ Path = path,
+ }));
+ });
+ }
+
+ public Task<FileSystemItem> GetFolder(Environment.SpecialFolder specialFolder)
+ {
+ return Task.Factory.StartNew<FileSystemItem>(() =>
+ {
+ return FileSystemItem.FromDTO(GetFolder(new GetFileSystemItemRequest()
+ {
+ SpecialFolder = specialFolder
+ }));
+ });
+ }
+
public void Delete(String path)
{
if (Directory.Exists(path))