Skip to content

Commit

Permalink
Add menu sorting
Browse files Browse the repository at this point in the history
Add refresh, delete and save shortcut keys
Add environment variable support, only [exe]
Fix other bugs
  • Loading branch information
ikas-mc committed Apr 23, 2022
1 parent 7846482 commit 3b14b19
Show file tree
Hide file tree
Showing 11 changed files with 129 additions and 82 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
/7zContextMenu/7zContextMenuHost/CustomeExplorerCommand.zip
/ContextMenuCustom/build.bat
/build.bat
/ContextMenuCustom/ContextMenuCustomHost/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ public class MenuItem : BaseModel
private string _acceptExts;
private bool _acceptDirectory;
private bool _acceptFile;
private bool _acceptMultipleFiles;
private string _pathDelimiter;
private string _paramForMultipleFiles;
private int _acceptMultipleFilesFlag;
private int _index;

public string Title { get => _title; set => SetProperty(ref _title, value); }
public string Exe { get => _exe; set => SetProperty(ref _exe, value); }
Expand All @@ -32,11 +32,10 @@ public class MenuItem : BaseModel
public string AcceptExts { get => _acceptExts; set => SetProperty(ref _acceptExts, string.IsNullOrEmpty(value) ? value : value.ToLower()); }// to lower for match
public bool AcceptDirectory { get => _acceptDirectory; set => SetProperty(ref _acceptDirectory, value); }
public bool AcceptFile { get => _acceptFile; set => SetProperty(ref _acceptFile, value); }
public bool AcceptMultipleFiles { get => _acceptMultipleFiles; set => SetProperty(ref _acceptMultipleFiles, value); }
public int AcceptMultipleFilesFlag { get => _acceptMultipleFilesFlag; set => SetProperty(ref _acceptMultipleFilesFlag, value); }
public string PathDelimiter { get => _pathDelimiter; set => SetProperty(ref _pathDelimiter, value); }
public string ParamForMultipleFiles { get => _paramForMultipleFiles; set => SetProperty(ref _paramForMultipleFiles, value); }

public int Index { get => _index; set => SetProperty(ref _index, value); }
private static string NameToJsonKey(string name)
{
return name[0].ToString().ToLower() + name.Substring(1);
Expand All @@ -54,10 +53,10 @@ public static MenuItem ReadFromJson(string content)
AcceptExts = json.GetNamedString(NameToJsonKey(nameof(AcceptExts)), string.Empty),
AcceptDirectory = json.GetNamedBoolean(NameToJsonKey(nameof(AcceptDirectory)), false),
AcceptFile = json.GetNamedBoolean(NameToJsonKey(nameof(AcceptFile)), true),
AcceptMultipleFiles = json.GetNamedBoolean(NameToJsonKey(nameof(AcceptMultipleFiles)), false),
AcceptMultipleFilesFlag = (int)json.GetNamedNumber(NameToJsonKey(nameof(AcceptMultipleFilesFlag)), (int)MultipleFilesFlag.OFF),
PathDelimiter = json.GetNamedString(NameToJsonKey(nameof(PathDelimiter)), string.Empty),
ParamForMultipleFiles = json.GetNamedString(NameToJsonKey(nameof(ParamForMultipleFiles)), string.Empty),
Index = (int)json.GetNamedNumber(NameToJsonKey(nameof(Index)), 0),
};
return menu;
}
Expand All @@ -74,10 +73,10 @@ public static string WriteToJson(MenuItem content)
[NameToJsonKey(nameof(AcceptExts))] = JsonValue.CreateStringValue(content.AcceptExts ?? string.Empty),
[NameToJsonKey(nameof(AcceptDirectory))] = JsonValue.CreateBooleanValue(content.AcceptDirectory),
[NameToJsonKey(nameof(AcceptFile))] = JsonValue.CreateBooleanValue(content.AcceptFile),
[NameToJsonKey(nameof(AcceptMultipleFiles))] = JsonValue.CreateBooleanValue(content.AcceptMultipleFiles),
[NameToJsonKey(nameof(AcceptMultipleFilesFlag))] = JsonValue.CreateNumberValue(content.AcceptMultipleFilesFlag),
[NameToJsonKey(nameof(PathDelimiter))] = JsonValue.CreateStringValue(content.PathDelimiter ?? string.Empty),
[NameToJsonKey(nameof(ParamForMultipleFiles))] = JsonValue.CreateStringValue(content.ParamForMultipleFiles ?? string.Empty),
[NameToJsonKey(nameof(Index))] = JsonValue.CreateNumberValue(content.Index),
};
return json.Stringify();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public async Task<List<MenuItem>> QueryAllAsync()
Debug.WriteLine(e.StackTrace);
}
}

result.Sort((l,r)=>l.Index-r.Index);
return result;
}

Expand Down
48 changes: 39 additions & 9 deletions ContextMenuCustom/ContextMenuCustomApp/View/Menu/MenuPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
x:Name="CommandList"
Grid.Row="1"
Grid.Column="0"
CanDragItems="False"
DragItemsCompleted="CommandList_DragItemsCompleted"
AllowDrop="False"
CanReorderItems="False"
ItemsSource="{Binding MenuItems}"
SelectionMode="Single">
<ListView.ItemTemplate>
Expand Down Expand Up @@ -79,7 +83,11 @@
HorizontalAlignment="Left"
VerticalAlignment="Center"
Click="Refresh_Click"
ToolTipService.ToolTip="Refresh menus">
ToolTipService.ToolTip="Refresh menus"
>
<Button.KeyboardAccelerators>
<KeyboardAccelerator Key="F5" />
</Button.KeyboardAccelerators>
<SymbolIcon Symbol="Refresh" />
</Button>
<Button
Expand Down Expand Up @@ -163,13 +171,27 @@

<controls:SettingItem Header="Title">
<controls:SettingItem.ActionContent>
<TextBox PlaceholderText="open with notepad" Text="{Binding Title, Mode=TwoWay}" />
<TextBox PlaceholderText="open with notepad" Text="{Binding Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</controls:SettingItem.ActionContent>
</controls:SettingItem>

<controls:SettingItem Header="Order">
<controls:SettingItem.ActionContent>
<muxc:NumberBox
Maximum="999999"
Minimum="-999999"
PlaceholderText="0"
SmallChange="1"
LargeChange="10"
SpinButtonPlacementMode="Inline"
Value="{Binding Index, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</controls:SettingItem.ActionContent>
</controls:SettingItem>

<controls:SettingItem Header="Exe">
<controls:SettingItem.ActionContent>
<TextBox PlaceholderText="&quot;C:\Windows\notepad.exe&quot;" Text="{Binding Exe, Mode=TwoWay}" />
<TextBox PlaceholderText="&quot;C:\Windows\notepad.exe&quot;"
Text="{Binding Exe, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</controls:SettingItem.ActionContent>

<controls:SettingItem.RightContent>
Expand All @@ -187,14 +209,16 @@

<controls:SettingItem Header="Param">
<controls:SettingItem.ActionContent>
<TextBox PlaceholderText="&quot;{path}&quot;" Text="{Binding Param, Mode=TwoWay}" />
<TextBox PlaceholderText="&quot;{path}&quot;"
Text="{Binding Param, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</controls:SettingItem.ActionContent>
</controls:SettingItem>


<controls:SettingItem Header="Icon">
<controls:SettingItem.ActionContent>
<TextBox PlaceholderText="&quot;c:\some\icon.icon&quot;" Text="{Binding Icon, Mode=TwoWay}" />
<TextBox PlaceholderText="&quot;c:\some\icon.icon&quot;"
Text="{Binding Icon, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</controls:SettingItem.ActionContent>
</controls:SettingItem>

Expand All @@ -212,7 +236,7 @@
<TextBox
Header="File Extensions"
PlaceholderText=".txt .zip or *"
Text="{Binding AcceptExts, Mode=TwoWay}"
Text="{Binding AcceptExts, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Visibility="{Binding AcceptFile}" />

</controls:SettingItem.BottomContent>
Expand Down Expand Up @@ -246,15 +270,15 @@
Grid.Row="8"
Header="Path Delimiter"
PlaceholderText="|"
Text="{Binding PathDelimiter, Mode=TwoWay}"
Text="{Binding PathDelimiter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Visibility="{Binding AcceptMultipleFilesFlag, Converter={StaticResource EqualsVisibilityConverter}, ConverterParameter=2}" />

<TextBox
Grid.Row="9"
Margin="0,8,0,0"
Header="Param"
PlaceholderText="{}{path}"
Text="{Binding ParamForMultipleFiles, Mode=TwoWay}"
Text="{Binding ParamForMultipleFiles, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Visibility="{Binding AcceptMultipleFilesFlag, Converter={StaticResource EqualsVisibilityConverter}, ConverterParameter=2}" />

</StackPanel>
Expand Down Expand Up @@ -292,7 +316,6 @@
HorizontalAlignment="Right"
Orientation="Horizontal">


<Button
Margin="4,0"
Padding="4"
Expand All @@ -301,6 +324,10 @@
Click="Save_Click"
ToolTipService.ToolTip="Save menu">
<SymbolIcon Symbol="Save" />
<Button.KeyboardAccelerators>
<KeyboardAccelerator Modifiers="Control"
Key="S" />
</Button.KeyboardAccelerators>
</Button>

<Button
Expand All @@ -310,6 +337,9 @@
VerticalAlignment="Center"
Click="Delete_Click"
ToolTipService.ToolTip="Delete menu">
<Button.KeyboardAccelerators>
<KeyboardAccelerator Key="Delete" />
</Button.KeyboardAccelerators>
<SymbolIcon Symbol="Delete" />
</Button>

Expand Down
10 changes: 10 additions & 0 deletions ContextMenuCustom/ContextMenuCustomApp/View/Menu/MenuPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ protected override void OnNavigatedTo(NavigationEventArgs e)

private async void Refresh_Click(object sender, RoutedEventArgs e)
{
var selectedItem = CommandList.SelectedItem as MenuItem;
await _viewModel.LoadAsync();
if (null != selectedItem?.File)
{
CommandList.SelectedItem = _viewModel.MenuItems.FirstOrDefault(item => Equals(selectedItem.File.Path, item.File.Path));
}
}

private void Add_Click(object sender, RoutedEventArgs e)
Expand Down Expand Up @@ -117,5 +122,10 @@ private void BuildCacheTipButton_Click(object sender, RoutedEventArgs e)
_viewModel.UpdateCacheTime();
CacheTip.IsOpen = true;
}

private void CommandList_DragItemsCompleted(Windows.UI.Xaml.Controls.ListViewBase sender, Windows.UI.Xaml.Controls.DragItemsCompletedEventArgs args)
{

}
}
}
99 changes: 50 additions & 49 deletions ContextMenuCustom/ContextMenuCustomHost/CustomExplorerCommand.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "pch.h"
#include "CustomExplorerCommand.h"
#include "CustomSubExplorerCommand.h"
#include "CustomExplorerCommandEnum.h"
#include "CustomSubExplorerCommand.h"
#include <winrt/base.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Data.Json.h>
Expand All @@ -17,7 +17,7 @@ using namespace winrt::Windows::Storage;
using namespace winrt::Windows::Data::Json;
using namespace std::filesystem;

CustomExplorerCommand::CustomExplorerCommand(){
CustomExplorerCommand::CustomExplorerCommand() {
}

const EXPCMDFLAGS CustomExplorerCommand::Flags() { return ECF_HASSUBCOMMANDS; }
Expand Down Expand Up @@ -49,7 +49,6 @@ const wchar_t* CustomExplorerCommand::GetIconId()
}

IFACEMETHODIMP CustomExplorerCommand::GetState(_In_opt_ IShellItemArray* selection, _In_ BOOL okToBeSlow, _Out_ EXPCMDSTATE* cmdState) {
HRESULT hr;

if (m_site)
{
Expand All @@ -68,60 +67,57 @@ IFACEMETHODIMP CustomExplorerCommand::GetState(_In_opt_ IShellItemArray* selecti
if (StrCmp(szWndClassName, L"NamespaceTreeControl"))
{
*cmdState = ECS_HIDDEN;
return S_OK;
return S_OK;
}
}
}

if (okToBeSlow)
if (!okToBeSlow)
{
if (selection) {
DWORD count;
selection->GetCount(&count);
if (count > 1) {
std::wstring currentPath;
ReadCommands(true, currentPath);
}
else {
auto currentPath = PathHelper::getPath(selection);
ReadCommands(false, currentPath);
}
*cmdState = ECS_DISABLED;
return E_PENDING;
}

if (selection) {
DWORD count;
selection->GetCount(&count);
if (count > 1) {
std::wstring currentPath;
ReadCommands(true, currentPath);
}
else {
std::wstring currentPath;
//fix right click on desktop
//https://github.com/microsoft/terminal/blob/main/src/cascadia/ShellExtension/OpenTerminalHere.cpp
auto hwnd = ::GetForegroundWindow();
if (hwnd)
auto currentPath = PathHelper::getPath(selection);
ReadCommands(false, currentPath);
}
}
else {
std::wstring currentPath;
//fix right click on desktop
//https://github.com/microsoft/terminal/blob/main/src/cascadia/ShellExtension/OpenTerminalHere.cpp
auto hwnd = ::GetForegroundWindow();
if (hwnd)
{
TCHAR szName[MAX_PATH] = { 0 };
::GetClassName(hwnd, szName, MAX_PATH);
if (0 == StrCmp(szName, L"WorkerW") ||
0 == StrCmp(szName, L"Progman"))
{
TCHAR szName[MAX_PATH] = { 0 };
::GetClassName(hwnd, szName, MAX_PATH);
if (0 == StrCmp(szName, L"WorkerW") ||
0 == StrCmp(szName, L"Progman"))
//special folder: desktop
auto hr = ::SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, szName);
if (SUCCEEDED(hr))
{
//special folder: desktop
hr = ::SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, szName);
if (SUCCEEDED(hr))
{
currentPath= szName;
}
currentPath = szName;
}
}

ReadCommands(false, currentPath);
}
ReadCommands(false, currentPath);
}

if (m_commands.size() == 0) {
*cmdState = ECS_HIDDEN;
}
else {
*cmdState = ECS_ENABLED;
}
if (m_commands.size() == 0) {
*cmdState = ECS_HIDDEN;
}
else
{
*cmdState = ECS_DISABLED;
hr = E_PENDING;
else {
*cmdState = ECS_ENABLED;
}

return S_OK;
Expand All @@ -134,23 +130,23 @@ IFACEMETHODIMP CustomExplorerCommand::EnumSubCommands(__RPC__deref_out_opt IEnum
return customCommands->QueryInterface(IID_PPV_ARGS(enumCommands));
}

void CustomExplorerCommand::ReadCommands(bool multipeFiles,const std::wstring& currentPath)
void CustomExplorerCommand::ReadCommands(bool multipleFiles, const std::wstring& currentPath)
{
auto menus = winrt::Windows::Storage::ApplicationData::Current().LocalSettings().CreateContainer(L"menus", ApplicationDataCreateDisposition::Always).Values();
if (menus.Size() > 0) {
std::wstring ext;
bool isDirectory = true; //TODO current_path may be empty when right click on desktop. set directory as default?
if (!multipeFiles) {
if (!multipleFiles) {
PathHelper::getExt(currentPath, isDirectory, ext);
}

auto current = menus.begin();
do {
if (current.HasCurrent()) {
auto conent=winrt::unbox_value_or<winrt::hstring>(current.Current().Value(), L"");
auto conent = winrt::unbox_value_or<winrt::hstring>(current.Current().Value(), L"");
if (conent.size() > 0) {
const auto command = Make<CustomSubExplorerCommand>(conent);
if (command->Accept(multipeFiles,isDirectory, ext)) {
if (command->Accept(multipleFiles, isDirectory, ext)) {
m_commands.push_back(command);
}
}
Expand All @@ -166,7 +162,7 @@ void CustomExplorerCommand::ReadCommands(bool multipeFiles,const std::wstring& c
if (exists(folder) && is_directory(folder)) {
std::wstring ext;
bool isDirectory = true; //TODO current_path may be empty when right click on desktop. set directory as default?
if (!multipeFiles) {
if (!multipleFiles) {
PathHelper::getExt(currentPath, isDirectory, ext);
}

Expand All @@ -177,11 +173,16 @@ void CustomExplorerCommand::ReadCommands(bool multipeFiles,const std::wstring& c
buffer << fs.rdbuf();//TODO
auto content = winrt::to_hstring(buffer.str());
auto command = Make<CustomSubExplorerCommand>(content);
if (command->Accept(multipeFiles,isDirectory, ext)) {
if (command->Accept(multipleFiles, isDirectory, ext)) {
m_commands.push_back(command);
}
}
}
}).wait();
}

if (m_commands.size() > 1) {
std::sort(m_commands.begin(), m_commands.end(), [](auto&& l, auto&& r) { return l->m_index < r->m_index; });
}

}
Loading

0 comments on commit 3b14b19

Please sign in to comment.