2019-09-05 00:26:26 +08:00
|
|
|
#include "pch.h"
|
|
|
|
#include "settings_objects.h"
|
|
|
|
#include "settings_helpers.h"
|
|
|
|
|
|
|
|
namespace PowerToysSettings {
|
|
|
|
|
|
|
|
Settings::Settings(const HINSTANCE hinstance, const std::wstring& 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();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Settings::set_description(UINT resource_id) {
|
|
|
|
m_json.as_object()[L"description"] = web::json::value::string(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_icon_key(const std::wstring& icon_key) {
|
|
|
|
m_json.as_object()[L"icon_key"] = web::json::value::string(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_video_link(const std::wstring& video_link) {
|
|
|
|
m_json.as_object()[L"video_link"] = web::json::value::string(video_link);
|
|
|
|
}
|
|
|
|
|
|
|
|
// add_bool_toogle overloads.
|
|
|
|
void Settings::add_bool_toogle(const std::wstring& 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);
|
|
|
|
|
|
|
|
m_json.as_object()[L"properties"].as_object()[name] = item;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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) {
|
|
|
|
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);
|
|
|
|
|
|
|
|
m_json.as_object()[L"properties"].as_object()[name] = item;
|
|
|
|
}
|
|
|
|
|
|
|
|
// add_string overloads.
|
|
|
|
void Settings::add_string(const std::wstring& name, UINT description_resource_id, const std::wstring& 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);
|
|
|
|
|
|
|
|
m_json.as_object()[L"properties"].as_object()[name] = item;
|
|
|
|
}
|
|
|
|
|
2019-11-18 17:29:56 +08:00
|
|
|
// add_multiline_string overloads.
|
|
|
|
void Settings::add_multiline_string(const std::wstring& name, UINT description_resource_id, const std::wstring& 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);
|
|
|
|
|
|
|
|
m_json.as_object()[L"properties"].as_object()[name] = item;
|
|
|
|
}
|
|
|
|
|
2019-09-05 00:26:26 +08:00
|
|
|
// add_color_picker overloads.
|
|
|
|
void Settings::add_color_picker(const std::wstring& name, UINT description_resource_id, const std::wstring& 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);
|
|
|
|
|
|
|
|
m_json.as_object()[L"properties"].as_object()[name] = item;
|
|
|
|
}
|
|
|
|
|
2019-10-02 23:18:55 +08:00
|
|
|
void Settings::add_hotkey(const std::wstring& 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);
|
|
|
|
|
|
|
|
m_json.as_object()[L"properties"].as_object()[name] = item;
|
|
|
|
}
|
|
|
|
|
2019-10-02 23:07:12 +08:00
|
|
|
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) {
|
|
|
|
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) {
|
|
|
|
keys_and_texts.emplace_back(kv.first, get_resource(kv.second));
|
|
|
|
}
|
|
|
|
add_choice_group(name, get_resource(description_resource_id), value, keys_and_texts);
|
|
|
|
}
|
2019-10-03 16:29:43 +08:00
|
|
|
|
2019-10-02 23:07:12 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
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);
|
|
|
|
|
|
|
|
m_json.as_object()[L"properties"].as_object()[name] = item;
|
|
|
|
}
|
|
|
|
|
2019-10-03 16:29:43 +08:00
|
|
|
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) {
|
|
|
|
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) {
|
|
|
|
keys_and_texts.emplace_back(kv.first, get_resource(kv.second));
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
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);
|
|
|
|
|
|
|
|
m_json.as_object()[L"properties"].as_object()[name] = item;
|
|
|
|
}
|
|
|
|
|
2019-09-05 00:26:26 +08:00
|
|
|
// 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) {
|
|
|
|
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) {
|
|
|
|
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);
|
|
|
|
|
|
|
|
m_json.as_object()[L"properties"].as_object()[name] = item;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Serialization methods.
|
|
|
|
std::wstring Settings::serialize() {
|
|
|
|
return m_json.serialize();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Settings::serialize_to_buffer(wchar_t* buffer, int *buffer_size) {
|
|
|
|
std::wstring result = m_json.serialize();
|
|
|
|
int result_len = (int)result.length();
|
|
|
|
|
|
|
|
if (buffer == nullptr || *buffer_size < result_len) {
|
|
|
|
*buffer_size = result_len + 1;
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
wcscpy_s(buffer, *buffer_size, result.c_str());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return L"RESOURCE ID NOT FOUND: " + std::to_wstring(resource_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
PowerToyValues::PowerToyValues(const std::wstring& 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();
|
|
|
|
}
|
|
|
|
|
|
|
|
PowerToyValues PowerToyValues::from_json_string(const std::wstring& json) {
|
|
|
|
PowerToyValues result = PowerToyValues();
|
|
|
|
result.m_json = web::json::value::parse(json);
|
|
|
|
result._name = result.m_json.as_object()[L"name"].as_string();
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
PowerToyValues PowerToyValues::load_from_settings_file(const std::wstring & 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
};
|
|
|
|
|
2019-10-02 23:18:55 +08:00
|
|
|
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());
|
|
|
|
};
|
|
|
|
|
2019-09-05 00:26:26 +08:00
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
2019-10-02 23:18:55 +08:00
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
2019-09-05 00:26:26 +08:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2019-10-02 23:18:55 +08:00
|
|
|
web::json::value PowerToyValues::get_json(const std::wstring& property_name) {
|
|
|
|
return m_json[L"properties"][property_name][L"value"];
|
|
|
|
}
|
|
|
|
|
2019-09-05 00:26:26 +08:00
|
|
|
std::wstring PowerToyValues::serialize() {
|
|
|
|
set_version();
|
|
|
|
return m_json.serialize();
|
|
|
|
}
|
|
|
|
|
|
|
|
void PowerToyValues::save_to_settings_file() {
|
|
|
|
set_version();
|
|
|
|
PTSettingsHelper::save_module_settings(_name, m_json);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PowerToyValues::set_version() {
|
|
|
|
m_json.as_object()[L"version"] = web::json::value::string(m_version);
|
|
|
|
}
|
|
|
|
}
|