mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 02:36:19 +02:00
Use WinRT JSON parser instead of custom cpprestsdk solution (#822)
This commit is contained in:
@@ -15,48 +15,45 @@ namespace UnitTestsCommonLib
|
||||
TEST_METHOD(LoadFromJsonBoolTrue)
|
||||
{
|
||||
PowerToyValues values = PowerToyValues::from_json_string(m_json);
|
||||
Assert::IsTrue(values.is_bool_value(L"bool_toggle_true"));
|
||||
|
||||
bool value = values.get_bool_value(L"bool_toggle_true");
|
||||
Assert::AreEqual(true, value);
|
||||
auto value = values.get_bool_value(L"bool_toggle_true");
|
||||
Assert::IsTrue(value.has_value());
|
||||
Assert::AreEqual(true, *value);
|
||||
}
|
||||
|
||||
TEST_METHOD(LoadFromJsonBoolFalse)
|
||||
{
|
||||
PowerToyValues values = PowerToyValues::from_json_string(m_json);
|
||||
Assert::IsTrue(values.is_bool_value(L"bool_toggle_false"));
|
||||
|
||||
bool value = values.get_bool_value(L"bool_toggle_false");
|
||||
Assert::AreEqual(false, value);
|
||||
auto value = values.get_bool_value(L"bool_toggle_false");
|
||||
Assert::IsTrue(value.has_value());
|
||||
Assert::AreEqual(false, *value);
|
||||
}
|
||||
|
||||
TEST_METHOD(LoadFromJsonInt)
|
||||
{
|
||||
PowerToyValues values = PowerToyValues::from_json_string(m_json);
|
||||
Assert::IsTrue(values.is_int_value(L"int_spinner"));
|
||||
|
||||
int value = values.get_int_value(L"int_spinner");
|
||||
Assert::AreEqual(10, value);
|
||||
auto value = values.get_int_value(L"int_spinner");
|
||||
Assert::IsTrue(value.has_value());
|
||||
Assert::AreEqual(10, *value);
|
||||
}
|
||||
|
||||
TEST_METHOD(LoadFromJsonString)
|
||||
{
|
||||
PowerToyValues values = PowerToyValues::from_json_string(m_json);
|
||||
Assert::IsTrue(values.is_string_value(L"string_text"));
|
||||
auto value = values.get_string_value(L"string_text");
|
||||
|
||||
std::wstring value = values.get_string_value(L"string_text");
|
||||
Assert::IsTrue(value.has_value());
|
||||
std::wstring expected = L"a quick fox";
|
||||
Assert::AreEqual(expected, value);
|
||||
Assert::AreEqual(expected, *value);
|
||||
}
|
||||
|
||||
TEST_METHOD(LoadFromJsonColorPicker)
|
||||
{
|
||||
PowerToyValues values = PowerToyValues::from_json_string(m_json);
|
||||
Assert::IsTrue(values.is_string_value(L"color_picker"));
|
||||
auto value = values.get_string_value(L"color_picker");
|
||||
|
||||
std::wstring value = values.get_string_value(L"color_picker");
|
||||
Assert::IsTrue(value.has_value());
|
||||
std::wstring expected = L"#ff8d12";
|
||||
Assert::AreEqual(expected, value);
|
||||
Assert::AreEqual(expected, *value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -98,6 +98,7 @@
|
||||
<ClInclude Include="d2d_window.h" />
|
||||
<ClInclude Include="dpi_aware.h" />
|
||||
<ClInclude Include="hwnd_data_cache.h" />
|
||||
<ClInclude Include="json.h" />
|
||||
<ClInclude Include="monitors.h" />
|
||||
<ClInclude Include="on_thread_executor.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
@@ -119,6 +120,7 @@
|
||||
<ClCompile Include="d2d_window.cpp" />
|
||||
<ClCompile Include="dpi_aware.cpp" />
|
||||
<ClCompile Include="hwnd_data_cache.cpp" />
|
||||
<ClCompile Include="json.cpp" />
|
||||
<ClCompile Include="monitors.cpp" />
|
||||
<ClCompile Include="on_thread_executor.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
@@ -132,11 +134,6 @@
|
||||
<ClCompile Include="common.cpp" />
|
||||
<ClCompile Include="windows_colors.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\deps\cpprestsdk\cpprestsdk.vcxproj">
|
||||
<Project>{4e577735-dfab-41af-8a6e-b6e8872a2928}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
||||
@@ -75,6 +75,9 @@
|
||||
<ClInclude Include="hwnd_data_cache.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="json.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="d2d_svg.cpp">
|
||||
@@ -120,5 +123,8 @@
|
||||
<ClCompile Include="hwnd_data_cache.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="json.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
26
src/common/json.cpp
Normal file
26
src/common/json.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "pch.h"
|
||||
#include "json.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace json
|
||||
{
|
||||
std::optional<JsonObject> from_file(std::wstring_view file_name)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::wifstream file(file_name.data(), std::ios::binary);
|
||||
using isbi = std::istreambuf_iterator<wchar_t>;
|
||||
return JsonValue::Parse(std::wstring{isbi{file}, isbi{}}).GetObjectW();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
void to_file(std::wstring_view file_name, const JsonObject & obj)
|
||||
{
|
||||
std::wofstream{file_name.data(), std::ios::binary} << obj.Stringify().c_str();
|
||||
}
|
||||
}
|
||||
50
src/common/json.h
Normal file
50
src/common/json.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Data.Json.h>
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace json
|
||||
{
|
||||
using namespace winrt::Windows::Data::Json;
|
||||
|
||||
std::optional<JsonObject> from_file(std::wstring_view file_name);
|
||||
|
||||
void to_file(std::wstring_view file_name, const JsonObject& obj);
|
||||
|
||||
inline bool has(
|
||||
const json::JsonObject & o,
|
||||
std::wstring_view name,
|
||||
const json::JsonValueType type = JsonValueType::Object)
|
||||
{
|
||||
return o.HasKey(name) && o.GetNamedValue(name).ValueType() == type;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::enable_if_t<std::is_arithmetic_v<T>, JsonValue> value(const T arithmetic)
|
||||
{
|
||||
return json::JsonValue::CreateNumberValue(arithmetic);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::enable_if_t<!std::is_arithmetic_v<T>, JsonValue> value(T s)
|
||||
{
|
||||
return json::JsonValue::CreateStringValue(s);
|
||||
}
|
||||
|
||||
inline JsonValue value(const bool boolean)
|
||||
{
|
||||
return json::JsonValue::CreateBooleanValue(boolean);
|
||||
}
|
||||
|
||||
inline JsonValue value(JsonObject value)
|
||||
{
|
||||
return value.as<JsonValue>();
|
||||
}
|
||||
|
||||
inline JsonValue value(JsonValue value)
|
||||
{
|
||||
return value; // identity function overload for convenience
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,13 @@
|
||||
#include <fstream>
|
||||
|
||||
namespace PTSettingsHelper {
|
||||
|
||||
constexpr inline const wchar_t * settings_filename = L"\\settings.json";
|
||||
|
||||
std::wstring get_root_save_folder_location() {
|
||||
PWSTR local_app_path;
|
||||
std::wstring result(L"");
|
||||
|
||||
winrt::check_hresult(SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &local_app_path));
|
||||
result = std::wstring(local_app_path);
|
||||
std::wstring result{local_app_path};
|
||||
CoTaskMemFree(local_app_path);
|
||||
|
||||
result += L"\\Microsoft\\PowerToys";
|
||||
@@ -20,7 +21,7 @@ namespace PTSettingsHelper {
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring get_module_save_folder_location(const std::wstring& powertoy_name) {
|
||||
std::wstring get_module_save_folder_location(std::wstring_view powertoy_name) {
|
||||
std::wstring result = get_root_save_folder_location();
|
||||
result += L"\\";
|
||||
result += powertoy_name;
|
||||
@@ -31,45 +32,33 @@ namespace PTSettingsHelper {
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring get_module_save_file_location(const std::wstring& powertoy_name) {
|
||||
std::wstring result = get_module_save_folder_location(powertoy_name);
|
||||
result += L"\\settings.json";
|
||||
return result;
|
||||
std::wstring get_module_save_file_location(std::wstring_view powertoy_name) {
|
||||
return get_module_save_folder_location(powertoy_name) + settings_filename;
|
||||
}
|
||||
|
||||
std::wstring get_powertoys_general_save_file_location() {
|
||||
std::wstring result = get_root_save_folder_location();
|
||||
result += L"\\settings.json";
|
||||
return result;
|
||||
return get_root_save_folder_location() + settings_filename;
|
||||
}
|
||||
|
||||
void save_module_settings(const std::wstring& powertoy_name, web::json::value& settings) {
|
||||
std::wstring save_file_location = get_module_save_file_location(powertoy_name);
|
||||
std::ofstream save_file(save_file_location, std::ios::binary);
|
||||
settings.serialize(save_file);
|
||||
save_file.close();
|
||||
void save_module_settings(std::wstring_view powertoy_name, json::JsonObject& settings) {
|
||||
const std::wstring save_file_location = get_module_save_file_location(powertoy_name);
|
||||
json::to_file(save_file_location, settings);
|
||||
}
|
||||
|
||||
web::json::value load_module_settings(const std::wstring& powertoy_name) {
|
||||
std::wstring save_file_location = get_module_save_file_location(powertoy_name);
|
||||
std::ifstream save_file(save_file_location, std::ios::binary);
|
||||
web::json::value result = web::json::value::parse(save_file);
|
||||
save_file.close();
|
||||
return result;
|
||||
json::JsonObject load_module_settings(std::wstring_view powertoy_name) {
|
||||
const std::wstring save_file_location = get_module_save_file_location(powertoy_name);
|
||||
auto saved_settings = json::from_file(save_file_location);
|
||||
return saved_settings.has_value() ? std::move(*saved_settings) : json::JsonObject{};
|
||||
}
|
||||
|
||||
void save_general_settings(web::json::value& settings) {
|
||||
std::wstring save_file_location = get_powertoys_general_save_file_location();
|
||||
std::ofstream save_file(save_file_location, std::ios::binary);
|
||||
settings.serialize(save_file);
|
||||
save_file.close();
|
||||
void save_general_settings(const json::JsonObject& settings) {
|
||||
const std::wstring save_file_location = get_powertoys_general_save_file_location();
|
||||
json::to_file(save_file_location, settings);
|
||||
}
|
||||
|
||||
web::json::value load_general_settings() {
|
||||
std::wstring save_file_location = get_powertoys_general_save_file_location();
|
||||
std::ifstream save_file(save_file_location, std::ios::binary);
|
||||
web::json::value result = web::json::value::parse(save_file);
|
||||
save_file.close();
|
||||
return result;
|
||||
json::JsonObject load_general_settings() {
|
||||
const std::wstring save_file_location = get_powertoys_general_save_file_location();
|
||||
auto saved_settings = json::from_file(save_file_location);
|
||||
return saved_settings.has_value() ? std::move(*saved_settings) : json::JsonObject{};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <Shlobj.h>
|
||||
#include <cpprest/json.h>
|
||||
|
||||
#include "json.h"
|
||||
|
||||
namespace PTSettingsHelper {
|
||||
|
||||
void save_module_settings(const std::wstring& powertoy_name, web::json::value& settings);
|
||||
web::json::value load_module_settings(const std::wstring& powertoy_name);
|
||||
void save_general_settings(web::json::value& settings);
|
||||
web::json::value load_general_settings();
|
||||
void save_module_settings(std::wstring_view powertoy_name, json::JsonObject& settings);
|
||||
json::JsonObject load_module_settings(std::wstring_view powertoy_name);
|
||||
void save_general_settings(const json::JsonObject& settings);
|
||||
json::JsonObject load_general_settings();
|
||||
|
||||
}
|
||||
|
||||
@@ -4,128 +4,127 @@
|
||||
|
||||
namespace PowerToysSettings {
|
||||
|
||||
Settings::Settings(const HINSTANCE hinstance, const std::wstring& powertoy_name) {
|
||||
Settings::Settings(const HINSTANCE hinstance, std::wstring_view powertoy_name) {
|
||||
m_instance = hinstance;
|
||||
m_json = web::json::value::object();
|
||||
m_json.as_object()[L"version"] = web::json::value::string(L"1.0");
|
||||
m_json.as_object()[L"name"] = web::json::value::string(powertoy_name);
|
||||
m_json.as_object()[L"properties"] = web::json::value::object();
|
||||
m_json.SetNamedValue(L"version", json::value(L"1.0"));
|
||||
m_json.SetNamedValue(L"name", json::value(powertoy_name));
|
||||
m_json.SetNamedValue(L"properties", json::JsonObject{});
|
||||
}
|
||||
|
||||
void Settings::set_description(UINT resource_id) {
|
||||
m_json.as_object()[L"description"] = web::json::value::string(get_resource(resource_id));
|
||||
m_json.SetNamedValue(L"description", json::value(get_resource(resource_id)));
|
||||
}
|
||||
|
||||
void Settings::set_description(const std::wstring& description) {
|
||||
m_json.as_object()[L"description"] = web::json::value::string(description);
|
||||
void Settings::set_description(std::wstring_view description) {
|
||||
m_json.SetNamedValue(L"description", json::value(description));
|
||||
}
|
||||
|
||||
void Settings::set_icon_key(const std::wstring& icon_key) {
|
||||
m_json.as_object()[L"icon_key"] = web::json::value::string(icon_key);
|
||||
void Settings::set_icon_key(std::wstring_view icon_key) {
|
||||
m_json.SetNamedValue(L"icon_key", json::value(icon_key));
|
||||
}
|
||||
|
||||
void Settings::set_overview_link(const std::wstring& overview_link) {
|
||||
m_json.as_object()[L"overview_link"] = web::json::value::string(overview_link);
|
||||
void Settings::set_overview_link(std::wstring_view overview_link) {
|
||||
m_json.SetNamedValue(L"overview_link", json::value(overview_link));
|
||||
}
|
||||
|
||||
void Settings::set_video_link(const std::wstring& video_link) {
|
||||
m_json.as_object()[L"video_link"] = web::json::value::string(video_link);
|
||||
void Settings::set_video_link(std::wstring_view video_link) {
|
||||
m_json.SetNamedValue(L"video_link", json::value(video_link));
|
||||
}
|
||||
|
||||
// add_bool_toogle overloads.
|
||||
void Settings::add_bool_toogle(const std::wstring& name, UINT description_resource_id, bool value) {
|
||||
void Settings::add_bool_toogle(std::wstring_view name, UINT description_resource_id, bool value) {
|
||||
add_bool_toogle(name, get_resource(description_resource_id), value);
|
||||
}
|
||||
|
||||
void Settings::add_bool_toogle(const std::wstring& name, const std::wstring& description, bool value) {
|
||||
web::json::value item = web::json::value::object();
|
||||
item.as_object()[L"display_name"] = web::json::value::string(description);
|
||||
item.as_object()[L"editor_type"] = web::json::value::string(L"bool_toggle");
|
||||
item.as_object()[L"value"] = web::json::value::boolean(value);
|
||||
item.as_object()[L"order"] = web::json::value::number(++m_curr_priority);
|
||||
void Settings::add_bool_toogle(std::wstring_view name, std::wstring_view description, bool value) {
|
||||
json::JsonObject toggle;
|
||||
toggle.SetNamedValue(L"display_name", json::value(description));
|
||||
toggle.SetNamedValue(L"editor_type", json::value(L"bool_toggle"));
|
||||
toggle.SetNamedValue(L"value", json::value(value));
|
||||
toggle.SetNamedValue(L"order", json::value(++m_curr_priority));
|
||||
|
||||
m_json.as_object()[L"properties"].as_object()[name] = item;
|
||||
m_json.GetNamedObject(L"properties").SetNamedValue(name, toggle);
|
||||
}
|
||||
|
||||
// add_int_spinner overloads.
|
||||
void Settings::add_int_spinner(const std::wstring& name, UINT description_resource_id, int value, int min, int max, int step) {
|
||||
void Settings::add_int_spinner(std::wstring_view name, UINT description_resource_id, int value, int min, int max, int step) {
|
||||
add_int_spinner(name, get_resource(description_resource_id), value, min, max, step);
|
||||
}
|
||||
|
||||
void Settings::add_int_spinner(const std::wstring& name, const std::wstring& description, int value, int min, int max, int step) {
|
||||
web::json::value item = web::json::value::object();
|
||||
item.as_object()[L"display_name"] = web::json::value::string(description);
|
||||
item.as_object()[L"editor_type"] = web::json::value::string(L"int_spinner");
|
||||
item.as_object()[L"value"] = web::json::value::number(value);
|
||||
item.as_object()[L"min"] = web::json::value::number(min);
|
||||
item.as_object()[L"max"] = web::json::value::number(max);
|
||||
item.as_object()[L"step"] = web::json::value::number(step);
|
||||
item.as_object()[L"order"] = web::json::value::number(++m_curr_priority);
|
||||
void Settings::add_int_spinner(std::wstring_view name, std::wstring_view description, int value, int min, int max, int step) {
|
||||
json::JsonObject spinner;
|
||||
spinner.SetNamedValue(L"display_name", json::value(description));
|
||||
spinner.SetNamedValue(L"editor_type", json::value(L"int_spinner"));
|
||||
spinner.SetNamedValue(L"value", json::value(value));
|
||||
spinner.SetNamedValue(L"min", json::value(min));
|
||||
spinner.SetNamedValue(L"max", json::value(max));
|
||||
spinner.SetNamedValue(L"step", json::value(step));
|
||||
spinner.SetNamedValue(L"order", json::value(++m_curr_priority));
|
||||
|
||||
m_json.as_object()[L"properties"].as_object()[name] = item;
|
||||
m_json.GetNamedObject(L"properties").SetNamedValue(name, spinner);
|
||||
}
|
||||
|
||||
// add_string overloads.
|
||||
void Settings::add_string(const std::wstring& name, UINT description_resource_id, const std::wstring& value) {
|
||||
void Settings::add_string(std::wstring_view name, UINT description_resource_id, std::wstring_view value) {
|
||||
add_string(name, get_resource(description_resource_id), value);
|
||||
}
|
||||
|
||||
void Settings::add_string(const std::wstring& name, const std::wstring& description, const std::wstring& value) {
|
||||
web::json::value item = web::json::value::object();
|
||||
item.as_object()[L"display_name"] = web::json::value::string(description);
|
||||
item.as_object()[L"editor_type"] = web::json::value::string(L"string_text");
|
||||
item.as_object()[L"value"] = web::json::value::string(value);
|
||||
item.as_object()[L"order"] = web::json::value::number(++m_curr_priority);
|
||||
void Settings::add_string(std::wstring_view name, std::wstring_view description, std::wstring_view value) {
|
||||
json::JsonObject string;
|
||||
string.SetNamedValue(L"display_name", json::value(description));
|
||||
string.SetNamedValue(L"editor_type", json::value(L"string_text"));
|
||||
string.SetNamedValue(L"value", json::value(value));
|
||||
string.SetNamedValue(L"order", json::value(++m_curr_priority));
|
||||
|
||||
m_json.as_object()[L"properties"].as_object()[name] = item;
|
||||
m_json.GetNamedObject(L"properties").SetNamedValue(name, string);
|
||||
}
|
||||
|
||||
// add_multiline_string overloads.
|
||||
void Settings::add_multiline_string(const std::wstring& name, UINT description_resource_id, const std::wstring& value) {
|
||||
void Settings::add_multiline_string(std::wstring_view name, UINT description_resource_id, std::wstring_view value) {
|
||||
add_multiline_string(name, get_resource(description_resource_id), value);
|
||||
}
|
||||
|
||||
void Settings::add_multiline_string(const std::wstring& name, const std::wstring& description, const std::wstring& value) {
|
||||
web::json::value item = web::json::value::object();
|
||||
item.as_object()[L"display_name"] = web::json::value::string(description);
|
||||
item.as_object()[L"editor_type"] = web::json::value::string(L"string_text");
|
||||
item.as_object()[L"value"] = web::json::value::string(value);
|
||||
item.as_object()[L"order"] = web::json::value::number(++m_curr_priority);
|
||||
item.as_object()[L"multiline"] = web::json::value::boolean(true);
|
||||
void Settings::add_multiline_string(std::wstring_view name, std::wstring_view description, std::wstring_view value) {
|
||||
json::JsonObject ml_string;
|
||||
ml_string.SetNamedValue(L"display_name", json::value(description));
|
||||
ml_string.SetNamedValue(L"editor_type", json::value(L"string_text"));
|
||||
ml_string.SetNamedValue(L"value", json::value(value));
|
||||
ml_string.SetNamedValue(L"order", json::value(++m_curr_priority));
|
||||
ml_string.SetNamedValue(L"multiline", json::value(true));
|
||||
|
||||
m_json.as_object()[L"properties"].as_object()[name] = item;
|
||||
m_json.GetNamedObject(L"properties").SetNamedValue(name, ml_string);
|
||||
}
|
||||
|
||||
// add_color_picker overloads.
|
||||
void Settings::add_color_picker(const std::wstring& name, UINT description_resource_id, const std::wstring& value) {
|
||||
void Settings::add_color_picker(std::wstring_view name, UINT description_resource_id, std::wstring_view value) {
|
||||
add_color_picker(name, get_resource(description_resource_id), value);
|
||||
}
|
||||
|
||||
void Settings::add_color_picker(const std::wstring& name, const std::wstring& description, const std::wstring& value) {
|
||||
web::json::value item = web::json::value::object();
|
||||
item.as_object()[L"display_name"] = web::json::value::string(description);
|
||||
item.as_object()[L"editor_type"] = web::json::value::string(L"color_picker");
|
||||
item.as_object()[L"value"] = web::json::value::string(value);
|
||||
item.as_object()[L"order"] = web::json::value::number(++m_curr_priority);
|
||||
void Settings::add_color_picker(std::wstring_view name, std::wstring_view description, std::wstring_view value) {
|
||||
json::JsonObject picker;
|
||||
picker.SetNamedValue(L"display_name", json::value(description));
|
||||
picker.SetNamedValue(L"editor_type", json::value(L"color_picker"));
|
||||
picker.SetNamedValue(L"value", json::value(value));
|
||||
picker.SetNamedValue(L"order", json::value(++m_curr_priority));
|
||||
|
||||
m_json.as_object()[L"properties"].as_object()[name] = item;
|
||||
m_json.GetNamedObject(L"properties").SetNamedValue(name, picker);
|
||||
}
|
||||
|
||||
void Settings::add_hotkey(const std::wstring& name, UINT description_resource_id, const HotkeyObject& hotkey) {
|
||||
void Settings::add_hotkey(std::wstring_view name, UINT description_resource_id, const HotkeyObject& hotkey) {
|
||||
add_hotkey(name, get_resource(description_resource_id), hotkey);
|
||||
}
|
||||
|
||||
void Settings::add_hotkey(const std::wstring& name, const std::wstring& description, const HotkeyObject& hotkey) {
|
||||
web::json::value item = web::json::value::object();
|
||||
item.as_object()[L"display_name"] = web::json::value::string(description);
|
||||
item.as_object()[L"editor_type"] = web::json::value::string(L"hotkey");
|
||||
item.as_object()[L"value"] = hotkey.get_json();
|
||||
item.as_object()[L"order"] = web::json::value::number(++m_curr_priority);
|
||||
void Settings::add_hotkey(std::wstring_view name, std::wstring_view description, const HotkeyObject& hotkey_obj) {
|
||||
json::JsonObject hotkey;
|
||||
hotkey.SetNamedValue(L"display_name", json::value(description));
|
||||
hotkey.SetNamedValue(L"editor_type", json::value(L"hotkey"));
|
||||
hotkey.SetNamedValue(L"value", hotkey_obj.get_json());
|
||||
hotkey.SetNamedValue(L"order", json::value(++m_curr_priority));
|
||||
|
||||
m_json.as_object()[L"properties"].as_object()[name] = item;
|
||||
m_json.GetNamedObject(L"properties").SetNamedValue(name, hotkey);
|
||||
}
|
||||
|
||||
void Settings::add_choice_group(const std::wstring& name, UINT description_resource_id, const std::wstring& value, const std::vector<std::pair<std::wstring, UINT>>& keys_and_text_ids) {
|
||||
void Settings::add_choice_group(std::wstring_view name, UINT description_resource_id, std::wstring_view value, const std::vector<std::pair<std::wstring, UINT>>& keys_and_text_ids) {
|
||||
std::vector<std::pair<std::wstring, std::wstring>> keys_and_texts;
|
||||
keys_and_texts.reserve(keys_and_text_ids.size());
|
||||
for (const auto& kv : keys_and_text_ids) {
|
||||
@@ -134,25 +133,25 @@ namespace PowerToysSettings {
|
||||
add_choice_group(name, get_resource(description_resource_id), value, keys_and_texts);
|
||||
}
|
||||
|
||||
void Settings::add_choice_group(const std::wstring& name, const std::wstring& description, const std::wstring& value, const std::vector<std::pair<std::wstring, std::wstring>>& keys_and_texts) {
|
||||
web::json::value item = web::json::value::object();
|
||||
item.as_object()[L"display_name"] = web::json::value::string(description);
|
||||
item.as_object()[L"editor_type"] = web::json::value::string(L"choice_group");
|
||||
auto options = web::json::value::array(keys_and_texts.size());
|
||||
for (std::size_t i = 0; i < keys_and_texts.size(); ++i) {
|
||||
auto entry = web::json::value::object();
|
||||
entry.as_object()[L"key"] = web::json::value::string(keys_and_texts[i].first);
|
||||
entry.as_object()[L"text"] = web::json::value::string(keys_and_texts[i].second);
|
||||
options.as_array()[i] = entry;
|
||||
void Settings::add_choice_group(std::wstring_view name, std::wstring_view description, std::wstring_view value, const std::vector<std::pair<std::wstring, std::wstring>>& keys_and_texts) {
|
||||
json::JsonObject choice_group;
|
||||
choice_group.SetNamedValue(L"display_name", json::value(description));
|
||||
choice_group.SetNamedValue(L"editor_type", json::value(L"choice_group"));
|
||||
json::JsonArray options;
|
||||
for(const auto & [key, text] : keys_and_texts) {
|
||||
json::JsonObject entry;
|
||||
entry.SetNamedValue(L"key", json::value(key));
|
||||
entry.SetNamedValue(L"text", json::value(text));
|
||||
options.Append(std::move(entry));
|
||||
}
|
||||
item.as_object()[L"options"] = options;
|
||||
item.as_object()[L"value"] = web::json::value::string(value);
|
||||
item.as_object()[L"order"] = web::json::value::number(++m_curr_priority);
|
||||
choice_group.SetNamedValue(L"options", std::move(options));
|
||||
choice_group.SetNamedValue(L"value", json::value(value));
|
||||
choice_group.SetNamedValue(L"order", json::value(++m_curr_priority));
|
||||
|
||||
m_json.as_object()[L"properties"].as_object()[name] = item;
|
||||
m_json.GetNamedObject(L"properties").SetNamedValue(name, choice_group);
|
||||
}
|
||||
|
||||
void Settings::add_dropdown(const std::wstring& name, UINT description_resource_id, const std::wstring& value, const std::vector<std::pair<std::wstring, UINT>>& keys_and_text_ids) {
|
||||
void Settings::add_dropdown(std::wstring_view name, UINT description_resource_id, std::wstring_view value, const std::vector<std::pair<std::wstring, UINT>>& keys_and_text_ids) {
|
||||
std::vector<std::pair<std::wstring, std::wstring>> keys_and_texts;
|
||||
keys_and_texts.reserve(keys_and_text_ids.size());
|
||||
for (const auto& kv : keys_and_text_ids) {
|
||||
@@ -161,55 +160,55 @@ namespace PowerToysSettings {
|
||||
add_dropdown(name, get_resource(description_resource_id), value, keys_and_texts);
|
||||
}
|
||||
|
||||
void Settings::add_dropdown(const std::wstring& name, const std::wstring& description, const std::wstring& value, const std::vector<std::pair<std::wstring, std::wstring>>& keys_and_texts) {
|
||||
web::json::value item = web::json::value::object();
|
||||
item.as_object()[L"display_name"] = web::json::value::string(description);
|
||||
item.as_object()[L"editor_type"] = web::json::value::string(L"dropdown");
|
||||
auto options = web::json::value::array(keys_and_texts.size());
|
||||
for (std::size_t i = 0; i < keys_and_texts.size(); ++i) {
|
||||
auto entry = web::json::value::object();
|
||||
entry.as_object()[L"key"] = web::json::value::string(keys_and_texts[i].first);
|
||||
entry.as_object()[L"text"] = web::json::value::string(keys_and_texts[i].second);
|
||||
options.as_array()[i] = entry;
|
||||
void Settings::add_dropdown(std::wstring_view name, std::wstring_view description, std::wstring_view value, const std::vector<std::pair<std::wstring, std::wstring>>& keys_and_texts) {
|
||||
json::JsonObject dropdown;
|
||||
dropdown.SetNamedValue(L"display_name", json::value(description));
|
||||
dropdown.SetNamedValue(L"editor_type", json::value(L"dropdown"));
|
||||
json::JsonArray options;
|
||||
for(const auto & [key, text] : keys_and_texts) {
|
||||
json::JsonObject entry;
|
||||
entry.SetNamedValue(L"key", json::value(key));
|
||||
entry.SetNamedValue(L"text", json::value(text));
|
||||
options.Append(std::move(entry));
|
||||
}
|
||||
item.as_object()[L"options"] = options;
|
||||
item.as_object()[L"value"] = web::json::value::string(value);
|
||||
item.as_object()[L"order"] = web::json::value::number(++m_curr_priority);
|
||||
dropdown.SetNamedValue(L"options", std::move(options));
|
||||
dropdown.SetNamedValue(L"value", json::value(value));
|
||||
dropdown.SetNamedValue(L"order", json::value(++m_curr_priority));
|
||||
|
||||
m_json.as_object()[L"properties"].as_object()[name] = item;
|
||||
m_json.GetNamedObject(L"properties").SetNamedValue(name, dropdown);
|
||||
}
|
||||
|
||||
// add_custom_action overloads.
|
||||
void Settings::add_custom_action(const std::wstring& name, UINT description_resource_id, UINT button_text_resource_id, UINT ext_description_resource_id) {
|
||||
void Settings::add_custom_action(std::wstring_view name, UINT description_resource_id, UINT button_text_resource_id, UINT ext_description_resource_id) {
|
||||
add_custom_action(name, get_resource(description_resource_id), get_resource(button_text_resource_id), get_resource(ext_description_resource_id));
|
||||
}
|
||||
|
||||
void Settings::add_custom_action(const std::wstring& name, UINT description_resource_id, UINT button_text_resource_id, const std::wstring& value) {
|
||||
void Settings::add_custom_action(std::wstring_view name, UINT description_resource_id, UINT button_text_resource_id, std::wstring_view value) {
|
||||
add_custom_action(name, get_resource(description_resource_id), get_resource(button_text_resource_id), value);
|
||||
}
|
||||
|
||||
void Settings::add_custom_action(const std::wstring& name, const std::wstring& description, const std::wstring& button_text, const std::wstring& value) {
|
||||
web::json::value item = web::json::value::object();
|
||||
item.as_object()[L"display_name"] = web::json::value::string(description);
|
||||
item.as_object()[L"button_text"] = web::json::value::string(button_text);
|
||||
item.as_object()[L"editor_type"] = web::json::value::string(L"custom_action");
|
||||
item.as_object()[L"value"] = web::json::value::string(value);
|
||||
item.as_object()[L"order"] = web::json::value::number(++m_curr_priority);
|
||||
void Settings::add_custom_action(std::wstring_view name, std::wstring_view description, std::wstring_view button_text, std::wstring_view value) {
|
||||
json::JsonObject custom_action;
|
||||
custom_action.SetNamedValue(L"display_name", json::value(description));
|
||||
custom_action.SetNamedValue(L"button_text", json::value(button_text));
|
||||
custom_action.SetNamedValue(L"editor_type", json::value(L"custom_action"));
|
||||
custom_action.SetNamedValue(L"value", json::value(value));
|
||||
custom_action.SetNamedValue(L"order", json::value(++m_curr_priority));
|
||||
|
||||
m_json.as_object()[L"properties"].as_object()[name] = item;
|
||||
m_json.GetNamedObject(L"properties").SetNamedValue(name, custom_action);
|
||||
}
|
||||
|
||||
// Serialization methods.
|
||||
std::wstring Settings::serialize() {
|
||||
return m_json.serialize();
|
||||
return m_json.Stringify().c_str();
|
||||
}
|
||||
|
||||
bool Settings::serialize_to_buffer(wchar_t* buffer, int *buffer_size) {
|
||||
std::wstring result = m_json.serialize();
|
||||
int result_len = (int)result.length();
|
||||
auto result = m_json.Stringify();
|
||||
const int result_len = (int)result.size() + 1;
|
||||
|
||||
if (buffer == nullptr || *buffer_size < result_len) {
|
||||
*buffer_size = result_len + 1;
|
||||
*buffer_size = result_len;
|
||||
return false;
|
||||
} else {
|
||||
wcscpy_s(buffer, *buffer_size, result.c_str());
|
||||
@@ -220,110 +219,73 @@ namespace PowerToysSettings {
|
||||
// Resource helper.
|
||||
std::wstring Settings::get_resource(UINT resource_id) {
|
||||
if (resource_id != 0) {
|
||||
wchar_t buffer[512];
|
||||
if (LoadString(m_instance, resource_id, buffer, ARRAYSIZE(buffer)) > 0) {
|
||||
return std::wstring(buffer);
|
||||
wchar_t* res_ptr;
|
||||
const size_t resource_length = LoadStringW(m_instance, resource_id, reinterpret_cast<wchar_t *>(&res_ptr), 0);
|
||||
if (resource_length != 0) {
|
||||
return {*reinterpret_cast<wchar_t **>(&res_ptr), resource_length};
|
||||
}
|
||||
}
|
||||
|
||||
return L"RESOURCE ID NOT FOUND: " + std::to_wstring(resource_id);
|
||||
}
|
||||
|
||||
PowerToyValues::PowerToyValues(const std::wstring& powertoy_name) {
|
||||
PowerToyValues::PowerToyValues(std::wstring_view powertoy_name) {
|
||||
_name = powertoy_name;
|
||||
m_json = web::json::value::object();
|
||||
set_version();
|
||||
m_json.as_object()[L"name"] = web::json::value::string(powertoy_name);
|
||||
m_json.as_object()[L"properties"] = web::json::value::object();
|
||||
m_json.SetNamedValue(L"name", json::value(powertoy_name));
|
||||
m_json.SetNamedValue(L"properties", json::JsonObject{});
|
||||
}
|
||||
|
||||
PowerToyValues PowerToyValues::from_json_string(const std::wstring& json) {
|
||||
PowerToyValues PowerToyValues::from_json_string(std::wstring_view json) {
|
||||
PowerToyValues result = PowerToyValues();
|
||||
result.m_json = web::json::value::parse(json);
|
||||
result._name = result.m_json.as_object()[L"name"].as_string();
|
||||
result.m_json = json::JsonValue::Parse(json).GetObjectW();
|
||||
result._name = result.m_json.GetNamedString(L"name");
|
||||
return result;
|
||||
}
|
||||
|
||||
PowerToyValues PowerToyValues::load_from_settings_file(const std::wstring & powertoy_name) {
|
||||
PowerToyValues PowerToyValues::load_from_settings_file(std::wstring_view powertoy_name) {
|
||||
PowerToyValues result = PowerToyValues();
|
||||
result.m_json = PTSettingsHelper::load_module_settings(powertoy_name);
|
||||
result._name = powertoy_name;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
web::json::value add_property_generic(const std::wstring& name, T value) {
|
||||
std::vector<std::pair<std::wstring, web::json::value>> vector = { std::make_pair(L"value", web::json::value(value)) };
|
||||
return web::json::value::object(vector);
|
||||
inline bool has_property(const json::JsonObject& o, std::wstring_view name, const json::JsonValueType type) {
|
||||
const json::JsonObject props = o.GetNamedObject(L"properties", json::JsonObject{});
|
||||
return json::has(props, name) && json::has(props.GetNamedObject(name), L"value", type);
|
||||
}
|
||||
|
||||
template <>
|
||||
void PowerToyValues::add_property(const std::wstring& name, bool value) {
|
||||
m_json.as_object()[L"properties"].as_object()[name] = add_property_generic(name, value);
|
||||
};
|
||||
|
||||
template <>
|
||||
void PowerToyValues::add_property(const std::wstring& name, int value) {
|
||||
m_json.as_object()[L"properties"].as_object()[name] = add_property_generic(name, value);
|
||||
};
|
||||
|
||||
template <>
|
||||
void PowerToyValues::add_property(const std::wstring& name, std::wstring value) {
|
||||
m_json.as_object()[L"properties"].as_object()[name] = add_property_generic(name, value);
|
||||
};
|
||||
|
||||
template <>
|
||||
void PowerToyValues::add_property(const std::wstring& name, HotkeyObject value) {
|
||||
m_json.as_object()[L"properties"].as_object()[name] = add_property_generic(name, value.get_json());
|
||||
};
|
||||
|
||||
bool PowerToyValues::is_bool_value(const std::wstring& property_name) {
|
||||
return m_json.is_object() &&
|
||||
m_json.has_object_field(L"properties") &&
|
||||
m_json[L"properties"].has_object_field(property_name) &&
|
||||
m_json[L"properties"][property_name].has_boolean_field(L"value");
|
||||
std::optional<bool> PowerToyValues::get_bool_value(std::wstring_view property_name) {
|
||||
if (!has_property(m_json, property_name, json::JsonValueType::Boolean)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return m_json.GetNamedObject(L"properties").GetNamedObject(property_name).GetNamedBoolean(L"value");
|
||||
}
|
||||
|
||||
bool PowerToyValues::is_int_value(const std::wstring& property_name) {
|
||||
return m_json.is_object() &&
|
||||
m_json.has_object_field(L"properties") &&
|
||||
m_json[L"properties"].has_object_field(property_name) &&
|
||||
m_json[L"properties"][property_name].has_integer_field(L"value");
|
||||
std::optional<int> PowerToyValues::get_int_value(std::wstring_view property_name) {
|
||||
if (!has_property(m_json, property_name, json::JsonValueType::Number)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return static_cast<int>(m_json.GetNamedObject(L"properties").GetNamedObject(property_name).GetNamedNumber(L"value"));
|
||||
}
|
||||
|
||||
bool PowerToyValues::is_string_value(const std::wstring& property_name) {
|
||||
return m_json.is_object() &&
|
||||
m_json.has_object_field(L"properties") &&
|
||||
m_json[L"properties"].has_object_field(property_name) &&
|
||||
m_json[L"properties"][property_name].has_string_field(L"value");
|
||||
std::optional<std::wstring> PowerToyValues::get_string_value(std::wstring_view property_name) {
|
||||
if (!has_property(m_json, property_name, json::JsonValueType::String)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return m_json.GetNamedObject(L"properties").GetNamedObject(property_name).GetNamedString(L"value").c_str();
|
||||
}
|
||||
|
||||
bool PowerToyValues::is_object_value(const std::wstring& property_name) {
|
||||
return m_json.is_object() &&
|
||||
m_json.has_object_field(L"properties") &&
|
||||
m_json[L"properties"].has_object_field(property_name) &&
|
||||
m_json[L"properties"][property_name].has_object_field(L"value");
|
||||
}
|
||||
|
||||
bool PowerToyValues::get_bool_value(const std::wstring& property_name) {
|
||||
return m_json[L"properties"][property_name][L"value"].as_bool();
|
||||
}
|
||||
|
||||
int PowerToyValues::get_int_value(const std::wstring& property_name) {
|
||||
return m_json[L"properties"][property_name][L"value"].as_integer();
|
||||
}
|
||||
|
||||
std::wstring PowerToyValues::get_string_value(const std::wstring& property_name) {
|
||||
return m_json[L"properties"][property_name][L"value"].as_string();
|
||||
}
|
||||
|
||||
web::json::value PowerToyValues::get_json(const std::wstring& property_name) {
|
||||
return m_json[L"properties"][property_name][L"value"];
|
||||
std::optional<json::JsonObject> PowerToyValues::get_json(std::wstring_view property_name) {
|
||||
if (!has_property(m_json, property_name, json::JsonValueType::Object)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return m_json.GetNamedObject(L"properties").GetNamedObject(property_name).GetNamedObject(L"value");
|
||||
}
|
||||
|
||||
std::wstring PowerToyValues::serialize() {
|
||||
set_version();
|
||||
return m_json.serialize();
|
||||
return m_json.Stringify().c_str();
|
||||
}
|
||||
|
||||
void PowerToyValues::save_to_settings_file() {
|
||||
@@ -332,6 +294,6 @@ namespace PowerToysSettings {
|
||||
}
|
||||
|
||||
void PowerToyValues::set_version() {
|
||||
m_json.as_object()[L"version"] = web::json::value::string(m_version);
|
||||
m_json.SetNamedValue(L"version", json::value(m_version));
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <cpprest/json.h>
|
||||
|
||||
#include "json.h"
|
||||
|
||||
namespace PowerToysSettings {
|
||||
|
||||
@@ -10,45 +10,45 @@ namespace PowerToysSettings {
|
||||
public:
|
||||
Settings(
|
||||
const HINSTANCE hinstance, // Module handle of the PowerToy DLL 'IMAGE_DOS_HEADER __ImageBase'
|
||||
const std::wstring& powertoy_name
|
||||
std::wstring_view powertoy_name
|
||||
);
|
||||
|
||||
// Add additional general information to the PowerToy settings.
|
||||
void set_description(UINT resource_id);
|
||||
void set_description(const std::wstring& description);
|
||||
void set_description(std::wstring_view description);
|
||||
|
||||
void set_icon_key(const std::wstring& icon_key);
|
||||
void set_overview_link(const std::wstring& overview_link);
|
||||
void set_video_link(const std::wstring& video_link);
|
||||
void set_icon_key(std::wstring_view icon_key);
|
||||
void set_overview_link(std::wstring_view overview_link);
|
||||
void set_video_link(std::wstring_view video_link);
|
||||
|
||||
// Add properties to the PowerToy settings.
|
||||
void add_bool_toogle(const std::wstring& name, UINT description_resource_id, bool value);
|
||||
void add_bool_toogle(const std::wstring& name, const std::wstring& description, bool value);
|
||||
void add_bool_toogle(std::wstring_view name, UINT description_resource_id, bool value);
|
||||
void add_bool_toogle(std::wstring_view name, std::wstring_view description, bool value);
|
||||
|
||||
void add_int_spinner(const std::wstring& name, UINT description_resource_id, int value, int min, int max, int step);
|
||||
void add_int_spinner(const std::wstring& name, const std::wstring& description, int value, int min, int max, int step);
|
||||
void add_int_spinner(std::wstring_view name, UINT description_resource_id, int value, int min, int max, int step);
|
||||
void add_int_spinner(std::wstring_view name, std::wstring_view description, int value, int min, int max, int step);
|
||||
|
||||
void add_string(const std::wstring& name, UINT description_resource_id, const std::wstring& value);
|
||||
void add_string(const std::wstring& name, const std::wstring& description, const std::wstring& value);
|
||||
void add_string(std::wstring_view name, UINT description_resource_id, std::wstring_view value);
|
||||
void add_string(std::wstring_view name, std::wstring_view description, std::wstring_view value);
|
||||
|
||||
void add_multiline_string(const std::wstring& name, UINT description_resource_id, const std::wstring& value);
|
||||
void add_multiline_string(const std::wstring& name, const std::wstring& description, const std::wstring& value);
|
||||
void add_multiline_string(std::wstring_view name, UINT description_resource_id, std::wstring_view value);
|
||||
void add_multiline_string(std::wstring_view name, std::wstring_view description, std::wstring_view value);
|
||||
|
||||
void add_color_picker(const std::wstring& name, UINT description_resource_id, const std::wstring& value);
|
||||
void add_color_picker(const std::wstring& name, const std::wstring& description, const std::wstring& value);
|
||||
void add_color_picker(std::wstring_view name, UINT description_resource_id, std::wstring_view value);
|
||||
void add_color_picker(std::wstring_view name, std::wstring_view description, std::wstring_view value);
|
||||
|
||||
void add_hotkey(const std::wstring& name, UINT description_resource_id, const HotkeyObject& hotkey);
|
||||
void add_hotkey(const std::wstring& name, const std::wstring& description, const HotkeyObject& hotkey);
|
||||
void add_hotkey(std::wstring_view name, UINT description_resource_id, const HotkeyObject& hotkey);
|
||||
void add_hotkey(std::wstring_view name, std::wstring_view description, const HotkeyObject& hotkey);
|
||||
|
||||
void add_choice_group(const std::wstring& name, UINT description_resource_id, const std::wstring& value, const std::vector<std::pair<std::wstring, UINT>>& keys_and_text_ids);
|
||||
void add_choice_group(const std::wstring& name, const std::wstring& description, const std::wstring& value, const std::vector<std::pair<std::wstring, std::wstring>>& keys_and_texts);
|
||||
void add_choice_group(std::wstring_view name, UINT description_resource_id, std::wstring_view value, const std::vector<std::pair<std::wstring, UINT>>& keys_and_text_ids);
|
||||
void add_choice_group(std::wstring_view name, std::wstring_view description, std::wstring_view value, const std::vector<std::pair<std::wstring, std::wstring>>& keys_and_texts);
|
||||
|
||||
void add_dropdown(const std::wstring& name, UINT description_resource_id, const std::wstring& value, const std::vector<std::pair<std::wstring, UINT>>& keys_and_text_ids);
|
||||
void add_dropdown(const std::wstring& name, const std::wstring& description, const std::wstring& value, const std::vector<std::pair<std::wstring, std::wstring>>& keys_and_texts);
|
||||
void add_dropdown(std::wstring_view name, UINT description_resource_id, std::wstring_view value, const std::vector<std::pair<std::wstring, UINT>>& keys_and_text_ids);
|
||||
void add_dropdown(std::wstring_view name, std::wstring_view description, std::wstring_view value, const std::vector<std::pair<std::wstring, std::wstring>>& keys_and_texts);
|
||||
|
||||
void add_custom_action(const std::wstring& name, UINT description_resource_id, UINT button_text_resource_id, UINT ext_description_resource_id);
|
||||
void add_custom_action(const std::wstring& name, UINT description_resource_id, UINT button_text_resource_id, const std::wstring& value);
|
||||
void add_custom_action(const std::wstring& name, const std::wstring& description, const std::wstring& button_text, const std::wstring& value);
|
||||
void add_custom_action(std::wstring_view name, UINT description_resource_id, UINT button_text_resource_id, UINT ext_description_resource_id);
|
||||
void add_custom_action(std::wstring_view name, UINT description_resource_id, UINT button_text_resource_id, std::wstring_view value);
|
||||
void add_custom_action(std::wstring_view name, std::wstring_view description, std::wstring_view button_text, std::wstring_view value);
|
||||
|
||||
|
||||
// Serialize the internal json to a string.
|
||||
@@ -57,7 +57,7 @@ namespace PowerToysSettings {
|
||||
bool serialize_to_buffer(wchar_t* buffer, int* buffer_size);
|
||||
|
||||
private:
|
||||
web::json::value m_json;
|
||||
json::JsonObject m_json;
|
||||
int m_curr_priority = 0; // For keeping order when adding elements.
|
||||
HINSTANCE m_instance;
|
||||
|
||||
@@ -66,24 +66,22 @@ namespace PowerToysSettings {
|
||||
|
||||
class PowerToyValues {
|
||||
public:
|
||||
PowerToyValues(const std::wstring& powertoy_name);
|
||||
static PowerToyValues from_json_string(const std::wstring& json);
|
||||
static PowerToyValues load_from_settings_file(const std::wstring& powertoy_name);
|
||||
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);
|
||||
|
||||
template <typename T>
|
||||
void add_property(const std::wstring& name, T value);
|
||||
inline void add_property(std::wstring_view name, T value)
|
||||
{
|
||||
json::JsonObject prop_value;
|
||||
prop_value.SetNamedValue(L"value", json::value(value));
|
||||
m_json.GetNamedObject(L"properties").SetNamedValue(name, prop_value);
|
||||
}
|
||||
|
||||
// Check property value type
|
||||
bool is_bool_value(const std::wstring& property_name);
|
||||
bool is_int_value(const std::wstring& property_name);
|
||||
bool is_string_value(const std::wstring& property_name);
|
||||
bool is_object_value(const std::wstring& property_name);
|
||||
|
||||
// Get property value
|
||||
bool get_bool_value(const std::wstring& property_name);
|
||||
int get_int_value(const std::wstring& property_name);
|
||||
std::wstring get_string_value(const std::wstring& property_name);
|
||||
web::json::value get_json(const std::wstring& property_name);
|
||||
std::optional<bool> get_bool_value(std::wstring_view property_name);
|
||||
std::optional<int> get_int_value(std::wstring_view property_name);
|
||||
std::optional<std::wstring> get_string_value(std::wstring_view property_name);
|
||||
std::optional<json::JsonObject> get_json(std::wstring_view property_name);
|
||||
|
||||
std::wstring serialize();
|
||||
void save_to_settings_file();
|
||||
@@ -91,60 +89,58 @@ namespace PowerToysSettings {
|
||||
private:
|
||||
const std::wstring m_version = L"1.0";
|
||||
void set_version();
|
||||
web::json::value m_json;
|
||||
json::JsonObject m_json;
|
||||
std::wstring _name;
|
||||
PowerToyValues() {}
|
||||
};
|
||||
|
||||
class CustomActionObject {
|
||||
public:
|
||||
static CustomActionObject from_json_string(const std::wstring& json) {
|
||||
web::json::value parsed_json = web::json::value::parse(json);
|
||||
return CustomActionObject(parsed_json);
|
||||
static CustomActionObject from_json_string(std::wstring_view json) {
|
||||
return CustomActionObject(json::JsonValue::Parse(json).GetObjectW());
|
||||
}
|
||||
|
||||
std::wstring get_name() { return m_json[L"action_name"].as_string(); }
|
||||
std::wstring get_value() { return m_json[L"value"].as_string(); }
|
||||
std::wstring get_name() { return m_json.GetNamedString(L"action_name").c_str(); }
|
||||
std::wstring get_value() { return m_json.GetNamedString(L"value").c_str(); }
|
||||
|
||||
protected:
|
||||
CustomActionObject(web::json::value action_json) : m_json(action_json) {};
|
||||
web::json::value m_json;
|
||||
CustomActionObject(json::JsonObject action_json) : m_json(std::move(action_json)) {};
|
||||
json::JsonObject m_json;
|
||||
};
|
||||
|
||||
class HotkeyObject {
|
||||
public:
|
||||
static HotkeyObject from_json(web::json::value json) {
|
||||
return HotkeyObject(json);
|
||||
static HotkeyObject from_json(json::JsonObject json) {
|
||||
return HotkeyObject(std::move(json));
|
||||
}
|
||||
static HotkeyObject from_json_string(const std::wstring& json) {
|
||||
web::json::value parsed_json = web::json::value::parse(json);
|
||||
return HotkeyObject(parsed_json);
|
||||
static HotkeyObject from_json_string(std::wstring_view json) {
|
||||
return HotkeyObject(json::JsonValue::Parse(json).GetObjectW());
|
||||
}
|
||||
static HotkeyObject from_settings(bool win_pressed, bool ctrl_pressed, bool alt_pressed, bool shift_pressed, UINT vk_code) {
|
||||
web::json::value json = web::json::value::object();
|
||||
json.as_object()[L"win"] = web::json::value::boolean(win_pressed);
|
||||
json.as_object()[L"ctrl"] = web::json::value::boolean(ctrl_pressed);
|
||||
json.as_object()[L"alt"] = web::json::value::boolean(alt_pressed);
|
||||
json.as_object()[L"shift"] = web::json::value::boolean(shift_pressed);
|
||||
json.as_object()[L"code"] = web::json::value::number(vk_code);
|
||||
json.as_object()[L"key"] = web::json::value::string(key_from_code(vk_code));
|
||||
return HotkeyObject(json);
|
||||
json::JsonObject json;
|
||||
json.SetNamedValue(L"win", json::value(win_pressed));
|
||||
json.SetNamedValue(L"ctrl", json::value(ctrl_pressed));
|
||||
json.SetNamedValue(L"alt", json::value(alt_pressed));
|
||||
json.SetNamedValue(L"shift", json::value(shift_pressed));
|
||||
json.SetNamedValue(L"code", json::value(vk_code));
|
||||
json.SetNamedValue(L"key", json::value(key_from_code(vk_code)));
|
||||
return std::move(json);
|
||||
}
|
||||
const web::json::value& get_json() const { return m_json; }
|
||||
const json::JsonObject& get_json() const { return m_json; }
|
||||
|
||||
std::wstring get_key() { return m_json[L"key"].as_string(); }
|
||||
UINT get_code() { return m_json[L"code"].as_integer(); }
|
||||
bool win_pressed() { return m_json[L"win"].as_bool(); }
|
||||
bool ctrl_pressed() { return m_json[L"ctrl"].as_bool(); }
|
||||
bool alt_pressed() { return m_json[L"alt"].as_bool(); }
|
||||
bool shift_pressed() { return m_json[L"shift"].as_bool(); }
|
||||
UINT get_modifiers_repeat() {
|
||||
std::wstring get_key() const { return m_json.GetNamedString(L"key").c_str(); }
|
||||
UINT get_code() const { return static_cast<UINT>(m_json.GetNamedNumber(L"code")); }
|
||||
bool win_pressed() const { return m_json.GetNamedBoolean(L"win"); }
|
||||
bool ctrl_pressed() const { return m_json.GetNamedBoolean(L"ctrl"); }
|
||||
bool alt_pressed() const { return m_json.GetNamedBoolean(L"alt"); }
|
||||
bool shift_pressed() const { return m_json.GetNamedBoolean(L"shift"); }
|
||||
UINT get_modifiers_repeat() const {
|
||||
return (win_pressed() ? MOD_WIN : 0) |
|
||||
(ctrl_pressed() ? MOD_CONTROL : 0) |
|
||||
(alt_pressed() ? MOD_ALT : 0) |
|
||||
(shift_pressed() ? MOD_SHIFT : 0);
|
||||
}
|
||||
UINT get_modifiers() {
|
||||
UINT get_modifiers() const {
|
||||
return get_modifiers_repeat() | MOD_NOREPEAT;
|
||||
}
|
||||
protected:
|
||||
@@ -178,12 +174,12 @@ namespace PowerToysSettings {
|
||||
}
|
||||
return L"(Key " + std::to_wstring(key_code) + L")";
|
||||
}
|
||||
HotkeyObject(web::json::value hotkey_json) : m_json(hotkey_json) {
|
||||
HotkeyObject(json::JsonObject hotkey_json) : m_json(std::move(hotkey_json)) {
|
||||
if (get_key() == L"~" && get_modifiers_repeat() == MOD_WIN) {
|
||||
m_json.as_object()[L"key"] = web::json::value::string(key_from_code(get_code()));
|
||||
m_json.SetNamedValue(L"key", json::value(key_from_code(get_code())));
|
||||
}
|
||||
};
|
||||
web::json::value m_json;
|
||||
json::JsonObject m_json;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -112,25 +112,25 @@ void FancyZonesSettings::LoadSettings(PCWSTR config, bool fromFile) noexcept try
|
||||
|
||||
for (auto const& setting : m_configBools)
|
||||
{
|
||||
if (values.is_bool_value(setting.name))
|
||||
if (const auto val = values.get_bool_value(setting.name))
|
||||
{
|
||||
*setting.value = values.get_bool_value(setting.name);
|
||||
*setting.value = *val;
|
||||
}
|
||||
}
|
||||
|
||||
if (values.is_string_value(m_zoneHiglightName))
|
||||
if (auto val = values.get_string_value(m_zoneHiglightName))
|
||||
{
|
||||
m_settings.zoneHightlightColor = values.get_string_value(m_zoneHiglightName);
|
||||
m_settings.zoneHightlightColor = std::move(*val);
|
||||
}
|
||||
|
||||
if (values.is_object_value(m_editorHotkeyName))
|
||||
if (const auto val = values.get_json(m_editorHotkeyName))
|
||||
{
|
||||
m_settings.editorHotkey = PowerToysSettings::HotkeyObject::from_json(values.get_json(m_editorHotkeyName));
|
||||
m_settings.editorHotkey = PowerToysSettings::HotkeyObject::from_json(*val);
|
||||
}
|
||||
|
||||
if (values.is_string_value(m_excludedAppsName))
|
||||
if (auto val = values.get_string_value(m_excludedAppsName))
|
||||
{
|
||||
m_settings.excludedApps = values.get_string_value(m_excludedAppsName);
|
||||
m_settings.excludedApps = std::move(*val);
|
||||
m_settings.excludedAppsArray.clear();
|
||||
auto excludedUppercase = m_settings.excludedApps;
|
||||
CharUpperBuffW(excludedUppercase.data(), (DWORD)excludedUppercase.length());
|
||||
@@ -163,7 +163,7 @@ void FancyZonesSettings::SaveSettings() noexcept try
|
||||
}
|
||||
|
||||
values.add_property(m_zoneHiglightName, m_settings.zoneHightlightColor);
|
||||
values.add_property(m_editorHotkeyName, m_settings.editorHotkey);
|
||||
values.add_property(m_editorHotkeyName, m_settings.editorHotkey.get_json());
|
||||
values.add_property(m_excludedAppsName, m_settings.excludedApps);
|
||||
|
||||
values.save_to_settings_file();
|
||||
|
||||
@@ -252,11 +252,11 @@ public:
|
||||
PowerToysSettings::PowerToyValues values =
|
||||
PowerToysSettings::PowerToyValues::from_json_string(config);
|
||||
|
||||
CSettings::SetPersistState(values.get_bool_value(L"bool_persist_input"));
|
||||
CSettings::SetMRUEnabled(values.get_bool_value(L"bool_mru_enabled"));
|
||||
CSettings::SetMaxMRUSize(values.get_int_value(L"int_max_mru_size"));
|
||||
CSettings::SetShowIconOnMenu(values.get_bool_value(L"bool_show_icon_on_menu"));
|
||||
CSettings::SetExtendedContextMenuOnly(values.get_bool_value(L"bool_show_extended_menu"));
|
||||
CSettings::SetPersistState(values.get_bool_value(L"bool_persist_input").value());
|
||||
CSettings::SetMRUEnabled(values.get_bool_value(L"bool_mru_enabled").value());
|
||||
CSettings::SetMaxMRUSize(values.get_int_value(L"int_max_mru_size").value());
|
||||
CSettings::SetShowIconOnMenu(values.get_bool_value(L"bool_show_icon_on_menu").value());
|
||||
CSettings::SetExtendedContextMenuOnly(values.get_bool_value(L"bool_show_extended_menu").value());
|
||||
}
|
||||
catch (std::exception) {
|
||||
// Improper JSON.
|
||||
|
||||
@@ -61,39 +61,37 @@ void OverlayWindow::set_config(const wchar_t * config) {
|
||||
try {
|
||||
PowerToysSettings::PowerToyValues _values =
|
||||
PowerToysSettings::PowerToyValues::from_json_string(config);
|
||||
if (_values.is_int_value(pressTime.name)) {
|
||||
int press_delay_time = _values.get_int_value(pressTime.name);
|
||||
pressTime.value = press_delay_time;
|
||||
if (const auto press_delay_time = _values.get_int_value(pressTime.name)) {
|
||||
pressTime.value = *press_delay_time;
|
||||
if (target_state) {
|
||||
target_state->set_delay(press_delay_time);
|
||||
target_state->set_delay(*press_delay_time);
|
||||
}
|
||||
}
|
||||
if (_values.is_int_value(overlayOpacity.name)) {
|
||||
int overlay_opacity = _values.get_int_value(overlayOpacity.name);
|
||||
overlayOpacity.value = overlay_opacity;
|
||||
if (const auto overlay_opacity = _values.get_int_value(overlayOpacity.name)) {
|
||||
overlayOpacity.value = *overlay_opacity;
|
||||
if (winkey_popup) {
|
||||
winkey_popup->apply_overlay_opacity(((float)overlayOpacity.value) / 100.0f);
|
||||
}
|
||||
}
|
||||
if (_values.is_string_value(theme.name)) {
|
||||
theme.value = _values.get_string_value(theme.name);
|
||||
if (auto val = _values.get_string_value(theme.name)) {
|
||||
theme.value = std::move(*val);
|
||||
winkey_popup->set_theme(theme.value);
|
||||
}
|
||||
_values.save_to_settings_file();
|
||||
Trace::SettingsChanged(pressTime.value, overlayOpacity.value, theme.value);
|
||||
}
|
||||
catch (std::exception&) {
|
||||
// Improper JSON.
|
||||
catch (...) {
|
||||
// Improper JSON. TODO: handle the error.
|
||||
}
|
||||
}
|
||||
|
||||
void OverlayWindow::enable() {
|
||||
if (!_enabled) {
|
||||
Trace::EnableShortcutGuide(true);
|
||||
winkey_popup = new D2DOverlayWindow();
|
||||
winkey_popup = std::make_unique<D2DOverlayWindow>();
|
||||
winkey_popup->apply_overlay_opacity(((float)overlayOpacity.value)/100.0f);
|
||||
winkey_popup->set_theme(theme.value);
|
||||
target_state = new TargetState(pressTime.value);
|
||||
target_state = std::make_unique<TargetState>(pressTime.value);
|
||||
winkey_popup->initialize();
|
||||
}
|
||||
_enabled = true;
|
||||
@@ -107,10 +105,8 @@ void OverlayWindow::disable(bool trace_event) {
|
||||
}
|
||||
winkey_popup->hide();
|
||||
target_state->exit();
|
||||
delete target_state;
|
||||
delete winkey_popup;
|
||||
target_state = nullptr;
|
||||
winkey_popup = nullptr;
|
||||
target_state.reset();
|
||||
winkey_popup.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,14 +160,14 @@ void OverlayWindow::init_settings() {
|
||||
try {
|
||||
PowerToysSettings::PowerToyValues settings =
|
||||
PowerToysSettings::PowerToyValues::load_from_settings_file(OverlayWindow::get_name());
|
||||
if (settings.is_int_value(pressTime.name)) {
|
||||
pressTime.value = settings.get_int_value(pressTime.name);
|
||||
if (const auto val = settings.get_int_value(pressTime.name)) {
|
||||
pressTime.value = *val;
|
||||
}
|
||||
if (settings.is_int_value(overlayOpacity.name)) {
|
||||
overlayOpacity.value = settings.get_int_value(overlayOpacity.name);
|
||||
if (const auto val = settings.get_int_value(overlayOpacity.name)) {
|
||||
overlayOpacity.value = *val;
|
||||
}
|
||||
if (settings.is_string_value(theme.name)) {
|
||||
theme.value = settings.get_string_value(theme.name);
|
||||
if (auto val = settings.get_string_value(theme.name)) {
|
||||
theme.value = std::move(*val);
|
||||
}
|
||||
}
|
||||
catch (std::exception&) {
|
||||
|
||||
@@ -32,8 +32,8 @@ public:
|
||||
virtual void destroy() override;
|
||||
|
||||
private:
|
||||
TargetState* target_state;
|
||||
D2DOverlayWindow *winkey_popup;
|
||||
std::unique_ptr<TargetState> target_state;
|
||||
std::unique_ptr<D2DOverlayWindow> winkey_popup;
|
||||
bool _enabled = false;
|
||||
|
||||
void init_settings();
|
||||
|
||||
@@ -5,45 +5,38 @@
|
||||
#include "powertoy_module.h"
|
||||
#include <common/windows_colors.h>
|
||||
|
||||
using namespace web;
|
||||
|
||||
static std::wstring settings_theme = L"system";
|
||||
|
||||
web::json::value load_general_settings() {
|
||||
json::JsonObject load_general_settings() {
|
||||
auto loaded = PTSettingsHelper::load_general_settings();
|
||||
if (loaded.has_string_field(L"theme")) {
|
||||
settings_theme = loaded.as_object()[L"theme"].as_string();
|
||||
if (settings_theme != L"dark" && settings_theme != L"light") {
|
||||
settings_theme = L"system";
|
||||
}
|
||||
} else {
|
||||
settings_theme = loaded.GetNamedString(L"theme", L"system");
|
||||
if (settings_theme != L"dark" && settings_theme != L"light") {
|
||||
settings_theme = L"system";
|
||||
}
|
||||
return loaded;
|
||||
}
|
||||
|
||||
web::json::value get_general_settings() {
|
||||
json::value result = json::value::object();
|
||||
bool startup = is_auto_start_task_active_for_this_user();
|
||||
result.as_object()[L"startup"] = json::value::boolean(startup);
|
||||
json::JsonObject get_general_settings() {
|
||||
json::JsonObject result;
|
||||
const bool startup = is_auto_start_task_active_for_this_user();
|
||||
result.SetNamedValue(L"startup", json::value(startup));
|
||||
|
||||
json::value enabled = json::value::object();
|
||||
json::JsonObject enabled;
|
||||
for (auto&[name, powertoy] : modules()) {
|
||||
enabled.as_object()[name] = json::value::boolean(powertoy.is_enabled());
|
||||
enabled.SetNamedValue(name, json::value(powertoy.is_enabled()));
|
||||
}
|
||||
result.as_object()[L"enabled"] = enabled;
|
||||
result.SetNamedValue(L"enabled", std::move(enabled));
|
||||
|
||||
result.as_object()[L"theme"] = json::value::string(settings_theme);
|
||||
result.as_object()[L"system_theme"] = json::value::string(WindowsColors::is_dark_mode() ? L"dark" : L"light");
|
||||
result.as_object()[L"powertoys_version"] = json::value::string(get_product_version());
|
||||
result.SetNamedValue(L"theme", json::value(settings_theme));
|
||||
result.SetNamedValue(L"system_theme", json::value(WindowsColors::is_dark_mode() ? L"dark" : L"light"));
|
||||
result.SetNamedValue(L"powertoys_version", json::value(get_product_version()));
|
||||
return result;
|
||||
}
|
||||
|
||||
void apply_general_settings(const json::value& general_configs) {
|
||||
bool contains_startup = general_configs.has_boolean_field(L"startup");
|
||||
if (contains_startup) {
|
||||
bool startup = general_configs.at(L"startup").as_bool();
|
||||
bool current_startup = is_auto_start_task_active_for_this_user();
|
||||
void apply_general_settings(const json::JsonObject& general_configs) {
|
||||
if (json::has(general_configs, L"startup", json::JsonValueType::Boolean)) {
|
||||
const bool startup = general_configs.GetNamedBoolean(L"startup");
|
||||
const bool current_startup = is_auto_start_task_active_for_this_user();
|
||||
if (current_startup != startup) {
|
||||
if (startup) {
|
||||
enable_auto_start_task_for_this_user();
|
||||
@@ -52,26 +45,33 @@ void apply_general_settings(const json::value& general_configs) {
|
||||
}
|
||||
}
|
||||
}
|
||||
bool contains_enabled = general_configs.has_object_field(L"enabled");
|
||||
if (contains_enabled) {
|
||||
for (auto enabled_element : general_configs.at(L"enabled").as_object()) {
|
||||
if (enabled_element.second.is_boolean() && modules().find(enabled_element.first) != modules().end()) {
|
||||
bool module_inst_enabled = modules().at(enabled_element.first).is_enabled();
|
||||
bool target_enabled = enabled_element.second.as_bool();
|
||||
if (module_inst_enabled != target_enabled) {
|
||||
if (target_enabled) {
|
||||
modules().at(enabled_element.first).enable();
|
||||
} else {
|
||||
modules().at(enabled_element.first).disable();
|
||||
}
|
||||
}
|
||||
if (json::has(general_configs, L"enabled")) {
|
||||
for (const auto& enabled_element : general_configs.GetNamedObject(L"enabled")) {
|
||||
const auto value = enabled_element.Value();
|
||||
if (value.ValueType() != json::JsonValueType::Boolean) {
|
||||
continue;
|
||||
}
|
||||
const std::wstring name{enabled_element.Key().c_str()};
|
||||
const bool found = modules().find(name) != modules().end();
|
||||
if (!found) {
|
||||
continue;
|
||||
}
|
||||
const bool module_inst_enabled = modules().at(name).is_enabled();
|
||||
const bool target_enabled = value.GetBoolean();
|
||||
if (module_inst_enabled == target_enabled) {
|
||||
continue;
|
||||
}
|
||||
if (target_enabled) {
|
||||
modules().at(name).enable();
|
||||
} else {
|
||||
modules().at(name).disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (general_configs.has_string_field(L"theme")) {
|
||||
settings_theme = general_configs.at(L"theme").as_string();
|
||||
if (json::has(general_configs, L"theme", json::JsonValueType::String)) {
|
||||
settings_theme = general_configs.GetNamedString(L"theme");
|
||||
}
|
||||
json::value save_settings = get_general_settings();
|
||||
json::JsonObject save_settings = get_general_settings();
|
||||
PTSettingsHelper::save_general_settings(save_settings);
|
||||
}
|
||||
|
||||
@@ -80,21 +80,22 @@ void start_initial_powertoys() {
|
||||
|
||||
std::unordered_set<std::wstring> powertoys_to_enable;
|
||||
|
||||
json::value general_settings;
|
||||
json::JsonObject general_settings;
|
||||
try {
|
||||
general_settings = load_general_settings();
|
||||
json::value enabled = general_settings[L"enabled"];
|
||||
for (auto enabled_element : enabled.as_object()) {
|
||||
if (enabled_element.second.as_bool()) {
|
||||
json::JsonObject enabled = general_settings.GetNamedObject(L"enabled");
|
||||
for (const auto & enabled_element : enabled) {
|
||||
if (enabled_element.Value().GetBoolean()) {
|
||||
// Enable this powertoy.
|
||||
powertoys_to_enable.emplace(enabled_element.first);
|
||||
powertoys_to_enable.emplace(enabled_element.Key());
|
||||
}
|
||||
}
|
||||
only_enable_some_powertoys = true;
|
||||
}
|
||||
catch (std::exception&) {
|
||||
catch (...) {
|
||||
// Couldn't read the general settings correctly.
|
||||
// Load all powertoys.
|
||||
// TODO: notify user about invalid json config
|
||||
only_enable_some_powertoys = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include <cpprest/json.h>
|
||||
|
||||
web::json::value get_general_settings();
|
||||
void apply_general_settings(const web::json::value& general_configs);
|
||||
#include <common/json.h>
|
||||
|
||||
json::JsonObject get_general_settings();
|
||||
void apply_general_settings(const json::JsonObject & general_configs);
|
||||
void start_initial_powertoys();
|
||||
|
||||
@@ -23,3 +23,12 @@ PowertoyModule load_powertoy(const std::wstring& filename) {
|
||||
module->register_system_menu_helper(&SystemMenuHelperInstace());
|
||||
return PowertoyModule(module, handle);
|
||||
}
|
||||
|
||||
json::JsonObject PowertoyModule::json_config() const {
|
||||
int size = 0;
|
||||
module->get_config(nullptr, &size);
|
||||
std::wstring result;
|
||||
result.resize(size - 1);
|
||||
module->get_config(result.data(), &size);
|
||||
return json::JsonObject::Parse(result);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <functional>
|
||||
|
||||
class PowertoyModule;
|
||||
#include <common/json.h>
|
||||
|
||||
struct PowertoyModuleDeleter {
|
||||
void operator()(PowertoyModuleIface* module) const {
|
||||
@@ -48,6 +49,8 @@ public:
|
||||
const std::wstring& get_name() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
json::JsonObject json_config() const;
|
||||
|
||||
const std::wstring get_config() const {
|
||||
std::wstring result;
|
||||
|
||||
@@ -4,89 +4,88 @@
|
||||
#include <sstream>
|
||||
#include <accctrl.h>
|
||||
#include <aclapi.h>
|
||||
#include <cpprest/json.h>
|
||||
|
||||
#include "powertoy_module.h"
|
||||
#include <common/two_way_pipe_message_ipc.h>
|
||||
#include "tray_icon.h"
|
||||
#include "general_settings.h"
|
||||
#include "common/windows_colors.h"
|
||||
|
||||
#define BUFSIZE 1024
|
||||
#include <common/json.h>
|
||||
|
||||
using namespace web;
|
||||
#define BUFSIZE 1024
|
||||
|
||||
TwoWayPipeMessageIPC* current_settings_ipc = NULL;
|
||||
|
||||
json::value get_power_toys_settings() {
|
||||
json::value result = json::value::object();
|
||||
for (auto&[name, powertoy] : modules()) {
|
||||
json::JsonObject get_power_toys_settings() {
|
||||
json::JsonObject result;
|
||||
for (const auto&[name, powertoy] : modules()) {
|
||||
try {
|
||||
json::value powertoys_config = json::value::parse(powertoy.get_config());
|
||||
result.as_object()[name] = powertoys_config;
|
||||
result.SetNamedValue(name, powertoy.json_config());
|
||||
}
|
||||
catch (json::json_exception&) {
|
||||
//Malformed JSON.
|
||||
catch (...) {
|
||||
// TODO: handle malformed JSON.
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
json::value get_all_settings() {
|
||||
json::value result = json::value::object();
|
||||
result.as_object()[L"general"] = get_general_settings();
|
||||
result.as_object()[L"powertoys"] = get_power_toys_settings();
|
||||
json::JsonObject get_all_settings() {
|
||||
json::JsonObject result;
|
||||
|
||||
result.SetNamedValue(L"general", get_general_settings());
|
||||
result.SetNamedValue(L"powertoys", get_power_toys_settings());
|
||||
return result;
|
||||
}
|
||||
|
||||
void dispatch_json_action_to_module(const json::value& powertoys_configs) {
|
||||
for (auto powertoy_element : powertoys_configs.as_object()) {
|
||||
std::wstringstream ws;
|
||||
ws << powertoy_element.second;
|
||||
if (modules().find(powertoy_element.first) != modules().end()) {
|
||||
modules().at(powertoy_element.first).call_custom_action(ws.str());
|
||||
void dispatch_json_action_to_module(const json::JsonObject& powertoys_configs) {
|
||||
for (const auto& powertoy_element : powertoys_configs) {
|
||||
const std::wstring name{powertoy_element.Key().c_str()};
|
||||
if (modules().find(name) != modules().end()) {
|
||||
const auto element = powertoy_element.Value().Stringify();
|
||||
modules().at(name).call_custom_action(element.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void send_json_config_to_module(const std::wstring& module_key, const std::wstring& settings) {
|
||||
if (modules().find(module_key) != modules().end()) {
|
||||
modules().at(module_key).set_config(settings);
|
||||
modules().at(module_key).set_config(settings.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void dispatch_json_config_to_modules(const json::value& powertoys_configs) {
|
||||
for (auto powertoy_element : powertoys_configs.as_object()) {
|
||||
std::wstringstream ws;
|
||||
ws << powertoy_element.second;
|
||||
send_json_config_to_module(powertoy_element.first, ws.str());
|
||||
void dispatch_json_config_to_modules(const json::JsonObject& powertoys_configs) {
|
||||
for (const auto& powertoy_element : powertoys_configs) {
|
||||
const auto element = powertoy_element.Value().Stringify();
|
||||
send_json_config_to_module(powertoy_element.Key().c_str(), element.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
void dispatch_received_json(const std::wstring &json_to_parse) {
|
||||
json::value j = json::value::parse(json_to_parse);
|
||||
for(auto base_element : j.as_object()) {
|
||||
if (base_element.first == L"general") {
|
||||
apply_general_settings(base_element.second);
|
||||
std::wstringstream ws;
|
||||
ws << get_all_settings();
|
||||
if (current_settings_ipc != NULL) {
|
||||
current_settings_ipc->send(ws.str());
|
||||
const json::JsonObject j = json::JsonObject::Parse(json_to_parse);
|
||||
for(const auto & base_element : j) {
|
||||
const auto name = base_element.Key();
|
||||
const auto value = base_element.Value();
|
||||
|
||||
if (name == L"general") {
|
||||
apply_general_settings(value.GetObjectW());
|
||||
if (current_settings_ipc != nullptr) {
|
||||
const std::wstring settings_string{get_all_settings().Stringify().c_str()};
|
||||
current_settings_ipc->send(settings_string);
|
||||
}
|
||||
} else if (base_element.first == L"powertoys") {
|
||||
dispatch_json_config_to_modules(base_element.second);
|
||||
std::wstringstream ws;
|
||||
ws << get_all_settings();
|
||||
if (current_settings_ipc != NULL) {
|
||||
current_settings_ipc->send(ws.str());
|
||||
} else if (name == L"powertoys") {
|
||||
dispatch_json_config_to_modules(value.GetObjectW());
|
||||
if (current_settings_ipc != nullptr) {
|
||||
const std::wstring settings_string{get_all_settings().Stringify().c_str()};
|
||||
current_settings_ipc->send(settings_string);
|
||||
}
|
||||
} else if (base_element.first == L"refresh") {
|
||||
std::wstringstream ws;
|
||||
ws << get_all_settings();
|
||||
if (current_settings_ipc != NULL) {
|
||||
current_settings_ipc->send(ws.str());
|
||||
} else if (name == L"refresh") {
|
||||
if (current_settings_ipc != nullptr) {
|
||||
const std::wstring settings_string{get_all_settings().Stringify().c_str()};
|
||||
current_settings_ipc->send(settings_string);
|
||||
}
|
||||
} else if (base_element.first == L"action") {
|
||||
dispatch_json_action_to_module(base_element.second);
|
||||
} else if (name == L"action") {
|
||||
dispatch_json_action_to_module(value.GetObjectW());
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -118,7 +117,7 @@ void run_settings_window() {
|
||||
wcscat_s(executable_path, L"\\PowerToysSettings.exe");
|
||||
WCHAR executable_args[MAX_PATH * 3];
|
||||
|
||||
std::wstring settings_theme_setting = get_general_settings().at(L"theme").as_string();
|
||||
const std::wstring settings_theme_setting{get_general_settings().GetNamedString(L"theme").c_str()};
|
||||
std::wstring settings_theme;
|
||||
if (settings_theme_setting == L"dark" || (settings_theme_setting == L"system" && WindowsColors::is_dark_mode())) {
|
||||
settings_theme = L" dark"; // Include arg separating space
|
||||
|
||||
Reference in New Issue
Block a user