using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; 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 Tango.FSE.Common.FileSystem; using static Tango.SharedUI.Controls.NavigationControl; namespace Tango.FSE.PPCConsole.ViewModels { public class FileSystemViewVM : FSEViewModel, INavigationViewModel { 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 List _drives; public List Drives { get { return _drives; } set { _drives = value; RaisePropertyChangedAuto(); } } public ObservableCollection SelectedItems { get; set; } public ObservableCollection FileSystemHandlers { get; set; } public RelayCommand NavigateCommand { get; set; } public RelayCommand OpenItemCommand { get; set; } public RelayCommand BackCommand { get; set; } public RelayCommand NavigateSpecialFolderCommand { get; set; } public RelayCommand NavigateToFolderCommand { get; set; } public RelayCommand> DeleteCommand { get; set; } public RelayCommand> DropCommand { get; set; } public RelayCommand> DragCommand { get; set; } public RelayCommand DeleteFileSystemHandlerCommand { get; set; } public RelayCommand OpenFileSystemHandlerDestinationCommand { get; set; } public RelayCommand RetryFailedFileSystemHandlerCommand { get; set; } public FileSystemViewVM() { SelectedItems = new ObservableCollection(); FileSystemHandlers = new ObservableCollection(); NavigateCommand = new RelayCommand(NavigateToCurrentPath); OpenItemCommand = new RelayCommand(OpenFileSystemItem); BackCommand = new RelayCommand(NavigateBack, () => !(CurrentItem is FolderItem) || !(CurrentItem as FolderItem).IsRoot); NavigateSpecialFolderCommand = new RelayCommand(NavigateToSpecialFolder); NavigateToFolderCommand = new RelayCommand(async (x) => await Navigate(x)); DeleteCommand = new RelayCommand>(DeleteSelectedItems); DragCommand = new RelayCommand>(OnItemsDraggedOut); DeleteFileSystemHandlerCommand = new RelayCommand(DeleteFileSystemHandler); OpenFileSystemHandlerDestinationCommand = new RelayCommand(OpenFileSystemHandlerDestination); RetryFailedFileSystemHandlerCommand = new RelayCommand(RetryFailedFileSystemHandler); } 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); } 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 void DeleteSelectedItems(IList items) { if (items != null && items.Count > 0) { if (await NotificationProvider.ShowWarningQuestion("Are you sure you want to delete the selected files/folders?", "DELETE")) { //TODO: Delete items } } } private async void OnItemsDraggedOut(List items) { foreach (var item in items.Where(x => x.FileSystemItem.Type != FileSystemItemType.Drive)) { Debug.WriteLine($"Dropped out: {item.FileSystemItem.Name} => {item.Destination}"); var handler = await FileSystemProvider.Download(item.FileSystemItem, item.Destination); FileSystemHandlers.Insert(0, handler); } } private async void DeleteFileSystemHandler(FileSystemHandler handler) { if (handler.Status != FileSystemHandlerStatus.Completed && handler.Status != FileSystemHandlerStatus.Failed) { if (await NotificationProvider.ShowWarningQuestion($"This item is currently {handler.Status}. Do you wish to abort and delete this item?")) { try { handler.Abort(); } catch { } FileSystemHandlers.Remove(handler); } } else { FileSystemHandlers.Remove(handler); } } private void OpenFileSystemHandlerDestination(FileSystemHandler handler) { String destination = String.Empty; if (File.Exists(handler.Destination) || Directory.Exists(handler.Destination)) { destination = handler.Destination; Process.Start("explorer.exe", string.Format("/select,\"{0}\"", destination)); } else { destination = Path.GetDirectoryName(handler.Destination); Process.Start("explorer.exe", destination); } } private async void RetryFailedFileSystemHandler(FileSystemHandler handler) { if (handler.Status == FileSystemHandlerStatus.Failed) { var newHandler = await FileSystemProvider.Download(handler.FileSystemItem, Path.GetDirectoryName(handler.Destination)); FileSystemHandlers.Replace(handler, newHandler); } } private async void NavigateToSpecialFolder(string folder) { Environment.SpecialFolder specialFolder = (Environment.SpecialFolder)Enum.Parse(typeof(Environment.SpecialFolder), folder); await Navigate(null, specialFolder); } private async Task Navigate(String path, Environment.SpecialFolder? specialFolder = null) { try { IsFree = false; Mouse.OverrideCursor = Cursors.AppStarting; if (path != null) { CurrentItem = await FileSystemProvider.GetFolder(path) as FileSystemItem; } else if (specialFolder != null) { CurrentItem = await FileSystemProvider.GetSpecialFolder(specialFolder.Value) as FileSystemItem; } else { CurrentItem = await FileSystemProvider.GetThisPC() as FileSystemItem; try { Drives = (CurrentItem as IFileSystemContainer).Items.Cast().ToList(); } catch (Exception ex) { LogManager.Log(ex, "Error setting file system drives menu."); } } } catch (Exception ex) { IsFree = true; Mouse.OverrideCursor = null; await NotificationProvider.ShowError($"Error navigating to the specified path.\n{ex.FlattenMessage()}"); } finally { IsFree = true; Mouse.OverrideCursor = null; } } private void OnCurrentItemChanged() { CurrentPath = CurrentItem.Path; InvalidateRelayCommands(); } } }