using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using RealTimeGraphEx.Models;
using RealTimeGraphEx.DataSeries;
using RealTimeGraphEx.Controllers;
using System.Runtime.ExceptionServices;
using RealTimeGraphEx.DX2D;
using System.Windows.Controls;
using System.Windows.Threading;
namespace RealTimeGraphEx.DirectXGraphs
{
public class RealTimeGraphExDirectXMultiLineScroll : RealTimeGraphExMultiBase
{
#region Cross Thread Fields
protected Direct2DControl dxGraph;
protected List<ConcurrentpointsList> _graphPolygons;
protected Brush _stroke;
protected Brush _fill;
protected bool _fillGraph;
protected double _strokeWidth;
#endregion
#region Constructors
public RealTimeGraphExDirectXMultiLineScroll()
: base()
{
_graphPolygons = new List<ConcurrentpointsList>();
_graphController = new GraphMultiController();
}
#endregion
#region Properties
/// <summary>
/// Gets or sets the graph strokes color.
/// </summary>
public Brush Stroke
{
get { return (Brush)GetValue(StrokeProperty); }
set { SetValue(StrokeProperty, value); }
}
public static readonly DependencyProperty StrokeProperty =
DependencyProperty.Register("Stroke", typeof(Brush), typeof(RealTimeGraphExDirectXMultiLineScroll), new PropertyMetadata(Brushes.Red, new PropertyChangedCallback(CrossModelChanged)));
/// <summary>
/// Gets or sets the graph fill color.
/// </summary>
public Brush Fill
{
get { return (Brushpre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */using MaterialDesignThemes.Wpf;
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.Core.Helpers;
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
{
/// <summary>
/// Represents the remote file system view model.
/// </summary>
/// <seealso cref="Tango.FSE.Common.FSEViewModel" />
/// <seealso cref="Tango.SharedUI.Controls.NavigationControl.INavigationViewModel" />
public class FileSystemViewVM : FSEViewModel, INavigationViewModel
{
#region Properties
private FileSystemItem _currentItem;
/// <summary>
/// Gets or sets the current file system item.
/// </summary>
public FileSystemItem CurrentItem
{
get { return _currentItem; }
set { _currentItem = value; RaisePropertyChangedAuto(); OnCurrentItemChanged(); }
}
private String _currentPath;
/// <summary>
/// Gets or sets the current remote path.
/// </summary>
public String CurrentPath
{
get { return _currentPath; }
set { _currentPath = value; RaisePropertyChangedAuto(); }
}
private List<DriveItem> _drives;
/// <summary>
/// Gets or sets the file system drives.
/// </summary>
public List<DriveItem> Drives
{
get { return _drives; }
set { _drives = value; RaisePropertyChangedAuto(); }
}
/// <summary>
/// Gets or sets the selected file system items.
/// </summary>
public ObservableCollection<FileSystemItem> SelectedItems { get; set; }
/// <summary>
/// Gets or sets the list of file system handlers downloads/uploads.
/// </summary>
public ObservableCollection<FileSystemHandler> FileSystemHandlers { get; set; }
#endregion
#region Commands
/// <summary>
/// Navigates to the current path.
/// </summary>
public RelayCommand NavigateCommand { get; set; }
/// <summary>
/// Opens the current selected item (context menu).
/// </summary>
public RelayCommand<FileSystemItem> OpenItemCommand { get; set; }
/// <summary>
/// Navigates back.
/// </summary>
public RelayCommand BackCommand { get; set; }
/// <summary>
/// Navigates to the specified special folder.
/// </summary>
public RelayCommand<String> NavigateSpecialFolderCommand { get; set; }
/// <summary>
/// Navigates to the specified folder.
/// </summary>
public RelayCommand<String> NavigateToFolderCommand { get; set; }
/// <summary>
/// Deletes the specified file system item (context menu or DEL key).
/// </summary>
public RelayCommand<IList<FileSystemItem>> DeleteCommand { get; set; }
/// <summary>
/// Handles the drag & drop of items from the operation system shell onto the file system view.
/// </summary>
public RelayCommand<List<FileSystemItem>> DropCommand { get; set; }
/// <summary>
/// Handles the drag & drop of items from the file system view onto the operation system shell.
/// </summary>
public RelayCommand<List<DragItem>> DragCommand { get; set; }
/// <summary>
/// Removes the specified file system handler.
/// </summary>
public RelayCommand<FileSystemHandler> DeleteFileSystemHandlerCommand { get; set; }
/// <summary>
/// Opens the parent directory of a file system handler item.
/// A download will execute the local explorer.exe.
/// An upload will navigate to the remote parent folder.
/// </summary>
public RelayCommand<FileSystemHandler> OpenFileSystemHandlerDestinationCommand { get; set; }
/// <summary>
/// Not supported.
/// </summary>
public RelayCommand<FileSystemHandler> RetryFailedFileSystemHandlerCommand { get; set; }
/// <summary>
/// Handles the copy paste of remote items to a remote location.
/// </summary>
public RelayCommand<List<FileSystemItem>> CopyPasteCommand { get; set; }
/// <summary>
/// Handles the cut parse of remote items to a remote location.
/// </summary>
public RelayCommand<List<FileSystemItem>> CutPasteCommand { get; set; }
/// <summary>
/// Downloads the specified remote items.
/// </summary>
public RelayCommand<List<FileSystemItem>> DownloadCommand { get; set; }
/// <summary>
/// Invokes a dialog for choosing items to upload and starts the upload.
/// </summary>
public RelayCommand UploadCommand { get; set; }
/// <summary>
/// Renames the specified file system item.
/// </summary>
public RelayCommand<FileSystemItem> RenameCommand { get; set; }
/// <summary>
/// Creates a new folder at the current remote path.
/// </summary>
public RelayCommand NewFolderCommand { get; set; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="FileSystemViewVM"/> class.
/// </summary>
public FileSystemViewVM()
{
SelectedItems = new ObservableCollection<FileSystemItem>();
FileSystemHandlers = new ObservableCollection<FileSystemHandler>();
NavigateCommand = new RelayCommand(NavigateToCurrentPath);
OpenItemCommand = 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));
DeleteCommand = new RelayCommand<IList<FileSystemItem>>(DeleteSelectedItems);
DragCommand = new RelayCommand<List<DragItem>>(OnItemsDraggedOut);
DropCommand = new RelayCommand<List<FileSystemItem>>(OnItemsDroppedIn);
DeleteFileSystemHandlerCommand = new RelayCommand<FileSystemHandler>(DeleteFileSystemHandler);
OpenFileSystemHandlerDestinationCommand = new RelayCommand<FileSystemHandler>(OpenFileSystemHandlerDestination);
RetryFailedFileSystemHandlerCommand = new RelayCommand<FileSystemHandler>(RetryFailedFileSystemHandler);
CopyPasteCommand = new RelayCommand<List<FileSystemItem>>((items) => PasteItems(items, false));
CutPasteCommand = new RelayCommand<List<FileSystemItem>>((items) => PasteItems(items, true));
DownloadCommand = new RelayCommand<List<FileSystemItem>>(DownloadSelectedItems);
RenameCommand = new RelayCommand<FileSystemItem>(RenameFileSystemItem);
NewFolderCommand = new RelayCommand(CreateNewFolder);
UploadCommand = new RelayCommand(UploadFilesAndFolder);
}
#endregion
#region Override Methods
/// <summary>
/// Called when the application has been started.
/// </summary>
public override void OnApplicationStarted()
{
base.OnApplicationStarted();
MachineProvider.MachineConnected += MachineProvider_MachineConnected;
}
#endregion
#region Event Handlers
private async void MachineProvider_MachineConnected(object sender, MachineConnectedEventArgs e)
{
if (MachineProvider.ConnectionType.IsRemote())
{
if (e.DifferentFromPrevious)
{
try
{
await Navigate(null, null, true);
}
catch (Exception ex)
{
NotificationProvider.PushErrorReportingSnackbar(ex, "PPC Module Error", "Could not initialize the remote file system provider.");
}
}
}
}
#endregion
#region Private Methods
private async void NavigateBack()
{
if (CurrentItem.Path.Length == 3)
{
await Navigate(null);
}
else
{
String parent = Path.GetDirectoryName(CurrentItem.Path);
await Navigate(parent);
}
}
private void NavigateToCurrentPath()
{
InvokeUI(async () =>
{
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<FileSystemItem> items)
{
if (items != null && items.Count > 0)
{
if (await NotificationProvider.ShowWarningQuestion($"Are you sure you want to delete {(items.Count == 1 ? $"'{items.First().Name}'" : $"the {items.Count} selected files/folders")}?", "DELETE"))
{
using (var task = NotificationProvider.PushTaskItem("Removing..."))
{
int remainingItems = items.Count;
foreach (var item in items)
{
task.UpdateProgress($"Removing '{item.Name}'...");
try
{
remainingItems--;
await FileSystemProvider.Delete(item);
}
catch (Exception ex)
{
LogManager.Log(ex, $"Could not remove '{item.Name}'.");
if (remainingItems > 0)
{
if (!await NotificationProvider.ShowWarningQuestion($"Could not remove '{item.Name}'.\n{ex.FlattenMessage()}\nDo you wish to continue removing the remaining items?"))
{
break;
}
}
else
{
await NotificationProvider.ShowError($"Could not remove '{item.Name}'.\n{ex.FlattenMessage()}");
}
}
}
}
NavigateToCurrentPath();
}
}
}
private async void OnItemsDraggedOut(List<DragItem> items)
{
foreach (var item in items.Where(x => x.FileSystemItem.Type != FileSystemItemType.Drive))
{
Debug.WriteLine($"Dropped out: {item.FileSystemItem.Name} => {item.Destination}");
if (File.Exists(Path.Combine(item.Destination, item.FileSystemItem.Name)) || Directory.Exists(Path.Combine(item.Destination, item.FileSystemItem.Name)))
{
if (!await NotificationProvider.ShowWarningQuestion($"'{item.FileSystemItem.Name}' already exists on '{Path.GetDirectoryName(item.Destination)}'. Do you want to overwrite?"))
{
continue;
}
}
var handler = await FileSystemProvider.Download(item.FileSystemItem, item.Destination);
FileSystemHandlers.Insert(0, handler);
}
}
private async void OnItemsDroppedIn(List<FileSystemItem> items)
{
try
{
String currentPathBefore = CurrentPath;
foreach (var item in items.Where(x => x.Type != FileSystemItemType.Drive))
{
Debug.WriteLine($"Dropped in: {item.Name} => {CurrentItem.Path}");
if ((CurrentItem as IFileSystemContainer).Items.ToList().Exists(x => x.Name.ToLower() == item.Name.ToLower()))
{
if (!await NotificationProvider.ShowWarningQuestion($"'{item.Name}' already exists on '{CurrentItem.Name}'. Do you want to overwrite?"))
{
continue;
}
}
var handler = await FileSystemProvider.Upload(item.Path, CurrentItem);
handler.StatusChanged += (x, status) =>
{
if (status == FileSystemHandlerStatus.Completed && currentPathBefore == CurrentPath)
{
NavigateToCurrentPath();
}
};
FileSystemHandlers.Insert(0, handler);
}
}
catch (Exception ex)
{
await NotificationProvider.ShowError($"Error uploading to file system.\n{ex.FlattenMessage()}");
}
}
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 async void OpenFileSystemHandlerDestination(FileSystemHandler handler)
{
if (handler.Type == FileSystemHandlerType.FileDownload || handler.Type == FileSystemHandlerType.FolderDownload)
{
await StorageProvider.ShowInExplorer(handler.Destination);
}
else
{
await Navigate(Path.GetDirectoryName(handler.Destination));
}
}
private void RetryFailedFileSystemHandler(FileSystemHandler handler)
{
//Not supported Yet!
//if (handler.Status == FileSystemHandlerStatus.Failed)
//{
// if (handler.Type == FileSystemHandlerType.FileDownload || handler.Type == FileSystemHandlerType.FolderDownload)
// {
// var newHandler = await FileSystemProvider.Download(handler.FileSystemItem, Path.GetDirectoryName(handler.Destination));
// FileSystemHandlers.Replace(handler, newHandler);
// }
// else
// {
// var newHandler = await FileSystemProvider.Upload(Path.GetDirectoryName(handler.Destination), handler.FileSystemItem);
// 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, bool throwError = false)
{
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<DriveItem>().ToList();
}
catch (Exception ex)
{
LogManager.Log(ex, "Error setting file system drives menu.");
}
}
}
catch (Exception ex)
{
IsFree = true;
Mouse.OverrideCursor = null;
if (!throwError)
{
await NotificationProvider.ShowError($"Error navigating to the specified path.\n{ex.FlattenMessage()}");
}
else
{
throw ex;
}
}
finally
{
IsFree = true;
Mouse.OverrideCursor = null;
}
}
private async void PasteItems(List<FileSystemItem> items, bool move = false)
{
using (var task = NotificationProvider.PushTaskItem("Please wait..."))
{
int remainingItems = items.Count;
foreach (var item in items)
{
Debug.WriteLine($"{(move ? "Cut" : "Copy")} Paste Item '{item.Name}' To '{CurrentItem.Name}'.");
try
{
remainingItems--;
if (move)
{
task.UpdateProgress($"Moving '{item.Name}'...");
await FileSystemProvider.Move(item, CurrentItem);
}
else
{
task.UpdateProgress($"Copying '{item.Name}'...");
await FileSystemProvider.Copy(item, CurrentItem);
}
}
catch (Exception ex)
{
string operation = move ? "move" : "copy";
LogManager.Log(ex, $"Could not {operation} '{item.Name}'.");
if (remainingItems > 0)
{
if (!await NotificationProvider.ShowWarningQuestion($"Could not {operation} '{item.Name}'.\n{ex.FlattenMessage()}\nDo you wish to continue with the remaining items?"))
{
break;
}
}
else
{
await NotificationProvider.ShowError($"Could not {operation} '{item.Name}'.\n{ex.FlattenMessage()}");
}
}
}
NavigateToCurrentPath();
}
}
private async void DownloadSelectedItems(List<FileSystemItem> items)
{
if (items.Count == 1 && items.First().Type == FileSystemItemType.File)
{
var fileItem = items.First() as FileItem;
var result = await StorageProvider.SaveFile("Select download destination file", $"{fileItem.Description}|*{fileItem.Extension}", fileItem.Name, fileItem.Extension);
if (result)
{
var handler = await FileSystemProvider.Download(fileItem, result.SelectedItem, true);
FileSystemHandlers.Insert(0, handler);
}
}
else
{
var result = await StorageProvider.SelectFolder("Select download destination folder");
if (result)
{
String destination = result.SelectedItem;
foreach (var item in items.Where(x => x.Type != FileSystemItemType.Drive))
{
if (File.Exists(Path.Combine(destination, item.Name)) || Directory.Exists(Path.Combine(destination, item.Name)))
{
if (!await NotificationProvider.ShowWarningQuestion($"'{item.Name}' already exists on '{Path.GetDirectoryName(destination)}'. Do you want to overwrite?"))
{
continue;
}
}
var handler = await FileSystemProvider.Download(item, destination);
FileSystemHandlers.Insert(0, handler);
}
}
}
}
private async void UploadFilesAndFolder()
{
var result = await StorageProvider.SelectFilesAndFolders("Select files and folders to upload");
if (result)
{
try
{
String currentPathBefore = CurrentPath;
foreach (var item in result.SelectedItems)
{
if (!File.Exists(item) && !Directory.Exists(item))
{
await NotificationProvider.ShowError($"File or folder '{item}' cannot be uploaded.");
return;
}
}
foreach (var item in result.SelectedItems)
{
String itemName = Path.GetFileName(item);
if ((CurrentItem as IFileSystemContainer).Items.ToList().Exists(x => x.Name.ToLower() == itemName.ToLower()))
{
if (!await NotificationProvider.ShowWarningQuestion($"'{itemName}' already exists on '{CurrentItem.Name}'. Do you want to overwrite?"))
{
continue;
}
}
var handler = await FileSystemProvider.Upload(item, CurrentItem);
handler.StatusChanged += (x, status) =>
{
if (status == FileSystemHandlerStatus.Completed && currentPathBefore == CurrentPath)
{
NavigateToCurrentPath();
}
};
FileSystemHandlers.Insert(0, handler);
}
}
catch (Exception ex)
{
await NotificationProvider.ShowError($"Error uploading to file system.\n{ex.FlattenMessage()}");
}
}
}
private async void RenameFileSystemItem(FileSystemItem item)
{
if (item.Type != FileSystemItemType.Drive)
{
var result = await NotificationProvider.ShowInputBox(
"Rename",
$"Please enter a new {(item.Type == FileSystemItemType.File ? "file" : "folder")} name and press 'ENTER'.",
PackIconKind.Rename, item.Name,
$"{(item.Type == FileSystemItemType.File ? "file" : "folder")} name",
100,
"RENAME");
if (result.Confirmed && result.Input != item.Name)
{
try
{
using (NotificationProvider.PushTaskItem("Renaming..."))
{
await FileSystemProvider.Rename(item, result.Input);
item.Path = Path.Combine(Path.GetDirectoryName(item.Path), result.Input);
}
}
catch (Exception ex)
{
LogManager.Log(ex, $"Error renaming '{item.Path}' to {result.Input}.");
await NotificationProvider.ShowError($"Error renaming '{item.Name}'.\n{ex.FlattenMessage()}");
}
}
}
}
private async void CreateNewFolder()
{
if (CurrentItem == null) return;
if (CurrentItem is FolderItem)
{
if ((CurrentItem as FolderItem).IsRoot) return;
}
var result = await NotificationProvider.ShowInputBox(
"New Folder",
$"Please enter a folder name and press 'ENTER'.",
PackIconKind.FolderAdd, "untitled",
"folder name",
100,
"CREATE");
if (result.Confirmed)
{
try
{
using (NotificationProvider.PushTaskItem("Creating new folder..."))
{
var folderItem = await FileSystemProvider.CreateFolder(CurrentItem, result.Input);
NavigateToCurrentPath(); //Instead of inserting folder item just refresh the current path...
}
}
catch (Exception ex)
{
LogManager.Log(ex, $"Error creating new folder '{Path.Combine(CurrentItem.Path, result.Input)}.");
await NotificationProvider.ShowError($"Error creating folder '{result.Input}'.\n{ex.FlattenMessage()}");
}
}
}
private void OnCurrentItemChanged()
{
CurrentPath = CurrentItem.Path;
InvalidateRelayCommands();
}
#endregion
}
}