2 * @file CIniOptionsMgr.cpp
4 * @brief Implementation of Ini file Options management class.
9 #include "CIniOptionsMgr.h"
10 #include "OptionsMgr.h"
17 using std::filesystem::current_path;
19 LPCWSTR CIniOptionsMgr::lpFilePath = NULL;
21 LPCWSTR lpAppName = TEXT("WinMerge");
22 LPCWSTR lpFileName = TEXT("\\winmerge.ini");
24 CIniOptionsMgr::CIniOptionsMgr()
26 InitializeCriticalSection(&m_cs);
29 CIniOptionsMgr::~CIniOptionsMgr()
31 DeleteCriticalSection(&m_cs);
32 delete[] CIniOptionsMgr::lpFilePath;
36 * @brief Checks wheter INI file exists.
37 * @return TRUE if INI file exist,
40 bool CIniOptionsMgr::CheckIfIniFileExist()
42 std::ifstream f(GetFilePath());
47 * @brief Get path to INI file.
48 * @return path to INI file
50 LPCWSTR CIniOptionsMgr::GetFilePath()
52 if (CIniOptionsMgr::lpFilePath == NULL)
55 std::filesystem::path p = current_path();
59 std::wstring str = p.wstring();
60 size_t length = str.length() + 1;
61 wchar_t* strCp = new wchar_t[length];
62 wcscpy_s(strCp, length, str.c_str());
65 CIniOptionsMgr::lpFilePath = strCp;
68 return CIniOptionsMgr::lpFilePath;
71 int CIniOptionsMgr::InitOption(const String& name, const varprop::VariantValue& defaultValue)
73 // Check type & bail if null
74 int valType = defaultValue.GetType();
75 if (valType == varprop::VT_NULL)
76 return COption::OPT_ERR;
78 // If we're not loading & saving options, bail
80 return AddOption(name, defaultValue);
82 EnterCriticalSection(&m_cs);
84 // check if value exist
85 String textValue = ReadValueFromFile(name);
86 bool found = textValue.size() != 0;
88 // Actually save value into our in-memory options table
89 int retVal = AddOption(name, defaultValue);
91 // Update registry if successfully saved to in-memory table
92 if (retVal == COption::OPT_OK)
96 varprop::VariantValue value(defaultValue);
97 retVal = ParseValue(name, textValue, value);
98 if (retVal == COption::OPT_OK)
100 retVal = Set(name, value);
105 LeaveCriticalSection(&m_cs);
109 int CIniOptionsMgr::InitOption(const String& name, const String& defaultValue)
111 varprop::VariantValue defValue;
112 defValue.SetString(defaultValue);
113 return InitOption(name, defValue);
116 int CIniOptionsMgr::InitOption(const String& name, const TCHAR* defaultValue)
118 return InitOption(name, String(defaultValue));
121 int CIniOptionsMgr::InitOption(const String& name, int defaultValue, bool serializable)
123 varprop::VariantValue defValue;
124 int retVal = COption::OPT_OK;
126 defValue.SetInt(defaultValue);
128 retVal = InitOption(name, defValue);
130 AddOption(name, defValue);
134 int CIniOptionsMgr::InitOption(const String& name, bool defaultValue)
136 varprop::VariantValue defValue;
137 defValue.SetBool(defaultValue);
138 return InitOption(name, defValue);
141 int CIniOptionsMgr::SaveOption(const String& name)
143 if (!m_serializing) return COption::OPT_OK;
145 varprop::VariantValue value;
146 int retVal = COption::OPT_OK;
149 int valType = value.GetType();
150 if (valType == varprop::VT_NULL)
151 retVal = COption::OPT_NOTFOUND;
153 if (retVal == COption::OPT_OK)
155 if (valType == varprop::VT_STRING)
157 String strVal = value.GetString();
158 LPCWSTR text = strVal.c_str();
159 WritePrivateProfileString(lpAppName, name.c_str(), text, GetFilePath());
161 else if (valType == varprop::VT_INT)
163 DWORD dwordVal = value.GetInt();
164 String strVal = strutils::to_str(dwordVal);
165 LPCWSTR text = strVal.c_str();
166 WritePrivateProfileString(lpAppName, name.c_str(), text, GetFilePath());
168 else if (valType == varprop::VT_BOOL)
170 DWORD dwordVal = value.GetBool() ? 1 : 0;
171 String strVal = strutils::to_str(dwordVal);
172 LPCWSTR text = strVal.c_str();
173 WritePrivateProfileString(lpAppName, name.c_str(), text, GetFilePath());
177 retVal = COption::OPT_UNKNOWN_TYPE;
184 * @brief Set new value for option and save option to file
186 int CIniOptionsMgr::SaveOption(const String& name, const varprop::VariantValue& value)
188 int retVal = Set(name, value);
189 if (retVal == COption::OPT_OK)
190 retVal = SaveOption(name);
195 * @brief Set new string value for option and save option to file
197 int CIniOptionsMgr::SaveOption(const String& name, const String& value)
199 varprop::VariantValue val;
200 val.SetString(value);
201 int retVal = Set(name, val);
202 if (retVal == COption::OPT_OK)
203 retVal = SaveOption(name);
208 * @brief Set new string value for option and save option to file
210 int CIniOptionsMgr::SaveOption(const String& name, const TCHAR* value)
212 return SaveOption(name, String(value));
215 int CIniOptionsMgr::SaveOption(const String& name, int value)
217 varprop::VariantValue val;
219 int retVal = Set(name, val);
220 if (retVal == COption::OPT_OK)
221 retVal = SaveOption(name);
225 int CIniOptionsMgr::SaveOption(const String& name, bool value)
227 varprop::VariantValue val;
229 int retVal = Set(name, val);
230 if (retVal == COption::OPT_OK)
231 retVal = SaveOption(name);
235 int CIniOptionsMgr::RemoveOption(const String& name)
237 int retVal = COption::OPT_OK;
242 SplitName(name, strPath, strValueName);
244 if (!strValueName.empty())
246 retVal = COptionsMgr::RemoveOption(name);
250 for (auto it = m_optionsMap.begin(); it != m_optionsMap.end(); )
252 if (it->first.find(strPath) == 0)
253 it = m_optionsMap.erase(it);
257 retVal = COption::OPT_OK;
260 EnterCriticalSection(&m_cs);
262 WritePrivateProfileString(lpAppName, name.c_str(), NULL, GetFilePath());
264 LeaveCriticalSection(&m_cs);
269 int CIniOptionsMgr::ExportOptions(const String& filename, const bool bHexColor) const
271 if (std::filesystem::copy_file(CIniOptionsMgr::GetFilePath(), filename))
273 return COption::OPT_OK;
277 return COption::OPT_ERR;
281 int CIniOptionsMgr::ImportOptions(const String& filename)
283 if (std::filesystem::copy_file(filename, CIniOptionsMgr::GetFilePath()))
285 return COption::OPT_OK;
289 return COption::OPT_ERR;
293 String CIniOptionsMgr::ReadValueFromFile(const String& name)
295 const int size = 100;
296 LPWSTR buffor = new TCHAR[size];
297 DWORD result = GetPrivateProfileString(lpAppName, name.c_str(), NULL, buffor, size, GetFilePath());
301 int CIniOptionsMgr::ParseValue(const String& strName, String& textValue, varprop::VariantValue& value)
303 int valType = value.GetType();
304 int retVal = COption::OPT_OK;
306 if (valType == varprop::VT_STRING)
308 value.SetString(textValue);
309 retVal = Set(strName, value);
311 else if (valType == varprop::VT_INT)
313 value.SetInt(std::stoi(textValue));
314 retVal = Set(strName, value);
316 else if (valType == varprop::VT_BOOL)
318 value.SetBool(textValue[0] == '1' ? true : false);
319 retVal = Set(strName, value);
322 retVal = COption::OPT_WRONG_TYPE;
328 * @brief Split option name to path (in registry) and
329 * valuename (in registry).
331 * Option names are given as "full path", e.g. "Settings/AutomaticRescan".
332 * This function splits that to path "Settings/" and valuename
334 * @param [in] strName Option name
335 * @param [out] srPath Path (key) in registry
336 * @param [out] strValue Value in registry
338 void CIniOptionsMgr::SplitName(const String& strName, String& strPath,
339 String& strValue) const
341 size_t pos = strName.rfind('/');
342 if (pos != String::npos)
344 size_t len = strName.length();
345 strValue = strName.substr(pos + 1, len - pos - 1); //Right(len - pos - 1);
346 strPath = strName.substr(0, pos); //Left(pos);