diff --git a/dev_doc/ID_of_QUndoCommand.txt b/dev_doc/ID_of_QUndoCommand.txt new file mode 100755 index 000000000..1b01037e7 --- /dev/null +++ b/dev_doc/ID_of_QUndoCommand.txt @@ -0,0 +1 @@ +ChangeElementInformationCommand = 1 diff --git a/sources/qetgraphicsitem/element.cpp b/sources/qetgraphicsitem/element.cpp index ba2004a5b..fdb24fb6b 100644 --- a/sources/qetgraphicsitem/element.cpp +++ b/sources/qetgraphicsitem/element.cpp @@ -415,7 +415,7 @@ bool Element::fromXml(QDomElement &e, QHash &table_id_adr, bool uuid_= QUuid(e.attribute("uuid", QUuid::createUuid().toString())); //load informations - element_informations_.fromXml(e.firstChildElement("elementInformations"), "elementInformation"); + m_element_informations.fromXml(e.firstChildElement("elementInformations"), "elementInformation"); //Position and selection. //We directly call setPos from QGraphicsObject, because QetGraphicsItem will snap to grid @@ -498,9 +498,9 @@ QDomElement Element::toXml(QDomDocument &document, QHash &table } //save information of this element - if (! element_informations_.keys().isEmpty()) { + if (! m_element_informations.keys().isEmpty()) { QDomElement infos = document.createElement("elementInformations"); - element_informations_.toXml(infos, "elementInformation"); + m_element_informations.toXml(infos, "elementInformation"); element.appendChild(infos); } @@ -556,13 +556,15 @@ void Element::initLink(QETProject *prj) /** * @brief Element::setElementInformations * Set new information for this element. - * This method emit @elementInfoChange + * If new information is different of current infotmation emit @elementInfoChange * @param dc */ -void Element::setElementInformations(DiagramContext dc) { - DiagramContext old_info = element_informations_; - element_informations_ = dc; - emit elementInfoChange(old_info, element_informations_); +void Element::setElementInformations(DiagramContext dc) +{ + if (m_element_informations == dc) return; + DiagramContext old_info = m_element_informations; + m_element_informations = dc; + emit elementInfoChange(old_info, m_element_informations); } /** diff --git a/sources/qetgraphicsitem/element.h b/sources/qetgraphicsitem/element.h index c2e5d3cf1..b23fa2085 100644 --- a/sources/qetgraphicsitem/element.h +++ b/sources/qetgraphicsitem/element.h @@ -125,8 +125,8 @@ class Element : public QetGraphicsItem { //METHODS related to information public: - DiagramContext elementInformations ()const {return element_informations_;} - DiagramContext& rElementInformations () {return element_informations_;} + DiagramContext elementInformations ()const {return m_element_informations;} + DiagramContext& rElementInformations () {return m_element_informations;} virtual void setElementInformations (DiagramContext dc); DiagramContext kindInformations () const {return kind_informations_;} //@kind_information_ is used to store more information //about the herited class like contactelement for know @@ -134,7 +134,7 @@ class Element : public QetGraphicsItem { //ATTRIBUTES protected: - DiagramContext element_informations_, kind_informations_; + DiagramContext m_element_informations, kind_informations_; /** Draw this element diff --git a/sources/ui/elementinfopartwidget.cpp b/sources/ui/elementinfopartwidget.cpp index d0bacaaff..e448bb7de 100644 --- a/sources/ui/elementinfopartwidget.cpp +++ b/sources/ui/elementinfopartwidget.cpp @@ -34,6 +34,10 @@ ElementInfoPartWidget::ElementInfoPartWidget(QString key, QString translated_key ui->setupUi(this); ui->label_->setText(translated_key); if(key == "label") ui->checkBox->setChecked(true); + + connect(ui->line_edit, &QLineEdit::textEdited, this, &ElementInfoPartWidget::textEdited); + connect(ui->line_edit, &QLineEdit::textChanged, this, &ElementInfoPartWidget::textChanged); + } /** diff --git a/sources/ui/elementinfopartwidget.h b/sources/ui/elementinfopartwidget.h index 6f9f5fa3e..062cfe11f 100644 --- a/sources/ui/elementinfopartwidget.h +++ b/sources/ui/elementinfopartwidget.h @@ -24,7 +24,8 @@ namespace Ui { class ElementInfoPartWidget; } -class ElementInfoPartWidget : public QWidget { +class ElementInfoPartWidget : public QWidget +{ Q_OBJECT //METHODS @@ -40,6 +41,10 @@ class ElementInfoPartWidget : public QWidget { void setHideShow (const bool &); void setFocusTolineEdit(); + signals: + void textEdited (const QString & text); + void textChanged(const QString & text); + //ATTRIBUTES private: Ui::ElementInfoPartWidget *ui; diff --git a/sources/ui/elementinfowidget.cpp b/sources/ui/elementinfowidget.cpp index f6075164f..2dc651191 100644 --- a/sources/ui/elementinfowidget.cpp +++ b/sources/ui/elementinfowidget.cpp @@ -45,7 +45,7 @@ ElementInfoWidget::ElementInfoWidget(Element *elmt, QWidget *parent) : */ ElementInfoWidget::~ElementInfoWidget() { - qDeleteAll(eipw_list); + qDeleteAll(m_eipw_list); delete ui; } @@ -57,9 +57,14 @@ ElementInfoWidget::~ElementInfoWidget() void ElementInfoWidget::setElement(Element *element) { if (m_element == element) return; + + if (m_element) + disconnect(m_element, &Element::elementInfoChange, this, &ElementInfoWidget::updateUi); + m_element = element; - m_element_info = m_element->elementInformations(); - fillInfo(); + updateUi(); + + connect(m_element, &Element::elementInfoChange, this, &ElementInfoWidget::updateUi); } /** @@ -80,11 +85,13 @@ void ElementInfoWidget::apply() * If no change return nullptr; * @return */ -QUndoCommand* ElementInfoWidget::associatedUndo() const { +QUndoCommand* ElementInfoWidget::associatedUndo() const +{ DiagramContext new_info; DiagramContext old_info = m_element -> elementInformations(); - foreach (ElementInfoPartWidget *eipw, eipw_list) { + foreach (ElementInfoPartWidget *eipw, m_eipw_list) + { //add value only if they're something to store if (!eipw->text().isEmpty()) new_info.addValue(eipw->key(), @@ -92,12 +99,30 @@ QUndoCommand* ElementInfoWidget::associatedUndo() const { eipw->mustShow()); } - if (old_info != new_info) { + if (old_info != new_info) return (new ChangeElementInformationCommand(m_element, old_info, new_info)); - } + return nullptr; } +/** + * @brief ElementInfoWidget::setLiveEdit + * @param live_edit true : enable the live edit mode, false disable + * @return always true; + */ +bool ElementInfoWidget::setLiveEdit(bool live_edit) +{ + if (m_live_edit == live_edit) return true; + m_live_edit = live_edit; + + if (m_live_edit) + enableLiveEdit(); + else + disableLiveEdit(); + + return true; +} + /** * @brief ElementInfoWidget::event * Reimplemented from QWidget::event @@ -119,38 +144,68 @@ bool ElementInfoWidget::event(QEvent *event) return(QWidget::event(event)); } +/** + * @brief ElementInfoWidget::enableLiveEdit + * Enable the live edit mode + */ +void ElementInfoWidget::enableLiveEdit() +{ + foreach (ElementInfoPartWidget *eipw, m_eipw_list) + connect(eipw, &ElementInfoPartWidget::textChanged, this, &ElementInfoWidget::apply); +} + +/** + * @brief ElementInfoWidget::disableLiveEdit + * disable the live edit mode + */ +void ElementInfoWidget::disableLiveEdit() +{ + foreach (ElementInfoPartWidget *eipw, m_eipw_list) + disconnect(eipw, &ElementInfoPartWidget::textChanged, this, &ElementInfoWidget::apply); +} + /** * @brief ElementInfoWidget::buildInterface * Build the widget */ -void ElementInfoWidget::buildInterface() { - foreach (QString str, QETApp::elementInfoKeys()) { +void ElementInfoWidget::buildInterface() +{ + foreach (QString str, QETApp::elementInfoKeys()) + { ElementInfoPartWidget *eipw = new ElementInfoPartWidget(str, QETApp::elementTranslatedInfoKey(str), this); ui->scroll_vlayout->addWidget(eipw); - eipw_list << eipw; + m_eipw_list << eipw; } } /** - * @brief ElementInfoWidget::fillInfo + * @brief ElementInfoWidget::updateUi * fill information fetch in m_element_info to the * corresponding line edit */ -void ElementInfoWidget::fillInfo() { - foreach (ElementInfoPartWidget *eipw, eipw_list) { +void ElementInfoWidget::updateUi() +{ + //We disable live edit to avoid wrong undo when we fill the line edit with new text + if (m_live_edit) disableLiveEdit(); - eipw -> setText (m_element_info[eipw->key()].toString()); - eipw -> setShow (m_element_info.keyMustShow(eipw->key())); + DiagramContext element_info = m_element->elementInformations(); + foreach (ElementInfoPartWidget *eipw, m_eipw_list) + { - //If the current eipw is for label or comment and the text is empty - //we force the checkbox to ckecked + eipw -> setText (element_info[eipw->key()].toString()); + eipw -> setShow (element_info.keyMustShow(eipw->key())); + + //If the current eipw is for label or comment and the text is empty + //we force the checkbox to ckecked if (eipw -> key() == "label" || eipw -> key() == "comment") { - if (m_element_info[eipw->key()].toString().isEmpty()) + if (element_info[eipw->key()].toString().isEmpty()) eipw->setShow(true); } else //< for other eipw we hide the checkbox eipw->setHideShow(true); } + + if (m_live_edit) enableLiveEdit(); } /** @@ -159,5 +214,5 @@ void ElementInfoWidget::fillInfo() { * Set the focus to the first line edit provided by this widget */ void ElementInfoWidget::firstActivated() { - eipw_list.first() -> setFocusTolineEdit(); + m_eipw_list.first() -> setFocusTolineEdit(); } diff --git a/sources/ui/elementinfowidget.h b/sources/ui/elementinfowidget.h index 5e6473349..cedaa2d4b 100644 --- a/sources/ui/elementinfowidget.h +++ b/sources/ui/elementinfowidget.h @@ -19,7 +19,6 @@ #define ELEMENTINFOWIDGET_H #include -#include "diagramcontext.h" #include "abstractelementpropertieseditorwidget.h" class Element; @@ -48,13 +47,16 @@ class ElementInfoWidget : public AbstractElementPropertiesEditorWidget void apply(); QUndoCommand *associatedUndo () const; QString title() const {return tr("Informations");} + bool setLiveEdit(bool live_edit); + virtual void updateUi(); protected: virtual bool event(QEvent *event); + virtual void enableLiveEdit(); + virtual void disableLiveEdit(); private: void buildInterface(); - void fillInfo(); private slots: void firstActivated(); @@ -62,8 +64,7 @@ class ElementInfoWidget : public AbstractElementPropertiesEditorWidget //ATTRIBUTES private: Ui::ElementInfoWidget *ui; - DiagramContext m_element_info; - QList eipw_list; + QList m_eipw_list; bool m_first_activation; }; diff --git a/sources/undocommand/changeelementinformationcommand.cpp b/sources/undocommand/changeelementinformationcommand.cpp index 00d53216e..cd7fae976 100644 --- a/sources/undocommand/changeelementinformationcommand.cpp +++ b/sources/undocommand/changeelementinformationcommand.cpp @@ -35,6 +35,15 @@ ChangeElementInformationCommand::ChangeElementInformationCommand(Element *elmt, setText(QObject::tr("Modifier les informations de l'élément : %1").arg(elmt -> name())); } +bool ChangeElementInformationCommand::mergeWith(const QUndoCommand *other) +{ + if (id() != other->id()) return false; + ChangeElementInformationCommand const *undo = static_cast(other); + if (m_element != undo->m_element) return false; + m_new_info = undo->m_new_info; + return true; +} + /** * @brief ChangeElementInformationCommand::undo */ diff --git a/sources/undocommand/changeelementinformationcommand.h b/sources/undocommand/changeelementinformationcommand.h index 25d92a610..610fc2369 100644 --- a/sources/undocommand/changeelementinformationcommand.h +++ b/sources/undocommand/changeelementinformationcommand.h @@ -32,6 +32,8 @@ class ChangeElementInformationCommand : public QUndoCommand public: ChangeElementInformationCommand(Element *elmt, DiagramContext &old_info, DiagramContext &new_info, QUndoCommand *parent = nullptr); + virtual int id() const {return 1;} + virtual bool mergeWith(const QUndoCommand *other); virtual void undo(); virtual void redo();