mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-09-29 22:24:13 +02:00
Fill the project database from the file as it is read
The project database -- behind parts lists, summary tables and the wiring list -- was filled by walking the built folios: every element and conductor object of every scene. Filling it from the document the project was just read from instead is what the database needs before a project could be opened without building every folio (qelectrotech-docker DB-FROM-XML-SCOPE.md). updateDB(document), called by readProjectXml(), fills diagram, diagram_info, element, element_info, terminal and conductor from the document, through the code the folios use: a BorderTitleBlock read from each folio's XML gives the title-block values and each element's grid cell, the embedded collection gives each definition, and the binders are shared with the live path. Shapes, texts and pictures still come from the folios (their boxes need fonts and pens). It falls back to the folios, saying why in the log, when the document does not carry what that needs: an item without a saved uuid (older files -- the folios derive them on load), a conductor naming its ends the older way, a %autonum folio number, a terminal showing its master's label, a missing or unbuildable definition. A symbol label computed from a formula is the one saved in the file, which QElectroTech writes as it computes it on every save. QET_DATABASE_FROM_FOLIOS=1 forces the folio path. tst_databasefromdocument saves every example once, then fills both ways and requires identical tables (24/24, filled from the document each time), and checks that an older file falls back with its reason. Red when the document path is made to write a wrong grid cell. Database phase of loading unchanged: industrial.qet 0.146 s vs 0.160 s, Polonez 0.040 s vs 0.038 s (median of 5). QETProject::projectWideProperties() is split out of updateDiagramsFolioData() so both fills use the same title-block context. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "sqlreadonly.h"
|
||||
|
||||
#include "../bordertitleblock.h"
|
||||
#include "../diagram.h"
|
||||
#include "../diagramposition.h"
|
||||
#include "../elementprovider.h"
|
||||
@@ -32,8 +33,15 @@
|
||||
#include "../qetgraphicsitem/terminal.h"
|
||||
#include "../qetinformation.h"
|
||||
#include "../qetproject.h"
|
||||
#include "../qet.h"
|
||||
#include "../ElementsCollection/xmlelementcollection.h"
|
||||
#include "../properties/elementdata.h"
|
||||
|
||||
#include <QLocale>
|
||||
#include <QDate>
|
||||
#include <QDomDocument>
|
||||
|
||||
#include <functional>
|
||||
#include <QMetaEnum>
|
||||
#include <QTextDocument>
|
||||
#include <QFile>
|
||||
@@ -125,6 +133,389 @@ void projectDataBase::updateDB()
|
||||
emit dataBaseUpdated();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief projectDataBase::updateDB
|
||||
updateDB() for a project just read from @p document.
|
||||
|
||||
The diagram, diagram_info, element, element_info, terminal and conductor
|
||||
tables are filled from the document itself when it carries everything
|
||||
they need -- see populateFromDocument() -- and from the built folios
|
||||
otherwise, as updateDB() does. Shapes, texts and pictures always come from
|
||||
the built folios: their boxes need the fonts and pens a folio renders with.
|
||||
|
||||
The two fills give the same tables (tst_databasefromdocument checks it on
|
||||
the shipped examples). Reading the document instead of the folios is what
|
||||
the database needs before a project can be opened without building every
|
||||
folio; see DB-FROM-XML-SCOPE.md in qelectrotech-docker.
|
||||
*/
|
||||
void projectDataBase::updateDB(const QDomDocument &document)
|
||||
{
|
||||
if (m_update_blocked || !m_content_changed) {
|
||||
updateDB();
|
||||
return;
|
||||
}
|
||||
//QET_DATABASE_FROM_FOLIOS=1 keeps the fill from the built folios:
|
||||
//a way back should the two ever disagree, and what the test that
|
||||
//says they do not compares against.
|
||||
QString why;
|
||||
if (qEnvironmentVariableIntValue("QET_DATABASE_FROM_FOLIOS") == 1) {
|
||||
why = QStringLiteral("QET_DATABASE_FROM_FOLIOS is set");
|
||||
} else if (populateFromDocument(document, &why)) {
|
||||
qInfo() << "Project database filled from the document";
|
||||
populateDrawingItemTables();
|
||||
m_content_changed = false;
|
||||
emit dataBaseUpdated();
|
||||
return;
|
||||
}
|
||||
qInfo().noquote() << "Project database filled from the folios:" << why;
|
||||
updateDB();
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct DocumentTerminal
|
||||
{
|
||||
QString uuid;
|
||||
QString name;
|
||||
bool master_label = false;
|
||||
};
|
||||
|
||||
struct DocumentDefinition
|
||||
{
|
||||
QString type;
|
||||
QString sub_type;
|
||||
QHash<QUuid, DocumentTerminal> terminals;
|
||||
};
|
||||
|
||||
struct DocumentElement
|
||||
{
|
||||
QString uuid;
|
||||
QString diagram_uuid;
|
||||
QString pos;
|
||||
QString type;
|
||||
QString sub_type;
|
||||
QVariant group;
|
||||
DiagramContext informations;
|
||||
QHash<QUuid, DocumentTerminal> terminals;
|
||||
};
|
||||
|
||||
struct DocumentConductor
|
||||
{
|
||||
QString uuid;
|
||||
QString diagram_uuid;
|
||||
QString element1, terminal1, element2, terminal2;
|
||||
QString text;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@brief projectDataBase::populateFromDocument
|
||||
Fill the diagram, diagram_info, element, element_info, terminal and
|
||||
conductor tables from @p document, the project as read from its file,
|
||||
with the same values the built folios give -- using the same code:
|
||||
a BorderTitleBlock read from each folio's XML gives the title-block
|
||||
values and each element's grid cell, the project's embedded collection
|
||||
gives each element's definition, and the binders are shared.
|
||||
|
||||
Nothing is written unless the whole document can be read this way. It
|
||||
cannot -- and false is returned, for the caller to fill from the folios
|
||||
instead -- when a folio, element or conductor carries no saved uuid (the
|
||||
folios derive one on load), a conductor names its ends the older way,
|
||||
a folio number uses %autonum, a conductor ends on a terminal that shows
|
||||
its master's contact label, or an element's definition is missing or
|
||||
not one the folios could build. A file saved by a current QElectroTech
|
||||
carries everything else.
|
||||
|
||||
A symbol label computed from a formula is the label saved in the file,
|
||||
which QElectroTech writes as it computes it on every save.
|
||||
@return true if the tables were filled
|
||||
*/
|
||||
bool projectDataBase::populateFromDocument(const QDomDocument &document, QString *why)
|
||||
{
|
||||
auto refuse = [why](const QString &reason) {
|
||||
if (why) *why = reason;
|
||||
return false;
|
||||
};
|
||||
if (!m_project) {
|
||||
return refuse(QStringLiteral("no project"));
|
||||
}
|
||||
|
||||
//The folios, in the order the project read them (readDiagramsXml()),
|
||||
//each with its saved uuid -- the one the built folio has.
|
||||
const QDomNodeList diagram_nodes = document.elementsByTagName(QStringLiteral("diagram"));
|
||||
const QList<Diagram *> diagrams = m_project->diagrams();
|
||||
if (diagram_nodes.size() != diagrams.size()) {
|
||||
return refuse(QStringLiteral("the folios are not the document's"));
|
||||
}
|
||||
|
||||
const DiagramContext project_wide = m_project->projectWideProperties();
|
||||
//One border and title block read from each folio's XML in turn:
|
||||
//only what it gives is kept.
|
||||
BorderTitleBlock reader;
|
||||
QList<DiagramContext> diagram_infos;
|
||||
QList<QDate> diagram_dates;
|
||||
QList<QUuid> diagram_uuids;
|
||||
QList<DocumentElement> elements;
|
||||
QList<DocumentConductor> conductors;
|
||||
QSet<QUuid> element_uuids;
|
||||
QHash<QString, DocumentDefinition> definitions; //by element type
|
||||
|
||||
//The project's own definitions by "embed://" path, which is how an
|
||||
//element's type names them: one walk of the embedded collection
|
||||
//rather than resolving an ElementsLocation per type.
|
||||
QHash<QString, QDomElement> stored;
|
||||
std::function<void (const QDomElement &, const QString &)> walk =
|
||||
[&stored, &walk](const QDomElement &category, const QString &path) {
|
||||
for (QDomElement child = category.firstChildElement() ;
|
||||
!child.isNull() ; child = child.nextSiblingElement()) {
|
||||
const QString name = path + child.attribute(QStringLiteral("name"));
|
||||
if (child.tagName() == QLatin1String("category")) {
|
||||
walk(child, name + QLatin1Char('/'));
|
||||
} else if (child.tagName() == QLatin1String("element")) {
|
||||
stored.insert(name, child.firstChildElement(QStringLiteral("definition")));
|
||||
}
|
||||
}
|
||||
};
|
||||
if (auto collection = m_project->embeddedElementCollection()) {
|
||||
walk(collection->root(), QStringLiteral("embed://"));
|
||||
}
|
||||
|
||||
for (int i = 0 ; i < diagram_nodes.size() ; ++i)
|
||||
{
|
||||
const QDomElement diagram_xml = diagram_nodes.at(i).toElement();
|
||||
const QUuid diagram_uuid(diagram_xml.attribute(QStringLiteral("uuid")));
|
||||
if (diagram_uuid.isNull() || diagram_uuid != diagrams.at(i)->uuid()) {
|
||||
return refuse(QStringLiteral("a folio has no saved uuid"));
|
||||
}
|
||||
|
||||
BorderTitleBlock *border = &reader;
|
||||
border->titleBlockFromXml(diagram_xml);
|
||||
border->borderFromXml(diagram_xml);
|
||||
if (border->folio().contains(QStringLiteral("%autonum"))) {
|
||||
return refuse(QStringLiteral("a folio number uses %autonum"));
|
||||
}
|
||||
border->setFolioData(i + 1, int(diagram_nodes.size()), QString(), project_wide);
|
||||
|
||||
QHash<QUuid, int> on_this_folio; //element uuid -> index in elements
|
||||
for (const QDomElement &element_xml : QET::findInDomElement(
|
||||
diagram_xml, QStringLiteral("elements"), QStringLiteral("element")))
|
||||
{
|
||||
const QUuid uuid(element_xml.attribute(QStringLiteral("uuid")));
|
||||
if (uuid.isNull() || element_uuids.contains(uuid)) {
|
||||
return refuse(QStringLiteral("an element has no saved uuid, or shares one"));
|
||||
}
|
||||
element_uuids.insert(uuid);
|
||||
|
||||
//The definition the folio builds the element from, with the
|
||||
//checks Element::buildFromXml() refuses an element on --
|
||||
//read once per type, as many elements share one.
|
||||
const QString type = element_xml.attribute(QStringLiteral("type"));
|
||||
auto known = definitions.constFind(type);
|
||||
if (known == definitions.constEnd())
|
||||
{
|
||||
const QDomElement definition = stored.value(type);
|
||||
if (definition.isNull()) {
|
||||
return refuse(QStringLiteral("an element's definition is not in the project"));
|
||||
}
|
||||
int number;
|
||||
if (definition.tagName() != QLatin1String("definition")
|
||||
|| definition.attribute(QStringLiteral("type")) != QLatin1String("element")
|
||||
|| !QET::attributeIsAnInteger(definition, QStringLiteral("width"), &number)
|
||||
|| !QET::attributeIsAnInteger(definition, QStringLiteral("height"), &number)
|
||||
|| !QET::attributeIsAnInteger(definition, QStringLiteral("hotspot_x"), &number)
|
||||
|| !QET::attributeIsAnInteger(definition, QStringLiteral("hotspot_y"), &number)
|
||||
|| definition.firstChild().isNull()) {
|
||||
return refuse(QStringLiteral("an element's definition cannot be built"));
|
||||
}
|
||||
DocumentDefinition read;
|
||||
ElementData data;
|
||||
data.fromXml(definition);
|
||||
read.type = data.typeToString();
|
||||
read.sub_type = data.masterTypeToString();
|
||||
const QDomElement description = definition.firstChildElement(QStringLiteral("description"));
|
||||
for (QDomElement t = description.firstChildElement(QStringLiteral("terminal")) ;
|
||||
!t.isNull() ; t = t.nextSiblingElement(QStringLiteral("terminal")))
|
||||
{
|
||||
const QUuid terminal_uuid(t.attribute(QStringLiteral("uuid")));
|
||||
if (terminal_uuid.isNull()) {
|
||||
continue;
|
||||
}
|
||||
DocumentTerminal terminal;
|
||||
terminal.uuid = terminal_uuid.toString();
|
||||
terminal.name = t.attribute(QStringLiteral("name"));
|
||||
terminal.master_label = t.attribute(QStringLiteral("use_master_label")) == QLatin1String("true");
|
||||
read.terminals.insert(terminal_uuid, terminal);
|
||||
}
|
||||
known = definitions.insert(type, read);
|
||||
}
|
||||
|
||||
DocumentElement element;
|
||||
element.uuid = uuid.toString();
|
||||
element.diagram_uuid = diagram_uuid.toString();
|
||||
element.pos = border->convertPosition(
|
||||
QPointF(element_xml.attribute(QStringLiteral("x")).toDouble(),
|
||||
element_xml.attribute(QStringLiteral("y")).toDouble()))
|
||||
.toString();
|
||||
element.type = known->type;
|
||||
element.sub_type = known->sub_type;
|
||||
element.terminals = known->terminals;
|
||||
const QUuid group = ItemGroups::read(element_xml);
|
||||
element.group = group.isNull() ? QVariant() : QVariant(group.toString());
|
||||
element.informations.fromXml(
|
||||
element_xml.firstChildElement(QStringLiteral("elementInformations")),
|
||||
QStringLiteral("elementInformation"));
|
||||
|
||||
on_this_folio.insert(uuid, int(elements.size()));
|
||||
elements << element;
|
||||
}
|
||||
|
||||
//The conductors the folio builds, and only those: an end that is
|
||||
//not found, a conductor from a terminal to itself and a second
|
||||
//conductor between the same two terminals are all dropped on load.
|
||||
QSet<QString> joined;
|
||||
for (QDomElement conductor_xml : QET::findInDomElement(
|
||||
diagram_xml, QStringLiteral("conductors"), QStringLiteral("conductor")))
|
||||
{
|
||||
if (!Conductor::valideXml(conductor_xml)) {
|
||||
continue;
|
||||
}
|
||||
const QUuid uuid(conductor_xml.attribute(QStringLiteral("uuid")));
|
||||
if (uuid.isNull()
|
||||
|| !conductor_xml.hasAttribute(QStringLiteral("element1"))
|
||||
|| !conductor_xml.hasAttribute(QStringLiteral("element2"))) {
|
||||
return refuse(QStringLiteral("a conductor has no saved uuid, or names its ends the older way"));
|
||||
}
|
||||
QString ends[2][2];
|
||||
bool found = true;
|
||||
for (int n = 0 ; n < 2 ; ++n)
|
||||
{
|
||||
const QString index = QString::number(n + 1);
|
||||
const QUuid owner(conductor_xml.attribute(QStringLiteral("element") + index));
|
||||
const QUuid terminal(conductor_xml.attribute(QStringLiteral("terminal") + index));
|
||||
const int e = on_this_folio.value(owner, -1);
|
||||
if (e < 0) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
if (!elements.at(e).terminals.contains(terminal)) {
|
||||
//The folio would try the terminal's derived uuid;
|
||||
//leave that to it.
|
||||
return refuse(QStringLiteral("a conductor ends on a terminal not in its element's definition"));
|
||||
}
|
||||
const DocumentTerminal &t = elements.at(e).terminals.value(terminal);
|
||||
if (t.master_label) {
|
||||
return refuse(QStringLiteral("a conductor ends on a terminal showing its master's label"));
|
||||
}
|
||||
ends[n][0] = elements.at(e).uuid;
|
||||
ends[n][1] = t.uuid;
|
||||
}
|
||||
if (!found) {
|
||||
continue;
|
||||
}
|
||||
const QString a = ends[0][0] + ends[0][1], b = ends[1][0] + ends[1][1];
|
||||
if (a == b) {
|
||||
continue;
|
||||
}
|
||||
const QString pair = a < b ? a + b : b + a;
|
||||
if (joined.contains(pair)) {
|
||||
continue;
|
||||
}
|
||||
joined.insert(pair);
|
||||
|
||||
DocumentConductor conductor;
|
||||
conductor.uuid = uuid.toString();
|
||||
conductor.diagram_uuid = diagram_uuid.toString();
|
||||
conductor.element1 = ends[0][0];
|
||||
conductor.terminal1 = ends[0][1];
|
||||
conductor.element2 = ends[1][0];
|
||||
conductor.terminal2 = ends[1][1];
|
||||
//ConductorProperties::fromXml()'s text, without reading the
|
||||
//rest of the properties
|
||||
conductor.text = conductor_xml.attribute(QStringLiteral("num"));
|
||||
conductors << conductor;
|
||||
}
|
||||
|
||||
diagram_uuids << diagram_uuid;
|
||||
diagram_infos << border->titleblockInformation();
|
||||
diagram_dates << border->date();
|
||||
}
|
||||
|
||||
//Everything could be read: write it.
|
||||
QSqlQuery query(m_data_base);
|
||||
for (const QString &table : {QStringLiteral("diagram"), QStringLiteral("diagram_info"),
|
||||
QStringLiteral("element"), QStringLiteral("element_info"),
|
||||
QStringLiteral("conductor"), QStringLiteral("terminal")}) {
|
||||
query.exec(QStringLiteral("DELETE FROM ") + table);
|
||||
}
|
||||
|
||||
for (int i = 0 ; i < diagram_uuids.size() ; ++i)
|
||||
{
|
||||
m_insert_diagram_query.bindValue(":uuid", diagram_uuids.at(i).toString());
|
||||
m_insert_diagram_query.bindValue(":pos", i + 1);
|
||||
if (!m_insert_diagram_query.exec()) {
|
||||
qDebug() << "projectDataBase::populateFromDocument diagram insert error : " << m_insert_diagram_query.lastError();
|
||||
}
|
||||
bindDiagramInfoValues(m_insert_diagram_info_query, diagram_uuids.at(i),
|
||||
diagram_infos.at(i), diagram_dates.at(i));
|
||||
if (!m_insert_diagram_info_query.exec()) {
|
||||
qDebug() << "projectDataBase::populateFromDocument diagram_info insert error : " << m_insert_diagram_info_query.lastError();
|
||||
}
|
||||
}
|
||||
|
||||
for (const DocumentElement &element : std::as_const(elements))
|
||||
{
|
||||
m_insert_elements_query.bindValue(QStringLiteral(":uuid"), element.uuid);
|
||||
m_insert_elements_query.bindValue(QStringLiteral(":diagram_uuid"), element.diagram_uuid);
|
||||
m_insert_elements_query.bindValue(QStringLiteral(":pos"), element.pos);
|
||||
m_insert_elements_query.bindValue(QStringLiteral(":type"), element.type);
|
||||
m_insert_elements_query.bindValue(QStringLiteral(":sub_type"), element.sub_type);
|
||||
m_insert_elements_query.bindValue(QStringLiteral(":group_uuid"), element.group);
|
||||
if (!m_insert_elements_query.exec()) {
|
||||
qDebug() << "projectDataBase::populateFromDocument element insert error : " << m_insert_elements_query.lastError();
|
||||
}
|
||||
bindElementInfoValues(m_insert_element_info_query, element.uuid, element.informations,
|
||||
element.informations[QStringLiteral("label")].toString());
|
||||
if (!m_insert_element_info_query.exec()) {
|
||||
qDebug() << "projectDataBase::populateFromDocument element_info insert error : " << m_insert_element_info_query.lastError();
|
||||
}
|
||||
}
|
||||
|
||||
QHash<QString, int> element_index;
|
||||
for (int i = 0 ; i < elements.size() ; ++i) {
|
||||
element_index.insert(elements.at(i).uuid, i);
|
||||
}
|
||||
for (const DocumentConductor &conductor : std::as_const(conductors))
|
||||
{
|
||||
for (const auto &end : {std::make_pair(conductor.element1, conductor.terminal1),
|
||||
std::make_pair(conductor.element2, conductor.terminal2)}) {
|
||||
const DocumentElement &owner = elements.at(element_index.value(end.first));
|
||||
insertTerminal(end.second, end.first,
|
||||
owner.terminals.value(QUuid(end.second)).name);
|
||||
}
|
||||
m_insert_conductor_query.bindValue(QStringLiteral(":uuid"), conductor.uuid);
|
||||
m_insert_conductor_query.bindValue(QStringLiteral(":diagram_uuid"), conductor.diagram_uuid);
|
||||
m_insert_conductor_query.bindValue(QStringLiteral(":terminal1_uuid"), conductor.terminal1);
|
||||
m_insert_conductor_query.bindValue(QStringLiteral(":terminal1_element_uuid"), conductor.element1);
|
||||
m_insert_conductor_query.bindValue(QStringLiteral(":terminal2_uuid"), conductor.terminal2);
|
||||
m_insert_conductor_query.bindValue(QStringLiteral(":terminal2_element_uuid"), conductor.element2);
|
||||
m_insert_conductor_query.bindValue(QStringLiteral(":text"), conductor.text);
|
||||
if (!m_insert_conductor_query.exec()) {
|
||||
qDebug() << "projectDataBase::populateFromDocument conductor insert error : " << m_insert_conductor_query.lastError();
|
||||
}
|
||||
}
|
||||
|
||||
//While every folio is still built, their conductors are watched for
|
||||
//property changes as populateConductorTable() does -- the one walk
|
||||
//over the built folios left here.
|
||||
for (Diagram *diagram : diagrams) {
|
||||
for (Conductor *conductor : diagram->conductors()) {
|
||||
if (conductor->terminal1->parentElement() && conductor->terminal2->parentElement()) {
|
||||
watchConductor(conductor);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief projectDataBase::setUpdateBlocked
|
||||
@param blocked : whether updateDB() should skip the full rebuild
|
||||
@@ -1514,9 +1905,21 @@ void projectDataBase::populateConductorTable()
|
||||
*/
|
||||
void projectDataBase::insertTerminal(Terminal *terminal)
|
||||
{
|
||||
m_insert_terminal_query.bindValue(":uuid", terminal->stableUuid().toString());
|
||||
m_insert_terminal_query.bindValue(":element_uuid", terminal->parentElement()->uuid().toString());
|
||||
m_insert_terminal_query.bindValue(":name", terminal->name());
|
||||
insertTerminal(terminal->stableUuid().toString(),
|
||||
terminal->parentElement()->uuid().toString(),
|
||||
terminal->name());
|
||||
}
|
||||
|
||||
/**
|
||||
@brief projectDataBase::insertTerminal
|
||||
insertTerminal(Terminal *) from values rather than a live terminal.
|
||||
*/
|
||||
void projectDataBase::insertTerminal(const QString &uuid, const QString &element_uuid,
|
||||
const QString &name)
|
||||
{
|
||||
m_insert_terminal_query.bindValue(":uuid", uuid);
|
||||
m_insert_terminal_query.bindValue(":element_uuid", element_uuid);
|
||||
m_insert_terminal_query.bindValue(":name", name);
|
||||
if (!m_insert_terminal_query.exec()) {
|
||||
qDebug() << "projectDataBase::insertTerminal insert error : " << m_insert_terminal_query.lastError();
|
||||
}
|
||||
@@ -1733,11 +2136,48 @@ void projectDataBase::bindElementInfoValues(QSqlQuery &query, Element *element)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief projectDataBase::bindElementInfoValues
|
||||
bindElementInfoValues(QSqlQuery &, Element *) from values: the element's
|
||||
information and the label to store for it.
|
||||
*/
|
||||
void projectDataBase::bindElementInfoValues(QSqlQuery &query, const QString &element_uuid,
|
||||
const DiagramContext &informations,
|
||||
const QString &label)
|
||||
{
|
||||
query.bindValue(QStringLiteral(":uuid"), element_uuid);
|
||||
for (const auto &key : QETInformation::elementInfoKeys()) {
|
||||
query.bindValue(QStringLiteral(":") + key,
|
||||
key == QLatin1String("label") ? label
|
||||
: informations[key].toString());
|
||||
}
|
||||
}
|
||||
|
||||
void projectDataBase::bindDiagramInfoValues(QSqlQuery &query, Diagram *diagram)
|
||||
{
|
||||
query.bindValue(":uuid", diagram->uuid());
|
||||
bindDiagramInfoValues(query, diagram->uuid(), diagram->border_and_titleblock);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief projectDataBase::bindDiagramInfoValues
|
||||
bindDiagramInfoValues(QSqlQuery &, Diagram *) from a folio's uuid and its
|
||||
border and title block, which need not belong to a built folio.
|
||||
*/
|
||||
void projectDataBase::bindDiagramInfoValues(QSqlQuery &query, const QUuid &diagram_uuid,
|
||||
const BorderTitleBlock &border)
|
||||
{
|
||||
bindDiagramInfoValues(query, diagram_uuid, border.titleblockInformation(), border.date());
|
||||
}
|
||||
|
||||
/**
|
||||
@brief projectDataBase::bindDiagramInfoValues
|
||||
The same from a title block's information and date.
|
||||
*/
|
||||
void projectDataBase::bindDiagramInfoValues(QSqlQuery &query, const QUuid &diagram_uuid,
|
||||
const DiagramContext &infos, const QDate &date)
|
||||
{
|
||||
query.bindValue(":uuid", diagram_uuid);
|
||||
|
||||
auto infos = diagram->border_and_titleblock.titleblockInformation();
|
||||
for (auto key : QETInformation::diagramInfoKeys())
|
||||
{
|
||||
if (key == "date") {
|
||||
@@ -1745,8 +2185,7 @@ void projectDataBase::bindDiagramInfoValues(QSqlQuery &query, Diagram *diagram)
|
||||
//back: that text is the locale's short format, and where
|
||||
//it has a two-digit year (en_US "M/d/yy") toDate() reads
|
||||
//2010 back as 1910.
|
||||
query.bindValue(QStringLiteral(":date"),
|
||||
diagram->border_and_titleblock.date());
|
||||
query.bindValue(QStringLiteral(":date"), date);
|
||||
} else {
|
||||
auto value = infos.value(key);
|
||||
auto bind = key.prepend(":");
|
||||
|
||||
@@ -33,6 +33,10 @@ class Diagram;
|
||||
class Conductor;
|
||||
class Terminal;
|
||||
class QGraphicsItem;
|
||||
class QDomDocument;
|
||||
class BorderTitleBlock;
|
||||
class DiagramContext;
|
||||
class QDate;
|
||||
|
||||
/**
|
||||
@brief The projectDataBase class
|
||||
@@ -50,6 +54,13 @@ class projectDataBase : public QObject
|
||||
virtual ~projectDataBase() override;
|
||||
|
||||
void updateDB();
|
||||
/**
|
||||
updateDB() for a project just read from @p document: the
|
||||
diagram, element, terminal and conductor tables are filled
|
||||
from the document when it carries everything they need (see
|
||||
populateFromDocument()), from the built folios otherwise.
|
||||
*/
|
||||
void updateDB(const QDomDocument &document);
|
||||
/**
|
||||
Suppress the full rebuild performed by updateDB().
|
||||
|
||||
@@ -131,18 +142,28 @@ class projectDataBase : public QObject
|
||||
void populateDiagramInfoTable();
|
||||
void populateConductorTable();
|
||||
void populateDrawingItemTables();
|
||||
bool populateFromDocument(const QDomDocument &document, QString *why = nullptr);
|
||||
bool writeDrawingItem(QObject *object);
|
||||
void flushDrawingItems();
|
||||
void forgetDrawingItem(QObject *object);
|
||||
void bindConductorValues(QSqlQuery &query, Conductor *conductor, Diagram *diagram);
|
||||
void watchConductor(Conductor *conductor);
|
||||
void insertTerminal(Terminal *terminal);
|
||||
void insertTerminal(const QString &uuid, const QString &element_uuid,
|
||||
const QString &name);
|
||||
void prepareQuery();
|
||||
static QHash<QString, QString> elementInfoToString(
|
||||
Element *elmt);
|
||||
void bindDiagramInfoValues(QSqlQuery &query, Diagram *diagram);
|
||||
static void bindDiagramInfoValues(QSqlQuery &query, const QUuid &diagram_uuid,
|
||||
const BorderTitleBlock &border);
|
||||
static void bindDiagramInfoValues(QSqlQuery &query, const QUuid &diagram_uuid,
|
||||
const DiagramContext &infos, const QDate &date);
|
||||
static void bindElementValues(QSqlQuery &query, Element *element, Diagram *diagram);
|
||||
static void bindElementInfoValues(QSqlQuery &query, Element *element);
|
||||
static void bindElementInfoValues(QSqlQuery &query, const QString &element_uuid,
|
||||
const DiagramContext &informations,
|
||||
const QString &label);
|
||||
|
||||
private:
|
||||
QPointer<QETProject> m_project;
|
||||
|
||||
Reference in New Issue
Block a user