Keep the previous versions of a project when saving it

Saving replaced the project file with nothing kept of what it was: one
bad save -- a fault in QElectroTech, a full disk, a wrong edit saved by
mistake -- and the last good version was gone. AutoCAD keeps a .bak on
every save, KiCad several backups.

Before a project is saved over, the file as it was is now copied to a
folder beside it, "<name>-backups", named by the time that version was
saved ("industrial 2026-10-16 08-30-12.qetz"); only the newest are kept,
5 by default (Settings > General > Projects, 0 for none). A copy is
never a move, so a save that fails leaves the file in place; a copy that
fails only warns, the save goes on. The same bytes as the newest version
kept are not kept twice.

The prompt on opening ("Create a backup copy?"), which writes one dated
copy beside the project and never removes any, is left as it is.

New tst_previousversions (newest kept, same bytes once, same second,
nothing for a new file or a count of 0, a failed copy said); it fails
with the oldest never removed. Checked with the program: two scripted
saves of a .qetz leave the original and the first save in
industrial-backups, the project holds the second. ctest 107/107.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ispyisail
2026-10-16 09:00:07 +13:00
parent c4b5cf2f11
commit e8201abb8a
8 changed files with 337 additions and 0 deletions
@@ -26,6 +26,7 @@
#include "../../cablelist/cabletypelist.h"
#include "../../utils/qetsettings.h"
#include "../../utils/qetutils.h"
#include "../../utils/previousversions.h"
#include "../../qetmessagebox.h"
#include "../../textgrid.h"
#include "../../wiringrules.h"
@@ -190,6 +191,7 @@ GeneralConfigurationPage::GeneralConfigurationPage(QWidget *parent) :
ui->m_use_folio_label->setChecked(settings.value("genericpanel/folio", true).toBool());
ui->m_border_0->setChecked(settings.value("border-columns_0", false).toBool());
ui->m_autosave_sb->setValue(settings.value("diagrameditor/autosave-interval", 0).toInt());
ui->m_previous_versions_sb->setValue(PreviousVersions::count());
QString fontInfos = settings.value("diagramitemfont", "Liberation Sans").toString() + " " +
settings.value("diagramitemsize", "9").toString() + " (" +
@@ -417,6 +419,7 @@ void GeneralConfigurationPage::applyConf()
}
}
settings.setValue("diagrameditor/autosave-interval", ui->m_autosave_sb->value());
PreviousVersions::setCount(ui->m_previous_versions_sb->value());
settings.setValue("diagrameditor/grid_display_startup", ui->grid_startup_cb->isChecked());
settings.setValue("diagrameditor/guides_display_startup", ui->guides_startup_cb->isChecked());
@@ -365,6 +365,29 @@
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="m_previous_versions_label">
<property name="text">
<string>Previous versions kept when saving a project</string>
</property>
<property name="toolTip">
<string>Before a project is saved, the file as it was is copied to a folder beside it, named after the project with "-backups". Only the newest are kept.</string>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QSpinBox" name="m_previous_versions_sb">
<property name="toolTip">
<string>Before a project is saved, the file as it was is copied to a folder beside it, named after the project with "-backups". Only the newest are kept.</string>
</property>
<property name="specialValueText">
<string>None</string>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item row="8" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -1534,6 +1557,7 @@
<tabstop>m_use_folio_label</tabstop>
<tabstop>m_border_0</tabstop>
<tabstop>m_autosave_sb</tabstop>
<tabstop>m_previous_versions_sb</tabstop>
<tabstop>m_common_elmt_path_cb</tabstop>
<tabstop>m_custom_elmt_path_cb</tabstop>
<tabstop>m_custom_tbt_path_cb</tabstop>