std::map<String, String> CIniOptionsMgr::Load(const String& iniFilePath)
{
- std::map<String, String> iniFileKeyValues;
- std::vector<tchar_t> str(32768);
- if (GetPrivateProfileSection(lpAppName, str.data(), static_cast<DWORD>(str.size()), iniFilePath.c_str()) > 0)
- {
- const tchar_t* p = str.data();
- while (*p)
- {
- const tchar_t* v = tc::tcschr(p, '=');
- if (!v)
- break;
- ++v;
- size_t vlen = tc::tcslen(v);
- String value{ v, v + vlen };
- String key{ p, v - 1 };
- iniFileKeyValues.insert_or_assign(key, UnescapeValue(value));
- p = v + vlen + 1;
- }
- }
+ std::map<String, String> iniFileKeyValues = ReadIniFile(iniFilePath, lpAppName);
+ std::vector<tchar_t> str(65536);
// after reading the "WinMerge" section try to read the "Defaults" section; overwrite existing entries in "iniFileKeyValues" with the ones from the "Defaults" section
if (GetPrivateProfileSection(lpDefaultSection, str.data(), static_cast<DWORD>(str.size()), iniFilePath.c_str()) > 0)
int COptionsMgr::ImportOptions(const String& filename)
{
int retVal = COption::OPT_OK;
- const int BufSize = 40960; // This should be enough for a long time..
+ const int BufSize = 65536; // This should be enough for a long time..
std::vector<tchar_t> buf(BufSize);
auto oleTranslateColor = [](unsigned color) -> unsigned { return ((color & 0xffffff00) == 0x80000000) ? GetSysColor(color & 0x000000ff) : color; };
if (len == 0)
return COption::OPT_NOTFOUND;
- bool init = false;
tchar_t *pKey = buf.data();
while (*pKey != '\0')
{
varprop::VariantValue value = Get(pKey);
- if (value.GetType() == varprop::VT_NULL)
- {
- init = true;
- tchar_t strType[MAX_PATH_FULL] = {0};
- GetPrivateProfileString(_T("WinMerge.TypeInfo"), pKey, _T(""), strType, MAX_PATH_FULL, filename.c_str());
- if (tc::tcsicmp(strType, _T("bool")) == 0)
- value.SetBool(false);
- else if (tc::tcsicmp(strType, _T("int")) == 0)
- value.SetInt(0);
- else if (tc::tcsicmp(strType, _T("string")) == 0)
- value.SetString(_T(""));
- }
if (value.GetType() == varprop::VT_BOOL)
{
}
if (value.GetType() != varprop::VT_NULL)
- {
- if (init)
- InitOption(pKey, value);
SaveOption(pKey, value);
- }
pKey += tc::tcslen(pKey);
return { strPath, strValue };
}
+std::map<String, String> COptionsMgr::ReadIniFile(const String& filename, const String& section)
+{
+ std::map<String, String> iniFileKeyValues;
+ std::vector<tchar_t> str(65536);
+ if (GetPrivateProfileSection(section.c_str(), str.data(), static_cast<DWORD>(str.size()), filename.c_str()) > 0)
+ {
+ const tchar_t* p = str.data();
+ while (*p)
+ {
+ const tchar_t* v = tc::tcschr(p, '=');
+ if (!v)
+ break;
+ ++v;
+ size_t vlen = tc::tcslen(v);
+ String value{ v, v + vlen };
+ String key{ p, v - 1 };
+ iniFileKeyValues.insert_or_assign(key, UnescapeValue(value));
+ p = v + vlen + 1;
+ }
+ }
+ return iniFileKeyValues;
+}
+
static String EscapeValue(const String& text);
static String UnescapeValue(const String& text);
static std::pair<String, String> SplitName(const String& strName);
+ static std::map<String, String> ReadIniFile(const String& filename, const String& section);
OptionsMap m_optionsMap; /**< Map where options are stored. */
return retVal;
}
+int CRegOptionsMgr::ImportOptions(const String& filename)
+{
+ int retVal = ImportAllUnloadedValues(filename);
+ if (retVal == COption::OPT_OK)
+ retVal = COptionsMgr::ImportOptions(filename);
+ return retVal;
+}
+
int CRegOptionsMgr::ExportAllUnloadedValues(HKEY hKey, const String& strPath, const String& filename) const
{
DWORD dwIndex = 0;
return COption::OPT_OK;
}
+int CRegOptionsMgr::ImportAllUnloadedValues(const String& filename)
+{
+ auto iniFileKeyValues = ReadIniFile(filename, _T("WinMerge"));
+ auto iniFileKeyTypes = ReadIniFile(filename, _T("WinMerge.TypeInfo"));
+ for (const auto& [key, strValue] : iniFileKeyValues)
+ {
+ if (m_optionsMap.find(key) == m_optionsMap.end() &&
+ iniFileKeyTypes.find(key) != iniFileKeyTypes.end())
+ {
+ auto [strPath, strValueName] = SplitName(key);
+ HKEY hKey = OpenKey(strPath, true);
+ if (hKey)
+ {
+ varprop::VariantValue value;
+ String strType = iniFileKeyTypes[key];
+ if (tc::tcsicmp(strType.c_str(), _T("bool")) == 0)
+ value.SetBool(tc::ttoi(strValue.c_str()) != 0);
+ else if (tc::tcsicmp(strType.c_str(), _T("int")) == 0)
+ {
+ auto lval = tc::tcstoll(strValue.c_str(), nullptr, 10);
+ value.SetInt(static_cast<int>(lval));
+ }
+ else if (tc::tcsicmp(strType.c_str(), _T("string")) == 0)
+ value.SetString(UnescapeValue(strValue));
+ SaveValueToReg(hKey, strValueName, value);
+ CloseKey(hKey, strPath);
+ }
+ }
+ }
+ return COption::OPT_OK;
+}
+
/**
* @brief Set registry root path for options.
*
virtual int FlushOptions() override;
virtual int ExportOptions(const String& filename, const bool bHexColor=false) const override;
+ virtual int ImportOptions(const String& filename) override;
virtual void SetSerializing(bool serializing=true) override { m_serializing = serializing; }
const varprop::VariantValue& value);
static unsigned __stdcall AsyncWriterThreadProc(void *pParam);
int ExportAllUnloadedValues(HKEY hKey, const String& strPath, const String& filename) const;
+ int ImportAllUnloadedValues(const String& filename);
private:
String m_registryRoot; /**< Registry path where to store options. */