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
This commit is contained in:
blacksun
2014-12-11 20:10:28 +00:00
parent 60dd0f2054
commit 77164adf4b
9 changed files with 280 additions and 95 deletions

View File

@@ -71,7 +71,8 @@ INCLUDEPATH += sources \
sources/properties \ sources/properties \
sources/dvevent \ sources/dvevent \
sources/editor \ sources/editor \
sources/editor/esevent sources/editor/esevent \
sources/undocommand
# Fichiers sources # Fichiers sources
@@ -79,13 +80,15 @@ HEADERS += $$files(sources/*.h) $$files(sources/ui/*.h) $$files(sources/editor/*
$$files(sources/properties/*.h) \ $$files(sources/properties/*.h) \
$$files(sources/editor/ui/*.h) \ $$files(sources/editor/ui/*.h) \
$$files(sources/editor/esevent/*.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) \ 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/properties/*.cpp) \
$$files(sources/editor/ui/*.cpp) \ $$files(sources/editor/ui/*.cpp) \
$$files(sources/editor/esevent/*.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 # Liste des fichiers qui seront incorpores au binaire en tant que ressources Qt
RESOURCES += qelectrotech.qrc RESOURCES += qelectrotech.qrc

View File

@@ -18,6 +18,10 @@
#include "elementinfowidget.h" #include "elementinfowidget.h"
#include "ui_elementinfowidget.h" #include "ui_elementinfowidget.h"
#include "qetapp.h" #include "qetapp.h"
#include "changeelementinformationcommand.h"
#include "diagram.h"
#include "elementinfopartwidget.h"
#include "element.h"
/** /**
* @brief ElementInfoWidget::ElementInfoWidget * @brief ElementInfoWidget::ElementInfoWidget
@@ -48,18 +52,41 @@ ElementInfoWidget::~ElementInfoWidget()
/** /**
* @brief ElementInfoWidget::apply * @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() { bool ElementInfoWidget::apply() {
DiagramContext dc; 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) { 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()) if (!eipw->text().isEmpty())
dc.addValue(eipw->key(), new_info.addValue(eipw->key(),
eipw->text(), eipw->text(),
eipw->mustShow()); eipw->mustShow());
} }
element_->setElementInformations(dc);
if (old_info != new_info) {
return (new ChangeElementInformationCommand(element_, old_info, new_info));
}
return nullptr;
} }
/** /**

View File

@@ -19,9 +19,12 @@
#define ELEMENTINFOWIDGET_H #define ELEMENTINFOWIDGET_H
#include <QWidget> #include <QWidget>
#include "qetgraphicsitem/element.h"
#include "diagramcontext.h" #include "diagramcontext.h"
#include "elementinfopartwidget.h"
class Element;
class QUndoCommand;
class ElementInfoPartWidget;
class ChangeElementInformationCommand;
namespace Ui { namespace Ui {
class ElementInfoWidget; class ElementInfoWidget;
@@ -35,20 +38,23 @@ class ElementInfoWidget : public QWidget {
Q_OBJECT Q_OBJECT
//METHODS //METHODS
public: public:
explicit ElementInfoWidget(Element *elmt, QWidget *parent = 0); explicit ElementInfoWidget(Element *elmt, QWidget *parent = 0);
~ElementInfoWidget(); ~ElementInfoWidget();
void apply();
private: bool apply();
void buildInterface(); QUndoCommand* associatedUndo () const;
void fillInfo();
private:
void buildInterface();
void fillInfo();
//ATTRIBUTES //ATTRIBUTES
private: private:
Ui::ElementInfoWidget *ui; Ui::ElementInfoWidget *ui;
Element *element_; Element *element_;
DiagramContext elmt_info; DiagramContext elmt_info;
QList <ElementInfoPartWidget *> eipw_list; QList <ElementInfoPartWidget *> eipw_list;
}; };
#endif // ELEMENTINFOWIDGET_H #endif // ELEMENTINFOWIDGET_H

View File

@@ -16,9 +16,13 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>. along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "elementpropertieswidget.h" #include "elementpropertieswidget.h"
#include "qetgraphicsitem/ghostelement.h" #include "ghostelement.h"
#include "qeticons.h" #include "qeticons.h"
#include "diagramposition.h" #include "diagramposition.h"
#include "diagram.h"
#include "elementinfowidget.h"
#include "masterpropertieswidget.h"
#include "linksingleelementwidget.h"
/** /**
* @brief elementpropertieswidget::elementpropertieswidget * @brief elementpropertieswidget::elementpropertieswidget
@@ -156,21 +160,46 @@ void elementpropertieswidget::buildInterface() {
* the cliked button * the cliked button
*/ */
void elementpropertieswidget::standardButtonClicked(QAbstractButton *button) { void elementpropertieswidget::standardButtonClicked(QAbstractButton *button) {
int answer = dbb -> buttonRole(button); int answer = dbb -> buttonRole(button);
bool accept = false;
switch (answer) { switch (answer) {
case QDialogButtonBox::ResetRole: case QDialogButtonBox::ResetRole:
if (mpw_) mpw_->reset(); if (mpw_) mpw_->reset();
break; break;
case QDialogButtonBox::ApplyRole: case QDialogButtonBox::ApplyRole:
if (eiw_) eiw_->apply(); //element information widget accept = true;
if (mpw_) mpw_->apply(); //master property widget break;
if (lsew_) lsew_->apply(); //link sigle element widget
this->accept();
case QDialogButtonBox::RejectRole: case QDialogButtonBox::RejectRole:
this->reject(); this -> reject();
break;
default: 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();
} }
} }

View File

@@ -18,44 +18,49 @@
#ifndef ELEMENTPROPERTIESWIDGET_H #ifndef ELEMENTPROPERTIESWIDGET_H
#define ELEMENTPROPERTIESWIDGET_H #define ELEMENTPROPERTIESWIDGET_H
#include <QtGui> #include <QDialog>
#include "qetgraphicsitem/element.h"
#include "diagram.h"
#include "elementinfowidget.h"
#include "masterpropertieswidget.h"
#include "linksingleelementwidget.h"
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 Q_OBJECT
public: public:
explicit elementpropertieswidget(Element *elmt, QWidget *parent = 0); explicit elementpropertieswidget(Element *elmt, QWidget *parent = 0);
private: private:
QWidget* generalWidget(); QWidget* generalWidget();
void buildInterface(); void buildInterface();
signals: signals:
/// Signal emitted when users wish to locate an element from the diagram within elements collection /// Signal emitted when users wish to locate an element from the diagram within elements collection
void findElementRequired(const ElementsLocation &); void findElementRequired(const ElementsLocation &);
/// Signal emitted when users wish to edit an element from the diagram /// Signal emitted when users wish to edit an element from the diagram
void editElementRequired(const ElementsLocation &); void editElementRequired(const ElementsLocation &);
public slots: public slots:
void standardButtonClicked (QAbstractButton *); void standardButtonClicked (QAbstractButton *);
void findInPanel (); void findInPanel ();
void editElement (); void editElement ();
private: private:
ElementInfoWidget *eiw_; Element *element_;
MasterPropertiesWidget *mpw_; Diagram *diagram_;
LinkSingleElementWidget *lsew_; QTabWidget *tab_;
QDialogButtonBox *dbb; QPushButton *find_in_panel,
Element *element_; *edit_element;
Diagram *diagram_; QDialogButtonBox *dbb;
QTabWidget *tab_; ElementInfoWidget *eiw_;
QPushButton *find_in_panel, *edit_element; MasterPropertiesWidget *mpw_;
LinkSingleElementWidget *lsew_;
}; };
#endif // ELEMENTPROPERTIESWIDGET_H #endif // ELEMENTPROPERTIESWIDGET_H

View File

@@ -53,44 +53,17 @@ MasterPropertiesWidget::~MasterPropertiesWidget()
/** /**
* @brief MasterPropertiesWidget::apply * @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() { bool MasterPropertiesWidget::apply() {
QList <Element *> to_link; if (QUndoCommand *undo = associatedUndo()) {
QList <Element *> linked_ = element_->linkedElements(); element_ -> diagram() -> undoStack().push(undo);
return true;
for (int i=0; i<ui->linked_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);
} }
return false;
} }
/** /**
@@ -105,6 +78,52 @@ void MasterPropertiesWidget::reset() {
buildInterface(); 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 <Element *> to_link;
QList <Element *> linked_ = element_->linkedElements();
for (int i=0; i<ui->linked_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 * @brief MasterPropertiesWidget::buildInterface
* Build the interface of the widget * Build the interface of the widget

View File

@@ -23,6 +23,7 @@
class QListWidgetItem; class QListWidgetItem;
class Element; class Element;
class QUndoCommand;
namespace Ui { namespace Ui {
class MasterPropertiesWidget; class MasterPropertiesWidget;
@@ -42,8 +43,9 @@ class MasterPropertiesWidget : public QWidget
explicit MasterPropertiesWidget(Element *elmt, QWidget *parent = 0); explicit MasterPropertiesWidget(Element *elmt, QWidget *parent = 0);
~MasterPropertiesWidget(); ~MasterPropertiesWidget();
void apply(); bool apply();
void reset(); void reset();
QUndoCommand* associatedUndo() const;
private: private:
void buildInterface(); void buildInterface();

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#include "changeelementinformationcommand.h"
#include "element.h"
#include <QObject>
/**
* @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);
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef CHANGEELEMENTINFORMATIONCOMMAND_H
#define CHANGEELEMENTINFORMATIONCOMMAND_H
#include <QUndoCommand>
#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