mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2025-12-18 22:00:35 +01:00
Rectangle editor widget : use QPropertyUndoCommand instead of ChangePartCommand
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@4064 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
@@ -16,7 +16,7 @@
|
|||||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include "qpropertyundocommand.h"
|
#include "qpropertyundocommand.h"
|
||||||
#include <QAnimationGroup>
|
#include <QPropertyAnimation>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief QPropertyUndoCommand::QPropertyUndoCommand
|
* @brief QPropertyUndoCommand::QPropertyUndoCommand
|
||||||
@@ -33,12 +33,7 @@ QPropertyUndoCommand::QPropertyUndoCommand(QObject *object, const char *property
|
|||||||
m_old_value(old_value),
|
m_old_value(old_value),
|
||||||
m_new_value(new_value),
|
m_new_value(new_value),
|
||||||
m_animate(false)
|
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
|
* @brief QPropertyUndoCommand::QPropertyUndoCommand
|
||||||
@@ -55,21 +50,15 @@ QPropertyUndoCommand::QPropertyUndoCommand(QObject *object, const char *property
|
|||||||
m_property_name(property_name),
|
m_property_name(property_name),
|
||||||
m_old_value(old_value),
|
m_old_value(old_value),
|
||||||
m_animate(false)
|
m_animate(false)
|
||||||
{
|
{}
|
||||||
m_animation.setTargetObject(object);
|
|
||||||
m_animation.setPropertyName(property_name);
|
|
||||||
m_animation.setStartValue(old_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief QPropertyUndoCommand::setNewValue
|
* @brief QPropertyUndoCommand::setNewValue
|
||||||
* Set the new value of the property (set with redo) to @new_value
|
* Set the new value of the property (set with redo) to @new_value
|
||||||
* @param 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_new_value = new_value;
|
||||||
m_animation.setEndValue(new_value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -93,7 +82,6 @@ bool QPropertyUndoCommand::mergeWith(const QUndoCommand *other)
|
|||||||
QPropertyUndoCommand const *undo = static_cast<const QPropertyUndoCommand *>(other);
|
QPropertyUndoCommand const *undo = static_cast<const QPropertyUndoCommand *>(other);
|
||||||
if (m_object != undo->m_object || m_property_name != undo->m_property_name) return false;
|
if (m_object != undo->m_object || m_property_name != undo->m_property_name) return false;
|
||||||
m_new_value = undo->m_new_value;
|
m_new_value = undo->m_new_value;
|
||||||
m_animation.setEndValue(m_new_value);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,8 +95,10 @@ void QPropertyUndoCommand::redo()
|
|||||||
{
|
{
|
||||||
if (m_animate)
|
if (m_animate)
|
||||||
{
|
{
|
||||||
m_animation.setDirection(QAnimationGroup::Forward);
|
QPropertyAnimation *animation = new QPropertyAnimation(m_object, m_property_name);
|
||||||
m_animation.start();
|
animation->setStartValue(m_old_value);
|
||||||
|
animation->setEndValue(m_new_value);
|
||||||
|
animation->start(QAbstractAnimation::DeleteWhenStopped);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_object->setProperty(m_property_name, m_new_value);
|
m_object->setProperty(m_property_name, m_new_value);
|
||||||
@@ -127,8 +117,10 @@ void QPropertyUndoCommand::undo()
|
|||||||
{
|
{
|
||||||
if (m_animate)
|
if (m_animate)
|
||||||
{
|
{
|
||||||
m_animation.setDirection(QAnimationGroup::Backward);
|
QPropertyAnimation *animation = new QPropertyAnimation(m_object, m_property_name);
|
||||||
m_animation.start();
|
animation->setStartValue(m_new_value);
|
||||||
|
animation->setEndValue(m_old_value);
|
||||||
|
animation->start(QAbstractAnimation::DeleteWhenStopped);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_object->setProperty(m_property_name, m_old_value);
|
m_object->setProperty(m_property_name, m_old_value);
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
#include <QUndoCommand>
|
#include <QUndoCommand>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QPropertyAnimation>
|
|
||||||
|
|
||||||
class QObject;
|
class QObject;
|
||||||
|
|
||||||
@@ -50,7 +49,6 @@ class QPropertyUndoCommand : public QUndoCommand
|
|||||||
const char *m_property_name;
|
const char *m_property_name;
|
||||||
QVariant m_old_value, m_new_value;
|
QVariant m_old_value, m_new_value;
|
||||||
bool m_animate;
|
bool m_animate;
|
||||||
QPropertyAnimation m_animation;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QPROPERTYUNDOCOMMAND_H
|
#endif // QPROPERTYUNDOCOMMAND_H
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ bool ESEventAddRect::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
|
|||||||
updateHelpCross(event -> scenePos());
|
updateHelpCross(event -> scenePos());
|
||||||
if (!m_rect) return false;
|
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);
|
m_rect -> setRect(rect);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,47 +129,7 @@ void PartRectangle::setRect(const QRectF &rect)
|
|||||||
if (rect == m_rect) return;
|
if (rect == m_rect) return;
|
||||||
prepareGeometryChange();
|
prepareGeometryChange();
|
||||||
m_rect = rect;
|
m_rect = rect;
|
||||||
}
|
emit rectChanged();
|
||||||
|
|
||||||
/**
|
|
||||||
* @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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -32,9 +32,6 @@ class PartRectangle : public CustomElementGraphicPart
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
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
|
// constructors, destructor
|
||||||
@@ -45,6 +42,9 @@ class PartRectangle : public CustomElementGraphicPart
|
|||||||
private:
|
private:
|
||||||
PartRectangle(const PartRectangle &);
|
PartRectangle(const PartRectangle &);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void rectChanged();
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
public:
|
public:
|
||||||
enum { Type = UserType + 1109 };
|
enum { Type = UserType + 1109 };
|
||||||
@@ -63,15 +63,6 @@ class PartRectangle : public CustomElementGraphicPart
|
|||||||
QRectF rect() const;
|
QRectF rect() const;
|
||||||
void setRect(const QRectF &rect);
|
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 QRectF sceneGeometricRect() const;
|
||||||
virtual QPointF sceneTopLeft() const;
|
virtual QPointF sceneTopLeft() const;
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
#include "rectangleeditor.h"
|
#include "rectangleeditor.h"
|
||||||
#include "partrectangle.h"
|
#include "partrectangle.h"
|
||||||
#include "styleeditor.h"
|
#include "styleeditor.h"
|
||||||
|
#include "QPropertyUndoCommand/qpropertyundocommand.h"
|
||||||
|
#include "elementscene.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Constructeur
|
Constructeur
|
||||||
@@ -27,7 +29,8 @@
|
|||||||
*/
|
*/
|
||||||
RectangleEditor::RectangleEditor(QETElementEditor *editor, PartRectangle *rect, QWidget *parent) :
|
RectangleEditor::RectangleEditor(QETElementEditor *editor, PartRectangle *rect, QWidget *parent) :
|
||||||
ElementItemEditor(editor, parent),
|
ElementItemEditor(editor, parent),
|
||||||
part(rect)
|
part(rect),
|
||||||
|
m_locked(false)
|
||||||
{
|
{
|
||||||
style_ = new StyleEditor(editor);
|
style_ = new StyleEditor(editor);
|
||||||
|
|
||||||
@@ -67,31 +70,41 @@ RectangleEditor::~RectangleEditor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Permet de specifier a cet editeur quelle primitive il doit editer. A noter
|
* @brief RectangleEditor::setPart
|
||||||
qu'un editeur peut accepter ou refuser d'editer une primitive.
|
* Specifie to this editor the part to edit.
|
||||||
L'editeur de rectangle acceptera d'editer la primitive new_part s'il s'agit
|
* Note that an editor can accept or refuse to edit a part. This editor accept only partRectangle.
|
||||||
d'un objet de la classe PartRectangle.
|
* @param new_part
|
||||||
@param new_part Nouvelle primitive a editer
|
* @return
|
||||||
@return true si l'editeur a accepter d'editer la primitive, false sinon
|
|
||||||
*/
|
*/
|
||||||
bool RectangleEditor::setPart(CustomElementPart *new_part) {
|
bool RectangleEditor::setPart(CustomElementPart *new_part)
|
||||||
if (!new_part) {
|
{
|
||||||
|
if (!new_part)
|
||||||
|
{
|
||||||
|
if (part)
|
||||||
|
disconnect(part, &PartRectangle::rectChanged, this, &RectangleEditor::updateForm);
|
||||||
part = 0;
|
part = 0;
|
||||||
style_ -> setPart(0);
|
style_ -> setPart(0);
|
||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
if (PartRectangle *part_rectangle = dynamic_cast<PartRectangle *>(new_part)) {
|
|
||||||
|
if (PartRectangle *part_rectangle = dynamic_cast<PartRectangle *>(new_part))
|
||||||
|
{
|
||||||
|
if (part == part_rectangle) return true;
|
||||||
|
if (part)
|
||||||
|
disconnect(part, &PartRectangle::rectChanged, this, &RectangleEditor::updateForm);
|
||||||
part = part_rectangle;
|
part = part_rectangle;
|
||||||
style_ -> setPart(part);
|
style_ -> setPart(part);
|
||||||
updateForm();
|
updateForm();
|
||||||
|
connect(part, &PartRectangle::rectChanged, this, &RectangleEditor::updateForm);
|
||||||
return(true);
|
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 {
|
CustomElementPart *RectangleEditor::currentPart() const {
|
||||||
return(part);
|
return(part);
|
||||||
@@ -106,52 +119,63 @@ QPointF RectangleEditor::editedTopLeft() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Met a jour le rectangle a partir des donnees du formulaire
|
* @brief RectangleEditor::updateForm
|
||||||
|
* Update the values displayed by this widget
|
||||||
*/
|
*/
|
||||||
void RectangleEditor::updateRectangle() {
|
void RectangleEditor::updateForm()
|
||||||
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() {
|
|
||||||
if (!part) return;
|
if (!part) return;
|
||||||
activeConnections(false);
|
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());
|
x->setValue(p.x());
|
||||||
y->setValue(p.y());
|
y->setValue(p.y());
|
||||||
w->setValue(part->property("width").toReal());
|
w->setValue(rect.width());
|
||||||
h->setValue(part->property("height").toReal());
|
h->setValue(rect.height());
|
||||||
|
|
||||||
activeConnections(true);
|
activeConnections(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Active ou desactive les connexionx signaux/slots entre les widgets internes.
|
* @brief RectangleEditor::editingFinished
|
||||||
@param active true pour activer les connexions, false pour les desactiver
|
* 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::activeConnections(bool active) {
|
void RectangleEditor::editingFinished()
|
||||||
if (active) {
|
{
|
||||||
connect(x, SIGNAL(editingFinished()), this, SLOT(updateRectangleX()));
|
if (m_locked) return;
|
||||||
connect(y, SIGNAL(editingFinished()), this, SLOT(updateRectangleY()));
|
m_locked = true;
|
||||||
connect(w, SIGNAL(editingFinished()), this, SLOT(updateRectangleW()));
|
|
||||||
connect(h, SIGNAL(editingFinished()), this, SLOT(updateRectangleH()));
|
QRectF rect(editedTopLeft(), QSizeF(w->value(), h->value()));
|
||||||
} else {
|
QPropertyUndoCommand *undo = new QPropertyUndoCommand(part, "rect", part->property("rect"), rect);
|
||||||
disconnect(x, SIGNAL(editingFinished()), this, SLOT(updateRectangleX()));
|
undo->setText(tr("Modifier un rectangle"));
|
||||||
disconnect(y, SIGNAL(editingFinished()), this, SLOT(updateRectangleY()));
|
undo->enableAnimation();
|
||||||
disconnect(w, SIGNAL(editingFinished()), this, SLOT(updateRectangleW()));
|
elementScene()->undoStack().push(undo);
|
||||||
disconnect(h, SIGNAL(editingFinished()), this, SLOT(updateRectangleH()));
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,10 @@ class StyleEditor;
|
|||||||
/**
|
/**
|
||||||
This class provides a widget to edit rectangles within the element editor.
|
This class provides a widget to edit rectangles within the element editor.
|
||||||
*/
|
*/
|
||||||
class RectangleEditor : public ElementItemEditor {
|
class RectangleEditor : public ElementItemEditor
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
// constructors, destructor
|
// constructors, destructor
|
||||||
public:
|
public:
|
||||||
RectangleEditor(QETElementEditor *, PartRectangle * = 0, QWidget * = 0);
|
RectangleEditor(QETElementEditor *, PartRectangle * = 0, QWidget * = 0);
|
||||||
@@ -38,6 +40,7 @@ class RectangleEditor : public ElementItemEditor {
|
|||||||
PartRectangle *part;
|
PartRectangle *part;
|
||||||
StyleEditor *style_;
|
StyleEditor *style_;
|
||||||
QDoubleSpinBox *x, *y, *w, *h;
|
QDoubleSpinBox *x, *y, *w, *h;
|
||||||
|
bool m_locked;
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
public:
|
public:
|
||||||
@@ -46,12 +49,8 @@ class RectangleEditor : public ElementItemEditor {
|
|||||||
QPointF editedTopLeft () const;
|
QPointF editedTopLeft () const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateRectangle();
|
|
||||||
void updateRectangleX();
|
|
||||||
void updateRectangleY();
|
|
||||||
void updateRectangleW();
|
|
||||||
void updateRectangleH();
|
|
||||||
void updateForm();
|
void updateForm();
|
||||||
|
void editingFinished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void activeConnections(bool);
|
void activeConnections(bool);
|
||||||
|
|||||||
Reference in New Issue
Block a user