[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:
gokcekantarci
2023-06-14 12:06:44 +03:00
committed by GitHub
parent a780e6ae72
commit 293b06d083
13 changed files with 273 additions and 11 deletions

View File

@@ -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>

View File

@@ -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";

View File

@@ -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)))
{

View File

@@ -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);
}

View File

@@ -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&)
{

View File

@@ -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();

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}

View 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;
}
}
}

View File

@@ -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>

View File

@@ -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()
{

View File

@@ -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>

View File

@@ -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();
}