Merge branch 'master' into dev/crutkas/buildFarmVersioningTake3

This commit is contained in:
Clint Rutkas
2020-10-20 15:58:08 -07:00
committed by GitHub
950 changed files with 102910 additions and 14004 deletions

View File

@@ -53,11 +53,12 @@ namespace UnitTestsCommonLib
private:
const std::wstring m_json = L"{\"name\":\"Module Name\",\"properties\" : {\"bool_toggle_true\":{\"value\":true},\"bool_toggle_false\":{\"value\":false},\"color_picker\" : {\"value\":\"#ff8d12\"},\"int_spinner\" : {\"value\":10},\"string_text\" : {\"value\":\"a quick fox\"}},\"version\" : \"1.0\" }";
const std::wstring m_moduleName = L"Module Name";
const std::wstring m_moduleKey = L"Module Key";
public:
TEST_METHOD (LoadFromJsonBoolTrue)
{
PowerToyValues values = PowerToyValues::from_json_string(m_json);
PowerToyValues values = PowerToyValues::from_json_string(m_json, m_moduleKey);
auto value = values.get_bool_value(L"bool_toggle_true");
Assert::IsTrue(value.has_value());
Assert::AreEqual(true, *value);
@@ -65,7 +66,7 @@ namespace UnitTestsCommonLib
TEST_METHOD (LoadFromJsonBoolFalse)
{
PowerToyValues values = PowerToyValues::from_json_string(m_json);
PowerToyValues values = PowerToyValues::from_json_string(m_json, m_moduleKey);
auto value = values.get_bool_value(L"bool_toggle_false");
Assert::IsTrue(value.has_value());
Assert::AreEqual(false, *value);
@@ -73,7 +74,7 @@ namespace UnitTestsCommonLib
TEST_METHOD (LoadFromJsonInt)
{
PowerToyValues values = PowerToyValues::from_json_string(m_json);
PowerToyValues values = PowerToyValues::from_json_string(m_json, m_moduleKey);
auto value = values.get_int_value(L"int_spinner");
Assert::IsTrue(value.has_value());
Assert::AreEqual(10, *value);
@@ -81,7 +82,7 @@ namespace UnitTestsCommonLib
TEST_METHOD (LoadFromJsonString)
{
PowerToyValues values = PowerToyValues::from_json_string(m_json);
PowerToyValues values = PowerToyValues::from_json_string(m_json, m_moduleKey);
auto value = values.get_string_value(L"string_text");
Assert::IsTrue(value.has_value());
@@ -91,7 +92,7 @@ namespace UnitTestsCommonLib
TEST_METHOD (LoadFromJsonColorPicker)
{
PowerToyValues values = PowerToyValues::from_json_string(m_json);
PowerToyValues values = PowerToyValues::from_json_string(m_json, m_moduleKey);
auto value = values.get_string_value(L"color_picker");
Assert::IsTrue(value.has_value());
@@ -101,19 +102,19 @@ namespace UnitTestsCommonLib
TEST_METHOD (LoadFromEmptyString)
{
auto func = [] { PowerToyValues values = PowerToyValues::from_json_string(L""); };
auto func = [] { PowerToyValues values = PowerToyValues::from_json_string(L"", L"Module Key"); };
Assert::ExpectException<winrt::hresult_error>(func);
}
TEST_METHOD (LoadFromInvalidString_NameMissed)
{
auto func = [] { PowerToyValues values = PowerToyValues::from_json_string(L"{\"properties\" : {\"bool_toggle_true\":{\"value\":true},\"bool_toggle_false\":{\"value\":false},\"color_picker\" : {\"value\":\"#ff8d12\"},\"int_spinner\" : {\"value\":10},\"string_text\" : {\"value\":\"a quick fox\"}},\"version\" : \"1.0\" }"); };
auto func = [] { PowerToyValues values = PowerToyValues::from_json_string(L"{\"properties\" : {\"bool_toggle_true\":{\"value\":true},\"bool_toggle_false\":{\"value\":false},\"color_picker\" : {\"value\":\"#ff8d12\"},\"int_spinner\" : {\"value\":10},\"string_text\" : {\"value\":\"a quick fox\"}},\"version\" : \"1.0\" }", L"Module Key"); };
Assert::ExpectException<winrt::hresult_error>(func);
}
TEST_METHOD (LoadFromInvalidString_VersionMissed)
{
PowerToyValues values = PowerToyValues::from_json_string(L"{\"name\":\"Module Name\",\"properties\" : {}}");
PowerToyValues values = PowerToyValues::from_json_string(L"{\"name\":\"Module Name\",\"properties\" : {}}", L"Module Key");
const std::wstring expectedStr = L"{\"name\" : \"Module Name\", \"properties\" : {},\"version\" : \"1.0\"}";
const auto expected = json::JsonObject::Parse(expectedStr);
const auto actual = json::JsonObject::Parse(values.serialize());
@@ -123,7 +124,7 @@ namespace UnitTestsCommonLib
TEST_METHOD (LoadFromInvalidString_PropertiesMissed)
{
PowerToyValues values = PowerToyValues::from_json_string(L"{\"name\":\"Module Name\",\"version\" : \"1.0\" }");
PowerToyValues values = PowerToyValues::from_json_string(L"{\"name\":\"Module Name\",\"version\" : \"1.0\" }", L"Module Key");
const std::wstring expectedStr = L"{\"name\":\"Module Name\",\"version\" : \"1.0\" }";
const auto expected = json::JsonObject::Parse(expectedStr);
const auto actual = json::JsonObject::Parse(values.serialize());
@@ -133,7 +134,7 @@ namespace UnitTestsCommonLib
TEST_METHOD (LoadFromValidString_EmptyProperties)
{
PowerToyValues values = PowerToyValues::from_json_string(L"{\"name\":\"Module Name\",\"properties\" : {}, \"version\" : \"1.0\" }");
PowerToyValues values = PowerToyValues::from_json_string(L"{\"name\":\"Module Name\",\"properties\" : {}, \"version\" : \"1.0\" }", L"Module Key");
const std::wstring expectedStr = L"{\"name\":\"Module Name\",\"properties\" : {},\"version\" : \"1.0\" }";
const auto expected = json::JsonObject::Parse(expectedStr);
const auto actual = json::JsonObject::Parse(values.serialize());
@@ -143,7 +144,7 @@ namespace UnitTestsCommonLib
TEST_METHOD (LoadFromValidString_ChangedVersion)
{
PowerToyValues values = PowerToyValues::from_json_string(L"{\"name\":\"Module Name\",\"properties\" : {},\"version\" : \"2.0\"}");
PowerToyValues values = PowerToyValues::from_json_string(L"{\"name\":\"Module Name\",\"properties\" : {},\"version\" : \"2.0\"}", L"Module Key");
const std::wstring expectedStr = L"{\"name\" : \"Module Name\", \"properties\" : {},\"version\" : \"1.0\"}"; //version from input json is ignored
const auto expected = json::JsonObject::Parse(expectedStr);
@@ -154,7 +155,7 @@ namespace UnitTestsCommonLib
TEST_METHOD (CreateWithName)
{
PowerToyValues values(m_moduleName);
PowerToyValues values(m_moduleName, m_moduleKey);
const std::wstring expectedStr = L"{\"name\":\"Module Name\",\"properties\" : {},\"version\" : \"1.0\" }";
const auto expected = json::JsonObject::Parse(expectedStr);
@@ -165,7 +166,7 @@ namespace UnitTestsCommonLib
TEST_METHOD (AddPropertyBoolPositive)
{
PowerToyValues values(m_moduleName);
PowerToyValues values(m_moduleName, m_moduleKey);
values.add_property<bool>(L"positive_bool_value", true);
auto value = values.get_bool_value(L"positive_bool_value");
@@ -175,7 +176,7 @@ namespace UnitTestsCommonLib
TEST_METHOD (AddPropertyBoolNegative)
{
PowerToyValues values(m_moduleName);
PowerToyValues values(m_moduleName, m_moduleKey);
values.add_property<bool>(L"negative_bool_value", false);
auto value = values.get_bool_value(L"negative_bool_value");
@@ -185,7 +186,7 @@ namespace UnitTestsCommonLib
TEST_METHOD (AddPropertyIntPositive)
{
PowerToyValues values(m_moduleName);
PowerToyValues values(m_moduleName, m_moduleKey);
const int intVal = 4392854;
values.add_property<int>(L"integer", intVal);
@@ -196,7 +197,7 @@ namespace UnitTestsCommonLib
TEST_METHOD (AddPropertyIntNegative)
{
PowerToyValues values(m_moduleName);
PowerToyValues values(m_moduleName, m_moduleKey);
const int intVal = -4392854;
values.add_property<int>(L"integer", intVal);
@@ -207,7 +208,7 @@ namespace UnitTestsCommonLib
TEST_METHOD (AddPropertyIntZero)
{
PowerToyValues values(m_moduleName);
PowerToyValues values(m_moduleName, m_moduleKey);
const int intVal = 0;
values.add_property<int>(L"integer", intVal);
@@ -218,7 +219,7 @@ namespace UnitTestsCommonLib
TEST_METHOD (AddPropertyStringEmpty)
{
PowerToyValues values(m_moduleName);
PowerToyValues values(m_moduleName, m_moduleKey);
const std::wstring stringVal = L"";
values.add_property<std::wstring>(L"stringval", stringVal);
@@ -229,7 +230,7 @@ namespace UnitTestsCommonLib
TEST_METHOD (AddPropertyString)
{
PowerToyValues values(m_moduleName);
PowerToyValues values(m_moduleName, m_moduleKey);
const std::wstring stringVal = L"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
values.add_property<std::wstring>(L"stringval", stringVal);
@@ -240,7 +241,7 @@ namespace UnitTestsCommonLib
TEST_METHOD (AddPropertyJsonEmpty)
{
PowerToyValues values(m_moduleName);
PowerToyValues values(m_moduleName, m_moduleKey);
const auto json = json::JsonObject();
values.add_property<json::JsonObject>(L"jsonval", json);
@@ -251,7 +252,7 @@ namespace UnitTestsCommonLib
TEST_METHOD (AddPropertyJsonObject)
{
PowerToyValues values(m_moduleName);
PowerToyValues values(m_moduleName, m_moduleKey);
const auto json = json::JsonObject::Parse(m_json);
values.add_property<json::JsonObject>(L"jsonval", json);

View File

@@ -60,7 +60,10 @@ LRESULT __clrcall KeyboardHook::HookProc(int nCode, WPARAM wParam, LPARAM lParam
KeyboardEvent ^ ev = gcnew KeyboardEvent();
ev->message = wParam;
ev->key = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam)->vkCode;
if (filterKeyboardEvent != nullptr && !filterKeyboardEvent->Invoke(ev))
ev->dwExtraInfo = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam)->dwExtraInfo;
// Ignore the keyboard hook if the FilterkeyboardEvent returns false.
if ((filterKeyboardEvent != nullptr && !filterKeyboardEvent->Invoke(ev)))
{
return CallNextHookEx(hookHandle, nCode, wParam, lParam);
}

View File

@@ -1,5 +1,7 @@
#pragma once
#include <cinttypes>
using namespace System::Threading;
using namespace System::Collections::Generic;
@@ -10,6 +12,7 @@ public
{
WPARAM message;
int key;
uint64_t dwExtraInfo;
};
public

View File

@@ -98,6 +98,8 @@
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<MultiProcessorCompilation Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</MultiProcessorCompilation>
<MultiProcessorCompilation Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</MultiProcessorCompilation>
<TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</TreatWarningAsError>
<TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>

View File

@@ -27,7 +27,7 @@ std::vector<DWORD> LayoutMap::GetKeyCodeList(const bool isShortcut)
return impl->GetKeyCodeList(isShortcut);
}
std::vector<std::wstring> LayoutMap::GetKeyNameList(const bool isShortcut)
std::vector<std::pair<DWORD, std::wstring>> LayoutMap::GetKeyNameList(const bool isShortcut)
{
return impl->GetKeyNameList(isShortcut);
}
@@ -215,6 +215,7 @@ void LayoutMap::LayoutMapImpl::UpdateLayout()
keyboardLayoutMap[VK_NONCONVERT] = L"IME Non-Convert";
keyboardLayoutMap[VK_ACCEPT] = L"IME Kana";
keyboardLayoutMap[VK_MODECHANGE] = L"IME Mode Change";
keyboardLayoutMap[CommonSharedConstants::VK_DISABLED] = L"Disable";
}
// Function to return the list of key codes in the order for the drop down. It creates it if it doesn't exist
@@ -304,25 +305,25 @@ std::vector<DWORD> LayoutMap::LayoutMapImpl::GetKeyCodeList(const bool isShortcu
return keyCodes;
}
std::vector<std::wstring> LayoutMap::LayoutMapImpl::GetKeyNameList(const bool isShortcut)
std::vector<std::pair<DWORD, std::wstring>> LayoutMap::LayoutMapImpl::GetKeyNameList(const bool isShortcut)
{
std::vector<std::wstring> keyNames;
std::vector<std::pair<DWORD, std::wstring>> keyNames;
std::vector<DWORD> keyCodes = GetKeyCodeList(isShortcut);
std::lock_guard<std::mutex> lock(keyboardLayoutMap_mutex);
// If it is a key list for the shortcut control then we add a "None" key at the start
if (isShortcut)
{
keyNames.push_back(L"None");
keyNames.push_back({ 0, L"None" });
for (int i = 1; i < keyCodes.size(); i++)
{
keyNames.push_back(keyboardLayoutMap[keyCodes[i]]);
keyNames.push_back({ keyCodes[i], keyboardLayoutMap[keyCodes[i]] });
}
}
else
{
for (int i = 0; i < keyCodes.size(); i++)
{
keyNames.push_back(keyboardLayoutMap[keyCodes[i]]);
keyNames.push_back({ keyCodes[i], keyboardLayoutMap[keyCodes[i]] });
}
}

View File

@@ -12,7 +12,7 @@ public:
void UpdateLayout();
std::wstring GetKeyName(DWORD key);
std::vector<DWORD> GetKeyCodeList(const bool isShortcut = false);
std::vector<std::wstring> GetKeyNameList(const bool isShortcut = false);
std::vector<std::pair<DWORD, std::wstring>> GetKeyNameList(const bool isShortcut = false);
private:
class LayoutMapImpl;

View File

@@ -46,6 +46,6 @@ public:
// Function to return the list of key codes in the order for the drop down. It creates it if it doesn't exist
std::vector<DWORD> GetKeyCodeList(const bool isShortcut);
// Function to return the list of key name in the order for the drop down based on the key codes
std::vector<std::wstring> GetKeyNameList(const bool isShortcut);
// Function to return the list of key name pairs in the order for the drop down based on the key codes
std::vector<std::pair<DWORD, std::wstring>> GetKeyNameList(const bool isShortcut);
};

View File

@@ -16,6 +16,14 @@ std::future<void> OnThreadExecutor::submit(task_t task)
return future;
}
void OnThreadExecutor::cancel()
{
std::lock_guard lock{ _task_mutex };
_task_queue = {};
_task_cv.notify_one();
}
void OnThreadExecutor::worker_thread()
{
while (!_shutdown_request)

View File

@@ -18,6 +18,7 @@ public:
OnThreadExecutor();
~OnThreadExecutor();
std::future<void> submit(task_t task);
void cancel();
private:
void worker_thread();

View File

@@ -23,11 +23,11 @@ namespace PTSettingsHelper
return result;
}
std::wstring get_module_save_folder_location(std::wstring_view powertoy_name)
std::wstring get_module_save_folder_location(std::wstring_view powertoy_key)
{
std::wstring result = get_root_save_folder_location();
result += L"\\";
result += powertoy_name;
result += powertoy_key;
std::filesystem::path save_path(result);
if (!std::filesystem::exists(save_path))
{
@@ -36,9 +36,9 @@ namespace PTSettingsHelper
return result;
}
std::wstring get_module_save_file_location(std::wstring_view powertoy_name)
std::wstring get_module_save_file_location(std::wstring_view powertoy_key)
{
return get_module_save_folder_location(powertoy_name) + settings_filename;
return get_module_save_folder_location(powertoy_key) + settings_filename;
}
std::wstring get_powertoys_general_save_file_location()
@@ -46,15 +46,15 @@ namespace PTSettingsHelper
return get_root_save_folder_location() + settings_filename;
}
void save_module_settings(std::wstring_view powertoy_name, json::JsonObject& settings)
void save_module_settings(std::wstring_view powertoy_key, json::JsonObject& settings)
{
const std::wstring save_file_location = get_module_save_file_location(powertoy_name);
const std::wstring save_file_location = get_module_save_file_location(powertoy_key);
json::to_file(save_file_location, settings);
}
json::JsonObject load_module_settings(std::wstring_view powertoy_name)
json::JsonObject load_module_settings(std::wstring_view powertoy_key)
{
const std::wstring save_file_location = get_module_save_file_location(powertoy_name);
const std::wstring save_file_location = get_module_save_file_location(powertoy_key);
auto saved_settings = json::from_file(save_file_location);
return saved_settings.has_value() ? std::move(*saved_settings) : json::JsonObject{};
}

View File

@@ -1,6 +1,7 @@
#include "pch.h"
#include "settings_objects.h"
#include "settings_helpers.h"
#include <winrt/base.h>
namespace PowerToysSettings
{
@@ -277,27 +278,33 @@ namespace PowerToysSettings
return L"RESOURCE ID NOT FOUND: " + std::to_wstring(resource_id);
}
PowerToyValues::PowerToyValues(std::wstring_view powertoy_name)
PowerToyValues::PowerToyValues(std::wstring_view powertoy_name, std::wstring_view powertoy_key)
{
_name = powertoy_name;
_key = powertoy_key;
set_version();
m_json.SetNamedValue(L"name", json::value(powertoy_name));
m_json.SetNamedValue(L"properties", json::JsonObject{});
}
PowerToyValues PowerToyValues::from_json_string(std::wstring_view json)
PowerToyValues PowerToyValues::from_json_string(std::wstring_view json, std::wstring_view powertoy_key)
{
PowerToyValues result = PowerToyValues();
json::JsonObject jsonObject = json::JsonValue::Parse(json).GetObjectW();
if (!jsonObject.HasKey(L"name"))
{
throw winrt::hresult_error(E_NOT_SET, L"name field not set");
}
result.m_json = json::JsonValue::Parse(json).GetObjectW();
result._name = result.m_json.GetNamedString(L"name");
result._key = powertoy_key;
return result;
}
PowerToyValues PowerToyValues::load_from_settings_file(std::wstring_view powertoy_name)
PowerToyValues PowerToyValues::load_from_settings_file(std::wstring_view powertoy_key)
{
PowerToyValues result = PowerToyValues();
result.m_json = PTSettingsHelper::load_module_settings(powertoy_name);
result._name = powertoy_name;
result.m_json = PTSettingsHelper::load_module_settings(powertoy_key);
result._key = powertoy_key;
return result;
}
@@ -357,7 +364,7 @@ namespace PowerToysSettings
void PowerToyValues::save_to_settings_file()
{
set_version();
PTSettingsHelper::save_module_settings(_name, m_json);
PTSettingsHelper::save_module_settings(_key, m_json);
}
void PowerToyValues::set_version()

View File

@@ -67,9 +67,9 @@ namespace PowerToysSettings
class PowerToyValues
{
public:
PowerToyValues(std::wstring_view powertoy_name);
static PowerToyValues from_json_string(std::wstring_view json);
static PowerToyValues load_from_settings_file(std::wstring_view powertoy_name);
PowerToyValues(std::wstring_view powertoy_name, std::wstring_view powertoy_key);
static PowerToyValues from_json_string(std::wstring_view json, std::wstring_view powertoy_key);
static PowerToyValues load_from_settings_file(std::wstring_view powertoy_key);
template<typename T>
inline void add_property(std::wstring_view name, T value)
@@ -92,7 +92,7 @@ namespace PowerToysSettings
const std::wstring m_version = L"1.0";
void set_version();
json::JsonObject m_json;
std::wstring _name;
std::wstring _key;
PowerToyValues() {}
};

View File

@@ -11,4 +11,7 @@ namespace CommonSharedConstants
// Path to the event used by PowerLauncher
const wchar_t POWER_LAUNCHER_SHARED_EVENT[] = L"Local\\PowerToysRunInvokeEvent-30f26ad7-d36d-4c0e-ab02-68bb5ff3c4ab";
}
// Max DWORD for key code to disable keys.
const DWORD VK_DISABLED = 0x100;
}

View File

@@ -102,6 +102,11 @@ namespace updating
std::future<std::optional<new_version_download_info>> get_new_github_version_info_async()
{
// If the current version starts with 0.0.*, it means we're on a local build from a farm and shouldn't check for updates.
if (VERSION_MAJOR == 0 && VERSION_MINOR == 0)
{
co_return std::nullopt;
}
try
{
http::HttpClient client;

View File

@@ -2,6 +2,7 @@
// 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.Collections.Generic;
using System.Text.Json.Serialization;
@@ -12,19 +13,27 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
[JsonPropertyName("targetApp")]
public string TargetApp { get; set; }
public new List<string> GetOriginalKeys()
public new List<string> GetMappedOriginalKeys()
{
return base.GetOriginalKeys();
return base.GetMappedOriginalKeys();
}
public new List<string> GetNewRemapKeys()
public new List<string> GetMappedNewRemapKeys()
{
return base.GetNewRemapKeys();
return base.GetMappedNewRemapKeys();
}
public bool Compare(AppSpecificKeysDataModel arg)
{
return OriginalKeys.Equals(arg.OriginalKeys) && NewRemapKeys.Equals(arg.NewRemapKeys) && TargetApp.Equals(arg.TargetApp);
if (arg == null)
{
throw new ArgumentNullException(nameof(arg));
}
// Using Ordinal comparison for internal text
return OriginalKeys.Equals(arg.OriginalKeys, StringComparison.Ordinal) &&
NewRemapKeys.Equals(arg.NewRemapKeys, StringComparison.Ordinal) &&
TargetApp.Equals(arg.TargetApp, StringComparison.Ordinal);
}
}
}

View File

@@ -5,11 +5,11 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.PowerToys.Settings.UI.Lib.Utilities;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class ColorPickerSettings : BasePTModuleSettings
public class ColorPickerSettings : BasePTModuleSettings, ISettingsConfig
{
public const string ModuleName = "ColorPicker";
@@ -31,7 +31,23 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
WriteIndented = true,
};
if (settingsUtils == null)
{
throw new ArgumentNullException(nameof(settingsUtils));
}
settingsUtils.SaveSettings(JsonSerializer.Serialize(this, options), ModuleName);
}
public string GetModuleName()
{
return Name;
}
// This can be utilized in the future if the settings.json file is to be modified/deleted.
public bool UpgradeSettingsConfiguration()
{
return false;
}
}
}

View File

@@ -25,7 +25,8 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.CustomAction
{
PropertyNamingPolicy = new CustomNamePolicy((propertyName) =>
{
return propertyName.Equals("ModuleAction") ? moduleName : propertyName;
// Using Ordinal as this is an internal property name
return propertyName.Equals("ModuleAction", System.StringComparison.Ordinal) ? moduleName : propertyName;
}),
};

View File

@@ -148,7 +148,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
return JsonSerializer.Serialize(this);
}
private void LogTelemetryEvent(bool value, [CallerMemberName] string moduleName = null)
private static void LogTelemetryEvent(bool value, [CallerMemberName] string moduleName = null)
{
var dataEvent = new SettingsEnabledEvent()
{

View File

@@ -3,19 +3,33 @@
// See the LICENSE file in the project root for more information.
using System.Text.Json.Serialization;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class FancyZonesSettings : BasePTModuleSettings
public class FancyZonesSettings : BasePTModuleSettings, ISettingsConfig
{
public const string ModuleName = "FancyZones";
public FancyZonesSettings()
{
Version = string.Empty;
Name = string.Empty;
Version = "1.0";
Name = ModuleName;
Properties = new FZConfigProperties();
}
[JsonPropertyName("properties")]
public FZConfigProperties Properties { get; set; }
public string GetModuleName()
{
return Name;
}
// This can be utilized in the future if the settings.json file is to be modified/deleted.
public bool UpgradeSettingsConfiguration()
{
return false;
}
}
}

View File

@@ -2,12 +2,15 @@
// 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;
using System.Text.Json.Serialization;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
using Microsoft.PowerToys.Settings.UI.Lib.Utilities;
namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class GeneralSettings
public class GeneralSettings : ISettingsConfig
{
// Gets or sets a value indicating whether packaged.
[JsonPropertyName("packaged")]
@@ -78,9 +81,36 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
return JsonSerializer.Serialize(this);
}
private string DefaultPowertoysVersion()
private static string DefaultPowertoysVersion()
{
return interop.CommonManaged.GetProductVersion();
}
// This function is to implement the ISettingsConfig interface.
// This interface helps in getting the settings configurations.
public string GetModuleName()
{
// The SettingsUtils functions access general settings when the module name is an empty string.
return string.Empty;
}
public bool UpgradeSettingsConfiguration()
{
try
{
if (Helper.CompareVersions(PowertoysVersion, Helper.GetProductVersion()) != 0)
{
// Update settings
PowertoysVersion = Helper.GetProductVersion();
return true;
}
}
catch (FormatException)
{
// If there is an issue with the version number format, don't migrate settings.
}
return false;
}
}
}

View File

@@ -10,6 +10,8 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class HotkeySettings
{
private const int VKTAB = 0x09;
public HotkeySettings()
{
Win = false;
@@ -100,6 +102,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
public bool IsValid()
{
if (IsAccessibleShortcut())
{
return false;
}
return (Alt || Ctrl || Win || Shift) && Code != 0;
}
@@ -107,5 +114,17 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
{
return !Alt && !Ctrl && !Win && !Shift && Code == 0;
}
public bool IsAccessibleShortcut()
{
// Shift+Tab and Tab are accessible shortcuts
if ((!Alt && !Ctrl && !Win && Shift && Code == VKTAB)
|| (!Alt && !Ctrl && !Win && !Shift && Code == VKTAB))
{
return true;
}
return false;
}
}
}

View File

@@ -2,6 +2,7 @@
// 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 interop;
namespace Microsoft.PowerToys.Settings.UI.Lib
@@ -10,7 +11,9 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
public delegate bool IsActive();
public class HotkeySettingsControlHook
public delegate bool FilterAccessibleKeyboardEvents(int key, UIntPtr extraInfo);
public class HotkeySettingsControlHook : IDisposable
{
private const int WmKeyDown = 0x100;
private const int WmKeyUp = 0x101;
@@ -21,13 +24,17 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
private KeyEvent _keyDown;
private KeyEvent _keyUp;
private IsActive _isActive;
private bool disposedValue;
public HotkeySettingsControlHook(KeyEvent keyDown, KeyEvent keyUp, IsActive isActive)
private FilterAccessibleKeyboardEvents _filterKeyboardEvent;
public HotkeySettingsControlHook(KeyEvent keyDown, KeyEvent keyUp, IsActive isActive, FilterAccessibleKeyboardEvents filterAccessibleKeyboardEvents)
{
_keyDown = keyDown;
_keyUp = keyUp;
_isActive = isActive;
_hook = new KeyboardHook(HotkeySettingsHookCallback, IsActive, null);
_filterKeyboardEvent = filterAccessibleKeyboardEvents;
_hook = new KeyboardHook(HotkeySettingsHookCallback, IsActive, FilterKeyboardEvents);
_hook.Start();
}
@@ -51,10 +58,29 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
}
}
private bool FilterKeyboardEvents(KeyboardEvent ev)
{
return _filterKeyboardEvent(ev.key, (UIntPtr)ev.dwExtraInfo);
}
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// Dispose the KeyboardHook object to terminate the hook threads
_hook.Dispose();
}
disposedValue = true;
}
}
public void Dispose()
{
// Dispose the KeyboardHook object to terminate the hook threads
_hook.Dispose();
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}

View File

@@ -2,11 +2,14 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
namespace Microsoft.PowerToys.Settings.UI.Lib
{
public interface ISettingsUtils
{
T GetSettings<T>(string powertoy = "", string fileName = "settings.json");
T GetSettings<T>(string powertoy = "", string fileName = "settings.json")
where T : ISettingsConfig, new();
void SaveSettings(string jsonSettings, string powertoy = "", string fileName = "settings.json");

View File

@@ -4,12 +4,13 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class ImageResizerSettings : BasePTModuleSettings
public class ImageResizerSettings : BasePTModuleSettings, ISettingsConfig
{
public const string ModuleName = "Image Resizer";
public const string ModuleName = "ImageResizer";
[JsonPropertyName("properties")]
public ImageResizerProperties Properties { get; set; }
@@ -29,5 +30,16 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
};
return JsonSerializer.Serialize(this, options);
}
public string GetModuleName()
{
return Name;
}
// This can be utilized in the future if the settings.json file is to be modified/deleted.
public bool UpgradeSettingsConfiguration()
{
return false;
}
}
}

View File

@@ -2,6 +2,7 @@
// 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.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text.Json;
@@ -203,8 +204,8 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
{
_unit = value;
OnPropertyChanged();
OnPropertyChanged("ExtraBoxOpacity");
OnPropertyChanged("EnableEtraBoxes");
OnPropertyChanged(nameof(ExtraBoxOpacity));
OnPropertyChanged(nameof(EnableEtraBoxes));
}
}
}
@@ -222,6 +223,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
public void Update(ImageSize modifiedSize)
{
if (modifiedSize == null)
{
throw new ArgumentNullException(nameof(modifiedSize));
}
Id = modifiedSize.Id;
Name = modifiedSize.Name;
Fit = modifiedSize.Fit;

View File

@@ -10,8 +10,13 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class ImageResizerSizes
{
// Suppressing this warning because removing the setter breaks
// deserialization with System.Text.Json. This affects the UI display.
// See: https://github.com/dotnet/runtime/issues/30258
[JsonPropertyName("value")]
#pragma warning disable CA2227 // Collection properties should be read only
public ObservableCollection<ImageSize> Value { get; set; }
#pragma warning restore CA2227 // Collection properties should be read only
public ImageResizerSizes()
{

View File

@@ -0,0 +1,16 @@
// 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.
namespace Microsoft.PowerToys.Settings.UI.Lib.Interface
{
// Common interface to be implemented by all the objects which get and store settings properties.
public interface ISettingsConfig
{
string ToJsonString();
string GetModuleName();
bool UpgradeSettingsConfiguration();
}
}

View File

@@ -0,0 +1,11 @@
// 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.
namespace Microsoft.PowerToys.Settings.UI.Lib.Interface
{
public interface ISettingsRepository<T>
{
T SettingsConfig { get; set; }
}
}

View File

@@ -2,11 +2,13 @@
// 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;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class KeyboardManagerProfile
public class KeyboardManagerProfile : ISettingsConfig
{
[JsonPropertyName("remapKeys")]
public RemapKeysDataModel RemapKeys { get; set; }
@@ -19,5 +21,21 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
RemapKeys = new RemapKeysDataModel();
RemapShortcuts = new ShortcutsKeyDataModel();
}
public string ToJsonString()
{
return JsonSerializer.Serialize(this);
}
public string GetModuleName()
{
return KeyboardManagerSettings.ModuleName;
}
// This can be utilized in the future if the default.json file is to be modified/deleted.
public bool UpgradeSettingsConfiguration()
{
return false;
}
}
}

View File

@@ -3,11 +3,14 @@
// See the LICENSE file in the project root for more information.
using System.Text.Json.Serialization;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class KeyboardManagerSettings : BasePTModuleSettings
public class KeyboardManagerSettings : BasePTModuleSettings, ISettingsConfig
{
public const string ModuleName = "Keyboard Manager";
[JsonPropertyName("properties")]
public KeyboardManagerProperties Properties { get; set; }
@@ -15,14 +18,18 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
{
Properties = new KeyboardManagerProperties();
Version = "1";
Name = "_unset_";
Name = ModuleName;
}
public KeyboardManagerSettings(string ptName)
public string GetModuleName()
{
Properties = new KeyboardManagerProperties();
Version = "1";
Name = ptName;
return Name;
}
// This can be utilized in the future if the settings.json file is to be modified/deleted.
public bool UpgradeSettingsConfiguration()
{
return false;
}
}
}

View File

@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.PowerToys.Settings.UI.Lib.Utilities;
@@ -17,7 +18,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
[JsonPropertyName("newRemapKeys")]
public string NewRemapKeys { get; set; }
private List<string> MapKeys(string stringOfKeys)
private static List<string> MapKeys(string stringOfKeys)
{
return stringOfKeys
.Split(';')
@@ -26,14 +27,19 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
.ToList();
}
public List<string> GetOriginalKeys()
public List<string> GetMappedOriginalKeys()
{
return MapKeys(OriginalKeys);
}
public List<string> GetNewRemapKeys()
public List<string> GetMappedNewRemapKeys()
{
return MapKeys(NewRemapKeys);
}
public string ToJsonString()
{
return JsonSerializer.Serialize(this);
}
}
}

View File

@@ -5,11 +5,11 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.PowerToys.Settings.UI.Lib.Utilities;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class PowerLauncherSettings : BasePTModuleSettings
public class PowerLauncherSettings : BasePTModuleSettings, ISettingsConfig
{
public const string ModuleName = "PowerToys Run";
@@ -31,7 +31,23 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
WriteIndented = true,
};
if (settingsUtils == null)
{
throw new ArgumentNullException(nameof(settingsUtils));
}
settingsUtils.SaveSettings(JsonSerializer.Serialize(this, options), ModuleName);
}
public string GetModuleName()
{
return Name;
}
// This can be utilized in the future if the settings.json file is to be modified/deleted.
public bool UpgradeSettingsConfiguration()
{
return false;
}
}
}

View File

@@ -72,7 +72,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
return JsonSerializer.Serialize(this);
}
private void LogTelemetryEvent(bool value, [CallerMemberName] string propertyName = null)
private static void LogTelemetryEvent(bool value, [CallerMemberName] string propertyName = null)
{
var dataEvent = new SettingsEnabledEvent()
{

View File

@@ -3,14 +3,15 @@
// See the LICENSE file in the project root for more information.
using System.Text.Json.Serialization;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class PowerPreviewSettings : BasePTModuleSettings
public class PowerPreviewSettings : BasePTModuleSettings, ISettingsConfig
{
public const string ModuleName = "File Explorer";
[JsonPropertyName("Properties")]
[JsonPropertyName("properties")]
public PowerPreviewProperties Properties { get; set; }
public PowerPreviewSettings()
@@ -20,11 +21,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
Name = ModuleName;
}
public PowerPreviewSettings(string ptName)
public string GetModuleName()
{
Properties = new PowerPreviewProperties();
Version = "1";
Name = ptName;
return Name;
}
// This can be utilized in the future if the settings.json file is to be modified/deleted.
public bool UpgradeSettingsConfiguration()
{
return false;
}
}
}

View File

@@ -3,10 +3,11 @@
// See the LICENSE file in the project root for more information.
using System.Text.Json;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class PowerRenameLocalProperties
public class PowerRenameLocalProperties : ISettingsConfig
{
public PowerRenameLocalProperties()
{
@@ -51,5 +52,18 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
{
return JsonSerializer.Serialize(this);
}
// This function is required to implement the ISettingsConfig interface and obtain the settings configurations.
public string GetModuleName()
{
string moduleName = PowerRenameSettings.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

@@ -2,11 +2,13 @@
// 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.Lib.Interface;
namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class PowerRenameSettings : BasePTModuleSettings
public class PowerRenameSettings : BasePTModuleSettings, ISettingsConfig
{
public const string ModuleName = "PowerRename";
@@ -22,6 +24,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
public PowerRenameSettings(PowerRenameLocalProperties localProperties)
{
if (localProperties == null)
{
throw new ArgumentNullException(nameof(localProperties));
}
Properties = new PowerRenameProperties();
Properties.PersistState.Value = localProperties.PersistState;
Properties.MRUEnabled.Value = localProperties.MRUEnabled;
@@ -39,5 +46,16 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
Version = "1";
Name = ptName;
}
public string GetModuleName()
{
return Name;
}
// This can be utilized in the future if the power-rename-settings.json file is to be modified/deleted.
public bool UpgradeSettingsConfiguration()
{
return false;
}
}
}

View File

@@ -3,18 +3,29 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class RemapKeysDataModel
{
// Suppressing this warning because removing the setter breaks
// deserialization with System.Text.Json. This affects the UI display.
// See: https://github.com/dotnet/runtime/issues/30258
[JsonPropertyName("inProcess")]
#pragma warning disable CA2227 // Collection properties should be read only
public List<KeysDataModel> InProcessRemapKeys { get; set; }
#pragma warning restore CA2227 // Collection properties should be read only
public RemapKeysDataModel()
{
InProcessRemapKeys = new List<KeysDataModel>();
}
public string ToJsonString()
{
return JsonSerializer.Serialize(this);
}
}
}

View File

@@ -0,0 +1,70 @@
// 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 Microsoft.PowerToys.Settings.UI.Lib.Interface;
namespace Microsoft.PowerToys.Settings.UI.Lib
{
// This Singleton class is a wrapper around the settings configurations that are accessed by viewmodels.
// This class can have only one instance and therefore the settings configurations are common to all.
public class SettingsRepository<T> : ISettingsRepository<T>
where T : class, ISettingsConfig, new()
{
private static readonly object _SettingsRepoLock = new object();
private static ISettingsUtils _settingsUtils;
private static SettingsRepository<T> settingsRepository;
private T settingsConfig;
// Suppressing the warning as this is a singleton class and this method is
// necessarily static
#pragma warning disable CA1000 // Do not declare static members on generic types
public static SettingsRepository<T> GetInstance(ISettingsUtils settingsUtils)
#pragma warning restore CA1000 // Do not declare static members on generic types
{
// To ensure that only one instance of Settings Repository is created in a multi-threaded environment.
lock (_SettingsRepoLock)
{
if (settingsRepository == null)
{
settingsRepository = new SettingsRepository<T>();
_settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils));
}
return settingsRepository;
}
}
// The Singleton class must have a private constructor so that it cannot be instantiated by any other object other than itself.
private SettingsRepository()
{
}
// Settings configurations shared across all viewmodels
public T SettingsConfig
{
get
{
if (settingsConfig == null)
{
T settingsItem = new T();
settingsConfig = _settingsUtils.GetSettings<T>(settingsItem.GetModuleName());
}
return settingsConfig;
}
set
{
if (value != null)
{
settingsConfig = value;
}
}
}
}
}

View File

@@ -4,6 +4,7 @@
using System;
using System.Text.Json;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
using Microsoft.PowerToys.Settings.UI.Lib.Utilities;
namespace Microsoft.PowerToys.Settings.UI.Lib
@@ -59,16 +60,42 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
/// <summary>
/// Get a Deserialized object of the json settings string.
/// This function creates a file in the powertoy folder if it does not exist and returns an object with default properties.
/// </summary>
/// <returns>Deserialized json settings object.</returns>
public T GetSettings<T>(string powertoy = DefaultModuleName, string fileName = DefaultFileName)
where T : ISettingsConfig, new()
{
if (SettingsExists(powertoy, fileName))
{
// Given the file already exists, to deserialize the file and read it's content.
T deserializedSettings = GetFile<T>(powertoy, fileName);
// IF the file needs to be modified, to save the new configurations accordingly.
if (deserializedSettings.UpgradeSettingsConfiguration())
{
SaveSettings(deserializedSettings.ToJsonString(), powertoy, fileName);
}
return deserializedSettings;
}
else
{
// If the settings file does not exist, to create a new object with default parameters and save it to a newly created settings file.
T newSettingsItem = new T();
SaveSettings(newSettingsItem.ToJsonString(), powertoy, fileName);
return newSettingsItem;
}
}
// Given the powerToy folder name and filename to be accessed, this function deserializes and returns the file.
private T GetFile<T>(string powertoyFolderName = DefaultModuleName, string fileName = DefaultFileName)
{
// Adding Trim('\0') to overcome possible NTFS file corruption.
// Look at issue https://github.com/microsoft/PowerToys/issues/6413 you'll see the file has a large sum of \0 to fill up a 4096 byte buffer for writing to disk
// This, while not totally ideal, does work around the problem by trimming the end.
// The file itself did write the content correctly but something is off with the actual end of the file, hence the 0x00 bug
var jsonSettingsString = _ioProvider.ReadAllText(GetSettingsPath(powertoy, fileName)).Trim('\0');
var jsonSettingsString = _ioProvider.ReadAllText(GetSettingsPath(powertoyFolderName, fileName)).Trim('\0');
return JsonSerializer.Deserialize<T>(jsonSettingsString);
}

View File

@@ -12,7 +12,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
{
OverlayOpacity = new IntProperty(90);
PressTime = new IntProperty(900);
Theme = new StringProperty("light");
Theme = new StringProperty("system");
}
[JsonPropertyName("overlay_opacity")]

View File

@@ -3,10 +3,11 @@
// See the LICENSE file in the project root for more information.
using System.Text.Json.Serialization;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class ShortcutGuideSettings : BasePTModuleSettings
public class ShortcutGuideSettings : BasePTModuleSettings, ISettingsConfig
{
public const string ModuleName = "Shortcut Guide";
@@ -19,5 +20,16 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
Properties = new ShortcutGuideProperties();
Version = "1.0";
}
public string GetModuleName()
{
return Name;
}
// This can be utilized in the future if the settings.json file is to be modified/deleted.
public bool UpgradeSettingsConfiguration()
{
return false;
}
}
}

View File

@@ -3,22 +3,35 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class ShortcutsKeyDataModel
{
// Suppressing these warnings because removing the setter breaks
// deserialization with System.Text.Json. This affects the UI display.
// See: https://github.com/dotnet/runtime/issues/30258
[JsonPropertyName("global")]
#pragma warning disable CA2227 // Collection properties should be read only
public List<KeysDataModel> GlobalRemapShortcuts { get; set; }
#pragma warning restore CA2227 // Collection properties should be read only
[JsonPropertyName("appSpecific")]
#pragma warning disable CA2227 // Collection properties should be read only
public List<AppSpecificKeysDataModel> AppSpecificRemapShortcuts { get; set; }
#pragma warning restore CA2227 // Collection properties should be read only
public ShortcutsKeyDataModel()
{
GlobalRemapShortcuts = new List<KeysDataModel>();
AppSpecificRemapShortcuts = new List<AppSpecificKeysDataModel>();
}
public string ToJsonString()
{
return JsonSerializer.Serialize(this);
}
}
}

View File

@@ -11,7 +11,7 @@ using Microsoft.PowerToys.Settings.UI.Lib.CustomAction;
namespace Microsoft.PowerToys.Settings.UI.Lib.Utilities
{
public class Helper
public static class Helper
{
public static bool AllowRunnerToForeground()
{
@@ -20,7 +20,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.Utilities
if (processes.Length > 0)
{
var pid = processes[0].Id;
result = AllowSetForegroundWindow(pid);
result = NativeMethods.AllowSetForegroundWindow(pid);
}
return result;
@@ -74,9 +74,6 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.Utilities
return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
}
[DllImport("user32.dll")]
private static extern bool AllowSetForegroundWindow(int dwProcessId);
private static readonly interop.LayoutMapManaged LayoutMap = new interop.LayoutMapManaged();
public static string GetKeyName(uint key)
@@ -95,10 +92,19 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.Utilities
{
// Split up the version strings into int[]
// Example: v10.0.2 -> {10, 0, 2};
if (version1 == null)
{
throw new ArgumentNullException(nameof(version1));
}
else if (version2 == null)
{
throw new ArgumentNullException(nameof(version2));
}
var v1 = version1.Substring(1).Split('.').Select(int.Parse).ToArray();
var v2 = version2.Substring(1).Split('.').Select(int.Parse).ToArray();
if (v1.Count() != 3 || v2.Count() != 3)
if (v1.Length != 3 || v2.Length != 3)
{
throw new FormatException();
}

View File

@@ -0,0 +1,17 @@
// 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.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace Microsoft.PowerToys.Settings.UI.Lib.Utilities
{
internal static class NativeMethods
{
[DllImport("user32.dll")]
public static extern bool AllowSetForegroundWindow(int dwProcessId);
}
}

View File

@@ -16,7 +16,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.Utilities
public void DeleteDirectory(string path)
{
Directory.Delete(path);
Directory.Delete(path, recursive: true);
}
public bool DirectoryExists(string path)

View File

@@ -3,22 +3,35 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Globalization;
using System.Text.Json;
using Microsoft.PowerToys.Settings.UI.Lib.Helpers;
using Microsoft.PowerToys.Settings.UI.Lib.Utilities;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
public class ColorPickerViewModel : Observable
{
private GeneralSettings GeneralSettingsConfig { get; set; }
private readonly ISettingsUtils _settingsUtils;
private ColorPickerSettings _colorPickerSettings;
private bool _isEnabled;
private Func<string, int> SendConfigMSG { get; }
public ColorPickerViewModel(ISettingsUtils settingsUtils, Func<string, int> ipcMSGCallBackFunc)
public ColorPickerViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, Func<string, int> ipcMSGCallBackFunc)
{
// Obtain the general PowerToy settings configurations
if (settingsRepository == null)
{
throw new ArgumentNullException(nameof(settingsRepository));
}
GeneralSettingsConfig = settingsRepository.SettingsConfig;
_settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils));
if (_settingsUtils.SettingsExists(ColorPickerSettings.ModuleName))
{
@@ -29,11 +42,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
_colorPickerSettings = new ColorPickerSettings();
}
if (_settingsUtils.SettingsExists())
{
var generalSettings = _settingsUtils.GetSettings<GeneralSettings>();
_isEnabled = generalSettings.Enabled.ColorPicker;
}
_isEnabled = GeneralSettingsConfig.Enabled.ColorPicker;
// set the callback functions value to hangle outgoing IPC message.
SendConfigMSG = ipcMSGCallBackFunc;
@@ -53,10 +62,10 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
_isEnabled = value;
OnPropertyChanged(nameof(IsEnabled));
// grab the latest version of settings
var generalSettings = _settingsUtils.GetSettings<GeneralSettings>();
generalSettings.Enabled.ColorPicker = value;
OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(generalSettings);
// Set the status of ColorPicker in the general settings
GeneralSettingsConfig.Enabled.ColorPicker = value;
OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig);
SendConfigMSG(outgoing.ToString());
}
}
@@ -118,8 +127,13 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
private void NotifySettingsChanged()
{
// Using InvariantCulture as this is an IPC message
SendConfigMSG(
string.Format("{{ \"powertoys\": {{ \"{0}\": {1} }} }}", ColorPickerSettings.ModuleName, JsonSerializer.Serialize(_colorPickerSettings)));
string.Format(
CultureInfo.InvariantCulture,
"{{ \"powertoys\": {{ \"{0}\": {1} }} }}",
ColorPickerSettings.ModuleName,
JsonSerializer.Serialize(_colorPickerSettings)));
}
}
}

View File

@@ -4,18 +4,19 @@
using System;
using System.Drawing;
using System.Globalization;
using System.Runtime.CompilerServices;
using Microsoft.PowerToys.Settings.UI.Lib.Helpers;
using Microsoft.PowerToys.Settings.UI.Lib.Utilities;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
using Microsoft.PowerToys.Settings.UI.Lib.ViewModels.Commands;
namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
public class FancyZonesViewModel : Observable
{
private readonly ISettingsUtils _settingsUtils;
private GeneralSettings GeneralSettingsConfig { get; set; }
private const string ModuleName = "FancyZones";
private const string ModuleName = FancyZonesSettings.ModuleName;
public ButtonClickCommand LaunchEditorEventHandler { get; set; }
@@ -25,21 +26,25 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
private string settingsConfigFileFolder = string.Empty;
public FancyZonesViewModel(ISettingsUtils settingsUtils, Func<string, int> ipcMSGCallBackFunc, string configFileSubfolder = "")
public FancyZonesViewModel(ISettingsRepository<GeneralSettings> settingsRepository, ISettingsRepository<FancyZonesSettings> moduleSettingsRepository, Func<string, int> ipcMSGCallBackFunc, string configFileSubfolder = "")
{
settingsConfigFileFolder = configFileSubfolder;
_settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils));
// To obtain the general settings configurations of PowerToys Settings.
if (settingsRepository == null)
{
throw new ArgumentNullException(nameof(settingsRepository));
}
try
GeneralSettingsConfig = settingsRepository.SettingsConfig;
settingsConfigFileFolder = configFileSubfolder;
// To obtain the settings configurations of Fancy zones.
if (moduleSettingsRepository == null)
{
Settings = _settingsUtils.GetSettings<FancyZonesSettings>(GetSettingsSubPath());
}
catch
{
Settings = new FancyZonesSettings();
_settingsUtils.SaveSettings(Settings.ToJsonString(), GetSettingsSubPath());
throw new ArgumentNullException(nameof(moduleSettingsRepository));
}
Settings = moduleSettingsRepository.SettingsConfig;
LaunchEditorEventHandler = new ButtonClickCommand(LaunchEditor);
_shiftDrag = Settings.Properties.FancyzonesShiftDrag.Value;
@@ -64,26 +69,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
SendConfigMSG = ipcMSGCallBackFunc;
string inactiveColor = Settings.Properties.FancyzonesInActiveColor.Value;
_zoneInActiveColor = inactiveColor != string.Empty ? inactiveColor : "#F5FCFF";
_zoneInActiveColor = !string.IsNullOrEmpty(inactiveColor) ? inactiveColor : "#F5FCFF";
string borderColor = Settings.Properties.FancyzonesBorderColor.Value;
_zoneBorderColor = borderColor != string.Empty ? borderColor : "#FFFFFF";
_zoneBorderColor = !string.IsNullOrEmpty(borderColor) ? borderColor : "#FFFFFF";
string highlightColor = Settings.Properties.FancyzonesZoneHighlightColor.Value;
_zoneHighlightColor = highlightColor != string.Empty ? highlightColor : "#0078D7";
_zoneHighlightColor = !string.IsNullOrEmpty(highlightColor) ? highlightColor : "#0078D7";
GeneralSettings generalSettings;
try
{
generalSettings = _settingsUtils.GetSettings<GeneralSettings>(string.Empty);
}
catch
{
generalSettings = new GeneralSettings();
_settingsUtils.SaveSettings(generalSettings.ToJsonString(), string.Empty);
}
_isEnabled = generalSettings.Enabled.FancyZones;
_isEnabled = GeneralSettingsConfig.Enabled.FancyZones;
}
private bool _isEnabled;
@@ -121,13 +115,14 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
if (value != _isEnabled)
{
_isEnabled = value;
GeneralSettings generalSettings = _settingsUtils.GetSettings<GeneralSettings>(string.Empty);
generalSettings.Enabled.FancyZones = value;
OutGoingGeneralSettings snd = new OutGoingGeneralSettings(generalSettings);
// Set the status of FancyZones in the general settings configuration
GeneralSettingsConfig.Enabled.FancyZones = value;
OutGoingGeneralSettings snd = new OutGoingGeneralSettings(GeneralSettingsConfig);
SendConfigMSG(snd.ToString());
OnPropertyChanged("IsEnabled");
OnPropertyChanged("SnapHotkeysCategoryEnabled");
OnPropertyChanged(nameof(IsEnabled));
OnPropertyChanged(nameof(SnapHotkeysCategoryEnabled));
}
}
}
@@ -153,7 +148,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
_shiftDrag = value;
Settings.Properties.FancyzonesShiftDrag.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -171,7 +166,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
_mouseSwitch = value;
Settings.Properties.FancyzonesMouseSwitch.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -194,8 +189,8 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
_overrideSnapHotkeys = value;
Settings.Properties.FancyzonesOverrideSnapHotkeys.Value = value;
RaisePropertyChanged();
OnPropertyChanged("SnapHotkeysCategoryEnabled");
NotifyPropertyChanged();
OnPropertyChanged(nameof(SnapHotkeysCategoryEnabled));
}
}
}
@@ -213,7 +208,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
_moveWindowsAcrossMonitors = value;
Settings.Properties.FancyzonesMoveWindowsAcrossMonitors.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -231,7 +226,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
_moveWindowsBasedOnPosition = value;
Settings.Properties.FancyzonesMoveWindowsBasedOnPosition.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -249,7 +244,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
_displayChangemoveWindows = value;
Settings.Properties.FancyzonesDisplayChangeMoveWindows.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -267,7 +262,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
_zoneSetChangeMoveWindows = value;
Settings.Properties.FancyzonesZoneSetChangeMoveWindows.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -285,7 +280,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
_appLastZoneMoveWindows = value;
Settings.Properties.FancyzonesAppLastZoneMoveWindows.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -303,7 +298,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
_openWindowOnActiveMonitor = value;
Settings.Properties.FancyzonesOpenWindowOnActiveMonitor.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -321,7 +316,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
_restoreSize = value;
Settings.Properties.FancyzonesRestoreSize.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -339,7 +334,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
_useCursorPosEditorStartupScreen = value;
Settings.Properties.UseCursorposEditorStartupscreen.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -357,7 +352,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
_showOnAllMonitors = value;
Settings.Properties.FancyzonesShowOnAllMonitors.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -375,7 +370,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
_spanZonesAcrossMonitors = value;
Settings.Properties.FancyzonesSpanZonesAcrossMonitors.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -393,11 +388,13 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
_makeDraggedWindowTransparent = value;
Settings.Properties.FancyzonesMakeDraggedWindowTransparent.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
// For the following setters we use OrdinalIgnoreCase string comparison since
// we expect value to be a hex code.
public string ZoneHighlightColor
{
get
@@ -407,12 +404,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
set
{
value = ToRGBHex(value);
if (!value.Equals(_zoneHighlightColor))
// The fallback value is based on ToRGBHex's behavior, which returns
// #FFFFFF if any exceptions are encountered, e.g. from passing in a null value.
// This extra handling is added here to deal with FxCop warnings.
value = (value != null) ? ToRGBHex(value) : "#FFFFFF";
if (!value.Equals(_zoneHighlightColor, StringComparison.OrdinalIgnoreCase))
{
_zoneHighlightColor = value;
Settings.Properties.FancyzonesZoneHighlightColor.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -426,12 +426,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
set
{
value = ToRGBHex(value);
// The fallback value is based on ToRGBHex's behavior, which returns
// #FFFFFF if any exceptions are encountered, e.g. from passing in a null value.
// This extra handling is added here to deal with FxCop warnings.
value = (value != null) ? ToRGBHex(value) : "#FFFFFF";
if (!value.Equals(_zoneBorderColor, StringComparison.OrdinalIgnoreCase))
{
_zoneBorderColor = value;
Settings.Properties.FancyzonesBorderColor.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -445,12 +448,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
set
{
value = ToRGBHex(value);
if (!value.Equals(_zoneInActiveColor))
// The fallback value is based on ToRGBHex's behavior, which returns
// #FFFFFF if any exceptions are encountered, e.g. from passing in a null value.
// This extra handling is added here to deal with FxCop warnings.
value = (value != null) ? ToRGBHex(value) : "#FFFFFF";
if (!value.Equals(_zoneInActiveColor, StringComparison.OrdinalIgnoreCase))
{
_zoneInActiveColor = value;
Settings.Properties.FancyzonesInActiveColor.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -468,7 +474,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
_highlightOpacity = value;
Settings.Properties.FancyzonesHighlightOpacity.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -484,7 +490,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
if (value != _editorHotkey)
{
if (value.IsEmpty())
if (value == null || value.IsEmpty())
{
_editorHotkey = FZConfigProperties.DefaultHotkeyValue;
}
@@ -494,7 +500,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
}
Settings.Properties.FancyzonesEditorHotkey.Value = _editorHotkey;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -512,7 +518,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
_excludedApps = value;
Settings.Properties.FancyzonesExcludedApps.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -523,7 +529,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
SendConfigMSG("{\"action\":{\"FancyZones\":{\"action_name\":\"ToggledFZEditor\", \"value\":\"\"}}}");
}
public void RaisePropertyChanged([CallerMemberName] string propertyName = null)
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
OnPropertyChanged(propertyName);
if (SendConfigMSG != null)
@@ -534,13 +540,19 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
}
}
private string ToRGBHex(string color)
private static string ToRGBHex(string color)
{
try
{
int argb = int.Parse(color.Replace("#", string.Empty), System.Globalization.NumberStyles.HexNumber);
// Using InvariantCulture as these are expected to be hex codes.
int argb = int.Parse(
color.Replace("#", string.Empty),
System.Globalization.NumberStyles.HexNumber,
CultureInfo.InvariantCulture);
Color clr = Color.FromArgb(argb);
return "#" + clr.R.ToString("X2") + clr.G.ToString("X2") + clr.B.ToString("X2");
return "#" + clr.R.ToString("X2", CultureInfo.InvariantCulture) +
clr.G.ToString("X2", CultureInfo.InvariantCulture) +
clr.B.ToString("X2", CultureInfo.InvariantCulture);
}
catch (Exception)
{

View File

@@ -3,9 +3,10 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.CompilerServices;
using Microsoft.PowerToys.Settings.UI.Lib.Helpers;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
using Microsoft.PowerToys.Settings.UI.Lib.Utilities;
using Microsoft.PowerToys.Settings.UI.Lib.ViewModels.Commands;
@@ -13,11 +14,9 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
public class GeneralViewModel : Observable
{
private readonly ISettingsUtils _settingsUtils;
private GeneralSettings GeneralSettingsConfig { get; set; }
private GeneralSettings GeneralSettingsConfigs { get; set; }
public ButtonClickCommand CheckFoUpdatesEventHandler { get; set; }
public ButtonClickCommand CheckForUpdatesEventHandler { get; set; }
public ButtonClickCommand RestartElevatedButtonEventHandler { get; set; }
@@ -35,33 +34,18 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
private string _settingsConfigFileFolder = string.Empty;
public GeneralViewModel(ISettingsUtils settingsUtils, string runAsAdminText, string runAsUserText, bool isElevated, bool isAdmin, Func<string, int> updateTheme, Func<string, int> ipcMSGCallBackFunc, Func<string, int> ipcMSGRestartAsAdminMSGCallBackFunc, Func<string, int> ipcMSGCheckForUpdatesCallBackFunc, string configFileSubfolder = "")
public GeneralViewModel(ISettingsRepository<GeneralSettings> settingsRepository, string runAsAdminText, string runAsUserText, bool isElevated, bool isAdmin, Func<string, int> updateTheme, Func<string, int> ipcMSGCallBackFunc, Func<string, int> ipcMSGRestartAsAdminMSGCallBackFunc, Func<string, int> ipcMSGCheckForUpdatesCallBackFunc, string configFileSubfolder = "")
{
CheckFoUpdatesEventHandler = new ButtonClickCommand(CheckForUpdates_Click);
RestartElevatedButtonEventHandler = new ButtonClickCommand(Restart_Elevated);
_settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils));
CheckForUpdatesEventHandler = new ButtonClickCommand(CheckForUpdatesClick);
RestartElevatedButtonEventHandler = new ButtonClickCommand(RestartElevated);
try
// To obtain the general settings configuration of PowerToys if it exists, else to create a new file and return the default configurations.
if (settingsRepository == null)
{
GeneralSettingsConfigs = _settingsUtils.GetSettings<GeneralSettings>(string.Empty);
throw new ArgumentNullException(nameof(settingsRepository));
}
if (Helper.CompareVersions(GeneralSettingsConfigs.PowertoysVersion, Helper.GetProductVersion()) < 0)
{
// Update settings
GeneralSettingsConfigs.PowertoysVersion = Helper.GetProductVersion();
_settingsUtils.SaveSettings(GeneralSettingsConfigs.ToJsonString(), string.Empty);
}
}
catch (FormatException e)
{
// If there is an issue with the version number format, don't migrate settings.
Debug.WriteLine(e.Message);
}
catch
{
GeneralSettingsConfigs = new GeneralSettings();
_settingsUtils.SaveSettings(GeneralSettingsConfigs.ToJsonString(), string.Empty);
}
GeneralSettingsConfig = settingsRepository.SettingsConfig;
// set the callback functions value to hangle outgoing IPC message.
SendConfigMSG = ipcMSGCallBackFunc;
@@ -70,28 +54,33 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
// set the callback function value to update the UI theme.
UpdateUIThemeCallBack = updateTheme;
UpdateUIThemeCallBack(GeneralSettingsConfigs.Theme.ToLower());
UpdateUIThemeCallBack(GeneralSettingsConfig.Theme);
// Update Settings file folder:
_settingsConfigFileFolder = configFileSubfolder;
switch (GeneralSettingsConfigs.Theme.ToLower())
// Using Invariant here as these are internal strings and fxcop
// expects strings to be normalized to uppercase. While the theme names
// are represented in lowercase everywhere else, we'll use uppercase
// normalization for switch statements
switch (GeneralSettingsConfig.Theme.ToUpperInvariant())
{
case "light":
case "LIGHT":
_isLightThemeRadioButtonChecked = true;
break;
case "dark":
case "DARK":
_isDarkThemeRadioButtonChecked = true;
break;
case "system":
case "SYSTEM":
_isSystemThemeRadioButtonChecked = true;
break;
}
_startup = GeneralSettingsConfigs.Startup;
_autoDownloadUpdates = GeneralSettingsConfigs.AutoDownloadUpdates;
_startup = GeneralSettingsConfig.Startup;
_autoDownloadUpdates = GeneralSettingsConfig.AutoDownloadUpdates;
_isElevated = isElevated;
_runElevated = GeneralSettingsConfigs.RunElevated;
_runElevated = GeneralSettingsConfig.RunElevated;
RunningAsUserDefaultText = runAsUserText;
RunningAsAdminDefaultText = runAsAdminText;
@@ -99,15 +88,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
_isAdmin = isAdmin;
}
private bool _packaged = false;
private bool _startup = false;
private bool _isElevated = false;
private bool _runElevated = false;
private bool _isAdmin = false;
private bool _isDarkThemeRadioButtonChecked = false;
private bool _isLightThemeRadioButtonChecked = false;
private bool _isSystemThemeRadioButtonChecked = false;
private bool _autoDownloadUpdates = false;
private bool _packaged;
private bool _startup;
private bool _isElevated;
private bool _runElevated;
private bool _isAdmin;
private bool _isDarkThemeRadioButtonChecked;
private bool _isLightThemeRadioButtonChecked;
private bool _isSystemThemeRadioButtonChecked;
private bool _autoDownloadUpdates;
private string _latestAvailableVersion = string.Empty;
@@ -124,7 +113,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
if (_packaged != value)
{
_packaged = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -142,8 +131,8 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
if (_startup != value)
{
_startup = value;
GeneralSettingsConfigs.Startup = value;
RaisePropertyChanged();
GeneralSettingsConfig.Startup = value;
NotifyPropertyChanged();
}
}
}
@@ -181,8 +170,8 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
if (_isElevated != value)
{
_isElevated = value;
OnPropertyChanged("IsElevated");
OnPropertyChanged("IsAdminButtonEnabled");
OnPropertyChanged(nameof(IsElevated));
OnPropertyChanged(nameof(IsAdminButtonEnabled));
OnPropertyChanged("RunningAsAdminText");
}
}
@@ -197,7 +186,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
set
{
OnPropertyChanged("IsAdminButtonEnabled");
OnPropertyChanged(nameof(IsAdminButtonEnabled));
}
}
@@ -214,8 +203,8 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
if (_runElevated != value)
{
_runElevated = value;
GeneralSettingsConfigs.RunElevated = value;
RaisePropertyChanged();
GeneralSettingsConfig.RunElevated = value;
NotifyPropertyChanged();
}
}
}
@@ -241,8 +230,8 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
if (_autoDownloadUpdates != value)
{
_autoDownloadUpdates = value;
GeneralSettingsConfigs.AutoDownloadUpdates = value;
RaisePropertyChanged();
GeneralSettingsConfig.AutoDownloadUpdates = value;
NotifyPropertyChanged();
}
}
}
@@ -258,17 +247,17 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
if (value == true)
{
GeneralSettingsConfigs.Theme = "dark";
GeneralSettingsConfig.Theme = "dark";
_isDarkThemeRadioButtonChecked = value;
try
{
UpdateUIThemeCallBack(GeneralSettingsConfigs.Theme);
UpdateUIThemeCallBack(GeneralSettingsConfig.Theme);
}
catch
{
}
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -284,17 +273,17 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
if (value == true)
{
GeneralSettingsConfigs.Theme = "light";
GeneralSettingsConfig.Theme = "light";
_isLightThemeRadioButtonChecked = value;
try
{
UpdateUIThemeCallBack(GeneralSettingsConfigs.Theme);
UpdateUIThemeCallBack(GeneralSettingsConfig.Theme);
}
catch
{
}
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -310,22 +299,27 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
if (value == true)
{
GeneralSettingsConfigs.Theme = "system";
GeneralSettingsConfig.Theme = "system";
_isSystemThemeRadioButtonChecked = value;
try
{
UpdateUIThemeCallBack(GeneralSettingsConfigs.Theme);
UpdateUIThemeCallBack(GeneralSettingsConfig.Theme);
}
catch
{
}
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
// FxCop suggests marking this member static, but it is accessed through
// an instance in autogenerated files (GeneralPage.g.cs) and will break
// the file if modified
#pragma warning disable CA1822 // Mark members as static
public string PowerToysVersion
#pragma warning restore CA1822 // Mark members as static
{
get
{
@@ -346,38 +340,36 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
if (_latestAvailableVersion != value)
{
_latestAvailableVersion = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
public void RaisePropertyChanged([CallerMemberName] string propertyName = null)
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
// Notify UI of property change
OnPropertyChanged(propertyName);
OutGoingGeneralSettings outsettings = new OutGoingGeneralSettings(GeneralSettingsConfigs);
OutGoingGeneralSettings outsettings = new OutGoingGeneralSettings(GeneralSettingsConfig);
SendConfigMSG(outsettings.ToString());
}
// callback function to launch the URL to check for updates.
private void CheckForUpdates_Click()
private void CheckForUpdatesClick()
{
GeneralSettings settings = _settingsUtils.GetSettings<GeneralSettings>(_settingsConfigFileFolder);
settings.CustomActionName = "check_for_updates";
GeneralSettingsConfig.CustomActionName = "check_for_updates";
OutGoingGeneralSettings outsettings = new OutGoingGeneralSettings(settings);
OutGoingGeneralSettings outsettings = new OutGoingGeneralSettings(GeneralSettingsConfig);
GeneralSettingsCustomAction customaction = new GeneralSettingsCustomAction(outsettings);
SendCheckForUpdatesConfigMSG(customaction.ToString());
}
public void Restart_Elevated()
public void RestartElevated()
{
GeneralSettings settings = _settingsUtils.GetSettings<GeneralSettings>(_settingsConfigFileFolder);
settings.CustomActionName = "restart_elevation";
GeneralSettingsConfig.CustomActionName = "restart_elevation";
OutGoingGeneralSettings outsettings = new OutGoingGeneralSettings(settings);
OutGoingGeneralSettings outsettings = new OutGoingGeneralSettings(GeneralSettingsConfig);
GeneralSettingsCustomAction customaction = new GeneralSettingsCustomAction(outsettings);
SendRestartAsAdminConfigMSG(customaction.ToString());

View File

@@ -7,24 +7,34 @@ using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using Microsoft.PowerToys.Settings.UI.Lib.Helpers;
using Microsoft.PowerToys.Settings.UI.Lib.Utilities;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
public class ImageResizerViewModel : Observable
{
private GeneralSettings GeneralSettingsConfig { get; set; }
private readonly ISettingsUtils _settingsUtils;
private ImageResizerSettings Settings { get; set; }
private const string ModuleName = "ImageResizer";
private const string ModuleName = ImageResizerSettings.ModuleName;
private Func<string, int> SendConfigMSG { get; }
public ImageResizerViewModel(ISettingsUtils settingsUtils, Func<string, int> ipcMSGCallBackFunc)
public ImageResizerViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, Func<string, int> ipcMSGCallBackFunc)
{
_settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils));
// To obtain the general settings configurations of PowerToys.
if (settingsRepository == null)
{
throw new ArgumentNullException(nameof(settingsRepository));
}
GeneralSettingsConfig = settingsRepository.SettingsConfig;
try
{
Settings = _settingsUtils.GetSettings<ImageResizerSettings>(ModuleName);
@@ -35,22 +45,10 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
_settingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
}
GeneralSettings generalSettings;
try
{
generalSettings = _settingsUtils.GetSettings<GeneralSettings>(string.Empty);
}
catch
{
generalSettings = new GeneralSettings();
_settingsUtils.SaveSettings(generalSettings.ToJsonString(), string.Empty);
}
// set the callback functions value to hangle outgoing IPC message.
SendConfigMSG = ipcMSGCallBackFunc;
_isEnabled = generalSettings.Enabled.ImageResizer;
_isEnabled = GeneralSettingsConfig.Enabled.ImageResizer;
_advancedSizes = Settings.Properties.ImageresizerSizes.Value;
_jpegQualityLevel = Settings.Properties.ImageresizerJpegQualityLevel.Value;
_pngInterlaceOption = Settings.Properties.ImageresizerPngInterlaceOption.Value;
@@ -64,18 +62,18 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
size.Id = i;
i++;
size.PropertyChanged += Size_PropertyChanged;
size.PropertyChanged += SizePropertyChanged;
}
}
private bool _isEnabled = false;
private bool _isEnabled;
private ObservableCollection<ImageSize> _advancedSizes = new ObservableCollection<ImageSize>();
private int _jpegQualityLevel = 0;
private int _jpegQualityLevel;
private int _pngInterlaceOption;
private int _tiffCompressOption;
private string _fileName;
private bool _keepDateModified;
private int _encoderGuidId = 0;
private int _encoderGuidId;
public bool IsEnabled
{
@@ -88,28 +86,34 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
if (value != _isEnabled)
{
// To set the status of ImageResizer in the General PowerToys settings.
_isEnabled = value;
GeneralSettings generalSettings = _settingsUtils.GetSettings<GeneralSettings>(string.Empty);
generalSettings.Enabled.ImageResizer = value;
OutGoingGeneralSettings snd = new OutGoingGeneralSettings(generalSettings);
GeneralSettingsConfig.Enabled.ImageResizer = value;
OutGoingGeneralSettings snd = new OutGoingGeneralSettings(GeneralSettingsConfig);
SendConfigMSG(snd.ToString());
OnPropertyChanged("IsEnabled");
OnPropertyChanged(nameof(IsEnabled));
}
}
}
#pragma warning disable CA2227 // Collection properties should be read only
public ObservableCollection<ImageSize> Sizes
#pragma warning restore CA2227 // Collection properties should be read only
{
get
{
return _advancedSizes;
}
// FxCop demands collection properties to be read-only, but this
// setter is used in autogenerated files (ImageResizerPage.g.cs)
// and replacing the setter with its own method will break the file
set
{
SavesImageSizes(value);
_advancedSizes = value;
OnPropertyChanged("Sizes");
OnPropertyChanged(nameof(Sizes));
}
}
@@ -127,7 +131,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
_jpegQualityLevel = value;
Settings.Properties.ImageresizerJpegQualityLevel.Value = value;
_settingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
OnPropertyChanged("JPEGQualityLevel");
OnPropertyChanged(nameof(JPEGQualityLevel));
}
}
}
@@ -146,7 +150,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
_pngInterlaceOption = value;
Settings.Properties.ImageresizerPngInterlaceOption.Value = value;
_settingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
OnPropertyChanged("PngInterlaceOption");
OnPropertyChanged(nameof(PngInterlaceOption));
}
}
}
@@ -165,7 +169,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
_tiffCompressOption = value;
Settings.Properties.ImageresizerTiffCompressOption.Value = value;
_settingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
OnPropertyChanged("TiffCompressOption");
OnPropertyChanged(nameof(TiffCompressOption));
}
}
}
@@ -184,7 +188,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
_fileName = value;
Settings.Properties.ImageresizerFileName.Value = value;
_settingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
OnPropertyChanged("FileName");
OnPropertyChanged(nameof(FileName));
}
}
}
@@ -201,7 +205,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
_keepDateModified = value;
Settings.Properties.ImageresizerKeepDateModified.Value = value;
_settingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
OnPropertyChanged("KeepDateModified");
OnPropertyChanged(nameof(KeepDateModified));
}
}
@@ -220,17 +224,25 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
_settingsUtils.SaveSettings(Settings.Properties.ImageresizerSizes.ToJsonString(), ModuleName, "sizes.json");
Settings.Properties.ImageresizerFallbackEncoder.Value = GetEncoderGuid(value);
_settingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
OnPropertyChanged("Encoder");
OnPropertyChanged(nameof(Encoder));
}
}
}
public string EncoderGuid
{
get
{
return ImageResizerViewModel.GetEncoderGuid(_encoderGuidId);
}
}
public void AddRow()
{
ObservableCollection<ImageSize> imageSizes = Sizes;
int maxId = imageSizes.Count > 0 ? imageSizes.OrderBy(x => x.Id).Last().Id : -1;
ImageSize newSize = new ImageSize(maxId + 1);
newSize.PropertyChanged += Size_PropertyChanged;
newSize.PropertyChanged += SizePropertyChanged;
imageSizes.Add(newSize);
_advancedSizes = imageSizes;
SavesImageSizes(imageSizes);
@@ -253,7 +265,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
_settingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
}
public string GetEncoderGuid(int value)
public static string GetEncoderGuid(int value)
{
// PNG Encoder guid
if (value == 0)
@@ -294,40 +306,40 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
return null;
}
public int GetEncoderIndex(string guid)
public static int GetEncoderIndex(string value)
{
// PNG Encoder guid
if (guid == "1b7cfaf4-713f-473c-bbcd-6137425faeaf")
if (value == "1b7cfaf4-713f-473c-bbcd-6137425faeaf")
{
return 0;
}
// Bitmap Encoder guid
else if (guid == "0af1d87e-fcfe-4188-bdeb-a7906471cbe3")
else if (value == "0af1d87e-fcfe-4188-bdeb-a7906471cbe3")
{
return 1;
}
// JPEG Encoder guid
else if (guid == "19e4a5aa-5662-4fc5-a0c0-1758028e1057")
else if (value == "19e4a5aa-5662-4fc5-a0c0-1758028e1057")
{
return 2;
}
// Tiff encoder guid.
else if (guid == "163bcc30-e2e9-4f0b-961d-a3e9fdb788a3")
else if (value == "163bcc30-e2e9-4f0b-961d-a3e9fdb788a3")
{
return 3;
}
// Tiff encoder guid.
else if (guid == "57a37caa-367a-4540-916b-f183c5093a4b")
else if (value == "57a37caa-367a-4540-916b-f183c5093a4b")
{
return 4;
}
// Gif encoder guid.
else if (guid == "1f8a5601-7d4d-4cbd-9c82-1bc8d4eeb9a5")
else if (value == "1f8a5601-7d4d-4cbd-9c82-1bc8d4eeb9a5")
{
return 5;
}
@@ -335,7 +347,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
return -1;
}
public void Size_PropertyChanged(object sender, PropertyChangedEventArgs e)
public void SizePropertyChanged(object sender, PropertyChangedEventArgs e)
{
ImageSize modifiedSize = (ImageSize)sender;
ObservableCollection<ImageSize> imageSizes = Sizes;

View File

@@ -4,11 +4,13 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using Microsoft.PowerToys.Settings.UI.Lib.Helpers;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
using Microsoft.PowerToys.Settings.UI.Lib.Utilities;
using Microsoft.PowerToys.Settings.UI.Lib.ViewModels.Commands;
@@ -16,9 +18,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
public class KeyboardManagerViewModel : Observable
{
private GeneralSettings GeneralSettingsConfig { get; set; }
private readonly ISettingsUtils _settingsUtils;
private const string PowerToyName = "Keyboard Manager";
private const string PowerToyName = KeyboardManagerSettings.ModuleName;
private const string RemapKeyboardActionName = "RemapKeyboard";
private const string RemapKeyboardActionValue = "Open Remap Keyboard Window";
private const string EditShortcutActionName = "EditShortcut";
@@ -32,14 +36,20 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
private ICommand _remapKeyboardCommand;
private ICommand _editShortcutCommand;
private KeyboardManagerProfile _profile;
private GeneralSettings _generalSettings;
private Func<string, int> SendConfigMSG { get; }
private Func<List<KeysDataModel>, int> FilterRemapKeysList { get; }
public KeyboardManagerViewModel(ISettingsUtils settingsUtils, Func<string, int> ipcMSGCallBackFunc, Func<List<KeysDataModel>, int> filterRemapKeysList)
public KeyboardManagerViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, Func<string, int> ipcMSGCallBackFunc, Func<List<KeysDataModel>, int> filterRemapKeysList)
{
if (settingsRepository == null)
{
throw new ArgumentNullException(nameof(settingsRepository));
}
GeneralSettingsConfig = settingsRepository.SettingsConfig;
// set the callback functions value to hangle outgoing IPC message.
SendConfigMSG = ipcMSGCallBackFunc;
FilterRemapKeysList = filterRemapKeysList;
@@ -59,35 +69,25 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
}
else
{
Settings = new KeyboardManagerSettings(PowerToyName);
Settings = new KeyboardManagerSettings();
_settingsUtils.SaveSettings(Settings.ToJsonString(), PowerToyName);
}
if (_settingsUtils.SettingsExists())
{
_generalSettings = _settingsUtils.GetSettings<GeneralSettings>(string.Empty);
}
else
{
_generalSettings = new GeneralSettings();
_settingsUtils.SaveSettings(_generalSettings.ToJsonString(), string.Empty);
}
}
public bool Enabled
{
get
{
return _generalSettings.Enabled.KeyboardManager;
return GeneralSettingsConfig.Enabled.KeyboardManager;
}
set
{
if (_generalSettings.Enabled.KeyboardManager != value)
if (GeneralSettingsConfig.Enabled.KeyboardManager != value)
{
_generalSettings.Enabled.KeyboardManager = value;
GeneralSettingsConfig.Enabled.KeyboardManager = value;
OnPropertyChanged(nameof(Enabled));
OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(_generalSettings);
OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig);
SendConfigMSG(outgoing.ToString());
}
@@ -112,7 +112,22 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
public static List<AppSpecificKeysDataModel> CombineShortcutLists(List<KeysDataModel> globalShortcutList, List<AppSpecificKeysDataModel> appSpecificShortcutList)
{
return globalShortcutList.ConvertAll(x => new AppSpecificKeysDataModel { OriginalKeys = x.OriginalKeys, NewRemapKeys = x.NewRemapKeys, TargetApp = "All Apps" }).Concat(appSpecificShortcutList).ToList();
if (globalShortcutList == null && appSpecificShortcutList == null)
{
return new List<AppSpecificKeysDataModel>();
}
else if (globalShortcutList == null)
{
return appSpecificShortcutList;
}
else if (appSpecificShortcutList == null)
{
return globalShortcutList.ConvertAll(x => new AppSpecificKeysDataModel { OriginalKeys = x.OriginalKeys, NewRemapKeys = x.NewRemapKeys, TargetApp = "All Apps" }).ToList();
}
else
{
return globalShortcutList.ConvertAll(x => new AppSpecificKeysDataModel { OriginalKeys = x.OriginalKeys, NewRemapKeys = x.NewRemapKeys, TargetApp = "All Apps" }).Concat(appSpecificShortcutList).ToList();
}
}
public List<AppSpecificKeysDataModel> RemapShortcuts
@@ -134,28 +149,31 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
public ICommand EditShortcutCommand => _editShortcutCommand ?? (_editShortcutCommand = new RelayCommand(OnEditShortcut));
// Note: FxCop suggests calling ConfigureAwait() for the following methods,
// and calling ConfigureAwait(true) has the same behavior as not explicitly
// calling it (continuations are scheduled on the task-creating thread)
private async void OnRemapKeyboard()
{
await Task.Run(() => OnRemapKeyboardBackground());
await Task.Run(() => OnRemapKeyboardBackground()).ConfigureAwait(true);
}
private async void OnEditShortcut()
{
await Task.Run(() => OnEditShortcutBackground());
await Task.Run(() => OnEditShortcutBackground()).ConfigureAwait(true);
}
private async Task OnRemapKeyboardBackground()
{
Helper.AllowRunnerToForeground();
SendConfigMSG(Helper.GetSerializedCustomAction(PowerToyName, RemapKeyboardActionName, RemapKeyboardActionValue));
await Task.CompletedTask;
await Task.CompletedTask.ConfigureAwait(true);
}
private async Task OnEditShortcutBackground()
{
Helper.AllowRunnerToForeground();
SendConfigMSG(Helper.GetSerializedCustomAction(PowerToyName, EditShortcutActionName, EditShortcutActionValue));
await Task.CompletedTask;
await Task.CompletedTask.ConfigureAwait(true);
}
public void NotifyFileChanged()
@@ -177,8 +195,19 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
// update the UI element here.
try
{
_profile = _settingsUtils.GetSettings<KeyboardManagerProfile>(PowerToyName, Settings.Properties.ActiveConfiguration.Value + JsonFileType);
FilterRemapKeysList(_profile.RemapKeys.InProcessRemapKeys);
string fileName = Settings.Properties.ActiveConfiguration.Value + JsonFileType;
if (_settingsUtils.SettingsExists(PowerToyName, fileName))
{
_profile = _settingsUtils.GetSettings<KeyboardManagerProfile>(PowerToyName, fileName);
}
else
{
// The KBM process out of runner creates the default.json file if it does not exist.
success = false;
}
FilterRemapKeysList(_profile?.RemapKeys?.InProcessRemapKeys);
}
finally
{

View File

@@ -3,19 +3,21 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Text.Json;
using Microsoft.PowerToys.Settings.UI.Lib.Helpers;
using Microsoft.PowerToys.Settings.UI.Lib.Utilities;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
public class PowerLauncherViewModel : Observable
{
private GeneralSettings GeneralSettingsConfig { get; set; }
private readonly ISettingsUtils _settingsUtils;
private PowerLauncherSettings settings;
private GeneralSettings generalSettings;
public delegate void SendCallback(PowerLauncherSettings settings);
@@ -23,18 +25,32 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
private Func<string, int> SendConfigMSG { get; }
public PowerLauncherViewModel(ISettingsUtils settingsUtils, Func<string, int> ipcMSGCallBackFunc, int defaultKeyCode)
public PowerLauncherViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, Func<string, int> ipcMSGCallBackFunc, int defaultKeyCode)
{
_settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils));
// To obtain the general Settings configurations of PowerToys
if (settingsRepository == null)
{
throw new ArgumentNullException(nameof(settingsRepository));
}
GeneralSettingsConfig = settingsRepository.SettingsConfig;
// set the callback functions value to hangle outgoing IPC message.
SendConfigMSG = ipcMSGCallBackFunc;
callback = (PowerLauncherSettings settings) =>
{
// Propagate changes to Power Launcher through IPC
// Using InvariantCulture as this is an IPC message
SendConfigMSG(
string.Format("{{ \"powertoys\": {{ \"{0}\": {1} }} }}", PowerLauncherSettings.ModuleName, JsonSerializer.Serialize(settings)));
string.Format(
CultureInfo.InvariantCulture,
"{{ \"powertoys\": {{ \"{0}\": {1} }} }}",
PowerLauncherSettings.ModuleName,
JsonSerializer.Serialize(settings)));
};
if (_settingsUtils.SettingsExists(PowerLauncherSettings.ModuleName))
{
settings = _settingsUtils.GetSettings<PowerLauncherSettings>(PowerLauncherSettings.ModuleName);
@@ -47,15 +63,6 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
settings.Properties.MaximumNumberOfResults = 4;
callback(settings);
}
if (_settingsUtils.SettingsExists())
{
generalSettings = _settingsUtils.GetSettings<GeneralSettings>();
}
else
{
generalSettings = new GeneralSettings();
}
}
public PowerLauncherViewModel(PowerLauncherSettings settings, SendCallback callback)
@@ -76,16 +83,16 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
get
{
return generalSettings.Enabled.PowerLauncher;
return GeneralSettingsConfig.Enabled.PowerLauncher;
}
set
{
if (generalSettings.Enabled.PowerLauncher != value)
if (GeneralSettingsConfig.Enabled.PowerLauncher != value)
{
generalSettings.Enabled.PowerLauncher = value;
GeneralSettingsConfig.Enabled.PowerLauncher = value;
OnPropertyChanged(nameof(EnablePowerLauncher));
OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(generalSettings);
OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig);
SendConfigMSG(outgoing.ToString());
}
}

View File

@@ -5,15 +5,13 @@
using System;
using System.Runtime.CompilerServices;
using Microsoft.PowerToys.Settings.UI.Lib.Helpers;
using Microsoft.PowerToys.Settings.UI.Lib.Utilities;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
public class PowerPreviewViewModel : Observable
{
private readonly ISettingsUtils _settingsUtils;
private const string ModuleName = "File Explorer";
private const string ModuleName = PowerPreviewSettings.ModuleName;
private PowerPreviewSettings Settings { get; set; }
@@ -21,22 +19,30 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
private string _settingsConfigFileFolder = string.Empty;
public PowerPreviewViewModel(ISettingsUtils settingsUtils, Func<string, int> ipcMSGCallBackFunc, string configFileSubfolder = "")
private GeneralSettings GeneralSettingsConfig { get; set; }
public PowerPreviewViewModel(ISettingsRepository<PowerPreviewSettings> moduleSettingsRepository, ISettingsRepository<GeneralSettings> generalSettingsRepository, Func<string, int> ipcMSGCallBackFunc, string configFileSubfolder = "")
{
// Update Settings file folder:
_settingsConfigFileFolder = configFileSubfolder;
_settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils));
try
// To obtain the general Settings configurations of PowerToys
if (generalSettingsRepository == null)
{
Settings = _settingsUtils.GetSettings<PowerPreviewSettings>(GetSettingsSubPath());
throw new ArgumentNullException(nameof(generalSettingsRepository));
}
catch
GeneralSettingsConfig = generalSettingsRepository.SettingsConfig;
// To obtain the PowerPreview settings if it exists.
// If the file does not exist, to create a new one and return the default settings configurations.
if (moduleSettingsRepository == null)
{
Settings = new PowerPreviewSettings();
_settingsUtils.SaveSettings(Settings.ToJsonString(), GetSettingsSubPath());
throw new ArgumentNullException(nameof(moduleSettingsRepository));
}
Settings = moduleSettingsRepository.SettingsConfig;
// set the callback functions value to hangle outgoing IPC message.
SendConfigMSG = ipcMSGCallBackFunc;
@@ -45,9 +51,9 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
_mdRenderIsEnabled = Settings.Properties.EnableMdPreview;
}
private bool _svgRenderIsEnabled = false;
private bool _mdRenderIsEnabled = false;
private bool _svgThumbnailIsEnabled = false;
private bool _svgRenderIsEnabled;
private bool _mdRenderIsEnabled;
private bool _svgThumbnailIsEnabled;
public bool SVGRenderIsEnabled
{
@@ -108,6 +114,14 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
return _settingsConfigFileFolder + "\\" + ModuleName;
}
public bool IsElevated
{
get
{
return GeneralSettingsConfig.IsElevated;
}
}
private void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
// Notify UI of property change

View File

@@ -5,15 +5,17 @@
using System;
using System.Runtime.CompilerServices;
using Microsoft.PowerToys.Settings.UI.Lib.Helpers;
using Microsoft.PowerToys.Settings.UI.Lib.Utilities;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
public class PowerRenameViewModel : Observable
{
private GeneralSettings GeneralSettingsConfig { get; set; }
private readonly ISettingsUtils _settingsUtils;
private const string ModuleName = "PowerRename";
private const string ModuleName = PowerRenameSettings.ModuleName;
private string _settingsConfigFileFolder = string.Empty;
@@ -21,12 +23,19 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
private Func<string, int> SendConfigMSG { get; }
public PowerRenameViewModel(ISettingsUtils settingsUtils, Func<string, int> ipcMSGCallBackFunc, string configFileSubfolder = "")
public PowerRenameViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, Func<string, int> ipcMSGCallBackFunc, string configFileSubfolder = "")
{
// Update Settings file folder:
_settingsConfigFileFolder = configFileSubfolder;
_settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils));
if (settingsRepository == null)
{
throw new ArgumentNullException(nameof(settingsRepository));
}
GeneralSettingsConfig = settingsRepository.SettingsConfig;
try
{
PowerRenameLocalProperties localSettings = _settingsUtils.GetSettings<PowerRenameLocalProperties>(GetSettingsSubPath(), "power-rename-settings.json");
@@ -47,27 +56,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
_powerRenameRestoreFlagsOnLaunch = Settings.Properties.PersistState.Value;
_powerRenameMaxDispListNumValue = Settings.Properties.MaxMRUSize.Value;
_autoComplete = Settings.Properties.MRUEnabled.Value;
GeneralSettings generalSettings;
try
{
generalSettings = _settingsUtils.GetSettings<GeneralSettings>(string.Empty);
}
catch
{
generalSettings = new GeneralSettings();
_settingsUtils.SaveSettings(generalSettings.ToJsonString(), string.Empty);
}
_powerRenameEnabled = generalSettings.Enabled.PowerRename;
_powerRenameEnabled = GeneralSettingsConfig.Enabled.PowerRename;
}
private bool _powerRenameEnabled = false;
private bool _powerRenameEnabledOnContextMenu = false;
private bool _powerRenameEnabledOnContextExtendedMenu = false;
private bool _powerRenameRestoreFlagsOnLaunch = false;
private int _powerRenameMaxDispListNumValue = 0;
private bool _autoComplete = false;
private bool _powerRenameEnabled;
private bool _powerRenameEnabledOnContextMenu;
private bool _powerRenameEnabledOnContextExtendedMenu;
private bool _powerRenameRestoreFlagsOnLaunch;
private int _powerRenameMaxDispListNumValue;
private bool _autoComplete;
public bool IsEnabled
{
@@ -80,14 +77,14 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
if (value != _powerRenameEnabled)
{
GeneralSettings generalSettings = _settingsUtils.GetSettings<GeneralSettings>(string.Empty);
generalSettings.Enabled.PowerRename = value;
OutGoingGeneralSettings snd = new OutGoingGeneralSettings(generalSettings);
GeneralSettingsConfig.Enabled.PowerRename = value;
OutGoingGeneralSettings snd = new OutGoingGeneralSettings(GeneralSettingsConfig);
SendConfigMSG(snd.ToString());
_powerRenameEnabled = value;
OnPropertyChanged("IsEnabled");
RaisePropertyChanged("GlobalAndMruEnabled");
OnPropertyChanged(nameof(IsEnabled));
RaisePropertyChanged(nameof(GlobalAndMruEnabled));
}
}
}
@@ -106,7 +103,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
_autoComplete = value;
Settings.Properties.MRUEnabled.Value = value;
RaisePropertyChanged();
RaisePropertyChanged("GlobalAndMruEnabled");
RaisePropertyChanged(nameof(GlobalAndMruEnabled));
}
}
}

View File

@@ -5,54 +5,48 @@
using System;
using System.Runtime.CompilerServices;
using Microsoft.PowerToys.Settings.UI.Lib.Helpers;
using Microsoft.PowerToys.Settings.UI.Lib.Utilities;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
public class ShortcutGuideViewModel : Observable
{
private readonly ISettingsUtils _settingsUtils;
private GeneralSettings GeneralSettingsConfig { get; set; }
private ShortcutGuideSettings Settings { get; set; }
private const string ModuleName = "Shortcut Guide";
private const string ModuleName = ShortcutGuideSettings.ModuleName;
private Func<string, int> SendConfigMSG { get; }
private string _settingsConfigFileFolder = string.Empty;
public ShortcutGuideViewModel(ISettingsUtils settingsUtils, Func<string, int> ipcMSGCallBackFunc, string configFileSubfolder = "")
public ShortcutGuideViewModel(ISettingsRepository<GeneralSettings> settingsRepository, ISettingsRepository<ShortcutGuideSettings> moduleSettingsRepository, Func<string, int> ipcMSGCallBackFunc, string configFileSubfolder = "")
{
// Update Settings file folder:
_settingsConfigFileFolder = configFileSubfolder;
_settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils));
try
// To obtain the general PowerToys settings.
if (settingsRepository == null)
{
Settings = _settingsUtils.GetSettings<ShortcutGuideSettings>(GetSettingsSubPath());
}
catch
{
Settings = new ShortcutGuideSettings();
_settingsUtils.SaveSettings(Settings.ToJsonString(), GetSettingsSubPath());
throw new ArgumentNullException(nameof(settingsRepository));
}
GeneralSettings generalSettings;
GeneralSettingsConfig = settingsRepository.SettingsConfig;
try
// To obtain the shortcut guide settings, if the file exists.
// If not, to create a file with the default settings and to return the default configurations.
if (moduleSettingsRepository == null)
{
generalSettings = _settingsUtils.GetSettings<GeneralSettings>(string.Empty);
}
catch
{
generalSettings = new GeneralSettings();
_settingsUtils.SaveSettings(generalSettings.ToJsonString(), string.Empty);
throw new ArgumentNullException(nameof(moduleSettingsRepository));
}
Settings = moduleSettingsRepository.SettingsConfig;
// set the callback functions value to hangle outgoing IPC message.
SendConfigMSG = ipcMSGCallBackFunc;
_isEnabled = generalSettings.Enabled.ShortcutGuide;
_isEnabled = GeneralSettingsConfig.Enabled.ShortcutGuide;
_pressTime = Settings.Properties.PressTime.Value;
_opacity = Settings.Properties.OverlayOpacity.Value;
@@ -74,10 +68,10 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
}
}
private bool _isEnabled = false;
private int _themeIndex = 0;
private int _pressTime = 0;
private int _opacity = 0;
private bool _isEnabled;
private int _themeIndex;
private int _pressTime;
private int _opacity;
public bool IsEnabled
{
@@ -91,11 +85,13 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
if (value != _isEnabled)
{
_isEnabled = value;
GeneralSettings generalSettings = _settingsUtils.GetSettings<GeneralSettings>(string.Empty);
generalSettings.Enabled.ShortcutGuide = value;
OutGoingGeneralSettings snd = new OutGoingGeneralSettings(generalSettings);
// To update the status of shortcut guide in General PowerToy settings.
GeneralSettingsConfig.Enabled.ShortcutGuide = value;
OutGoingGeneralSettings snd = new OutGoingGeneralSettings(GeneralSettingsConfig);
SendConfigMSG(snd.ToString());
OnPropertyChanged("IsEnabled");
OnPropertyChanged(nameof(IsEnabled));
}
}
}
@@ -116,7 +112,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
// set theme to dark.
Settings.Properties.Theme.Value = "dark";
_themeIndex = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
if (value == 1)
@@ -124,7 +120,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
// set theme to light.
Settings.Properties.Theme.Value = "light";
_themeIndex = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
if (value == 2)
@@ -132,7 +128,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
// set theme to system default.
Settings.Properties.Theme.Value = "system";
_themeIndex = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -151,7 +147,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
_pressTime = value;
Settings.Properties.PressTime.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -169,7 +165,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
{
_opacity = value;
Settings.Properties.OverlayOpacity.Value = value;
RaisePropertyChanged();
NotifyPropertyChanged();
}
}
}
@@ -179,7 +175,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
return _settingsConfigFileFolder + "\\" + ModuleName;
}
public void RaisePropertyChanged([CallerMemberName] string propertyName = null)
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
OnPropertyChanged(propertyName);
SndShortcutGuideSettings outsettings = new SndShortcutGuideSettings(Settings);

View File

@@ -30,6 +30,12 @@ namespace Microsoft.PowerToys.Settings.UI.Runner
private void WindowsXamlHost_ChildChanged(object sender, EventArgs e)
{
// If sender is null, it could lead to a NullReferenceException. This might occur on restarting as admin (check https://github.com/microsoft/PowerToys/issues/7393 for details)
if (sender == null)
{
return;
}
// Hook up x:Bind source.
WindowsXamlHost windowsXamlHost = sender as WindowsXamlHost;
ShellPage shellPage = windowsXamlHost.GetUwpInternalObject() as ShellPage;

View File

@@ -0,0 +1,87 @@
using Microsoft.PowerToys.Settings.UI.Lib;
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
using Microsoft.PowerToys.Settings.UI.Lib.Utilities;
using Microsoft.PowerToys.Settings.UI.UnitTests.Mocks;
using Moq;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq.Expressions;
using System.Text;
namespace Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility
{
public static class BackCompatTestProperties
{
public const string RootPathStubFiles = "..\\..\\..\\..\\src\\core\\Microsoft.PowerToys.Settings.UI.UnitTests\\BackwardsCompatibility\\TestFiles\\{0}\\Microsoft\\PowerToys\\{1}\\{2}";
internal class MockSettingsRepository<T> : ISettingsRepository<T> where T : ISettingsConfig, new()
{
T _settingsConfig;
readonly ISettingsUtils _settingsUtils;
public MockSettingsRepository( ISettingsUtils settingsUtils)
{
_settingsUtils = settingsUtils;
}
public T SettingsConfig
{
get
{
T settingsItem = new T();
_settingsConfig = _settingsUtils.GetSettings<T>(settingsItem.GetModuleName());
return _settingsConfig;
}
set
{
if (value != null)
{
_settingsConfig = value;
}
}
}
}
public static Mock<IIOProvider>GetModuleIOProvider(string version, string module, string fileName)
{
var stubSettingsPath = string.Format(CultureInfo.InvariantCulture, BackCompatTestProperties.RootPathStubFiles, version, module, fileName);
Expression<Func<string, bool>> filterExpression = (string s) => s.Contains(module, StringComparison.Ordinal);
var mockIOProvider = IIOProviderMocks.GetMockIOReadWithStubFile(stubSettingsPath, filterExpression);
return mockIOProvider;
}
public static void VerifyModuleIOProviderWasRead(Mock<IIOProvider> provider, string module, int expectedCallCount)
{
if(provider == null)
{
throw new ArgumentNullException(nameof(provider));
}
Expression<Func<string, bool>> filterExpression = (string s) => s.Contains(module, StringComparison.Ordinal);
IIOProviderMocks.VerifyIOReadWithStubFile(provider, filterExpression, expectedCallCount);
}
public static Mock<IIOProvider> GetGeneralSettingsIOProvider(string version)
{
var stubGeneralSettingsPath = string.Format(CultureInfo.InvariantCulture, BackCompatTestProperties.RootPathStubFiles, version, string.Empty, "settings.json");
Expression<Func<string, bool>> filterExpression = (string s) => s.Contains("Microsoft\\PowerToys\\settings.json", StringComparison.Ordinal);
var mockGeneralIOProvider = IIOProviderMocks.GetMockIOReadWithStubFile(stubGeneralSettingsPath, filterExpression);
return mockGeneralIOProvider;
}
public static void VerifyGeneralSettingsIOProviderWasRead(Mock<IIOProvider> provider, int expectedCallCount)
{
if (provider == null)
{
throw new ArgumentNullException(nameof(provider));
}
Expression<Func<string, bool>> filterExpression = (string s) => s.Contains("Microsoft\\PowerToys\\settings.json", StringComparison.Ordinal);
IIOProviderMocks.VerifyIOReadWithStubFile(provider, filterExpression, expectedCallCount);
}
}
}

View File

@@ -0,0 +1 @@
{"properties":{"ActivationShortcut":{"win":false,"ctrl":false,"alt":false,"shift":true,"code":222,"key":""},"changecursor":{"value":false},"copiedcolorrepresentation":1},"name":"ColorPicker","version":"1.0"}

View File

@@ -0,0 +1 @@
{"version":"1.0","name":"FancyZones","properties":{"fancyzones_shiftDrag":{"value":false},"fancyzones_mouseSwitch":{"value":true},"fancyzones_overrideSnapHotkeys":{"value":true},"fancyzones_moveWindowAcrossMonitors":{"value":true},"fancyzones_moveWindowsBasedOnPosition":{"value":true},"fancyzones_displayChange_moveWindows":{"value":true},"fancyzones_zoneSetChange_moveWindows":{"value":true},"fancyzones_appLastZone_moveWindows":{"value":true},"fancyzones_openWindowOnActiveMonitor":{"value":true},"fancyzones_restoreSize":{"value":true},"use_cursorpos_editor_startupscreen":{"value":false},"fancyzones_show_on_all_monitors":{"value":true},"fancyzones_span_zones_across_monitors":{"value":true},"fancyzones_makeDraggedWindowTransparent":{"value":true},"fancyzones_zoneColor":{"value":"#B53AFF"},"fancyzones_zoneBorderColor":{"value":"#FF6508"},"fancyzones_zoneHighlightColor":{"value":"#9BD7D6"},"fancyzones_highlight_opacity":{"value":26},"fancyzones_editor_hotkey":{"value":{"win":false,"ctrl":false,"alt":false,"shift":true,"code":80,"key":""}},"fancyzones_excluded_apps":{"value":""}}}

View File

@@ -0,0 +1 @@
{"Properties":{"svg-previewer-toggle-setting":{"value":false},"svg-thumbnail-toggle-setting":{"value":false},"md-previewer-toggle-setting":{"value":false}},"name":"File Explorer","version":"1.0"}

View File

@@ -0,0 +1,92 @@
{
"properties": {
"imageresizer_selectedSizeIndex": {
"value": 0
},
"imageresizer_shrinkOnly": {
"value": false
},
"imageresizer_replace": {
"value": false
},
"imageresizer_ignoreOrientation": {
"value": true
},
"imageresizer_jpegQualityLevel": {
"value": 92
},
"imageresizer_pngInterlaceOption": {
"value": 1
},
"imageresizer_tiffCompressOption": {
"value": 4
},
"imageresizer_fileName": {
"value": "%1 (%2)"
},
"imageresizer_sizes": {
"value": [
{
"Id": 0,
"ExtraBoxOpacity": 100,
"EnableEtraBoxes": true,
"name": "Small",
"fit": 1,
"width": 853,
"height": 479,
"unit": 3
},
{
"Id": 1,
"ExtraBoxOpacity": 100,
"EnableEtraBoxes": true,
"name": "Medium",
"fit": 1,
"width": 1365,
"height": 767,
"unit": 3
},
{
"Id": 2,
"ExtraBoxOpacity": 100,
"EnableEtraBoxes": true,
"name": "Large",
"fit": 1,
"width": 1919,
"height": 1079,
"unit": 3
},
{
"Id": 3,
"ExtraBoxOpacity": 100,
"EnableEtraBoxes": true,
"name": "Phone",
"fit": 1,
"width": 319,
"height": 567,
"unit": 3
}
]
},
"imageresizer_keepDateModified": {
"value": true
},
"imageresizer_fallbackEncoder": {
"value": "163bcc30-e2e9-4f0b-961d-a3e9fdb788a3"
},
"imageresizer_customSize": {
"value": {
"Id": 4,
"ExtraBoxOpacity": 100,
"EnableEtraBoxes": true,
"name": "custom",
"fit": 1,
"width": 1024,
"height": 640,
"unit": 3
}
}
},
"name": "Image Resizer",
"version": "1"
}

View File

@@ -0,0 +1,44 @@
{
"value": [
{
"Id": 0,
"ExtraBoxOpacity": 100,
"EnableEtraBoxes": true,
"name": "Small",
"fit": 1,
"width": 853,
"height": 479,
"unit": 3
},
{
"Id": 1,
"ExtraBoxOpacity": 100,
"EnableEtraBoxes": true,
"name": "Medium",
"fit": 1,
"width": 1365,
"height": 767,
"unit": 3
},
{
"Id": 2,
"ExtraBoxOpacity": 100,
"EnableEtraBoxes": true,
"name": "Large",
"fit": 1,
"width": 1919,
"height": 1079,
"unit": 3
},
{
"Id": 3,
"ExtraBoxOpacity": 100,
"EnableEtraBoxes": true,
"name": "Phone",
"fit": 1,
"width": 319,
"height": 567,
"unit": 3
}
]
}

View File

@@ -0,0 +1 @@
{"remapKeys":{"inProcess":[{"originalKeys":"83","newRemapKeys":"65"}]},"remapShortcuts":{"global":[{"originalKeys":"160;70","newRemapKeys":"160;20"}],"appSpecific":[]}}

View File

@@ -0,0 +1 @@
{"properties":{"activeConfiguration":{"value":"default"},"keyboardConfigurations":{"value":["default"]}},"name":"Keyboard Manager","version":"1"}

View File

@@ -0,0 +1 @@
{"Enabled":false,"ShowIcon":false,"ExtendedContextMenuOnly":true,"PersistState":false,"MRUEnabled":true,"MaxMRUSize":13,"SearchText":"","ReplaceText":""}

View File

@@ -0,0 +1 @@
{"properties":{"search_result_preference":"most_recently_used","search_type_preference":"application_name","maximum_number_of_results":8,"open_powerlauncher":{"win":false,"ctrl":false,"alt":false,"shift":true,"code":186,"key":""},"open_file_location":{"win":false,"ctrl":false,"alt":false,"shift":false,"code":0,"key":""},"copy_path_location":{"win":false,"ctrl":false,"alt":false,"shift":false,"code":0,"key":""},"open_console":{"win":false,"ctrl":false,"alt":false,"shift":false,"code":0,"key":""},"override_win_r_key":false,"override_win_s_key":false,"ignore_hotkeys_in_fullscreen":false,"disable_drive_detection_warning":true,"clear_input_on_launch":true},"name":"PowerToys Run","version":"1.0"}

View File

@@ -0,0 +1 @@
{"properties":{"overlay_opacity":{"value":36},"press_time":{"value":1050},"theme":{"value":"dark"}},"name":"Shortcut Guide","version":"1.0"}

View File

@@ -0,0 +1 @@
{"packaged":false,"startup":false,"enabled":{"ColorPicker":false,"FancyZones":false,"File Explorer":true,"Image Resizer":false,"Keyboard Manager":false,"PowerRename":false,"PowerToys Run":false,"Shortcut Guide":false},"is_elevated":false,"run_elevated":false,"download_updates_automatically":false,"is_admin":true,"theme":"light","system_theme":"dark","powertoys_version":"v0.21.1"}

View File

@@ -0,0 +1 @@
{"github_update_last_checked_date":"1601059000","pending_update":false,"pending_installer_filename":""}

View File

@@ -0,0 +1 @@
{"properties":{"ActivationShortcut":{"win":true,"ctrl":false,"alt":false,"shift":true,"code":67,"key":""},"changecursor":{"value":false},"copiedcolorrepresentation":0},"name":"ColorPicker","version":"1"}

View File

@@ -0,0 +1 @@
{"version":"1.0","name":"FancyZones","properties":{"fancyzones_shiftDrag":{"value":false},"fancyzones_mouseSwitch":{"value":true},"fancyzones_overrideSnapHotkeys":{"value":true},"fancyzones_moveWindowAcrossMonitors":{"value":true},"fancyzones_displayChange_moveWindows":{"value":true},"fancyzones_zoneSetChange_moveWindows":{"value":true},"fancyzones_virtualDesktopChange_moveWindows":{"value":true},"fancyzones_appLastZone_moveWindows":{"value":true},"use_cursorpos_editor_startupscreen":{"value":false},"fancyzones_show_on_all_monitors":{"value":true},"fancyzones_makeDraggedWindowTransparent":{"value":true},"fancyzones_zoneColor":{"value":"#F5FCFF"},"fancyzones_zoneBorderColor":{"value":"#365E5C"},"fancyzones_zoneHighlightColor":{"value":"#D77F70"},"fancyzones_highlight_opacity":{"value":93},"fancyzones_editor_hotkey":{"value":{"win":false,"ctrl":false,"alt":false,"shift":true,"key":"D","code":68}},"fancyzones_excluded_apps":{"value":""}}}

View File

@@ -0,0 +1 @@
{"app-zone-history":[],"devices":[{"device-id":"LEN4140#4&2cf01444&0&UID265988_1920_1200_{FAD9BC94-3335-41ED-A550-A14A1B4E2FB7}","active-zoneset":{"uuid":"{0C77400D-EBC4-40EB-A820-262706297DD0}","type":"priority-grid"},"editor-show-spacing":true,"editor-spacing":16,"editor-zone-count":3}],"custom-zone-sets":[]}

View File

@@ -0,0 +1 @@
{"properties":{"svg-previewer-toggle-setting":{"value":false},"md-previewer-toggle-setting":{"value":false}},"name":"File Explorer","version":"1.0"}

View File

@@ -0,0 +1,82 @@
{
"version": "1",
"name": "Image Resizer",
"properties": {
"imageresizer_selectedSizeIndex": {
"value": 0
},
"imageresizer_shrinkOnly": {
"value": false
},
"imageresizer_replace": {
"value": false
},
"imageresizer_ignoreOrientation": {
"value": true
},
"imageresizer_jpegQualityLevel": {
"value": 89
},
"imageresizer_pngInterlaceOption": {
"value": 2
},
"imageresizer_tiffCompressOption": {
"value": 2
},
"imageresizer_fileName": {
"value": "%1 (%2)"
},
"imageresizer_sizes": {
"value": [
{
"Id": 0,
"name": "Small",
"fit": 1,
"width": 1,
"height": 1,
"unit": 3
},
{
"Id": 1,
"name": "Medium",
"fit": 1,
"width": 1,
"height": 1,
"unit": 3
},
{
"Id": 2,
"name": "Large",
"fit": 1,
"width": 1,
"height": 1,
"unit": 3
},
{
"Id": 3,
"name": "Phone",
"fit": 1,
"width": 1,
"height": 1,
"unit": 3
}
]
},
"imageresizer_keepDateModified": {
"value": true
},
"imageresizer_fallbackEncoder": {
"value": "163bcc30-e2e9-4f0b-961d-a3e9fdb788a3"
},
"imageresizer_customSize": {
"value": {
"Id": 4,
"name": "custom",
"fit": 1,
"width": 1024,
"height": 640,
"unit": 3
}
}
}
}

View File

@@ -0,0 +1,36 @@
{
"value": [
{
"Id": 0,
"name": "Small",
"fit": 1,
"width": 1,
"height": 1,
"unit": 3
},
{
"Id": 1,
"name": "Medium",
"fit": 1,
"width": 1,
"height": 1,
"unit": 3
},
{
"Id": 2,
"name": "Large",
"fit": 1,
"width": 1,
"height": 1,
"unit": 3
},
{
"Id": 3,
"name": "Phone",
"fit": 1,
"width": 1,
"height": 1,
"unit": 3
}
]
}

View File

@@ -0,0 +1 @@
{"remapKeys":{"inProcess":[{"originalKeys":"65","newRemapKeys":"105"}]},"remapShortcuts":{"global":[{"originalKeys":"160;70","newRemapKeys":"160;82"}]}}

View File

@@ -0,0 +1 @@
{"properties":{"activeConfiguration":{"value":"default"},"keyboardConfigurations":{"value":["default"]}},"name":"Keyboard Manager","version":"1"}

View File

@@ -0,0 +1 @@
{"Enabled":false,"ShowIcon":false,"ExtendedContextMenuOnly":true,"PersistState":false,"MRUEnabled":true,"MaxMRUSize":8,"SearchText":"","ReplaceText":""}

View File

@@ -0,0 +1 @@
{"properties":{"search_result_preference":"most_recently_used","search_type_preference":"application_name","maximum_number_of_results":10,"open_powerlauncher":{"win":false,"ctrl":false,"alt":false,"shift":true,"key":"P","code":80},"open_file_location":{"win":false,"ctrl":false,"alt":false,"shift":false,"key":"","code":0},"copy_path_location":{"win":false,"ctrl":false,"alt":false,"shift":false,"key":"","code":0},"open_console":{"win":false,"ctrl":false,"alt":false,"shift":false,"key":"","code":0},"override_win_r_key":false,"override_win_s_key":false},"name":"PowerToys Run","version":"1.0"}

View File

@@ -0,0 +1 @@
{"name":"Shortcut Guide","properties":{"overlay_opacity":{"value":51},"press_time":{"value":100},"theme":{"value":"dark"}},"version":"1.0"}

View File

@@ -0,0 +1 @@
{"packaged":false,"startup":false,"enabled":{"FancyZones":false,"File Explorer":true,"Image Resizer":false,"Keyboard Manager":false,"PowerRename":false,"PowerToys Run":false,"Shortcut Guide":false},"is_elevated":false,"run_elevated":false,"download_updates_automatically":false,"is_admin":true,"theme":"dark","system_theme":"dark","powertoys_version":"v0.18.2"}

View File

@@ -0,0 +1 @@
{"github_update_last_checked_date":"1601047811","pending_update":false}

View File

@@ -0,0 +1 @@
{"version":"1.0","name":"FancyZones","properties":{"fancyzones_shiftDrag":{"value":true},"fancyzones_mouseSwitch":{"value":false},"fancyzones_overrideSnapHotkeys":{"value":false},"fancyzones_moveWindowAcrossMonitors":{"value":false},"fancyzones_displayChange_moveWindows":{"value":false},"fancyzones_zoneSetChange_moveWindows":{"value":false},"fancyzones_appLastZone_moveWindows":{"value":false},"use_cursorpos_editor_startupscreen":{"value":true},"fancyzones_show_on_all_monitors":{"value":false},"fancyzones_makeDraggedWindowTransparent":{"value":false},"fancyzones_zoneColor":{"value":"#F5FCFF"},"fancyzones_zoneBorderColor":{"value":"#FFFFFF"},"fancyzones_zoneHighlightColor":{"value":"#0078D7"},"fancyzones_highlight_opacity":{"value":50},"fancyzones_editor_hotkey":{"value":{"win":true,"ctrl":false,"alt":false,"shift":false,"key":"`","code":192}},"fancyzones_excluded_apps":{"value":""}}}

View File

@@ -0,0 +1 @@
{"properties":{"svg-previewer-toggle-setting":{"value":false},"md-previewer-toggle-setting":{"value":false}},"name":"File Explorer","version":"1.0"}

View File

@@ -0,0 +1,92 @@
{
"version": "1",
"name": "Image Resizer",
"properties": {
"imageresizer_selectedSizeIndex": {
"value": 0
},
"imageresizer_shrinkOnly": {
"value": false
},
"imageresizer_replace": {
"value": false
},
"imageresizer_ignoreOrientation": {
"value": true
},
"imageresizer_jpegQualityLevel": {
"value": 89
},
"imageresizer_pngInterlaceOption": {
"value": 1
},
"imageresizer_tiffCompressOption": {
"value": 2
},
"imageresizer_fileName": {
"value": "%1 (%2)"
},
"imageresizer_sizes": {
"value": [
{
"Id": 0,
"ExtraBoxOpacity": 100,
"EnableEtraBoxes": true,
"name": "Small",
"fit": 1,
"width": 850,
"height": 480,
"unit": 3
},
{
"Id": 1,
"ExtraBoxOpacity": 100,
"EnableEtraBoxes": true,
"name": "Medium",
"fit": 1,
"width": 1363,
"height": 768,
"unit": 3
},
{
"Id": 2,
"ExtraBoxOpacity": 100,
"EnableEtraBoxes": true,
"name": "Large",
"fit": 1,
"width": 1917,
"height": 1080,
"unit": 3
},
{
"Id": 3,
"ExtraBoxOpacity": 100,
"EnableEtraBoxes": true,
"name": "Phone",
"fit": 1,
"width": 316,
"height": 568,
"unit": 3
}
]
},
"imageresizer_keepDateModified": {
"value": true
},
"imageresizer_fallbackEncoder": {
"value": "57a37caa-367a-4540-916b-f183c5093a4b"
},
"imageresizer_customSize": {
"value": {
"Id": 4,
"ExtraBoxOpacity": 100,
"EnableEtraBoxes": true,
"name": "custom",
"fit": 1,
"width": 1024,
"height": 640,
"unit": 3
}
}
}
}

View File

@@ -0,0 +1,44 @@
{
"value": [
{
"Id": 0,
"ExtraBoxOpacity": 100,
"EnableEtraBoxes": true,
"name": "Small",
"fit": 1,
"width": 850,
"height": 480,
"unit": 3
},
{
"Id": 1,
"ExtraBoxOpacity": 100,
"EnableEtraBoxes": true,
"name": "Medium",
"fit": 1,
"width": 1363,
"height": 768,
"unit": 3
},
{
"Id": 2,
"ExtraBoxOpacity": 100,
"EnableEtraBoxes": true,
"name": "Large",
"fit": 1,
"width": 1917,
"height": 1080,
"unit": 3
},
{
"Id": 3,
"ExtraBoxOpacity": 100,
"EnableEtraBoxes": true,
"name": "Phone",
"fit": 1,
"width": 316,
"height": 568,
"unit": 3
}
]
}

View File

@@ -0,0 +1 @@
{"remapKeys":{"inProcess":[{"originalKeys":"68","newRemapKeys":"65"}]},"remapShortcuts":{"global":[{"originalKeys":"160;20","newRemapKeys":"160;9"}]}}

View File

@@ -0,0 +1 @@
{"properties":{"activeConfiguration":{"value":"default"},"keyboardConfigurations":{"value":["default"]}},"name":"Keyboard Manager","version":"1"}

View File

@@ -0,0 +1 @@
{"Enabled":false,"ShowIcon":false,"ExtendedContextMenuOnly":true,"PersistState":false,"MRUEnabled":false,"MaxMRUSize":10,"SearchText":"","ReplaceText":""}

View File

@@ -0,0 +1 @@
{"properties":{"search_result_preference":"most_recently_used","search_type_preference":"application_name","maximum_number_of_results":8,"open_powerlauncher":{"win":false,"ctrl":false,"alt":false,"shift":true,"key":"P","code":80},"open_file_location":{"win":false,"ctrl":false,"alt":false,"shift":false,"key":"","code":0},"copy_path_location":{"win":false,"ctrl":false,"alt":false,"shift":false,"key":"","code":0},"open_console":{"win":false,"ctrl":false,"alt":false,"shift":false,"key":"","code":0},"override_win_r_key":false,"override_win_s_key":false,"ignore_hotkeys_in_fullscreen":true},"name":"PowerToys Run","version":"1.0"}

Some files were not shown because too many files have changed in this diff Show More