mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 03:07:56 +01:00
[File locksmith]Add setting to show only in extended context menu (#26711)
* [File Locksmith] Move File Locksmith "What's using this file?" into the extended context menu * [File Locksmith] Add FileLocksmithExt to directory background context menu * [File Locksmith] * Directory background right click crash fixed. *Settings added. * [File Locksmith] Remove uncessary things. * [File Locksmith] Spell check correction
This commit is contained in:
@@ -26,6 +26,9 @@
|
||||
</RegistryKey>
|
||||
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\Drive\ShellEx\ContextMenuHandlers\FileLocksmithExt">
|
||||
<RegistryValue Type="string" Value="{84D68575-E186-46AD-B0CB-BAEB45EE29C0}"/>
|
||||
</RegistryKey>
|
||||
<RegistryKey Root="$(var.RegistryScope)" Key="SOFTWARE\Classes\Directory\background\ShellEx\ContextMenuHandlers\FileLocksmithExt">
|
||||
<RegistryValue Type="string" Value="{84D68575-E186-46AD-B0CB-BAEB45EE29C0}"/>
|
||||
</RegistryKey>
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
|
||||
@@ -20,6 +20,9 @@ namespace constants::nonlocalizable
|
||||
// JSON key used to store whether the module is enabled
|
||||
constexpr WCHAR JsonKeyEnabled[] = L"Enabled";
|
||||
|
||||
// JSON key used to store extended menu enabled
|
||||
constexpr WCHAR JsonKeyShowInExtendedContextMenu[] = L"showInExtendedContextMenu";
|
||||
|
||||
// Path of the JSON file used to store settings
|
||||
constexpr WCHAR DataFilePath[] = L"\\file-locksmith-settings.json";
|
||||
|
||||
|
||||
@@ -69,14 +69,25 @@ IFACEMETHODIMP ExplorerCommand::GetCanonicalName(GUID* pguidCommandName)
|
||||
|
||||
IFACEMETHODIMP ExplorerCommand::GetState(IShellItemArray* psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE* pCmdState)
|
||||
{
|
||||
if (globals::enabled)
|
||||
{
|
||||
*pCmdState = ECS_ENABLED;
|
||||
}
|
||||
else
|
||||
if (!globals::enabled)
|
||||
{
|
||||
*pCmdState = ECS_HIDDEN;
|
||||
}
|
||||
|
||||
if (FileLocksmithSettingsInstance().GetShowInExtendedContextMenu())
|
||||
{
|
||||
*pCmdState = ECS_HIDDEN;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// When right clicking directory background, selection is empty.
|
||||
if (nullptr == psiItemArray)
|
||||
{
|
||||
*pCmdState = ECS_HIDDEN;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
*pCmdState = ECS_ENABLED;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -101,8 +112,16 @@ IFACEMETHODIMP ExplorerCommand::EnumSubCommands(IEnumExplorerCommand** ppEnum)
|
||||
|
||||
IFACEMETHODIMP ExplorerCommand::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject* pdtobj, HKEY hkeyProgID)
|
||||
{
|
||||
m_data_obj = pdtobj;
|
||||
m_data_obj->AddRef();
|
||||
if (!FileLocksmithSettingsInstance().GetEnabled())
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (pdtobj)
|
||||
{
|
||||
m_data_obj = pdtobj;
|
||||
m_data_obj->AddRef();
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -116,6 +135,11 @@ IFACEMETHODIMP ExplorerCommand::QueryContextMenu(HMENU hmenu, UINT indexMenu, UI
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (FileLocksmithSettingsInstance().GetShowInExtendedContextMenu() && !(uFlags & CMF_EXTENDEDVERBS))
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT hr = E_UNEXPECTED;
|
||||
if (m_data_obj && !(uFlags & (CMF_DEFAULTONLY | CMF_VERBSONLY | CMF_OPTIMIZEFORINVOKE)))
|
||||
{
|
||||
|
||||
@@ -62,7 +62,8 @@ public:
|
||||
PowerToysSettings::PowerToyValues values =
|
||||
PowerToysSettings::PowerToyValues::from_json_string(config, get_key());
|
||||
|
||||
// Currently, there are no settings, so we don't do anything.
|
||||
toggle_extended_only(values.get_bool_value(L"bool_show_extended_menu").value());
|
||||
save_settings();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
@@ -89,6 +90,18 @@ public:
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
virtual void toggle_extended_only(bool extended_only)
|
||||
{
|
||||
Logger::info(L"File Locksmith toggle extended only");
|
||||
m_extended_only = extended_only;
|
||||
save_settings();
|
||||
}
|
||||
|
||||
virtual bool is_extended_only()
|
||||
{
|
||||
return m_extended_only;
|
||||
}
|
||||
|
||||
virtual void destroy() override
|
||||
{
|
||||
delete this;
|
||||
@@ -96,10 +109,12 @@ public:
|
||||
|
||||
private:
|
||||
bool m_enabled;
|
||||
bool m_extended_only;
|
||||
|
||||
void init_settings()
|
||||
{
|
||||
m_enabled = FileLocksmithSettingsInstance().GetEnabled();
|
||||
m_extended_only = FileLocksmithSettingsInstance().GetShowInExtendedContextMenu();
|
||||
Trace::EnableFileLocksmith(m_enabled);
|
||||
}
|
||||
|
||||
@@ -107,6 +122,8 @@ private:
|
||||
{
|
||||
auto& settings = FileLocksmithSettingsInstance();
|
||||
settings.SetEnabled(m_enabled);
|
||||
settings.SetExtendedContextMenuOnly(m_extended_only);
|
||||
|
||||
settings.Save();
|
||||
Trace::EnableFileLocksmith(m_enabled);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ void FileLocksmithSettings::Save()
|
||||
json::JsonObject jsonData;
|
||||
|
||||
jsonData.SetNamedValue(constants::nonlocalizable::JsonKeyEnabled, json::value(settings.enabled));
|
||||
jsonData.SetNamedValue(constants::nonlocalizable::JsonKeyShowInExtendedContextMenu, json::value(settings.showInExtendedContextMenu));
|
||||
|
||||
json::to_file(jsonFilePath, jsonData);
|
||||
GetSystemTimeAsFileTime(&lastLoadedTime);
|
||||
@@ -70,6 +71,11 @@ void FileLocksmithSettings::ParseJson()
|
||||
{
|
||||
settings.enabled = jsonSettings.GetNamedBoolean(constants::nonlocalizable::JsonKeyEnabled);
|
||||
}
|
||||
|
||||
if (json::has(jsonSettings, constants::nonlocalizable::JsonKeyShowInExtendedContextMenu, json::JsonValueType::Boolean))
|
||||
{
|
||||
settings.showInExtendedContextMenu = jsonSettings.GetNamedBoolean(constants::nonlocalizable::JsonKeyShowInExtendedContextMenu);
|
||||
}
|
||||
}
|
||||
catch (const winrt::hresult_error&)
|
||||
{
|
||||
|
||||
@@ -25,6 +25,16 @@ public:
|
||||
Save();
|
||||
}
|
||||
|
||||
inline bool GetShowInExtendedContextMenu() const
|
||||
{
|
||||
return settings.showInExtendedContextMenu;
|
||||
}
|
||||
|
||||
inline void SetExtendedContextMenuOnly(bool extendedOnly)
|
||||
{
|
||||
settings.showInExtendedContextMenu = extendedOnly;
|
||||
}
|
||||
|
||||
void Save();
|
||||
void Load();
|
||||
|
||||
@@ -32,6 +42,7 @@ private:
|
||||
struct Settings
|
||||
{
|
||||
bool enabled{ true };
|
||||
bool showInExtendedContextMenu{ false };
|
||||
};
|
||||
|
||||
void Reload();
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Text.Json;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class FileLocksmithLocalProperties : ISettingsConfig
|
||||
{
|
||||
public FileLocksmithLocalProperties()
|
||||
{
|
||||
ExtendedContextMenuOnly = false;
|
||||
}
|
||||
|
||||
public bool ExtendedContextMenuOnly { get; set; }
|
||||
|
||||
public string ToJsonString()
|
||||
{
|
||||
return JsonSerializer.Serialize(this);
|
||||
}
|
||||
|
||||
// This function is required to implement the ISettingsConfig interface and obtain the settings configurations.
|
||||
public string GetModuleName()
|
||||
{
|
||||
string moduleName = FileLocksmithSettings.ModuleName;
|
||||
return moduleName;
|
||||
}
|
||||
|
||||
// This can be utilized in the future if the settings.json file is to be modified/deleted.
|
||||
public bool UpgradeSettingsConfiguration()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class FileLocksmithProperties
|
||||
{
|
||||
public FileLocksmithProperties()
|
||||
{
|
||||
ExtendedContextMenuOnly = new BoolProperty(false);
|
||||
}
|
||||
|
||||
[JsonPropertyName("bool_show_extended_menu")]
|
||||
public BoolProperty ExtendedContextMenuOnly { get; set; }
|
||||
|
||||
public override string ToString() => JsonSerializer.Serialize(this);
|
||||
}
|
||||
}
|
||||
49
src/settings-ui/Settings.UI.Library/FileLocksmithSettings.cs
Normal file
49
src/settings-ui/Settings.UI.Library/FileLocksmithSettings.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class FileLocksmithSettings : BasePTModuleSettings, ISettingsConfig
|
||||
{
|
||||
public const string ModuleName = "File Locksmith";
|
||||
public const string ModuleVersion = "1";
|
||||
|
||||
[JsonPropertyName("properties")]
|
||||
public FileLocksmithProperties Properties { get; set; }
|
||||
|
||||
public FileLocksmithSettings()
|
||||
{
|
||||
Name = ModuleName;
|
||||
Version = ModuleVersion;
|
||||
Properties = new FileLocksmithProperties();
|
||||
}
|
||||
|
||||
public FileLocksmithSettings(FileLocksmithLocalProperties localProperties)
|
||||
{
|
||||
if (localProperties == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(localProperties));
|
||||
}
|
||||
|
||||
Properties = new FileLocksmithProperties();
|
||||
Properties.ExtendedContextMenuOnly.Value = localProperties.ExtendedContextMenuOnly;
|
||||
Version = "1";
|
||||
Name = ModuleName;
|
||||
}
|
||||
|
||||
public string GetModuleName()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
public bool UpgradeSettingsConfiguration()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3309,6 +3309,19 @@ Activate by holding the key for the character you want to add an accent to, then
|
||||
<value>Enable File Locksmith</value>
|
||||
<comment>File Locksmith is the name of the utility</comment>
|
||||
</data>
|
||||
<data name="FileLocksmith_Toggle_StandardContextMenu.Content" xml:space="preserve">
|
||||
<value>Default and extended context menu</value>
|
||||
</data>
|
||||
<data name="FileLocksmith_Toggle_ExtendedContextMenu.Content" xml:space="preserve">
|
||||
<value>Extended context menu only</value>
|
||||
</data>
|
||||
<data name="FileLocksmith_Toggle_ContextMenu.Header" xml:space="preserve">
|
||||
<value>Show File Locksmith in</value>
|
||||
</data>
|
||||
<data name="FileLocksmith_ShellIntegration.Header" xml:space="preserve">
|
||||
<value>Shell integration</value>
|
||||
<comment>This refers to directly integrating in with Windows</comment>
|
||||
</data>
|
||||
<data name="GPO_IsSettingForced.Title" xml:space="preserve">
|
||||
<value>The system administrator is forcing this setting.</value>
|
||||
</data>
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
using global::PowerToys.GPOWrapper;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
|
||||
@@ -14,8 +16,18 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
{
|
||||
private GeneralSettings GeneralSettingsConfig { get; set; }
|
||||
|
||||
public FileLocksmithViewModel(ISettingsRepository<GeneralSettings> settingsRepository, Func<string, int> ipcMSGCallBackFunc)
|
||||
private readonly ISettingsUtils _settingsUtils;
|
||||
|
||||
private FileLocksmithSettings Settings { get; set; }
|
||||
|
||||
private const string ModuleName = FileLocksmithSettings.ModuleName;
|
||||
|
||||
private string _settingsConfigFileFolder = string.Empty;
|
||||
|
||||
public FileLocksmithViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, Func<string, int> ipcMSGCallBackFunc, string configFileSubfolder = "")
|
||||
{
|
||||
_settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils));
|
||||
|
||||
// To obtain the general settings configurations of PowerToys Settings.
|
||||
if (settingsRepository == null)
|
||||
{
|
||||
@@ -24,10 +36,29 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
|
||||
GeneralSettingsConfig = settingsRepository.SettingsConfig;
|
||||
|
||||
try
|
||||
{
|
||||
FileLocksmithLocalProperties localSettings = _settingsUtils.GetSettingsOrDefault<FileLocksmithLocalProperties>(GetSettingsSubPath(), "file-locksmith-settings.json");
|
||||
Settings = new FileLocksmithSettings(localSettings);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
FileLocksmithLocalProperties localSettings = new FileLocksmithLocalProperties();
|
||||
Settings = new FileLocksmithSettings(localSettings);
|
||||
_settingsUtils.SaveSettings(localSettings.ToJsonString(), GetSettingsSubPath(), "file-locksmith-settings.json");
|
||||
}
|
||||
|
||||
InitializeEnabledValue();
|
||||
|
||||
// set the callback functions value to hangle outgoing IPC message.
|
||||
SendConfigMSG = ipcMSGCallBackFunc;
|
||||
|
||||
_fileLocksmithEnabledOnContextExtendedMenu = Settings.Properties.ExtendedContextMenuOnly.Value;
|
||||
}
|
||||
|
||||
public string GetSettingsSubPath()
|
||||
{
|
||||
return _settingsConfigFileFolder + "\\" + ModuleName;
|
||||
}
|
||||
|
||||
private void InitializeEnabledValue()
|
||||
@@ -67,7 +98,27 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
SendConfigMSG(outgoing.ToString());
|
||||
|
||||
// TODO: Implement when this module has properties.
|
||||
// NotifyPropertyChanged();
|
||||
NotifySettingsChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool EnabledOnContextExtendedMenu
|
||||
{
|
||||
get
|
||||
{
|
||||
return _fileLocksmithEnabledOnContextExtendedMenu;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (value != _fileLocksmithEnabledOnContextExtendedMenu)
|
||||
{
|
||||
_fileLocksmithEnabledOnContextExtendedMenu = value;
|
||||
Settings.Properties.ExtendedContextMenuOnly.Value = value;
|
||||
OnPropertyChanged(nameof(EnabledOnContextExtendedMenu));
|
||||
|
||||
NotifySettingsChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,11 +128,23 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
get => _enabledStateIsGPOConfigured;
|
||||
}
|
||||
|
||||
private void NotifySettingsChanged()
|
||||
{
|
||||
// Using InvariantCulture as this is an IPC message
|
||||
SendConfigMSG(
|
||||
string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"{{ \"powertoys\": {{ \"{0}\": {1} }} }}",
|
||||
FileLocksmithSettings.ModuleName,
|
||||
JsonSerializer.Serialize(Settings)));
|
||||
}
|
||||
|
||||
private Func<string, int> SendConfigMSG { get; }
|
||||
|
||||
private GpoRuleConfigured _enabledGpoRuleConfiguration;
|
||||
private bool _enabledStateIsGPOConfigured;
|
||||
private bool _isFileLocksmithEnabled;
|
||||
private bool _fileLocksmithEnabledOnContextExtendedMenu;
|
||||
|
||||
public void RefreshEnabledState()
|
||||
{
|
||||
|
||||
@@ -30,6 +30,20 @@
|
||||
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
|
||||
Severity="Informational" />
|
||||
|
||||
<controls:SettingsGroup
|
||||
x:Uid="FileLocksmith_ShellIntegration"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsFileLocksmithEnabled}">
|
||||
<labs:SettingsExpander
|
||||
x:Uid="FileLocksmith_Toggle_ContextMenu"
|
||||
IsExpanded="True">
|
||||
<ComboBox
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
SelectedIndex="{x:Bind Mode=TwoWay, Path=ViewModel.EnabledOnContextExtendedMenu, Converter={StaticResource BoolToComboBoxIndexConverter}}">
|
||||
<ComboBoxItem x:Uid="FileLocksmith_Toggle_StandardContextMenu" />
|
||||
<ComboBoxItem x:Uid="FileLocksmith_Toggle_ExtendedContextMenu" />
|
||||
</ComboBox>
|
||||
</labs:SettingsExpander>
|
||||
</controls:SettingsGroup>
|
||||
</StackPanel>
|
||||
</controls:SettingsPageControl.ModuleContent>
|
||||
<controls:SettingsPageControl.PrimaryLinks>
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
public FileLocksmithPage()
|
||||
{
|
||||
var settingsUtils = new SettingsUtils();
|
||||
ViewModel = new FileLocksmithViewModel(SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage);
|
||||
ViewModel = new FileLocksmithViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage);
|
||||
DataContext = ViewModel;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user