Save preferences periodically if they are modified (fix #4154)

This commit is contained in:
David Capello 2023-11-22 19:04:45 -03:00
parent 8226e5285a
commit f4d9e33806
3 changed files with 58 additions and 1 deletions

View File

@ -429,6 +429,15 @@ namespace {
CloseMainWindow(std::unique_ptr<MainWindow>& win) : m_win(win) { }
~CloseMainWindow() { m_win.reset(nullptr); }
};
// Each 10 seconds we save the modified preferences
struct SavePreferencesPeriodically {
ui::Timer m_timer;
SavePreferencesPeriodically() : m_timer(10000) {
m_timer.Tick.connect([]{ Preferences::instance().save(); });
}
~SavePreferencesPeriodically() { }
void start() { m_timer.start(); }
};
#endif
struct CloseAllDocs {
@ -466,6 +475,7 @@ void App::run()
{
#ifdef ENABLE_UI
CloseMainWindow closeMainWindow(m_mainWindow);
SavePreferencesPeriodically savePrefTimer;
#endif
CloseAllDocs closeAllDocsAtExit(context());
@ -543,6 +553,8 @@ void App::run()
// Run the GUI main message loop
try {
savePrefTimer.start();
manager->run();
set_app_state(AppState::kClosing);
}

View File

@ -65,26 +65,32 @@ public:
}
void setValue(const char* section, const char* name, const char* value) {
m_dirty = true;
m_ini.SetValue(section, name, value);
}
void setBoolValue(const char* section, const char* name, bool value) {
m_dirty = true;
m_ini.SetBoolValue(section, name, value);
}
void setIntValue(const char* section, const char* name, int value) {
m_dirty = true;
m_ini.SetLongValue(section, name, value);
}
void setDoubleValue(const char* section, const char* name, double value) {
m_dirty = true;
m_ini.SetDoubleValue(section, name, value);
}
void deleteValue(const char* section, const char* name) {
m_dirty = true;
m_ini.Delete(section, name, true);
}
void deleteSection(const char* section) {
m_dirty = true;
m_ini.Delete(section, nullptr, true);
}
@ -101,10 +107,15 @@ public:
return false;
}
}
m_dirty = false;
return true;
}
void save() {
if (!m_dirty)
return;
base::FileHandle file(base::open_file(m_filename, "wb"));
if (file) {
SI_Error err = m_ini.SaveFile(file.get());
@ -112,12 +123,16 @@ public:
LOG(ERROR, "CFG: Error %d saving configuration into %s\n",
(int)err, m_filename.c_str());
}
else {
m_dirty = false;
}
}
}
private:
std::string m_filename;
CSimpleIniA m_ini;
bool m_dirty = false;
};
CfgFile::CfgFile()

View File

@ -36,6 +36,7 @@ static void print_pref_class_def(TiXmlElement* elem, const std::string& classNam
std::cout
<< indent << " void load();\n"
<< indent << " void save();\n"
<< indent << " bool isDirty() const;\n"
<< indent << " Section* section(const char* id) override;\n"
<< indent << " OptionBase* option(const char* id) override;\n";
@ -200,7 +201,9 @@ static void print_pref_class_impl(TiXmlElement* elem, const std::string& prefix,
std::cout
<< "void " << prefix << className << "::save()\n"
<< "{\n";
<< "{\n"
<< " if (!isDirty())\n"
<< " return;\n";
child = (elem->FirstChild() ? elem->FirstChild()->ToElement(): NULL);
while (child) {
@ -222,6 +225,33 @@ static void print_pref_class_impl(TiXmlElement* elem, const std::string& prefix,
<< "}\n"
<< "\n";
// Section::isDirty()
std::cout
<< "bool " << prefix << className << "::isDirty() const\n"
<< "{\n";
child = (elem->FirstChild() ? elem->FirstChild()->ToElement(): NULL);
while (child) {
if (child->Value()) {
std::string name = child->Value();
if (name == "option") {
std::string memberName = convert_xmlid_to_cppid(child->Attribute("id"), false);
std::cout << " if (" << memberName << ".isDirty()) return true;\n";
}
else if (name == "section") {
std::string memberName = convert_xmlid_to_cppid(child->Attribute("id"), false);
std::cout << " if (" << memberName << ".isDirty()) return true;\n";
}
}
child = child->NextSiblingElement();
}
std::cout
<< " return false;\n"
<< "}\n"
<< "\n";
// Section::section(id)
std::cout