mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-19 20:44:16 +02:00
Merge pull request #1543 from ispyisail/fix/save-keeps-qet
Linux build and tests / Build and test (Qt 6, Debug) (push) Failing after 1m54s
Linux build and tests / Build and test (Qt 6, Debug) (push) Failing after 1m54s
Fix Save writing a .qetz beside an opened .qet: keep the .qet
This commit is contained in:
@@ -313,7 +313,7 @@ ProjectLock::Result ProjectLock::acquire(const QString &project_path, bool take_
|
||||
|
||||
/**
|
||||
@brief ProjectLock::moveTo
|
||||
The project is now @p project_path (Save As, .qet saved as .qetz): take
|
||||
The project is now @p project_path (Save As): take
|
||||
the new lock, then let the old one go. Nothing changes when the new one
|
||||
cannot be had.
|
||||
@return true when the lock is now on @p project_path
|
||||
|
||||
+1
-27
@@ -795,7 +795,7 @@ QETResult ProjectView::writeProject(bool *cancelled)
|
||||
return(m_project -> write());
|
||||
}
|
||||
|
||||
const QString name = QFileInfo(m_project -> writeTarget()).fileName();
|
||||
const QString name = QFileInfo(m_project -> filePath()).fileName();
|
||||
QMessageBox box(QMessageBox::Warning,
|
||||
tr("File changed on disk", "message box title"),
|
||||
tr("Someone else changed %1 on disk at %2 since you opened it.\n\n"
|
||||
@@ -838,32 +838,6 @@ QETResult ProjectView::doSave()
|
||||
return(saveAs());
|
||||
}
|
||||
|
||||
//A project read from a .qet is saved as a .qetz beside it: say so,
|
||||
//and ask before replacing a .qetz already there
|
||||
if (m_project->savesBesideOpenedFile()) {
|
||||
const QString beside = m_project->besideContainerPath();
|
||||
if (!refuseIfLockedByOther(beside)) return(QETResult());
|
||||
const QString message = tr("This project was opened from %1. It is saved as %2, "
|
||||
"beside it, in the zipped project format; %1 stays as "
|
||||
"it is.\n\nTo write a file for a version of "
|
||||
"QElectroTech that cannot open %2, use File > Save a "
|
||||
"copy for an older QElectroTech.")
|
||||
.arg(QFileInfo(m_project->filePath()).fileName(), QFileInfo(beside).fileName());
|
||||
if (QFileInfo::exists(beside)) {
|
||||
if (QET::QetMessageBox::question(
|
||||
this, tr("Save as a zipped project", "message box title"),
|
||||
message + QStringLiteral("\n\n")
|
||||
+ tr("%1 already exists. Replace it?").arg(QFileInfo(beside).fileName()),
|
||||
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel)
|
||||
!= QMessageBox::Yes) {
|
||||
return(QETResult());
|
||||
}
|
||||
} else {
|
||||
QET::QetMessageBox::information(
|
||||
this, tr("Save as a zipped project", "message box title"), message);
|
||||
}
|
||||
}
|
||||
|
||||
// write to file
|
||||
bool cancelled = false;
|
||||
QETResult result = writeProject(&cancelled);
|
||||
|
||||
+6
-46
@@ -197,8 +197,6 @@ QETProject::QETProject(KAutoSaveFile *backup, QObject *parent) :
|
||||
}
|
||||
//Set the real path, instead of the path of the backup.
|
||||
setFilePath(backup->managedFile().path());
|
||||
//A project read from a .qet is saved as a .qetz beside it
|
||||
m_opened_from_qet = !isContainerPath(m_file_path);
|
||||
delete backup;
|
||||
|
||||
//Set the project to read only mode if the file it.
|
||||
@@ -511,8 +509,6 @@ QETProject::ProjectState QETProject::openFile(QFile *file)
|
||||
//from a .qet only, a .qetz is a zip of parts
|
||||
if (!content.startsWith("PK\x03\x04"))
|
||||
m_opened_content = content;
|
||||
//A project read from a .qet is saved as a .qetz beside it
|
||||
m_opened_from_qet = !content.startsWith("PK\x03\x04");
|
||||
QDomDocument xml_project;
|
||||
// PreserveSpacingOnlyNodes: without it, a text node that is entirely
|
||||
// whitespace -- e.g. a title-block custom variable deliberately set to
|
||||
@@ -1201,8 +1197,6 @@ void QETProject::setFilePath(const QString &filepath)
|
||||
}
|
||||
m_next_backup_slot = 0;
|
||||
m_file_path = filepath;
|
||||
//A path chosen is saved to as it is
|
||||
m_opened_from_qet = false;
|
||||
|
||||
QFileInfo fi(m_file_path);
|
||||
if (fi.isWritable()) {
|
||||
@@ -2774,20 +2768,6 @@ bool QETProject::writeContainerFile(const QString &path, QString *error)
|
||||
kept.isEmpty() ? QHash<QString, QByteArray>() : m_container_files);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETProject::besideContainerPath
|
||||
@return the .qetz a project read from a .qet is saved to: the same
|
||||
name, beside it
|
||||
*/
|
||||
QString QETProject::besideContainerPath() const
|
||||
{
|
||||
QString path = m_file_path;
|
||||
if (path.endsWith(QStringLiteral(".qet"), Qt::CaseInsensitive)) {
|
||||
path.chop(4);
|
||||
}
|
||||
return path + QStringLiteral(".qetz");
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETProject::writeCopyForOlderVersions
|
||||
Write this project as a .qet at @p path, which a QElectroTech that
|
||||
@@ -2817,16 +2797,6 @@ void QETProject::rememberDiskState()
|
||||
m_disk_mtime = info.exists() ? info.lastModified() : QDateTime();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETProject::writeTarget
|
||||
@return the file write() writes to: the .qetz beside a project read
|
||||
from a .qet, else the project's own file
|
||||
*/
|
||||
QString QETProject::writeTarget() const
|
||||
{
|
||||
return m_opened_from_qet ? besideContainerPath() : m_file_path;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETProject::changedOnDisk
|
||||
@param when set to the modification time of the file now on disk
|
||||
@@ -2837,7 +2807,7 @@ QString QETProject::writeTarget() const
|
||||
*/
|
||||
bool QETProject::changedOnDisk(QDateTime *when) const
|
||||
{
|
||||
const QString target = writeTarget();
|
||||
const QString target = m_file_path;
|
||||
if (target.isEmpty() || target != m_disk_path || m_disk_size < 0)
|
||||
return false;
|
||||
const QFileInfo info(target);
|
||||
@@ -2898,20 +2868,10 @@ QETResult QETProject::write(bool overwrite_changed)
|
||||
if (!m_locked_out_path.isEmpty() && m_locked_out_path == m_file_path)
|
||||
return(tr("%1 was opened read-only because someone else has it open. Use Save As to keep your changes in another file.").arg(m_file_path));
|
||||
|
||||
//A project read from a .qet is saved as a .qetz beside it; the
|
||||
//.qet stays as it was (stage D1). If the .qetz cannot be written
|
||||
//(a read-only folder), the project stays the .qet it was.
|
||||
const QString opened_qet = m_opened_from_qet ? m_file_path : QString();
|
||||
if (m_opened_from_qet) {
|
||||
setFilePath(besideContainerPath());
|
||||
}
|
||||
const auto failed = [this, &opened_qet](const QString &error) {
|
||||
const QString message = tr("Cannot save %1: %2").arg(m_file_path, error);
|
||||
if (!opened_qet.isEmpty()) {
|
||||
setFilePath(opened_qet);
|
||||
m_opened_from_qet = true;
|
||||
}
|
||||
return(QETResult(message));
|
||||
//Saved in the format it was opened in: a .qet stays a .qet, and
|
||||
//only Save As changes it (#1512)
|
||||
const auto failed = [this](const QString &error) {
|
||||
return(QETResult(tr("Cannot save %1: %2").arg(m_file_path, error)));
|
||||
};
|
||||
|
||||
// If the project was opened read-only, only refuse when the target
|
||||
@@ -2985,7 +2945,7 @@ QETResult QETProject::write(bool overwrite_changed)
|
||||
if (isReadOnly())
|
||||
setReadOnly(false);
|
||||
|
||||
//The file may be a new one (Save As, a .qet saved as .qetz): the lock
|
||||
//The file may be a new one (Save As): the lock
|
||||
//follows it. A project that had none (new, or opened read-only for
|
||||
//another's lock) takes one now. Never stops the save: it is done.
|
||||
if (ProjectLock::mayTake()) {
|
||||
|
||||
@@ -337,7 +337,6 @@ class QETProject : public QObject
|
||||
static QString spliceKeptFolios(QString text, const QHash<int, QByteArray> &kept_folios);
|
||||
bool close();
|
||||
QETResult write(bool overwrite_changed = false);
|
||||
QString writeTarget() const;
|
||||
void rememberDiskState();
|
||||
bool changedOnDisk(QDateTime *when = nullptr) const;
|
||||
bool isReadOnly() const;
|
||||
@@ -470,11 +469,6 @@ class QETProject : public QObject
|
||||
public:
|
||||
static bool isContainerPath(const QString &path);
|
||||
static QString openFileFilter();
|
||||
/// Saving writes a .qetz: one read from a .qet is saved as
|
||||
/// a .qetz beside it, the .qet left as it is
|
||||
/// (stage D1)
|
||||
bool savesBesideOpenedFile() const {return m_opened_from_qet;}
|
||||
QString besideContainerPath() const;
|
||||
QETResult writeCopyForOlderVersions(const QString &path);
|
||||
static bool writeContainer(const QDomDocument &project, const QString &path,
|
||||
QString *error = nullptr,
|
||||
@@ -571,8 +565,6 @@ class QETProject : public QObject
|
||||
/// database rows came from it, and nothing project-wide that
|
||||
/// a folio's saved items depend on has changed since
|
||||
bool m_kept_folios_trusted = false;
|
||||
/// Read from a .qet whose path nobody chose since: saved beside it
|
||||
bool m_opened_from_qet = false;
|
||||
/// The file the saved date and path were set for, and the undo
|
||||
/// index then: an unchanged project keeps them (stampSaved())
|
||||
QString m_stamped_path;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -732,10 +732,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");
|
||||
@@ -752,19 +753,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
|
||||
|
||||
Reference in New Issue
Block a user