Settings.cpp
1 #include "pch.h" 2 #include "Settings.h" 3 #include "ImageResizerConstants.h" 4 5 #include <common/utils/json.h> 6 #include <common/SettingsAPI/settings_helpers.h> 7 #include <filesystem> 8 #include <commctrl.h> 9 10 namespace 11 { 12 const wchar_t c_imageResizerDataFilePath[] = L"\\image-resizer-settings.json"; 13 const wchar_t c_rootRegPath[] = L"Software\\Microsoft\\ImageResizer"; 14 const wchar_t c_enabled[] = L"enabled"; 15 const wchar_t c_ImageResizer[] = L"Image Resizer"; 16 17 unsigned int RegReadInteger(const std::wstring& valueName, unsigned int defaultValue) 18 { 19 DWORD type = REG_DWORD; 20 DWORD data = 0; 21 DWORD size = sizeof(DWORD); 22 if (SHGetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName.c_str(), &type, &data, &size) == ERROR_SUCCESS) 23 { 24 return data; 25 } 26 return defaultValue; 27 } 28 29 bool RegReadBoolean(const std::wstring& valueName, bool defaultValue) 30 { 31 DWORD value = RegReadInteger(valueName.c_str(), defaultValue ? 1 : 0); 32 return (value == 0) ? false : true; 33 } 34 35 bool LastModifiedTime(const std::wstring& filePath, FILETIME* lpFileTime) 36 { 37 WIN32_FILE_ATTRIBUTE_DATA attr{}; 38 if (GetFileAttributesExW(filePath.c_str(), GetFileExInfoStandard, &attr)) 39 { 40 *lpFileTime = attr.ftLastWriteTime; 41 return true; 42 } 43 return false; 44 } 45 } 46 47 CSettings::CSettings() 48 { 49 generalJsonFilePath = PTSettingsHelper::get_powertoys_general_save_file_location(); 50 std::wstring oldSavePath = PTSettingsHelper::get_module_save_folder_location(ImageResizerConstants::ModuleOldSaveFolderKey); 51 std::wstring savePath = PTSettingsHelper::get_module_save_folder_location(ImageResizerConstants::ModuleSaveFolderKey); 52 std::error_code ec; 53 if (std::filesystem::exists(oldSavePath, ec)) 54 { 55 std::filesystem::copy(oldSavePath, savePath, std::filesystem::copy_options::recursive, ec); 56 std::filesystem::remove_all(oldSavePath, ec); 57 } 58 59 jsonFilePath = savePath + std::wstring(c_imageResizerDataFilePath); 60 Load(); 61 } 62 63 void CSettings::Save() 64 { 65 json::JsonObject jsonData; 66 67 json::to_file(jsonFilePath, jsonData); 68 GetSystemTimeAsFileTime(&lastLoadedTime); 69 } 70 71 void CSettings::Load() 72 { 73 if (!std::filesystem::exists(jsonFilePath)) 74 { 75 MigrateFromRegistry(); 76 77 Save(); 78 } 79 else 80 { 81 ParseJson(); 82 } 83 } 84 85 void CSettings::RefreshEnabledState() 86 { 87 // Load json settings from data file if it is modified in the meantime. 88 FILETIME lastModifiedTime{}; 89 if (!(LastModifiedTime(generalJsonFilePath, &lastModifiedTime) && 90 CompareFileTime(&lastModifiedTime, &lastLoadedGeneralSettingsTime) == 1)) 91 return; 92 93 lastLoadedGeneralSettingsTime = lastModifiedTime; 94 95 auto json = json::from_file(generalJsonFilePath); 96 if (!json) 97 return; 98 99 const json::JsonObject& jsonSettings = json.value(); 100 try 101 { 102 json::JsonObject modulesEnabledState; 103 json::get(jsonSettings, c_enabled, modulesEnabledState, json::JsonObject{}); 104 json::get(modulesEnabledState, c_ImageResizer, settings.enabled, true); 105 } 106 catch (const winrt::hresult_error&) 107 { 108 } 109 } 110 111 void CSettings::Reload() 112 { 113 // Load json settings from data file if it is modified in the meantime. 114 FILETIME lastModifiedTime{}; 115 if (LastModifiedTime(jsonFilePath, &lastModifiedTime) && 116 CompareFileTime(&lastModifiedTime, &lastLoadedTime) == 1) 117 { 118 Load(); 119 } 120 } 121 122 void CSettings::MigrateFromRegistry() 123 { 124 settings.enabled = RegReadBoolean(c_enabled, true); 125 } 126 127 void CSettings::ParseJson() 128 { 129 auto json = json::from_file(jsonFilePath); 130 if (json) 131 { 132 const json::JsonObject& jsonSettings = json.value(); 133 try 134 { 135 // NB: add any new settings here 136 } 137 catch (const winrt::hresult_error&) 138 { 139 } 140 } 141 GetSystemTimeAsFileTime(&lastLoadedTime); 142 } 143 144 CSettings& CSettingsInstance() 145 { 146 static CSettings instance; 147 return instance; 148 }