From 7e67dc4f1e09c10cf55ce43faf004f78d70037b0 Mon Sep 17 00:00:00 2001 From: Yair <39923744+yaira2@users.noreply.github.com> Date: Wed, 30 Oct 2024 16:29:05 -0400 Subject: [PATCH] Feature: Added an action to copy the path of the current directory (#16406) --- .../Actions/FileSystem/CopyItemPathAction.cs | 56 ++++++++++++++++++ .../CopyItemPathWithQuotesAction.cs | 57 +++++++++++++++++++ .../Actions/FileSystem/CopyPathAction.cs | 13 ++--- .../FileSystem/CopyPathWithQuotesAction.cs | 14 ++--- .../Data/Commands/Manager/CommandCodes.cs | 2 + .../Data/Commands/Manager/CommandManager.cs | 4 ++ .../Data/Commands/Manager/ICommandManager.cs | 2 + .../ContentPageContextFlyoutFactory.cs | 2 +- src/Files.App/Strings/en-US/Resources.resw | 11 +++- 9 files changed, 140 insertions(+), 21 deletions(-) create mode 100644 src/Files.App/Actions/FileSystem/CopyItemPathAction.cs create mode 100644 src/Files.App/Actions/FileSystem/CopyItemPathWithQuotesAction.cs diff --git a/src/Files.App/Actions/FileSystem/CopyItemPathAction.cs b/src/Files.App/Actions/FileSystem/CopyItemPathAction.cs new file mode 100644 index 000000000000..c174feeb04d4 --- /dev/null +++ b/src/Files.App/Actions/FileSystem/CopyItemPathAction.cs @@ -0,0 +1,56 @@ +// Copyright (c) 2024 Files Community +// Licensed under the MIT License. See the LICENSE. + +using Windows.ApplicationModel.DataTransfer; + +namespace Files.App.Actions +{ + internal sealed class CopyItemPathAction : IAction + { + private readonly IContentPageContext context; + + public string Label + => Strings.CopyPath.GetLocalizedResource(); + + public string Description + => Strings.CopyItemPathDescription.GetLocalizedResource(); + + public RichGlyph Glyph + => new RichGlyph(themedIconStyle: "App.ThemedIcons.CopyAsPath"); + + public HotKey HotKey + => new(Keys.C, KeyModifiers.CtrlShift); + + public bool IsExecutable + => context.HasSelection; + + public CopyItemPathAction() + { + context = Ioc.Default.GetRequiredService(); + } + + public Task ExecuteAsync(object? parameter = null) + { + if (context.ShellPage?.SlimContentPage is not null) + { + var path = context.ShellPage.SlimContentPage.SelectedItems is not null + ? context.ShellPage.SlimContentPage.SelectedItems.Select(x => x.ItemPath).Aggregate((accum, current) => accum + "\n" + current) + : context.ShellPage.ShellViewModel.WorkingDirectory; + + if (FtpHelpers.IsFtpPath(path)) + path = path.Replace("\\", "/", StringComparison.Ordinal); + + SafetyExtensions.IgnoreExceptions(() => + { + DataPackage data = new(); + data.SetText(path); + + Clipboard.SetContent(data); + Clipboard.Flush(); + }); + } + + return Task.CompletedTask; + } + } +} \ No newline at end of file diff --git a/src/Files.App/Actions/FileSystem/CopyItemPathWithQuotesAction.cs b/src/Files.App/Actions/FileSystem/CopyItemPathWithQuotesAction.cs new file mode 100644 index 000000000000..1ece05148a4b --- /dev/null +++ b/src/Files.App/Actions/FileSystem/CopyItemPathWithQuotesAction.cs @@ -0,0 +1,57 @@ +// Copyright (c) 2024 Files Community +// Licensed under the MIT License. See the LICENSE. + +using Windows.ApplicationModel.DataTransfer; + +namespace Files.App.Actions +{ + internal sealed class CopyItemPathWithQuotesAction : IAction + { + private readonly IContentPageContext context; + + public string Label + => Strings.CopyItemPathWithQuotes.GetLocalizedResource(); + + public string Description + => Strings.CopyItemPathWithQuotesDescription.GetLocalizedResource(); + + public RichGlyph Glyph + => new RichGlyph(themedIconStyle: "App.ThemedIcons.CopyAsPath"); + + public HotKey HotKey + => new(Keys.C, KeyModifiers.CtrlAlt); + + public bool IsExecutable + => context.HasSelection; + + public CopyItemPathWithQuotesAction() + { + context = Ioc.Default.GetRequiredService(); + } + + public Task ExecuteAsync(object? parameter = null) + { + if (context.ShellPage?.SlimContentPage is not null) + { + var selectedItems = context.ShellPage.SlimContentPage.SelectedItems; + var path = selectedItems is not null + ? string.Join("\n", selectedItems.Select(item => $"\"{item.ItemPath}\"")) + : context.ShellPage.ShellViewModel.WorkingDirectory; + + if (FtpHelpers.IsFtpPath(path)) + path = path.Replace("\\", "/", StringComparison.Ordinal); + + SafetyExtensions.IgnoreExceptions(() => + { + DataPackage data = new(); + data.SetText(path); + + Clipboard.SetContent(data); + Clipboard.Flush(); + }); + } + + return Task.CompletedTask; + } + } +} diff --git a/src/Files.App/Actions/FileSystem/CopyPathAction.cs b/src/Files.App/Actions/FileSystem/CopyPathAction.cs index 585af05a0281..43b4ca8bc7b6 100644 --- a/src/Files.App/Actions/FileSystem/CopyPathAction.cs +++ b/src/Files.App/Actions/FileSystem/CopyPathAction.cs @@ -10,19 +10,16 @@ internal sealed class CopyPathAction : IAction private readonly IContentPageContext context; public string Label - => "CopyPath".GetLocalizedResource(); + => Strings.CopyPath.GetLocalizedResource(); public string Description - => "CopyPathDescription".GetLocalizedResource(); + => Strings.CopyPathDescription.GetLocalizedResource(); public RichGlyph Glyph => new RichGlyph(themedIconStyle: "App.ThemedIcons.CopyAsPath"); - public HotKey HotKey - => new(Keys.C, KeyModifiers.CtrlShift); - public bool IsExecutable - => context.HasSelection; + => context.PageType != ContentPageTypes.Home && context.PageType != ContentPageTypes.RecycleBin; public CopyPathAction() { @@ -33,9 +30,7 @@ public Task ExecuteAsync(object? parameter = null) { if (context.ShellPage?.SlimContentPage is not null) { - var path = context.ShellPage.SlimContentPage.SelectedItems is not null - ? context.ShellPage.SlimContentPage.SelectedItems.Select(x => x.ItemPath).Aggregate((accum, current) => accum + "\n" + current) - : context.ShellPage.ShellViewModel.WorkingDirectory; + var path = context.ShellPage.ShellViewModel.WorkingDirectory; if (FtpHelpers.IsFtpPath(path)) path = path.Replace("\\", "/", StringComparison.Ordinal); diff --git a/src/Files.App/Actions/FileSystem/CopyPathWithQuotesAction.cs b/src/Files.App/Actions/FileSystem/CopyPathWithQuotesAction.cs index 378dff68b198..c5670beda199 100644 --- a/src/Files.App/Actions/FileSystem/CopyPathWithQuotesAction.cs +++ b/src/Files.App/Actions/FileSystem/CopyPathWithQuotesAction.cs @@ -10,19 +10,16 @@ internal sealed class CopyPathWithQuotesAction : IAction private readonly IContentPageContext context; public string Label - => "CopyPathWithQuotes".GetLocalizedResource(); + => Strings.CopyPathWithQuotes.GetLocalizedResource(); public string Description - => "CopyPathWithQuotesDescription".GetLocalizedResource(); + => Strings.CopyPathWithQuotesDescription.GetLocalizedResource(); public RichGlyph Glyph => new RichGlyph(themedIconStyle: "App.ThemedIcons.CopyAsPath"); - public HotKey HotKey - => new(Keys.C, KeyModifiers.CtrlAlt); - public bool IsExecutable - => context.HasSelection; + => context.PageType != ContentPageTypes.Home && context.PageType != ContentPageTypes.RecycleBin; public CopyPathWithQuotesAction() { @@ -33,10 +30,7 @@ public Task ExecuteAsync(object? parameter = null) { if (context.ShellPage?.SlimContentPage is not null) { - var selectedItems = context.ShellPage.SlimContentPage.SelectedItems; - var path = selectedItems is not null - ? string.Join("\n", selectedItems.Select(item => $"\"{item.ItemPath}\"")) - : context.ShellPage.ShellViewModel.WorkingDirectory; + var path = "\"" + context.ShellPage.ShellViewModel.WorkingDirectory + "\""; if (FtpHelpers.IsFtpPath(path)) path = path.Replace("\\", "/", StringComparison.Ordinal); diff --git a/src/Files.App/Data/Commands/Manager/CommandCodes.cs b/src/Files.App/Data/Commands/Manager/CommandCodes.cs index 79484215b1d8..54df5eaaa3b2 100644 --- a/src/Files.App/Data/Commands/Manager/CommandCodes.cs +++ b/src/Files.App/Data/Commands/Manager/CommandCodes.cs @@ -29,7 +29,9 @@ public enum CommandCodes // File System CopyItem, + CopyItemPath, CopyPath, + CopyItemPathWithQuotes, CopyPathWithQuotes, CutItem, PasteItem, diff --git a/src/Files.App/Data/Commands/Manager/CommandManager.cs b/src/Files.App/Data/Commands/Manager/CommandManager.cs index a217ecf33b16..2dcda76eaf63 100644 --- a/src/Files.App/Data/Commands/Manager/CommandManager.cs +++ b/src/Files.App/Data/Commands/Manager/CommandManager.cs @@ -81,7 +81,9 @@ public IRichCommand this[HotKey hotKey] public IRichCommand SetAsLockscreenBackground => commands[CommandCodes.SetAsLockscreenBackground]; public IRichCommand SetAsAppBackground => commands[CommandCodes.SetAsAppBackground]; public IRichCommand CopyItem => commands[CommandCodes.CopyItem]; + public IRichCommand CopyItemPath => commands[CommandCodes.CopyItemPath]; public IRichCommand CopyPath => commands[CommandCodes.CopyPath]; + public IRichCommand CopyItemPathWithQuotes => commands[CommandCodes.CopyItemPathWithQuotes]; public IRichCommand CopyPathWithQuotes => commands[CommandCodes.CopyPathWithQuotes]; public IRichCommand CutItem => commands[CommandCodes.CutItem]; public IRichCommand PasteItem => commands[CommandCodes.PasteItem]; @@ -273,7 +275,9 @@ public IEnumerator GetEnumerator() => [CommandCodes.SetAsLockscreenBackground] = new SetAsLockscreenBackgroundAction(), [CommandCodes.SetAsAppBackground] = new SetAsAppBackgroundAction(), [CommandCodes.CopyItem] = new CopyItemAction(), + [CommandCodes.CopyItemPath] = new CopyItemPathAction(), [CommandCodes.CopyPath] = new CopyPathAction(), + [CommandCodes.CopyItemPathWithQuotes] = new CopyItemPathWithQuotesAction(), [CommandCodes.CopyPathWithQuotes] = new CopyPathWithQuotesAction(), [CommandCodes.CutItem] = new CutItemAction(), [CommandCodes.PasteItem] = new PasteItemAction(), diff --git a/src/Files.App/Data/Commands/Manager/ICommandManager.cs b/src/Files.App/Data/Commands/Manager/ICommandManager.cs index 7f8b156cce97..8d215da50f1a 100644 --- a/src/Files.App/Data/Commands/Manager/ICommandManager.cs +++ b/src/Files.App/Data/Commands/Manager/ICommandManager.cs @@ -33,7 +33,9 @@ public interface ICommandManager : IEnumerable IRichCommand ToggleToolbar { get; } IRichCommand CopyItem { get; } + IRichCommand CopyItemPath { get; } IRichCommand CopyPath { get; } + IRichCommand CopyItemPathWithQuotes { get; } IRichCommand CopyPathWithQuotes { get; } IRichCommand CutItem { get; } IRichCommand PasteItem { get; } diff --git a/src/Files.App/Data/Factories/ContentPageContextFlyoutFactory.cs b/src/Files.App/Data/Factories/ContentPageContextFlyoutFactory.cs index ae5ccdc87359..57db349b7f07 100644 --- a/src/Files.App/Data/Factories/ContentPageContextFlyoutFactory.cs +++ b/src/Files.App/Data/Factories/ContentPageContextFlyoutFactory.cs @@ -459,7 +459,7 @@ public static List GetBaseItemMenuItems( IsPrimary = true, IsVisible = true, }.Build(), - new ContextMenuFlyoutItemViewModelBuilder(Commands.CopyPath) + new ContextMenuFlyoutItemViewModelBuilder(Commands.CopyItemPath) { IsVisible = UserSettingsService.GeneralSettingsService.ShowCopyPath && itemsSelected diff --git a/src/Files.App/Strings/en-US/Resources.resw b/src/Files.App/Strings/en-US/Resources.resw index b08160214dc8..03c9666346bd 100644 --- a/src/Files.App/Strings/en-US/Resources.resw +++ b/src/Files.App/Strings/en-US/Resources.resw @@ -126,6 +126,9 @@ Copy path with quotes + + Copy selected item path with quotes + Browse @@ -2391,11 +2394,17 @@ Copy item(s) to clipboard + Copy path of the current directory to the clipboard + + Copy path of selected items to the clipboard - + Copy path of selected items with quotes to the clipboard + + Copy path of the current directory with quotes to the clipboard + Cut item(s) to clipboard