Fix Save writing a .qetz beside an opened .qet: keep the .qet

A project opened from a .qet was saved as a .qetz beside it, with a
notice, and the .qet left as it was: a project kept in git did not stay
a .qet. Save now writes the format the project was opened in; only Save
As changes it (scorpio810, discussion #1512). A .qetz is saved as a
.qetz as before.

The save-beside path goes: the flag set on opening, the .qetz path made
from the .qet's, write()'s switch to it and back on failure, and the
notice and replace question in ProjectView::doSave().

tst_resaveunchanged::qetSavedAsQetzBeside becomes qetSavedAsQet: Save of
an opened .qet writes no .qetz and the .qet holds what a plain save of
it holds (it fails without the fix: a .qetz is written beside).
tst_changedondisk makes its .qetz with Save As, as Save no longer does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ispyisail
2026-10-18 22:56:22 +13:00
parent 8c5a16d50e
commit 89c3979957
6 changed files with 23 additions and 96 deletions
+3 -3
View File
@@ -55,10 +55,10 @@ private slots:
QVERIFY(QFile::exists(QStringLiteral(QET_TEST_BINARY_PATH)));
const QString qet = m_dir.filePath(QStringLiteral("p.qet"));
QVERIFY(QFile::copy(QStringLiteral(QET_EXAMPLES_DIR "/741.qet"), qet));
// a .qet is saved as a .qetz beside it; that .qetz is the project below
const QString out = run(QStringLiteral("qet.log('R ' + qet.save(''));\n"), qet);
QVERIFY2(out.contains(QStringLiteral("R true")), qPrintable(out));
// the .qet saved as a .qetz is the project below
m_project = m_dir.filePath(QStringLiteral("p.qetz"));
const QString out = run(QStringLiteral("qet.log('R ' + qet.save('%1'));\n").arg(m_project), qet);
QVERIFY2(out.contains(QStringLiteral("R true")), qPrintable(out));
QVERIFY(QFile::exists(m_project));
}
+12 -11
View File
@@ -600,10 +600,11 @@ private slots:
QCOMPARE(rowsOf(edited), rowsOf(reopened));
}
// A project read from a .qet and saved where it is, is saved as a .qetz
// beside it, and the .qet is left as it was (stage D1).
// What the .qetz holds is what a plain save of the .qet holds.
void qetSavedAsQetzBeside()
// A project read from a .qet and saved where it is stays a .qet: Save
// keeps the format it was opened in, only Save As changes it (#1512).
// It used to be saved as a .qetz beside the .qet (stage D1). What the
// .qet holds is what a plain save of it holds.
void qetSavedAsQet()
{
#ifndef QET_HAS_SCRIPTING
QSKIP("needs --run: this QElectroTech is built without Qt Qml");
@@ -620,19 +621,19 @@ private slots:
const QString log = runChecked({QStringLiteral("--run"), script, qet});
QVERIFY2(log.contains(QStringLiteral("SAVED true")), qPrintable(log.right(400)));
QCOMPARE(read(qet), before);
const QString qetz = m_dir.filePath(QStringLiteral("beside.qetz"));
QVERIFY2(read(qetz).startsWith("PK\x03\x04"), "no .qetz beside the .qet");
QVERIFY2(!QFile::exists(m_dir.filePath(QStringLiteral("beside.qetz"))), "a .qetz written beside the .qet");
const QByteArray saved = read(qet);
QVERIFY2(saved.startsWith("<project"), "the .qet is no longer XML");
QVERIFY(saved != before); //written: the saved date and path are new
auto without_save_stamps = [](QByteArray xml) {
static const QRegularExpression stamp(QStringLiteral(
"\\s*<property [^>]*name=\"saved(filename|filepath|filenamedir|date|date-us|date-eu|time)\"[^>]*>[^<]*</property>"));
return QString::fromUtf8(xml).remove(stamp);
};
const QString straight = resave(qet);
const QString back = resave(qetz);
QVERIFY(!straight.isEmpty() && !back.isEmpty());
QCOMPARE(without_save_stamps(read(back)), without_save_stamps(read(straight)));
const QString straight = resave(QStringLiteral(QET_EXAMPLES_DIR "/industrial.qet"));
QVERIFY(!straight.isEmpty());
QCOMPARE(without_save_stamps(saved), without_save_stamps(read(straight)));
}
// A title-block value that is a single space is kept through two saves