mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-21 22:04:13 +02:00
Keep the project's numbering in the project database too
QETZ-DB-FIRST stage 2b-1. The numbering schemes of wires, symbols, folios and cables, and the settings saved with them (the scheme in use of each kind, freezing new labels, auto-break, the cable axis and question), get three tables of the project database: numbering_scheme, numbering_part (one row per part, in order) and numbering_setting. QETProject writes them when it reads its file and after each change of its numbering, from every setter; nothing reads them yet. The save writes the numbering through writeNumberingXml(), the code it had moved out of writeDefaultPropertiesXml(), so the same writer can take the rows once the save moves to them (2b-2). QET_CHECK_NUMBERING_ROWS=1 writes the numbering from the project and from the rows at each save and says whether the two differ. tst_elementautonumids::numberingRowsFollowEveryChange checks it after each of 23 changes; with one setter not writing the rows, one save differs and it fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2695,6 +2695,25 @@ bool projectDataBase::createDataBase()
|
||||
qDebug() << " link_table query : " << query_.lastError();
|
||||
}
|
||||
|
||||
//The numbering tables (QETZ-DB-FIRST stage 2b): the project's
|
||||
//schemes, one row per part of each in its order, and the settings
|
||||
//saved with them. Not filled from the folios: QETProject writes
|
||||
//them when it reads its file and whenever its numbering changes.
|
||||
for (const char *table : {
|
||||
"CREATE TABLE numbering_scheme ("
|
||||
"kind VARCHAR(20) NOT NULL, title TEXT NOT NULL, uuid VARCHAR(50), "
|
||||
"PRIMARY KEY (kind, title))",
|
||||
"CREATE TABLE numbering_part ("
|
||||
"kind VARCHAR(20) NOT NULL, title TEXT NOT NULL, ord INTEGER NOT NULL, "
|
||||
"type TEXT, value TEXT, increase TEXT, initialvalue TEXT, modulus TEXT, format TEXT, "
|
||||
"PRIMARY KEY (kind, title, ord), "
|
||||
"FOREIGN KEY (kind, title) REFERENCES numbering_scheme (kind, title))",
|
||||
"CREATE TABLE numbering_setting (name VARCHAR(50) PRIMARY KEY NOT NULL, value TEXT)"}) {
|
||||
if (!query_.exec(QLatin1String(table))) {
|
||||
qDebug() << " numbering table query : " << query_.lastError();
|
||||
}
|
||||
}
|
||||
|
||||
//Create the terminal table.
|
||||
//Terminal::uuid() is the terminal-position id baked into the catalog
|
||||
//.elmt definition (e.g. "the top terminal") -- identical across every
|
||||
@@ -4091,6 +4110,120 @@ QStringList projectDataBase::linkRowMismatches()
|
||||
return mismatches;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief projectDataBase::setNumbering
|
||||
The numbering tables hold @p numbering from now on, and nothing else
|
||||
(QETZ-DB-FIRST stage 2b-1: QETProject writes them after reading its
|
||||
file and after each change of its numbering)
|
||||
*/
|
||||
void projectDataBase::setNumbering(const Numbering &numbering)
|
||||
{
|
||||
QSqlQuery query(m_data_base);
|
||||
bool ok = true;
|
||||
for (const char *table : {"numbering_part", "numbering_scheme", "numbering_setting"})
|
||||
ok = ok && query.exec(QStringLiteral("DELETE FROM %1").arg(QLatin1String(table)));
|
||||
|
||||
QSqlQuery scheme(m_data_base);
|
||||
scheme.prepare(QStringLiteral("INSERT INTO numbering_scheme (kind, title, uuid) "
|
||||
"VALUES (:kind, :title, :uuid)"));
|
||||
QSqlQuery part(m_data_base);
|
||||
part.prepare(QStringLiteral("INSERT INTO numbering_part (kind, title, ord, type, value, "
|
||||
"increase, initialvalue, modulus, format) VALUES (:kind, :title, "
|
||||
":ord, :type, :value, :increase, :initialvalue, :modulus, :format)"));
|
||||
for (const NumberingScheme &item : numbering.schemes)
|
||||
{
|
||||
scheme.bindValue(QStringLiteral(":kind"), item.kind);
|
||||
scheme.bindValue(QStringLiteral(":title"), item.title);
|
||||
scheme.bindValue(QStringLiteral(":uuid"), item.uuid.isNull() ? QVariant()
|
||||
: QVariant(item.uuid.toString()));
|
||||
ok = ok && scheme.exec();
|
||||
for (int i = 0 ; i < item.context.size() ; ++i)
|
||||
{
|
||||
const QStringList fields = item.context.itemAt(i);
|
||||
part.bindValue(QStringLiteral(":kind"), item.kind);
|
||||
part.bindValue(QStringLiteral(":title"), item.title);
|
||||
part.bindValue(QStringLiteral(":ord"), i);
|
||||
int field = 0;
|
||||
for (const char *name : {":type", ":value", ":increase", ":initialvalue", ":modulus", ":format"}) {
|
||||
part.bindValue(QLatin1String(name), field < fields.size() ? QVariant(fields.at(field))
|
||||
: QVariant());
|
||||
++field;
|
||||
}
|
||||
ok = ok && part.exec();
|
||||
}
|
||||
}
|
||||
|
||||
QSqlQuery setting(m_data_base);
|
||||
setting.prepare(QStringLiteral("INSERT INTO numbering_setting (name, value) VALUES (:name, :value)"));
|
||||
auto set = [&setting, &ok](const QString &name, const QString &value) {
|
||||
setting.bindValue(QStringLiteral(":name"), name);
|
||||
setting.bindValue(QStringLiteral(":value"), value);
|
||||
ok = ok && setting.exec();
|
||||
};
|
||||
auto flag = [](bool value) { return value ? QStringLiteral("true") : QStringLiteral("false"); };
|
||||
set(QStringLiteral("conductor_current"), numbering.current_conductor);
|
||||
set(QStringLiteral("element_current"), numbering.current_element);
|
||||
set(QStringLiteral("cable_current"), numbering.current_cable);
|
||||
set(QStringLiteral("freeze_new_conductors"), flag(numbering.freeze_new_conductors));
|
||||
set(QStringLiteral("freeze_new_elements"), flag(numbering.freeze_new_elements));
|
||||
set(QStringLiteral("auto_break_conductors"), flag(numbering.auto_break_conductors));
|
||||
set(QStringLiteral("cable_x_axis_first"), flag(numbering.cable_x_axis_first));
|
||||
set(QStringLiteral("cable_ask_numbering"), flag(numbering.cable_ask_numbering));
|
||||
|
||||
if (!ok) {
|
||||
qDebug() << "projectDataBase::setNumbering error : " << query.lastError()
|
||||
<< scheme.lastError() << part.lastError() << setting.lastError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief projectDataBase::numbering
|
||||
@return the numbering the numbering tables hold (setNumbering()); the
|
||||
schemes in no particular order
|
||||
*/
|
||||
projectDataBase::Numbering projectDataBase::numbering() const
|
||||
{
|
||||
Numbering numbering;
|
||||
QSqlQuery query(m_data_base);
|
||||
query.exec(QStringLiteral("SELECT kind, title, uuid FROM numbering_scheme"));
|
||||
QHash<std::pair<QString, QString>, int> index;
|
||||
while (query.next()) {
|
||||
NumberingScheme scheme;
|
||||
scheme.kind = query.value(0).toString();
|
||||
scheme.title = query.value(1).toString();
|
||||
scheme.uuid = QUuid(query.value(2).toString());
|
||||
index.insert({scheme.kind, scheme.title}, numbering.schemes.size());
|
||||
numbering.schemes << scheme;
|
||||
}
|
||||
query.exec(QStringLiteral("SELECT kind, title, type, value, increase, initialvalue, modulus, "
|
||||
"format FROM numbering_part ORDER BY kind, title, ord"));
|
||||
while (query.next()) {
|
||||
const int at = index.value({query.value(0).toString(), query.value(1).toString()}, -1);
|
||||
if (at < 0) {
|
||||
continue;
|
||||
}
|
||||
numbering.schemes[at].context.addValue(query.value(2).toString(), query.value(3).toString(),
|
||||
query.value(4).toInt(), query.value(5).toInt(),
|
||||
query.value(6).toInt(), query.value(7).toString());
|
||||
}
|
||||
query.exec(QStringLiteral("SELECT name, value FROM numbering_setting"));
|
||||
while (query.next())
|
||||
{
|
||||
const QString name = query.value(0).toString();
|
||||
const QString value = query.value(1).toString();
|
||||
const bool flag = value == QLatin1String("true");
|
||||
if (name == QLatin1String("conductor_current")) numbering.current_conductor = value;
|
||||
else if (name == QLatin1String("element_current")) numbering.current_element = value;
|
||||
else if (name == QLatin1String("cable_current")) numbering.current_cable = value;
|
||||
else if (name == QLatin1String("freeze_new_conductors")) numbering.freeze_new_conductors = flag;
|
||||
else if (name == QLatin1String("freeze_new_elements")) numbering.freeze_new_elements = flag;
|
||||
else if (name == QLatin1String("auto_break_conductors")) numbering.auto_break_conductors = flag;
|
||||
else if (name == QLatin1String("cable_x_axis_first")) numbering.cable_x_axis_first = flag;
|
||||
else if (name == QLatin1String("cable_ask_numbering")) numbering.cable_ask_numbering = flag;
|
||||
}
|
||||
return numbering;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief projectDataBase::savedLinks
|
||||
The links @p element saves, read from its link rows, in their order
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "../titleblockproperties.h"
|
||||
#include "../conductorproperties.h"
|
||||
#include "../autoNum/assignvariables.h"
|
||||
#include "../autoNum/numerotationcontext.h"
|
||||
|
||||
class Element;
|
||||
class QETProject;
|
||||
@@ -156,6 +157,28 @@ class projectDataBase : public QObject
|
||||
void conductorUuidChanged(Conductor *conductor, const QUuid &old_uuid);
|
||||
QStringList conductorPropertiesMismatches() const;
|
||||
QStringList linkRowMismatches();
|
||||
/// A numbering scheme of the project (QETZ-DB-FIRST stage 2b)
|
||||
struct NumberingScheme {
|
||||
QString kind; ///< conductor, element, folio or cable
|
||||
QString title;
|
||||
QUuid uuid; ///< element schemes only
|
||||
NumerotationContext context;
|
||||
};
|
||||
/// The project's numbering: its schemes of every kind and the
|
||||
/// settings saved with them
|
||||
struct Numbering {
|
||||
QList<NumberingScheme> schemes;
|
||||
QString current_conductor;
|
||||
QString current_element;
|
||||
QString current_cable;
|
||||
bool freeze_new_conductors = false;
|
||||
bool freeze_new_elements = false;
|
||||
bool auto_break_conductors = false;
|
||||
bool cable_x_axis_first = true;
|
||||
bool cable_ask_numbering = true;
|
||||
};
|
||||
void setNumbering(const Numbering &numbering);
|
||||
Numbering numbering() const;
|
||||
bool savedLinks(const Element *element, QList<std::pair<QUuid, int>> *links);
|
||||
//The link rows are written (opening filled them): a symbol
|
||||
//built links from them (Element::initLink())
|
||||
|
||||
+156
-55
@@ -140,6 +140,8 @@ m_project_properties_handler{this}
|
||||
setCurrentCableAutoNum(cableData.second);
|
||||
}
|
||||
}
|
||||
//m_auto_break_conductor above is read from the settings directly
|
||||
writeNumberingRows();
|
||||
}
|
||||
|
||||
ProjectPropertiesHandler &QETProject::projectPropertiesHandler()
|
||||
@@ -1504,6 +1506,7 @@ QString QETProject::elementCurrentAutoNum () const
|
||||
*/
|
||||
void QETProject::setCurrrentElementAutonum(QString autoNum) {
|
||||
m_current_element_autonum = std::move(autoNum);
|
||||
writeNumberingRows();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1549,6 +1552,7 @@ QString QETProject::cableCurrentAutoNum() const
|
||||
void QETProject::setCurrentCableAutoNum(QString autoNum)
|
||||
{
|
||||
m_current_cable_autonum = std::move(autoNum);
|
||||
writeNumberingRows();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1581,6 +1585,7 @@ bool QETProject::cableXAxisFirst() const
|
||||
void QETProject::setCableXAxisFirst(bool x_axis_first)
|
||||
{
|
||||
m_cable_axis_x_first = x_axis_first;
|
||||
writeNumberingRows();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1607,6 +1612,7 @@ bool QETProject::cableAskNumbering() const
|
||||
void QETProject::setCableAskNumbering(bool ask)
|
||||
{
|
||||
m_cable_ask_numbering = ask;
|
||||
writeNumberingRows();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1660,6 +1666,7 @@ QString QETProject::conductorCurrentAutoNum () const
|
||||
*/
|
||||
void QETProject::setCurrentConductorAutoNum(QString autoNum) {
|
||||
m_current_conductor_autonum = std::move(autoNum);
|
||||
writeNumberingRows();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1680,6 +1687,7 @@ QHash <QString, NumerotationContext> QETProject::folioAutoNum() const
|
||||
*/
|
||||
void QETProject::addConductorAutoNum(const QString& key, const NumerotationContext& context) {
|
||||
m_conductor_autonum.insert(key, context);
|
||||
writeNumberingRows();
|
||||
emit autoNumContextUpdated();
|
||||
}
|
||||
|
||||
@@ -1724,6 +1732,7 @@ void QETProject::addElementAutoNum(const QString &key,
|
||||
}
|
||||
m_element_autonum_id.insert(key, scheme_id);
|
||||
m_element_autonum.insert(key, context);
|
||||
writeNumberingRows();
|
||||
emit elementAutoNumAdded(key);
|
||||
emit autoNumContextUpdated();
|
||||
}
|
||||
@@ -1795,6 +1804,7 @@ bool QETProject::renameElementAutoNum(const QString &old_title, const QString &n
|
||||
}
|
||||
}
|
||||
|
||||
writeNumberingRows();
|
||||
emit elementAutoNumRemoved(old_title);
|
||||
emit elementAutoNumAdded(new_title);
|
||||
emit autoNumContextUpdated();
|
||||
@@ -2023,6 +2033,7 @@ QList<QETProject::SymbolNumbering> QETProject::symbolNumbering() const
|
||||
*/
|
||||
void QETProject::addFolioAutoNum(const QString& key, const NumerotationContext& context) {
|
||||
m_folio_autonum.insert(key, context);
|
||||
writeNumberingRows();
|
||||
emit autoNumContextUpdated();
|
||||
}
|
||||
|
||||
@@ -2049,6 +2060,7 @@ void QETProject::addCableAutoNum(const QString& key, const NumerotationContext&
|
||||
|| !m_cable_autonum.contains(m_current_cable_autonum))) {
|
||||
m_current_cable_autonum = key;
|
||||
}
|
||||
writeNumberingRows();
|
||||
emit autoNumContextUpdated();
|
||||
}
|
||||
|
||||
@@ -2059,6 +2071,7 @@ void QETProject::addCableAutoNum(const QString& key, const NumerotationContext&
|
||||
*/
|
||||
void QETProject::removeConductorAutoNum(const QString& key) {
|
||||
m_conductor_autonum.remove(key);
|
||||
writeNumberingRows();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2070,6 +2083,7 @@ void QETProject::removeElementAutoNum(const QString& key)
|
||||
{
|
||||
m_element_autonum.remove(key);
|
||||
m_element_autonum_id.remove(key);
|
||||
writeNumberingRows();
|
||||
emit elementAutoNumRemoved(key);
|
||||
}
|
||||
|
||||
@@ -2080,6 +2094,7 @@ void QETProject::removeElementAutoNum(const QString& key)
|
||||
*/
|
||||
void QETProject::removeFolioAutoNum(const QString& key) {
|
||||
m_folio_autonum.remove(key);
|
||||
writeNumberingRows();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2094,6 +2109,7 @@ void QETProject::removeCableAutoNum(const QString& key)
|
||||
m_current_cable_autonum = m_cable_autonum.isEmpty()
|
||||
? QString() : m_cable_autonum.keys().first();
|
||||
}
|
||||
writeNumberingRows();
|
||||
emit autoNumContextUpdated();
|
||||
}
|
||||
|
||||
@@ -2186,6 +2202,7 @@ bool QETProject::isFreezeNewConductors()
|
||||
*/
|
||||
void QETProject::setFreezeNewConductors(bool set) {
|
||||
m_freeze_new_conductors = set;
|
||||
writeNumberingRows();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2230,6 +2247,7 @@ bool QETProject::isFreezeNewElements()
|
||||
*/
|
||||
void QETProject::setFreezeNewElements(bool set) {
|
||||
m_freeze_new_elements = set;
|
||||
writeNumberingRows();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2363,6 +2381,7 @@ void QETProject::setAutoBreakConductor(bool abc)
|
||||
{
|
||||
if (abc != m_auto_break_conductor)
|
||||
m_auto_break_conductor = abc;
|
||||
writeNumberingRows();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4044,6 +4063,7 @@ void QETProject::readDefaultPropertiesXml(QDomDocument &xml_project)
|
||||
m_default_guides.append(g);
|
||||
}
|
||||
}
|
||||
writeNumberingRows();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4227,21 +4247,116 @@ void QETProject::writeDefaultPropertiesXml(QDomElement &xml_element)
|
||||
}
|
||||
xml_element.appendChild(xrefs_elmt);
|
||||
|
||||
writeNumberingXml(numberingOfProject(), xml_element);
|
||||
//QET_CHECK_NUMBERING_ROWS=1: say whether the project database's
|
||||
//numbering rows write what the project writes (QETZ-DB-FIRST stage
|
||||
//2b-1). A test and debugging aid; it changes nothing.
|
||||
if (qEnvironmentVariableIntValue("QET_CHECK_NUMBERING_ROWS") == 1) {
|
||||
QDomDocument from_project, from_rows;
|
||||
QDomElement project_root = from_project.createElement(QStringLiteral("numbering"));
|
||||
QDomElement rows_root = from_rows.createElement(QStringLiteral("numbering"));
|
||||
from_project.appendChild(project_root);
|
||||
from_rows.appendChild(rows_root);
|
||||
writeNumberingXml(numberingOfProject(), project_root);
|
||||
writeNumberingXml(m_data_base.numbering(), rows_root);
|
||||
const bool same = from_project.toString() == from_rows.toString();
|
||||
qWarning().noquote() << "numbering rows:" << (same ? 0 : 1) << "differ";
|
||||
}
|
||||
|
||||
// Export default guides
|
||||
QDomElement guides_elmt = xml_document.createElement("guides");
|
||||
for (const auto &g : m_default_guides) {
|
||||
QDomElement guide_elmt = xml_document.createElement("guide");
|
||||
guide_elmt.setAttribute("orientation", static_cast<int>(g.orientation));
|
||||
guide_elmt.setAttribute("position", g.position);
|
||||
guide_elmt.setAttribute("color", g.color.name());
|
||||
guides_elmt.appendChild(guide_elmt);
|
||||
}
|
||||
xml_element.appendChild(guides_elmt);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETProject::numberingOfProject
|
||||
@return the project's numbering schemes and their settings, as the
|
||||
project holds them, for the project database's numbering tables
|
||||
(QETZ-DB-FIRST stage 2b) and for the save
|
||||
*/
|
||||
projectDataBase::Numbering QETProject::numberingOfProject() const
|
||||
{
|
||||
projectDataBase::Numbering numbering;
|
||||
auto add = [&numbering](const QString &kind, const QHash<QString, NumerotationContext> &schemes,
|
||||
const QHash<QString, QUuid> &ids) {
|
||||
for (auto it = schemes.cbegin() ; it != schemes.cend() ; ++it)
|
||||
numbering.schemes << projectDataBase::NumberingScheme{kind, it.key(), ids.value(it.key()), it.value()};
|
||||
};
|
||||
add(QStringLiteral("conductor"), m_conductor_autonum, {});
|
||||
add(QStringLiteral("folio"), m_folio_autonum, {});
|
||||
add(QStringLiteral("element"), m_element_autonum, m_element_autonum_id);
|
||||
add(QStringLiteral("cable"), m_cable_autonum, {});
|
||||
numbering.current_conductor = m_current_conductor_autonum;
|
||||
numbering.current_element = m_current_element_autonum;
|
||||
numbering.current_cable = m_current_cable_autonum;
|
||||
numbering.freeze_new_conductors = m_freeze_new_conductors;
|
||||
numbering.freeze_new_elements = m_freeze_new_elements;
|
||||
numbering.auto_break_conductors = m_auto_break_conductor;
|
||||
numbering.cable_x_axis_first = m_cable_axis_x_first;
|
||||
numbering.cable_ask_numbering = m_cable_ask_numbering;
|
||||
return numbering;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETProject::writeNumberingRows
|
||||
Write the project's numbering into the project database's numbering
|
||||
tables (QETZ-DB-FIRST stage 2b-1): after reading the file and after
|
||||
each change of the numbering, so the rows are always what the save
|
||||
writes (QET_CHECK_NUMBERING_ROWS checks it)
|
||||
*/
|
||||
void QETProject::writeNumberingRows()
|
||||
{
|
||||
m_data_base.setNumbering(numberingOfProject());
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETProject::writeNumberingXml
|
||||
Export @p numbering as the <conductors_autonums>, <folio_autonums>,
|
||||
<element_autonums> and <cable_autonums> children of @p xml_element
|
||||
*/
|
||||
void QETProject::writeNumberingXml(const projectDataBase::Numbering &numbering,
|
||||
QDomElement &xml_element)
|
||||
{
|
||||
QDomDocument xml_document = xml_element.ownerDocument();
|
||||
//Sorted, as the xrefs are: the schemes come in no particular order
|
||||
//(they were QHash, whose key order is randomised per process), so
|
||||
//an unsorted write reorders these children on every save.
|
||||
auto schemes = [&numbering](const QString &kind) {
|
||||
QMap<QString, projectDataBase::NumberingScheme> sorted;
|
||||
QStringList titles;
|
||||
for (const auto &scheme : numbering.schemes) {
|
||||
if (scheme.kind == kind) {
|
||||
sorted.insert(scheme.title, scheme);
|
||||
titles << scheme.title;
|
||||
}
|
||||
}
|
||||
titles.sort();
|
||||
QList<projectDataBase::NumberingScheme> list;
|
||||
for (const QString &title : std::as_const(titles))
|
||||
list << sorted.value(title);
|
||||
return list;
|
||||
};
|
||||
auto formula = [](const projectDataBase::NumberingScheme &scheme) {
|
||||
return autonum::numerotationContextToFormula(scheme.context);
|
||||
};
|
||||
|
||||
//Export Conductor Autonums
|
||||
QDomElement conductor_autonums = xml_document.createElement("conductors_autonums");
|
||||
conductor_autonums.setAttribute("current_autonum", m_current_conductor_autonum);
|
||||
conductor_autonums.setAttribute("freeze_new_conductors", m_freeze_new_conductors ? "true" : "false");
|
||||
conductor_autonums.setAttribute("auto_break_conductors", m_auto_break_conductor ? "true" : "false");
|
||||
//Sorted for the same reason as the xrefs above: these three
|
||||
//collections are QHash, whose key order is randomised per process,
|
||||
//so an unsorted write reorders these children on every save.
|
||||
QStringList conductor_autonum_keys = conductorAutoNum().keys();
|
||||
conductor_autonum_keys.sort();
|
||||
for (const QString &key : std::as_const(conductor_autonum_keys)) {
|
||||
QDomElement conductor_autonum = conductorAutoNum(key).toXml(xml_document, "conductor_autonum");
|
||||
if (key != "" && conductorAutoNumFormula(key) != "") {
|
||||
conductor_autonum.setAttribute("title", key);
|
||||
conductor_autonum.setAttribute("formula", conductorAutoNumFormula(key));
|
||||
conductor_autonums.setAttribute("current_autonum", numbering.current_conductor);
|
||||
conductor_autonums.setAttribute("freeze_new_conductors", numbering.freeze_new_conductors ? "true" : "false");
|
||||
conductor_autonums.setAttribute("auto_break_conductors", numbering.auto_break_conductors ? "true" : "false");
|
||||
for (auto scheme : schemes(QStringLiteral("conductor"))) {
|
||||
QDomElement conductor_autonum = scheme.context.toXml(xml_document, "conductor_autonum");
|
||||
if (scheme.title != "" && formula(scheme) != "") {
|
||||
conductor_autonum.setAttribute("title", scheme.title);
|
||||
conductor_autonum.setAttribute("formula", formula(scheme));
|
||||
conductor_autonums.appendChild(conductor_autonum);
|
||||
}
|
||||
}
|
||||
@@ -4249,31 +4364,30 @@ void QETProject::writeDefaultPropertiesXml(QDomElement &xml_element)
|
||||
|
||||
//Export Folio Autonums
|
||||
QDomElement folio_autonums = xml_document.createElement("folio_autonums");
|
||||
QStringList folio_autonum_keys = folioAutoNum().keys();
|
||||
folio_autonum_keys.sort();
|
||||
for (const QString &key : std::as_const(folio_autonum_keys)) {
|
||||
QDomElement folio_autonum = folioAutoNum(key).toXml(xml_document, "folio_autonum");
|
||||
folio_autonum.setAttribute("title", key);
|
||||
for (auto scheme : schemes(QStringLiteral("folio"))) {
|
||||
QDomElement folio_autonum = scheme.context.toXml(xml_document, "folio_autonum");
|
||||
folio_autonum.setAttribute("title", scheme.title);
|
||||
folio_autonums.appendChild(folio_autonum);
|
||||
}
|
||||
xml_element.appendChild(folio_autonums);
|
||||
|
||||
//Export Element Autonums
|
||||
const QList<projectDataBase::NumberingScheme> element_schemes = schemes(QStringLiteral("element"));
|
||||
QUuid current_element_id;
|
||||
for (const auto &scheme : element_schemes)
|
||||
if (scheme.title == numbering.current_element) current_element_id = scheme.uuid;
|
||||
QDomElement element_autonums = xml_document.createElement("element_autonums");
|
||||
element_autonums.setAttribute("current_autonum", m_current_element_autonum);
|
||||
if (!elementAutoNumId(m_current_element_autonum).isNull()) {
|
||||
element_autonums.setAttribute("current_autonum_id",
|
||||
elementAutoNumId(m_current_element_autonum).toString());
|
||||
element_autonums.setAttribute("current_autonum", numbering.current_element);
|
||||
if (!current_element_id.isNull()) {
|
||||
element_autonums.setAttribute("current_autonum_id", current_element_id.toString());
|
||||
}
|
||||
element_autonums.setAttribute("freeze_new_elements", m_freeze_new_elements ? "true" : "false");
|
||||
QStringList element_autonum_keys = elementAutoNum().keys();
|
||||
element_autonum_keys.sort();
|
||||
for (const QString &key : std::as_const(element_autonum_keys)) {
|
||||
QDomElement element_autonum = elementAutoNum(key).toXml(xml_document, "element_autonum");
|
||||
if (key != "" && elementAutoNumFormula(key) != "") {
|
||||
element_autonum.setAttribute("title", key);
|
||||
element_autonum.setAttribute("id", elementAutoNumId(key).toString());
|
||||
element_autonum.setAttribute("formula", elementAutoNumFormula(key));
|
||||
element_autonums.setAttribute("freeze_new_elements", numbering.freeze_new_elements ? "true" : "false");
|
||||
for (auto scheme : element_schemes) {
|
||||
QDomElement element_autonum = scheme.context.toXml(xml_document, "element_autonum");
|
||||
if (scheme.title != "" && formula(scheme) != "") {
|
||||
element_autonum.setAttribute("title", scheme.title);
|
||||
element_autonum.setAttribute("id", scheme.uuid.toString());
|
||||
element_autonum.setAttribute("formula", formula(scheme));
|
||||
element_autonums.appendChild(element_autonum);
|
||||
}
|
||||
}
|
||||
@@ -4293,23 +4407,21 @@ void QETProject::writeDefaultPropertiesXml(QDomElement &xml_element)
|
||||
//drawn, an axis chosen before it, and the numbering question
|
||||
//answered with no are answers only this element can carry.
|
||||
QDomElement cable_autonums = xml_document.createElement("cable_autonums");
|
||||
cable_autonums.setAttribute("current_autonum", m_current_cable_autonum);
|
||||
cable_autonums.setAttribute("current_autonum", numbering.current_cable);
|
||||
cable_autonums.setAttribute("axis_priority",
|
||||
m_cable_axis_x_first ? "x" : "y");
|
||||
numbering.cable_x_axis_first ? "x" : "y");
|
||||
//Only the no is written down: a project which has not answered
|
||||
//the numbering question yet asks again, so silence in the file
|
||||
//means asking rather than holding back.
|
||||
if (!m_cable_ask_numbering) {
|
||||
if (!numbering.cable_ask_numbering) {
|
||||
cable_autonums.setAttribute("ask_numbering_rule", "false");
|
||||
}
|
||||
int written_cable_rules = 0;
|
||||
QStringList cable_autonum_keys = cableAutoNum().keys();
|
||||
cable_autonum_keys.sort();
|
||||
for (const QString &key : std::as_const(cable_autonum_keys)) {
|
||||
QDomElement cable_autonum = cableAutoNum(key).toXml(xml_document, "cable_autonum");
|
||||
if (key != "" && cableAutoNumFormula(key) != "") {
|
||||
cable_autonum.setAttribute("title", key);
|
||||
cable_autonum.setAttribute("formula", cableAutoNumFormula(key));
|
||||
for (auto scheme : schemes(QStringLiteral("cable"))) {
|
||||
QDomElement cable_autonum = scheme.context.toXml(xml_document, "cable_autonum");
|
||||
if (scheme.title != "" && formula(scheme) != "") {
|
||||
cable_autonum.setAttribute("title", scheme.title);
|
||||
cable_autonum.setAttribute("formula", formula(scheme));
|
||||
cable_autonums.appendChild(cable_autonum);
|
||||
++written_cable_rules;
|
||||
}
|
||||
@@ -4318,23 +4430,12 @@ void QETProject::writeDefaultPropertiesXml(QDomElement &xml_element)
|
||||
//chose an axis other than the default and has not answered the
|
||||
//numbering question with no -- then this element would say
|
||||
//nothing the reader does not assume anyway.
|
||||
if (!m_current_cable_autonum.isEmpty()
|
||||
|| !m_cable_ask_numbering
|
||||
|| !m_cable_axis_x_first
|
||||
if (!numbering.current_cable.isEmpty()
|
||||
|| !numbering.cable_ask_numbering
|
||||
|| !numbering.cable_x_axis_first
|
||||
|| written_cable_rules > 0) {
|
||||
xml_element.appendChild(cable_autonums);
|
||||
}
|
||||
|
||||
// Export default guides
|
||||
QDomElement guides_elmt = xml_document.createElement("guides");
|
||||
for (const auto &g : m_default_guides) {
|
||||
QDomElement guide_elmt = xml_document.createElement("guide");
|
||||
guide_elmt.setAttribute("orientation", static_cast<int>(g.orientation));
|
||||
guide_elmt.setAttribute("position", g.position);
|
||||
guide_elmt.setAttribute("color", g.color.name());
|
||||
guides_elmt.appendChild(guide_elmt);
|
||||
}
|
||||
xml_element.appendChild(guides_elmt);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -457,6 +457,10 @@ class QETProject : public QObject
|
||||
|
||||
void writeProjectPropertiesXml(QDomElement &);
|
||||
void writeDefaultPropertiesXml(QDomElement &);
|
||||
projectDataBase::Numbering numberingOfProject() const;
|
||||
void writeNumberingRows();
|
||||
static void writeNumberingXml(const projectDataBase::Numbering &numbering,
|
||||
QDomElement &xml_element);
|
||||
void writeUsageXml(QDomElement &);
|
||||
void writeWireHopsXml(QDomElement &);
|
||||
void writeSymbolTextsXml(QDomElement &);
|
||||
|
||||
@@ -42,6 +42,7 @@ class tst_elementautonumids : public QObject
|
||||
int m_run = 0;
|
||||
|
||||
QString m_preferences; // contents of the settings file of the next run
|
||||
bool m_check_numbering = false; // QET_CHECK_NUMBERING_ROWS for the runs
|
||||
|
||||
QProcessEnvironment environment()
|
||||
{
|
||||
@@ -61,6 +62,9 @@ class tst_elementautonumids : public QObject
|
||||
env.insert(QStringLiteral("QET_SETTINGS_DIR"), settings_dir);
|
||||
env.insert(QStringLiteral("QT_QPA_PLATFORM"), QStringLiteral("offscreen"));
|
||||
env.insert(QStringLiteral("QET_ENABLE_SCRIPTING"), QStringLiteral("1"));
|
||||
if (m_check_numbering) {
|
||||
env.insert(QStringLiteral("QET_CHECK_NUMBERING_ROWS"), QStringLiteral("1"));
|
||||
}
|
||||
env.insert(QStringLiteral("HOME"), home);
|
||||
env.insert(QStringLiteral("XDG_CONFIG_HOME"), home + QStringLiteral("/config"));
|
||||
env.insert(QStringLiteral("XDG_DATA_HOME"), home + QStringLiteral("/data"));
|
||||
@@ -725,6 +729,62 @@ qet.log('PROBE ' + JSON.stringify(r));
|
||||
// the folios which read the numbering with it (26 folios of
|
||||
// industrial.qet read "Wire"), a numbering which folios read cannot be
|
||||
// removed, an unused one can, and every step is one undo.
|
||||
// The project database's numbering rows (QETZ-DB-FIRST stage 2b-1)
|
||||
// follow every change of the numbering: each save below writes the
|
||||
// numbering from the project and from the rows, and the two must be
|
||||
// the same (QET_CHECK_NUMBERING_ROWS). A scheme of each kind added,
|
||||
// renamed, removed, undone and redone, then made current; a
|
||||
// renumbering and its undo.
|
||||
void numberingRowsFollowEveryChange()
|
||||
{
|
||||
const QString saved = m_dir.filePath(QStringLiteral("numbering-rows.qet"));
|
||||
const QString script = QStringLiteral(R"JS(
|
||||
var saves = 0;
|
||||
function save() { if (qet.save(%1)) saves++; }
|
||||
save();
|
||||
['conductor', 'element', 'folio'].forEach(function (k) {
|
||||
qet.addAutoNum(k, 'Rows ' + k, ['string:R-', 'unit:7:2']); save();
|
||||
qet.renameAutoNum(k, 'Rows ' + k, 'Rows renamed ' + k); save();
|
||||
qet.undo(); save();
|
||||
qet.redo(); save();
|
||||
});
|
||||
['conductor', 'element', 'folio'].forEach(function (k) {
|
||||
qet.removeAutoNum(k, 'Rows renamed ' + k); save();
|
||||
qet.undo(); save();
|
||||
});
|
||||
qet.useElementAutoNum('Rows renamed element'); save();
|
||||
qet.useConductorAutoNum(0, 'Rows renamed conductor'); save();
|
||||
var schemes = qet.autoNums('element');
|
||||
qet.renumberElementAutoNum(schemes[0].split(': formula=')[0]); save();
|
||||
qet.undo(); save();
|
||||
qet.log('PROBE ' + JSON.stringify({saves: saves}));
|
||||
)JS").arg(QStringLiteral("'") + saved + QStringLiteral("'"));
|
||||
|
||||
m_check_numbering = true;
|
||||
const QString path = m_dir.filePath(QStringLiteral("probe%1.js").arg(m_run));
|
||||
QFile f(path);
|
||||
QVERIFY(f.open(QIODevice::WriteOnly));
|
||||
f.write(script.toUtf8());
|
||||
f.close();
|
||||
QProcess proc;
|
||||
proc.setProcessEnvironment(environment());
|
||||
m_check_numbering = false;
|
||||
proc.start(QStringLiteral(QET_TEST_BINARY_PATH),
|
||||
{QStringLiteral("--run"), path, QStringLiteral(QET_EXAMPLES_DIR "/industrial.qet")});
|
||||
QVERIFY(proc.waitForFinished(180000));
|
||||
const QString out = QString::fromUtf8(proc.readAllStandardOutput() + proc.readAllStandardError());
|
||||
|
||||
QVERIFY2(out.contains(QLatin1String("PROBE {\"saves\":23}")), qPrintable(out.right(2000)));
|
||||
QCOMPARE(out.count(QLatin1String("numbering rows: 0 differ")), 23);
|
||||
QCOMPARE(out.count(QLatin1String("numbering rows:")), 23);
|
||||
// the changes are in the file: the folio numbering's removal was
|
||||
// undone, the wires of the first folio follow the new numbering
|
||||
const QByteArray xml = read(saved);
|
||||
QVERIFY(xml.contains("title=\"Rows renamed folio\""));
|
||||
QCOMPARE(diagramAttributes(xml, QStringLiteral("conductorAutonum")).value(0),
|
||||
QStringLiteral("Rows renamed conductor"));
|
||||
}
|
||||
|
||||
void conductorNumberings()
|
||||
{
|
||||
const QString saved = m_dir.filePath(QStringLiteral("conductors.qet"));
|
||||
|
||||
Reference in New Issue
Block a user