mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-23 15:34:12 +02:00
Move reading and writing a .qetz out of QETProject
QETZ-DB-FIRST stage 3a. QETProject::openFile() unzipped and joined a .qetz itself and kept what it held beside the document in three members of its own (the entries, each folio's part, the pictures), and writeContainer() split and zipped it. Both now live in their own classes under sources/container: QetzReader reads a .qet or a .qetz and keeps what a .qetz holds for as long as the project is open; QetzWriter writes the document as a .qetz. No behaviour change: the same calls in the same order. This is the seam stage 3b needs, where opening fills the working database straight from project.sqlite instead of rebuilding it from the joined XML. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -173,6 +173,10 @@ set(QET_SRC_FILES
|
||||
${QET_DIR}/sources/container/qetcontainer.h
|
||||
${QET_DIR}/sources/container/qetzip.cpp
|
||||
${QET_DIR}/sources/container/qetzip.h
|
||||
${QET_DIR}/sources/container/qetzreader.cpp
|
||||
${QET_DIR}/sources/container/qetzreader.h
|
||||
${QET_DIR}/sources/container/qetzwriter.cpp
|
||||
${QET_DIR}/sources/container/qetzwriter.h
|
||||
${QET_DIR}/sources/borderproperties.cpp
|
||||
${QET_DIR}/sources/borderproperties.h
|
||||
${QET_DIR}/sources/bordertitleblock.cpp
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright 2006-2026 The QElectroTech Team
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
QElectroTech is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "qetzreader.h"
|
||||
|
||||
#include "qetzip.h"
|
||||
|
||||
/**
|
||||
@brief QetzReader::read
|
||||
Read @p content, the bytes of a .qet or a .qetz, into @p document.
|
||||
For a .qetz, its entries, folio parts, pictures and format are kept.
|
||||
@return false, with @p error set, if it cannot be read
|
||||
*/
|
||||
bool QetzReader::read(const QByteArray &content, QDomDocument *document, QString *error)
|
||||
{
|
||||
m_files.clear();
|
||||
m_folio_parts.clear();
|
||||
m_format = 0;
|
||||
bool read = false;
|
||||
if (QetContainer::isZip(content)) {
|
||||
QList<QetZip::Entry> entries;
|
||||
read = QetZip::fromBytes(content, &entries, error)
|
||||
&& QetContainer::join(entries, document, error, &m_folio_parts,
|
||||
&m_pictures, &m_format);
|
||||
if (read)
|
||||
for (const QetZip::Entry &entry : std::as_const(entries))
|
||||
m_files.insert(entry.name, entry.data);
|
||||
} else {
|
||||
read = QetContainer::readDocument(content, document, error);
|
||||
}
|
||||
if (!read) {
|
||||
m_pictures.clear();
|
||||
m_folio_parts.clear();
|
||||
}
|
||||
return read;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
Copyright 2006-2026 The QElectroTech Team
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
QElectroTech is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef QETZREADER_H
|
||||
#define QETZREADER_H
|
||||
|
||||
#include "qetcontainer.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QDomDocument>
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
/**
|
||||
@brief The QetzReader class
|
||||
Reads the bytes of a project file, a .qet or a .qetz, into its project
|
||||
document, and keeps what a .qetz holds beside that document for as long
|
||||
as the project is open: its entries (a save copies the parts of the
|
||||
folios not built from them), the part each folio was read from, its
|
||||
pictures and its format.
|
||||
*/
|
||||
class QetzReader
|
||||
{
|
||||
public:
|
||||
bool read(const QByteArray &content, QDomDocument *document, QString *error = nullptr);
|
||||
|
||||
/// The format the .qetz says it is; 0 for a .qet
|
||||
int format() const {return m_format;}
|
||||
/// The entries of the .qetz read, by name
|
||||
const QHash<QString, QByteArray> &files() const {return m_files;}
|
||||
QByteArray file(const QString &name) const {return m_files.value(name);}
|
||||
/// The part each folio was read from, in order
|
||||
const QStringList &folioParts() const {return m_folio_parts;}
|
||||
/// The picture in @p file, or an empty array when there is none
|
||||
QByteArray picture(const QString &file) const {return m_pictures.value(file);}
|
||||
|
||||
private:
|
||||
QHash<QString, QByteArray> m_files;
|
||||
QStringList m_folio_parts;
|
||||
QetContainer::Pictures m_pictures;
|
||||
int m_format = 0;
|
||||
};
|
||||
|
||||
#endif // QETZREADER_H
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright 2006-2026 The QElectroTech Team
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
QElectroTech is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "qetzwriter.h"
|
||||
|
||||
#include "../qetversion.h"
|
||||
#include "qetcontainer.h"
|
||||
#include "qetzip.h"
|
||||
|
||||
/**
|
||||
@brief QetzWriter::write
|
||||
Write the project document @p project to @p path as a .qetz: the same
|
||||
document, in parts, zipped (#1440). The file is replaced only once
|
||||
the whole archive is written. @p kept_from: the entries of the .qetz
|
||||
read, whose parts the folios not built are copied from.
|
||||
*/
|
||||
bool QetzWriter::write(const QDomDocument &project, const QString &path, QString *error,
|
||||
const QHash<QString, QByteArray> &kept_from)
|
||||
{
|
||||
QList<QetZip::Entry> entries = QetContainer::split(
|
||||
project,
|
||||
QStringLiteral("QElectroTech %1").arg(QetVersion::currentVersion().toString()),
|
||||
error, kept_from);
|
||||
return !entries.isEmpty() && QetZip::write(path, entries, error);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2006-2026 The QElectroTech Team
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
QElectroTech is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef QETZWRITER_H
|
||||
#define QETZWRITER_H
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QDomDocument>
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
|
||||
/**
|
||||
@brief The QetzWriter namespace
|
||||
Writes a project document as a .qetz file.
|
||||
*/
|
||||
namespace QetzWriter
|
||||
{
|
||||
bool write(const QDomDocument &project, const QString &path, QString *error = nullptr,
|
||||
const QHash<QString, QByteArray> &kept_from = QHash<QString, QByteArray>());
|
||||
}
|
||||
|
||||
#endif // QETZWRITER_H
|
||||
+11
-43
@@ -19,6 +19,7 @@
|
||||
#include "qetproject.h"
|
||||
#include "container/qetcontainer.h"
|
||||
#include "container/qetcontainerdb.h"
|
||||
#include "container/qetzwriter.h"
|
||||
|
||||
#include "ElementsCollection/xmlelementcollection.h"
|
||||
#include "autoNum/assignvariables.h"
|
||||
@@ -294,7 +295,7 @@ QUuid QETProject::uuid() const
|
||||
*/
|
||||
QByteArray QETProject::containerPicture(const QString &file) const
|
||||
{
|
||||
return m_container_pictures.value(file);
|
||||
return m_container.picture(file);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -528,27 +529,10 @@ QETProject::ProjectState QETProject::openFile(QFile *file)
|
||||
QString read_error;
|
||||
//A .qetz: its entries are kept, for a save to copy the parts of the
|
||||
//folios not built (stage D4)
|
||||
m_container_files.clear();
|
||||
m_folio_parts.clear();
|
||||
bool read = false;
|
||||
int container_format = 0;
|
||||
if (QetContainer::isZip(content)) {
|
||||
QList<QetZip::Entry> entries;
|
||||
read = QetZip::fromBytes(content, &entries, &read_error)
|
||||
&& QetContainer::join(entries, &xml_project, &read_error, &m_folio_parts,
|
||||
&m_container_pictures, &container_format);
|
||||
if (read)
|
||||
for (const QetZip::Entry &entry : std::as_const(entries))
|
||||
m_container_files.insert(entry.name, entry.data);
|
||||
} else {
|
||||
read = QetContainer::readDocument(content, &xml_project, &read_error);
|
||||
}
|
||||
if (!read)
|
||||
if (!m_container.read(content, &xml_project, &read_error))
|
||||
{
|
||||
qWarning().noquote() << "Unable to read" << fi.fileName() << ":" << read_error;
|
||||
m_open_error = read_error;
|
||||
m_container_pictures.clear();
|
||||
m_folio_parts.clear();
|
||||
if(opened_here) {
|
||||
file->close();
|
||||
}
|
||||
@@ -581,13 +565,13 @@ QETProject::ProjectState QETProject::openFile(QFile *file)
|
||||
|
||||
//Written by a later QElectroTech that lets this one read it: saving
|
||||
//here would drop what this version does not know
|
||||
m_from_later_version = container_format > QetContainer::Format;
|
||||
m_from_later_version = m_container.format() > QetContainer::Format;
|
||||
if (!fi.isWritable() || m_from_later_version) {
|
||||
setReadOnly(true);
|
||||
}
|
||||
if (m_from_later_version) {
|
||||
qInfo().noquote() << QStringLiteral("Project %1 is of .qetz format %2 (this version writes %3): opened read-only")
|
||||
.arg(fi.fileName()).arg(container_format).arg(QetContainer::Format);
|
||||
.arg(fi.fileName()).arg(m_container.format()).arg(QetContainer::Format);
|
||||
}
|
||||
if(opened_here) {
|
||||
file->close();
|
||||
@@ -2757,22 +2741,6 @@ QString QETProject::openFileFilter()
|
||||
return tr("QElectroTech project (*.qet *.qetz)");
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETProject::writeContainer
|
||||
Write the project document @p project to @p path as a .qetz: the same
|
||||
document, in parts, zipped (#1440). The file is replaced only once
|
||||
the whole archive is written.
|
||||
*/
|
||||
bool QETProject::writeContainer(const QDomDocument &project, const QString &path, QString *error,
|
||||
const QHash<QString, QByteArray> &kept_from)
|
||||
{
|
||||
QList<QetZip::Entry> entries = QetContainer::split(
|
||||
project,
|
||||
QStringLiteral("QElectroTech %1").arg(QetVersion::currentVersion().toString()),
|
||||
error, kept_from);
|
||||
return !entries.isEmpty() && QetZip::write(path, entries, error);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETProject::writeContainerFile
|
||||
Write this project to @p path as a .qetz
|
||||
@@ -2783,8 +2751,8 @@ bool QETProject::writeContainerFile(const QString &path, QString *error)
|
||||
//what building them would write (toXml()); every other folio built
|
||||
QStringList kept;
|
||||
const QDomDocument document = toXml(nullptr, &kept);
|
||||
return writeContainer(document, path, error,
|
||||
kept.isEmpty() ? QHash<QString, QByteArray>() : m_container_files);
|
||||
return QetzWriter::write(document, path, error,
|
||||
kept.isEmpty() ? QHash<QString, QByteArray>() : m_container.files());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3651,10 +3619,10 @@ void QETProject::readProjectXml(QDomDocument &xml_project)
|
||||
for (Diagram *diagram : std::as_const(m_diagrams_list))
|
||||
if (!diagram->isLoaded() && diagram->keptText().isEmpty())
|
||||
m_kept_folios_trusted = false;
|
||||
m_kept_parts_trusted = !m_folio_parts.isEmpty() && unloadedFolioCount() > 0
|
||||
m_kept_parts_trusted = !m_container.folioParts().isEmpty() && unloadedFolioCount() > 0
|
||||
&& m_project_qet_version == QetVersion::currentVersion()
|
||||
&& m_data_base.rowsFromDocument()
|
||||
&& QetContainerDb::currentFormat(m_container_files.value(QStringLiteral("project.sqlite")));
|
||||
&& QetContainerDb::currentFormat(m_container.file(QStringLiteral("project.sqlite")));
|
||||
for (Diagram *diagram : std::as_const(m_diagrams_list))
|
||||
if (!diagram->isLoaded() && diagram->keptPart().isEmpty())
|
||||
m_kept_parts_trusted = false;
|
||||
@@ -3823,8 +3791,8 @@ void QETProject::readDiagramsXml(QDomDocument &xml_project)
|
||||
m_deferring_folios = false;
|
||||
if (!diagram->isLoaded() && !line_starts.isEmpty())
|
||||
diagram->setKeptText(folio_text(diagram_xml_element));
|
||||
if (!diagram->isLoaded() && m_folio_parts.size() == diagram_nodes.length())
|
||||
diagram->setKeptPart(m_folio_parts.at(i));
|
||||
if (!diagram->isLoaded() && m_container.folioParts().size() == diagram_nodes.length())
|
||||
diagram->setKeptPart(m_container.folioParts().at(i));
|
||||
m_data_base.placeFolio(diagram);
|
||||
if(dlgWaiting)
|
||||
dlgWaiting->setDetail(diagram->title());
|
||||
|
||||
+4
-10
@@ -34,6 +34,7 @@
|
||||
#include "diagram.h"
|
||||
#include "autoNum/assignvariables.h"
|
||||
#include "container/qetcontainerdb.h"
|
||||
#include "container/qetzreader.h"
|
||||
#include "projectlock.h"
|
||||
#ifdef BUILD_WITHOUT_KF
|
||||
# include "ui/nokde/kautosavefile.h"
|
||||
@@ -472,9 +473,6 @@ class QETProject : public QObject
|
||||
static bool isContainerPath(const QString &path);
|
||||
static QString openFileFilter();
|
||||
QETResult writeCopyForOlderVersions(const QString &path);
|
||||
static bool writeContainer(const QDomDocument &project, const QString &path,
|
||||
QString *error = nullptr,
|
||||
const QHash<QString, QByteArray> &kept_from = QHash<QString, QByteArray>());
|
||||
bool writeContainerFile(const QString &path, QString *error = nullptr);
|
||||
private:
|
||||
static QUuid derivedUuid(const QByteArray &content);
|
||||
@@ -486,9 +484,9 @@ class QETProject : public QObject
|
||||
static bool m_backup_enabled;
|
||||
/// Something changed since the last backup, see writeBackup()
|
||||
bool m_backup_needed = true;
|
||||
/// The pictures of the .qetz this project was opened from, see
|
||||
/// containerPicture()
|
||||
QHash<QString, QByteArray> m_container_pictures;
|
||||
/// What the file this project was opened from holds beside its
|
||||
/// document: a .qetz's entries, folio parts and pictures
|
||||
QetzReader m_container;
|
||||
/// File path this project is saved to
|
||||
QString m_file_path;
|
||||
/// Current state of the project
|
||||
@@ -562,10 +560,6 @@ class QETProject : public QObject
|
||||
/// Saving a .qetz may copy the part of a folio not built
|
||||
/// (toXml(), stage D4)
|
||||
bool m_kept_parts_trusted = false;
|
||||
/// The entries of the .qetz opened, and the part each folio
|
||||
/// was read from, in order
|
||||
QHash<QString, QByteArray> m_container_files;
|
||||
QStringList m_folio_parts;
|
||||
bool m_kept_folios_stale = false;
|
||||
/// Something was edited since the project was opened: a table
|
||||
/// filled from the database may have changed
|
||||
|
||||
Reference in New Issue
Block a user