diff --git a/sources/qetgraphicsitem/dynamicelementtextitem.cpp b/sources/qetgraphicsitem/dynamicelementtextitem.cpp index 2b90e57e5..a4f47b6bb 100644 --- a/sources/qetgraphicsitem/dynamicelementtextitem.cpp +++ b/sources/qetgraphicsitem/dynamicelementtextitem.cpp @@ -49,6 +49,15 @@ DynamicElementTextItem::DynamicElementTextItem(Element *parent_element) : } }); + + //If the parent is slave, we keep aware about the changement of master. + if(parent_element->linkType() == Element::Slave) + { + connect(parent_element, &Element::linkedElementChanged, this, &DynamicElementTextItem::masterChanged); + //The parent is already linked, wa call master changed for init the connection + if(!parent_element->linkedElements().isEmpty()) + masterChanged(); + } } DynamicElementTextItem::~DynamicElementTextItem() @@ -132,10 +141,11 @@ void DynamicElementTextItem::fromXml(const QDomElement &dom_elmt) QMetaEnum me = metaObject()->enumerator(metaObject()->indexOfEnumerator("TextFrom")); m_text_from = DynamicElementTextItem::TextFrom(me.keyToValue(dom_elmt.attribute("text_from").toStdString().data())); - if(m_text_from == ElementInfo) + if(m_text_from == ElementInfo || m_text_from == CompositeText) { setNoEditable(true); - connect(m_parent_element.data(), &Element::elementInfoChange, this, &DynamicElementTextItem::elementInfoChanged); + if (elementUseForInfo()) + connect(elementUseForInfo(), &Element::elementInfoChange, this, &DynamicElementTextItem::elementInfoChanged); } else { setNoEditable(false); @@ -175,6 +185,47 @@ Element *DynamicElementTextItem::parentElement() const { return m_parent_element; } +/** + * @brief DynamicElementTextItem::elementUseForInfo + * @return a pointer to the element we must use for the variable information. + * If this text is owned by a simple element, the simple element is returned, this is the same element returned by the function parentElement(). + * If this text is owned by a master element, the master element is returned, this is the same element returned by the function parentElement(). + * If this text is owned by a report element, the report element is returned, this is the same element returned by the function parentElement(). + * If this text is owned by a terminal element, the terminal element is returned, this is the same element returned by the function parentElement(). + * If this text is owned by a slave element, we return the master element set as master of the parent slave element, + * if the parent slave is not linked to a master, this function return a nullptr. + * If this text have no parent element, return nullptr + */ +Element *DynamicElementTextItem::elementUseForInfo() const +{ + Element *elmt = parentElement(); + if(!elmt) + return nullptr; + + switch (elmt->linkType()) + { + case Element::Simple: + return elmt; + case Element::NextReport: + return elmt; + case Element::PreviousReport: + return elmt; + case Element::Master: + return elmt; + case Element::Slave: + { + if(elmt->linkedElements().isEmpty()) + return nullptr; + else + return elmt->linkedElements().first(); + } + case Element::Terminale: + return elmt; + default: + return elmt; + } +} + /** * @brief DynamicElementTextItem::textFrom * @return what the final text is created from. @@ -190,29 +241,32 @@ DynamicElementTextItem::TextFrom DynamicElementTextItem::textFrom() const { */ void DynamicElementTextItem::setTextFrom(DynamicElementTextItem::TextFrom text_from) { - setNoEditable(text_from == ElementInfo? true : false); + setNoEditable(text_from == UserText? false : true); if(text_from == UserText) { setPlainText(m_text); disconnect(m_parent_element.data(), &Element::elementInfoChange, this, &DynamicElementTextItem::elementInfoChanged); } - else if (text_from == ElementInfo && m_parent_element) + else if (text_from == ElementInfo && elementUseForInfo()) { - setPlainText(m_parent_element->elementInformations().value(m_info_name).toString()); + setPlainText(elementUseForInfo()->elementInformations().value(m_info_name).toString()); if(m_text_from == UserText) - connect(m_parent_element.data(), &Element::elementInfoChange, this, &DynamicElementTextItem::elementInfoChanged); + connect(elementUseForInfo(), &Element::elementInfoChange, this, &DynamicElementTextItem::elementInfoChanged); } - else if (text_from == CompositeText && m_parent_element) + else if (text_from == CompositeText && elementUseForInfo()) { - setPlainText(autonum::AssignVariables::replaceVariable(m_composite_text, m_parent_element->elementInformations())); + setPlainText(autonum::AssignVariables::replaceVariable(m_composite_text, elementUseForInfo()->elementInformations())); if(m_text_from == UserText) - connect(m_parent_element.data(), &Element::elementInfoChange, this, &DynamicElementTextItem::elementInfoChanged); + connect(elementUseForInfo(), &Element::elementInfoChange, this, &DynamicElementTextItem::elementInfoChanged); } - m_text_from = text_from; - emit textFromChanged(m_text_from); + if(m_text_from != text_from) + { + m_text_from = text_from; + emit textFromChanged(m_text_from); + } } /** @@ -263,8 +317,8 @@ void DynamicElementTextItem::setInfoName(const QString &info_name) { m_info_name = info_name; - if(m_parent_element) { - setPlainText(m_parent_element->elementInformations().value(info_name).toString()); + if(elementUseForInfo()) { + setPlainText(elementUseForInfo()->elementInformations().value(info_name).toString()); } emit infoNameChanged(info_name); @@ -278,10 +332,11 @@ void DynamicElementTextItem::setCompositeText(const QString &text) { m_composite_text = text; + DiagramContext dc; + if(elementUseForInfo()) + dc = elementUseForInfo()->elementInformations(); + setPlainText(autonum::AssignVariables::replaceVariable(m_composite_text, dc)); - if(m_parent_element) { - setPlainText(autonum::AssignVariables::replaceVariable(m_composite_text, m_parent_element->elementInformations())); - } emit compositeTextChanged(m_composite_text); } @@ -342,18 +397,74 @@ void DynamicElementTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QGraphicsTextItem::mouseReleaseEvent(event); } +/** + * @brief DynamicElementTextItem::mouseDoubleClickEvent + * Reimplemented functions, for add extra feature when this text is owned by a slave. + * In this case if the parent slave element is linked to a master, and this text display the label of the master + * (both if the 'text from' is 'element info' or 'composite text') the QGraphicsView go to master and select it. + * @param event + */ +void DynamicElementTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) +{ + DiagramTextItem::mouseDoubleClickEvent(event); + + if(m_parent_element && m_parent_element.data()->linkType() == Element::Slave && m_master_element) + { + if ((m_text_from == ElementInfo && m_info_name == "label") || + (m_text_from == CompositeText && m_composite_text.contains("%{label}"))) + { + //Unselect and ungrab mouse to prevent unwanted + //move when linked element is in the same scene of this. + setSelected(false); + ungrabMouse(); + + if(scene() != m_master_element.data()->scene()) + m_master_element.data()->diagram()->showMe(); + m_master_element.data()->setSelected(true); + + //Zoom to the master element + for(QGraphicsView *view : m_master_element.data()->scene()->views()) + { + QRectF fit = m_master_element.data()->sceneBoundingRect(); + fit.adjust(-200, -200, 200, 200); + view->fitInView(fit, Qt::KeepAspectRatioByExpanding); + } + } + } +} + void DynamicElementTextItem::elementInfoChanged() { - if(!m_parent_element) - return; + DiagramContext dc; + if(elementUseForInfo()) + dc = elementUseForInfo()->elementInformations(); QString final_text; - + if (m_text_from == ElementInfo) - final_text = m_parent_element->elementInformations().value(m_info_name).toString(); + final_text = dc.value(m_info_name).toString(); else if (m_text_from == CompositeText) - final_text = autonum::AssignVariables::replaceVariable(m_composite_text, m_parent_element->elementInformations()); + final_text = autonum::AssignVariables::replaceVariable(m_composite_text, dc); + else if (m_text_from == UserText) + final_text = m_text; setPlainText(final_text); } +void DynamicElementTextItem::masterChanged() +{ + //First we remove the old connection + if(!m_master_element.isNull() && (m_text_from == ElementInfo || m_text_from == CompositeText)) + disconnect(m_master_element.data(), &Element::elementInfoChange, this, &DynamicElementTextItem::elementInfoChanged); + + if(elementUseForInfo()) + { + m_master_element = elementUseForInfo(); + if(m_text_from == ElementInfo || m_text_from == CompositeText) + connect(m_master_element.data(), &Element::elementInfoChange, this, &DynamicElementTextItem::elementInfoChanged); + } + + //Because master changed we update this text + elementInfoChanged(); +} + diff --git a/sources/qetgraphicsitem/dynamicelementtextitem.h b/sources/qetgraphicsitem/dynamicelementtextitem.h index 4a79f12a6..9df9c0bb6 100644 --- a/sources/qetgraphicsitem/dynamicelementtextitem.h +++ b/sources/qetgraphicsitem/dynamicelementtextitem.h @@ -68,6 +68,7 @@ class DynamicElementTextItem : public DiagramTextItem void fromXml(const QDomElement &dom_elmt) override; Element *parentElement() const; + Element *elementUseForInfo() const; DynamicElementTextItem::TextFrom textFrom() const; void setTextFrom (DynamicElementTextItem::TextFrom text_from); @@ -84,12 +85,15 @@ class DynamicElementTextItem : public DiagramTextItem protected: void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; + void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override; private: void elementInfoChanged(); + void masterChanged(); private: - QPointer m_parent_element; + QPointer m_parent_element, + m_master_element; QString m_tagg, m_text, m_info_name, diff --git a/sources/qetgraphicsitem/slaveelement.cpp b/sources/qetgraphicsitem/slaveelement.cpp index 60904c741..c1bc053be 100644 --- a/sources/qetgraphicsitem/slaveelement.cpp +++ b/sources/qetgraphicsitem/slaveelement.cpp @@ -56,18 +56,23 @@ void SlaveElement::linkToElement(Element *elmt) // check if element is master and if isn't already linked if (elmt->linkType() == Master && !connected_elements.contains(elmt)) { - if(!isFree()) unlinkAllElements(); - this->disconnect(); + if(!isFree()) + unlinkAllElements(); + + for(QMetaObject::Connection c : m_connections) + this->disconnect(c); + m_connections.clear(); + connected_elements << elmt; QETProject *project = elmt->diagram()->project(); - connect(elmt, SIGNAL(xChanged()), this, SLOT(updateLabel())); - connect(elmt, SIGNAL(yChanged()), this, SLOT(updateLabel())); - connect(elmt, SIGNAL(elementInfoChange(DiagramContext, DiagramContext)), this, SLOT(updateLabel())); - connect(project, SIGNAL(projectDiagramsOrderChanged(QETProject*,int,int)), this, SLOT(updateLabel())); - connect(project, SIGNAL(diagramRemoved(QETProject*,Diagram*)), this, SLOT(updateLabel())); - connect(project, SIGNAL(XRefPropertiesChanged()), this, SLOT(updateLabel())); - connect(elmt, SIGNAL(updateLabel()), this, SLOT(updateLabel())); + m_connections << connect(elmt, SIGNAL(xChanged()), this, SLOT(updateLabel())); + m_connections << connect(elmt, SIGNAL(yChanged()), this, SLOT(updateLabel())); + m_connections << connect(elmt, SIGNAL(elementInfoChange(DiagramContext, DiagramContext)), this, SLOT(updateLabel())); + m_connections << connect(project, SIGNAL(projectDiagramsOrderChanged(QETProject*,int,int)), this, SLOT(updateLabel())); + m_connections << connect(project, SIGNAL(diagramRemoved(QETProject*,Diagram*)), this, SLOT(updateLabel())); + m_connections << connect(project, SIGNAL(XRefPropertiesChanged()), this, SLOT(updateLabel())); + m_connections << connect(elmt, SIGNAL(updateLabel()), this, SLOT(updateLabel())); updateLabel(); elmt -> linkToElement(this); diff --git a/sources/qetgraphicsitem/slaveelement.h b/sources/qetgraphicsitem/slaveelement.h index 02dd1ab6b..017e62e6e 100644 --- a/sources/qetgraphicsitem/slaveelement.h +++ b/sources/qetgraphicsitem/slaveelement.h @@ -38,6 +38,7 @@ class SlaveElement : public CustomElement private: QGraphicsTextItem *m_xref_item; + QList m_connections; }; #endif // SLAVEELEMENT_H diff --git a/sources/ui/compositetexteditdialog.cpp b/sources/ui/compositetexteditdialog.cpp index 2c55b799b..65d54f309 100644 --- a/sources/ui/compositetexteditdialog.cpp +++ b/sources/ui/compositetexteditdialog.cpp @@ -37,7 +37,7 @@ QString CompositeTextEditDialog::plainText() const { void CompositeTextEditDialog::setUpComboBox() { QStringList qstrl; - Element *elmt = m_text->parentElement(); + Element *elmt = m_text->elementUseForInfo(); if(!elmt) return; diff --git a/sources/ui/compositetexteditdialog.ui b/sources/ui/compositetexteditdialog.ui index b6258c5f7..8880dcc92 100644 --- a/sources/ui/compositetexteditdialog.ui +++ b/sources/ui/compositetexteditdialog.ui @@ -11,7 +11,7 @@ - Dialog + Texte composé diff --git a/sources/ui/dynamicelementtextmodel.cpp b/sources/ui/dynamicelementtextmodel.cpp index 646e5d980..d4bf0b8e5 100644 --- a/sources/ui/dynamicelementtextmodel.cpp +++ b/sources/ui/dynamicelementtextmodel.cpp @@ -105,9 +105,12 @@ void DynamicElementTextModel::addText(DynamicElementTextItem *deti) QStandardItem *composite = new QStandardItem(tr("Texte composé")); composite->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + DiagramContext dc; + if(deti->elementUseForInfo()) + dc = deti->elementUseForInfo()->elementInformations(); QStandardItem *compositea = new QStandardItem(deti->compositeText().isEmpty() ? tr("Mon texte composé") : - autonum::AssignVariables::replaceVariable(deti->compositeText(), deti->parentElement()->elementInformations())); + autonum::AssignVariables::replaceVariable(deti->compositeText(), dc)); compositea->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); compositea->setData(DynamicElementTextModel::compositeText, Qt::UserRole+1); //Use to know the edited thing compositea->setData(deti->compositeText(), Qt::UserRole+2); //Use to know to element composite formula @@ -329,6 +332,9 @@ void DynamicElementTextModel::itemDataChanged(QStandardItem *qsi) return; QStandardItem *text_qsi = m_texts_list.value(deti); + DiagramContext dc; + if(deti->elementUseForInfo()) + dc = deti->elementUseForInfo()->elementInformations(); if (qsi->data().toInt() == textFrom) { @@ -344,13 +350,13 @@ void DynamicElementTextModel::itemDataChanged(QStandardItem *qsi) { enableSourceText(deti, DynamicElementTextItem::ElementInfo); QString info = text_from_qsi->child(1,1)->data(Qt::UserRole+2).toString(); - text_qsi->setData(deti->parentElement()->elementInformations().value(info), Qt::DisplayRole); + text_qsi->setData(dc.value(info), Qt::DisplayRole); } else { enableSourceText(deti, DynamicElementTextItem::CompositeText); QString compo = text_from_qsi->child(2,1)->data(Qt::UserRole+2).toString(); - text_qsi->setData(autonum::AssignVariables::replaceVariable(compo, deti->parentElement()->elementInformations()), Qt::DisplayRole); + text_qsi->setData(autonum::AssignVariables::replaceVariable(compo, dc), Qt::DisplayRole); } @@ -360,15 +366,15 @@ void DynamicElementTextModel::itemDataChanged(QStandardItem *qsi) QString text = qsi->data(Qt::DisplayRole).toString(); text_qsi->setData(text, Qt::DisplayRole); } - else if (qsi->data().toInt() == infoText && deti->parentElement()) + else if (qsi->data().toInt() == infoText && deti->elementUseForInfo()) { QString info = qsi->data(Qt::UserRole+2).toString(); - text_qsi->setData(deti->parentElement()->elementInformations().value(info), Qt::DisplayRole); + text_qsi->setData(dc.value(info), Qt::DisplayRole); } - else if (qsi->data().toInt() == compositeText && deti->parentElement()) + else if (qsi->data().toInt() == compositeText && deti->elementUseForInfo()) { QString compo = qsi->data(Qt::UserRole+2).toString(); - text_qsi->setData(autonum::AssignVariables::replaceVariable(compo, deti->parentElement()->elementInformations()), Qt::DisplayRole); + text_qsi->setData(autonum::AssignVariables::replaceVariable(compo, dc), Qt::DisplayRole); } //We emit the signal only if @qsi is in the second column, because the data are stored on this column @@ -597,7 +603,9 @@ void DynamicTextItemDelegate::setModelData(QWidget *editor, QAbstractItemModel * DynamicElementTextItem *deti = detm->textFromIndex(index); if(deti) { - DiagramContext dc = deti->parentElement()->elementInformations(); + DiagramContext dc; + if(deti->elementUseForInfo()) + dc = deti->elementUseForInfo()->elementInformations(); assigned_text = autonum::AssignVariables::replaceVariable(edited_text, dc); } @@ -620,9 +628,10 @@ void DynamicTextItemDelegate::setModelData(QWidget *editor, QAbstractItemModel * QStringList DynamicTextItemDelegate::availableInfo(DynamicElementTextItem *deti) const { QStringList qstrl; - Element *elmt = deti->parentElement(); + Element *elmt = deti->elementUseForInfo(); if(!elmt) return qstrl; + QStringList info_list = QETApp::elementInfoKeys(); info_list.removeAll("formula"); //No need to have formula