diff --git a/sources/QPropertyUndoCommand/qpropertyundocommand.cpp b/sources/QPropertyUndoCommand/qpropertyundocommand.cpp index 1ed38e173..1b2ce353c 100644 --- a/sources/QPropertyUndoCommand/qpropertyundocommand.cpp +++ b/sources/QPropertyUndoCommand/qpropertyundocommand.cpp @@ -16,7 +16,7 @@ along with QElectroTech. If not, see . */ #include "qpropertyundocommand.h" -#include +#include /** * @brief QPropertyUndoCommand::QPropertyUndoCommand @@ -33,12 +33,7 @@ QPropertyUndoCommand::QPropertyUndoCommand(QObject *object, const char *property 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 @@ -55,21 +50,15 @@ QPropertyUndoCommand::QPropertyUndoCommand(QObject *object, const char *property 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) -{ +void QPropertyUndoCommand::setNewValue(const QVariant &new_value) { m_new_value = new_value; - m_animation.setEndValue(new_value); } /** @@ -93,7 +82,6 @@ bool QPropertyUndoCommand::mergeWith(const QUndoCommand *other) 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; } @@ -107,8 +95,10 @@ void QPropertyUndoCommand::redo() { if (m_animate) { - m_animation.setDirection(QAnimationGroup::Forward); - m_animation.start(); + QPropertyAnimation *animation = new QPropertyAnimation(m_object, m_property_name); + animation->setStartValue(m_old_value); + animation->setEndValue(m_new_value); + animation->start(QAbstractAnimation::DeleteWhenStopped); } else m_object->setProperty(m_property_name, m_new_value); @@ -127,8 +117,10 @@ void QPropertyUndoCommand::undo() { if (m_animate) { - m_animation.setDirection(QAnimationGroup::Backward); - m_animation.start(); + QPropertyAnimation *animation = new QPropertyAnimation(m_object, m_property_name); + animation->setStartValue(m_new_value); + animation->setEndValue(m_old_value); + animation->start(QAbstractAnimation::DeleteWhenStopped); } else m_object->setProperty(m_property_name, m_old_value); diff --git a/sources/QPropertyUndoCommand/qpropertyundocommand.h b/sources/QPropertyUndoCommand/qpropertyundocommand.h index 5f7214ca2..821c637bc 100644 --- a/sources/QPropertyUndoCommand/qpropertyundocommand.h +++ b/sources/QPropertyUndoCommand/qpropertyundocommand.h @@ -20,7 +20,6 @@ #include #include -#include class QObject; @@ -50,7 +49,6 @@ class QPropertyUndoCommand : public QUndoCommand 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/eseventaddrect.cpp b/sources/editor/esevent/eseventaddrect.cpp index fe7daf3b2..cb26d5ac7 100644 --- a/sources/editor/esevent/eseventaddrect.cpp +++ b/sources/editor/esevent/eseventaddrect.cpp @@ -83,7 +83,7 @@ bool ESEventAddRect::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { updateHelpCross(event -> scenePos()); if (!m_rect) return false; - QRectF rect(m_rect->rectTopLeft(), m_scene->snapToGrid(event -> scenePos())); + QRectF rect(m_rect->rect().topLeft(), m_scene->snapToGrid(event -> scenePos())); m_rect -> setRect(rect); return true; } diff --git a/sources/editor/graphicspart/partrectangle.cpp b/sources/editor/graphicspart/partrectangle.cpp index 9ac978161..f0a30346f 100644 --- a/sources/editor/graphicspart/partrectangle.cpp +++ b/sources/editor/graphicspart/partrectangle.cpp @@ -129,47 +129,7 @@ void PartRectangle::setRect(const QRectF &rect) if (rect == m_rect) return; prepareGeometryChange(); m_rect = rect; -} - -/** - * @brief PartRectangle::rectTopLeft - * @return the rectangle top left in item coordinate - */ -QPointF PartRectangle::rectTopLeft() const { - return m_rect.topLeft(); -} - -/** - * @brief PartRectangle::setRectTopLeft - * @param point, set the rectangle top left in item coordinate. - * The rectangle size is unchanged - */ -void PartRectangle::setRectTopLeft(const QPointF &point) { - m_rect.moveTopLeft(point); -} - -/** - * @brief PartRectangle::setWidth - * Sets the width of the rectangle to the given width. - * The right edge is changed, but not the left one. - * @param w new value - */ -void PartRectangle::setWidth(qreal w) -{ - prepareGeometryChange(); - m_rect.setWidth(qAbs(w)); -} - -/** - * @brief PartRectangle::setHeight - * Sets the height of the rectangle to the given height. - * The bottom edge is changed, but not the top one. - * @param h new value - */ -void PartRectangle::setHeight(qreal h) -{ - prepareGeometryChange(); - m_rect.setHeight(qAbs(h)); + emit rectChanged(); } /** diff --git a/sources/editor/graphicspart/partrectangle.h b/sources/editor/graphicspart/partrectangle.h index 986a92c53..227f66b36 100644 --- a/sources/editor/graphicspart/partrectangle.h +++ b/sources/editor/graphicspart/partrectangle.h @@ -32,10 +32,7 @@ class PartRectangle : public CustomElementGraphicPart { Q_OBJECT - Q_PROPERTY(QPointF rectTopLeft READ rectTopLeft WRITE setRectTopLeft) - Q_PROPERTY(qreal width READ width WRITE setWidth) - Q_PROPERTY(qreal height READ height WRITE setHeight) - Q_PROPERTY(QRectF rect READ rect WRITE setRect) + Q_PROPERTY(QRectF rect READ rect WRITE setRect) // constructors, destructor public: @@ -44,6 +41,9 @@ class PartRectangle : public CustomElementGraphicPart private: PartRectangle(const PartRectangle &); + + signals: + void rectChanged(); // methods public: @@ -63,15 +63,6 @@ class PartRectangle : public CustomElementGraphicPart QRectF rect() const; void setRect(const QRectF &rect); - QPointF rectTopLeft () const; - void setRectTopLeft (const QPointF &point); - - qreal width () const {return rect().width();} - void setWidth (qreal w); - - qreal height () const { return rect().height();} - void setHeight (qreal h); - virtual QRectF sceneGeometricRect() const; virtual QPointF sceneTopLeft() const; diff --git a/sources/editor/rectangleeditor.cpp b/sources/editor/rectangleeditor.cpp index c9cdbc9f4..a564d5b15 100644 --- a/sources/editor/rectangleeditor.cpp +++ b/sources/editor/rectangleeditor.cpp @@ -18,6 +18,8 @@ #include "rectangleeditor.h" #include "partrectangle.h" #include "styleeditor.h" +#include "QPropertyUndoCommand/qpropertyundocommand.h" +#include "elementscene.h" /** Constructeur @@ -27,7 +29,8 @@ */ RectangleEditor::RectangleEditor(QETElementEditor *editor, PartRectangle *rect, QWidget *parent) : ElementItemEditor(editor, parent), - part(rect) + part(rect), + m_locked(false) { style_ = new StyleEditor(editor); @@ -67,32 +70,42 @@ RectangleEditor::~RectangleEditor() { } /** - Permet de specifier a cet editeur quelle primitive il doit editer. A noter - qu'un editeur peut accepter ou refuser d'editer une primitive. - L'editeur de rectangle acceptera d'editer la primitive new_part s'il s'agit - d'un objet de la classe PartRectangle. - @param new_part Nouvelle primitive a editer - @return true si l'editeur a accepter d'editer la primitive, false sinon -*/ -bool RectangleEditor::setPart(CustomElementPart *new_part) { - if (!new_part) { + * @brief RectangleEditor::setPart + * Specifie to this editor the part to edit. + * Note that an editor can accept or refuse to edit a part. This editor accept only partRectangle. + * @param new_part + * @return + */ +bool RectangleEditor::setPart(CustomElementPart *new_part) +{ + if (!new_part) + { + if (part) + disconnect(part, &PartRectangle::rectChanged, this, &RectangleEditor::updateForm); part = 0; style_ -> setPart(0); return(true); } - if (PartRectangle *part_rectangle = dynamic_cast(new_part)) { + + if (PartRectangle *part_rectangle = dynamic_cast(new_part)) + { + if (part == part_rectangle) return true; + if (part) + disconnect(part, &PartRectangle::rectChanged, this, &RectangleEditor::updateForm); part = part_rectangle; style_ -> setPart(part); updateForm(); + connect(part, &PartRectangle::rectChanged, this, &RectangleEditor::updateForm); return(true); - } else { - return(false); } + + return(false); } /** - @return la primitive actuellement editee, ou 0 si ce widget n'en edite pas -*/ + * @brief RectangleEditor::currentPart + * @return the curent edited part, or 0 if there is no edited part + */ CustomElementPart *RectangleEditor::currentPart() const { return(part); } @@ -106,52 +119,63 @@ QPointF RectangleEditor::editedTopLeft() const { } /** - Met a jour le rectangle a partir des donnees du formulaire -*/ -void RectangleEditor::updateRectangle() { - if (!part) return; - part -> setProperty("rectTopLeft", editedTopLeft()); - part -> setProperty("width", w -> value()); - part -> setProperty("height", h -> value()); -} - -/// Met a jour l'abscisse du coin superieur gauche du rectangle et cree un objet d'annulation -void RectangleEditor::updateRectangleX() { addChangePartCommand(tr("abscisse"), part, "rectTopLeft", editedTopLeft());} -/// Met a jour l'ordonnee du coin superieur gauche du rectangle et cree un objet d'annulation -void RectangleEditor::updateRectangleY() { addChangePartCommand(tr("ordonnée"), part, "rectTopLeft", editedTopLeft());} -/// Met a jour la largeur du rectangle et cree un objet d'annulation -void RectangleEditor::updateRectangleW() { addChangePartCommand(tr("largeur"), part, "width", w -> value());} -/// Met a jour la hauteur du rectangle et cree un objet d'annulation -void RectangleEditor::updateRectangleH() { addChangePartCommand(tr("hauteur"), part, "height", h -> value());} - -/** - Met a jour le formulaire d'edition -*/ -void RectangleEditor::updateForm() { + * @brief RectangleEditor::updateForm + * Update the values displayed by this widget + */ +void RectangleEditor::updateForm() +{ if (!part) return; activeConnections(false); - QPointF p = part->mapToScene(part->property("rectTopLeft").toPointF()); + + QRectF rect = part->property("rect").toRectF(); + QPointF p = part->mapToScene(rect.topLeft()); x->setValue(p.x()); y->setValue(p.y()); - w->setValue(part->property("width").toReal()); - h->setValue(part->property("height").toReal()); + w->setValue(rect.width()); + h->setValue(rect.height()); + activeConnections(true); } /** - Active ou desactive les connexionx signaux/slots entre les widgets internes. - @param active true pour activer les connexions, false pour les desactiver -*/ -void RectangleEditor::activeConnections(bool active) { - if (active) { - connect(x, SIGNAL(editingFinished()), this, SLOT(updateRectangleX())); - connect(y, SIGNAL(editingFinished()), this, SLOT(updateRectangleY())); - connect(w, SIGNAL(editingFinished()), this, SLOT(updateRectangleW())); - connect(h, SIGNAL(editingFinished()), this, SLOT(updateRectangleH())); - } else { - disconnect(x, SIGNAL(editingFinished()), this, SLOT(updateRectangleX())); - disconnect(y, SIGNAL(editingFinished()), this, SLOT(updateRectangleY())); - disconnect(w, SIGNAL(editingFinished()), this, SLOT(updateRectangleW())); - disconnect(h, SIGNAL(editingFinished()), this, SLOT(updateRectangleH())); + * @brief RectangleEditor::editingFinished + * Slot called when a editor widget is finish to be edited + * Update the geometry of the rectangle according to value of editing widget. + */ +void RectangleEditor::editingFinished() +{ + if (m_locked) return; + m_locked = true; + + QRectF rect(editedTopLeft(), QSizeF(w->value(), h->value())); + QPropertyUndoCommand *undo = new QPropertyUndoCommand(part, "rect", part->property("rect"), rect); + undo->setText(tr("Modifier un rectangle")); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + + m_locked = false; +} + +/** + * @brief RectangleEditor::activeConnections + * Enable/disable connection between editor widget and slot editingFinished + * True == enable | false == disable + * @param active + */ +void RectangleEditor::activeConnections(bool active) +{ + if (active) + { + connect(x, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + connect(y, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + connect(w, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + connect(h, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + } + else + { + disconnect(x, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + disconnect(y, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + disconnect(w, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + disconnect(h, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); } } diff --git a/sources/editor/rectangleeditor.h b/sources/editor/rectangleeditor.h index 2bb5d417f..c12127a68 100644 --- a/sources/editor/rectangleeditor.h +++ b/sources/editor/rectangleeditor.h @@ -24,36 +24,35 @@ class StyleEditor; /** This class provides a widget to edit rectangles within the element editor. */ -class RectangleEditor : public ElementItemEditor { +class RectangleEditor : public ElementItemEditor +{ Q_OBJECT - // constructors, destructor + + // constructors, destructor public: - RectangleEditor(QETElementEditor *, PartRectangle * = 0, QWidget * = 0); - virtual ~RectangleEditor(); + RectangleEditor(QETElementEditor *, PartRectangle * = 0, QWidget * = 0); + virtual ~RectangleEditor(); private: - RectangleEditor(const RectangleEditor &); + RectangleEditor(const RectangleEditor &); - // attributes + // attributes private: - PartRectangle *part; - StyleEditor *style_; - QDoubleSpinBox *x, *y, *w, *h; + PartRectangle *part; + StyleEditor *style_; + QDoubleSpinBox *x, *y, *w, *h; + bool m_locked; - // methods + // methods public: - virtual bool setPart(CustomElementPart *); - virtual CustomElementPart *currentPart() const; - QPointF editedTopLeft () const; + virtual bool setPart(CustomElementPart *); + virtual CustomElementPart *currentPart() const; + QPointF editedTopLeft () const; public slots: - void updateRectangle(); - void updateRectangleX(); - void updateRectangleY(); - void updateRectangleW(); - void updateRectangleH(); - void updateForm(); + void updateForm(); + void editingFinished(); private: - void activeConnections(bool); + void activeConnections(bool); }; #endif