diff --git a/dev_doc/ID_of_QUndoCommand.txt b/dev_doc/ID_of_QUndoCommand.txt index 8be57ee23..a0966f646 100755 --- a/dev_doc/ID_of_QUndoCommand.txt +++ b/dev_doc/ID_of_QUndoCommand.txt @@ -3,3 +3,4 @@ LinkElementCommand = 2 ItemResizerCommand = 3 ChangeShapeStyleCommand = 4 QetShapeGeometryCommand = 5 +QPropertyUndoCommand = 10 000 diff --git a/qelectrotech.pro b/qelectrotech.pro index 32fcafa0d..20bf76304 100644 --- a/qelectrotech.pro +++ b/qelectrotech.pro @@ -63,6 +63,7 @@ DEFINES += QET_ALLOW_OVERRIDE_CD_OPTION include(sources/PropertiesEditor/PropertiesEditor.pri) include(sources/QetGraphicsItemModeler/QetGraphicsItemModeler.pri) +include(sources/QPropertyUndoCommand/QPropertyUndoCommand.pri) TEMPLATE = app DEPENDPATH += . diff --git a/sources/QPropertyUndoCommand/QPropertyUndoCommand.pri b/sources/QPropertyUndoCommand/QPropertyUndoCommand.pri new file mode 100755 index 000000000..6f91dd24e --- /dev/null +++ b/sources/QPropertyUndoCommand/QPropertyUndoCommand.pri @@ -0,0 +1,5 @@ +HEADERS += \ + $$PWD/qpropertyundocommand.h + +SOURCES += \ + $$PWD/qpropertyundocommand.cpp diff --git a/sources/QPropertyUndoCommand/qpropertyundocommand.cpp b/sources/QPropertyUndoCommand/qpropertyundocommand.cpp new file mode 100644 index 000000000..1ed38e173 --- /dev/null +++ b/sources/QPropertyUndoCommand/qpropertyundocommand.cpp @@ -0,0 +1,138 @@ +/* + Copyright 2006-2015 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 "qpropertyundocommand.h" +#include + +/** + * @brief QPropertyUndoCommand::QPropertyUndoCommand + * Default constructor with old and new value + * This command don't take ownership of @object + * @param object + * @param old_value + * @param new_value + */ +QPropertyUndoCommand::QPropertyUndoCommand(QObject *object, const char *property_name, const QVariant &old_value, const QVariant &new_value, QUndoCommand *parent) : + QUndoCommand(parent), + m_object(object), + m_property_name(property_name), + m_old_value(old_value), + m_new_value(new_value), + m_animate(false) +{ + m_animation.setTargetObject(object); + m_animation.setPropertyName(property_name); + m_animation.setStartValue(old_value); + m_animation.setEndValue(new_value); +} + +/** + * @brief QPropertyUndoCommand::QPropertyUndoCommand + * Default constructor with old value. + * Call setNewValue to setup the new value of the edited QObject + * This command don't take ownership of @object + * @param object + * @param old_value + * @param parent + */ +QPropertyUndoCommand::QPropertyUndoCommand(QObject *object, const char *property_name, const QVariant &old_value, QUndoCommand *parent) : + QUndoCommand(parent), + m_object(object), + m_property_name(property_name), + m_old_value(old_value), + m_animate(false) +{ + m_animation.setTargetObject(object); + m_animation.setPropertyName(property_name); + m_animation.setStartValue(old_value); +} + +/** + * @brief QPropertyUndoCommand::setNewValue + * Set the new value of the property (set with redo) to @new_value + * @param new_value + */ +void QPropertyUndoCommand::setNewValue(const QVariant &new_value) +{ + m_new_value = new_value; + m_animation.setEndValue(new_value); +} + +/** + * @brief QPropertyUndoCommand::enableAnimation + * True to enable animation + * @param animate + */ +void QPropertyUndoCommand::enableAnimation (bool animate) { + m_animate = animate; +} + +/** + * @brief QPropertyUndoCommand::mergeWith + * Try to merge this command with other command + * @param other + * @return true if was merged, else false + */ +bool QPropertyUndoCommand::mergeWith(const QUndoCommand *other) +{ + if (id() != other->id() || other->childCount()) return false; + QPropertyUndoCommand const *undo = static_cast(other); + if (m_object != undo->m_object || m_property_name != undo->m_property_name) return false; + m_new_value = undo->m_new_value; + m_animation.setEndValue(m_new_value); + return true; +} + +/** + * @brief QPropertyUndoCommand::redo + * Redo this command + */ +void QPropertyUndoCommand::redo() +{ + if (m_object->property(m_property_name) != m_new_value) + { + if (m_animate) + { + m_animation.setDirection(QAnimationGroup::Forward); + m_animation.start(); + } + else + m_object->setProperty(m_property_name, m_new_value); + } + + QUndoCommand::redo(); +} + +/** + * @brief QPropertyUndoCommand::undo + * Undo this command + */ +void QPropertyUndoCommand::undo() +{ + if (m_object->property(m_property_name) != m_old_value) + { + if (m_animate) + { + m_animation.setDirection(QAnimationGroup::Backward); + m_animation.start(); + } + else + m_object->setProperty(m_property_name, m_old_value); + } + + QUndoCommand::undo(); +} diff --git a/sources/QPropertyUndoCommand/qpropertyundocommand.h b/sources/QPropertyUndoCommand/qpropertyundocommand.h new file mode 100644 index 000000000..5f7214ca2 --- /dev/null +++ b/sources/QPropertyUndoCommand/qpropertyundocommand.h @@ -0,0 +1,56 @@ +/* + Copyright 2006-2015 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 QPROPERTYUNDOCOMMAND_H +#define QPROPERTYUNDOCOMMAND_H + +#include +#include +#include + +class QObject; + +/** + * @brief The QPropertyUndoCommand class + * This undo command manage QProperty of a QObject. + * This undo command can use QPropertyAnimation to animate the change when undo/redo is call + * To use animation call setAnimated(true). By default animation is disable. + * Some QVariant date can't be animated and result this command don't work. + */ +class QPropertyUndoCommand : public QUndoCommand +{ + public: + QPropertyUndoCommand(QObject *object, const char *property_name, const QVariant &old_value, const QVariant &new_value, QUndoCommand *parent = 0); + QPropertyUndoCommand(QObject *object, const char *property_name, const QVariant &old_value, QUndoCommand *parent = 0); + + void setNewValue(const QVariant &new_value); + void enableAnimation (bool animate = true); + + int id() const{return 10000;} + virtual bool mergeWith(const QUndoCommand *other); + void redo(); + void undo(); + + private: + QObject *m_object; + const char *m_property_name; + QVariant m_old_value, m_new_value; + bool m_animate; + QPropertyAnimation m_animation; +}; + +#endif // QPROPERTYUNDOCOMMAND_H diff --git a/sources/editor/esevent/eseventaddpolygon.cpp b/sources/editor/esevent/eseventaddpolygon.cpp index edeabd15c..2c1d9855a 100644 --- a/sources/editor/esevent/eseventaddpolygon.cpp +++ b/sources/editor/esevent/eseventaddpolygon.cpp @@ -103,13 +103,16 @@ bool ESEventAddPolygon::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { * @param event * @return */ -bool ESEventAddPolygon::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) { - if (event -> button() == Qt::LeftButton) { - if (m_polygon) { - m_polygon -> addPoint(m_scene -> snapToGrid(event -> scenePos())); +bool ESEventAddPolygon::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) +{ + if (event -> button() == Qt::LeftButton) + { + if (m_polygon) + { + m_polygon->removeLastPoint(); m_scene -> undoStack().push(new AddPartCommand(QObject::tr("Polygone"), m_scene, m_polygon)); - //Set m_polygon to nullptr for create new polygon at next mouse press + //Set m_polygon to nullptr for create new polygon at next mouse press m_polygon = nullptr; return true; } diff --git a/sources/editor/graphicspart/customelementgraphicpart.cpp b/sources/editor/graphicspart/customelementgraphicpart.cpp index 73880d7e8..d87fcc1b4 100644 --- a/sources/editor/graphicspart/customelementgraphicpart.cpp +++ b/sources/editor/graphicspart/customelementgraphicpart.cpp @@ -17,7 +17,7 @@ */ #include "customelementgraphicpart.h" #include "elementscene.h" -#include "editorcommands.h" +#include "QPropertyUndoCommand/qpropertyundocommand.h" /** * @brief CustomElementGraphicPart::CustomElementGraphicPart @@ -40,7 +40,6 @@ CustomElementGraphicPart::CustomElementGraphicPart(QETElementEditor *editor, QGr #if QT_VERSION >= 0x040600 setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); #endif - setAcceptedMouseButtons(Qt::LeftButton); setAcceptHoverEvents(true); } @@ -462,7 +461,12 @@ void CustomElementGraphicPart::mouseMoveEvent(QGraphicsSceneMouseEvent *event) void CustomElementGraphicPart::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if((event->button() & Qt::LeftButton) && (flags() & QGraphicsItem::ItemIsMovable) && m_origin_pos != pos()) - elementScene()->stackAction(new MovePartsCommand(pos() - m_origin_pos, 0, QList{this})); + { + QPropertyUndoCommand *undo = new QPropertyUndoCommand(this, "pos", QVariant(m_origin_pos), QVariant(pos())); + undo->setText(tr("Déplacer une primitive")); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } QGraphicsObject::mouseReleaseEvent(event); } diff --git a/sources/editor/graphicspart/partarc.cpp b/sources/editor/graphicspart/partarc.cpp index 5a2ddf475..f916cfd82 100644 --- a/sources/editor/graphicspart/partarc.cpp +++ b/sources/editor/graphicspart/partarc.cpp @@ -16,7 +16,9 @@ along with QElectroTech. If not, see . */ #include "partarc.h" -#include "editorcommands.h" +#include "QPropertyUndoCommand/qpropertyundocommand.h" +#include "elementscene.h" + /** * @brief PartArc::PartArc @@ -27,7 +29,8 @@ PartArc::PartArc(QETElementEditor *editor, QGraphicsItem *parent) : AbstractPartEllipse(editor, parent), m_handler(10), - m_handler_index(-1) + m_handler_index(-1), + m_undo_command(nullptr) { m_start_angle = 0; m_span_angle = -1440; @@ -152,7 +155,11 @@ void PartArc::mousePressEvent(QGraphicsSceneMouseEvent *event) m_handler_index = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForRect(m_rect)); if(m_handler_index >= 0 && m_handler_index <= 7) //User click on an handler - m_undo_command = new ChangePartCommand(tr("Arc"), this, "rect", QVariant(m_rect)); + { + m_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect)); + m_undo_command->setText(tr("Modifier un arc")); + m_undo_command->enableAnimation(); + } else CustomElementGraphicPart::mousePressEvent(event); } @@ -190,7 +197,7 @@ void PartArc::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) m_rect = m_rect.normalized(); m_undo_command->setNewValue(QVariant(m_rect)); - elementScene()->stackAction(m_undo_command); + elementScene()->undoStack().push(m_undo_command); m_undo_command = nullptr; m_handler_index = -1; } diff --git a/sources/editor/graphicspart/partarc.h b/sources/editor/graphicspart/partarc.h index 3121bf821..e6df024ad 100644 --- a/sources/editor/graphicspart/partarc.h +++ b/sources/editor/graphicspart/partarc.h @@ -21,7 +21,7 @@ #include "abstractpartellipse.h" #include "QetGraphicsItemModeler/qetgraphicshandlerutility.h" -class ChangePartCommand; +class QPropertyUndoCommand; /** * @brief The PartArc class @@ -65,6 +65,6 @@ class PartArc : public AbstractPartEllipse private: QetGraphicsHandlerUtility m_handler; int m_handler_index; - ChangePartCommand *m_undo_command; + QPropertyUndoCommand *m_undo_command; }; #endif diff --git a/sources/editor/graphicspart/partellipse.cpp b/sources/editor/graphicspart/partellipse.cpp index 0d1f993bb..4c58e8573 100644 --- a/sources/editor/graphicspart/partellipse.cpp +++ b/sources/editor/graphicspart/partellipse.cpp @@ -16,7 +16,8 @@ along with QElectroTech. If not, see . */ #include "partellipse.h" -#include "editorcommands.h" +#include "QPropertyUndoCommand/qpropertyundocommand.h" +#include "elementscene.h" /** * @brief PartEllipse::PartEllipse @@ -27,7 +28,8 @@ PartEllipse::PartEllipse(QETElementEditor *editor, QGraphicsItem *parent) : AbstractPartEllipse(editor, parent), m_handler(10), - m_handler_index(-1) + m_handler_index(-1), + m_undo_command(nullptr) {} /** @@ -155,7 +157,11 @@ void PartEllipse::mousePressEvent(QGraphicsSceneMouseEvent *event) m_handler_index = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForRect(m_rect)); if(m_handler_index >= 0 && m_handler_index <= 7) //User click on an handler - m_undo_command = new ChangePartCommand(tr("Ellipse"), this, "rect", QVariant(m_rect)); + { + m_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect)); + m_undo_command->setText(tr("Modifier une ellipse")); + m_undo_command->enableAnimation(); + } else CustomElementGraphicPart::mousePressEvent(event); } @@ -193,7 +199,7 @@ void PartEllipse::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) m_rect = m_rect.normalized(); m_undo_command->setNewValue(QVariant(m_rect)); - elementScene()->stackAction(m_undo_command); + elementScene()->undoStack().push(m_undo_command); m_undo_command = nullptr; m_handler_index = -1; } diff --git a/sources/editor/graphicspart/partellipse.h b/sources/editor/graphicspart/partellipse.h index bfe121c89..15147fbf0 100644 --- a/sources/editor/graphicspart/partellipse.h +++ b/sources/editor/graphicspart/partellipse.h @@ -21,7 +21,7 @@ #include "abstractpartellipse.h" #include "QetGraphicsItemModeler/qetgraphicshandlerutility.h" -class ChangePartCommand; +class QPropertyUndoCommand; /** * @brief The PartEllipse class @@ -66,6 +66,6 @@ class PartEllipse : public AbstractPartEllipse private: QetGraphicsHandlerUtility m_handler; int m_handler_index; - ChangePartCommand *m_undo_command; + QPropertyUndoCommand *m_undo_command; }; #endif diff --git a/sources/editor/graphicspart/partline.cpp b/sources/editor/graphicspart/partline.cpp index 6f67a81eb..ebd9cdd79 100644 --- a/sources/editor/graphicspart/partline.cpp +++ b/sources/editor/graphicspart/partline.cpp @@ -17,7 +17,8 @@ */ #include "partline.h" #include -#include "editorcommands.h" +#include "elementscene.h" +#include "QPropertyUndoCommand/qpropertyundocommand.h" /** @@ -33,7 +34,8 @@ PartLine::PartLine(QETElementEditor *editor, QGraphicsItem *parent) : second_end(Qet::None), second_length(1.5), m_handler(10), - m_handler_index(-1) + m_handler_index(-1), + m_undo_command(nullptr) {} /// Destructeur @@ -189,7 +191,11 @@ void PartLine::mousePressEvent(QGraphicsSceneMouseEvent *event) m_handler_index = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForLine(m_line)); if(m_handler_index >= 0 && m_handler_index <= 1) //User click on an handler - m_undo_command = new ChangePartCommand(tr("Ligne"), this, "line", QVariant(m_line)); + { + m_undo_command = new QPropertyUndoCommand(this, "line", QVariant(m_line)); + m_undo_command->setText(tr("Modifier une ligne")); + m_undo_command->enableAnimation(); + } else CustomElementGraphicPart::mousePressEvent(event); } @@ -224,7 +230,7 @@ void PartLine::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) if (m_handler_index >= 0 && m_handler_index <= 1) { m_undo_command->setNewValue(QVariant(m_line)); - elementScene()->stackAction(m_undo_command); + elementScene()->undoStack().push(m_undo_command); m_undo_command = nullptr; m_handler_index = -1; } diff --git a/sources/editor/graphicspart/partline.h b/sources/editor/graphicspart/partline.h index 95a3762d2..4413f73df 100644 --- a/sources/editor/graphicspart/partline.h +++ b/sources/editor/graphicspart/partline.h @@ -22,7 +22,7 @@ #include "qet.h" #include "QetGraphicsItemModeler/qetgraphicshandlerutility.h" -class ChangePartCommand; +class QPropertyUndoCommand; /** This class represents a line primitive which may be used to compose the @@ -119,6 +119,6 @@ class PartLine : public CustomElementGraphicPart QLineF m_line; QetGraphicsHandlerUtility m_handler; int m_handler_index; - ChangePartCommand *m_undo_command; + QPropertyUndoCommand *m_undo_command; }; #endif diff --git a/sources/editor/graphicspart/partpolygon.cpp b/sources/editor/graphicspart/partpolygon.cpp index 618a585aa..d539e56c4 100644 --- a/sources/editor/graphicspart/partpolygon.cpp +++ b/sources/editor/graphicspart/partpolygon.cpp @@ -16,7 +16,8 @@ along with QElectroTech. If not, see . */ #include "partpolygon.h" -#include "editorcommands.h" +#include "QPropertyUndoCommand/qpropertyundocommand.h" +#include "elementscene.h" /** @@ -29,13 +30,16 @@ PartPolygon::PartPolygon(QETElementEditor *editor, QGraphicsItem *parent) : CustomElementGraphicPart(editor, parent), m_closed(false), m_handler(10), - m_handler_index(-1) + m_handler_index(-1), + m_undo_command(nullptr) {} /** * @brief PartPolygon::~PartPolygon */ -PartPolygon::~PartPolygon() {} +PartPolygon::~PartPolygon() { + if(m_undo_command) delete m_undo_command; +} /** * @brief PartPolygon::paint @@ -247,7 +251,10 @@ void PartPolygon::mousePressEvent(QGraphicsSceneMouseEvent *event) m_handler_index = m_handler.pointIsHoverHandler(event->pos(), m_polygon); if(m_handler_index >= 0) //User click on an handler - m_undo_command = new ChangePartCommand(tr("Polygone"), this, "polygon", QVariant(m_polygon)); + { + m_undo_command = new QPropertyUndoCommand(this, "polygon", QVariant(m_polygon)); + m_undo_command->setText(tr("Modifier un polygone")); + } else CustomElementGraphicPart::mousePressEvent(event); } @@ -282,7 +289,7 @@ void PartPolygon::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) if (m_handler_index >= 0) { m_undo_command->setNewValue(QVariant(m_polygon)); - elementScene()->stackAction(m_undo_command); + elementScene()->undoStack().push(m_undo_command); m_undo_command = nullptr; m_handler_index = -1; } diff --git a/sources/editor/graphicspart/partpolygon.h b/sources/editor/graphicspart/partpolygon.h index c6b863a4d..c7f73b26a 100644 --- a/sources/editor/graphicspart/partpolygon.h +++ b/sources/editor/graphicspart/partpolygon.h @@ -23,7 +23,7 @@ #include "QetGraphicsItemModeler/qetgraphicshandlerutility.h" -class ChangePartCommand; +class QPropertyUndoCommand; /** * @brief The PartPolygon class @@ -90,6 +90,6 @@ class PartPolygon : public CustomElementGraphicPart QPolygonF m_polygon; QetGraphicsHandlerUtility m_handler; int m_handler_index; - ChangePartCommand *m_undo_command; + QPropertyUndoCommand *m_undo_command; }; #endif diff --git a/sources/editor/graphicspart/partrectangle.cpp b/sources/editor/graphicspart/partrectangle.cpp index 70f0658cc..fee6a7b83 100644 --- a/sources/editor/graphicspart/partrectangle.cpp +++ b/sources/editor/graphicspart/partrectangle.cpp @@ -17,7 +17,7 @@ */ #include "partrectangle.h" #include "elementscene.h" -#include "editorcommands.h" +#include "QPropertyUndoCommand/qpropertyundocommand.h" /** * @brief PartRectangle::PartRectangle @@ -28,7 +28,8 @@ PartRectangle::PartRectangle(QETElementEditor *editor, QGraphicsItem *parent) : CustomElementGraphicPart(editor, parent), m_handler(10), - m_handler_index(-1) + m_handler_index(-1), + m_undo_command(nullptr) {} /** @@ -268,7 +269,11 @@ void PartRectangle::mousePressEvent(QGraphicsSceneMouseEvent *event) m_handler_index = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForRect(m_rect)); if(m_handler_index >= 0 && m_handler_index <= 7) //User click on an handler - m_undo_command = new ChangePartCommand(tr("Rectangle"), this, "rect", QVariant(m_rect)); + { + m_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect)); + m_undo_command->setText(tr("Modifier un rectangle")); + m_undo_command->enableAnimation(); + } else CustomElementGraphicPart::mousePressEvent(event); } @@ -306,7 +311,7 @@ void PartRectangle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) m_rect = m_rect.normalized(); m_undo_command->setNewValue(QVariant(m_rect)); - elementScene()->stackAction(m_undo_command); + elementScene()->undoStack().push(m_undo_command); m_undo_command = nullptr; m_handler_index = -1; } diff --git a/sources/editor/graphicspart/partrectangle.h b/sources/editor/graphicspart/partrectangle.h index 75c4ba24f..9e0001e52 100644 --- a/sources/editor/graphicspart/partrectangle.h +++ b/sources/editor/graphicspart/partrectangle.h @@ -21,7 +21,7 @@ #include "customelementgraphicpart.h" #include "QetGraphicsItemModeler/qetgraphicshandlerutility.h" -class ChangePartCommand; +class QPropertyUndoCommand; /** * This class represents a rectangle primitive which may be used to compose the @@ -92,6 +92,6 @@ class PartRectangle : public CustomElementGraphicPart QList saved_points_; QetGraphicsHandlerUtility m_handler; int m_handler_index; - ChangePartCommand *m_undo_command; + QPropertyUndoCommand *m_undo_command; }; #endif