mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-11 14:44:15 +02:00
Merge pull request #1248 from ispyisail/feature/wiring-terminal-identity
Add terminal index and uuid to the wiring list export
This commit is contained in:
@@ -620,6 +620,12 @@ QHash<Element *, int> folioIndex(QETProject &project)
|
||||
/// From-to wiring list: one row per conductor, each endpoint resolved to its
|
||||
/// element label and terminal name.
|
||||
///
|
||||
/// Most symbols leave their terminals unnamed, so each end also carries the
|
||||
/// terminal's index -- the one the scripting API's addConductor() takes,
|
||||
/// empty for two terminals at one point -- and its uuid, the one the project
|
||||
/// file names the terminal by. These come last, after the columns the list
|
||||
/// has always had, so a reader of those is not disturbed.
|
||||
///
|
||||
/// Reads wiring_list_view out of the project database. --export-cables produces
|
||||
/// the same logical list from the document XML instead, and the two are meant
|
||||
/// to agree: running both and diffing them is a direct check that the database
|
||||
@@ -632,7 +638,8 @@ int exportWiring(QETProject &project, const QString &output)
|
||||
|
||||
static const QStringList columns {
|
||||
"wire_number", "from_element_label", "from_terminal",
|
||||
"to_element_label", "to_terminal", "diagram_position", "conductor_uuid"
|
||||
"to_element_label", "to_terminal", "diagram_position", "conductor_uuid",
|
||||
"from_terminal_index", "from_terminal_uuid", "to_terminal_index", "to_terminal_uuid"
|
||||
};
|
||||
|
||||
QSqlQuery query = project.dataBase()->newQuery(
|
||||
|
||||
@@ -180,8 +180,37 @@ struct DocumentTerminal
|
||||
QString uuid;
|
||||
QString name;
|
||||
bool master_label = false;
|
||||
QVariant index;
|
||||
};
|
||||
|
||||
//The index each of @p points has in Element::terminals() -- the index
|
||||
//the scripting API's addConductor() and conductor calls take -- or a
|
||||
//null QVariant for a point another terminal shares. Element::
|
||||
//parseTerminal() sorts the list top to bottom, then left to right, on
|
||||
//each terminal's position in its definition, and the sort is not
|
||||
//stable, so which of two terminals at the same point comes first is
|
||||
//not defined: no index is given rather than one that can change.
|
||||
QList<QVariant> terminalIndexes(const QList<QPointF> &points)
|
||||
{
|
||||
QList<int> order;
|
||||
for (int i = 0 ; i < points.size() ; ++i) {
|
||||
order << i;
|
||||
}
|
||||
std::stable_sort(order.begin(), order.end(), [&points](int a, int b) {
|
||||
if (points.at(a).y() == points.at(b).y()) {
|
||||
return points.at(a).x() < points.at(b).x();
|
||||
}
|
||||
return points.at(a).y() < points.at(b).y();
|
||||
});
|
||||
QList<QVariant> indexes(points.size());
|
||||
for (int i = 0 ; i < order.size() ; ++i) {
|
||||
if (points.count(points.at(order.at(i))) == 1) {
|
||||
indexes[order.at(i)] = i;
|
||||
}
|
||||
}
|
||||
return indexes;
|
||||
}
|
||||
|
||||
struct DocumentDefinition
|
||||
{
|
||||
QString type;
|
||||
@@ -391,6 +420,25 @@ bool projectDataBase::populateFromDocument(const QDomDocument &document, QString
|
||||
data.fromXml(definition);
|
||||
read.type = data.typeToString();
|
||||
read.sub_type = data.masterTypeToString();
|
||||
//Every terminal the element is built with counts towards
|
||||
//the indexes, as Element::parseTerminal() keeps every one
|
||||
//whose position reads, in every <description>.
|
||||
QList<QDomElement> parsed;
|
||||
QList<QPointF> points;
|
||||
for (QDomElement d = definition.firstChildElement(QStringLiteral("description")) ;
|
||||
!d.isNull() ; d = d.nextSiblingElement(QStringLiteral("description"))) {
|
||||
for (QDomElement t = d.firstChildElement(QStringLiteral("terminal")) ;
|
||||
!t.isNull() ; t = t.nextSiblingElement(QStringLiteral("terminal")))
|
||||
{
|
||||
qreal x, y;
|
||||
if (QET::attributeIsAReal(t, QStringLiteral("x"), &x)
|
||||
&& QET::attributeIsAReal(t, QStringLiteral("y"), &y)) {
|
||||
parsed << t;
|
||||
points << QPointF(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
const QList<QVariant> indexes = terminalIndexes(points);
|
||||
const QDomElement description = definition.firstChildElement(QStringLiteral("description"));
|
||||
for (QDomElement t = description.firstChildElement(QStringLiteral("terminal")) ;
|
||||
!t.isNull() ; t = t.nextSiblingElement(QStringLiteral("terminal")))
|
||||
@@ -403,6 +451,10 @@ bool projectDataBase::populateFromDocument(const QDomDocument &document, QString
|
||||
terminal.uuid = terminal_uuid.toString();
|
||||
terminal.name = t.attribute(QStringLiteral("name"));
|
||||
terminal.master_label = t.attribute(QStringLiteral("use_master_label")) == QLatin1String("true");
|
||||
const int place = parsed.indexOf(t);
|
||||
if (place >= 0) {
|
||||
terminal.index = indexes.at(place);
|
||||
}
|
||||
read.terminals.insert(terminal_uuid, terminal);
|
||||
}
|
||||
known = definitions.insert(type, read);
|
||||
@@ -582,8 +634,8 @@ bool projectDataBase::populateFromDocument(const QDomDocument &document, QString
|
||||
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);
|
||||
const DocumentTerminal &terminal = owner.terminals.value(QUuid(end.second));
|
||||
insertTerminal(end.second, end.first, terminal.name, terminal.index);
|
||||
}
|
||||
m_insert_conductor_query.bindValue(QStringLiteral(":uuid"), conductor.uuid);
|
||||
m_insert_conductor_query.bindValue(QStringLiteral(":diagram_uuid"), conductor.diagram_uuid);
|
||||
@@ -1560,6 +1612,7 @@ bool projectDataBase::createDataBase()
|
||||
"uuid VARCHAR(50) NOT NULL, "
|
||||
"element_uuid VARCHAR(50) NOT NULL,"
|
||||
"name VARCHAR(50),"
|
||||
"terminal_index INTEGER,"
|
||||
"PRIMARY KEY (uuid, element_uuid),"
|
||||
"FOREIGN KEY (element_uuid) REFERENCES element (uuid)"
|
||||
")");
|
||||
@@ -1812,7 +1865,11 @@ void projectDataBase::createWiringListView()
|
||||
"t2.element_uuid AS to_element_uuid,"
|
||||
"ei2.label AS to_element_label,"
|
||||
"t2.name AS to_terminal,"
|
||||
"d.pos AS diagram_position"
|
||||
"d.pos AS diagram_position,"
|
||||
"t1.uuid AS from_terminal_uuid,"
|
||||
"t1.terminal_index AS from_terminal_index,"
|
||||
"t2.uuid AS to_terminal_uuid,"
|
||||
"t2.terminal_index AS to_terminal_index"
|
||||
" FROM conductor c"
|
||||
" JOIN terminal t1 ON c.terminal1_uuid = t1.uuid AND c.terminal1_element_uuid = t1.element_uuid"
|
||||
" JOIN terminal t2 ON c.terminal2_uuid = t2.uuid AND c.terminal2_element_uuid = t2.element_uuid"
|
||||
@@ -1999,9 +2056,15 @@ void projectDataBase::populateConductorTable()
|
||||
*/
|
||||
void projectDataBase::insertTerminal(Terminal *terminal)
|
||||
{
|
||||
const QList<Terminal *> terminals = terminal->parentElement()->terminals();
|
||||
QList<QPointF> points;
|
||||
for (const Terminal *t : terminals) {
|
||||
points << terminal->parentElement()->mapFromScene(t->dockConductor());
|
||||
}
|
||||
insertTerminal(terminal->stableUuid().toString(),
|
||||
terminal->parentElement()->uuid().toString(),
|
||||
terminal->name());
|
||||
terminal->name(),
|
||||
terminalIndexes(points).value(terminals.indexOf(terminal)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2009,11 +2072,12 @@ void projectDataBase::insertTerminal(Terminal *terminal)
|
||||
insertTerminal(Terminal *) from values rather than a live terminal.
|
||||
*/
|
||||
void projectDataBase::insertTerminal(const QString &uuid, const QString &element_uuid,
|
||||
const QString &name)
|
||||
const QString &name, const QVariant &index)
|
||||
{
|
||||
m_insert_terminal_query.bindValue(":uuid", uuid);
|
||||
m_insert_terminal_query.bindValue(":element_uuid", element_uuid);
|
||||
m_insert_terminal_query.bindValue(":name", name);
|
||||
m_insert_terminal_query.bindValue(":terminal_index", index);
|
||||
if (!m_insert_terminal_query.exec()) {
|
||||
qDebug() << "projectDataBase::insertTerminal insert error : " << m_insert_terminal_query.lastError();
|
||||
}
|
||||
@@ -2146,7 +2210,7 @@ void projectDataBase::prepareQuery()
|
||||
|
||||
//INSERT TERMINAL
|
||||
m_insert_terminal_query = QSqlQuery(m_data_base);
|
||||
m_insert_terminal_query.prepare("INSERT OR IGNORE INTO terminal (uuid, element_uuid, name) VALUES (:uuid, :element_uuid, :name)");
|
||||
m_insert_terminal_query.prepare("INSERT OR IGNORE INTO terminal (uuid, element_uuid, name, terminal_index) VALUES (:uuid, :element_uuid, :name, :terminal_index)");
|
||||
|
||||
//INSERT CONDUCTOR
|
||||
m_insert_conductor_query = QSqlQuery(m_data_base);
|
||||
|
||||
@@ -150,7 +150,7 @@ class projectDataBase : public QObject
|
||||
void watchConductor(Conductor *conductor);
|
||||
void insertTerminal(Terminal *terminal);
|
||||
void insertTerminal(const QString &uuid, const QString &element_uuid,
|
||||
const QString &name);
|
||||
const QString &name, const QVariant &index);
|
||||
void prepareQuery();
|
||||
static QHash<QString, QString> elementInfoToString(
|
||||
Element *elmt);
|
||||
|
||||
Reference in New Issue
Block a user