Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions src/Files.App/Actions/FileSystem/PasteItemAsShortcutAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.

namespace Files.App.Actions
{
internal sealed class PasteItemAsShortcutAction : ObservableObject, IAction
{
private readonly IContentPageContext context;

public string Label
=> Strings.PasteShortcut.GetLocalizedResource();

public string Description
=> Strings.PasteShortcutDescription.GetLocalizedResource();

public RichGlyph Glyph
=> new(themedIconStyle: "App.ThemedIcons.Paste");

public bool IsExecutable
=> GetIsExecutable();

public PasteItemAsShortcutAction()
{
context = Ioc.Default.GetRequiredService<IContentPageContext>();

context.PropertyChanged += Context_PropertyChanged;
App.AppModel.PropertyChanged += AppModel_PropertyChanged;
}

public Task ExecuteAsync(object? parameter = null)
{
if (context.ShellPage is null)
return Task.CompletedTask;

string path = context.ShellPage.ShellViewModel.WorkingDirectory;
return UIFilesystemHelpers.PasteItemAsShortcutAsync(path, context.ShellPage);
}

public bool GetIsExecutable()
{
return
App.AppModel.IsPasteEnabled &&
context.PageType != ContentPageTypes.Home &&
context.PageType != ContentPageTypes.RecycleBin &&
context.PageType != ContentPageTypes.SearchResults;
}

private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName is nameof(IContentPageContext.PageType))
OnPropertyChanged(nameof(IsExecutable));
}

private void AppModel_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName is nameof(AppModel.IsPasteEnabled))
OnPropertyChanged(nameof(IsExecutable));
}
}
}
1 change: 1 addition & 0 deletions src/Files.App/Data/Commands/Manager/CommandCodes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public enum CommandCodes
CopyPathWithQuotes,
CutItem,
PasteItem,
PasteItemAsShortcut,
PasteItemToSelection,
DeleteItem,
DeleteItemPermanently,
Expand Down
2 changes: 2 additions & 0 deletions src/Files.App/Data/Commands/Manager/CommandManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public IRichCommand this[HotKey hotKey]
public IRichCommand CopyPathWithQuotes => commands[CommandCodes.CopyPathWithQuotes];
public IRichCommand CutItem => commands[CommandCodes.CutItem];
public IRichCommand PasteItem => commands[CommandCodes.PasteItem];
public IRichCommand PasteItemAsShortcut => commands[CommandCodes.PasteItemAsShortcut];
public IRichCommand PasteItemToSelection => commands[CommandCodes.PasteItemToSelection];
public IRichCommand DeleteItem => commands[CommandCodes.DeleteItem];
public IRichCommand DeleteItemPermanently => commands[CommandCodes.DeleteItemPermanently];
Expand Down Expand Up @@ -281,6 +282,7 @@ public IEnumerator<IRichCommand> GetEnumerator() =>
[CommandCodes.CopyPathWithQuotes] = new CopyPathWithQuotesAction(),
[CommandCodes.CutItem] = new CutItemAction(),
[CommandCodes.PasteItem] = new PasteItemAction(),
[CommandCodes.PasteItemAsShortcut] = new PasteItemAsShortcutAction(),
[CommandCodes.PasteItemToSelection] = new PasteItemToSelectionAction(),
[CommandCodes.DeleteItem] = new DeleteItemAction(),
[CommandCodes.DeleteItemPermanently] = new DeleteItemPermanentlyAction(),
Expand Down
1 change: 1 addition & 0 deletions src/Files.App/Data/Commands/Manager/ICommandManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public interface ICommandManager : IEnumerable<IRichCommand>
IRichCommand CopyPathWithQuotes { get; }
IRichCommand CutItem { get; }
IRichCommand PasteItem { get; }
IRichCommand PasteItemAsShortcut { get; }
IRichCommand PasteItemToSelection { get; }
IRichCommand DeleteItem { get; }
IRichCommand DeleteItemPermanently { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ public static List<ContextMenuFlyoutItemViewModel> GetBaseItemMenuItems(
IsPrimary = true,
IsVisible = true,
}.Build(),
new ContextMenuFlyoutItemViewModelBuilder(Commands.PasteItemAsShortcut).Build(),
new ContextMenuFlyoutItemViewModelBuilder(Commands.CopyItemPath)
{
IsVisible = UserSettingsService.GeneralSettingsService.ShowCopyPath
Expand Down
20 changes: 20 additions & 0 deletions src/Files.App/Helpers/UI/UIFilesystemHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,26 @@ public static async Task PasteItemAsync(string destinationPath, IShellPage assoc
}
}

public static async Task PasteItemAsShortcutAsync(string destinationPath, IShellPage associatedInstance)
{
FilesystemResult<DataPackageView> packageView = await FilesystemTasks.Wrap(() => Task.FromResult(Clipboard.GetContent()));
if (packageView.Result.Contains(StandardDataFormats.StorageItems))
{
var items = await packageView.Result.GetStorageItemsAsync();
foreach (IStorageItem item in items)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hishitetsu would it be better to use Parallel?

{
var fileName = FilesystemHelpers.GetShortcutNamingPreference(item.Name);
var filePath = Path.Combine(destinationPath ?? string.Empty, fileName);

if (!await FileOperationsHelpers.CreateOrUpdateLinkAsync(filePath, item.Path))
await HandleShortcutCannotBeCreated(fileName, item.Path);
}
}

if (associatedInstance is not null)
await associatedInstance.RefreshIfNoWatcherExistsAsync();
}

public static async Task<bool> RenameFileItemAsync(ListedItem item, string newName, IShellPage associatedInstance, bool showExtensionDialog = true)
{
if (item is AlternateStreamItem ads) // For alternate streams Name is not a substring ItemNameRaw
Expand Down
6 changes: 6 additions & 0 deletions src/Files.App/Strings/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,9 @@
<data name="Paste" xml:space="preserve">
<value>Paste</value>
</data>
<data name="PasteShortcut" xml:space="preserve">
<value>Paste shortcut</value>
</data>
<data name="BaseLayoutContextFlyoutNew.Label" xml:space="preserve">
<value>New</value>
</data>
Expand Down Expand Up @@ -2411,6 +2414,9 @@
<data name="PasteItemDescription" xml:space="preserve">
<value>Paste item(s) from clipboard to current folder</value>
</data>
<data name="PasteShortcutDescription" xml:space="preserve">
<value>Paste item(s) from clipboard to current folder as shortcuts</value>
</data>
<data name="PasteItemToSelectionDescription" xml:space="preserve">
<value>Paste item(s) from clipboard to selected folder</value>
</data>
Expand Down