Use uuid instead of an index to connect multiple elements

This commit is contained in:
Martin Marmsoler 2020-05-26 18:47:24 +02:00 committed by Laurent Trinques
parent c2e17daab9
commit af989b1cd8
7 changed files with 117 additions and 42 deletions

View File

@ -863,6 +863,53 @@ bool Diagram::initFromXml(QDomElement &document, QPointF position, bool consider
return(from_xml); return(from_xml);
} }
/*!
* \brief findTerminal
* Find terminal to which the conductor should be connected
* \param conductor_index 1 or 2 depending on which terminal is searched
* \param f Conductor xml element
* \param table_adr_id Hash table to all terminal id assignement (legacy)
* \param added_elements Elements found in the xml file
* \return
*/
Terminal* findTerminal(int conductor_index, QDomElement& f, QHash<int, Terminal *>& table_adr_id, QList<Element *>& added_elements) {
assert(conductor_index == 1 || conductor_index == 2);
QString element_index = "element" + QString::number(conductor_index);
QString terminal_index = "terminal" + QString::number(conductor_index);
if (f.hasAttribute(element_index)) {
QUuid element_uuid = QUuid(f.attribute(element_index));
// element1 did not exist in the conductor part of the xml until prior 0.7
// It is used as an indicator that uuid's are used to identify terminals
bool element_found = false;
foreach (auto element, added_elements) {
if (element->uuid() != element_uuid)
continue;
element_found = true;
QUuid terminal_uuid = QUuid(f.attribute(terminal_index));
foreach (auto terminal, element->terminals()) {
if (terminal->uuid() != terminal_uuid)
continue;
return terminal;
}
qDebug() << "Diagram::fromXml() : "<< terminal_index << ":" << terminal_uuid << "not found in " << element_index << ":" << element_uuid;
break;
}
if (!element_found)
qDebug() << "Diagram::fromXml() : " << element_index << ": " << element_uuid << "not found";
} else {
// Backward compatibility. Until version 0.7 a generated id is used to link the terminal.
int id_p1 = f.attribute(terminal_index).toInt();
if (!table_adr_id.contains(id_p1)) {
qDebug() << "Diagram::fromXml() : terminal id " << id_p1 << " not found";
} else
return table_adr_id.value(id_p1);
}
return nullptr;
}
/** /**
Importe le schema decrit dans un element XML. Si une position est Importe le schema decrit dans un element XML. Si une position est
precisee, les elements importes sont positionnes de maniere a ce que le precisee, les elements importes sont positionnes de maniere a ce que le
@ -1031,13 +1078,11 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf
if (!Conductor::valideXml(f)) continue; if (!Conductor::valideXml(f)) continue;
//Check if terminal that conductor must be linked is know //Check if terminal that conductor must be linked is know
int id_p1 = f.attribute("terminal1").toInt();
int id_p2 = f.attribute("terminal2").toInt(); Terminal* p1 = findTerminal(1, f, table_adr_id, added_elements);
if (table_adr_id.contains(id_p1) && table_adr_id.contains(id_p2)) Terminal* p2 = findTerminal(2, f, table_adr_id, added_elements);
{
Terminal *p1 = table_adr_id.value(id_p1); if (p1 && p2 && p1 != p2)
Terminal *p2 = table_adr_id.value(id_p2);
if (p1 != p2)
{ {
Conductor *c = new Conductor(p1, p2); Conductor *c = new Conductor(p1, p2);
if (c->isValid()) if (c->isValid())
@ -1050,8 +1095,6 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf
delete c; delete c;
} }
} }
else qDebug() << "Diagram::fromXml() : Le chargement du conducteur" << id_p1 << id_p2 << "a echoue";
}
//Load tables //Load tables
QVector<QetGraphicsTableItem *> added_tables; QVector<QetGraphicsTableItem *> added_tables;

View File

@ -5,14 +5,17 @@
TerminalData::TerminalData(): TerminalData::TerminalData():
PropertiesInterface() PropertiesInterface()
{ {
init();
} }
TerminalData::TerminalData(QGraphicsObject *parent): TerminalData::TerminalData(QGraphicsObject *parent):
PropertiesInterface(), PropertiesInterface(),
q(parent) q(parent)
{ {
init();
}
void TerminalData::init() {
} }
TerminalData::~TerminalData() TerminalData::~TerminalData()
@ -69,7 +72,8 @@ bool TerminalData::fromXml (const QDomElement &xml_element)
QString uuid = xml_element.attribute("uuid"); QString uuid = xml_element.attribute("uuid");
// update part and add uuid, which is used in the new version to connect terminals together // update part and add uuid, which is used in the new version to connect terminals together
// if the attribute not exists, in the constructor of PartTerminal already one is created // if the attribute not exists, means, the element is created with an older version of qet. So use the legacy approach
// to identify terminals
if (!uuid.isEmpty()) if (!uuid.isEmpty())
m_uuid = QUuid(uuid); m_uuid = QUuid(uuid);

View File

@ -21,6 +21,8 @@ public:
TerminalData(QGraphicsObject* parent); TerminalData(QGraphicsObject* parent);
~TerminalData(); ~TerminalData();
void init();
void setParent(QGraphicsObject* parent); void setParent(QGraphicsObject* parent);
// Save/load properties to setting file. QString is use for prefix a word befor the name of each paramètre // Save/load properties to setting file. QString is use for prefix a word befor the name of each paramètre

View File

@ -582,12 +582,26 @@ bool Conductor::valideXml(QDomElement &e){
bool conv_ok; bool conv_ok;
// parse l'abscisse // parse l'abscisse
if (e.hasAttribute("element1")) {
if (QUuid(e.attribute("element1")).isNull())
return false;
if (QUuid(e.attribute("terminal1")).isNull())
return false;
} else {
e.attribute("terminal1").toInt(&conv_ok); e.attribute("terminal1").toInt(&conv_ok);
if (!conv_ok) return(false); if (!conv_ok) return(false);
}
// parse l'ordonnee // parse l'ordonnee
if (e.hasAttribute("element2")) {
if (QUuid(e.attribute("element2")).isNull())
return false;
if (QUuid(e.attribute("terminal2")).isNull())
return false;
} else {
e.attribute("terminal2").toInt(&conv_ok); e.attribute("terminal2").toInt(&conv_ok);
if (!conv_ok) return(false); if (!conv_ok) return(false);
}
return(true); return(true);
} }
@ -996,8 +1010,23 @@ QDomElement Conductor::toXml(QDomDocument &dom_document, QHash<Terminal *, int>
dom_element.setAttribute("x", QString::number(pos().x())); dom_element.setAttribute("x", QString::number(pos().x()));
dom_element.setAttribute("y", QString::number(pos().y())); dom_element.setAttribute("y", QString::number(pos().y()));
dom_element.setAttribute("terminal1", table_adr_id.value(terminal1));
dom_element.setAttribute("terminal2", table_adr_id.value(terminal2)); // Terminal is uniquely identified by the uuid of the terminal and the element
if (terminal1->uuid().isNull()) {
// legacy method to identify the terminal
dom_element.setAttribute("terminal1", table_adr_id.value(terminal1)); // for backward compability
} else {
dom_element.setAttribute("element1", terminal1->parentElement()->uuid().toString());
dom_element.setAttribute("terminal1", terminal1->uuid().toString());
}
if (terminal2->uuid().isNull()) {
// legacy method to identify the terminal
dom_element.setAttribute("terminal2", table_adr_id.value(terminal2)); // for backward compability
} else {
dom_element.setAttribute("element2", terminal2->parentElement()->uuid().toString());
dom_element.setAttribute("terminal2", terminal2->uuid().toString());
}
dom_element.setAttribute("freezeLabel", m_freeze_label? "true" : "false"); dom_element.setAttribute("freezeLabel", m_freeze_label? "true" : "false");
// on n'exporte les segments du conducteur que si ceux-ci ont // on n'exporte les segments du conducteur que si ceux-ci ont
@ -1033,7 +1062,8 @@ QDomElement Conductor::toXml(QDomDocument &dom_document, QHash<Terminal *, int>
/** /**
* @brief Conductor::pathFromXml * @brief Conductor::pathFromXml
* Generate the path from xml file * Generate the path (of the line) from xml file by checking the segments in the xml
* file
* @param e * @param e
* @return true if generate path success else return false * @return true if generate path success else return false
*/ */

View File

@ -1047,7 +1047,7 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
foreach(Terminal *t, terminals()) { foreach(Terminal *t, terminals()) {
// alors on enregistre la borne // alors on enregistre la borne
QDomElement terminal = t -> toXml(document); QDomElement terminal = t -> toXml(document);
terminal.setAttribute("id", id_terminal); terminal.setAttribute("id", id_terminal); // for backward compatibility
table_adr_id.insert(t, id_terminal ++); table_adr_id.insert(t, id_terminal ++);
xml_terminals.appendChild(terminal); xml_terminals.appendChild(terminal);
} }

View File

@ -43,7 +43,6 @@ const qreal Terminal::Z = 1000;
void Terminal::init(QString number, QString name, bool hiddenName) { void Terminal::init(QString number, QString name, bool hiddenName) {
hovered_color_ = Terminal::neutralColor; hovered_color_ = Terminal::neutralColor;
m_uuid = QUuid::createUuid();
// calcul de la position du point d'amarrage a l'element // calcul de la position du point d'amarrage a l'element
dock_elmt_ = d->m_pos; dock_elmt_ = d->m_pos;
@ -709,13 +708,12 @@ QList<Conductor *> Terminal::conductors() const {
*/ */
QDomElement Terminal::toXml(QDomDocument &doc) const { QDomElement Terminal::toXml(QDomDocument &doc) const {
QDomElement qdo = doc.createElement("terminal"); QDomElement qdo = doc.createElement("terminal");
qdo.setAttribute("x", QString("%1").arg(dock_elmt_.x())); qdo.setAttribute("x", QString("%1").arg(dock_elmt_.x())); // for backward compatibility
qdo.setAttribute("y", QString("%1").arg(dock_elmt_.y())); qdo.setAttribute("y", QString("%1").arg(dock_elmt_.y()));// for backward compatibility
qdo.setAttribute("orientation", d->m_orientation); qdo.setAttribute("orientation", d->m_orientation);
qdo.setAttribute("number", number_terminal_); qdo.setAttribute("number", number_terminal_);
qdo.setAttribute("name", name_terminal_); qdo.setAttribute("name", name_terminal_);
qdo.setAttribute("nameHidden", name_terminal_hidden); qdo.setAttribute("nameHidden", name_terminal_hidden);
qdo.setAttribute("uuid", m_uuid.toString());
return(qdo); return(qdo);
} }
@ -764,9 +762,6 @@ bool Terminal::fromXml(QDomElement &terminal) {
number_terminal_ = terminal.attribute("number"); number_terminal_ = terminal.attribute("number");
name_terminal_ = terminal.attribute("name"); name_terminal_ = terminal.attribute("name");
name_terminal_hidden = terminal.attribute("nameHidden").toInt(); name_terminal_hidden = terminal.attribute("nameHidden").toInt();
QString uuid = terminal.attribute("uuid");
if (!uuid.isEmpty())
m_uuid = uuid;
return ( return (
qFuzzyCompare(terminal.attribute("x").toDouble(), dock_elmt_.x()) && qFuzzyCompare(terminal.attribute("x").toDouble(), dock_elmt_.x()) &&
@ -797,6 +792,10 @@ Element *Terminal::parentElement() const {
return(parent_element_); return(parent_element_);
} }
QUuid Terminal::uuid() const {
return d->m_uuid;
}
/** /**
* @brief Conductor::relatedPotentialTerminal * @brief Conductor::relatedPotentialTerminal
* Return terminal at the same potential from the same * Return terminal at the same potential from the same

View File

@ -67,6 +67,7 @@ class Terminal : public QGraphicsObject
int conductorsCount () const; int conductorsCount () const;
Diagram *diagram () const; Diagram *diagram () const;
Element *parentElement () const; Element *parentElement () const;
QUuid uuid () const;
QList<Conductor *> conductors() const; QList<Conductor *> conductors() const;
Qet::Orientation orientation() const; Qet::Orientation orientation() const;
@ -139,10 +140,6 @@ class Terminal : public QGraphicsObject
QString name_terminal_; QString name_terminal_;
bool name_terminal_hidden; bool name_terminal_hidden;
/// Unique identifier of the terminal
/// This uuid is different to the uuid of the part terminal it represents
QUuid m_uuid;
private: private:
void init(QString number, QString name, bool hiddenName); void init(QString number, QString name, bool hiddenName);
void init(QPointF pf, Qet::Orientation o, QString number, QString name, bool hiddenName); void init(QPointF pf, Qet::Orientation o, QString number, QString name, bool hiddenName);