Use WinRT JSON parser instead of custom cpprestsdk solution (#822)

This commit is contained in:
yuyoyuppe
2019-12-06 11:40:23 +03:00
committed by GitHub
parent e714cb9e8b
commit 7357e40d3f
41 changed files with 488 additions and 15702 deletions

View File

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

View File

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

View File

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

View File

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

View File

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