Merge pull request #2288 from KLayout/bugfix/issue-2284

Implemented backup files for the configuration file
This commit is contained in:
Matthias Köfferlein 2026-03-01 23:25:08 +01:00 committed by GitHub
commit 0753aa47e4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 30 additions and 12 deletions

View File

@ -164,12 +164,17 @@ static gsi::Methods application_methods ()
// TODO: basically this method belongs to Dispatcher (aka MainWindow). // TODO: basically this method belongs to Dispatcher (aka MainWindow).
// There is separate declaration for Dispatcher which we have to synchronize // There is separate declaration for Dispatcher which we have to synchronize
// with this method. // with this method.
method<C, bool, const std::string &> ("write_config", &C::write_config, gsi::arg ("file_name"), method<C, bool, const std::string &, int> ("write_config", &C::write_config, gsi::arg ("file_name"), gsi::arg ("keep_backups", 0),
"@brief Writes configuration to a file\n" "@brief Writes configuration to a file\n"
"@return A value indicating whether the operation was successful\n" "@return A value indicating whether the operation was successful\n"
"\n" "\n"
"If the configuration file cannot be written, \n" "If the configuration file cannot be written, \n"
"is returned but no exception is thrown.\n" "is returned but no exception is thrown.\n"
"\n"
"@param file_name The path to write the config file to.\n"
"@param keep_backups The number of backups to keep (0 for 'no backups').\n"
"\n"
"The 'keep_backups' option was introduced in version 0.30.7.\n"
) + ) +
// TODO: basically this method belongs to Dispatcher (aka MainWindow). // TODO: basically this method belongs to Dispatcher (aka MainWindow).
// There is separate declaration for Dispatcher which we have to synchronize // There is separate declaration for Dispatcher which we have to synchronize

View File

@ -202,9 +202,9 @@ static void clear_config (lay::MainWindow *mw)
mw->dispatcher ()->clear_config (); mw->dispatcher ()->clear_config ();
} }
static bool write_config (lay::MainWindow *mw, const std::string &config_file) static bool write_config (lay::MainWindow *mw, const std::string &config_file, int keep_backups)
{ {
return mw->dispatcher ()->write_config (config_file); return mw->dispatcher ()->write_config (config_file, keep_backups);
} }
static bool read_config (lay::MainWindow *mw, const std::string &config_file) static bool read_config (lay::MainWindow *mw, const std::string &config_file)
@ -348,7 +348,7 @@ Class<lay::MainWindow> decl_MainWindow (QT_EXTERNAL_BASE (QMainWindow) "lay", "M
"\n" "\n"
"This method has been introduced in version 0.27.\n" "This method has been introduced in version 0.27.\n"
) + ) +
method_ext ("write_config", &write_config, gsi::arg ("file_name"), method_ext ("write_config", &write_config, gsi::arg ("file_name"), gsi::arg ("keep_backups", 0),
"@brief Writes configuration to a file\n" "@brief Writes configuration to a file\n"
"This method is provided for using MainWindow without an Application object. " "This method is provided for using MainWindow without an Application object. "
"It's a convience method which is equivalent to 'dispatcher().write_config(...)'. See \\Dispatcher#write_config for details.\n" "It's a convience method which is equivalent to 'dispatcher().write_config(...)'. See \\Dispatcher#write_config for details.\n"

View File

@ -992,6 +992,8 @@ ApplicationBase::exit (int result)
::exit (result); ::exit (result);
} }
const int number_of_config_file_backups = 10;
void void
ApplicationBase::finish () ApplicationBase::finish ()
{ {
@ -1001,7 +1003,7 @@ ApplicationBase::finish ()
if (tl::verbosity () >= 20) { if (tl::verbosity () >= 20) {
tl::info << tl::to_string (QObject::tr ("Updating configuration file ")) << m_config_file_to_write; tl::info << tl::to_string (QObject::tr ("Updating configuration file ")) << m_config_file_to_write;
} }
dispatcher ()->write_config (m_config_file_to_write); dispatcher ()->write_config (m_config_file_to_write, number_of_config_file_backups);
} }
if (! m_config_file_to_delete.empty () && m_config_file_to_delete != m_config_file_to_write) { if (! m_config_file_to_delete.empty () && m_config_file_to_delete != m_config_file_to_write) {
if (tl::verbosity () >= 20) { if (tl::verbosity () >= 20) {
@ -1419,9 +1421,9 @@ ApplicationBase::process_events_impl (QEventLoop::ProcessEventsFlags /*flags*/,
} }
bool bool
ApplicationBase::write_config (const std::string &config_file) ApplicationBase::write_config (const std::string &config_file, int keep_backups)
{ {
return dispatcher () ? dispatcher ()->write_config (config_file) : 0; return dispatcher () ? dispatcher ()->write_config (config_file, keep_backups) : 0;
} }
void void

View File

@ -183,8 +183,11 @@ public:
* *
* If the configuration file cannot be written, false * If the configuration file cannot be written, false
* is returned but no exception is thrown. * is returned but no exception is thrown.
*
* "keep_backups" controls how many backups are kept for
* the configuration file.
*/ */
bool write_config (const std::string &config_file); bool write_config (const std::string &config_file, int keep_backups = 0);
/** /**
* @brief Read the configuration from a file * @brief Read the configuration from a file

View File

@ -71,12 +71,17 @@ Class<lay::Dispatcher> decl_Dispatcher ("lay", "Dispatcher",
"\n" "\n"
"@return The instance\n" "@return The instance\n"
) + ) +
method ("write_config", &lay::Dispatcher::write_config, gsi::arg ("file_name"), method ("write_config", &lay::Dispatcher::write_config, gsi::arg ("file_name"), gsi::arg ("keep_backups", 0),
"@brief Writes configuration to a file\n" "@brief Writes configuration to a file\n"
"@return A value indicating whether the operation was successful\n" "@return A value indicating whether the operation was successful\n"
"\n" "\n"
"If the configuration file cannot be written, false \n" "If the configuration file cannot be written, false \n"
"is returned but no exception is thrown.\n" "is returned but no exception is thrown.\n"
"\n"
"@param file_name The path to write the config file to.\n"
"@param keep_backups The number of backups to keep (0 for 'no backups').\n"
"\n"
"The 'keep_backups' option was introduced in version 0.30.7.\n"
) + ) +
method ("read_config", &lay::Dispatcher::read_config, gsi::arg ("file_name"), method ("read_config", &lay::Dispatcher::read_config, gsi::arg ("file_name"),
"@brief Reads the configuration from a file\n" "@brief Reads the configuration from a file\n"

View File

@ -238,10 +238,10 @@ config_structure (const lay::Dispatcher *plugin)
bool bool
Dispatcher::write_config (const std::string &config_file) Dispatcher::write_config (const std::string &config_file, int keep_backups)
{ {
try { try {
tl::OutputStream os (config_file, tl::OutputStream::OM_Plain); tl::OutputStream os (config_file, tl::OutputStream::OM_Plain, true, keep_backups);
config_structure (this).write (os, *this); config_structure (this).write (os, *this);
return true; return true;
} catch (...) { } catch (...) {

View File

@ -147,9 +147,12 @@ public:
* If the configuration file cannot be written, false * If the configuration file cannot be written, false
* is returned but no exception is thrown. * is returned but no exception is thrown.
* *
* "keep_backups" is the number of backup files kept.
* By default, no backups are kept.
*
* @return false, if an error occurred. * @return false, if an error occurred.
*/ */
bool write_config (const std::string &config_file); bool write_config (const std::string &config_file, int keep_backups = 0);
/** /**
* @brief Read the configuration from a file * @brief Read the configuration from a file