From 5248c891f41c0be1d9bc3f7ef04a697aee694365 Mon Sep 17 00:00:00 2001 From: blacksun Date: Tue, 29 Aug 2017 14:54:27 +0000 Subject: [PATCH] Dynamic element text item : First : If the parent element of the text item is a slave, the info use to create the text (both if option are 'element info' or 'composite text') are taken to the linked master element, and not the slave. If the salve element is not linked, no information is taken. Second : if the text is composed with the variable 'label' of the master (both if text from are 'element info' or 'composite text') double click on the text, act like a link and go to the master. git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5035 bfdf4180-ca20-0410-9c96-a3a8aa849046 --- .../dynamicelementtextitem.cpp | 153 +++++++++++++++--- .../qetgraphicsitem/dynamicelementtextitem.h | 6 +- sources/qetgraphicsitem/slaveelement.cpp | 23 +-- sources/qetgraphicsitem/slaveelement.h | 1 + sources/ui/compositetexteditdialog.cpp | 2 +- sources/ui/compositetexteditdialog.ui | 2 +- sources/ui/dynamicelementtextmodel.cpp | 27 ++-- 7 files changed, 172 insertions(+), 42 deletions(-) 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