Merge master into fix/joined-wire-uuid

The conflict was tests/qttest/CMakeLists.txt, where #1520 added
tst_savedstamps at the place this branch adds tst_joinedwireuuid. Both
are kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ispyisail
2026-10-18 20:50:24 +13:00
13 changed files with 545 additions and 113 deletions
+93 -51
View File
@@ -847,13 +847,15 @@ bool projectDataBase::populateFromDocument(const QDomDocument &document, QString
}
}
query.prepare(QStringLiteral("INSERT INTO link (element_uuid, linked_uuid, group_index) "
"VALUES (:element_uuid, :linked_uuid, :group_index)"));
query.prepare(QStringLiteral("INSERT INTO link (element_uuid, linked_uuid, group_index, ord) "
"VALUES (:element_uuid, :linked_uuid, :group_index, :ord)"));
for (const DocumentElement &element : std::as_const(elements)) {
int ord = 0;
for (const auto &link : element.links) {
query.bindValue(QStringLiteral(":element_uuid"), element.uuid);
query.bindValue(QStringLiteral(":linked_uuid"), link.first);
query.bindValue(QStringLiteral(":group_index"), link.second >= 0 ? QVariant(link.second) : QVariant());
query.bindValue(QStringLiteral(":ord"), ord++);
if (!query.exec()) {
qDebug() << "projectDataBase::populateFromDocument link insert error : " << query.lastError();
}
@@ -1092,7 +1094,7 @@ QList<QUuid> projectDataBase::linkedSymbols(const QUuid &element) const
{
QList<QUuid> linked;
QSqlQuery query(m_data_base);
query.prepare(QStringLiteral("SELECT linked_uuid FROM link WHERE element_uuid = :uuid ORDER BY rowid"));
query.prepare(QStringLiteral("SELECT linked_uuid FROM link WHERE element_uuid = :uuid ORDER BY ord, rowid"));
query.bindValue(QStringLiteral(":uuid"), element.toString());
if (query.exec()) {
while (query.next())
@@ -2602,12 +2604,14 @@ bool projectDataBase::createDataBase()
//Create the link table: one row per element and element it is
//linked to -- a coil and its contacts, a pair of folio reports --
//from each side, with the contact group the element saved for it.
//from each side, with the contact group the element saved for it,
//and its place (ord) in the order the element saves its links.
const QString link_table(QStringLiteral(
"CREATE TABLE link ("
"element_uuid VARCHAR(50) NOT NULL, "
"linked_uuid VARCHAR(50) NOT NULL, "
"group_index INTEGER, "
"ord INTEGER NOT NULL DEFAULT 0, "
"PRIMARY KEY (element_uuid, linked_uuid), "
"FOREIGN KEY (element_uuid) REFERENCES element (uuid))"));
if (!query_.exec(link_table)) {
@@ -3868,10 +3872,11 @@ QString projectDataBase::prefillReport() const
void projectDataBase::populateLinkTable()
{
m_dirty_link_elements.clear();
const QSet<QUuid> waiting = waitingSymbols();
QSqlQuery query(m_data_base);
query.exec(QStringLiteral("DELETE FROM link"));
query.prepare(QStringLiteral("INSERT INTO link (element_uuid, linked_uuid, group_index) "
"VALUES (:element_uuid, :linked_uuid, :group_index)"));
query.prepare(QStringLiteral("INSERT INTO link (element_uuid, linked_uuid, group_index, ord) "
"VALUES (:element_uuid, :linked_uuid, :group_index, :ord)"));
for (const auto &diagram : m_project->folios())
{
@@ -3885,23 +3890,7 @@ void projectDataBase::populateLinkTable()
}
const ElementProvider ep(diagram);
for (const auto &elmt : ep.find(allElementTypes()))
{
QList<std::pair<QString, int>> rows;
for (Element *linked : elmt->linkedElements())
rows.append({linked->uuid().toString(), elmt->groupIndexForElement(linked)});
//Partners on a folio not built, which it will be linked to
for (const auto &waiting : elmt->waitingLinks())
rows.append({waiting.first.toString(), waiting.second});
for (const auto &row : std::as_const(rows))
{
query.bindValue(QStringLiteral(":element_uuid"), elmt->uuid().toString());
query.bindValue(QStringLiteral(":linked_uuid"), row.first);
query.bindValue(QStringLiteral(":group_index"), row.second >= 0 ? QVariant(row.second) : QVariant());
if (!query.exec()) {
qDebug() << "projectDataBase::populateLinkTable insert error : " << query.lastError();
}
}
}
insertLinkRows(query, elmt, waiting);
}
}
@@ -3927,6 +3916,83 @@ void projectDataBase::queueLinks(Element *element)
}
}
/**
@brief projectDataBase::linkRowMismatches
A test and debugging aid (QET_CHECK_LINK_ROWS): the placed
symbols whose link rows are not the links they save, in order
(Element::linksToSave(), insertLinkRows())
@return one entry per such symbol: its uuid
*/
QStringList projectDataBase::linkRowMismatches()
{
flushLinks();
const QSet<QUuid> waiting = waitingSymbols();
QStringList mismatches;
QSqlQuery query(m_data_base);
query.prepare(QStringLiteral("SELECT linked_uuid, group_index FROM link "
"WHERE element_uuid = :uuid ORDER BY ord, rowid"));
for (auto it = m_placed_elements.cbegin() ; it != m_placed_elements.cend() ; ++it)
{
Element *element = it.value();
if (!element) {
continue;
}
QList<std::pair<QString, int>> expected;
for (const Element::SavedLink &link : element->linksToSave(waiting))
if (!link.built || m_placed_elements.contains(link.uuid, link.built))
expected.append({link.uuid.toString(), link.group_index});
QList<std::pair<QString, int>> rows;
query.bindValue(QStringLiteral(":uuid"), element->uuid().toString());
if (query.exec())
while (query.next())
rows.append({query.value(0).toString(),
query.value(1).isNull() ? -1 : query.value(1).toInt()});
if (rows != expected) {
mismatches << element->uuid().toString();
}
}
return mismatches;
}
/**
@brief projectDataBase::waitingSymbols
@return the symbols on folios not built yet (lazy folios): partners a
symbol keeps its saved links to until they are built
*/
QSet<QUuid> projectDataBase::waitingSymbols() const
{
return m_project && m_project->unloadedFolioCount() ? m_project->symbolsOnUnbuiltFolios()
: QSet<QUuid>();
}
/**
@brief projectDataBase::insertLinkRows
Write @p element's link rows with @p insert (prepared with :element_uuid,
:linked_uuid, :group_index and :ord): its partners as it saves them
(Element::linksToSave()), in that order, so the rows and the file say
the same: @p waiting is the symbols on folios not built, as a save
takes them (waitingSymbols()). A built partner the project no longer has (on a removed
folio, linked still for the undo) gets no row.
*/
void projectDataBase::insertLinkRows(QSqlQuery &insert, Element *element,
const QSet<QUuid> &waiting)
{
int ord = 0;
for (const Element::SavedLink &link : element->linksToSave(waiting))
{
if (link.built && !m_placed_elements.contains(link.uuid, link.built)) {
continue;
}
insert.bindValue(QStringLiteral(":element_uuid"), element->uuid().toString());
insert.bindValue(QStringLiteral(":linked_uuid"), link.uuid.toString());
insert.bindValue(QStringLiteral(":group_index"), link.group_index >= 0 ? QVariant(link.group_index) : QVariant());
insert.bindValue(QStringLiteral(":ord"), ord++);
if (!insert.exec()) {
qDebug() << "projectDataBase::insertLinkRows insert error : " << insert.lastError();
}
}
}
/**
@brief projectDataBase::flushLinks
Write the link rows of every element queued by linksChanged()
@@ -3939,12 +4005,13 @@ void projectDataBase::flushLinks()
const auto dirty = m_dirty_link_elements;
m_dirty_link_elements.clear();
const QSet<QUuid> waiting = waitingSymbols();
const bool own_transaction = m_data_base.transaction();
QSqlQuery remove(m_data_base);
remove.prepare(QStringLiteral("DELETE FROM link WHERE element_uuid = :uuid"));
QSqlQuery insert(m_data_base);
insert.prepare(QStringLiteral("INSERT INTO link (element_uuid, linked_uuid, group_index) "
"VALUES (:element_uuid, :linked_uuid, :group_index)"));
insert.prepare(QStringLiteral("INSERT INTO link (element_uuid, linked_uuid, group_index, ord) "
"VALUES (:element_uuid, :linked_uuid, :group_index, :ord)"));
for (const QPointer<Element> &element : dirty)
{
if (!element) {
@@ -3960,32 +4027,7 @@ void projectDataBase::flushLinks()
if (!m_placed_elements.contains(element->uuid(), element)) {
continue;
}
for (Element *linked : element->linkedElements())
{
//A symbol on a removed folio stays linked, for the undo,
//but the project no longer has it
if (!m_placed_elements.contains(linked->uuid(), linked)) {
continue;
}
const int group = element->groupIndexForElement(linked);
insert.bindValue(QStringLiteral(":element_uuid"), element->uuid().toString());
insert.bindValue(QStringLiteral(":linked_uuid"), linked->uuid().toString());
insert.bindValue(QStringLiteral(":group_index"), group >= 0 ? QVariant(group) : QVariant());
if (!insert.exec()) {
qDebug() << "projectDataBase::flushLinks insert error : " << insert.lastError();
}
}
//Partners on a folio not built (lazy folios), which it will
//be linked to once that folio is
for (const auto &waiting : element->waitingLinks())
{
insert.bindValue(QStringLiteral(":element_uuid"), element->uuid().toString());
insert.bindValue(QStringLiteral(":linked_uuid"), waiting.first.toString());
insert.bindValue(QStringLiteral(":group_index"), waiting.second >= 0 ? QVariant(waiting.second) : QVariant());
if (!insert.exec()) {
qDebug() << "projectDataBase::flushLinks insert error : " << insert.lastError();
}
}
insertLinkRows(insert, element, waiting);
}
if (own_transaction) {
m_data_base.commit();
+3
View File
@@ -154,6 +154,7 @@ class projectDataBase : public QObject
void conductorPropertiesStored(Conductor *conductor, const ConductorProperties &properties);
void conductorUuidChanged(Conductor *conductor, const QUuid &old_uuid);
QStringList conductorPropertiesMismatches() const;
QStringList linkRowMismatches();
//Fill the three stores from a project's document before its
//folios are built, then, once
@@ -253,6 +254,8 @@ class projectDataBase : public QObject
void populateConductorTable();
void populateLinkTable();
void flushLinks();
void insertLinkRows(QSqlQuery &insert, Element *element, const QSet<QUuid> &waiting);
QSet<QUuid> waitingSymbols() const;
void populateDrawingItemTables();
bool populateFromDocument(const QDomDocument &document, QString *why = nullptr);
bool writeDrawingItem(QObject *object);
+17
View File
@@ -2342,6 +2342,23 @@ bool Diagram::fromXml(QDomElement &document,
<< "wire end(s) on a terminal that moved since the project was saved,"
<< "matched to it by place";
}
//A copy of a symbol sharing its uuid with another (older versions'
//copies, F100) gets its own, now that its wires are connected to
//it: wires and links then name one symbol each
//(QETProject::renewedSharedUuid(), only while the project opens)
if (consider_informations && m_project) {
const int folio_index = m_project->folioIndex(this);
QHash<QUuid, int> ordinal;
for (Element *element : std::as_const(added_elements)) {
const QUuid shared = element->uuid();
const QUuid renewed = m_project->renewedSharedUuid(folio_index, ordinal[shared]++,
shared, uuid());
if (!renewed.isNull()) {
element->setUuid(renewed);
}
}
}
if (consider_informations && !m_wires_not_reconnected.isEmpty()) {
qWarning().noquote() << "Diagram::fromXml():"
<< m_wires_not_reconnected.size()
+43 -25
View File
@@ -1437,32 +1437,11 @@ QDomElement Element::toXml(
element.appendChild(inputs);
//if this element is linked to other elements,
//save the uuid of each other elements
//A partner on a folio not built yet (lazy folios), which this
//symbol will be linked to, is saved too, in the order the symbol was
//saved with: saving needs no partner built (stage D5a)
//save the uuid of each other elements (linksToSave())
QList<std::pair<QUuid, int>> links;
if (keepsSavedLinks() && diagram() && diagram()->project()) {
const QSet<QUuid> waiting = diagram()->project()->waitingLinkTargets();
QSet<Element *> written;
for (const auto &link_info : std::as_const(tmp_uuids_link)) {
Element *linked = nullptr;
for (Element *elmt : std::as_const(connected_elements))
if (elmt->uuid() == link_info.uuid && !written.contains(elmt)) { linked = elmt; break; }
if (linked) {
written.insert(linked);
links.append({linked->uuid(), m_group_index_map.value(linked, -1)});
} else if (waiting.contains(link_info.uuid)) {
links.append({link_info.uuid, link_info.group_index});
}
}
for (Element *elmt : std::as_const(connected_elements))
if (!written.contains(elmt))
links.append({elmt->uuid(), m_group_index_map.value(elmt, -1)});
} else {
for (Element *elmt : std::as_const(connected_elements))
links.append({elmt->uuid(), m_group_index_map.value(elmt, -1)});
}
for (const SavedLink &link : linksToSave(diagram() && diagram()->project()
? diagram()->project()->waitingLinkTargets() : QSet<QUuid>()))
links.append({link.uuid, link.group_index});
if (!links.isEmpty()) {
QDomElement links_uuids = document.createElement(QStringLiteral("links_uuids"));
for (const auto &link : std::as_const(links)) {
@@ -1869,6 +1848,45 @@ void Element::initLink(QETProject *prj)
}
}
/**
@brief Element::linksToSave
The partners this symbol saves, in the order it saves them: the order
it was saved with (tmp_uuids_link), then partners linked since. A
partner on a folio not built yet (lazy folios), which this symbol will
be linked to, is in the list too: saving needs no partner built (stage
D5a). toXml() writes this list, and the project database's link rows
are written from it, so the two are the same (QETZ-DB-FIRST stage 2a).
@param waiting the symbols on folios not built: a saved partner among
them is kept (QETProject::symbolsOnUnbuiltFolios())
@return each partner's uuid, its contact group (-1 if none), and the
partner itself when it is built (nullptr for one waiting)
*/
QList<Element::SavedLink> Element::linksToSave(const QSet<QUuid> &waiting) const
{
QList<SavedLink> links;
if (keepsSavedLinks() && diagram() && diagram()->project()) {
QSet<Element *> written;
for (const auto &link_info : std::as_const(tmp_uuids_link)) {
Element *linked = nullptr;
for (Element *elmt : std::as_const(connected_elements))
if (elmt->uuid() == link_info.uuid && !written.contains(elmt)) { linked = elmt; break; }
if (linked) {
written.insert(linked);
links.append({linked->uuid(), m_group_index_map.value(linked, -1), linked});
} else if (waiting.contains(link_info.uuid)) {
links.append({link_info.uuid, link_info.group_index, nullptr});
}
}
for (Element *elmt : std::as_const(connected_elements))
if (!written.contains(elmt))
links.append({elmt->uuid(), m_group_index_map.value(elmt, -1), elmt});
} else {
for (Element *elmt : std::as_const(connected_elements))
links.append({elmt->uuid(), m_group_index_map.value(elmt, -1), elmt});
}
return links;
}
/**
@brief Element::pendingLinks
@return the uuids of the partners this symbol was saved linked to and
+7
View File
@@ -227,6 +227,13 @@ class Element : public QetGraphicsItem
virtual void unlinkElement(Element *) {}
virtual void initLink(QETProject *);
QSet<QUuid> pendingLinks() const;
/// A partner as the symbol saves it (linksToSave())
struct SavedLink {
QUuid uuid;
int group_index = -1;
Element *built = nullptr; ///< nullptr: on a folio not built yet
};
QList<SavedLink> linksToSave(const QSet<QUuid> &waiting) const;
bool keepsSavedLinks() const {return !tmp_uuids_link.isEmpty();}
QList<std::pair<QUuid, int>> waitingLinks() const;
/**
+118 -24
View File
@@ -299,6 +299,27 @@ QByteArray QETProject::containerPicture(const QString &file) const
return m_container_pictures.value(file);
}
/**
@brief QETProject::renewedSharedUuid
While the project opens: the uuid of the @p ordinal -th symbol carrying
@p uuid on the folio at @p folio_index (in the file's order), when
other symbols of the project carry the same uuid and this copy is not
the one keeping it (readDiagramsXml()). Derived from the uuid and the
folio's uuid, so the same file gives the same uuid on every open.
@return a null uuid when this symbol keeps its uuid
*/
QUuid QETProject::renewedSharedUuid(int folio_index, int ordinal, const QUuid &uuid,
const QUuid &folio_uuid)
{
const auto keeper = m_shared_uuid_keepers.constFind(uuid);
if (keeper == m_shared_uuid_keepers.constEnd()
|| (keeper->first == folio_index && keeper->second == ordinal)) {
return QUuid();
}
return derivedItemUuid(QStringLiteral("element-copy"),
uuid.toString() + QLatin1Char('\n') + folio_uuid.toString());
}
/**
@brief QETProject::derivedItemUuid
A uuid for an item of this project that was saved without one, the same
@@ -474,6 +495,8 @@ QETProject::ProjectState QETProject::openFile(QFile *file)
}
QFileInfo fi(*file);
setFilePath(fi.absoluteFilePath());
//Saved again unchanged, the file keeps its saved date and path
m_stamped_path = m_file_path;
//Extract the content of the xml. The raw bytes are kept : a project
//file without a persisted uuid derives its uuid from them.
@@ -1161,16 +1184,8 @@ void QETProject::setFilePath(const QString &filepath)
setReadOnly(false);
}
//title block variables should be updated after file save as dialog is confirmed, before file is saved.
m_project_properties.addValue("saveddate", QLocale::system().toString(QDate::currentDate(), QLocale::ShortFormat));
m_project_properties.addValue("saveddate-eu", QDate::currentDate().toString("dd-MM-yyyy"));
m_project_properties.addValue("saveddate-us", QDate::currentDate().toString("yyyy-MM-dd"));
m_project_properties.addValue("savedtime", QDateTime::currentDateTime().toString("HH:mm"));
m_project_properties.addValue("savedfilename", QFileInfo(filePath()).completeBaseName());
m_project_properties.addValue("savedfilepath", filePath());
//The saved date, time and path of the title block are set by
//write(), when the project is saved (stampSaved())
emit projectFilePathChanged(this, m_file_path);
emit projectInformationsChanged(this);
updateDiagramsFolioData();
@@ -2636,6 +2651,16 @@ QDomDocument QETProject::toXml(QHash<int, QByteArray> *kept_folios, QStringList
// Write the elements collection.
project_root.appendChild(m_elements_collection->root().cloneNode(true));
//QET_CHECK_LINK_ROWS=1: say whether the project database's link rows
//are the links each placed symbol saves, in its order, once the
//folios are written. Builds nothing (lazy folios stay as they are):
//a test and debugging aid; it changes nothing.
if (qEnvironmentVariableIntValue("QET_CHECK_LINK_ROWS") == 1) {
const QStringList links = m_data_base.linkRowMismatches();
qWarning().noquote() << "link rows:" << links.size() << "differ"
<< links.mid(0, 5).join(QStringLiteral(", "));
}
m_waiting_link_targets.clear();
return(xml_doc);
}
@@ -2801,6 +2826,33 @@ bool QETProject::changedOnDisk(QDateTime *when) const
return true;
}
/**
@brief QETProject::stampSaved
Set the title block variables of the save (saveddate, saveddate-eu,
saveddate-us, savedtime, savedfilename, savedfilepath) to now and to
the file being written, when there is something new to save: the
project changed since it was opened or last saved, or it is written to
another file. Otherwise they keep what the file holds, so saving an
unchanged project gives an identical file (F124).
@return true if they were set
*/
bool QETProject::stampSaved()
{
const bool changed = m_modified || m_undo_stack->index() != m_stamped_undo_index;
if (!changed && m_file_path == m_stamped_path) {
return false;
}
m_project_properties.addValue("saveddate", QLocale::system().toString(QDate::currentDate(), QLocale::ShortFormat));
m_project_properties.addValue("saveddate-eu", QDate::currentDate().toString("dd-MM-yyyy"));
m_project_properties.addValue("saveddate-us", QDate::currentDate().toString("yyyy-MM-dd"));
m_project_properties.addValue("savedtime", QDateTime::currentDateTime().toString("HH:mm"));
m_project_properties.addValue("savedfilename", QFileInfo(filePath()).completeBaseName());
m_project_properties.addValue("savedfilepath", filePath());
emit projectInformationsChanged(this);
updateDiagramsFolioData();
return true;
}
/**
@brief QETProject::write
Save the project in a file.
@@ -2868,13 +2920,28 @@ QETResult QETProject::write(bool overwrite_changed)
if (!PreviousVersions::keep(m_file_path, PreviousVersions::count(), &backup_error))
qWarning().noquote() << "Previous version of" << m_file_path << "not kept:" << backup_error;
//The saved date, time and path go into the file being written, and
//only when there is something new to save: an unchanged project
//saves to an identical file (F124, a project kept in git). A
//failed write puts the previous values back.
const DiagramContext stamped_before = m_project_properties;
const bool stamped = stampSaved();
const auto failed_stamped = [&](const QString &error) {
if (stamped) {
m_project_properties = stamped_before;
emit projectInformationsChanged(this);
updateDiagramsFolioData();
}
return failed(error);
};
QString error_message;
if (isContainerPath(m_file_path))
{
//A container is written from the whole document: every folio
//built (stage D4 writes it from the database)
if (!writeContainerFile(m_file_path, &error_message))
return(failed(error_message));
return(failed_stamped(error_message));
}
else
{
@@ -2884,7 +2951,7 @@ QETResult QETProject::write(bool overwrite_changed)
QDomDocument xml_project(toXml(&kept_folios));
if (!QET::writeXmlText(spliceKeptFolios(xml_project.toString(4), kept_folios),
m_file_path, &error_message))
return(failed(error_message));
return(failed_stamped(error_message));
}
rememberDiskState();
@@ -2905,17 +2972,8 @@ QETResult QETProject::write(bool overwrite_changed)
}
}
//title block variables should be updated after file save dialog is confirmed, before file is saved.
m_project_properties.addValue("saveddate", QLocale::system().toString(QDate::currentDate(), QLocale::ShortFormat));
m_project_properties.addValue("saveddate-us", QDate::currentDate().toString("yyyy-MM-dd"));
m_project_properties.addValue("saveddate-eu", QDate::currentDate().toString("dd-MM-yyyy"));
m_project_properties.addValue("savedtime", QDateTime::currentDateTime().toString("HH:mm"));
m_project_properties.addValue("savedfilename", QFileInfo(filePath()).completeBaseName());
m_project_properties.addValue("savedfilepath", filePath());
emit projectInformationsChanged(this);
updateDiagramsFolioData();
m_stamped_path = m_file_path;
m_stamped_undo_index = m_undo_stack->index();
setModified(false);
return(QETResult());
}
@@ -3637,6 +3695,41 @@ void QETProject::readDiagramsXml(QDomDocument &xml_project)
}
}
//Symbols sharing a uuid (copies made by older versions, F100): the
//project database, links and wires name a symbol by its uuid, so
//each copy but one gets its own (renewedSharedUuid()). The copy
//that keeps it is the first one linked to another symbol (a
//partner's link names the uuid), else the first. The folios with
//a copy to renew are built now, also with lazy folios, so the
//whole project has one uuid per symbol from the start.
m_shared_uuid_keepers.clear();
QSet<int> build_now;
{
QHash<QUuid, QList<std::tuple<int, int, bool>>> copies;
for (int i = 0 ; i < diagram_nodes.length() ; ++i) {
const QDomElement elements = diagram_nodes.at(i).toElement()
.firstChildElement(QStringLiteral("elements"));
QHash<QUuid, int> ordinal;
for (QDomElement e = elements.firstChildElement(QStringLiteral("element"));
!e.isNull() ; e = e.nextSiblingElement(QStringLiteral("element"))) {
const QUuid uuid(e.attribute(QStringLiteral("uuid")));
if (uuid.isNull()) continue;
const bool linked = !e.firstChildElement(QStringLiteral("links_uuids"))
.firstChildElement(QStringLiteral("link_uuid")).isNull();
copies[uuid].append({i, ordinal[uuid]++, linked});
}
}
for (auto it = copies.cbegin() ; it != copies.cend() ; ++it) {
if (it.value().size() < 2) continue;
auto keeper = it.value().first();
for (const auto &copy : it.value())
if (std::get<2>(copy)) { keeper = copy; break; }
m_shared_uuid_keepers.insert(it.key(), {std::get<0>(keeper), std::get<1>(keeper)});
for (const auto &copy : it.value())
if (copy != keeper) build_now.insert(std::get<0>(copy));
}
}
if(dlgWaiting)
dlgWaiting->setProgressBarRange(0, diagram_nodes.length()*3);
@@ -3690,7 +3783,7 @@ void QETProject::readDiagramsXml(QDomDocument &xml_project)
connect(diagram, &Diagram::usedTitleBlockTemplateChanged,
this, &QETProject::usedTitleBlockTemplateChanged);
m_deferring_folios = m_lazy_open;
m_deferring_folios = m_lazy_open && !build_now.contains(i);
diagram->initFromXml(diagram_xml_element);
m_deferring_folios = false;
if (!diagram->isLoaded() && !line_starts.isEmpty())
@@ -3703,6 +3796,7 @@ void QETProject::readDiagramsXml(QDomDocument &xml_project)
}
}
m_shared_uuid_keepers.clear();
updateDiagramsFolioData();
//Initialise links between elements in this project
+12 -1
View File
@@ -123,6 +123,8 @@ class QETProject : public QObject
projectDataBase *dataBase();
QUuid uuid() const;
QUuid derivedItemUuid(const QString &kind, const QString &key);
QUuid renewedSharedUuid(int folio_index, int ordinal, const QUuid &uuid,
const QUuid &folio_uuid);
QByteArray containerPicture(const QString &file) const;
ProjectState state() const;
QString openError() const;
@@ -441,6 +443,7 @@ class QETProject : public QObject
}
private:
bool stampSaved();
void readProjectXml(QDomDocument &xml_project);
void readDiagramsXml(QDomDocument &xml_project);
void readElementsCollectionXml(QDomDocument &xml_project);
@@ -570,6 +573,10 @@ class QETProject : public QObject
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;
int m_stamped_undo_index = 0;
/// The project file as this QET last read or wrote it, to see
/// whether something else changed it since (changedOnDisk())
QString m_disk_path;
@@ -610,7 +617,11 @@ class QETProject : public QObject
int m_next_backup_slot = 0;
QUuid m_uuid = QUuid::createUuid();
QHash<QString, int> m_derived_uuid_keys;
QSet<QUuid> m_saved_item_uuids; //symbol and wire uuids the file carries, see derivedItemUuid()
QSet<QUuid> m_saved_item_uuids;
/// While opening: per uuid carried by several symbols, the copy
/// keeping it (folio index, ordinal on that folio), see
/// renewedSharedUuid()
QHash<QUuid, std::pair<int, int>> m_shared_uuid_keepers; //symbol and wire uuids the file carries, see derivedItemUuid()
projectDataBase m_data_base;
QVector<TerminalStrip *> m_terminal_strip_vector;
QVector<Cable *> m_cables;