From 77164adf4bf8e256eddcab14ad5588e5d800931a Mon Sep 17 00:00:00 2001 From: blacksun Date: Thu, 11 Dec 2014 20:10:28 +0000 Subject: [PATCH] Change element information is now managed by an undo command git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@3542 bfdf4180-ca20-0410-9c96-a3a8aa849046 --- qelectrotech.pro | 9 +- sources/ui/elementinfowidget.cpp | 39 ++++++-- sources/ui/elementinfowidget.h | 34 ++++--- sources/ui/elementpropertieswidget.cpp | 45 +++++++-- sources/ui/elementpropertieswidget.h | 59 ++++++------ sources/ui/masterpropertieswidget.cpp | 91 +++++++++++-------- sources/ui/masterpropertieswidget.h | 4 +- .../changeelementinformationcommand.cpp | 50 ++++++++++ .../changeelementinformationcommand.h | 44 +++++++++ 9 files changed, 280 insertions(+), 95 deletions(-) create mode 100644 sources/undocommand/changeelementinformationcommand.cpp create mode 100644 sources/undocommand/changeelementinformationcommand.h diff --git a/qelectrotech.pro b/qelectrotech.pro index e30d505c7..ad0337014 100644 --- a/qelectrotech.pro +++ b/qelectrotech.pro @@ -71,7 +71,8 @@ INCLUDEPATH += sources \ sources/properties \ sources/dvevent \ sources/editor \ - sources/editor/esevent + sources/editor/esevent \ + sources/undocommand # Fichiers sources @@ -79,13 +80,15 @@ HEADERS += $$files(sources/*.h) $$files(sources/ui/*.h) $$files(sources/editor/* $$files(sources/properties/*.h) \ $$files(sources/editor/ui/*.h) \ $$files(sources/editor/esevent/*.h) \ - $$files(sources/dvevent/*.h) + $$files(sources/dvevent/*.h) \ + $$files(sources/undocommand/*.h) SOURCES += $$files(sources/*.cpp) $$files(sources/editor/*.cpp) $$files(sources/titleblock/*.cpp) $$files(sources/richtext/*.cpp) $$files(sources/ui/*.cpp) $$files(sources/qetgraphicsitem/*.cpp) $$files(sources/factory/*.cpp) \ $$files(sources/properties/*.cpp) \ $$files(sources/editor/ui/*.cpp) \ $$files(sources/editor/esevent/*.cpp) \ - $$files(sources/dvevent/*.cpp) + $$files(sources/dvevent/*.cpp) \ + $$files(sources/undocommand/*.cpp) # Liste des fichiers qui seront incorpores au binaire en tant que ressources Qt RESOURCES += qelectrotech.qrc diff --git a/sources/ui/elementinfowidget.cpp b/sources/ui/elementinfowidget.cpp index 7617e30fe..d89f37d4c 100644 --- a/sources/ui/elementinfowidget.cpp +++ b/sources/ui/elementinfowidget.cpp @@ -18,6 +18,10 @@ #include "elementinfowidget.h" #include "ui_elementinfowidget.h" #include "qetapp.h" +#include "changeelementinformationcommand.h" +#include "diagram.h" +#include "elementinfopartwidget.h" +#include "element.h" /** * @brief ElementInfoWidget::ElementInfoWidget @@ -48,18 +52,41 @@ ElementInfoWidget::~ElementInfoWidget() /** * @brief ElementInfoWidget::apply - * Apply the new information + * Apply the new information with a new undo command (got with method associatedUndo) + * pushed to the stack of element project. + * Return true if new info change, else false. */ -void ElementInfoWidget::apply() { - DiagramContext dc; +bool ElementInfoWidget::apply() { + if (QUndoCommand *undo = associatedUndo()) { + element_ -> diagram() -> undoStack().push(undo); + return true; + } + return false; +} + +/** + * @brief ElementInfoWidget::associatedUndo + * If the edited info is different of the actual element info, + * return a QUndoCommand with the change. + * If no change return nullptr; + * @return + */ +QUndoCommand* ElementInfoWidget::associatedUndo() const { + DiagramContext new_info; + DiagramContext old_info = element_ -> elementInformations(); + foreach (ElementInfoPartWidget *eipw, eipw_list) { - //add value only if they're something to store + //add value only if they're something to store if (!eipw->text().isEmpty()) - dc.addValue(eipw->key(), + new_info.addValue(eipw->key(), eipw->text(), eipw->mustShow()); } - element_->setElementInformations(dc); + + if (old_info != new_info) { + return (new ChangeElementInformationCommand(element_, old_info, new_info)); + } + return nullptr; } /** diff --git a/sources/ui/elementinfowidget.h b/sources/ui/elementinfowidget.h index 686ef4bd3..ee307f491 100644 --- a/sources/ui/elementinfowidget.h +++ b/sources/ui/elementinfowidget.h @@ -19,9 +19,12 @@ #define ELEMENTINFOWIDGET_H #include -#include "qetgraphicsitem/element.h" #include "diagramcontext.h" -#include "elementinfopartwidget.h" + +class Element; +class QUndoCommand; +class ElementInfoPartWidget; +class ChangeElementInformationCommand; namespace Ui { class ElementInfoWidget; @@ -35,20 +38,23 @@ class ElementInfoWidget : public QWidget { Q_OBJECT //METHODS - public: - explicit ElementInfoWidget(Element *elmt, QWidget *parent = 0); - ~ElementInfoWidget(); - void apply(); - private: - void buildInterface(); - void fillInfo(); + public: + explicit ElementInfoWidget(Element *elmt, QWidget *parent = 0); + ~ElementInfoWidget(); + + bool apply(); + QUndoCommand* associatedUndo () const; + + private: + void buildInterface(); + void fillInfo(); //ATTRIBUTES - private: - Ui::ElementInfoWidget *ui; - Element *element_; - DiagramContext elmt_info; - QList eipw_list; + private: + Ui::ElementInfoWidget *ui; + Element *element_; + DiagramContext elmt_info; + QList eipw_list; }; #endif // ELEMENTINFOWIDGET_H diff --git a/sources/ui/elementpropertieswidget.cpp b/sources/ui/elementpropertieswidget.cpp index aa8003190..e96fa63d3 100644 --- a/sources/ui/elementpropertieswidget.cpp +++ b/sources/ui/elementpropertieswidget.cpp @@ -16,9 +16,13 @@ along with QElectroTech. If not, see . */ #include "elementpropertieswidget.h" -#include "qetgraphicsitem/ghostelement.h" +#include "ghostelement.h" #include "qeticons.h" #include "diagramposition.h" +#include "diagram.h" +#include "elementinfowidget.h" +#include "masterpropertieswidget.h" +#include "linksingleelementwidget.h" /** * @brief elementpropertieswidget::elementpropertieswidget @@ -156,21 +160,46 @@ void elementpropertieswidget::buildInterface() { * the cliked button */ void elementpropertieswidget::standardButtonClicked(QAbstractButton *button) { - int answer = dbb -> buttonRole(button); + int answer = dbb -> buttonRole(button); + bool accept = false; switch (answer) { case QDialogButtonBox::ResetRole: if (mpw_) mpw_->reset(); break; case QDialogButtonBox::ApplyRole: - if (eiw_) eiw_->apply(); //element information widget - if (mpw_) mpw_->apply(); //master property widget - if (lsew_) lsew_->apply(); //link sigle element widget - this->accept(); + accept = true; + break; case QDialogButtonBox::RejectRole: - this->reject(); + this -> reject(); + break; default: - this->reject(); + this -> reject(); + break; + } + + if (accept) { + QUndoCommand *a = nullptr; + QUndoCommand *b = nullptr; + + if (eiw_) a = eiw_ -> associatedUndo(); + if (mpw_) b = mpw_ -> associatedUndo(); + if (lsew_) lsew_ -> apply(); + + //If two undo, we push it in a macro + if (a && b) { + QUndoStack &stack = element_ -> diagram() -> undoStack(); + stack.beginMacro(a -> text() + " + " + b -> text()); + stack.push(a); + stack.push(b); + stack.endMacro(); + } + else { + if (a) element_ -> diagram() -> undoStack().push(a); + if (b) element_ -> diagram() -> undoStack().push(b); + } + + this -> accept(); } } diff --git a/sources/ui/elementpropertieswidget.h b/sources/ui/elementpropertieswidget.h index a48301879..933dd5bc2 100644 --- a/sources/ui/elementpropertieswidget.h +++ b/sources/ui/elementpropertieswidget.h @@ -18,44 +18,49 @@ #ifndef ELEMENTPROPERTIESWIDGET_H #define ELEMENTPROPERTIESWIDGET_H -#include -#include "qetgraphicsitem/element.h" -#include "diagram.h" -#include "elementinfowidget.h" -#include "masterpropertieswidget.h" -#include "linksingleelementwidget.h" +#include -class elementpropertieswidget : public QDialog -{ +class Diagram; +class Element; +class ElementsLocation; +class ElementInfoWidget; +class MasterPropertiesWidget; +class LinkSingleElementWidget; +class QAbstractButton; +class QDialogButtonBox; +class QTabWidget; + +class elementpropertieswidget : public QDialog { Q_OBJECT + public: - explicit elementpropertieswidget(Element *elmt, QWidget *parent = 0); + explicit elementpropertieswidget(Element *elmt, QWidget *parent = 0); private: - QWidget* generalWidget(); - void buildInterface(); + QWidget* generalWidget(); + void buildInterface(); signals: - /// Signal emitted when users wish to locate an element from the diagram within elements collection - void findElementRequired(const ElementsLocation &); - /// Signal emitted when users wish to edit an element from the diagram - void editElementRequired(const ElementsLocation &); + /// Signal emitted when users wish to locate an element from the diagram within elements collection + void findElementRequired(const ElementsLocation &); + /// Signal emitted when users wish to edit an element from the diagram + void editElementRequired(const ElementsLocation &); public slots: - void standardButtonClicked (QAbstractButton *); - void findInPanel (); - void editElement (); + void standardButtonClicked (QAbstractButton *); + void findInPanel (); + void editElement (); private: - ElementInfoWidget *eiw_; - MasterPropertiesWidget *mpw_; - LinkSingleElementWidget *lsew_; - QDialogButtonBox *dbb; - Element *element_; - Diagram *diagram_; - QTabWidget *tab_; - QPushButton *find_in_panel, *edit_element; - + Element *element_; + Diagram *diagram_; + QTabWidget *tab_; + QPushButton *find_in_panel, + *edit_element; + QDialogButtonBox *dbb; + ElementInfoWidget *eiw_; + MasterPropertiesWidget *mpw_; + LinkSingleElementWidget *lsew_; }; #endif // ELEMENTPROPERTIESWIDGET_H diff --git a/sources/ui/masterpropertieswidget.cpp b/sources/ui/masterpropertieswidget.cpp index 09a4dffed..6bcf019ab 100644 --- a/sources/ui/masterpropertieswidget.cpp +++ b/sources/ui/masterpropertieswidget.cpp @@ -53,44 +53,17 @@ MasterPropertiesWidget::~MasterPropertiesWidget() /** * @brief MasterPropertiesWidget::apply - * Do what we need when apply new conf + * If link betwen edited element and other change, + * apply the change with a QUndoCommand (got with method associatedUndo) + * pushed to the stack of element project. + * Return true if link change, else false */ -void MasterPropertiesWidget::apply() { - QList to_link; - QList linked_ = element_->linkedElements(); - - for (int i=0; ilinked_list->count(); i++) { - to_link << lwi_hash[ui->linked_list->item(i)]; - } - - //If same element are find in to_link and linked, that means - // element are already linked, so we remove element on the two list - //if linked_ contains element at the end of the operation, - //that means this element must be unlinked from @element_ - foreach (Element *elmt, to_link) { - if(linked_.contains(elmt)) { - to_link.removeAll(elmt); - linked_.removeAll(elmt); - } - } - - // if two list, contain element, we link and unlink @element_ with corresponding - //undo command, and add first command for parent of the second, user see only one - //undo command - if (linked_.count() && to_link.count()) { - LinkElementsCommand *lec = new LinkElementsCommand(element_, to_link); - new unlinkElementsCommand(element_, linked_, lec); - element_->diagram()->undoStack().push(lec); - } - //Else do the single undo command corresponding to the link. - else if (to_link.count()) { - LinkElementsCommand *lec = new LinkElementsCommand(element_, to_link); - element_->diagram()->undoStack().push(lec); - } - else if (linked_.count()) { - unlinkElementsCommand *uec = new unlinkElementsCommand(element_, linked_); - element_->diagram()->undoStack().push(uec); +bool MasterPropertiesWidget::apply() { + if (QUndoCommand *undo = associatedUndo()) { + element_ -> diagram() -> undoStack().push(undo); + return true; } + return false; } /** @@ -105,6 +78,52 @@ void MasterPropertiesWidget::reset() { buildInterface(); } +/** + * @brief MasterPropertiesWidget::associatedUndo + * If link between the edited element and other change, + * return a QUndoCommand with this change. + * If no change return nullptr. + * @return + */ +QUndoCommand* MasterPropertiesWidget::associatedUndo() const { + QList to_link; + QList linked_ = element_->linkedElements(); + + for (int i=0; ilinked_list->count(); i++) { + to_link << lwi_hash[ui->linked_list->item(i)]; + } + + //If same element are find in to_link and linked, that means + // element are already linked, so we remove element on the two list + //if linked_ contains element at the end of the operation, + //that means this element must be unlinked from @element_ + foreach (Element *elmt, to_link) { + if(linked_.contains(elmt)) { + to_link.removeAll(elmt); + linked_.removeAll(elmt); + } + } + + // if two list, contain element, we link and unlink @element_ with corresponding + //undo command, and add first command for parent of the second, user see only one + //undo command + if (linked_.count() && to_link.count()) { + LinkElementsCommand *lec = new LinkElementsCommand(element_, to_link); + new unlinkElementsCommand(element_, linked_, lec); + return lec; + } + //Else do the single undo command corresponding to the link. + else if (to_link.count()) { + return (new LinkElementsCommand(element_, to_link)); + } + else if (linked_.count()) { + return (new unlinkElementsCommand(element_, linked_)); + } + else { + return nullptr; + } +} + /** * @brief MasterPropertiesWidget::buildInterface * Build the interface of the widget diff --git a/sources/ui/masterpropertieswidget.h b/sources/ui/masterpropertieswidget.h index 6f7f27752..914257a5c 100644 --- a/sources/ui/masterpropertieswidget.h +++ b/sources/ui/masterpropertieswidget.h @@ -23,6 +23,7 @@ class QListWidgetItem; class Element; +class QUndoCommand; namespace Ui { class MasterPropertiesWidget; @@ -42,8 +43,9 @@ class MasterPropertiesWidget : public QWidget explicit MasterPropertiesWidget(Element *elmt, QWidget *parent = 0); ~MasterPropertiesWidget(); - void apply(); + bool apply(); void reset(); + QUndoCommand* associatedUndo() const; private: void buildInterface(); diff --git a/sources/undocommand/changeelementinformationcommand.cpp b/sources/undocommand/changeelementinformationcommand.cpp new file mode 100644 index 000000000..b617cbb89 --- /dev/null +++ b/sources/undocommand/changeelementinformationcommand.cpp @@ -0,0 +1,50 @@ +/* + Copyright 2006-2014 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#include "changeelementinformationcommand.h" +#include "element.h" +#include + +/** + * @brief ChangeElementInformationCommand::ChangeElementInformationCommand + * Default constructor + * @param elmt : element to change information + * @param old_info : old info of element + * @param new_info : new info of element + */ +ChangeElementInformationCommand::ChangeElementInformationCommand(Element *elmt, DiagramContext &old_info, DiagramContext &new_info, QUndoCommand *parent) : + QUndoCommand (parent), + m_element (elmt), + m_old_info (old_info), + m_new_info (new_info) +{ + setText(QObject::tr("Modifier les informations de l'\351l\351ment : %1").arg(elmt -> name())); +} + +/** + * @brief ChangeElementInformationCommand::undo + */ +void ChangeElementInformationCommand::undo() { + m_element -> setElementInformations(m_old_info); +} + +/** + * @brief ChangeElementInformationCommand::redo + */ +void ChangeElementInformationCommand::redo() { + m_element -> setElementInformations(m_new_info); +} diff --git a/sources/undocommand/changeelementinformationcommand.h b/sources/undocommand/changeelementinformationcommand.h new file mode 100644 index 000000000..c64dfc2cd --- /dev/null +++ b/sources/undocommand/changeelementinformationcommand.h @@ -0,0 +1,44 @@ +/* + Copyright 2006-2014 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#ifndef CHANGEELEMENTINFORMATIONCOMMAND_H +#define CHANGEELEMENTINFORMATIONCOMMAND_H + +#include +#include "diagramcontext.h" + +class Element; + +/** + * @brief The ChangeElementInformationCommand class + * This class manage undo/redo to change the element information. + */ +class ChangeElementInformationCommand : public QUndoCommand +{ + public: + ChangeElementInformationCommand(Element *elmt, DiagramContext &old_info, DiagramContext &new_info, QUndoCommand *parent = nullptr); + + virtual void undo(); + virtual void redo(); + + private: + Element *m_element; + DiagramContext m_old_info, + m_new_info; +}; + +#endif // CHANGEELEMENTINFORMATIONCOMMAND_H