From 558c24c1751c559854948b4257e606e00104a88f Mon Sep 17 00:00:00 2001 From: Oleg Shilo Date: Thu, 18 Apr 2024 20:28:38 +1000 Subject: [PATCH] #26: Is it possible to implement context menu for the same type of files? - Added support for single item multipart extension list as config folder name (e.g. `[png]` will be treated the same way as `png`) - Added 'Naming convention' section in the CLI help content. --- bin/shell-x.exe | Bin 76800 -> 79872 bytes shell-x/GenericExtensions.cs | 2 +- shell-x/Program.cs | 60 ++++++++++++++++++++++++----------- 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/bin/shell-x.exe b/bin/shell-x.exe index 6c0f3e5dcbd8572a65d3941def31263a39ef637c..6dd9fcb5d2a5248334a50f3adeb9ea39b3776574 100644 GIT binary patch delta 25261 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 x.Contains(",") && x.StartsWith("[") && x.EndsWith("]") ? x.Substring(1, x.Length - 2).Split(',') : null).Where(x => x != null).ToArray(); + return items.Select(x => !Globals.IsSpecialFolder(x) && x.StartsWith("[") && x.EndsWith("]") ? x.Substring(1, x.Length - 2).Split(',') : null).Where(x => x != null).ToArray(); } public static bool Matching(this string text, string pattern, bool ignoreCase = true) diff --git a/shell-x/Program.cs b/shell-x/Program.cs index 2ba2919..8a3d462 100644 --- a/shell-x/Program.cs +++ b/shell-x/Program.cs @@ -1,13 +1,10 @@ -using SharpShell; -using SharpShell.Attributes; -using SharpShell.SharpContextMenu; -using ShellX; -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; +using static System.Environment; using System.IO; using System.Linq; using System.Reflection; @@ -15,8 +12,11 @@ using System.Text; using System.Threading.Tasks; using System.Windows.Forms; -using static System.Environment; using static System.Windows.Forms.VisualStyles.VisualStyleElement; +using SharpShell; +using SharpShell.Attributes; +using SharpShell.SharpContextMenu; +using ShellX; class App { @@ -39,13 +39,13 @@ public static int Main(string[] args) File.WriteAllText(dir.PathJoin("02.separator"), ""); File.WriteAllText(dir.PathJoin("03.Show Info.c.cmd"), $"dir %*{NewLine}pause"); File.WriteAllText(dir.PathJoin("03.Show Path.c.ps1"), $"Write-Host \"File: $($args[0])\" \n" + - $"Write-Host -NoNewLine 'Press any key to continue...'; " + - $"$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');"); + $"Write-Host -NoNewLine 'Press any key to continue...'; " + + $"$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');"); File.WriteAllText(dir.PathJoin("04.separator"), ""); File.WriteAllText(dir.PathJoin("05.Shell-X configure.cmd"), $"explorer \"{ConfigDir}\""); Resources.logo.Save(dir.PathJoin("05.Shell-X configure.ico")); - dir = ConfigDir.PathJoin("[any]").EnsureDirectory(); + dir = ConfigDir.PathJoin(Globals.AnyPath).EnsureDirectory(); File.WriteAllText(dir.PathJoin("01.Shell-X configure.cmd"), $"explorer \"{ConfigDir}\""); Resources.logo.Save(dir.PathJoin("01.Shell-X configure.ico")); @@ -82,8 +82,6 @@ public static int Main(string[] args) Console.WriteLine("=================================================================="); // Console.WriteLine("-----------------------"); Console.WriteLine(); - Console.WriteLine($"{Assembly.GetExecutingAssembly().GetName().Name} [option]"); - Console.WriteLine(); Console.WriteLine($"Options:"); Console.WriteLine($" -open Opens configuration folder."); Console.WriteLine($" You can edit the context menus by changing the content of this folder"); @@ -92,6 +90,22 @@ public static int Main(string[] args) $" interact with the explorer."); Console.WriteLine($" -register|-r Registers shell extension server"); Console.WriteLine($" -unregister|-u Unregisters shell extension server"); + Console.WriteLine("-----------------------"); + Console.WriteLine(); + Console.WriteLine($"The naming convention for configuration folders:"); + Console.WriteLine($"Read more at https://github.com/oleg-shilo/shell-x/blob/master/README.md#how-it-works"); + Console.WriteLine(""); + Console.WriteLine($"- "); + Console.WriteLine($" Any selected file, whose extension is the same as the name of the folder (e.g. `txt`)."); + Console.WriteLine($"- [any]"); + Console.WriteLine($" Any selected path"); + Console.WriteLine($"- [file]"); + Console.WriteLine($" Any selected file"); + Console.WriteLine($"- [folder]"); + Console.WriteLine($" Any selected folder"); + Console.WriteLine($"- [,,..]"); + Console.WriteLine($" A selected file, whose extension is one of the comma-delimited values in the folder " + + $"name (e.g. `[png,bmp,jpeg]`)."); } return 0; @@ -139,6 +153,16 @@ public ContextMenuStrip CreateMenu() } } +class Globals +{ + public const string AnyPath = "[any]"; + public const string AnyFile = "[file]"; + public const string AnyFolder = "[folder]"; + + public static bool IsSpecialFolder(string path) + => path.Matching(AnyPath) || path.Matching(AnyFile) || path.Matching(AnyFolder); +} + [ComVisible(true)] // [COMServerAssociation(AssociationType.ClassOfExtension, ".dll", ".txt", ".cs")] [COMServerAssociation(AssociationType.AllFiles)] @@ -175,9 +199,9 @@ protected override bool CanShowMenu() Directory.Exists(path) || // always allow for folders as it is the only way to invoke shell-x config (single menu item) ConfiguredFileExtensions.Any(x => x.Matching(ext)) || ConfiguredFileExtensions.Any(x => Path.GetFileName(path).MatchingAsExpression(x)) || - ConfiguredFileExtensions.Any(x => x.Matching("[any]")) || - (ConfiguredFileExtensions.Any(x => x.Matching("[file]")) && path.IsFile()) || - (ConfiguredFileExtensions.Any(x => x.Matching("[folder]")) && path.IsDir()) || + ConfiguredFileExtensions.Any(x => x.Matching(Globals.AnyPath)) || + (ConfiguredFileExtensions.Any(x => x.Matching(Globals.AnyFile)) && path.IsFile()) || + (ConfiguredFileExtensions.Any(x => x.Matching(Globals.AnyFolder)) && path.IsDir()) || ConfiguredFileExtensions.ParseMultipleExt().Any(x => x != null ? x.Any(e => e.Matching(ext)) : false); } else @@ -198,9 +222,9 @@ protected override bool CanShowMenu() } if (this.SelectedItemPaths.Any()) - return ConfiguredFileExtensions.Any(x => x.Matching("[any]")); + return ConfiguredFileExtensions.Any(x => x.Matching(Globals.AnyPath)); else - return ConfiguredFileExtensions.Any(x => x.Matching("[folder]")); + return ConfiguredFileExtensions.Any(x => x.Matching(Globals.AnyFolder)); } return false; } @@ -222,7 +246,7 @@ protected override ContextMenuStrip CreateMenu() try { - if (ConfiguredFileExtensions.Any(x => x.Matching("[any]"))) + if (ConfiguredFileExtensions.Any(x => x.Matching(Globals.AnyPath))) { var extraItems = BuildMenuFrom(GetConfigDirForAny(), selectedItemPaths.ToArgumentsString()); items = items.Concat(extraItems).ToArray(); @@ -512,7 +536,7 @@ string GetConfigDirFor(string file) return match; } - string GetConfigDirForAny() => App.ConfigDir.PathJoin("[any]"); + string GetConfigDirForAny() => App.ConfigDir.PathJoin(Globals.AnyPath); string GetConfigDirByPath(string dir) => App.ConfigDir.PathJoin(dir); }