Add Open in Notepad++ and static Windows shell verbs without embedding IContextMenu on right-click.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -34,6 +34,9 @@
|
||||
<Button Content="Open in Cursor" MinWidth="120" Height="32"
|
||||
Command="{Binding OpenSelectedInCursorCommand}"
|
||||
IsEnabled="{Binding CanOpenInCursor}" Margin="0,0,8,8"/>
|
||||
<Button Content="Open in Notepad++" MinWidth="140" Height="32"
|
||||
Command="{Binding OpenSelectedInNotepadPlusPlusCommand}"
|
||||
IsEnabled="{Binding CanOpenInCursor}" Margin="0,0,8,8"/>
|
||||
<Button Content="Stage" MinWidth="72" Height="32" Click="OnStage"
|
||||
IsEnabled="{Binding CanStage}" Margin="0,0,8,8"/>
|
||||
<Button Content="Unstage" MinWidth="72" Height="32" Click="OnUnstage"
|
||||
@@ -58,6 +61,8 @@
|
||||
<MenuItem Header="View diff" Click="OnDiff" IsEnabled="{Binding CanDiff}"/>
|
||||
<MenuItem Header="Open in Cursor" Command="{Binding OpenSelectedInCursorCommand}"
|
||||
IsEnabled="{Binding CanOpenInCursor}"/>
|
||||
<MenuItem Header="Open in Notepad++" Command="{Binding OpenSelectedInNotepadPlusPlusCommand}"
|
||||
IsEnabled="{Binding CanOpenInCursor}"/>
|
||||
<Separator/>
|
||||
<MenuItem Header="Stage" Click="OnStage" IsEnabled="{Binding CanStage}"/>
|
||||
<MenuItem Header="Unstage" Click="OnUnstage" IsEnabled="{Binding CanUnstage}"/>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<Window.Resources>
|
||||
<ContextMenu x:Key="FolderListContextMenu" x:Shared="false">
|
||||
<MenuItem Header="Open" Click="OnCtxOpen"/>
|
||||
<Separator/>
|
||||
<Separator Tag="ShellVerbAnchor" Visibility="Collapsed"/>
|
||||
<MenuItem Header="Cut" Command="{Binding CutCommand}"/>
|
||||
<MenuItem Header="Copy" Command="{Binding CopyCommand}"/>
|
||||
<MenuItem Header="Paste" Command="{Binding PasteCommand}"/>
|
||||
@@ -74,6 +74,8 @@
|
||||
Visibility="{Binding ShowOpenTerminal, Converter={StaticResource BoolVis}}"/>
|
||||
<MenuItem Header="Open in Cursor" Command="{Binding OpenInCursorCommand}"
|
||||
Visibility="{Binding ShowOpenInCursor, Converter={StaticResource BoolVis}}"/>
|
||||
<MenuItem Header="Open in Notepad++" Command="{Binding OpenInNotepadPlusPlusCommand}"
|
||||
Visibility="{Binding ShowOpenInNotepadPlusPlus, Converter={StaticResource BoolVis}}"/>
|
||||
<MenuItem Header="Add to Favorites" Click="OnAddFavorite"
|
||||
Visibility="{Binding ShowAddFavorite, Converter={StaticResource BoolVis}}"/>
|
||||
<MenuItem Header="Remove from Favorites" Click="OnRemoveFavorite"
|
||||
@@ -191,6 +193,8 @@
|
||||
IsEnabled="{Binding ShowOpenTerminal}"/>
|
||||
<MenuItem Header="Open in _Cursor" Command="{Binding OpenInCursorCommand}"
|
||||
IsEnabled="{Binding ShowOpenInCursor}"/>
|
||||
<MenuItem Header="Open in _Notepad++" Command="{Binding OpenInNotepadPlusPlusCommand}"
|
||||
IsEnabled="{Binding ShowOpenInNotepadPlusPlus}"/>
|
||||
</MenuItem>
|
||||
<MenuItem Header="_Recycle Bin">
|
||||
<MenuItem Header="_Open Recycle Bin" Click="OnOpenRecycleBin"/>
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
using Explorer.Domain;
|
||||
using Explorer.Domain.Abstractions;
|
||||
using Explorer.Presentation;
|
||||
using Explorer.Presentation.ViewModels;
|
||||
|
||||
@@ -651,6 +652,15 @@ public partial class MainWindow : Window
|
||||
if (sender is FrameworkElement { ContextMenu: { } menu })
|
||||
{
|
||||
menu.DataContext = DataContext;
|
||||
try
|
||||
{
|
||||
FillShellContextVerbs(menu);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Shell extras must not take down the Workbench menu.
|
||||
}
|
||||
|
||||
_ = FillRunProfileMenuAsync(menu);
|
||||
}
|
||||
}
|
||||
@@ -1364,6 +1374,66 @@ public partial class MainWindow : Window
|
||||
dlg.ShowDialog();
|
||||
}
|
||||
|
||||
private void FillShellContextVerbs(ContextMenu menu)
|
||||
{
|
||||
const string anchor = "ShellVerbAnchor";
|
||||
const string tagPrefix = "shell:";
|
||||
for (var i = menu.Items.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (menu.Items[i] is FrameworkElement { Tag: string tag }
|
||||
&& tag.StartsWith(tagPrefix, StringComparison.Ordinal))
|
||||
{
|
||||
menu.Items.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
var anchorItem = menu.Items.OfType<Separator>().FirstOrDefault(item => Equals(item.Tag, anchor));
|
||||
if (anchorItem is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var verbs = Vm.ListShellContextVerbs();
|
||||
anchorItem.Visibility = verbs.Count > 0 ? Visibility.Visible : Visibility.Collapsed;
|
||||
if (verbs.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var index = menu.Items.IndexOf(anchorItem) + 1;
|
||||
foreach (var verb in verbs)
|
||||
{
|
||||
menu.Items.Insert(index++, BuildShellMenuItem(verb));
|
||||
}
|
||||
}
|
||||
|
||||
private MenuItem BuildShellMenuItem(ShellContextVerb verb)
|
||||
{
|
||||
var item = new MenuItem { Header = verb.Label, Tag = "shell:" + verb.Id };
|
||||
if (verb.Children is { Count: > 0 })
|
||||
{
|
||||
foreach (var child in verb.Children)
|
||||
{
|
||||
item.Items.Add(BuildShellMenuItem(child));
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
item.Click += OnShellContextVerb;
|
||||
return item;
|
||||
}
|
||||
|
||||
private void OnShellContextVerb(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is not MenuItem { Tag: string tag } || !tag.StartsWith("shell:", StringComparison.Ordinal))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vm.InvokeShellContextVerb(tag["shell:".Length..]);
|
||||
}
|
||||
|
||||
private async Task FillRunProfileMenuAsync(ContextMenu menu)
|
||||
{
|
||||
var host = menu.Items.OfType<MenuItem>().FirstOrDefault(i => Equals(i.Tag, "RunProfileMenu"));
|
||||
|
||||
Reference in New Issue
Block a user