PowerToys/src/common/settings_objects.cpp
udit3333 83ce8a2197
[0.16]: Merge Preview Handlers in Master (#1516)
* Added project template for common library

* Added reference to stylecop.json

* Fixed xml documetation file path for common project

* Added reference to stylecop.json

* Added COM interface interpolations to C#

* Changed namespace to Common

* Added xml doc to com interfaces

* Removed AnyCPU configuration from solution file

* Added Preview Hander and form User Control Implementation

* Fix stylecop warnings

* Added test control and handler

* Added Xaml description for preview handler

* Added Xml documenatation

* Updated the control to form

* Added registration and unregistration logic for the handler

* Moved the files in separate folder and fix PR comments

* updated the name of previewhandler class to base class

* Added the DoPreview to PreviewHandlerControl Interface

* Modified the Dopreview and Unload as virtual method

* Uncommented the DocumentText to help bug repro

* HTML Parsing Extension for preview pane markdown renderer (#1108)

* Added Extension for html post processing

* Added unit test poroject for preview pane

* Added pipline test and base test function

* Added Tests for extension

* Added tests for url slashes

* Added tests for url and figure caption

* Markdown preview pane (#1128)

* Added Extension for html post processing

* Added unit test poroject for preview pane

* Added pipline test and base test function

* Added Tests for extension

* Added handler and control for markdown

* Tests added

* Locally working version for markdown

* Working image relative url's in markdown

* Added CSS to preview display

* Updates CSS for code block

* Removed html file write comment in markdown control

* Updated assembly version and web browser control test

* Add Svg preview handler (#1129)

* Added a new project for Svg preview handler

* Added initial implementation of Svg Preview Handler

* Fixed output path

* Added Unit Test Project

* Added StreamWrapper and Update Svg Control

* Updated Svg Handler Guid

* Removed migration backup folder

* Removed Fluent Assertions NuGet

* Added Comments for StreamWrapper

* Removed the manual GC collect

* Added unit tests for Svg preview Handler

* Updated the xml doc for stream wrapper

* User/lamotile/add_powerpreviewsettings (#1075)

* Added powersettings to PowerToys Settings UI

* added settings library

* updated settings-web

* updated project oncfiguration

* updated project onfiguration

* updated project .sln file

* removed .etl file and added it to git-ignore

* separated the PowerPreviewModule into split classes .cpp and .h

* moved PowerPreviewModule implemnetations to .cpp file

* fixed StringTable formatter

* fixed spacing in resource.h

* added m_ to member varibales

* initiliaze m_isPreviewEnabled in the base class

* removed duplication of objects by using pass by refference and std::move

* made the getters const

* updated naming convention

* Split test calsses

* Add const string

* Replaced move with const string

* Made attributes private

* Made attributes private

* removed unused constructor

* Update resource.h

formatted resource.h

* Adding unit tests for preview handler common (#1156)

* Changed the name of the Common library to PreviewHandlerCommon

* Added unit tests project for PreviewHandlerCommon

* Updated ComInterop accessor type

* Added unit tests for PreviewHandlerbase

* Added tests for file and stream based handler

* Added unit tests for StreamWrapper

* Added form handler unit tests

* Added Unit tests for FormHandlerControl

* Added file header

* Add Powerpreview project

* Add spacing in sln file

* swapped string refferences (#1199)

* added registry methods and enable/disable preview handlers (#1230)

* added registry methods and enable/disable preview handlers

* formatted .rc file.

* formatted resource file

* formatted .rc file.

* formatted settings.cpp

* formatted settings.h

* formatted SVGPreviewSettingsClassTest.cpp

* Formatted MarkDownPreviewSettingsClassTest.cpp

* using wide strings

* formatted settings.h

* FileExplorerPreviewSettingsTest.cpp formatting

* fixed typo and formatting

* closing Registry and fixing typos

* formmarted code using ctrl+k+d

* fixed naming

* fixed typo

* changed if/else reverse order

* Markdown preview pane  (#1220)

* Added rich text bar for information display

* Added infobar

* Added tests for extension and markdown control

* Added xml docstring for markdown preview handler control

* Updated assembly file for markdown preview pane

* Updated removal of script tag without modifying CSS

* Added info bar text string to resource file.

* Removed error with infobar display on first rendering

* Updated assembly version

* Remove script and image element from Svg (#1231)

* Added implementation to remove script and image tag

* Added Unit tests for SvgPreviewHandlerHelper

* Updated Unit tests for SvgPreviewControl

* Moved the hardcoded string to resource file

* Changed the LocalMachine to CurrentUser for preview handler registration

* Added unit tests for multiple blocked elements tags

* User/lamotile/update settings objects (#1263)

* added registry methods and enable/disable preview handlers

* formatted .rc file.

* formatted resource file

* formatted .rc file.

* formatted settings.cpp

* formatted settings.h

* formatted SVGPreviewSettingsClassTest.cpp

* Formatted MarkDownPreviewSettingsClassTest.cpp

* using wide strings

* formatted settings.h

* FileExplorerPreviewSettingsTest.cpp formatting

* fixed typo and formatting

* closing Registry and fixing typos

* formmarted code using ctrl+k+d

* fixed naming

* fixed typo

* changed if/else reverse order

* updated setiings_objects.cpp

* removed changes on files that are not part of this PR

* removed const ref on primative types

* updated pass by ref semantic and removed pas by reff on primative types

* fixed spaces in the commas

* fixed spaces in brackets

* Preview pane telemetry (#1299)

* Added telemetry base class and markdown telemetry class

* Updated docstring for telemetry event.

* Added telemetry to markdown for error

* Added try catch for markdown preview handler and display error bar

* Updated markdown telemetry to make event names global variable

* Updated parameter name to camel casing and telemetry event name naming.

* Corrected assembbly version for svg renderer

* Markdown Image files display (#1303)

* Added telemetry base class and markdown telemetry class

* Updated docstring for telemetry event.

* Added telemetry to markdown for error

* Added try catch for markdown preview handler and display error bar

* Updated markdown telemetry to make event names global variable

* Updated Markdown preview to display without vertical scrollbar and removed xml doc to html agility pack.

* Updated parameter name to camel casing and telemetry event name naming.

* Corrected assembbly version for svg renderer

* Removed duplicate function

* Add telemetry for Svg preview handler (#1314)

* Added telemetry events for Svg Preview Handler

* Added unit test in case preview handler throws

* Updated the Error event name

* Remove the not required return statement

* User/lamotile/add read me (#1332)

* add readme

* moved images

* re-added images'

* Fixed gramma

* Update figure number refference

* improve preview handler intergration (#1319)

* improve preview handler intergration

* Fixed typo

* updated typo

* updated enable() function

* updated is enabled()

* re-updated is enabled()

* added this-> key word

* (0.16) - Install preview handler with msix (#1339)

* Removed the registration logic from preview handlers

* Updated the output path

* Added logic to shim the activation of .net assembly

* Updated manifest file

* Fix the allowedsilenttakeover filed in manifest

* Updated the appxmanifest file

* Added AllowSilentDefaultTakeOver in manifest

* Fix returned error code by DllGetClassObject

* Moved the CLSID to a common header file

* Added info about where CLSID needs to be updated

* Added a .reg file for the Keys added in registry.dat

* Added comments for DllGetClassObject

* Svg Preview Handler block external component  (#1368)

* Removed the registration logic from preview handlers

* Updated the output path

* Added logic to shim the activation of .net assembly

* Updated manifest file

* Fix the allowedsilenttakeover filed in manifest

* Updated the appxmanifest file

* Added AllowSilentDefaultTakeOver in manifest

* Fix returned error code by DllGetClassObject

* Moved the CLSID to a common header file

* Added info about where CLSID needs to be updated

* Added a .reg file for the Keys added in registry.dat

* Added comments for DllGetClassObject

* Extended WebBrowserSite for setting flags in DISPID_AMBIENT_DLCONTROL

* Added XML Documenatation

* Removed the logic for deleting image and script element from Svg

* Updated Unit Tests

* Updated typecast of uint

* Forwarded calls to Type.InvokeMember

* Resolve PR Comments

* Adding MSI Installation for Preview Handler (#1436)

* Updated wxs for including dll and registry keys for preview handlers

* Changed the casing for registry key

* Resolve PR Comments

* Added comments for File element

* Call GC on preview unloading (#1456)

* Call GC collect on preview unloading

* Added github issue link

* Update Web browser control for Markdown Previewer (#1464)

* Updated Webbrowser control

* Updated Unit tests

* Disabled Navigation for Svg Previewer

* Fix power preview unit tests (#1508)

* Decoupled registry interaction logic

* Updated File explorer settings

* Updated unit tests for PowerPreview Settings

* Added Asserrtion for Scope of registry key

* Updated the registry value to match with installation registry value

* Sync master settings.cpp

* Merge settings changes from PreviewHandlers

* Remove newline changes added into in example_powertoy\trace.cpp

* Chaned .net framework to 4.7.2

* Updated Csproj files to auto generate Assembly.info files

* Updated msi installer to use version variable for preview handlers assembly

* Removed the signing of Assembly and updated wxs to not include PublicKeyToken

* Updated the Path in Packaginglayout.xml to modules from Gac and the registry hive binary

* Regenerated updated JS and html file

* Resolve PR Comments

* Readded the wprp file

Co-authored-by: Divyansh <divyan@microsoft.com>
Co-authored-by: Divyansh <somm14divi@gmail.com>
Co-authored-by: Lavius Motileng <58791731+laviusmotileng-ms@users.noreply.github.com>
2020-03-11 15:53:49 -07:00

362 lines
15 KiB
C++

#include "pch.h"
#include "settings_objects.h"
#include "settings_helpers.h"
namespace PowerToysSettings
{
Settings::Settings(const HINSTANCE hinstance, std::wstring_view powertoy_name)
{
m_instance = hinstance;
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.SetNamedValue(L"description", json::value(get_resource(resource_id)));
}
void Settings::set_description(std::wstring_view description)
{
m_json.SetNamedValue(L"description", json::value(description));
}
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(std::wstring_view overview_link)
{
m_json.SetNamedValue(L"overview_link", json::value(overview_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(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(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.GetNamedObject(L"properties").SetNamedValue(name, toggle);
}
// add_int_spinner overloads.
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(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.GetNamedObject(L"properties").SetNamedValue(name, spinner);
}
// add_string overloads.
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(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.GetNamedObject(L"properties").SetNamedValue(name, string);
}
// add_multiline_string overloads.
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(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.GetNamedObject(L"properties").SetNamedValue(name, ml_string);
}
void Settings::add_header_szLarge(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"header_large"));
string.SetNamedValue(L"value", json::value(value));
string.SetNamedValue(L"order", json::value(++m_curr_priority));
m_json.GetNamedObject(L"properties").SetNamedValue(name, string);
}
// add_color_picker overloads.
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(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.GetNamedObject(L"properties").SetNamedValue(name, picker);
}
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(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.GetNamedObject(L"properties").SetNamedValue(name, hotkey);
}
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)
{
keys_and_texts.emplace_back(kv.first, get_resource(kv.second));
}
add_choice_group(name, get_resource(description_resource_id), value, keys_and_texts);
}
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));
}
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.GetNamedObject(L"properties").SetNamedValue(name, choice_group);
}
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)
{
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(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));
}
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.GetNamedObject(L"properties").SetNamedValue(name, dropdown);
}
// add_custom_action overloads.
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(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(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.GetNamedObject(L"properties").SetNamedValue(name, custom_action);
}
// Serialization methods.
std::wstring Settings::serialize()
{
return m_json.Stringify().c_str();
}
bool Settings::serialize_to_buffer(wchar_t* buffer, int* buffer_size)
{
auto result = m_json.Stringify();
const int result_len = (int)result.size() + 1;
if (buffer == nullptr || *buffer_size < result_len)
{
*buffer_size = result_len;
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* 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(std::wstring_view powertoy_name)
{
_name = powertoy_name;
set_version();
m_json.SetNamedValue(L"name", json::value(powertoy_name));
m_json.SetNamedValue(L"properties", json::JsonObject{});
}
PowerToyValues PowerToyValues::from_json_string(std::wstring_view json)
{
PowerToyValues result = PowerToyValues();
result.m_json = json::JsonValue::Parse(json).GetObjectW();
result._name = result.m_json.GetNamedString(L"name");
return result;
}
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;
}
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);
}
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");
}
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"));
}
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();
}
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.Stringify().c_str();
}
void PowerToyValues::save_to_settings_file()
{
set_version();
PTSettingsHelper::save_module_settings(_name, m_json);
}
void PowerToyValues::set_version()
{
m_json.SetNamedValue(L"version", json::value(m_version));
}
}