Skip to content

Commit aca294a

Browse files
authored
Feature: Added Terminal action to context menu (#15990)
1 parent c449eba commit aca294a

12 files changed

+124
-4
lines changed

src/Files.App/Actions/Open/OpenTerminalAction.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@ public virtual HotKey HotKey
2222
public RichGlyph Glyph
2323
=> new("\uE756");
2424

25-
public bool IsExecutable
25+
public virtual bool IsExecutable
2626
=> GetIsExecutable();
2727

28+
public virtual bool IsAccessibleGlobally
29+
=> true;
30+
2831
public OpenTerminalAction()
2932
{
3033
context = Ioc.Default.GetRequiredService<IContentPageContext>();
@@ -74,7 +77,7 @@ public Task ExecuteAsync(object? parameter = null)
7477
};
7578
}
7679

77-
protected string[] GetPaths()
80+
protected virtual string[] GetPaths()
7881
{
7982
if (context.HasSelection)
8083
{
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright (c) 2024 Files Community
2+
// Licensed under the MIT License. See the LICENSE.
3+
4+
namespace Files.App.Actions
5+
{
6+
internal sealed class OpenTerminalFromHomeAction : OpenTerminalAction
7+
{
8+
private IHomePageContext HomePageContext { get; } = Ioc.Default.GetRequiredService<IHomePageContext>();
9+
10+
public override string Label
11+
=> "OpenTerminal".GetLocalizedResource();
12+
13+
public override string Description
14+
=> "OpenTerminalDescription".GetLocalizedResource();
15+
16+
public override bool IsExecutable =>
17+
HomePageContext.IsAnyItemRightClicked &&
18+
HomePageContext.RightClickedItem is not null &&
19+
(HomePageContext.RightClickedItem is WidgetFileTagCardItem fileTagItem
20+
? fileTagItem.IsFolder
21+
: true) &&
22+
HomePageContext.RightClickedItem.Path is not null &&
23+
HomePageContext.RightClickedItem.Path != Constants.UserEnvironmentPaths.RecycleBinPath;
24+
25+
public override bool IsAccessibleGlobally
26+
=> false;
27+
28+
public override HotKey HotKey
29+
=> HotKey.None;
30+
31+
protected override string[] GetPaths()
32+
{
33+
if (HomePageContext.IsAnyItemRightClicked && HomePageContext.RightClickedItem?.Path is not null)
34+
return [HomePageContext.RightClickedItem.Path];
35+
36+
return [];
37+
}
38+
}
39+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright (c) 2024 Files Community
2+
// Licensed under the MIT License. See the LICENSE.
3+
4+
namespace Files.App.Actions
5+
{
6+
internal sealed class OpenTerminalFromSidebarAction : OpenTerminalAction
7+
{
8+
private ISidebarContext SidebarContext { get; } = Ioc.Default.GetRequiredService<ISidebarContext>();
9+
10+
public override string Label
11+
=> "OpenTerminal".GetLocalizedResource();
12+
13+
public override string Description
14+
=> "OpenTerminalDescription".GetLocalizedResource();
15+
16+
public override bool IsExecutable =>
17+
SidebarContext.IsItemRightClicked &&
18+
SidebarContext.RightClickedItem is not null &&
19+
SidebarContext.RightClickedItem.MenuOptions.ShowShellItems &&
20+
!SidebarContext.RightClickedItem.MenuOptions.ShowEmptyRecycleBin;
21+
22+
public override bool IsAccessibleGlobally
23+
=> false;
24+
25+
public override HotKey HotKey
26+
=> HotKey.None;
27+
28+
protected override string[] GetPaths()
29+
{
30+
if (SidebarContext.IsItemRightClicked && SidebarContext.RightClickedItem is not null)
31+
return [SidebarContext.RightClickedItem.Path];
32+
33+
return [];
34+
}
35+
}
36+
}

src/Files.App/Data/Commands/Manager/CommandCodes.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ public enum CommandCodes
108108
OpenSettings,
109109
OpenTerminal,
110110
OpenTerminalAsAdmin,
111+
OpenTerminalFromSidebar,
112+
OpenTerminalFromHome,
111113
OpenCommandPalette,
112114
EditInNotepad,
113115

src/Files.App/Data/Commands/Manager/CommandManager.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ public IRichCommand this[HotKey hotKey]
113113
public IRichCommand OpenSettings => commands[CommandCodes.OpenSettings];
114114
public IRichCommand OpenTerminal => commands[CommandCodes.OpenTerminal];
115115
public IRichCommand OpenTerminalAsAdmin => commands[CommandCodes.OpenTerminalAsAdmin];
116+
public IRichCommand OpenTerminalFromSidebar => commands[CommandCodes.OpenTerminalFromSidebar];
117+
public IRichCommand OpenTerminalFromHome => commands[CommandCodes.OpenTerminalFromHome];
116118
public IRichCommand OpenCommandPalette => commands[CommandCodes.OpenCommandPalette];
117119
public IRichCommand EditInNotepad => commands[CommandCodes.EditInNotepad];
118120
public IRichCommand LayoutDecreaseSize => commands[CommandCodes.LayoutDecreaseSize];
@@ -300,6 +302,8 @@ public IEnumerator<IRichCommand> GetEnumerator() =>
300302
[CommandCodes.OpenSettings] = new OpenSettingsAction(),
301303
[CommandCodes.OpenTerminal] = new OpenTerminalAction(),
302304
[CommandCodes.OpenTerminalAsAdmin] = new OpenTerminalAsAdminAction(),
305+
[CommandCodes.OpenTerminalFromSidebar] = new OpenTerminalFromSidebarAction(),
306+
[CommandCodes.OpenTerminalFromHome] = new OpenTerminalFromHomeAction(),
303307
[CommandCodes.OpenCommandPalette] = new OpenCommandPaletteAction(),
304308
[CommandCodes.EditInNotepad] = new EditInNotepadAction(),
305309
[CommandCodes.LayoutDecreaseSize] = new LayoutDecreaseSizeAction(),

src/Files.App/Data/Commands/Manager/ICommandManager.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ public interface ICommandManager : IEnumerable<IRichCommand>
9898
IRichCommand OpenSettings { get; }
9999
IRichCommand OpenTerminal { get; }
100100
IRichCommand OpenTerminalAsAdmin { get; }
101+
IRichCommand OpenTerminalFromSidebar { get; }
102+
IRichCommand OpenTerminalFromHome { get; }
101103
IRichCommand OpenCommandPalette { get; }
102104
IRichCommand EditInNotepad { get; }
103105

src/Files.App/Data/Factories/ContentPageContextFlyoutFactory.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,16 @@ public static List<ContextMenuFlyoutItemViewModel> GetBaseItemMenuItems(
578578
ShowItem = isDriveRoot,
579579
IsEnabled = false
580580
},
581+
new ContextMenuFlyoutItemViewModelBuilder(Commands.EditInNotepad).Build(),
582+
new ContextMenuFlyoutItemViewModel()
583+
{
584+
ItemType = ContextMenuFlyoutItemType.Separator,
585+
ShowItem = !itemsSelected && Commands.OpenTerminal.IsExecutable || areAllItemsFolders && Commands.OpenTerminal.IsExecutable
586+
},
587+
new ContextMenuFlyoutItemViewModelBuilder(Commands.OpenTerminal)
588+
{
589+
IsVisible = !itemsSelected && Commands.OpenTerminal.IsExecutable || areAllItemsFolders && Commands.OpenTerminal.IsExecutable
590+
}.Build(),
581591
// Shell extensions are not available on the FTP server or in the archive,
582592
// but following items are intentionally added because icons in the context menu will not appear
583593
// unless there is at least one menu item with an icon that is not an ThemedIconModel. (#12943)
@@ -590,7 +600,6 @@ public static List<ContextMenuFlyoutItemViewModel> GetBaseItemMenuItems(
590600
ShowInRecycleBin = true,
591601
ShowInSearchPage = true,
592602
},
593-
new ContextMenuFlyoutItemViewModelBuilder(Commands.EditInNotepad).Build(),
594603
new ContextMenuFlyoutItemViewModel()
595604
{
596605
Text = "Loading".GetLocalizedResource(),

src/Files.App/Data/Factories/ShellContextFlyoutHelper.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Func<string, bool> FilterMenuItems(bool showOpenMenu)
4545
Win32Helper.ExtractStringFromDLL("shell32.dll", 5385), // Unpin from Start
4646
Win32Helper.ExtractStringFromDLL("shell32.dll", 5386), // Pin to taskbar
4747
Win32Helper.ExtractStringFromDLL("shell32.dll", 5387), // Unpin from taskbar
48+
"{9F156763-7844-4DC4-B2B1-901F640F5155}", // Open in Terminal
4849
};
4950

5051
bool filterMenuItemsImpl(string menuItem) => !string.IsNullOrEmpty(menuItem)

src/Files.App/ViewModels/UserControls/SidebarViewModel.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,12 @@ private List<ContextMenuFlyoutItemViewModel> GetLocationItemMenuItems(INavigatio
10651065
ShowItem = options.ShowProperties
10661066
},
10671067
new ContextMenuFlyoutItemViewModel()
1068+
{
1069+
ItemType = ContextMenuFlyoutItemType.Separator,
1070+
ShowItem = Commands.OpenTerminalFromSidebar.IsExecutable
1071+
},
1072+
new ContextMenuFlyoutItemViewModelBuilder(Commands.OpenTerminalFromSidebar).Build(),
1073+
new ContextMenuFlyoutItemViewModel()
10681074
{
10691075
ItemType = ContextMenuFlyoutItemType.Separator,
10701076
Tag = "OverflowSeparator",

src/Files.App/ViewModels/UserControls/Widgets/DrivesWidgetViewModel.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,12 @@ public override List<ContextMenuFlyoutItemViewModel> GetItemMenuItems(WidgetCard
146146
Tag = "ManageBitLockerPlaceholder",
147147
IsEnabled = false
148148
},
149+
new ContextMenuFlyoutItemViewModel()
150+
{
151+
ItemType = ContextMenuFlyoutItemType.Separator,
152+
ShowItem = CommandManager.OpenTerminalFromHome.IsExecutable
153+
},
154+
new ContextMenuFlyoutItemViewModelBuilder(CommandManager.OpenTerminalFromHome).Build(),
149155
new()
150156
{
151157
ItemType = ContextMenuFlyoutItemType.Separator,

0 commit comments

Comments
 (0)