From 6e766aa9d4c38593fadc466234170d57a7efb14e Mon Sep 17 00:00:00 2001 From: d2dyno006 <53011783+d2dyno006@users.noreply.github.com> Date: Sat, 20 Mar 2021 22:22:21 +0100 Subject: [PATCH 1/9] rm1 --- .../BaseLayoutCommandImplementationModel.cs | 263 ++++++++++++++++++ .../Interacts/BaseLayoutCommandsViewModel.cs | 35 ++- .../IBaseLayoutCommandImplementationModel.cs | 22 ++ Files/Interacts/Interaction.cs | 253 +---------------- .../Views/LayoutModes/GenericFileBrowser.xaml | 78 +++++- .../LayoutModes/GenericFileBrowser.xaml.cs | 2 +- Files/Views/LayoutModes/GridViewBrowser.xaml | 78 +++++- .../Views/LayoutModes/GridViewBrowser.xaml.cs | 2 +- Files/Views/ModernShellPage.xaml.cs | 4 +- 9 files changed, 453 insertions(+), 284 deletions(-) diff --git a/Files/Interacts/BaseLayoutCommandImplementationModel.cs b/Files/Interacts/BaseLayoutCommandImplementationModel.cs index 6e3f487446dc..c6374ce1eed2 100644 --- a/Files/Interacts/BaseLayoutCommandImplementationModel.cs +++ b/Files/Interacts/BaseLayoutCommandImplementationModel.cs @@ -4,7 +4,15 @@ using Microsoft.Toolkit.Uwp; using Windows.Foundation.Collections; using Windows.UI.Xaml; +using Windows.ApplicationModel.DataTransfer; +using Windows.Storage; +using System.Collections.Generic; +using System.Linq; +using Windows.ApplicationModel.AppService; +using Files.Views; using System; +using Windows.UI.Core; +using Windows.System; namespace Files.Interacts { @@ -20,6 +28,8 @@ public class BaseLayoutCommandImplementationModel : IBaseLayoutCommandImplementa private IBaseLayout SlimContentPage => associatedInstance?.SlimContentPage; + private IFilesystemHelpers FilesystemHelpers => associatedInstance?.FilesystemHelpers; + #endregion #region Private Members @@ -144,6 +154,259 @@ public virtual void QuickLook(RoutedEventArgs e) QuickLookHelpers.ToggleQuickLook(associatedInstance); } + public virtual async void CopyItem(RoutedEventArgs e) + { + DataPackage dataPackage = new DataPackage() + { + RequestedOperation = DataPackageOperation.Copy + }; + List items = new List(); + + string copySourcePath = associatedInstance.FilesystemViewModel.WorkingDirectory; + FilesystemResult result = (FilesystemResult)false; + + if (associatedInstance.SlimContentPage.IsItemSelected) + { + foreach (ListedItem listedItem in associatedInstance.SlimContentPage.SelectedItems) + { + if (listedItem.PrimaryItemAttribute == StorageItemTypes.File) + { + result = await associatedInstance.FilesystemViewModel.GetFileFromPathAsync(listedItem.ItemPath) + .OnSuccess(t => items.Add(t)); + if (!result) + { + break; + } + } + else + { + result = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(listedItem.ItemPath) + .OnSuccess(t => items.Add(t)); + if (!result) + { + break; + } + } + } + if (result.ErrorCode == FileSystemStatusCode.Unauthorized) + { + // Try again with fulltrust process + if (ServiceConnection != null) + { + string filePaths = string.Join('|', associatedInstance.SlimContentPage.SelectedItems.Select(x => x.ItemPath)); + await ServiceConnection.SendMessageAsync(new ValueSet() + { + { "Arguments", "FileOperation" }, + { "fileop", "Clipboard" }, + { "filepath", filePaths }, + { "operation", (int)DataPackageOperation.Copy } + }); + } + return; + } + } + + if (items?.Count > 0) + { + dataPackage.SetStorageItems(items); + try + { + Clipboard.SetContent(dataPackage); + Clipboard.Flush(); + } + catch + { + dataPackage = null; + } + } + } + + public virtual async void CutItem(RoutedEventArgs e) + { + DataPackage dataPackage = new DataPackage + { + RequestedOperation = DataPackageOperation.Move + }; + List items = new List(); + FilesystemResult result = (FilesystemResult)false; + + if (associatedInstance.SlimContentPage.IsItemSelected) + { + // First, reset DataGrid Rows that may be in "cut" command mode + associatedInstance.SlimContentPage.ResetItemOpacity(); + + foreach (ListedItem listedItem in associatedInstance.SlimContentPage.SelectedItems) + { + // Dim opacities accordingly + associatedInstance.SlimContentPage.SetItemOpacity(listedItem); + + if (listedItem.PrimaryItemAttribute == StorageItemTypes.File) + { + result = await associatedInstance.FilesystemViewModel.GetFileFromPathAsync(listedItem.ItemPath) + .OnSuccess(t => items.Add(t)); + if (!result) + { + break; + } + } + else + { + result = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(listedItem.ItemPath) + .OnSuccess(t => items.Add(t)); + if (!result) + { + break; + } + } + } + if (result.ErrorCode == FileSystemStatusCode.NotFound) + { + associatedInstance.SlimContentPage.ResetItemOpacity(); + return; + } + else if (result.ErrorCode == FileSystemStatusCode.Unauthorized) + { + // Try again with fulltrust process + if (ServiceConnection != null) + { + string filePaths = string.Join('|', associatedInstance.SlimContentPage.SelectedItems.Select(x => x.ItemPath)); + AppServiceResponseStatus status = await ServiceConnection.SendMessageAsync(new ValueSet() + { + { "Arguments", "FileOperation" }, + { "fileop", "Clipboard" }, + { "filepath", filePaths }, + { "operation", (int)DataPackageOperation.Move } + }); + if (status == AppServiceResponseStatus.Success) + { + return; + } + } + associatedInstance.SlimContentPage.ResetItemOpacity(); + return; + } + } + + if (!items.Any()) + { + return; + } + dataPackage.SetStorageItems(items); + try + { + Clipboard.SetContent(dataPackage); + Clipboard.Flush(); + } + catch + { + dataPackage = null; + } + } + + public virtual async void RestoreItem(RoutedEventArgs e) + { + if (associatedInstance.SlimContentPage.IsItemSelected) + { + foreach (ListedItem listedItem in associatedInstance.SlimContentPage.SelectedItems) + { + if (listedItem is RecycleBinItem binItem) + { + FilesystemItemType itemType = binItem.PrimaryItemAttribute == StorageItemTypes.Folder ? FilesystemItemType.Directory : FilesystemItemType.File; + await FilesystemHelpers.RestoreFromTrashAsync(StorageItemHelpers.FromPathAndType( + (listedItem as RecycleBinItem).ItemPath, + itemType), (listedItem as RecycleBinItem).ItemOriginalPath, true); + } + } + } + } + + public virtual async void DeleteItem(RoutedEventArgs e) + { + await FilesystemHelpers.DeleteItemsAsync( + associatedInstance.SlimContentPage.SelectedItems.Select((item) => StorageItemHelpers.FromPathAndType( + item.ItemPath, + item.PrimaryItemAttribute == StorageItemTypes.File ? FilesystemItemType.File : FilesystemItemType.Directory)).ToList(), + true, false, true); + } + + public virtual void ShowFolderProperties(RoutedEventArgs e) + { + associatedInstance.InteractionOperations.ShowProperties(); + } + + public virtual void ShowProperties(RoutedEventArgs e) + { + associatedInstance.InteractionOperations.ShowProperties(); + } + + public virtual async void OpenFileLocation(RoutedEventArgs e) + { + ShortcutItem item = associatedInstance.SlimContentPage.SelectedItem as ShortcutItem; + + if (string.IsNullOrWhiteSpace(item?.TargetPath)) + { + return; + } + + // Check if destination path exists + string folderPath = System.IO.Path.GetDirectoryName(item.TargetPath); + FilesystemResult destFolder = await associatedInstance.FilesystemViewModel.GetFolderWithPathFromPathAsync(folderPath); + + if (destFolder) + { + associatedInstance.NavigateWithArguments(associatedInstance.InstanceViewModel.FolderSettings.GetLayoutType(folderPath), new NavigationArguments() + { + NavPathParam = folderPath, + AssociatedTabInstance = associatedInstance + }); + } + else if (destFolder == FileSystemStatusCode.NotFound) + { + await DialogDisplayHelper.ShowDialogAsync("FileNotFoundDialog/Title".GetLocalized(), "FileNotFoundDialog/Text".GetLocalized()); + } + else + { + await DialogDisplayHelper.ShowDialogAsync("InvalidItemDialogTitle".GetLocalized(), + string.Format("InvalidItemDialogContent".GetLocalized(), Environment.NewLine, destFolder.ErrorCode.ToString())); + } + } + + public virtual void OpenItemWithApplicationPicker(RoutedEventArgs e) + { + associatedInstance.InteractionOperations.OpenSelectedItems(true); + } + + public virtual async void OpenDirectoryInNewTab(RoutedEventArgs e) + { + foreach (ListedItem listedItem in associatedInstance.SlimContentPage.SelectedItems) + { + await CoreWindow.GetForCurrentThread().Dispatcher.RunAsync(CoreDispatcherPriority.Low, async () => + { + await MainPage.AddNewTabByPathAsync(typeof(PaneHolderPage), (listedItem as ShortcutItem)?.TargetPath ?? listedItem.ItemPath); + }); + } + } + + public virtual void OpenDirectoryInNewPane(RoutedEventArgs e) + { + ListedItem listedItem = associatedInstance.SlimContentPage.SelectedItems.FirstOrDefault(); + if (listedItem != null) + { + associatedInstance.PaneHolder?.OpenPathInNewPane((listedItem as ShortcutItem)?.TargetPath ?? listedItem.ItemPath); + } + } + + public virtual async void OpenInNewWindowItem(RoutedEventArgs e) + { + List items = associatedInstance.SlimContentPage.SelectedItems; + foreach (ListedItem listedItem in items) + { + var selectedItemPath = (listedItem as ShortcutItem)?.TargetPath ?? listedItem.ItemPath; + var folderUri = new Uri($"files-uwp:?folder={@selectedItemPath}"); + await Launcher.LaunchUriAsync(folderUri); + } + } + #endregion } } diff --git a/Files/Interacts/BaseLayoutCommandsViewModel.cs b/Files/Interacts/BaseLayoutCommandsViewModel.cs index 115f749f9d36..fd37cf770301 100644 --- a/Files/Interacts/BaseLayoutCommandsViewModel.cs +++ b/Files/Interacts/BaseLayoutCommandsViewModel.cs @@ -40,14 +40,23 @@ private void InitializeCommands() OpenItemCommand = new RelayCommand(commandsModel.OpenItem); EmptyRecycleBinCommand = new RelayCommand(commandsModel.EmptyRecycleBin); QuickLookCommand = new RelayCommand(commandsModel.QuickLook); + CopyItemCommand = new RelayCommand(commandsModel.CopyItem); + CutItemCommand = new RelayCommand(commandsModel.CutItem); + RestoreItemCommand = new RelayCommand(commandsModel.RestoreItem); + DeleteItemCommand = new RelayCommand(commandsModel.DeleteItem); + ShowFolderPropertiesCommand = new RelayCommand(commandsModel.ShowFolderProperties); + ShowPropertiesCommand = new RelayCommand(commandsModel.ShowProperties); + OpenFileLocationCommand = new RelayCommand(commandsModel.OpenFileLocation); + OpenItemWithApplicationPickerCommand = new RelayCommand(commandsModel.OpenItemWithApplicationPicker); + OpenDirectoryInNewTabCommand = new RelayCommand(commandsModel.OpenDirectoryInNewTab); + OpenDirectoryInNewPaneCommand = new RelayCommand(commandsModel.OpenDirectoryInNewPane); + OpenInNewWindowItemCommand = new RelayCommand(commandsModel.OpenInNewWindowItem); } #endregion #region Commands - // TODO: We'll have there all BaseLayout commands to bind to -> and these will call implementation in commandsModel - public ICommand RenameItemCommand { get; private set; } public ICommand CreateShortcutCommand { get; private set; } @@ -71,6 +80,28 @@ private void InitializeCommands() public ICommand EmptyRecycleBinCommand { get; private set; } public ICommand QuickLookCommand { get; private set; } + + public ICommand CopyItemCommand { get; private set; } + + public ICommand CutItemCommand { get; private set; } + + public ICommand RestoreItemCommand { get; private set; } + + public ICommand DeleteItemCommand { get; private set; } + + public ICommand ShowFolderPropertiesCommand { get; private set; } + + public ICommand ShowPropertiesCommand { get; private set; } + + public ICommand OpenFileLocationCommand { get; private set; } + + public ICommand OpenItemWithApplicationPickerCommand { get; private set; } + + public ICommand OpenDirectoryInNewTabCommand { get; private set; } + + public ICommand OpenDirectoryInNewPaneCommand { get; private set; } + + public ICommand OpenInNewWindowItemCommand { get; private set; } #endregion diff --git a/Files/Interacts/IBaseLayoutCommandImplementationModel.cs b/Files/Interacts/IBaseLayoutCommandImplementationModel.cs index e1f0eb2df1c7..23e035f9fce7 100644 --- a/Files/Interacts/IBaseLayoutCommandImplementationModel.cs +++ b/Files/Interacts/IBaseLayoutCommandImplementationModel.cs @@ -28,5 +28,27 @@ public interface IBaseLayoutCommandImplementationModel : IDisposable void EmptyRecycleBin(RoutedEventArgs e); void QuickLook(RoutedEventArgs e); + + void CopyItem(RoutedEventArgs e); + + void CutItem(RoutedEventArgs e); + + void RestoreItem(RoutedEventArgs e); + + void DeleteItem(RoutedEventArgs e); + + void ShowFolderProperties(RoutedEventArgs e); + + void ShowProperties(RoutedEventArgs e); + + void OpenFileLocation(RoutedEventArgs e); + + void OpenItemWithApplicationPicker(RoutedEventArgs e); + + void OpenDirectoryInNewTab(RoutedEventArgs e); + + void OpenDirectoryInNewPane(RoutedEventArgs e); + + void OpenInNewWindowItem(RoutedEventArgs e); } } diff --git a/Files/Interacts/Interaction.cs b/Files/Interacts/Interaction.cs index 871e977bfa52..5c1d556fb9b1 100644 --- a/Files/Interacts/Interaction.cs +++ b/Files/Interacts/Interaction.cs @@ -48,7 +48,6 @@ namespace Files.Interacts public class Interaction { private NamedPipeAsAppServiceConnection Connection => AssociatedInstance?.ServiceConnection; - private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private string jumpString = ""; private readonly DispatcherTimer jumpTimer = new DispatcherTimer(); private readonly IShellPage AssociatedInstance; @@ -158,26 +157,6 @@ private async void OpenNewTab() await MainPage.AddNewTabByPathAsync(typeof(PaneHolderPage), "NewTab".GetLocalized()); } - public async void OpenInNewWindowItem_Click() - { - var items = AssociatedInstance.SlimContentPage.SelectedItems; - foreach (ListedItem listedItem in items) - { - var selectedItemPath = (listedItem as ShortcutItem)?.TargetPath ?? listedItem.ItemPath; - var folderUri = new Uri($"files-uwp:?folder={@selectedItemPath}"); - await Launcher.LaunchUriAsync(folderUri); - } - } - - public void OpenDirectoryInNewPane_Click() - { - var listedItem = AssociatedInstance.SlimContentPage.SelectedItems.FirstOrDefault(); - if (listedItem != null) - { - AssociatedInstance.PaneHolder?.OpenPathInNewPane((listedItem as ShortcutItem)?.TargetPath ?? listedItem.ItemPath); - } - } - public RelayCommand OpenNewPane => new RelayCommand(() => OpenNewPaneCommand()); public void OpenNewPaneCommand() @@ -185,17 +164,6 @@ public void OpenNewPaneCommand() AssociatedInstance.PaneHolder?.OpenPathInNewPane("NewTab".GetLocalized()); } - public async void OpenDirectoryInNewTab_Click() - { - foreach (ListedItem listedItem in AssociatedInstance.SlimContentPage.SelectedItems) - { - await CoreWindow.GetForCurrentThread().Dispatcher.RunAsync(CoreDispatcherPriority.Low, async () => - { - await MainPage.AddNewTabByPathAsync(typeof(PaneHolderPage), (listedItem as ShortcutItem)?.TargetPath ?? listedItem.ItemPath); - }); - } - } - public void ItemPointerPressed(object sender, PointerRoutedEventArgs e) { if (e.GetCurrentPoint(null).Properties.IsMiddleButtonPressed) @@ -303,40 +271,6 @@ public static bool IsAnyContentDialogOpen() return openedPopups.Any(popup => popup.Child is ContentDialog); } - public void OpenItemWithApplicationPicker_Click(object sender, RoutedEventArgs e) - { - OpenSelectedItems(true); - } - - public async void OpenFileLocation_Click(object sender, RoutedEventArgs e) - { - var item = ((sender as MenuFlyoutItem).DataContext as ShortcutItem); - if (string.IsNullOrEmpty(item?.TargetPath)) - { - return; - } - var folderPath = Path.GetDirectoryName(item.TargetPath); - // Check if destination path exists - var destFolder = await AssociatedInstance.FilesystemViewModel.GetFolderWithPathFromPathAsync(folderPath); - if (destFolder) - { - AssociatedInstance.NavigateWithArguments(FolderSettings.GetLayoutType(folderPath), new NavigationArguments() - { - NavPathParam = folderPath, - AssociatedTabInstance = AssociatedInstance - }); - } - else if (destFolder == FileSystemStatusCode.NotFound) - { - await DialogDisplayHelper.ShowDialogAsync("FileNotFoundDialog/Title".GetLocalized(), "FileNotFoundDialog/Text".GetLocalized()); - } - else - { - await DialogDisplayHelper.ShowDialogAsync("InvalidItemDialogTitle".GetLocalized(), - string.Format("InvalidItemDialogContent".GetLocalized(), Environment.NewLine, destFolder.ErrorCode.ToString())); - } - } - /// /// Navigates to a directory or opens file /// @@ -636,7 +570,7 @@ public void ShareItem_Click(object sender, RoutedEventArgs e) DataTransferManager.ShowShareUI(); } - private async void ShowProperties() + public async void ShowProperties() { if (AssociatedInstance.SlimContentPage.IsItemSelected) { @@ -714,16 +648,6 @@ await newWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => } } - public void ShowPropertiesButton_Click(object sender, RoutedEventArgs e) - { - ShowProperties(); - } - - public void ShowFolderPropertiesButton_Click(object sender, RoutedEventArgs e) - { - ShowProperties(); - } - public void PinDirectoryToSidebar(object sender, RoutedEventArgs e) { App.SidebarPinnedController.Model.AddItem(AssociatedInstance.FilesystemViewModel.WorkingDirectory); @@ -789,15 +713,6 @@ private async void Manager_DataRequested(DataTransferManager sender, DataRequest dataRequestDeferral.Complete(); } - public async void DeleteItem_Click(object sender, RoutedEventArgs e) - { - await FilesystemHelpers.DeleteItemsAsync( - AssociatedInstance.SlimContentPage.SelectedItems.Select((item) => StorageItemHelpers.FromPathAndType( - item.ItemPath, - item.PrimaryItemAttribute == StorageItemTypes.File ? FilesystemItemType.File : FilesystemItemType.Directory)).ToList(), - true, false, true); - } - public async Task RenameFileItemAsync(ListedItem item, string oldName, string newName) { if (oldName == newName) @@ -842,172 +757,6 @@ public void SetHiddenAttributeItem(ListedItem item, bool isHidden) AssociatedInstance.SlimContentPage.ResetItemOpacity(); } - public async void RestoreItem_Click(object sender, RoutedEventArgs e) - { - if (AssociatedInstance.SlimContentPage.IsItemSelected) - { - foreach (ListedItem listedItem in AssociatedInstance.SlimContentPage.SelectedItems) - { - if (listedItem is RecycleBinItem binItem) - { - FilesystemItemType itemType = binItem.PrimaryItemAttribute == StorageItemTypes.Folder ? FilesystemItemType.Directory : FilesystemItemType.File; - await FilesystemHelpers.RestoreFromTrashAsync(StorageItemHelpers.FromPathAndType( - (listedItem as RecycleBinItem).ItemPath, - itemType), (listedItem as RecycleBinItem).ItemOriginalPath, true); - } - } - } - } - - public async void CutItem_Click(object sender, RoutedEventArgs e) - { - DataPackage dataPackage = new DataPackage - { - RequestedOperation = DataPackageOperation.Move - }; - List items = new List(); - var cut = (FilesystemResult)false; - if (AssociatedInstance.SlimContentPage.IsItemSelected) - { - // First, reset DataGrid Rows that may be in "cut" command mode - AssociatedInstance.SlimContentPage.ResetItemOpacity(); - - foreach (ListedItem listedItem in AssociatedInstance.SlimContentPage.SelectedItems) - { - // Dim opacities accordingly - AssociatedInstance.SlimContentPage.SetItemOpacity(listedItem); - - if (listedItem.PrimaryItemAttribute == StorageItemTypes.File) - { - cut = await AssociatedInstance.FilesystemViewModel.GetFileFromPathAsync(listedItem.ItemPath) - .OnSuccess(t => items.Add(t)); - if (!cut) - { - break; - } - } - else - { - cut = await AssociatedInstance.FilesystemViewModel.GetFolderFromPathAsync(listedItem.ItemPath) - .OnSuccess(t => items.Add(t)); - if (!cut) - { - break; - } - } - } - if (cut.ErrorCode == FileSystemStatusCode.NotFound) - { - AssociatedInstance.SlimContentPage.ResetItemOpacity(); - return; - } - else if (cut.ErrorCode == FileSystemStatusCode.Unauthorized) - { - // Try again with fulltrust process - if (Connection != null) - { - var filePaths = string.Join('|', AssociatedInstance.SlimContentPage.SelectedItems.Select(x => x.ItemPath)); - var status = await Connection.SendMessageAsync(new ValueSet() - { - { "Arguments", "FileOperation" }, - { "fileop", "Clipboard" }, - { "filepath", filePaths }, - { "operation", (int)DataPackageOperation.Move } - }); - if (status == AppServiceResponseStatus.Success) - { - return; - } - } - AssociatedInstance.SlimContentPage.ResetItemOpacity(); - return; - } - } - if (!items.Any()) - { - return; - } - dataPackage.SetStorageItems(items); - try - { - Clipboard.SetContent(dataPackage); - Clipboard.Flush(); - } - catch - { - dataPackage = null; - } - } - - public string CopySourcePath; - - public async void CopyItem_ClickAsync(object sender, RoutedEventArgs e) - { - DataPackage dataPackage = new DataPackage - { - RequestedOperation = DataPackageOperation.Copy - }; - List items = new List(); - - CopySourcePath = AssociatedInstance.FilesystemViewModel.WorkingDirectory; - var copied = (FilesystemResult)false; - - if (AssociatedInstance.SlimContentPage.IsItemSelected) - { - foreach (ListedItem listedItem in AssociatedInstance.SlimContentPage.SelectedItems) - { - if (listedItem.PrimaryItemAttribute == StorageItemTypes.File) - { - copied = await AssociatedInstance.FilesystemViewModel.GetFileFromPathAsync(listedItem.ItemPath) - .OnSuccess(t => items.Add(t)); - if (!copied) - { - break; - } - } - else - { - copied = await AssociatedInstance.FilesystemViewModel.GetFolderFromPathAsync(listedItem.ItemPath) - .OnSuccess(t => items.Add(t)); - if (!copied) - { - break; - } - } - } - if (copied.ErrorCode == FileSystemStatusCode.Unauthorized) - { - // Try again with fulltrust process - if (Connection != null) - { - var filePaths = string.Join('|', AssociatedInstance.SlimContentPage.SelectedItems.Select(x => x.ItemPath)); - await Connection.SendMessageAsync(new ValueSet() - { - { "Arguments", "FileOperation" }, - { "fileop", "Clipboard" }, - { "filepath", filePaths }, - { "operation", (int)DataPackageOperation.Copy } - }); - } - return; - } - } - - if (items?.Count > 0) - { - dataPackage.SetStorageItems(items); - try - { - Clipboard.SetContent(dataPackage); - Clipboard.Flush(); - } - catch - { - dataPackage = null; - } - } - } - public RelayCommand CopyPathOfSelectedItem => new RelayCommand(() => CopyLocation()); private void CopyLocation() diff --git a/Files/Views/LayoutModes/GenericFileBrowser.xaml b/Files/Views/LayoutModes/GenericFileBrowser.xaml index 91521b8e0780..bb1d93cc2df4 100644 --- a/Files/Views/LayoutModes/GenericFileBrowser.xaml +++ b/Files/Views/LayoutModes/GenericFileBrowser.xaml @@ -252,8 +252,12 @@ + + + + + @@ -386,9 +390,13 @@ x:Name="OpenItemWithAppPicker" x:Uid="BaseLayoutItemContextFlyoutOpenItemWith" x:Load="False" - Click="{x:Bind ParentShellPageInstance.InteractionOperations.OpenItemWithApplicationPicker_Click}" Tag="OpenWith" Text="Open With"> + + + + + @@ -396,9 +404,13 @@ + + + + + @@ -406,9 +418,13 @@ + + + + + @@ -417,9 +433,13 @@ x:Name="OpenInNewTab" x:Uid="BaseLayoutItemContextFlyoutOpenInNewTab" x:Load="False" - Click="{x:Bind ParentShellPageInstance.InteractionOperations.OpenDirectoryInNewTab_Click}" Tag="OpenTab_FlyoutItem" Text="Open in new tab"> + + + + + @@ -428,9 +448,13 @@ x:Name="OpenInNewWindowItem" x:Uid="BaseLayoutItemContextFlyoutOpenInNewWindow" x:Load="False" - Click="{x:Bind ParentShellPageInstance.InteractionOperations.OpenInNewWindowItem_Click}" Tag="OpenWindow_FlyoutItem" Text="Open in new window"> + + + + + @@ -508,8 +532,12 @@ + + + + + @@ -523,8 +551,12 @@ + + + + + @@ -561,8 +593,12 @@ + + + + + @@ -620,8 +656,12 @@ + + + + + @@ -646,8 +686,12 @@ + + + + + @@ -656,8 +700,12 @@ + + + + + @@ -669,8 +717,12 @@ + + + + + diff --git a/Files/Views/LayoutModes/GenericFileBrowser.xaml.cs b/Files/Views/LayoutModes/GenericFileBrowser.xaml.cs index 83774f9a57d8..84d2af1de30f 100644 --- a/Files/Views/LayoutModes/GenericFileBrowser.xaml.cs +++ b/Files/Views/LayoutModes/GenericFileBrowser.xaml.cs @@ -504,7 +504,7 @@ private void AllView_PreviewKeyDown(object sender, KeyRoutedEventArgs e) } else if (e.Key == VirtualKey.Enter && e.KeyStatus.IsMenuKeyDown) { - ParentShellPageInstance.InteractionOperations.ShowPropertiesButton_Click(null, null); + ParentShellPageInstance.InteractionOperations.ShowProperties(); e.Handled = true; } else if (e.KeyStatus.IsMenuKeyDown && (e.Key == VirtualKey.Left || e.Key == VirtualKey.Right || e.Key == VirtualKey.Up)) diff --git a/Files/Views/LayoutModes/GridViewBrowser.xaml b/Files/Views/LayoutModes/GridViewBrowser.xaml index a1319917c171..115129457e63 100644 --- a/Files/Views/LayoutModes/GridViewBrowser.xaml +++ b/Files/Views/LayoutModes/GridViewBrowser.xaml @@ -233,8 +233,12 @@ + + + + + @@ -349,9 +353,13 @@ x:Name="OpenItemWithAppPicker" x:Uid="BaseLayoutItemContextFlyoutOpenItemWith" x:Load="False" - Click="{x:Bind ParentShellPageInstance.InteractionOperations.OpenItemWithApplicationPicker_Click}" Tag="OpenWith" Text="Open With"> + + + + + @@ -359,9 +367,13 @@ + + + + + @@ -369,9 +381,13 @@ + + + + + @@ -380,9 +396,13 @@ x:Name="OpenInNewTab" x:Uid="BaseLayoutItemContextFlyoutOpenInNewTab" x:Load="False" - Click="{x:Bind ParentShellPageInstance.InteractionOperations.OpenDirectoryInNewTab_Click}" Tag="OpenTab_FlyoutItem" Text="Open in new tab"> + + + + + @@ -391,9 +411,13 @@ x:Name="OpenInNewWindowItem" x:Uid="BaseLayoutItemContextFlyoutOpenInNewWindow" x:Load="False" - Click="{x:Bind ParentShellPageInstance.InteractionOperations.OpenInNewWindowItem_Click}" Tag="OpenWindow_FlyoutItem" Text="Open in new window"> + + + + + @@ -471,8 +495,12 @@ + + + + + @@ -486,8 +514,12 @@ + + + + + @@ -524,8 +556,12 @@ + + + + + @@ -583,8 +619,12 @@ + + + + + @@ -609,8 +649,12 @@ + + + + + @@ -619,8 +663,12 @@ + + + + + @@ -632,8 +680,12 @@ + + + + + diff --git a/Files/Views/LayoutModes/GridViewBrowser.xaml.cs b/Files/Views/LayoutModes/GridViewBrowser.xaml.cs index df870f620ff3..e99baa168903 100644 --- a/Files/Views/LayoutModes/GridViewBrowser.xaml.cs +++ b/Files/Views/LayoutModes/GridViewBrowser.xaml.cs @@ -329,7 +329,7 @@ private void FileList_PreviewKeyDown(object sender, KeyRoutedEventArgs e) } else if (e.Key == VirtualKey.Enter && e.KeyStatus.IsMenuKeyDown) { - ParentShellPageInstance.InteractionOperations.ShowPropertiesButton_Click(null, null); + ParentShellPageInstance.InteractionOperations.ShowProperties(); e.Handled = true; } else if (e.Key == VirtualKey.Space) diff --git a/Files/Views/ModernShellPage.xaml.cs b/Files/Views/ModernShellPage.xaml.cs index 08cc36fc62c3..16d6b450aeda 100644 --- a/Files/Views/ModernShellPage.xaml.cs +++ b/Files/Views/ModernShellPage.xaml.cs @@ -937,7 +937,7 @@ await FilesystemHelpers.DeleteItemsAsync( case (true, false, false, true, VirtualKey.C): // ctrl + c, copy if (!NavigationToolbar.IsEditModeEnabled && !ContentPage.IsRenamingItem) { - InteractionOperations.CopyItem_ClickAsync(null, null); + InteractionOperations.ShowProperties(); } break; @@ -953,7 +953,7 @@ await FilesystemHelpers.DeleteItemsAsync( case (true, false, false, true, VirtualKey.X): // ctrl + x, cut if (!NavigationToolbar.IsEditModeEnabled && !ContentPage.IsRenamingItem) { - InteractionOperations.CutItem_Click(null, null); + InteractionOperations.ShowProperties(); } break; From ff134994a8c7e25b9fa5de245e3e92c98d006f2c Mon Sep 17 00:00:00 2001 From: d2dyno006 <53011783+d2dyno006@users.noreply.github.com> Date: Sun, 21 Mar 2021 10:39:37 +0100 Subject: [PATCH 2/9] rm2 --- Files/BaseLayout.cs | 4 +- .../BaseLayoutCommandImplementationModel.cs | 134 +++++++++++++++ .../Interacts/BaseLayoutCommandsViewModel.cs | 25 +++ .../IBaseLayoutCommandImplementationModel.cs | 17 ++ Files/Interacts/Interaction.cs | 160 +----------------- .../Views/LayoutModes/GenericFileBrowser.xaml | 47 ++++- Files/Views/LayoutModes/GridViewBrowser.xaml | 49 +++++- .../Views/LayoutModes/GridViewBrowser.xaml.cs | 8 - Files/Views/ModernShellPage.xaml | 22 +-- Files/Views/ModernShellPage.xaml.cs | 46 ++++- 10 files changed, 315 insertions(+), 197 deletions(-) diff --git a/Files/BaseLayout.cs b/Files/BaseLayout.cs index 003b187f7e58..dbcc962181bc 100644 --- a/Files/BaseLayout.cs +++ b/Files/BaseLayout.cs @@ -1,5 +1,6 @@ using Files.Common; using Files.DataModels; +using Files.Dialogs; using Files.Enums; using Files.EventArguments; using Files.Extensions; @@ -9,6 +10,7 @@ using Files.UserControls; using Files.ViewModels; using Files.Views; +using Microsoft.Toolkit.Mvvm.Input; using Microsoft.Toolkit.Uwp; using Microsoft.Toolkit.Uwp.UI; using Newtonsoft.Json; @@ -618,7 +620,7 @@ public void RightClickContextMenu_Opening(object sender, object e) Tag = "CreateNewFile" }; } - menuLayoutItem.Command = ParentShellPageInstance.InteractionOperations.CreateNewFile; + menuLayoutItem.Command = new RelayCommand(() => ParentShellPageInstance.InteractionOperations.CreateFileFromDialogResultType(AddItemType.File, null)); menuLayoutItem.CommandParameter = newEntry; newItemMenu.Items.Insert(separatorIndex + 1, menuLayoutItem); } diff --git a/Files/Interacts/BaseLayoutCommandImplementationModel.cs b/Files/Interacts/BaseLayoutCommandImplementationModel.cs index c6374ce1eed2..3ecaf4a16058 100644 --- a/Files/Interacts/BaseLayoutCommandImplementationModel.cs +++ b/Files/Interacts/BaseLayoutCommandImplementationModel.cs @@ -13,6 +13,10 @@ using System; using Windows.UI.Core; using Windows.System; +using Files.Dialogs; +using System.Diagnostics; +using Windows.Foundation; +using Windows.UI.Xaml.Input; namespace Files.Interacts { @@ -407,6 +411,136 @@ public virtual async void OpenInNewWindowItem(RoutedEventArgs e) } } + public virtual void CreateNewFolder(RoutedEventArgs e) + { + associatedInstance.InteractionOperations.CreateFileFromDialogResultType(AddItemType.Folder, null); + } + + public virtual void CreateNewFile(RoutedEventArgs e) + { + associatedInstance.InteractionOperations.CreateFileFromDialogResultType(AddItemType.File, null); + } + + public virtual async void PasteItemsFromClipboard(RoutedEventArgs e) + { + await associatedInstance.InteractionOperations.PasteItemAsync(associatedInstance.FilesystemViewModel.WorkingDirectory); + } + + public virtual void CopyPathOfSelectedItem(RoutedEventArgs e) + { + try + { + if (associatedInstance.SlimContentPage != null) + { + DataPackage data = new DataPackage(); + data.SetText(associatedInstance.SlimContentPage.SelectedItem.ItemPath); + Clipboard.SetContent(data); + Clipboard.Flush(); + } + } + catch (Exception ex) + { + Debugger.Break(); + } + } + + public virtual void OpenDirectoryInDefaultTerminal(RoutedEventArgs e) + { + associatedInstance.InteractionOperations.OpenDirectoryInTerminal(associatedInstance.FilesystemViewModel.WorkingDirectory); + } + + public virtual void ShareItem(RoutedEventArgs e) + { + DataTransferManager manager = DataTransferManager.GetForCurrentView(); + manager.DataRequested += new TypedEventHandler(Manager_DataRequested); + DataTransferManager.ShowShareUI(); + + async void Manager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args) + { + DataRequestDeferral dataRequestDeferral = args.Request.GetDeferral(); + List items = new List(); + DataRequest dataRequest = args.Request; + + /*dataRequest.Data.Properties.Title = "Data Shared From Files"; + dataRequest.Data.Properties.Description = "The items you selected will be shared";*/ + + foreach (ListedItem item in associatedInstance.SlimContentPage.SelectedItems) + { + if (item.IsShortcutItem) + { + if (item.IsLinkItem) + { + dataRequest.Data.Properties.Title = string.Format("ShareDialogTitle".GetLocalized(), items.First().Name); + dataRequest.Data.Properties.Description = "ShareDialogSingleItemDescription".GetLocalized(); + dataRequest.Data.SetWebLink(new Uri(((ShortcutItem)item).TargetPath)); + dataRequestDeferral.Complete(); + return; + } + } + else if (item.PrimaryItemAttribute == StorageItemTypes.Folder) + { + if (await StorageItemHelpers.ToStorageItem(item.ItemPath, associatedInstance) is StorageFolder folder) + { + items.Add(folder); + } + } + else + { + if (await StorageItemHelpers.ToStorageItem(item.ItemPath, associatedInstance) is StorageFile file) + { + items.Add(file); + } + } + } + + if (items.Count == 1) + { + dataRequest.Data.Properties.Title = string.Format("ShareDialogTitle".GetLocalized(), items.First().Name); + dataRequest.Data.Properties.Description = "ShareDialogSingleItemDescription".GetLocalized(); + } + else if (items.Count == 0) + { + dataRequest.FailWithDisplayText("ShareDialogFailMessage".GetLocalized()); + dataRequestDeferral.Complete(); + return; + } + else + { + dataRequest.Data.Properties.Title = string.Format("ShareDialogTitleMultipleItems".GetLocalized(), items.Count, + "ItemsCount.Text".GetLocalized()); + dataRequest.Data.Properties.Description = "ShareDialogMultipleItemsDescription".GetLocalized(); + } + + dataRequest.Data.SetStorageItems(items); + dataRequestDeferral.Complete(); + + // TODO: Unhook the event somewhere + } + } + + public virtual void PinDirectoryToSidebar(RoutedEventArgs e) + { + App.SidebarPinnedController.Model.AddItem(associatedInstance.FilesystemViewModel.WorkingDirectory); + } + + public virtual void ItemPointerPressed(PointerRoutedEventArgs e) + { + if (e.GetCurrentPoint(null).Properties.IsMiddleButtonPressed) + { + if ((e.OriginalSource as FrameworkElement)?.DataContext is ListedItem Item && Item.PrimaryItemAttribute == StorageItemTypes.Folder) + { + if (Item.IsShortcutItem) + { + Interaction.OpenPathInNewTab(((e.OriginalSource as FrameworkElement)?.DataContext as ShortcutItem)?.TargetPath ?? Item.ItemPath); + } + else + { + Interaction.OpenPathInNewTab(Item.ItemPath); + } + } + } + } + #endregion } } diff --git a/Files/Interacts/BaseLayoutCommandsViewModel.cs b/Files/Interacts/BaseLayoutCommandsViewModel.cs index fd37cf770301..114c298a6e80 100644 --- a/Files/Interacts/BaseLayoutCommandsViewModel.cs +++ b/Files/Interacts/BaseLayoutCommandsViewModel.cs @@ -2,6 +2,7 @@ using System; using System.Windows.Input; using Windows.UI.Xaml; +using Windows.UI.Xaml.Input; namespace Files.Interacts { @@ -51,6 +52,14 @@ private void InitializeCommands() OpenDirectoryInNewTabCommand = new RelayCommand(commandsModel.OpenDirectoryInNewTab); OpenDirectoryInNewPaneCommand = new RelayCommand(commandsModel.OpenDirectoryInNewPane); OpenInNewWindowItemCommand = new RelayCommand(commandsModel.OpenInNewWindowItem); + CreateNewFolderCommand = new RelayCommand(commandsModel.CreateNewFolder); + CreateNewFileCommand = new RelayCommand(commandsModel.CreateNewFile); + PasteItemsFromClipboardCommand = new RelayCommand(commandsModel.PasteItemsFromClipboard); + CopyPathOfSelectedItemCommand = new RelayCommand(commandsModel.CopyPathOfSelectedItem); + OpenDirectoryInDefaultTerminalCommand = new RelayCommand(commandsModel.OpenDirectoryInDefaultTerminal); + ShareItemCommand = new RelayCommand(commandsModel.ShareItem); + PinDirectoryToSidebarCommand = new RelayCommand(commandsModel.PinDirectoryToSidebar); + ItemPointerPressedCommand = new RelayCommand(commandsModel.ItemPointerPressed); } #endregion @@ -103,6 +112,22 @@ private void InitializeCommands() public ICommand OpenInNewWindowItemCommand { get; private set; } + public ICommand CreateNewFolderCommand { get; private set; } + + public ICommand CreateNewFileCommand { get; private set; } + + public ICommand PasteItemsFromClipboardCommand { get; private set; } + + public ICommand CopyPathOfSelectedItemCommand { get; private set; } + + public ICommand OpenDirectoryInDefaultTerminalCommand { get; private set; } + + public ICommand ShareItemCommand { get; private set; } + + public ICommand PinDirectoryToSidebarCommand { get; private set; } + + public ICommand ItemPointerPressedCommand { get; private set; } + #endregion #region IDisposable diff --git a/Files/Interacts/IBaseLayoutCommandImplementationModel.cs b/Files/Interacts/IBaseLayoutCommandImplementationModel.cs index 23e035f9fce7..43cb01c0311d 100644 --- a/Files/Interacts/IBaseLayoutCommandImplementationModel.cs +++ b/Files/Interacts/IBaseLayoutCommandImplementationModel.cs @@ -1,5 +1,6 @@ using System; using Windows.UI.Xaml; +using Windows.UI.Xaml.Input; namespace Files.Interacts { @@ -50,5 +51,21 @@ public interface IBaseLayoutCommandImplementationModel : IDisposable void OpenDirectoryInNewPane(RoutedEventArgs e); void OpenInNewWindowItem(RoutedEventArgs e); + + void CreateNewFolder(RoutedEventArgs e); + + void CreateNewFile(RoutedEventArgs e); + + void PasteItemsFromClipboard(RoutedEventArgs e); + + void CopyPathOfSelectedItem(RoutedEventArgs e); + + void OpenDirectoryInDefaultTerminal(RoutedEventArgs e); + + void ShareItem(RoutedEventArgs e); + + void PinDirectoryToSidebar(RoutedEventArgs e); + + void ItemPointerPressed(PointerRoutedEventArgs e); } } diff --git a/Files/Interacts/Interaction.cs b/Files/Interacts/Interaction.cs index 5c1d556fb9b1..1066b1e5bf6f 100644 --- a/Files/Interacts/Interaction.cs +++ b/Files/Interacts/Interaction.cs @@ -150,38 +150,6 @@ public async void SetAsBackground(WallpaperType type, string filePath) } } - public RelayCommand AddNewTabToMultitaskingControl => new RelayCommand(() => OpenNewTab()); - - private async void OpenNewTab() - { - await MainPage.AddNewTabByPathAsync(typeof(PaneHolderPage), "NewTab".GetLocalized()); - } - - public RelayCommand OpenNewPane => new RelayCommand(() => OpenNewPaneCommand()); - - public void OpenNewPaneCommand() - { - AssociatedInstance.PaneHolder?.OpenPathInNewPane("NewTab".GetLocalized()); - } - - public void ItemPointerPressed(object sender, PointerRoutedEventArgs e) - { - if (e.GetCurrentPoint(null).Properties.IsMiddleButtonPressed) - { - if ((e.OriginalSource as FrameworkElement)?.DataContext is ListedItem Item && Item.PrimaryItemAttribute == StorageItemTypes.Folder) - { - if (Item.IsShortcutItem) - { - OpenPathInNewTab(((e.OriginalSource as FrameworkElement)?.DataContext as ShortcutItem)?.TargetPath ?? Item.ItemPath); - } - else - { - OpenPathInNewTab(Item.ItemPath); - } - } - } - } - public static async void OpenPathInNewTab(string path) { await MainPage.AddNewTabByPathAsync(typeof(PaneHolderPage), path); @@ -199,9 +167,7 @@ public static async Task OpenTabInNewWindowAsync(string tabArgs) return await Launcher.LaunchUriAsync(folderUri); } - public RelayCommand OpenDirectoryInDefaultTerminal => new RelayCommand(() => OpenDirectoryInTerminal(AssociatedInstance.FilesystemViewModel.WorkingDirectory)); - - private async void OpenDirectoryInTerminal(string workingDir) + public async void OpenDirectoryInTerminal(string workingDir) { var terminal = AppSettings.TerminalController.Model.GetDefaultTerminal(); @@ -555,21 +521,12 @@ public async void OpenSelectedItems(bool openViaApplicationPicker = false) } } - public RelayCommand OpenNewWindow => new RelayCommand(() => LaunchNewWindow()); - public async void LaunchNewWindow() { var filesUWPUri = new Uri("files-uwp:"); await Launcher.LaunchUriAsync(filesUWPUri); } - public void ShareItem_Click(object sender, RoutedEventArgs e) - { - DataTransferManager manager = DataTransferManager.GetForCurrentView(); - manager.DataRequested += new TypedEventHandler(Manager_DataRequested); - DataTransferManager.ShowShareUI(); - } - public async void ShowProperties() { if (AssociatedInstance.SlimContentPage.IsItemSelected) @@ -648,71 +605,6 @@ await newWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => } } - public void PinDirectoryToSidebar(object sender, RoutedEventArgs e) - { - App.SidebarPinnedController.Model.AddItem(AssociatedInstance.FilesystemViewModel.WorkingDirectory); - } - - private async void Manager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args) - { - DataRequestDeferral dataRequestDeferral = args.Request.GetDeferral(); - List items = new List(); - DataRequest dataRequest = args.Request; - - /*dataRequest.Data.Properties.Title = "Data Shared From Files"; - dataRequest.Data.Properties.Description = "The items you selected will be shared";*/ - - foreach (ListedItem item in AssociatedInstance.SlimContentPage.SelectedItems) - { - if (item.IsShortcutItem) - { - if (item.IsLinkItem) - { - dataRequest.Data.Properties.Title = string.Format("ShareDialogTitle".GetLocalized(), items.First().Name); - dataRequest.Data.Properties.Description = "ShareDialogSingleItemDescription".GetLocalized(); - dataRequest.Data.SetWebLink(new Uri(((ShortcutItem)item).TargetPath)); - dataRequestDeferral.Complete(); - return; - } - } - else if (item.PrimaryItemAttribute == StorageItemTypes.Folder) - { - if (await StorageItemHelpers.ToStorageItem(item.ItemPath, AssociatedInstance) is StorageFolder folder) - { - items.Add(folder); - } - } - else - { - if (await StorageItemHelpers.ToStorageItem(item.ItemPath, AssociatedInstance) is StorageFile file) - { - items.Add(file); - } - } - } - - if (items.Count == 1) - { - dataRequest.Data.Properties.Title = string.Format("ShareDialogTitle".GetLocalized(), items.First().Name); - dataRequest.Data.Properties.Description = "ShareDialogSingleItemDescription".GetLocalized(); - } - else if (items.Count == 0) - { - dataRequest.FailWithDisplayText("ShareDialogFailMessage".GetLocalized()); - dataRequestDeferral.Complete(); - return; - } - else - { - dataRequest.Data.Properties.Title = string.Format("ShareDialogTitleMultipleItems".GetLocalized(), items.Count, - "ItemsCount.Text".GetLocalized()); - dataRequest.Data.Properties.Description = "ShareDialogMultipleItemsDescription".GetLocalized(); - } - - dataRequest.Data.SetStorageItems(items); - dataRequestDeferral.Complete(); - } - public async Task RenameFileItemAsync(ListedItem item, string oldName, string newName) { if (oldName == newName) @@ -757,28 +649,7 @@ public void SetHiddenAttributeItem(ListedItem item, bool isHidden) AssociatedInstance.SlimContentPage.ResetItemOpacity(); } - public RelayCommand CopyPathOfSelectedItem => new RelayCommand(() => CopyLocation()); - - private void CopyLocation() - { - try - { - if (AssociatedInstance.SlimContentPage != null) - { - DataPackage data = new DataPackage(); - data.SetText(AssociatedInstance.SlimContentPage.SelectedItem.ItemPath); - Clipboard.SetContent(data); - Clipboard.Flush(); - } - } - catch - { - } - } - - public RelayCommand CopyPathOfWorkingDirectory => new RelayCommand(() => CopyWorkingLocation()); - - private void CopyWorkingLocation() + public void CopyWorkingLocation() { try { @@ -795,8 +666,6 @@ private void CopyWorkingLocation() } } - public RelayCommand PasteItemsFromClipboard => new RelayCommand(async () => await PasteItemAsync(AssociatedInstance.FilesystemViewModel.WorkingDirectory)); - public async Task PasteItemAsync(string destinationPath) { DataPackageView packageView = await FilesystemTasks.Wrap(() => Task.FromResult(Clipboard.GetContent())); @@ -859,31 +728,6 @@ public async void CreateFileFromDialogResultType(AddItemType itemType, ShellNewE } } - public RelayCommand CreateNewFolder => new RelayCommand(() => NewFolder()); - public RelayCommand CreateNewFile => new RelayCommand((itemType) => NewFile(itemType)); - - private void NewFolder() - { - CreateFileFromDialogResultType(AddItemType.Folder, null); - } - - private void NewFile(ShellNewEntry itemType) - { - CreateFileFromDialogResultType(AddItemType.File, itemType); - } - - public RelayCommand SelectAllContentPageItems => new RelayCommand(() => SelectAllItems(AssociatedInstance.SlimContentPage)); - - public void SelectAllItems(IBaseLayout contentPage) => contentPage.SelectAllItems(); - - public RelayCommand InvertContentPageSelction => new RelayCommand(() => InvertAllItems(AssociatedInstance.SlimContentPage)); - - public void InvertAllItems(IBaseLayout contentPage) => contentPage.InvertSelection(); - - public RelayCommand ClearContentPageSelection => new RelayCommand(() => ClearAllItems(AssociatedInstance.SlimContentPage)); - - public void ClearAllItems(IBaseLayout contentPage) => contentPage.ClearSelection(); - public void PushJumpChar(char letter) { JumpString += letter.ToString().ToLower(); diff --git a/Files/Views/LayoutModes/GenericFileBrowser.xaml b/Files/Views/LayoutModes/GenericFileBrowser.xaml index bb1d93cc2df4..1ca2894235a2 100644 --- a/Files/Views/LayoutModes/GenericFileBrowser.xaml +++ b/Files/Views/LayoutModes/GenericFileBrowser.xaml @@ -164,9 +164,13 @@ + + + + + @@ -181,9 +185,13 @@ + + + + + @@ -205,8 +213,12 @@ + + + + + @@ -215,10 +227,13 @@ + + + + + @@ -229,8 +244,12 @@ x:Name="PinDirectoryToSidebar" x:Uid="BaseLayoutContextFlyoutPinDirectoryToSidebar" x:Load="False" - Click="{x:Bind ParentShellPageInstance.InteractionOperations.PinDirectoryToSidebar}" Text="Pin directory to sidebar"> + + + + + @@ -522,8 +541,12 @@ + + + + + @@ -570,8 +593,12 @@ + + + + + @@ -817,7 +844,6 @@ Holding="AllView_Holding" IsDoubleTapEnabled="True" IsRightTapEnabled="True" - PointerPressed="{x:Bind ParentShellPageInstance.InteractionOperations.ItemPointerPressed}" PreparingCellForEdit="AllView_PreparingCellForEdit" PreviewKeyDown="AllView_PreviewKeyDown" RightTapped="AllView_RightTapped" @@ -884,6 +910,9 @@ + + + + + + + + + + + + + @@ -162,9 +170,13 @@ + + + + + @@ -186,8 +198,12 @@ + + + + + @@ -196,10 +212,13 @@ + + + + + @@ -210,8 +229,12 @@ x:Name="PinDirectoryToSidebar" x:Uid="BaseLayoutContextFlyoutPinDirectoryToSidebar" x:Load="False" - Click="{x:Bind ParentShellPageInstance.InteractionOperations.PinDirectoryToSidebar}" Text="Pin directory to sidebar"> + + + + + @@ -485,8 +508,12 @@ + + + + + @@ -533,8 +560,12 @@ + + + + + diff --git a/Files/Views/LayoutModes/GridViewBrowser.xaml.cs b/Files/Views/LayoutModes/GridViewBrowser.xaml.cs index e99baa168903..12c85d8ccb3f 100644 --- a/Files/Views/LayoutModes/GridViewBrowser.xaml.cs +++ b/Files/Views/LayoutModes/GridViewBrowser.xaml.cs @@ -180,14 +180,6 @@ private void StackPanel_RightTapped(object sender, RightTappedRoutedEventArgs e) SetSelectedItemOnUi(FileList.ItemFromContainer(parentContainer) as ListedItem); } - private void GridViewBrowserViewer_PointerPressed(object sender, PointerRoutedEventArgs e) - { - if (e.GetCurrentPoint(null).Properties.IsMiddleButtonPressed) - { - ParentShellPageInstance.InteractionOperations.ItemPointerPressed(sender, e); - } - } - private void FileList_SelectionChanged(object sender, SelectionChangedEventArgs e) { SelectedItems = FileList.SelectedItems.Cast().Where(x => x != null).ToList(); diff --git a/Files/Views/ModernShellPage.xaml b/Files/Views/ModernShellPage.xaml index 0b75161562b1..426d3bae4b9a 100644 --- a/Files/Views/ModernShellPage.xaml +++ b/Files/Views/ModernShellPage.xaml @@ -248,9 +248,9 @@ x:FieldModifier="public" MultiselectEnabled="{x:Bind InteractionViewModel.MultiselectEnabled}" - SelectAllInvokedCommand="{x:Bind InteractionOperations.SelectAllContentPageItems, Mode=OneWay}" - InvertSelectionInvokedCommand="{x:Bind InteractionOperations.InvertContentPageSelction, Mode=OneWay}" - ClearSelectionInvokedCommand="{x:Bind InteractionOperations.ClearContentPageSelection, Mode=OneWay}" + SelectAllInvokedCommand="{x:Bind SelectAllContentPageItemsCommand}" + InvertSelectionInvokedCommand="{x:Bind InvertContentPageSelctionCommand}" + ClearSelectionInvokedCommand="{x:Bind ClearContentPageSelectionCommand}" LayoutModeInformation="{x:Bind FolderSettings.LayoutModeInformation}" ToggleLayoutModeDetailsView="{x:Bind FolderSettings.ToggleLayoutModeDetailsView}" @@ -264,18 +264,18 @@ CanCreateFileInPage="{x:Bind InstanceViewModel.CanCreateFileInPage, Mode=OneWay}" CanOpenTerminalInPage="{x:Bind InstanceViewModel.CanOpenTerminalInPage, Mode=OneWay}" CanPasteInPage="{x:Bind InstanceViewModel.CanPasteInPage, Mode=OneWay}" - CopyPathInvokedCommand="{x:Bind InteractionOperations.CopyPathOfWorkingDirectory, Mode=OneWay}" + CopyPathInvokedCommand="{x:Bind CopyPathOfWorkingDirectoryCommand}" IsCreateButtonEnabledInPage="{x:Bind InstanceViewModel.IsCreateButtonEnabledInPage, Mode=OneWay}" IsMultiPaneActive="{x:Bind IsMultiPaneActive, Mode=OneWay}" IsPageMainPane="{x:Bind IsPageMainPane, Mode=OneWay}" IsPageTypeNotHome="{x:Bind InstanceViewModel.IsPageTypeNotHome, Mode=OneWay}" - NewFileInvokedCommand="{x:Bind InteractionOperations.CreateNewFile, Mode=OneWay}" - NewFolderInvokedCommand="{x:Bind InteractionOperations.CreateNewFolder, Mode=OneWay}" - NewPaneInvokedCommand="{x:Bind InteractionOperations.OpenNewPane, Mode=OneWay}" - NewTabInvokedCommand="{x:Bind InteractionOperations.AddNewTabToMultitaskingControl, Mode=OneWay}" - NewWindowInvokedCommand="{x:Bind InteractionOperations.OpenNewWindow, Mode=OneWay}" - OpenInTerminalInvokedCommand="{x:Bind InteractionOperations.OpenDirectoryInDefaultTerminal, Mode=OneWay}" - PasteInvokedCommand="{x:Bind InteractionOperations.PasteItemsFromClipboard, Mode=OneWay}" + NewFileInvokedCommand="{x:Bind CreateNewFileCommand}" + NewFolderInvokedCommand="{x:Bind CreateNewFolderCommand}" + NewPaneInvokedCommand="{x:Bind OpenNewPaneCommand}" + NewTabInvokedCommand="{x:Bind AddNewTabToMultitaskingControlCommand}" + NewWindowInvokedCommand="{x:Bind OpenNewWindowCommand}" + OpenInTerminalInvokedCommand="{x:Bind OpenDirectoryInDefaultTerminalCommand}" + PasteInvokedCommand="{x:Bind PasteItemsFromClipboardCommand}" PreviewPaneEnabled="{x:Bind PreviewPaneEnabled, Mode=TwoWay}" ShowMultiPaneControls="{x:Bind converters1:MultiBooleanConverter.AndConvert(IsMultiPaneEnabled, IsPageMainPane), Mode=OneWay}" /> diff --git a/Files/Views/ModernShellPage.xaml.cs b/Files/Views/ModernShellPage.xaml.cs index 16d6b450aeda..f97b8c0cdced 100644 --- a/Files/Views/ModernShellPage.xaml.cs +++ b/Files/Views/ModernShellPage.xaml.cs @@ -11,6 +11,7 @@ using Files.UserControls.MultitaskingControl; using Files.ViewModels; using Files.Views.LayoutModes; +using Microsoft.Toolkit.Mvvm.Input; using Microsoft.Toolkit.Uwp; using System; using System.Collections.Generic; @@ -22,6 +23,7 @@ using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; +using System.Windows.Input; using Windows.ApplicationModel.AppService; using Windows.ApplicationModel.Core; using Windows.ApplicationModel.DataTransfer; @@ -135,6 +137,28 @@ public bool IsPageMainPane } } + public ICommand SelectAllContentPageItemsCommand { get; private set; } + + public ICommand InvertContentPageSelctionCommand { get; private set; } + + public ICommand ClearContentPageSelectionCommand { get; private set; } + + public ICommand PasteItemsFromClipboardCommand { get; private set; } + + public ICommand CopyPathOfWorkingDirectoryCommand { get; private set; } + + public ICommand OpenNewWindowCommand { get; private set; } + + public ICommand OpenNewPaneCommand { get; private set; } + + public ICommand OpenDirectoryInDefaultTerminalCommand { get; private set; } + + public ICommand AddNewTabToMultitaskingControlCommand { get; private set; } + + public ICommand CreateNewFileCommand { get; private set; } + + public ICommand CreateNewFolderCommand { get; private set; } + public static readonly DependencyProperty IsPageMainPaneProperty = DependencyProperty.Register("IsPageMainPane", typeof(bool), typeof(ModernShellPage), new PropertyMetadata(true)); @@ -207,6 +231,25 @@ public ModernShellPage() AppServiceConnectionHelper.ConnectionChanged += AppServiceConnectionHelper_ConnectionChanged; } + private void InitializeCommands() + { + if (this.SlimContentPage != null) + { + SelectAllContentPageItemsCommand = new RelayCommand(this.SlimContentPage.SelectAllItems); + ClearContentPageSelectionCommand = new RelayCommand(this.SlimContentPage.ClearSelection); + InvertContentPageSelctionCommand = new RelayCommand(this.SlimContentPage.InvertSelection); + } + PasteItemsFromClipboardCommand = new RelayCommand(async () => await this.InteractionOperations.PasteItemAsync(FilesystemViewModel.WorkingDirectory)); + CopyPathOfWorkingDirectoryCommand = new RelayCommand(this.InteractionOperations.CopyWorkingLocation); + OpenNewWindowCommand = new RelayCommand(this.InteractionOperations.LaunchNewWindow); + OpenNewPaneCommand = new RelayCommand(() => PaneHolder?.OpenPathInNewPane("NewTab".GetLocalized())); + OpenDirectoryInDefaultTerminalCommand = new RelayCommand(() => this.InteractionOperations.OpenDirectoryInTerminal(this.FilesystemViewModel.WorkingDirectory)); + AddNewTabToMultitaskingControlCommand = new RelayCommand(async () => await MainPage.AddNewTabByPathAsync(typeof(PaneHolderPage), "NewTab".GetLocalized())); + + CreateNewFileCommand = new RelayCommand(() => InteractionOperations.CreateFileFromDialogResultType(AddItemType.File, null)); + CreateNewFolderCommand = new RelayCommand(() => InteractionOperations.CreateFileFromDialogResultType(AddItemType.Folder, null)); + } + private void FolderSettings_LayoutPreferencesUpdateRequired(object sender, LayoutPreferenceEventArgs e) { if (FilesystemViewModel != null) @@ -859,6 +902,7 @@ private void ViewModel_WorkingDirectoryModified(object sender, WorkingDirectoryM private async void ItemDisplayFrame_Navigated(object sender, NavigationEventArgs e) { ContentPage = await GetContentOrNullAsync(); + InitializeCommands(); NavigationToolbar.ClearSearchBoxQueryText(true); if (ItemDisplayFrame.CurrentSourcePageType == typeof(GenericFileBrowser) || ItemDisplayFrame.CurrentSourcePageType == typeof(GridViewBrowser)) @@ -961,7 +1005,7 @@ await FilesystemHelpers.DeleteItemsAsync( case (true, false, false, true, VirtualKey.A): // ctrl + a, select all if (!NavigationToolbar.IsEditModeEnabled && !ContentPage.IsRenamingItem) { - InteractionOperations.SelectAllItems(this.ContentPage); + this.SlimContentPage.SelectAllItems(); } break; From 76dea6405201b9029c2f33c30f9f3dbc5afa778e Mon Sep 17 00:00:00 2001 From: d2dyno006 <53011783+d2dyno006@users.noreply.github.com> Date: Sun, 21 Mar 2021 11:50:09 +0100 Subject: [PATCH 3/9] rm3 --- Files/BaseLayout.cs | 2 +- Files/Files.csproj | 3 + Files/Helpers/NavigationHelpers.cs | 342 +++++++++++++++ Files/Helpers/WallpaperHelpers.cs | 49 +++ Files/Helpers/Win32Helpers.cs | 49 +++ .../BaseLayoutCommandImplementationModel.cs | 56 +-- Files/Interacts/Interaction.cs | 403 ------------------ .../HorizontalMultitaskingControl.xaml.cs | 5 +- .../VerticalTabViewControl.xaml.cs | 5 +- Files/UserControls/SidebarControl.xaml.cs | 4 +- .../UserControls/Widgets/DrivesWidget.xaml.cs | 4 +- .../ViewModels/Bundles/BundleItemViewModel.cs | 4 +- Files/ViewModels/Properties/FileProperties.cs | 2 +- .../LayoutModes/GenericFileBrowser.xaml.cs | 6 +- .../Views/LayoutModes/GridViewBrowser.xaml.cs | 6 +- Files/Views/MainPage.xaml.cs | 4 +- Files/Views/ModernShellPage.xaml.cs | 25 +- Files/Views/YourHome.xaml.cs | 2 +- 18 files changed, 515 insertions(+), 456 deletions(-) create mode 100644 Files/Helpers/NavigationHelpers.cs create mode 100644 Files/Helpers/WallpaperHelpers.cs create mode 100644 Files/Helpers/Win32Helpers.cs diff --git a/Files/BaseLayout.cs b/Files/BaseLayout.cs index dbcc962181bc..44c6a72ca2f0 100644 --- a/Files/BaseLayout.cs +++ b/Files/BaseLayout.cs @@ -951,7 +951,7 @@ protected async void Item_DragOver(object sender, DragEventArgs e) { dragOverItem = null; dragOverTimer.Stop(); - ParentShellPageInstance.InteractionOperations.OpenSelectedItems(false); + NavigationHelpers.OpenSelectedItems(ParentShellPageInstance, false); } }, TimeSpan.FromMilliseconds(1000), false); } diff --git a/Files/Files.csproj b/Files/Files.csproj index 9207900c1455..4deb50c5f450 100644 --- a/Files/Files.csproj +++ b/Files/Files.csproj @@ -211,6 +211,9 @@ ConfirmDeleteDialog.xaml + + + RestartControl.xaml diff --git a/Files/Helpers/NavigationHelpers.cs b/Files/Helpers/NavigationHelpers.cs new file mode 100644 index 000000000000..d42fd9e228e5 --- /dev/null +++ b/Files/Helpers/NavigationHelpers.cs @@ -0,0 +1,342 @@ +using Files.Filesystem; +using Files.Views; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.ApplicationModel.AppService; +using Windows.Foundation.Collections; +using Windows.System; +using Files.Common; +using Windows.Storage.Search; +using Windows.Storage; +using Files.Enums; +using Microsoft.Toolkit.Uwp; +using Windows.UI.Core; +using Windows.ApplicationModel.Core; + +namespace Files.Helpers +{ + public static class NavigationHelpers + { + public static async void OpenPathInNewTab(string path) + { + await MainPage.AddNewTabByPathAsync(typeof(PaneHolderPage), path); + } + + public static async Task OpenPathInNewWindowAsync(string path) + { + var folderUri = new Uri($"files-uwp:?folder={Uri.EscapeDataString(path)}"); + return await Launcher.LaunchUriAsync(folderUri); + } + + public static async Task OpenTabInNewWindowAsync(string tabArgs) + { + var folderUri = new Uri($"files-uwp:?tab={Uri.EscapeDataString(tabArgs)}"); + return await Launcher.LaunchUriAsync(folderUri); + } + + public static async void OpenDirectoryInTerminal(string workingDir, IShellPage associatedInstance) + { + var terminal = App.AppSettings.TerminalController.Model.GetDefaultTerminal(); + + if (associatedInstance.ServiceConnection != null) + { + var value = new ValueSet() + { + { "WorkingDirectory", workingDir }, + { "Application", terminal.Path }, + { "Arguments", string.Format(terminal.Arguments, + Helpers.PathNormalization.NormalizePath(workingDir)) } + }; + await associatedInstance.ServiceConnection.SendMessageAsync(value); + } + } + + public static async void OpenSelectedItems(IShellPage associatedInstance, bool openViaApplicationPicker = false) + { + if (associatedInstance.FilesystemViewModel.WorkingDirectory.StartsWith(App.AppSettings.RecycleBinPath)) + { + // Do not open files and folders inside the recycle bin + return; + } + if (associatedInstance.SlimContentPage == null) + { + return; + } + foreach (ListedItem item in associatedInstance.SlimContentPage.SelectedItems) + { + var type = item.PrimaryItemAttribute == StorageItemTypes.Folder ? + FilesystemItemType.Directory : FilesystemItemType.File; + await OpenPath(item.ItemPath, associatedInstance, type, false, openViaApplicationPicker); + } + } + + /// + /// Navigates to a directory or opens file + /// + /// The path to navigate to or open + /// The instance associated with view + /// + /// Determines whether history of opened item is saved (... to Recent Items/Windows Timeline/opening in background) + /// Determines whether open file using application picker + /// List of filenames that are selected upon navigation + public static async Task OpenPath(string path, IShellPage associatedInstance, FilesystemItemType? itemType = null, bool openSilent = false, bool openViaApplicationPicker = false, IEnumerable selectItems = null) + // TODO: This function reliability has not been extensively tested + { + string previousDir = associatedInstance.FilesystemViewModel.WorkingDirectory; + bool isHiddenItem = NativeFileOperationsHelper.HasFileAttribute(path, System.IO.FileAttributes.Hidden); + bool isShortcutItem = path.EndsWith(".lnk") || path.EndsWith(".url"); // Determine + FilesystemResult opened = (FilesystemResult)false; + + // Shortcut item variables + string shortcutTargetPath = null; + string shortcutArguments = null; + string shortcutWorkingDirectory = null; + bool shortcutRunAsAdmin = false; + bool shortcutIsFolder = false; + + if (itemType == null || isShortcutItem || isHiddenItem) + { + if (isShortcutItem) + { + var (status, response) = await associatedInstance.ServiceConnection.SendMessageForResponseAsync(new ValueSet() + { + { "Arguments", "FileOperation" }, + { "fileop", "ParseLink" }, + { "filepath", path } + }); + + if (status == AppServiceResponseStatus.Success) + { + shortcutTargetPath = response.Get("TargetPath", string.Empty); + shortcutArguments = response.Get("Arguments", string.Empty); + shortcutWorkingDirectory = response.Get("WorkingDirectory", string.Empty); + shortcutRunAsAdmin = response.Get("RunAsAdmin", false); + shortcutIsFolder = response.Get("IsFolder", false); + + itemType = shortcutIsFolder ? FilesystemItemType.Directory : FilesystemItemType.File; + } + else + { + return false; + } + } + else if (isHiddenItem) + { + itemType = NativeFileOperationsHelper.HasFileAttribute(path, System.IO.FileAttributes.Directory) ? FilesystemItemType.Directory : FilesystemItemType.File; + } + else + { + itemType = await StorageItemHelpers.GetTypeFromPath(path); + } + } + + var mostRecentlyUsed = Windows.Storage.AccessCache.StorageApplicationPermissions.MostRecentlyUsedList; + + if (itemType == FilesystemItemType.Directory) // OpenDirectory + { + if (isShortcutItem) + { + if (string.IsNullOrEmpty(shortcutTargetPath)) + { + await Win32Helpers.InvokeWin32ComponentAsync(path, associatedInstance); + return true; + } + else + { + associatedInstance.NavigationToolbar.PathControlDisplayText = shortcutTargetPath; + associatedInstance.NavigateWithArguments(associatedInstance.InstanceViewModel.FolderSettings.GetLayoutType(shortcutTargetPath), new NavigationArguments() + { + NavPathParam = shortcutTargetPath, + AssociatedTabInstance = associatedInstance, + SelectItems = selectItems + }); + + return true; + } + } + else if (isHiddenItem) + { + associatedInstance.NavigationToolbar.PathControlDisplayText = path; + associatedInstance.NavigateWithArguments(associatedInstance.InstanceViewModel.FolderSettings.GetLayoutType(path), new NavigationArguments() + { + NavPathParam = path, + AssociatedTabInstance = associatedInstance + }); + + return true; + } + else + { + opened = await associatedInstance.FilesystemViewModel.GetFolderWithPathFromPathAsync(path) + .OnSuccess(childFolder => + { + // Add location to MRU List + mostRecentlyUsed.Add(childFolder.Folder, childFolder.Path); + }); + if (!opened) + { + opened = (FilesystemResult)FolderHelpers.CheckFolderAccessWithWin32(path); + } + if (!opened) + { + opened = (FilesystemResult)path.StartsWith("ftp:"); + } + if (opened) + { + associatedInstance.NavigationToolbar.PathControlDisplayText = path; + associatedInstance.NavigateWithArguments(associatedInstance.InstanceViewModel.FolderSettings.GetLayoutType(path), new NavigationArguments() + { + NavPathParam = path, + AssociatedTabInstance = associatedInstance, + SelectItems = selectItems + }); + } + } + } + else if (itemType == FilesystemItemType.File) // OpenFile + { + if (isShortcutItem) + { + if (string.IsNullOrEmpty(shortcutTargetPath)) + { + await Win32Helpers.InvokeWin32ComponentAsync(path, associatedInstance); + } + else + { + if (!path.EndsWith(".url")) + { + StorageFileWithPath childFile = await associatedInstance.FilesystemViewModel.GetFileWithPathFromPathAsync(shortcutTargetPath); + if (childFile != null) + { + // Add location to MRU List + mostRecentlyUsed.Add(childFile.File, childFile.Path); + } + } + await Win32Helpers.InvokeWin32ComponentAsync(shortcutTargetPath, associatedInstance, shortcutArguments, shortcutRunAsAdmin, shortcutWorkingDirectory); + } + opened = (FilesystemResult)true; + } + else if (isHiddenItem) + { + await Win32Helpers.InvokeWin32ComponentAsync(path, associatedInstance); + } + else + { + opened = await associatedInstance.FilesystemViewModel.GetFileWithPathFromPathAsync(path) + .OnSuccess(async childFile => + { + // Add location to MRU List + mostRecentlyUsed.Add(childFile.File, childFile.Path); + + if (openViaApplicationPicker) + { + LauncherOptions options = new LauncherOptions + { + DisplayApplicationPicker = true + }; + await Launcher.LaunchFileAsync(childFile.File, options); + } + else + { + //try using launcher first + bool launchSuccess = false; + + StorageFileQueryResult fileQueryResult = null; + + //Get folder to create a file query (to pass to apps like Photos, Movies & TV..., needed to scroll through the folder like what Windows Explorer does) + StorageFolder currentFolder = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(System.IO.Path.GetDirectoryName(path)); + + if (currentFolder != null) + { + QueryOptions queryOptions = new QueryOptions(CommonFileQuery.DefaultQuery, null); + + //We can have many sort entries + SortEntry sortEntry = new SortEntry() + { + AscendingOrder = associatedInstance.InstanceViewModel.FolderSettings.DirectorySortDirection == Microsoft.Toolkit.Uwp.UI.SortDirection.Ascending + }; + + //Basically we tell to the launched app to follow how we sorted the files in the directory. + + var sortOption = associatedInstance.InstanceViewModel.FolderSettings.DirectorySortOption; + + switch (sortOption) + { + case Enums.SortOption.Name: + sortEntry.PropertyName = "System.ItemNameDisplay"; + queryOptions.SortOrder.Clear(); + queryOptions.SortOrder.Add(sortEntry); + break; + + case Enums.SortOption.DateModified: + sortEntry.PropertyName = "System.DateModified"; + queryOptions.SortOrder.Clear(); + queryOptions.SortOrder.Add(sortEntry); + break; + + case Enums.SortOption.DateCreated: + sortEntry.PropertyName = "System.DateCreated"; + queryOptions.SortOrder.Clear(); + queryOptions.SortOrder.Add(sortEntry); + break; + + //Unfortunately this is unsupported | Remarks: https://docs.microsoft.com/en-us/uwp/api/windows.storage.search.queryoptions.sortorder?view=winrt-19041 + //case Enums.SortOption.Size: + + //sortEntry.PropertyName = "System.TotalFileSize"; + //queryOptions.SortOrder.Clear(); + //queryOptions.SortOrder.Add(sortEntry); + //break; + + //Unfortunately this is unsupported | Remarks: https://docs.microsoft.com/en-us/uwp/api/windows.storage.search.queryoptions.sortorder?view=winrt-19041 + //case Enums.SortOption.FileType: + + //sortEntry.PropertyName = "System.FileExtension"; + //queryOptions.SortOrder.Clear(); + //queryOptions.SortOrder.Add(sortEntry); + //break; + + //Handle unsupported + default: + //keep the default one in SortOrder IList + break; + } + + fileQueryResult = currentFolder.CreateFileQueryWithOptions(queryOptions); + + var options = new LauncherOptions + { + NeighboringFilesQuery = fileQueryResult + }; + + // Now launch file with options. + launchSuccess = await Launcher.LaunchFileAsync(childFile.File, options); + } + + if (!launchSuccess) + { + await Win32Helpers.InvokeWin32ComponentAsync(path, associatedInstance); + } + } + }); + } + } + + if (opened.ErrorCode == FileSystemStatusCode.NotFound && !openSilent) + { + await DialogDisplayHelper.ShowDialogAsync("FileNotFoundDialog/Title".GetLocalized(), "FileNotFoundDialog/Text".GetLocalized()); + associatedInstance.NavigationToolbar.CanRefresh = false; + await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + { + var ContentOwnedViewModelInstance = associatedInstance.FilesystemViewModel; + ContentOwnedViewModelInstance?.RefreshItems(previousDir); + }); + } + + return opened; + } + } +} diff --git a/Files/Helpers/WallpaperHelpers.cs b/Files/Helpers/WallpaperHelpers.cs new file mode 100644 index 000000000000..91d07770c12f --- /dev/null +++ b/Files/Helpers/WallpaperHelpers.cs @@ -0,0 +1,49 @@ +using Files.Enums; +using Files.Filesystem; +using System; +using Windows.Storage; +using Windows.System.UserProfile; + +namespace Files.Helpers +{ + public static class WallpaperHelpers + { + public static async void SetAsBackground(WallpaperType type, string filePath, IShellPage associatedInstance) + { + if (UserProfilePersonalizationSettings.IsSupported()) + { + // Get the path of the selected file + StorageFile sourceFile = await StorageItemHelpers.ToStorageItem(filePath, associatedInstance); + if (sourceFile == null) + { + return; + } + + // Get the app's local folder to use as the destination folder. + StorageFolder localFolder = ApplicationData.Current.LocalFolder; + + // the file to the destination folder. + // Generate unique name if the file already exists. + // If the file you are trying to set as the wallpaper has the same name as the current wallpaper, + // the system will ignore the request and no-op the operation + StorageFile file = await FilesystemTasks.Wrap(() => sourceFile.CopyAsync(localFolder, sourceFile.Name, NameCollisionOption.GenerateUniqueName).AsTask()); + if (file == null) + { + return; + } + + UserProfilePersonalizationSettings profileSettings = UserProfilePersonalizationSettings.Current; + if (type == WallpaperType.Desktop) + { + // Set the desktop background + await profileSettings.TrySetWallpaperImageAsync(file); + } + else if (type == WallpaperType.LockScreen) + { + // Set the lockscreen background + await profileSettings.TrySetLockScreenImageAsync(file); + } + } + } + } +} diff --git a/Files/Helpers/Win32Helpers.cs b/Files/Helpers/Win32Helpers.cs new file mode 100644 index 000000000000..fd4ab931aa83 --- /dev/null +++ b/Files/Helpers/Win32Helpers.cs @@ -0,0 +1,49 @@ +using Files.Extensions; +using Newtonsoft.Json; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using Windows.Foundation.Collections; + +namespace Files.Helpers +{ + public static class Win32Helpers + { + public static async Task InvokeWin32ComponentAsync(string applicationPath, IShellPage associatedInstance, string arguments = null, bool runAsAdmin = false, string workingDirectory = null) + { + await InvokeWin32ComponentsAsync(applicationPath.CreateEnumerable(), associatedInstance, arguments, runAsAdmin, workingDirectory); + } + + public static async Task InvokeWin32ComponentsAsync(IEnumerable applicationPaths, IShellPage associatedInstance, string arguments = null, bool runAsAdmin = false, string workingDirectory = null) + { + Debug.WriteLine("Launching EXE in FullTrustProcess"); + + if (string.IsNullOrEmpty(workingDirectory)) + { + workingDirectory = associatedInstance.FilesystemViewModel.WorkingDirectory; + } + + if (associatedInstance.ServiceConnection != null) + { + var value = new ValueSet() + { + { "WorkingDirectory", string.IsNullOrEmpty(workingDirectory) ? associatedInstance?.FilesystemViewModel?.WorkingDirectory : workingDirectory }, + { "Application", applicationPaths.FirstOrDefault() }, + { "ApplicationList", JsonConvert.SerializeObject(applicationPaths) }, + }; + + if (runAsAdmin) + { + value.Add("Arguments", "runas"); + } + else + { + value.Add("Arguments", arguments); + } + + await associatedInstance.ServiceConnection.SendMessageAsync(value); + } + } + } +} diff --git a/Files/Interacts/BaseLayoutCommandImplementationModel.cs b/Files/Interacts/BaseLayoutCommandImplementationModel.cs index 3ecaf4a16058..ffa0500a8fb7 100644 --- a/Files/Interacts/BaseLayoutCommandImplementationModel.cs +++ b/Files/Interacts/BaseLayoutCommandImplementationModel.cs @@ -64,7 +64,7 @@ public void Dispose() public virtual void RenameItem(RoutedEventArgs e) { - associatedInstance.SlimContentPage.StartRenameItem(); + SlimContentPage.StartRenameItem(); } public virtual async void CreateShortcut(RoutedEventArgs e) @@ -94,12 +94,12 @@ public virtual async void CreateShortcut(RoutedEventArgs e) public virtual void SetAsLockscreenBackgroundItem(RoutedEventArgs e) { - associatedInstance.InteractionOperations.SetAsBackground(WallpaperType.LockScreen, SlimContentPage.SelectedItem.ItemPath); + WallpaperHelpers.SetAsBackground(WallpaperType.LockScreen, SlimContentPage.SelectedItem.ItemPath, associatedInstance); } public virtual void SetAsDesktopBackgroundItem(RoutedEventArgs e) { - associatedInstance.InteractionOperations.SetAsBackground(WallpaperType.Desktop, SlimContentPage.SelectedItem.ItemPath); + WallpaperHelpers.SetAsBackground(WallpaperType.Desktop, SlimContentPage.SelectedItem.ItemPath, associatedInstance); } public virtual async void RunAsAdmin(RoutedEventArgs e) @@ -140,7 +140,7 @@ public virtual void SidebarUnpinItem(RoutedEventArgs e) public virtual void OpenItem(RoutedEventArgs e) { - associatedInstance.InteractionOperations.OpenSelectedItems(false); + NavigationHelpers.OpenSelectedItems(associatedInstance, false); } public virtual void UnpinDirectoryFromSidebar(RoutedEventArgs e) @@ -169,9 +169,9 @@ public virtual async void CopyItem(RoutedEventArgs e) string copySourcePath = associatedInstance.FilesystemViewModel.WorkingDirectory; FilesystemResult result = (FilesystemResult)false; - if (associatedInstance.SlimContentPage.IsItemSelected) + if (SlimContentPage.IsItemSelected) { - foreach (ListedItem listedItem in associatedInstance.SlimContentPage.SelectedItems) + foreach (ListedItem listedItem in SlimContentPage.SelectedItems) { if (listedItem.PrimaryItemAttribute == StorageItemTypes.File) { @@ -197,7 +197,7 @@ public virtual async void CopyItem(RoutedEventArgs e) // Try again with fulltrust process if (ServiceConnection != null) { - string filePaths = string.Join('|', associatedInstance.SlimContentPage.SelectedItems.Select(x => x.ItemPath)); + string filePaths = string.Join('|', SlimContentPage.SelectedItems.Select(x => x.ItemPath)); await ServiceConnection.SendMessageAsync(new ValueSet() { { "Arguments", "FileOperation" }, @@ -234,15 +234,15 @@ public virtual async void CutItem(RoutedEventArgs e) List items = new List(); FilesystemResult result = (FilesystemResult)false; - if (associatedInstance.SlimContentPage.IsItemSelected) + if (SlimContentPage.IsItemSelected) { // First, reset DataGrid Rows that may be in "cut" command mode - associatedInstance.SlimContentPage.ResetItemOpacity(); + SlimContentPage.ResetItemOpacity(); - foreach (ListedItem listedItem in associatedInstance.SlimContentPage.SelectedItems) + foreach (ListedItem listedItem in SlimContentPage.SelectedItems) { // Dim opacities accordingly - associatedInstance.SlimContentPage.SetItemOpacity(listedItem); + SlimContentPage.SetItemOpacity(listedItem); if (listedItem.PrimaryItemAttribute == StorageItemTypes.File) { @@ -265,7 +265,7 @@ public virtual async void CutItem(RoutedEventArgs e) } if (result.ErrorCode == FileSystemStatusCode.NotFound) { - associatedInstance.SlimContentPage.ResetItemOpacity(); + SlimContentPage.ResetItemOpacity(); return; } else if (result.ErrorCode == FileSystemStatusCode.Unauthorized) @@ -273,7 +273,7 @@ public virtual async void CutItem(RoutedEventArgs e) // Try again with fulltrust process if (ServiceConnection != null) { - string filePaths = string.Join('|', associatedInstance.SlimContentPage.SelectedItems.Select(x => x.ItemPath)); + string filePaths = string.Join('|', SlimContentPage.SelectedItems.Select(x => x.ItemPath)); AppServiceResponseStatus status = await ServiceConnection.SendMessageAsync(new ValueSet() { { "Arguments", "FileOperation" }, @@ -286,7 +286,7 @@ public virtual async void CutItem(RoutedEventArgs e) return; } } - associatedInstance.SlimContentPage.ResetItemOpacity(); + SlimContentPage.ResetItemOpacity(); return; } } @@ -309,9 +309,9 @@ public virtual async void CutItem(RoutedEventArgs e) public virtual async void RestoreItem(RoutedEventArgs e) { - if (associatedInstance.SlimContentPage.IsItemSelected) + if (SlimContentPage.IsItemSelected) { - foreach (ListedItem listedItem in associatedInstance.SlimContentPage.SelectedItems) + foreach (ListedItem listedItem in SlimContentPage.SelectedItems) { if (listedItem is RecycleBinItem binItem) { @@ -327,7 +327,7 @@ await FilesystemHelpers.RestoreFromTrashAsync(StorageItemHelpers.FromPathAndType public virtual async void DeleteItem(RoutedEventArgs e) { await FilesystemHelpers.DeleteItemsAsync( - associatedInstance.SlimContentPage.SelectedItems.Select((item) => StorageItemHelpers.FromPathAndType( + SlimContentPage.SelectedItems.Select((item) => StorageItemHelpers.FromPathAndType( item.ItemPath, item.PrimaryItemAttribute == StorageItemTypes.File ? FilesystemItemType.File : FilesystemItemType.Directory)).ToList(), true, false, true); @@ -345,7 +345,7 @@ public virtual void ShowProperties(RoutedEventArgs e) public virtual async void OpenFileLocation(RoutedEventArgs e) { - ShortcutItem item = associatedInstance.SlimContentPage.SelectedItem as ShortcutItem; + ShortcutItem item = SlimContentPage.SelectedItem as ShortcutItem; if (string.IsNullOrWhiteSpace(item?.TargetPath)) { @@ -377,12 +377,12 @@ await DialogDisplayHelper.ShowDialogAsync("InvalidItemDialogTitle".GetLocalized( public virtual void OpenItemWithApplicationPicker(RoutedEventArgs e) { - associatedInstance.InteractionOperations.OpenSelectedItems(true); + NavigationHelpers.OpenSelectedItems(associatedInstance, true); } public virtual async void OpenDirectoryInNewTab(RoutedEventArgs e) { - foreach (ListedItem listedItem in associatedInstance.SlimContentPage.SelectedItems) + foreach (ListedItem listedItem in SlimContentPage.SelectedItems) { await CoreWindow.GetForCurrentThread().Dispatcher.RunAsync(CoreDispatcherPriority.Low, async () => { @@ -393,7 +393,7 @@ await CoreWindow.GetForCurrentThread().Dispatcher.RunAsync(CoreDispatcherPriorit public virtual void OpenDirectoryInNewPane(RoutedEventArgs e) { - ListedItem listedItem = associatedInstance.SlimContentPage.SelectedItems.FirstOrDefault(); + ListedItem listedItem = SlimContentPage.SelectedItems.FirstOrDefault(); if (listedItem != null) { associatedInstance.PaneHolder?.OpenPathInNewPane((listedItem as ShortcutItem)?.TargetPath ?? listedItem.ItemPath); @@ -402,7 +402,7 @@ public virtual void OpenDirectoryInNewPane(RoutedEventArgs e) public virtual async void OpenInNewWindowItem(RoutedEventArgs e) { - List items = associatedInstance.SlimContentPage.SelectedItems; + List items = SlimContentPage.SelectedItems; foreach (ListedItem listedItem in items) { var selectedItemPath = (listedItem as ShortcutItem)?.TargetPath ?? listedItem.ItemPath; @@ -430,10 +430,10 @@ public virtual void CopyPathOfSelectedItem(RoutedEventArgs e) { try { - if (associatedInstance.SlimContentPage != null) + if (SlimContentPage != null) { DataPackage data = new DataPackage(); - data.SetText(associatedInstance.SlimContentPage.SelectedItem.ItemPath); + data.SetText(SlimContentPage.SelectedItem.ItemPath); Clipboard.SetContent(data); Clipboard.Flush(); } @@ -446,7 +446,7 @@ public virtual void CopyPathOfSelectedItem(RoutedEventArgs e) public virtual void OpenDirectoryInDefaultTerminal(RoutedEventArgs e) { - associatedInstance.InteractionOperations.OpenDirectoryInTerminal(associatedInstance.FilesystemViewModel.WorkingDirectory); + NavigationHelpers.OpenDirectoryInTerminal(associatedInstance.FilesystemViewModel.WorkingDirectory, associatedInstance); } public virtual void ShareItem(RoutedEventArgs e) @@ -464,7 +464,7 @@ async void Manager_DataRequested(DataTransferManager sender, DataRequestedEventA /*dataRequest.Data.Properties.Title = "Data Shared From Files"; dataRequest.Data.Properties.Description = "The items you selected will be shared";*/ - foreach (ListedItem item in associatedInstance.SlimContentPage.SelectedItems) + foreach (ListedItem item in SlimContentPage.SelectedItems) { if (item.IsShortcutItem) { @@ -531,11 +531,11 @@ public virtual void ItemPointerPressed(PointerRoutedEventArgs e) { if (Item.IsShortcutItem) { - Interaction.OpenPathInNewTab(((e.OriginalSource as FrameworkElement)?.DataContext as ShortcutItem)?.TargetPath ?? Item.ItemPath); + NavigationHelpers.OpenPathInNewTab(((e.OriginalSource as FrameworkElement)?.DataContext as ShortcutItem)?.TargetPath ?? Item.ItemPath); } else { - Interaction.OpenPathInNewTab(Item.ItemPath); + NavigationHelpers.OpenPathInNewTab(Item.ItemPath); } } } diff --git a/Files/Interacts/Interaction.cs b/Files/Interacts/Interaction.cs index 1066b1e5bf6f..5e0866576687 100644 --- a/Files/Interacts/Interaction.cs +++ b/Files/Interacts/Interaction.cs @@ -112,108 +112,6 @@ public string JumpString } } - public async void SetAsBackground(WallpaperType type, string filePath) - { - if (UserProfilePersonalizationSettings.IsSupported()) - { - // Get the path of the selected file - StorageFile sourceFile = await StorageItemHelpers.ToStorageItem(filePath, AssociatedInstance); - if (sourceFile == null) - { - return; - } - - // Get the app's local folder to use as the destination folder. - StorageFolder localFolder = ApplicationData.Current.LocalFolder; - - // the file to the destination folder. - // Generate unique name if the file already exists. - // If the file you are trying to set as the wallpaper has the same name as the current wallpaper, - // the system will ignore the request and no-op the operation - var file = (StorageFile)await FilesystemTasks.Wrap(() => sourceFile.CopyAsync(localFolder, sourceFile.Name, NameCollisionOption.GenerateUniqueName).AsTask()); - if (file == null) - { - return; - } - - UserProfilePersonalizationSettings profileSettings = UserProfilePersonalizationSettings.Current; - if (type == WallpaperType.Desktop) - { - // Set the desktop background - await profileSettings.TrySetWallpaperImageAsync(file); - } - else if (type == WallpaperType.LockScreen) - { - // Set the lockscreen background - await profileSettings.TrySetLockScreenImageAsync(file); - } - } - } - - public static async void OpenPathInNewTab(string path) - { - await MainPage.AddNewTabByPathAsync(typeof(PaneHolderPage), path); - } - - public static async Task OpenPathInNewWindowAsync(string path) - { - var folderUri = new Uri($"files-uwp:?folder={Uri.EscapeDataString(path)}"); - return await Launcher.LaunchUriAsync(folderUri); - } - - public static async Task OpenTabInNewWindowAsync(string tabArgs) - { - var folderUri = new Uri($"files-uwp:?tab={Uri.EscapeDataString(tabArgs)}"); - return await Launcher.LaunchUriAsync(folderUri); - } - - public async void OpenDirectoryInTerminal(string workingDir) - { - var terminal = AppSettings.TerminalController.Model.GetDefaultTerminal(); - - if (Connection != null) - { - var value = new ValueSet - { - { "WorkingDirectory", workingDir }, - { "Application", terminal.Path }, - { "Arguments", string.Format(terminal.Arguments, - Helpers.PathNormalization.NormalizePath(workingDir)) } - }; - await Connection.SendMessageAsync(value); - } - } - - public async Task InvokeWin32ComponentAsync(string applicationPath, string arguments = null, bool runAsAdmin = false, string workingDir = null) - { - await InvokeWin32ComponentsAsync(new List() { applicationPath }, arguments, runAsAdmin, workingDir); - } - - public async Task InvokeWin32ComponentsAsync(List applicationPaths, string arguments = null, bool runAsAdmin = false, string workingDir = null) - { - Debug.WriteLine("Launching EXE in FullTrustProcess"); - if (Connection != null) - { - var value = new ValueSet - { - { "WorkingDirectory", string.IsNullOrEmpty(workingDir) ? AssociatedInstance?.FilesystemViewModel?.WorkingDirectory : workingDir }, - { "Application", applicationPaths.FirstOrDefault() }, - { "ApplicationList", JsonConvert.SerializeObject(applicationPaths) }, - }; - - if (runAsAdmin) - { - value.Add("Arguments", "runas"); - } - else - { - value.Add("Arguments", arguments); - } - - await Connection.SendMessageAsync(value); - } - } - public async Task OpenShellCommandInExplorerAsync(string shellCommand) { Debug.WriteLine("Launching shell command in FullTrustProcess"); @@ -237,290 +135,6 @@ public static bool IsAnyContentDialogOpen() return openedPopups.Any(popup => popup.Child is ContentDialog); } - /// - /// Navigates to a directory or opens file - /// - /// - /// - /// Determines whether history of opened item is saved (... to Recent Items/Windows Timeline/opening in background) - /// Determines whether open file using application picker - /// List of filenames that are selected upon navigation - public async Task OpenPath(string path, FilesystemItemType? itemType = null, bool openSilent = false, bool openViaApplicationPicker = false, IEnumerable selectItems = null) - // TODO: This function reliability has not been extensively tested - { - string previousDir = AssociatedInstance.FilesystemViewModel.WorkingDirectory; - bool isHiddenItem = NativeFileOperationsHelper.HasFileAttribute(path, System.IO.FileAttributes.Hidden); - bool isShortcutItem = path.EndsWith(".lnk") || path.EndsWith(".url"); // Determine - FilesystemResult opened = (FilesystemResult)false; - - // Shortcut item variables - string shortcutTargetPath = null; - string shortcutArguments = null; - string shortcutWorkingDirectory = null; - bool shortcutRunAsAdmin = false; - bool shortcutIsFolder = false; - - if (itemType == null || isShortcutItem || isHiddenItem) - { - if (isShortcutItem) - { - var (status, response) = await Connection.SendMessageForResponseAsync(new ValueSet() - { - { "Arguments", "FileOperation" }, - { "fileop", "ParseLink" }, - { "filepath", path } - }); - - if (status == AppServiceResponseStatus.Success) - { - shortcutTargetPath = response.Get("TargetPath", string.Empty); - shortcutArguments = response.Get("Arguments", string.Empty); - shortcutWorkingDirectory = response.Get("WorkingDirectory", string.Empty); - shortcutRunAsAdmin = response.Get("RunAsAdmin", false); - shortcutIsFolder = response.Get("IsFolder", false); - - itemType = shortcutIsFolder ? FilesystemItemType.Directory : FilesystemItemType.File; - } - else - { - return false; - } - } - else if (isHiddenItem) - { - itemType = NativeFileOperationsHelper.HasFileAttribute(path, System.IO.FileAttributes.Directory) ? FilesystemItemType.Directory : FilesystemItemType.File; - } - else - { - itemType = await StorageItemHelpers.GetTypeFromPath(path); - } - } - - var mostRecentlyUsed = Windows.Storage.AccessCache.StorageApplicationPermissions.MostRecentlyUsedList; - - if (itemType == FilesystemItemType.Directory) // OpenDirectory - { - if (isShortcutItem) - { - if (string.IsNullOrEmpty(shortcutTargetPath)) - { - await InvokeWin32ComponentAsync(path); - return true; - } - else - { - AssociatedInstance.NavigationToolbar.PathControlDisplayText = shortcutTargetPath; - AssociatedInstance.NavigateWithArguments(AssociatedInstance.InstanceViewModel.FolderSettings.GetLayoutType(shortcutTargetPath), new NavigationArguments() - { - NavPathParam = shortcutTargetPath, - AssociatedTabInstance = AssociatedInstance, - SelectItems = selectItems - }); - - return true; - } - } - else if (isHiddenItem) - { - AssociatedInstance.NavigationToolbar.PathControlDisplayText = path; - AssociatedInstance.NavigateWithArguments(AssociatedInstance.InstanceViewModel.FolderSettings.GetLayoutType(path), new NavigationArguments() - { - NavPathParam = path, - AssociatedTabInstance = AssociatedInstance - }); - - return true; - } - else - { - opened = await AssociatedInstance.FilesystemViewModel.GetFolderWithPathFromPathAsync(path) - .OnSuccess(childFolder => - { - // Add location to MRU List - mostRecentlyUsed.Add(childFolder.Folder, childFolder.Path); - }); - if (!opened) - { - opened = (FilesystemResult)FolderHelpers.CheckFolderAccessWithWin32(path); - } - if (!opened) - { - opened = (FilesystemResult)path.StartsWith("ftp:"); - } - if (opened) - { - AssociatedInstance.NavigationToolbar.PathControlDisplayText = path; - AssociatedInstance.NavigateWithArguments(AssociatedInstance.InstanceViewModel.FolderSettings.GetLayoutType(path), new NavigationArguments() - { - NavPathParam = path, - AssociatedTabInstance = AssociatedInstance, - SelectItems = selectItems - }); - } - } - } - else if (itemType == FilesystemItemType.File) // OpenFile - { - if (isShortcutItem) - { - if (string.IsNullOrEmpty(shortcutTargetPath)) - { - await InvokeWin32ComponentAsync(path); - } - else - { - if (!path.EndsWith(".url")) - { - StorageFileWithPath childFile = await AssociatedInstance.FilesystemViewModel.GetFileWithPathFromPathAsync(shortcutTargetPath); - if (childFile != null) - { - // Add location to MRU List - mostRecentlyUsed.Add(childFile.File, childFile.Path); - } - } - await InvokeWin32ComponentAsync(shortcutTargetPath, shortcutArguments, shortcutRunAsAdmin, shortcutWorkingDirectory); - } - opened = (FilesystemResult)true; - } - else if (isHiddenItem) - { - await InvokeWin32ComponentAsync(path); - } - else - { - opened = await AssociatedInstance.FilesystemViewModel.GetFileWithPathFromPathAsync(path) - .OnSuccess(async childFile => - { - // Add location to MRU List - mostRecentlyUsed.Add(childFile.File, childFile.Path); - - if (openViaApplicationPicker) - { - LauncherOptions options = new LauncherOptions - { - DisplayApplicationPicker = true - }; - await Launcher.LaunchFileAsync(childFile.File, options); - } - else - { - //try using launcher first - bool launchSuccess = false; - - StorageFileQueryResult fileQueryResult = null; - - //Get folder to create a file query (to pass to apps like Photos, Movies & TV..., needed to scroll through the folder like what Windows Explorer does) - StorageFolder currFolder = await AssociatedInstance.FilesystemViewModel.GetFolderFromPathAsync(Path.GetDirectoryName(path)); - - if (currFolder != null) - { - QueryOptions queryOptions = new QueryOptions(CommonFileQuery.DefaultQuery, null); - - //We can have many sort entries - SortEntry sortEntry = new SortEntry() - { - AscendingOrder = FolderSettings.DirectorySortDirection == Microsoft.Toolkit.Uwp.UI.SortDirection.Ascending - }; - - //Basically we tell to the launched app to follow how we sorted the files in the directory. - - var sortOption = FolderSettings.DirectorySortOption; - - switch (sortOption) - { - case Enums.SortOption.Name: - sortEntry.PropertyName = "System.ItemNameDisplay"; - queryOptions.SortOrder.Clear(); - queryOptions.SortOrder.Add(sortEntry); - break; - - case Enums.SortOption.DateModified: - sortEntry.PropertyName = "System.DateModified"; - queryOptions.SortOrder.Clear(); - queryOptions.SortOrder.Add(sortEntry); - break; - - case Enums.SortOption.DateCreated: - sortEntry.PropertyName = "System.DateCreated"; - queryOptions.SortOrder.Clear(); - queryOptions.SortOrder.Add(sortEntry); - break; - - //Unfortunately this is unsupported | Remarks: https://docs.microsoft.com/en-us/uwp/api/windows.storage.search.queryoptions.sortorder?view=winrt-19041 - //case Enums.SortOption.Size: - - //sortEntry.PropertyName = "System.TotalFileSize"; - //queryOptions.SortOrder.Clear(); - //queryOptions.SortOrder.Add(sortEntry); - //break; - - //Unfortunately this is unsupported | Remarks: https://docs.microsoft.com/en-us/uwp/api/windows.storage.search.queryoptions.sortorder?view=winrt-19041 - //case Enums.SortOption.FileType: - - //sortEntry.PropertyName = "System.FileExtension"; - //queryOptions.SortOrder.Clear(); - //queryOptions.SortOrder.Add(sortEntry); - //break; - - //Handle unsupported - default: - //keep the default one in SortOrder IList - break; - } - - fileQueryResult = currFolder.CreateFileQueryWithOptions(queryOptions); - - var options = new LauncherOptions - { - NeighboringFilesQuery = fileQueryResult - }; - - // Now launch file with options. - launchSuccess = await Launcher.LaunchFileAsync(childFile.File, options); - } - - if (!launchSuccess) - { - await InvokeWin32ComponentAsync(path); - } - } - }); - } - } - - if (opened.ErrorCode == FileSystemStatusCode.NotFound && !openSilent) - { - await DialogDisplayHelper.ShowDialogAsync("FileNotFoundDialog/Title".GetLocalized(), "FileNotFoundDialog/Text".GetLocalized()); - AssociatedInstance.NavigationToolbar.CanRefresh = false; - await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => - { - var ContentOwnedViewModelInstance = AssociatedInstance.FilesystemViewModel; - ContentOwnedViewModelInstance?.RefreshItems(previousDir); - }); - } - - return opened; - } - - public async void OpenSelectedItems(bool openViaApplicationPicker = false) - { - if (AssociatedInstance.FilesystemViewModel.WorkingDirectory.StartsWith(AppSettings.RecycleBinPath)) - { - // Do not open files and folders inside the recycle bin - return; - } - if (AssociatedInstance.SlimContentPage == null) - { - return; - } - foreach (ListedItem item in AssociatedInstance.SlimContentPage.SelectedItems) - { - var type = item.PrimaryItemAttribute == StorageItemTypes.Folder ? - FilesystemItemType.Directory : FilesystemItemType.File; - await OpenPath(item.ItemPath, type, false, openViaApplicationPicker); - } - } - public async void LaunchNewWindow() { var filesUWPUri = new Uri("files-uwp:"); @@ -649,23 +263,6 @@ public void SetHiddenAttributeItem(ListedItem item, bool isHidden) AssociatedInstance.SlimContentPage.ResetItemOpacity(); } - public void CopyWorkingLocation() - { - try - { - if (AssociatedInstance.SlimContentPage != null) - { - DataPackage data = new DataPackage(); - data.SetText(AssociatedInstance.FilesystemViewModel.WorkingDirectory); - Clipboard.SetContent(data); - Clipboard.Flush(); - } - } - catch - { - } - } - public async Task PasteItemAsync(string destinationPath) { DataPackageView packageView = await FilesystemTasks.Wrap(() => Task.FromResult(Clipboard.GetContent())); diff --git a/Files/UserControls/MultitaskingControl/HorizontalMultitaskingControl.xaml.cs b/Files/UserControls/MultitaskingControl/HorizontalMultitaskingControl.xaml.cs index a8b5e0c1c4f6..3f07b6e560b5 100644 --- a/Files/UserControls/MultitaskingControl/HorizontalMultitaskingControl.xaml.cs +++ b/Files/UserControls/MultitaskingControl/HorizontalMultitaskingControl.xaml.cs @@ -1,4 +1,5 @@ -using Files.Interacts; +using Files.Helpers; +using Files.Interacts; using Files.ViewModels; using Files.Views; using Microsoft.Toolkit.Uwp; @@ -178,7 +179,7 @@ private async void TabStrip_TabDroppedOutside(TabView sender, TabViewTabDroppedO var tabViewItemArgs = (args.Item as TabItem).TabItemArguments; var selectedTabViewItemIndex = sender.SelectedIndex; RemoveTab(args.Item as TabItem); - if (!await Interaction.OpenTabInNewWindowAsync(tabViewItemArgs.Serialize())) + if (!await NavigationHelpers.OpenTabInNewWindowAsync(tabViewItemArgs.Serialize())) { sender.TabItems.Insert(indexOfTabViewItem, args.Tab); sender.SelectedIndex = selectedTabViewItemIndex; diff --git a/Files/UserControls/MultitaskingControl/VerticalTabViewControl.xaml.cs b/Files/UserControls/MultitaskingControl/VerticalTabViewControl.xaml.cs index 86cf5727e6cb..d4a9f25d58f7 100644 --- a/Files/UserControls/MultitaskingControl/VerticalTabViewControl.xaml.cs +++ b/Files/UserControls/MultitaskingControl/VerticalTabViewControl.xaml.cs @@ -1,4 +1,5 @@ -using Files.Interacts; +using Files.Helpers; +using Files.Interacts; using Files.Views; using Microsoft.Toolkit.Uwp; using Microsoft.UI.Xaml.Controls; @@ -157,7 +158,7 @@ private async void TabStrip_TabDroppedOutside(TabView sender, TabViewTabDroppedO var tabViewItemArgs = (args.Item as TabItem).TabItemArguments; var selectedTabViewItemIndex = sender.SelectedIndex; RemoveTab(args.Item as TabItem); - if (!await Interaction.OpenTabInNewWindowAsync(tabViewItemArgs.Serialize())) + if (!await NavigationHelpers.OpenTabInNewWindowAsync(tabViewItemArgs.Serialize())) { sender.TabItems.Insert(indexOfTabViewItem, args.Tab); sender.SelectedIndex = selectedTabViewItemIndex; diff --git a/Files/UserControls/SidebarControl.xaml.cs b/Files/UserControls/SidebarControl.xaml.cs index b033f7359471..25e5f75cc8b5 100644 --- a/Files/UserControls/SidebarControl.xaml.cs +++ b/Files/UserControls/SidebarControl.xaml.cs @@ -293,12 +293,12 @@ private void NavigationViewWSLItem_RightTapped(object sender, RightTappedRoutedE private void OpenInNewTab_Click(object sender, RoutedEventArgs e) { - Interaction.OpenPathInNewTab(App.RightClickedItem.Path); + NavigationHelpers.OpenPathInNewTab(App.RightClickedItem.Path); } private async void OpenInNewWindow_Click(object sender, RoutedEventArgs e) { - await Interaction.OpenPathInNewWindowAsync(App.RightClickedItem.Path); + await NavigationHelpers.OpenPathInNewWindowAsync(App.RightClickedItem.Path); } private void NavigationViewItem_DragStarting(UIElement sender, DragStartingEventArgs args) diff --git a/Files/UserControls/Widgets/DrivesWidget.xaml.cs b/Files/UserControls/Widgets/DrivesWidget.xaml.cs index 8d0077780d43..551b59cbd344 100644 --- a/Files/UserControls/Widgets/DrivesWidget.xaml.cs +++ b/Files/UserControls/Widgets/DrivesWidget.xaml.cs @@ -65,13 +65,13 @@ private async void EjectDevice_Click(object sender, RoutedEventArgs e) private void OpenInNewTab_Click(object sender, RoutedEventArgs e) { var item = ((MenuFlyoutItem)sender).DataContext as DriveItem; - Interaction.OpenPathInNewTab(item.Path); + NavigationHelpers.OpenPathInNewTab(item.Path); } private async void OpenInNewWindow_Click(object sender, RoutedEventArgs e) { var item = ((MenuFlyoutItem)sender).DataContext as DriveItem; - await Interaction.OpenPathInNewWindowAsync(item.Path); + await NavigationHelpers.OpenPathInNewWindowAsync(item.Path); } private async void OpenDriveProperties_Click(object sender, RoutedEventArgs e) diff --git a/Files/ViewModels/Bundles/BundleItemViewModel.cs b/Files/ViewModels/Bundles/BundleItemViewModel.cs index 09c1ff71ff8f..91f473112c78 100644 --- a/Files/ViewModels/Bundles/BundleItemViewModel.cs +++ b/Files/ViewModels/Bundles/BundleItemViewModel.cs @@ -136,7 +136,7 @@ private void OpenInNewPane() private async void OpenItemLocation() { - await associatedInstance.InteractionOperations.OpenPath(System.IO.Path.GetDirectoryName(Path), FilesystemItemType.Directory, selectItems: System.IO.Path.GetFileName(Path).CreateEnumerable()); + await NavigationHelpers.OpenPath(System.IO.Path.GetDirectoryName(Path), associatedInstance, FilesystemItemType.Directory, selectItems: System.IO.Path.GetFileName(Path).CreateEnumerable()); } #endregion Command Implementation @@ -197,7 +197,7 @@ await CoreApplication.MainView.ExecuteOnUIThreadAsync(async () => public async void OpenItem() { - await associatedInstance.InteractionOperations.OpenPath(Path, TargetType); + await NavigationHelpers.OpenPath(Path, associatedInstance, TargetType); } public void RemoveItem() diff --git a/Files/ViewModels/Properties/FileProperties.cs b/Files/ViewModels/Properties/FileProperties.cs index 31f9b8fc285f..7705b2848282 100644 --- a/Files/ViewModels/Properties/FileProperties.cs +++ b/Files/ViewModels/Properties/FileProperties.cs @@ -82,7 +82,7 @@ public override void GetBaseProperties() if (Item.IsLinkItem) { var tmpItem = (ShortcutItem)Item; - await AppInstance.InteractionOperations.InvokeWin32ComponentAsync(ViewModel.ShortcutItemPath, ViewModel.ShortcutItemArguments, tmpItem.RunAsAdmin, ViewModel.ShortcutItemWorkingDir); + await Win32Helpers.InvokeWin32ComponentAsync(ViewModel.ShortcutItemPath, AppInstance, ViewModel.ShortcutItemArguments, tmpItem.RunAsAdmin, ViewModel.ShortcutItemWorkingDir); } else { diff --git a/Files/Views/LayoutModes/GenericFileBrowser.xaml.cs b/Files/Views/LayoutModes/GenericFileBrowser.xaml.cs index 84d2af1de30f..161b026e24a9 100644 --- a/Files/Views/LayoutModes/GenericFileBrowser.xaml.cs +++ b/Files/Views/LayoutModes/GenericFileBrowser.xaml.cs @@ -455,7 +455,7 @@ private async void AllView_ItemPress(object sender, PointerRoutedEventArgs e) { tapDebounceTimer.Stop(); await Task.Delay(200); // The delay gives time for the item to be selected - ParentShellPageInstance.InteractionOperations.OpenSelectedItems(false); + NavigationHelpers.OpenSelectedItems(ParentShellPageInstance, false); } } @@ -498,7 +498,7 @@ private void AllView_PreviewKeyDown(object sender, KeyRoutedEventArgs e) } else { - ParentShellPageInstance.InteractionOperations.OpenSelectedItems(false); + NavigationHelpers.OpenSelectedItems(ParentShellPageInstance, false); } e.Handled = true; } @@ -655,7 +655,7 @@ private void RadioMenuSortDirection_Click(object sender, RoutedEventArgs e) private void AllView_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e) { tapDebounceTimer.Stop(); - ParentShellPageInstance.InteractionOperations.OpenSelectedItems(false); + NavigationHelpers.OpenSelectedItems(ParentShellPageInstance, false); } #region IDisposable diff --git a/Files/Views/LayoutModes/GridViewBrowser.xaml.cs b/Files/Views/LayoutModes/GridViewBrowser.xaml.cs index 12c85d8ccb3f..c55495a3c8a5 100644 --- a/Files/Views/LayoutModes/GridViewBrowser.xaml.cs +++ b/Files/Views/LayoutModes/GridViewBrowser.xaml.cs @@ -315,7 +315,7 @@ private void FileList_PreviewKeyDown(object sender, KeyRoutedEventArgs e) { if (!IsRenamingItem) { - ParentShellPageInstance.InteractionOperations.OpenSelectedItems(false); + NavigationHelpers.OpenSelectedItems(ParentShellPageInstance, false); e.Handled = true; } } @@ -443,7 +443,7 @@ private async void FileList_ItemClick(object sender, ItemClickEventArgs e) if (AppSettings.OpenItemsWithOneclick) { await Task.Delay(200); // The delay gives time for the item to be selected - ParentShellPageInstance.InteractionOperations.OpenSelectedItems(false); + NavigationHelpers.OpenSelectedItems(ParentShellPageInstance, false); } } @@ -472,7 +472,7 @@ private void FileList_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e) // Skip opening selected items if the double tap doesn't capture an item if ((e.OriginalSource as FrameworkElement)?.DataContext is ListedItem && !AppSettings.OpenItemsWithOneclick) { - ParentShellPageInstance.InteractionOperations.OpenSelectedItems(false); + NavigationHelpers.OpenSelectedItems(ParentShellPageInstance, false); } } diff --git a/Files/Views/MainPage.xaml.cs b/Files/Views/MainPage.xaml.cs index 7df45919b239..326ad0a8261a 100644 --- a/Files/Views/MainPage.xaml.cs +++ b/Files/Views/MainPage.xaml.cs @@ -216,11 +216,11 @@ public static async void MoveTabToNewWindow(object sender, RoutedEventArgs e) if (tabItemArguments != null) { - await Interacts.Interaction.OpenTabInNewWindowAsync(tabItemArguments.Serialize()); + await NavigationHelpers.OpenTabInNewWindowAsync(tabItemArguments.Serialize()); } else { - await Interacts.Interaction.OpenPathInNewWindowAsync("NewTab".GetLocalized()); + await NavigationHelpers.OpenPathInNewWindowAsync("NewTab".GetLocalized()); } } diff --git a/Files/Views/ModernShellPage.xaml.cs b/Files/Views/ModernShellPage.xaml.cs index f97b8c0cdced..51f1e170c35f 100644 --- a/Files/Views/ModernShellPage.xaml.cs +++ b/Files/Views/ModernShellPage.xaml.cs @@ -240,16 +240,33 @@ private void InitializeCommands() InvertContentPageSelctionCommand = new RelayCommand(this.SlimContentPage.InvertSelection); } PasteItemsFromClipboardCommand = new RelayCommand(async () => await this.InteractionOperations.PasteItemAsync(FilesystemViewModel.WorkingDirectory)); - CopyPathOfWorkingDirectoryCommand = new RelayCommand(this.InteractionOperations.CopyWorkingLocation); + CopyPathOfWorkingDirectoryCommand = new RelayCommand(CopyWorkingLocation); OpenNewWindowCommand = new RelayCommand(this.InteractionOperations.LaunchNewWindow); OpenNewPaneCommand = new RelayCommand(() => PaneHolder?.OpenPathInNewPane("NewTab".GetLocalized())); - OpenDirectoryInDefaultTerminalCommand = new RelayCommand(() => this.InteractionOperations.OpenDirectoryInTerminal(this.FilesystemViewModel.WorkingDirectory)); + OpenDirectoryInDefaultTerminalCommand = new RelayCommand(() => NavigationHelpers.OpenDirectoryInTerminal(this.FilesystemViewModel.WorkingDirectory, this)); AddNewTabToMultitaskingControlCommand = new RelayCommand(async () => await MainPage.AddNewTabByPathAsync(typeof(PaneHolderPage), "NewTab".GetLocalized())); CreateNewFileCommand = new RelayCommand(() => InteractionOperations.CreateFileFromDialogResultType(AddItemType.File, null)); CreateNewFolderCommand = new RelayCommand(() => InteractionOperations.CreateFileFromDialogResultType(AddItemType.Folder, null)); } + private void CopyWorkingLocation() + { + try + { + if (this.SlimContentPage != null) + { + DataPackage data = new DataPackage(); + data.SetText(this.FilesystemViewModel.WorkingDirectory); + Clipboard.SetContent(data); + Clipboard.Flush(); + } + } + catch + { + } + } + private void FolderSettings_LayoutPreferencesUpdateRequired(object sender, LayoutPreferenceEventArgs e) { if (FilesystemViewModel != null) @@ -305,7 +322,7 @@ private async void ModernShellPage_SearchSuggestionChosen(AutoSuggestBox sender, else { // TODO: Add fancy file launch options similar to Interactions.cs OpenSelectedItems() - await InteractionOperations.InvokeWin32ComponentAsync(invokedItem.ItemPath); + await Win32Helpers.InvokeWin32ComponentAsync(invokedItem.ItemPath, this); } } @@ -634,7 +651,7 @@ public async void CheckPathInput(ItemViewModel instance, string currentInput, st if (resFile) { var pathToInvoke = resFile.Result.Path; - await InteractionOperations.InvokeWin32ComponentAsync(pathToInvoke); + await Win32Helpers.InvokeWin32ComponentAsync(pathToInvoke, this); } else // Not a file or not accessible { diff --git a/Files/Views/YourHome.xaml.cs b/Files/Views/YourHome.xaml.cs index 9ecd1516a3f3..8eb6cc17f546 100644 --- a/Files/Views/YourHome.xaml.cs +++ b/Files/Views/YourHome.xaml.cs @@ -61,7 +61,7 @@ private async void RecentFilesWidget_RecentFileInvoked(object sender, UserContro try { var directoryName = Path.GetDirectoryName(e.ItemPath); - await AppInstance.InteractionOperations.InvokeWin32ComponentAsync(e.ItemPath, workingDir: directoryName); + await Win32Helpers.InvokeWin32ComponentAsync(e.ItemPath, AppInstance, workingDirectory: directoryName); } catch (UnauthorizedAccessException) { From fcfd57ab28a794ba58ec67cda748fc47354b994f Mon Sep 17 00:00:00 2001 From: d2dyno006 <53011783+d2dyno006@users.noreply.github.com> Date: Sun, 21 Mar 2021 12:35:41 +0100 Subject: [PATCH 4/9] rm4 --- Files/BaseLayout.cs | 2 +- Files/Files.csproj | 3 + .../FilesystemOperations.cs | 10 +- .../Helpers/FilesystemHelpers.cs | 21 +- Files/Helpers/FilePropertiesHelpers.cs | 100 ++++++++ Files/Helpers/NavigationHelpers.cs | 6 + Files/Helpers/UIFilesystemHelpers.cs | 121 ++++++++++ Files/Helpers/UIHelpers.cs | 16 ++ .../BaseLayoutCommandImplementationModel.cs | 10 +- Files/Interacts/Interaction.cs | 216 ------------------ .../UserControls/Widgets/DrivesWidget.xaml.cs | 2 +- .../LayoutModes/GenericFileBrowser.xaml.cs | 4 +- .../Views/LayoutModes/GridViewBrowser.xaml.cs | 4 +- Files/Views/ModernShellPage.xaml.cs | 19 +- Files/Views/Pages/PropertiesDetails.xaml.cs | 2 +- Files/Views/Pages/PropertiesGeneral.xaml.cs | 12 +- Files/Views/PaneHolderPage.xaml.cs | 4 +- 17 files changed, 300 insertions(+), 252 deletions(-) create mode 100644 Files/Helpers/FilePropertiesHelpers.cs create mode 100644 Files/Helpers/UIFilesystemHelpers.cs create mode 100644 Files/Helpers/UIHelpers.cs diff --git a/Files/BaseLayout.cs b/Files/BaseLayout.cs index 44c6a72ca2f0..24232057d33f 100644 --- a/Files/BaseLayout.cs +++ b/Files/BaseLayout.cs @@ -620,7 +620,7 @@ public void RightClickContextMenu_Opening(object sender, object e) Tag = "CreateNewFile" }; } - menuLayoutItem.Command = new RelayCommand(() => ParentShellPageInstance.InteractionOperations.CreateFileFromDialogResultType(AddItemType.File, null)); + menuLayoutItem.Command = new RelayCommand(() => UIFilesystemHelpers.CreateFileFromDialogResultType(AddItemType.File, null, ParentShellPageInstance)); menuLayoutItem.CommandParameter = newEntry; newItemMenu.Items.Insert(separatorIndex + 1, menuLayoutItem); } diff --git a/Files/Files.csproj b/Files/Files.csproj index 4deb50c5f450..1fba9196cbb8 100644 --- a/Files/Files.csproj +++ b/Files/Files.csproj @@ -211,7 +211,10 @@ ConfirmDeleteDialog.xaml + + + diff --git a/Files/Filesystem/FilesystemOperations/FilesystemOperations.cs b/Files/Filesystem/FilesystemOperations/FilesystemOperations.cs index 05d5298d758b..6c8b3d1052a3 100644 --- a/Files/Filesystem/FilesystemOperations/FilesystemOperations.cs +++ b/Files/Filesystem/FilesystemOperations/FilesystemOperations.cs @@ -183,7 +183,7 @@ await DialogDisplayHelper.ShowDialogAsync( CloseButtonText = "ItemAlreadyExistsDialogCloseButtonText".GetLocalized() }; - if (Interacts.Interaction.IsAnyContentDialogOpen()) + if (UIHelpers.IsAnyContentDialogOpen()) { // Only a single ContentDialog can be open at any time. return null; @@ -249,7 +249,7 @@ await DialogDisplayHelper.ShowDialogAsync( CloseButtonText = "ItemAlreadyExistsDialogCloseButtonText".GetLocalized() }; - if (Interacts.Interaction.IsAnyContentDialogOpen()) + if (UIHelpers.IsAnyContentDialogOpen()) { // Only a single ContentDialog can be open at any time. return null; @@ -411,7 +411,7 @@ await DialogDisplayHelper.ShowDialogAsync( CloseButtonText = "ItemAlreadyExistsDialogCloseButtonText".GetLocalized() }; - if (Interacts.Interaction.IsAnyContentDialogOpen()) + if (UIHelpers.IsAnyContentDialogOpen()) { // Only a single ContentDialog can be open at any time. return null; @@ -474,7 +474,7 @@ await DialogDisplayHelper.ShowDialogAsync( CloseButtonText = "ItemAlreadyExistsDialogCloseButtonText".GetLocalized() }; - if (Interacts.Interaction.IsAnyContentDialogOpen()) + if (UIHelpers.IsAnyContentDialogOpen()) { // Only a single ContentDialog can be open at any time. return null; @@ -738,7 +738,7 @@ public async Task RenameAsync(IStorageItemWithPath source, CloseButtonText = "ItemAlreadyExistsDialogCloseButtonText".GetLocalized() }; - if (Interacts.Interaction.IsAnyContentDialogOpen()) + if (UIHelpers.IsAnyContentDialogOpen()) { // Only a single ContentDialog can be open at any time. return null; diff --git a/Files/Filesystem/FilesystemOperations/Helpers/FilesystemHelpers.cs b/Files/Filesystem/FilesystemOperations/Helpers/FilesystemHelpers.cs index f55f80a768fe..c2f58f7c3b32 100644 --- a/Files/Filesystem/FilesystemOperations/Helpers/FilesystemHelpers.cs +++ b/Files/Filesystem/FilesystemOperations/Helpers/FilesystemHelpers.cs @@ -14,6 +14,7 @@ using System.Threading; using System.Threading.Tasks; using Windows.ApplicationModel.DataTransfer; +using Windows.Foundation.Collections; using Windows.Storage; using static Files.Helpers.NativeFindStorageItemHelper; using FileAttributes = System.IO.FileAttributes; @@ -119,7 +120,7 @@ public async Task DeleteItemsAsync(IEnumerable DeleteItemAsync(IStorageItemWithPath source, boo permanently, associatedInstance.SlimContentPage.SelectedItems.Count); - if (Interacts.Interaction.IsAnyContentDialogOpen()) + if (UIHelpers.IsAnyContentDialogOpen()) { // Can show only one dialog at a time banner.Remove(); @@ -301,7 +302,7 @@ public async Task DeleteItemAsync(IStorageItem source, bool showDi permanently, associatedInstance.SlimContentPage.SelectedItems.Count); - if (Interacts.Interaction.IsAnyContentDialogOpen()) + if (UIHelpers.IsAnyContentDialogOpen()) { // Can show only one dialog at a time banner.Remove(); @@ -925,6 +926,20 @@ public static bool ContainsRestrictedFileName(string input) return false; } + public async Task OpenShellCommandInExplorerAsync(string shellCommand, NamedPipeAsAppServiceConnection serviceConnection) + { + Debug.WriteLine("Launching shell command in FullTrustProcess"); + if (serviceConnection != null) + { + ValueSet value = new ValueSet() + { + { "ShellCommand", shellCommand }, + { "Arguments", "ShellCommand" } + }; + await serviceConnection.SendMessageAsync(value); + } + } + #endregion Public Helpers #region IDisposable diff --git a/Files/Helpers/FilePropertiesHelpers.cs b/Files/Helpers/FilePropertiesHelpers.cs new file mode 100644 index 000000000000..2899164bbabb --- /dev/null +++ b/Files/Helpers/FilePropertiesHelpers.cs @@ -0,0 +1,100 @@ +using Files.Dialogs; +using Files.Views; +using Microsoft.Toolkit.Uwp; +using System; +using System.Linq; +using System.Threading.Tasks; +using Windows.ApplicationModel.Core; +using Windows.Foundation; +using Windows.Foundation.Metadata; +using Windows.UI.Core; +using Windows.UI.ViewManagement; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Media.Animation; +using static Files.Views.Properties; + +namespace Files.Helpers +{ + public static class FilePropertiesHelpers + { + public static async void ShowProperties(IShellPage associatedInstance) + { + if (associatedInstance.SlimContentPage.IsItemSelected) + { + if (associatedInstance.SlimContentPage.SelectedItems.Count > 1) + { + await OpenPropertiesWindowAsync(associatedInstance.SlimContentPage.SelectedItems, associatedInstance); + } + else + { + await OpenPropertiesWindowAsync(associatedInstance.SlimContentPage.SelectedItem, associatedInstance); + } + } + else + { + if (!System.IO.Path.GetPathRoot(associatedInstance.FilesystemViewModel.CurrentFolder.ItemPath) + .Equals(associatedInstance.FilesystemViewModel.CurrentFolder.ItemPath, StringComparison.OrdinalIgnoreCase)) + { + await OpenPropertiesWindowAsync(associatedInstance.FilesystemViewModel.CurrentFolder, associatedInstance); + } + else + { + await OpenPropertiesWindowAsync(App.DrivesManager.Drives + .SingleOrDefault(x => x.Path.Equals(associatedInstance.FilesystemViewModel.CurrentFolder.ItemPath)), associatedInstance); + } + } + } + + public static async Task OpenPropertiesWindowAsync(object item, IShellPage associatedInstance) + { + if (item == null) + { + return; + } + + if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8)) + { + CoreApplicationView newWindow = CoreApplication.CreateNewView(); + ApplicationView newView = null; + + await newWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + { + Frame frame = new Frame(); + frame.Navigate(typeof(Properties), new PropertiesPageNavigationArguments() + { + Item = item, + AppInstanceArgument = associatedInstance + }, new SuppressNavigationTransitionInfo()); + Window.Current.Content = frame; + Window.Current.Activate(); + + newView = ApplicationView.GetForCurrentView(); + newWindow.TitleBar.ExtendViewIntoTitleBar = true; + newView.Title = "PropertiesTitle".GetLocalized(); + newView.PersistedStateId = "Properties"; + newView.SetPreferredMinSize(new Size(400, 550)); + newView.Consolidated += delegate + { + Window.Current.Close(); + }; + }); + + bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newView.Id); + // Set window size again here as sometimes it's not resized in the page Loaded event + newView.TryResizeView(new Size(400, 550)); + } + else + { + var propertiesDialog = new PropertiesDialog(); + propertiesDialog.propertiesFrame.Tag = propertiesDialog; + propertiesDialog.propertiesFrame.Navigate(typeof(Properties), new PropertiesPageNavigationArguments() + { + Item = item, + AppInstanceArgument = associatedInstance + }, new SuppressNavigationTransitionInfo()); + await propertiesDialog.ShowAsync(ContentDialogPlacement.Popup); + } + } + } +} diff --git a/Files/Helpers/NavigationHelpers.cs b/Files/Helpers/NavigationHelpers.cs index d42fd9e228e5..52dfecb4b9c3 100644 --- a/Files/Helpers/NavigationHelpers.cs +++ b/Files/Helpers/NavigationHelpers.cs @@ -37,6 +37,12 @@ public static async Task OpenTabInNewWindowAsync(string tabArgs) return await Launcher.LaunchUriAsync(folderUri); } + public static async void LaunchNewWindow() + { + var filesUWPUri = new Uri("files-uwp:"); + await Launcher.LaunchUriAsync(filesUWPUri); + } + public static async void OpenDirectoryInTerminal(string workingDir, IShellPage associatedInstance) { var terminal = App.AppSettings.TerminalController.Model.GetDefaultTerminal(); diff --git a/Files/Helpers/UIFilesystemHelpers.cs b/Files/Helpers/UIFilesystemHelpers.cs new file mode 100644 index 000000000000..bd4f8fa77d22 --- /dev/null +++ b/Files/Helpers/UIFilesystemHelpers.cs @@ -0,0 +1,121 @@ +using System; +using Files.DataModels; +using Files.Dialogs; +using Files.Enums; +using Files.Filesystem; +using Microsoft.Toolkit.Uwp; +using System.Threading.Tasks; +using Windows.ApplicationModel.DataTransfer; +using Windows.Storage; + +namespace Files.Helpers +{ + public static class UIFilesystemHelpers + { + public static async Task PasteItemAsync(string destinationPath, IShellPage associatedInstance) + { + DataPackageView packageView = await FilesystemTasks.Wrap(() => Task.FromResult(Clipboard.GetContent())); + if (packageView != null) + { + await associatedInstance.FilesystemHelpers.PerformOperationTypeAsync(packageView.RequestedOperation, packageView, destinationPath, true); + associatedInstance.SlimContentPage.ResetItemOpacity(); + } + } + + public static async Task RenameFileItemAsync(ListedItem item, string oldName, string newName, IShellPage associatedInstance) + { + if (oldName == newName) + { + return true; + } + + ReturnResult renamed = ReturnResult.InProgress; + if (item.PrimaryItemAttribute == StorageItemTypes.Folder) + { + renamed = await associatedInstance.FilesystemHelpers.RenameAsync(StorageItemHelpers.FromPathAndType(item.ItemPath, FilesystemItemType.Directory), + newName, NameCollisionOption.FailIfExists, true); + } + else + { + if (item.IsShortcutItem || !App.AppSettings.ShowFileExtensions) + { + newName += item.FileExtension; + } + + renamed = await associatedInstance.FilesystemHelpers.RenameAsync(StorageItemHelpers.FromPathAndType(item.ItemPath, FilesystemItemType.File), + newName, NameCollisionOption.FailIfExists, true); + } + + if (renamed == ReturnResult.Success) + { + associatedInstance.NavigationToolbar.CanGoForward = false; + return true; + } + return false; + } + + public static async void CreateFileFromDialogResultType(AddItemType itemType, ShellNewEntry itemInfo, IShellPage associatedInstance) + { + string currentPath = null; + if (associatedInstance.SlimContentPage != null) + { + currentPath = associatedInstance.FilesystemViewModel.WorkingDirectory; + } + + // Show rename dialog + DynamicDialog dialog = DynamicDialogFactory.GetFor_RenameDialog(); + await dialog.ShowAsync(); + + if (dialog.DynamicResult != DynamicDialogResult.Primary) + { + return; + } + + // Create file based on dialog result + string userInput = dialog.ViewModel.AdditionalData as string; + var folderRes = await associatedInstance.FilesystemViewModel.GetFolderWithPathFromPathAsync(currentPath); + FilesystemResult created = folderRes; + if (folderRes) + { + switch (itemType) + { + case AddItemType.Folder: + userInput = !string.IsNullOrWhiteSpace(userInput) ? userInput : "NewFolder".GetLocalized(); + created = await FilesystemTasks.Wrap(async () => + { + return await associatedInstance.FilesystemHelpers.CreateAsync( + StorageItemHelpers.FromPathAndType(System.IO.Path.Combine(folderRes.Result.Path, userInput), FilesystemItemType.Directory), + true); + }); + break; + + case AddItemType.File: + userInput = !string.IsNullOrWhiteSpace(userInput) ? userInput : itemInfo?.Name ?? "NewFile".GetLocalized(); + created = await FilesystemTasks.Wrap(async () => + { + return await associatedInstance.FilesystemHelpers.CreateAsync( + StorageItemHelpers.FromPathAndType(System.IO.Path.Combine(folderRes.Result.Path, userInput + itemInfo?.Extension), FilesystemItemType.File), + true); + }); + break; + } + } + if (created == FileSystemStatusCode.Unauthorized) + { + await DialogDisplayHelper.ShowDialogAsync("AccessDeniedCreateDialog/Title".GetLocalized(), "AccessDeniedCreateDialog/Text".GetLocalized()); + } + } + + /// + /// Set a single file or folder to hidden or unhidden an refresh the + /// view after setting the flag + /// + /// + /// + public static void SetHiddenAttributeItem(ListedItem item, bool isHidden, IBaseLayout slimContentPage) + { + item.IsHiddenItem = isHidden; + slimContentPage.ResetItemOpacity(); + } + } +} diff --git a/Files/Helpers/UIHelpers.cs b/Files/Helpers/UIHelpers.cs new file mode 100644 index 000000000000..d910afb55578 --- /dev/null +++ b/Files/Helpers/UIHelpers.cs @@ -0,0 +1,16 @@ +using System.Linq; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Media; + +namespace Files.Helpers +{ + public static class UIHelpers + { + public static bool IsAnyContentDialogOpen() + { + var openedPopups = VisualTreeHelper.GetOpenPopups(Window.Current); + return openedPopups.Any(popup => popup.Child is ContentDialog); + } + } +} diff --git a/Files/Interacts/BaseLayoutCommandImplementationModel.cs b/Files/Interacts/BaseLayoutCommandImplementationModel.cs index ffa0500a8fb7..404d6e2ee07d 100644 --- a/Files/Interacts/BaseLayoutCommandImplementationModel.cs +++ b/Files/Interacts/BaseLayoutCommandImplementationModel.cs @@ -335,12 +335,12 @@ await FilesystemHelpers.DeleteItemsAsync( public virtual void ShowFolderProperties(RoutedEventArgs e) { - associatedInstance.InteractionOperations.ShowProperties(); + FilePropertiesHelpers.ShowProperties(associatedInstance); } public virtual void ShowProperties(RoutedEventArgs e) { - associatedInstance.InteractionOperations.ShowProperties(); + FilePropertiesHelpers.ShowProperties(associatedInstance); } public virtual async void OpenFileLocation(RoutedEventArgs e) @@ -413,17 +413,17 @@ public virtual async void OpenInNewWindowItem(RoutedEventArgs e) public virtual void CreateNewFolder(RoutedEventArgs e) { - associatedInstance.InteractionOperations.CreateFileFromDialogResultType(AddItemType.Folder, null); + UIFilesystemHelpers.CreateFileFromDialogResultType(AddItemType.Folder, null, associatedInstance); } public virtual void CreateNewFile(RoutedEventArgs e) { - associatedInstance.InteractionOperations.CreateFileFromDialogResultType(AddItemType.File, null); + UIFilesystemHelpers.CreateFileFromDialogResultType(AddItemType.File, null, associatedInstance); } public virtual async void PasteItemsFromClipboard(RoutedEventArgs e) { - await associatedInstance.InteractionOperations.PasteItemAsync(associatedInstance.FilesystemViewModel.WorkingDirectory); + await UIFilesystemHelpers.PasteItemAsync(associatedInstance.FilesystemViewModel.WorkingDirectory, associatedInstance); } public virtual void CopyPathOfSelectedItem(RoutedEventArgs e) diff --git a/Files/Interacts/Interaction.cs b/Files/Interacts/Interaction.cs index 5e0866576687..fb5dc9ad1736 100644 --- a/Files/Interacts/Interaction.cs +++ b/Files/Interacts/Interaction.cs @@ -47,14 +47,11 @@ namespace Files.Interacts { public class Interaction { - private NamedPipeAsAppServiceConnection Connection => AssociatedInstance?.ServiceConnection; private string jumpString = ""; private readonly DispatcherTimer jumpTimer = new DispatcherTimer(); private readonly IShellPage AssociatedInstance; - public SettingsViewModel AppSettings => App.AppSettings; public IFilesystemHelpers FilesystemHelpers => AssociatedInstance.FilesystemHelpers; - public FolderSettingsViewModel FolderSettings => AssociatedInstance?.InstanceViewModel.FolderSettings; public Interaction(IShellPage appInstance) { @@ -112,219 +109,6 @@ public string JumpString } } - public async Task OpenShellCommandInExplorerAsync(string shellCommand) - { - Debug.WriteLine("Launching shell command in FullTrustProcess"); - if (Connection != null) - { - var value = new ValueSet(); - value.Add("ShellCommand", shellCommand); - value.Add("Arguments", "ShellCommand"); - await Connection.SendMessageAsync(value); - } - } - - public async void GrantAccessPermissionHandler(IUICommand command) - { - await Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-broadfilesystemaccess")); - } - - public static bool IsAnyContentDialogOpen() - { - var openedPopups = VisualTreeHelper.GetOpenPopups(Window.Current); - return openedPopups.Any(popup => popup.Child is ContentDialog); - } - - public async void LaunchNewWindow() - { - var filesUWPUri = new Uri("files-uwp:"); - await Launcher.LaunchUriAsync(filesUWPUri); - } - - public async void ShowProperties() - { - if (AssociatedInstance.SlimContentPage.IsItemSelected) - { - if (AssociatedInstance.SlimContentPage.SelectedItems.Count > 1) - { - await OpenPropertiesWindowAsync(AssociatedInstance.SlimContentPage.SelectedItems); - } - else - { - await OpenPropertiesWindowAsync(AssociatedInstance.SlimContentPage.SelectedItem); - } - } - else - { - if (!Path.GetPathRoot(AssociatedInstance.FilesystemViewModel.CurrentFolder.ItemPath) - .Equals(AssociatedInstance.FilesystemViewModel.CurrentFolder.ItemPath, StringComparison.OrdinalIgnoreCase)) - { - await OpenPropertiesWindowAsync(AssociatedInstance.FilesystemViewModel.CurrentFolder); - } - else - { - await OpenPropertiesWindowAsync(App.DrivesManager.Drives - .SingleOrDefault(x => x.Path.Equals(AssociatedInstance.FilesystemViewModel.CurrentFolder.ItemPath))); - } - } - } - - public async Task OpenPropertiesWindowAsync(object item) - { - if (item == null) - { - return; - } - if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8)) - { - CoreApplicationView newWindow = CoreApplication.CreateNewView(); - ApplicationView newView = null; - - await newWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => - { - Frame frame = new Frame(); - frame.Navigate(typeof(Properties), new PropertiesPageNavigationArguments() - { - Item = item, - AppInstanceArgument = AssociatedInstance - }, new SuppressNavigationTransitionInfo()); - Window.Current.Content = frame; - Window.Current.Activate(); - - newView = ApplicationView.GetForCurrentView(); - newWindow.TitleBar.ExtendViewIntoTitleBar = true; - newView.Title = "PropertiesTitle".GetLocalized(); - newView.PersistedStateId = "Properties"; - newView.SetPreferredMinSize(new Size(400, 550)); - newView.Consolidated += delegate - { - Window.Current.Close(); - }; - }); - - bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newView.Id); - // Set window size again here as sometimes it's not resized in the page Loaded event - newView.TryResizeView(new Size(400, 550)); - } - else - { - var propertiesDialog = new PropertiesDialog(); - propertiesDialog.propertiesFrame.Tag = propertiesDialog; - propertiesDialog.propertiesFrame.Navigate(typeof(Properties), new PropertiesPageNavigationArguments() - { - Item = item, - AppInstanceArgument = AssociatedInstance - }, new SuppressNavigationTransitionInfo()); - await propertiesDialog.ShowAsync(ContentDialogPlacement.Popup); - } - } - - public async Task RenameFileItemAsync(ListedItem item, string oldName, string newName) - { - if (oldName == newName) - { - return true; - } - - var renamed = ReturnResult.InProgress; - if (item.PrimaryItemAttribute == StorageItemTypes.Folder) - { - renamed = await FilesystemHelpers.RenameAsync(StorageItemHelpers.FromPathAndType(item.ItemPath, FilesystemItemType.Directory), - newName, NameCollisionOption.FailIfExists, true); - } - else - { - if (item.IsShortcutItem || !AppSettings.ShowFileExtensions) - { - newName += item.FileExtension; - } - - renamed = await FilesystemHelpers.RenameAsync(StorageItemHelpers.FromPathAndType(item.ItemPath, FilesystemItemType.File), - newName, NameCollisionOption.FailIfExists, true); - } - - if (renamed == ReturnResult.Success) - { - AssociatedInstance.NavigationToolbar.CanGoForward = false; - return true; - } - return false; - } - - /// - /// Set a single file or folder to hidden or unhidden an refresh the - /// view after setting the flag - /// - /// - /// - public void SetHiddenAttributeItem(ListedItem item, bool isHidden) - { - item.IsHiddenItem = isHidden; - AssociatedInstance.SlimContentPage.ResetItemOpacity(); - } - - public async Task PasteItemAsync(string destinationPath) - { - DataPackageView packageView = await FilesystemTasks.Wrap(() => Task.FromResult(Clipboard.GetContent())); - if (packageView != null) - { - await FilesystemHelpers.PerformOperationTypeAsync(packageView.RequestedOperation, packageView, destinationPath, true); - AssociatedInstance.SlimContentPage.ResetItemOpacity(); - } - } - - public async void CreateFileFromDialogResultType(AddItemType itemType, ShellNewEntry itemInfo) - { - string currentPath = null; - if (AssociatedInstance.SlimContentPage != null) - { - currentPath = AssociatedInstance.FilesystemViewModel.WorkingDirectory; - } - - // Show rename dialog - DynamicDialog dialog = DynamicDialogFactory.GetFor_RenameDialog(); - await dialog.ShowAsync(); - - if (dialog.DynamicResult != DynamicDialogResult.Primary) - { - return; - } - - // Create file based on dialog result - string userInput = dialog.ViewModel.AdditionalData as string; - var folderRes = await AssociatedInstance.FilesystemViewModel.GetFolderWithPathFromPathAsync(currentPath); - FilesystemResult created = folderRes; - if (folderRes) - { - switch (itemType) - { - case AddItemType.Folder: - userInput = !string.IsNullOrWhiteSpace(userInput) ? userInput : "NewFolder".GetLocalized(); - created = await FilesystemTasks.Wrap(async () => - { - return await FilesystemHelpers.CreateAsync( - StorageItemHelpers.FromPathAndType(Path.Combine(folderRes.Result.Path, userInput), FilesystemItemType.Directory), - true); - }); - break; - - case AddItemType.File: - userInput = !string.IsNullOrWhiteSpace(userInput) ? userInput : itemInfo?.Name ?? "NewFile".GetLocalized(); - created = await FilesystemTasks.Wrap(async () => - { - return await FilesystemHelpers.CreateAsync( - StorageItemHelpers.FromPathAndType(Path.Combine(folderRes.Result.Path, userInput + itemInfo?.Extension), FilesystemItemType.File), - true); - }); - break; - } - } - if (created == FileSystemStatusCode.Unauthorized) - { - await DialogDisplayHelper.ShowDialogAsync("AccessDeniedCreateDialog/Title".GetLocalized(), "AccessDeniedCreateDialog/Text".GetLocalized()); - } - } - public void PushJumpChar(char letter) { JumpString += letter.ToString().ToLower(); diff --git a/Files/UserControls/Widgets/DrivesWidget.xaml.cs b/Files/UserControls/Widgets/DrivesWidget.xaml.cs index 551b59cbd344..f32a12d6b538 100644 --- a/Files/UserControls/Widgets/DrivesWidget.xaml.cs +++ b/Files/UserControls/Widgets/DrivesWidget.xaml.cs @@ -77,7 +77,7 @@ private async void OpenInNewWindow_Click(object sender, RoutedEventArgs e) private async void OpenDriveProperties_Click(object sender, RoutedEventArgs e) { var item = ((MenuFlyoutItem)sender).DataContext as DriveItem; - await AppInstance.InteractionOperations.OpenPropertiesWindowAsync(item); + await FilePropertiesHelpers.OpenPropertiesWindowAsync(item, associatedInstance); } private void Button_Click(object sender, RoutedEventArgs e) diff --git a/Files/Views/LayoutModes/GenericFileBrowser.xaml.cs b/Files/Views/LayoutModes/GenericFileBrowser.xaml.cs index 161b026e24a9..546fd3152374 100644 --- a/Files/Views/LayoutModes/GenericFileBrowser.xaml.cs +++ b/Files/Views/LayoutModes/GenericFileBrowser.xaml.cs @@ -414,7 +414,7 @@ private async void AllView_CellEditEnding(object sender, DataGridCellEditEndingE var selectedItem = e.Row.DataContext as ListedItem; string newItemName = renamingTextBox.Text; - bool successful = await ParentShellPageInstance.InteractionOperations.RenameFileItemAsync(selectedItem, oldItemName, newItemName); + bool successful = await UIFilesystemHelpers.RenameFileItemAsync(selectedItem, oldItemName, newItemName, ParentShellPageInstance); if (!successful) { selectedItem.ItemName = oldItemName; @@ -504,7 +504,7 @@ private void AllView_PreviewKeyDown(object sender, KeyRoutedEventArgs e) } else if (e.Key == VirtualKey.Enter && e.KeyStatus.IsMenuKeyDown) { - ParentShellPageInstance.InteractionOperations.ShowProperties(); + FilePropertiesHelpers.ShowProperties(ParentShellPageInstance); e.Handled = true; } else if (e.KeyStatus.IsMenuKeyDown && (e.Key == VirtualKey.Left || e.Key == VirtualKey.Right || e.Key == VirtualKey.Up)) diff --git a/Files/Views/LayoutModes/GridViewBrowser.xaml.cs b/Files/Views/LayoutModes/GridViewBrowser.xaml.cs index c55495a3c8a5..16890298bfcf 100644 --- a/Files/Views/LayoutModes/GridViewBrowser.xaml.cs +++ b/Files/Views/LayoutModes/GridViewBrowser.xaml.cs @@ -273,7 +273,7 @@ private async void CommitRename(TextBox textBox) EndRename(textBox); string newItemName = textBox.Text.Trim().TrimEnd('.'); - bool successful = await ParentShellPageInstance.InteractionOperations.RenameFileItemAsync(renamingItem, oldItemName, newItemName); + bool successful = await UIFilesystemHelpers.RenameFileItemAsync(renamingItem, oldItemName, newItemName, ParentShellPageInstance); if (!successful) { renamingItem.ItemName = oldItemName; @@ -321,7 +321,7 @@ private void FileList_PreviewKeyDown(object sender, KeyRoutedEventArgs e) } else if (e.Key == VirtualKey.Enter && e.KeyStatus.IsMenuKeyDown) { - ParentShellPageInstance.InteractionOperations.ShowProperties(); + FilePropertiesHelpers.ShowProperties(ParentShellPageInstance); e.Handled = true; } else if (e.Key == VirtualKey.Space) diff --git a/Files/Views/ModernShellPage.xaml.cs b/Files/Views/ModernShellPage.xaml.cs index 51f1e170c35f..ddd793d40c3f 100644 --- a/Files/Views/ModernShellPage.xaml.cs +++ b/Files/Views/ModernShellPage.xaml.cs @@ -239,15 +239,15 @@ private void InitializeCommands() ClearContentPageSelectionCommand = new RelayCommand(this.SlimContentPage.ClearSelection); InvertContentPageSelctionCommand = new RelayCommand(this.SlimContentPage.InvertSelection); } - PasteItemsFromClipboardCommand = new RelayCommand(async () => await this.InteractionOperations.PasteItemAsync(FilesystemViewModel.WorkingDirectory)); + PasteItemsFromClipboardCommand = new RelayCommand(async () => await UIFilesystemHelpers.PasteItemAsync(FilesystemViewModel.WorkingDirectory, this)); CopyPathOfWorkingDirectoryCommand = new RelayCommand(CopyWorkingLocation); - OpenNewWindowCommand = new RelayCommand(this.InteractionOperations.LaunchNewWindow); + OpenNewWindowCommand = new RelayCommand(NavigationHelpers.LaunchNewWindow); OpenNewPaneCommand = new RelayCommand(() => PaneHolder?.OpenPathInNewPane("NewTab".GetLocalized())); OpenDirectoryInDefaultTerminalCommand = new RelayCommand(() => NavigationHelpers.OpenDirectoryInTerminal(this.FilesystemViewModel.WorkingDirectory, this)); AddNewTabToMultitaskingControlCommand = new RelayCommand(async () => await MainPage.AddNewTabByPathAsync(typeof(PaneHolderPage), "NewTab".GetLocalized())); - CreateNewFileCommand = new RelayCommand(() => InteractionOperations.CreateFileFromDialogResultType(AddItemType.File, null)); - CreateNewFolderCommand = new RelayCommand(() => InteractionOperations.CreateFileFromDialogResultType(AddItemType.Folder, null)); + CreateNewFileCommand = new RelayCommand(() => UIFilesystemHelpers.CreateFileFromDialogResultType(AddItemType.File, null, this)); + CreateNewFolderCommand = new RelayCommand(() => UIFilesystemHelpers.CreateFileFromDialogResultType(AddItemType.Folder, null, this)); } private void CopyWorkingLocation() @@ -976,9 +976,10 @@ private async void KeyboardAccelerator_Invoked(KeyboardAccelerator sender, Keybo await addItemDialog.ShowAsync(); if (addItemDialog.ResultType.ItemType != AddItemType.Cancel) { - InteractionOperations.CreateFileFromDialogResultType( + UIFilesystemHelpers.CreateFileFromDialogResultType( addItemDialog.ResultType.ItemType, - addItemDialog.ResultType.ItemInfo); + addItemDialog.ResultType.ItemInfo, + this); } } break; @@ -998,7 +999,7 @@ await FilesystemHelpers.DeleteItemsAsync( case (true, false, false, true, VirtualKey.C): // ctrl + c, copy if (!NavigationToolbar.IsEditModeEnabled && !ContentPage.IsRenamingItem) { - InteractionOperations.ShowProperties(); + FilePropertiesHelpers.ShowProperties(this); } break; @@ -1006,7 +1007,7 @@ await FilesystemHelpers.DeleteItemsAsync( case (true, false, false, true, VirtualKey.V): // ctrl + v, paste if (!NavigationToolbar.IsEditModeEnabled && !ContentPage.IsRenamingItem && !InstanceViewModel.IsPageTypeSearchResults) { - await InteractionOperations.PasteItemAsync(FilesystemViewModel.WorkingDirectory); + await UIFilesystemHelpers.PasteItemAsync(FilesystemViewModel.WorkingDirectory, this); } break; @@ -1014,7 +1015,7 @@ await FilesystemHelpers.DeleteItemsAsync( case (true, false, false, true, VirtualKey.X): // ctrl + x, cut if (!NavigationToolbar.IsEditModeEnabled && !ContentPage.IsRenamingItem) { - InteractionOperations.ShowProperties(); + FilePropertiesHelpers.ShowProperties(this); } break; diff --git a/Files/Views/Pages/PropertiesDetails.xaml.cs b/Files/Views/Pages/PropertiesDetails.xaml.cs index f5b141bb46c4..c84d903489a5 100644 --- a/Files/Views/Pages/PropertiesDetails.xaml.cs +++ b/Files/Views/Pages/PropertiesDetails.xaml.cs @@ -48,7 +48,7 @@ public async Task SaveChangesAsync() { // Attempting to open more than one ContentDialog // at a time will throw an error) - if (Interacts.Interaction.IsAnyContentDialogOpen()) + if (UIHelpers.IsAnyContentDialogOpen()) { return false; } diff --git a/Files/Views/Pages/PropertiesGeneral.xaml.cs b/Files/Views/Pages/PropertiesGeneral.xaml.cs index dd979ede4f13..c337d1446ab8 100644 --- a/Files/Views/Pages/PropertiesGeneral.xaml.cs +++ b/Files/Views/Pages/PropertiesGeneral.xaml.cs @@ -1,6 +1,7 @@ using Files.Filesystem; using Files.Helpers; using Files.ViewModels.Properties; +using Microsoft.Toolkit.Uwp; using Microsoft.Toolkit.Uwp.Helpers; using System; using System.Threading.Tasks; @@ -32,7 +33,7 @@ public async Task SaveChangesAsync(ListedItem item) { "drivename", drive.Path }, { "newlabel", ViewModel.ItemName } }); - _ = CoreApplication.MainView.ExecuteOnUIThreadAsync(async () => + _ = CoreApplication.MainView.DispatcherQueue.EnqueueAsync(async () => { await drive.UpdateLabelAsync(); await AppInstance.FilesystemViewModel?.SetWorkingDirectoryAsync(drive.Path); @@ -44,9 +45,10 @@ public async Task SaveChangesAsync(ListedItem item) { if (!string.IsNullOrWhiteSpace(ViewModel.ItemName) && ViewModel.OriginalItemName != ViewModel.ItemName) { - await CoreApplication.MainView.ExecuteOnUIThreadAsync(() => AppInstance.InteractionOperations?.RenameFileItemAsync(item, + await CoreApplication.MainView.DispatcherQueue.EnqueueAsync(() => UIFilesystemHelpers.RenameFileItemAsync(item, ViewModel.OriginalItemName, - ViewModel.ItemName)); + ViewModel.ItemName, + AppInstance)); } // Handle the hidden attribute @@ -56,13 +58,13 @@ await CoreApplication.MainView.ExecuteOnUIThreadAsync(() => AppInstance.Interact var items = (BaseProperties as CombinedProperties).List; foreach (var fileOrFolder in items) { - await CoreApplication.MainView.ExecuteOnUIThreadAsync(() => AppInstance.InteractionOperations?.SetHiddenAttributeItem(fileOrFolder, ViewModel.IsHidden)); + await CoreApplication.MainView.DispatcherQueue.EnqueueAsync(() => UIFilesystemHelpers.SetHiddenAttributeItem(fileOrFolder, ViewModel.IsHidden, AppInstance.SlimContentPage)); } } else { // Handle the visibility attribute for a single file - await CoreApplication.MainView.ExecuteOnUIThreadAsync(() => AppInstance.InteractionOperations?.SetHiddenAttributeItem(item, ViewModel.IsHidden)); + await CoreApplication.MainView.DispatcherQueue.EnqueueAsync(() => UIFilesystemHelpers.SetHiddenAttributeItem(item, ViewModel.IsHidden, AppInstance.SlimContentPage)); } } } diff --git a/Files/Views/PaneHolderPage.xaml.cs b/Files/Views/PaneHolderPage.xaml.cs index 3a0d1003dae3..606b8662bdf1 100644 --- a/Files/Views/PaneHolderPage.xaml.cs +++ b/Files/Views/PaneHolderPage.xaml.cs @@ -519,7 +519,7 @@ private async void SidebarControl_SidebarItemPropertiesInvoked(object sender, Si { if (e.InvokedItemDataContext is DriveItem) { - await InteractionOperations.OpenPropertiesWindowAsync(e.InvokedItemDataContext); + await FilePropertiesHelpers.OpenPropertiesWindowAsync(e.InvokedItemDataContext, ActivePane); } else if (e.InvokedItemDataContext is LocationItem) { @@ -531,7 +531,7 @@ private async void SidebarControl_SidebarItemPropertiesInvoked(object sender, Si ItemType = "FileFolderListItem".GetLocalized(), LoadFolderGlyph = true }; - await InteractionOperations.OpenPropertiesWindowAsync(listedItem); + await FilePropertiesHelpers.OpenPropertiesWindowAsync(listedItem, ActivePane); } } From 5c1ae0518c8221bdbef2454fa6d525e77a872c83 Mon Sep 17 00:00:00 2001 From: d2dyno006 <53011783+d2dyno006@users.noreply.github.com> Date: Sun, 21 Mar 2021 12:54:46 +0100 Subject: [PATCH 5/9] rm5 --- Files/BaseLayout.cs | 57 +++++++++++++++- Files/IShellPage.cs | 2 +- Files/Interacts/Interaction.cs | 66 ------------------- .../Views/LayoutModes/GridViewBrowser.xaml.cs | 5 -- Files/Views/ModernShellPage.xaml.cs | 21 +----- Files/Views/PaneHolderPage.xaml.cs | 3 - 6 files changed, 56 insertions(+), 98 deletions(-) diff --git a/Files/BaseLayout.cs b/Files/BaseLayout.cs index 24232057d33f..c42547152f22 100644 --- a/Files/BaseLayout.cs +++ b/Files/BaseLayout.cs @@ -88,6 +88,57 @@ internal set } } + private string jumpString = string.Empty; + + public string JumpString + { + get => jumpString; + set + { + // If current string is "a", and the next character typed is "a", + // search for next file that starts with "a" (a.k.a. _jumpString = "a") + if (jumpString.Length == 1 && value == jumpString + jumpString) + { + value = jumpString; + } + if (value != string.Empty) + { + ListedItem jumpedToItem = null; + ListedItem previouslySelectedItem = null; + + // Use FilesAndFolders because only displayed entries should be jumped to + IEnumerable candidateItems = ParentShellPageInstance.FilesystemViewModel.FilesAndFolders.Where(f => f.ItemName.Length >= value.Length && f.ItemName.Substring(0, value.Length).ToLower() == value); + + if (IsItemSelected) + { + previouslySelectedItem = SelectedItem; + } + + // If the user is trying to cycle through items + // starting with the same letter + if (value.Length == 1 && previouslySelectedItem != null) + { + // Try to select item lexicographically bigger than the previous item + jumpedToItem = candidateItems.FirstOrDefault(f => f.ItemName.CompareTo(previouslySelectedItem.ItemName) > 0); + } + if (jumpedToItem == null) + { + jumpedToItem = candidateItems.FirstOrDefault(); + } + + if (jumpedToItem != null) + { + SetSelectedItemOnUi(jumpedToItem); + ScrollIntoView(jumpedToItem); + } + + // Reset + jumpString = ""; + } + jumpString = value; + } + } + private List selectedItems = new List(); public List SelectedItems @@ -808,8 +859,8 @@ protected virtual void Page_CharacterReceived(CoreWindow sender, CharacterReceiv { if (ParentShellPageInstance.IsCurrentInstance) { - char letterPressed = Convert.ToChar(args.KeyCode); - ParentShellPageInstance.InteractionOperations.PushJumpChar(letterPressed); + char letter = Convert.ToChar(args.KeyCode); + JumpString += letter.ToString().ToLowerInvariant(); } } @@ -876,7 +927,7 @@ protected async void List_Drop(object sender, DragEventArgs e) if (e.DataView.Contains(StandardDataFormats.StorageItems)) { - await ParentShellPageInstance.InteractionOperations.FilesystemHelpers.PerformOperationTypeAsync(e.AcceptedOperation, e.DataView, ParentShellPageInstance.FilesystemViewModel.WorkingDirectory, true); + await ParentShellPageInstance.FilesystemHelpers.PerformOperationTypeAsync(e.AcceptedOperation, e.DataView, ParentShellPageInstance.FilesystemViewModel.WorkingDirectory, true); e.Handled = true; } diff --git a/Files/IShellPage.cs b/Files/IShellPage.cs index dce497359eea..a3545b171dc2 100644 --- a/Files/IShellPage.cs +++ b/Files/IShellPage.cs @@ -14,7 +14,7 @@ public interface IShellPage : ITabItemContent, IMultiPaneInfo, IDisposable { IStatusCenterActions StatusCenterActions { get; } - Interaction InteractionOperations { get; } + //Interaction InteractionOperations { get; } ItemViewModel FilesystemViewModel { get; } diff --git a/Files/Interacts/Interaction.cs b/Files/Interacts/Interaction.cs index fb5dc9ad1736..c3b60cb39107 100644 --- a/Files/Interacts/Interaction.cs +++ b/Files/Interacts/Interaction.cs @@ -47,77 +47,11 @@ namespace Files.Interacts { public class Interaction { - private string jumpString = ""; - private readonly DispatcherTimer jumpTimer = new DispatcherTimer(); private readonly IShellPage AssociatedInstance; - public IFilesystemHelpers FilesystemHelpers => AssociatedInstance.FilesystemHelpers; - public Interaction(IShellPage appInstance) { AssociatedInstance = appInstance; - jumpTimer.Interval = TimeSpan.FromSeconds(0.8); - jumpTimer.Tick += JumpTimer_Tick; - } - - public string JumpString - { - get => jumpString; - set - { - // If current string is "a", and the next character typed is "a", - // search for next file that starts with "a" (a.k.a. _jumpString = "a") - if (jumpString.Length == 1 && value == jumpString + jumpString) - { - value = jumpString; - } - if (value != "") - { - ListedItem jumpedToItem = null; - ListedItem previouslySelectedItem = null; - - // use FilesAndFolders because only displayed entries should be jumped to - var candidateItems = AssociatedInstance.FilesystemViewModel.FilesAndFolders.Where(f => f.ItemName.Length >= value.Length && f.ItemName.Substring(0, value.Length).ToLower() == value); - - if (AssociatedInstance.SlimContentPage != null && AssociatedInstance.SlimContentPage.IsItemSelected) - { - previouslySelectedItem = AssociatedInstance.SlimContentPage.SelectedItem; - } - - // If the user is trying to cycle through items - // starting with the same letter - if (value.Length == 1 && previouslySelectedItem != null) - { - // Try to select item lexicographically bigger than the previous item - jumpedToItem = candidateItems.FirstOrDefault(f => f.ItemName.CompareTo(previouslySelectedItem.ItemName) > 0); - } - if (jumpedToItem == null) - { - jumpedToItem = candidateItems.FirstOrDefault(); - } - - if (jumpedToItem != null) - { - AssociatedInstance.SlimContentPage.SetSelectedItemOnUi(jumpedToItem); - AssociatedInstance.SlimContentPage.ScrollIntoView(jumpedToItem); - } - - // Restart the timer - jumpTimer.Start(); - } - jumpString = value; - } - } - - public void PushJumpChar(char letter) - { - JumpString += letter.ToString().ToLower(); - } - - private void JumpTimer_Tick(object sender, object e) - { - jumpString = ""; - jumpTimer.Stop(); } } } \ No newline at end of file diff --git a/Files/Views/LayoutModes/GridViewBrowser.xaml.cs b/Files/Views/LayoutModes/GridViewBrowser.xaml.cs index 16890298bfcf..0581d71f7cce 100644 --- a/Files/Views/LayoutModes/GridViewBrowser.xaml.cs +++ b/Files/Views/LayoutModes/GridViewBrowser.xaml.cs @@ -5,15 +5,12 @@ using Files.Helpers.XamlHelpers; using Files.Interacts; using Files.UserControls.Selection; -using Microsoft.Toolkit.Uwp; using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; -using System.IO; using System.Linq; using System.Threading.Tasks; -using Windows.Foundation.Collections; using Windows.System; using Windows.UI.Core; using Windows.UI.Xaml; @@ -21,8 +18,6 @@ using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Navigation; -using static Files.ViewModels.FolderSettingsViewModel; -using Interaction = Files.Interacts.Interaction; namespace Files.Views.LayoutModes { diff --git a/Files/Views/ModernShellPage.xaml.cs b/Files/Views/ModernShellPage.xaml.cs index ddd793d40c3f..ae1d19a34473 100644 --- a/Files/Views/ModernShellPage.xaml.cs +++ b/Files/Views/ModernShellPage.xaml.cs @@ -57,24 +57,6 @@ public sealed partial class ModernShellPage : Page, IShellPage, INotifyPropertyC public InteractionViewModel InteractionViewModel => App.InteractionViewModel; - private Interaction interactionOperations = null; - - public Interaction InteractionOperations - { - get - { - return interactionOperations; - } - private set - { - if (interactionOperations != value) - { - interactionOperations = value; - NotifyPropertyChanged(nameof(InteractionOperations)); - } - } - } - private bool isCurrentInstance { get; set; } = false; public bool IsCurrentInstance @@ -181,7 +163,6 @@ public ModernShellPage() { InitializeComponent(); - InteractionOperations = new Interaction(this); InstanceViewModel = new CurrentInstanceViewModel(); InstanceViewModel.FolderSettings.LayoutPreferencesUpdateRequired += FolderSettings_LayoutPreferencesUpdateRequired; cancellationTokenSource = new CancellationTokenSource(); @@ -1286,7 +1267,7 @@ public async Task TabItemDrop(object sender, DragEventArgs { if (InstanceViewModel.IsPageTypeNotHome && !InstanceViewModel.IsPageTypeSearchResults) { - await InteractionOperations.FilesystemHelpers.PerformOperationTypeAsync( + await FilesystemHelpers.PerformOperationTypeAsync( DataPackageOperation.Move, e.DataView, FilesystemViewModel.WorkingDirectory, diff --git a/Files/Views/PaneHolderPage.xaml.cs b/Files/Views/PaneHolderPage.xaml.cs index 606b8662bdf1..a5ad93b7544d 100644 --- a/Files/Views/PaneHolderPage.xaml.cs +++ b/Files/Views/PaneHolderPage.xaml.cs @@ -30,8 +30,6 @@ namespace Files.Views public sealed partial class PaneHolderPage : Page, IPaneHolder, ITabItemContent, INotifyPropertyChanged { public SettingsViewModel AppSettings => App.AppSettings; - - public Interaction InteractionOperations => ActivePane?.InteractionOperations; public double DragRegionWidth => CoreApplication.GetCurrentView().TitleBar.SystemOverlayRightInset; public IFilesystemHelpers FilesystemHelpers => ActivePane?.FilesystemHelpers; @@ -217,7 +215,6 @@ public IShellPage ActivePane NotifyPropertyChanged(nameof(ActivePane)); NotifyPropertyChanged(nameof(IsLeftPaneActive)); NotifyPropertyChanged(nameof(IsRightPaneActive)); - NotifyPropertyChanged(nameof(InteractionOperations)); NotifyPropertyChanged(nameof(FilesystemHelpers)); UpdateSidebarSelectedItem(); } From 6ced938e7cfe589e14a2095f9c81c21ab2c1ef13 Mon Sep 17 00:00:00 2001 From: d2dyno006 <53011783+d2dyno006@users.noreply.github.com> Date: Sun, 21 Mar 2021 12:55:54 +0100 Subject: [PATCH 6/9] Farewell, Interaction --- Files/Files.csproj | 1 - Files/Interacts/Interaction.cs | 57 ---------------------------------- 2 files changed, 58 deletions(-) delete mode 100644 Files/Interacts/Interaction.cs diff --git a/Files/Files.csproj b/Files/Files.csproj index 1fba9196cbb8..09599d3aeeea 100644 --- a/Files/Files.csproj +++ b/Files/Files.csproj @@ -453,7 +453,6 @@ - GridViewBrowser.xaml diff --git a/Files/Interacts/Interaction.cs b/Files/Interacts/Interaction.cs deleted file mode 100644 index c3b60cb39107..000000000000 --- a/Files/Interacts/Interaction.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Files.Common; -using Files.DataModels; -using Files.Dialogs; -using Files.Enums; -using Files.Filesystem; -using Files.Helpers; -using Files.ViewModels; -using Files.Views; -using Microsoft.Toolkit.Mvvm.Input; -using Microsoft.Toolkit.Uwp; -using Microsoft.Toolkit.Uwp.Notifications; -using Newtonsoft.Json; -using NLog; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Threading; -using System.Threading.Tasks; -using Windows.ApplicationModel.AppService; -using Windows.ApplicationModel.Core; -using Windows.ApplicationModel.DataTransfer; -using Windows.Foundation; -using Windows.Foundation.Collections; -using Windows.Foundation.Metadata; -using Windows.Security.Cryptography; -using Windows.Security.Cryptography.Core; -using Windows.Storage; -using Windows.Storage.Search; -using Windows.Storage.Streams; -using Windows.System; -using Windows.System.UserProfile; -using Windows.UI.Core; -using Windows.UI.Notifications; -using Windows.UI.Popups; -using Windows.UI.ViewManagement; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Input; -using Windows.UI.Xaml.Media; -using Windows.UI.Xaml.Media.Animation; -using static Files.Views.Properties; - -namespace Files.Interacts -{ - public class Interaction - { - private readonly IShellPage AssociatedInstance; - - public Interaction(IShellPage appInstance) - { - AssociatedInstance = appInstance; - } - } -} \ No newline at end of file From 31fb2a1d95b59f6f305204d4f26cf7b2c3b8905b Mon Sep 17 00:00:00 2001 From: d2dyno006 <53011783+d2dyno006@users.noreply.github.com> Date: Sun, 21 Mar 2021 12:59:34 +0100 Subject: [PATCH 7/9] JumpString fix --- Files/BaseLayout.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Files/BaseLayout.cs b/Files/BaseLayout.cs index c42547152f22..b5f456ec7409 100644 --- a/Files/BaseLayout.cs +++ b/Files/BaseLayout.cs @@ -134,6 +134,7 @@ public string JumpString // Reset jumpString = ""; + return; } jumpString = value; } From 6b7db72deb2cb7f214b8848a6b89535b6594d329 Mon Sep 17 00:00:00 2001 From: d2dyno006 <53011783+d2dyno006@users.noreply.github.com> Date: Sun, 21 Mar 2021 18:09:38 +0100 Subject: [PATCH 8/9] Fix build error --- Files/UserControls/SidebarControl.xaml.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Files/UserControls/SidebarControl.xaml.cs b/Files/UserControls/SidebarControl.xaml.cs index f1917d76878c..e03e943987d6 100644 --- a/Files/UserControls/SidebarControl.xaml.cs +++ b/Files/UserControls/SidebarControl.xaml.cs @@ -299,12 +299,12 @@ private void NavigationViewWSLItem_RightTapped(object sender, RightTappedRoutedE private void OpenInNewTab_Click(object sender, RoutedEventArgs e) { - NavigationHelpers.OpenPathInNewTab(App.RightClickedItem.Path); + NavigationHelpers.OpenPathInNewTab(RightClickedItem.Path); } private async void OpenInNewWindow_Click(object sender, RoutedEventArgs e) { - await NavigationHelpers.OpenPathInNewWindowAsync(App.RightClickedItem.Path); + await NavigationHelpers.OpenPathInNewWindowAsync(RightClickedItem.Path); } private void NavigationViewItem_DragStarting(UIElement sender, DragStartingEventArgs args) From 232ec15dd807cbe9e834a522f74bafcadb752275 Mon Sep 17 00:00:00 2001 From: d2dyno006 <53011783+d2dyno006@users.noreply.github.com> Date: Sun, 21 Mar 2021 19:39:30 +0100 Subject: [PATCH 9/9] Re-add jumpTimer --- Files/BaseLayout.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Files/BaseLayout.cs b/Files/BaseLayout.cs index 2b9018b45ae4..ba1bab687f21 100644 --- a/Files/BaseLayout.cs +++ b/Files/BaseLayout.cs @@ -42,6 +42,8 @@ namespace Files /// public abstract class BaseLayout : Page, IBaseLayout, INotifyPropertyChanged { + private readonly DispatcherTimer jumpTimer; + protected NamedPipeAsAppServiceConnection Connection => ParentShellPageInstance?.ServiceConnection; public SelectedItemsPropertiesViewModel SelectedItemsPropertiesViewModel { get; } @@ -132,9 +134,8 @@ public string JumpString ScrollIntoView(jumpedToItem); } - // Reset - jumpString = ""; - return; + // Restart the timer + jumpTimer.Start(); } jumpString = value; } @@ -208,6 +209,10 @@ internal set public BaseLayout() { + jumpTimer = new DispatcherTimer(); + jumpTimer.Interval = TimeSpan.FromSeconds(0.8); + jumpTimer.Tick += JumpTimer_Tick; ; + SelectedItemsPropertiesViewModel = new SelectedItemsPropertiesViewModel(this); DirectoryPropertiesViewModel = new DirectoryPropertiesViewModel(); @@ -223,6 +228,12 @@ public BaseLayout() dragOverTimer = DispatcherQueue.GetForCurrentThread().CreateTimer(); } + private void JumpTimer_Tick(object sender, object e) + { + jumpString = string.Empty; + jumpTimer.Stop(); + } + protected abstract void InitializeCommandsViewModel(); public abstract void FocusFileList();