Add undo command for QetShapeItem geometry change

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@4046 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
blacksun
2015-07-12 13:35:40 +00:00
parent 57fdcd70a4
commit 27117ef9d1
5 changed files with 249 additions and 30 deletions

View File

@@ -2,3 +2,4 @@ ChangeElementInformationCommand = 1
LinkElementCommand = 2 LinkElementCommand = 2
ItemResizerCommand = 3 ItemResizerCommand = 3
ChangeShapeStyleCommand = 4 ChangeShapeStyleCommand = 4
QetShapeGeometryCommand = 5

View File

@@ -22,6 +22,7 @@
#include "shapegraphicsitempropertieswidget.h" #include "shapegraphicsitempropertieswidget.h"
#include "PropertiesEditor/propertieseditordialog.h" #include "PropertiesEditor/propertieseditordialog.h"
#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h" #include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
#include "qetshapegeometrycommand.h"
typedef QetGraphicsHandlerUtility QGHU; typedef QetGraphicsHandlerUtility QGHU;
@@ -40,7 +41,8 @@ QetShapeItem::QetShapeItem(QPointF p1, QPointF p2, ShapeType type, QGraphicsItem
m_P1 (Diagram::snapToGrid(p1)), m_P1 (Diagram::snapToGrid(p1)),
m_P2 (Diagram::snapToGrid(p2)), m_P2 (Diagram::snapToGrid(p2)),
m_hovered(false), m_hovered(false),
m_mouse_grab_handler(false) m_mouse_grab_handler(false),
m_undo_command(nullptr)
{ {
if (type == Polyline) m_polygon << m_P1 << m_P2; if (type == Polyline) m_polygon << m_P1 << m_P2;
@@ -49,7 +51,9 @@ QetShapeItem::QetShapeItem(QPointF p1, QPointF p2, ShapeType type, QGraphicsItem
} }
QetShapeItem::~QetShapeItem() QetShapeItem::~QetShapeItem()
{} {
if (m_undo_command) delete m_undo_command;
}
/** /**
* @brief QetShapeItem::setStyle * @brief QetShapeItem::setStyle
@@ -70,21 +74,36 @@ void QetShapeItem::setStyle(Qt::PenStyle newStyle)
* the last point of the polyline is replaced by P2. * the last point of the polyline is replaced by P2.
* @param P2 * @param P2
*/ */
void QetShapeItem::setP2(QPointF P2) { void QetShapeItem::setP2(const QPointF &P2)
P2 = Diagram::snapToGrid(P2); {
if (m_shapeType == Polyline && m_polygon.last() != P2)
if (m_shapeType == Polyline) { {
prepareGeometryChange(); prepareGeometryChange();
m_polygon.replace(m_polygon.size()-1, P2); m_polygon.replace(m_polygon.size()-1, P2);
} }
else { else if (P2 != m_P2)
if (P2 == m_P2) return; {
prepareGeometryChange(); prepareGeometryChange();
m_P2 = P2; m_P2 = P2;
} }
setTransformOriginPoint(boundingRect().center()); setTransformOriginPoint(boundingRect().center());
} }
/**
* @brief QetShapeItem::setLine
* Set item geometry to line (only available for line shape)
* @param line
*/
void QetShapeItem::setLine(const QLineF &line)
{
if (Q_LIKELY(m_shapeType == Line))
{
prepareGeometryChange();
m_P1 = line.p1();
m_P2 = line.p2();
}
}
/** /**
* @brief QetShapeItem::setRect * @brief QetShapeItem::setRect
* Set this item geometry to rect (only available if shape is a rectangle or an ellipse) * Set this item geometry to rect (only available if shape is a rectangle or an ellipse)
@@ -110,7 +129,7 @@ bool QetShapeItem::setRect(const QRectF &rect)
* @param polygon : new polygon * @param polygon : new polygon
* @return true if item is polygon, else false * @return true if item is polygon, else false
*/ */
bool QetShapeItem::setPolygon(const QPolygon &polygon) bool QetShapeItem::setPolygon(const QPolygonF &polygon)
{ {
if (Q_UNLIKELY(m_shapeType != Polyline)) return false; if (Q_UNLIKELY(m_shapeType != Polyline)) return false;
prepareGeometryChange(); prepareGeometryChange();
@@ -173,26 +192,18 @@ QRectF QetShapeItem::boundingRect() const {
* @brief QetShapeItem::shape * @brief QetShapeItem::shape
* @return the shape of this item * @return the shape of this item
*/ */
QPainterPath QetShapeItem::shape() const { QPainterPath QetShapeItem::shape() const
{
QPainterPath path; QPainterPath path;
switch (m_shapeType) { switch (m_shapeType)
case Line: {
path.moveTo(m_P1); case Line: path.moveTo(m_P1);
path.lineTo(m_P2); path.lineTo(m_P2); break;
break; case Rectangle: path.addRect(QRectF(m_P1, m_P2)); break;
case Rectangle: case Ellipse: path.addEllipse(QRectF(m_P1, m_P2)); break;
path.addRect(QRectF(m_P1, m_P2)); case Polyline: path.addPolygon(m_polygon); break;
break; default: Q_ASSERT(false); break;
case Ellipse:
path.addEllipse(QRectF(m_P1, m_P2));
break;
case Polyline:
path.addPolygon(m_polygon);
break;
default:
Q_ASSERT(false);
break;
} }
QPainterPathStroker pps; QPainterPathStroker pps;
@@ -371,6 +382,14 @@ void QetShapeItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{ {
//User click on an handler //User click on an handler
m_mouse_grab_handler = true; m_mouse_grab_handler = true;
switch (m_shapeType)
{
case Line: m_undo_command = new QetShapeGeometryCommand(this, QLineF(m_P1, m_P2)); break;
case Rectangle: m_undo_command = new QetShapeGeometryCommand(this, QRectF(m_P1, m_P2)); break;
case Ellipse: m_undo_command = new QetShapeGeometryCommand(this, QRectF(m_P1, m_P2)); break;
case Polyline: m_undo_command = new QetShapeGeometryCommand(this, m_polygon); break;
}
return; return;
} }
} }
@@ -441,7 +460,26 @@ void QetShapeItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
*/ */
void QetShapeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) void QetShapeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{ {
if (m_mouse_grab_handler)
{
m_mouse_grab_handler = false; m_mouse_grab_handler = false;
switch(m_shapeType)
{
case Line: m_undo_command->setNewLine(QLineF(m_P1, m_P2)); break;
case Rectangle: m_undo_command->setNewRect(QRectF(m_P1, m_P2)); break;
case Ellipse: m_undo_command->setNewRect(QRectF(m_P1, m_P2)); break;
case Polyline : m_undo_command->setNewPolygon(m_polygon); break;
}
if (diagram())
{
diagram()->undoStack().push(m_undo_command);
m_undo_command = nullptr;
}
else
delete m_undo_command;
}
QetGraphicsItem::mouseReleaseEvent(event); QetGraphicsItem::mouseReleaseEvent(event);
} }

View File

@@ -22,6 +22,7 @@
class QDomElement; class QDomElement;
class QDomDocument; class QDomDocument;
class QetShapeGeometryCommand;
/** /**
* @brief The QetShapeItem class * @brief The QetShapeItem class
@@ -53,6 +54,7 @@ class QetShapeItem : public QetGraphicsItem
///METHODS ///METHODS
void setStyle(Qt::PenStyle); void setStyle(Qt::PenStyle);
Qt::PenStyle penStyle() const { return m_shapeStyle;} Qt::PenStyle penStyle() const { return m_shapeStyle;}
ShapeType shapeType() const {return m_shapeType;}
virtual bool fromXml (const QDomElement &); virtual bool fromXml (const QDomElement &);
virtual QDomElement toXml (QDomDocument &document) const; virtual QDomElement toXml (QDomDocument &document) const;
@@ -61,9 +63,10 @@ class QetShapeItem : public QetGraphicsItem
virtual void editProperty(); virtual void editProperty();
virtual QString name() const; virtual QString name() const;
void setP2 (QPointF P2); void setP2 (const QPointF &P2);
void setLine (const QLineF &line);
bool setRect (const QRectF &rect); bool setRect (const QRectF &rect);
bool setPolygon (const QPolygon &polygon); bool setPolygon (const QPolygonF &polygon);
//Methods available for polygon shape //Methods available for polygon shape
int pointsCount () const; int pointsCount () const;
@@ -93,5 +96,6 @@ class QetShapeItem : public QetGraphicsItem
bool m_hovered, bool m_hovered,
m_mouse_grab_handler; m_mouse_grab_handler;
int m_vector_index; int m_vector_index;
QetShapeGeometryCommand *m_undo_command;
}; };
#endif // QETSHAPEITEM_H #endif // QETSHAPEITEM_H

View File

@@ -0,0 +1,122 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
#include "qetshapegeometrycommand.h"
#include "qetshapeitem.h"
#include <QObject>
/**
* @brief QetShapeGeometryCommand::QetShapeGeometryCommand
* Constructor for a line shape
* @param item : item to change the geometry
* @param old_line : old line
* @param parent : parent undo command
*/
QetShapeGeometryCommand::QetShapeGeometryCommand(QetShapeItem *item, const QLineF &old_line, QUndoCommand *parent) :
QUndoCommand(parent),
m_shape_item(item),
m_old_line(old_line)
{
setText(QObject::tr("Modifier la géometrie de : %1").arg(m_shape_item->name()));
}
/**
* @brief QetShapeGeometryCommand::QetShapeGeometryCommand
* Constructor for a rectangle or ellipse shape
* @param item : item to change the geometry
* @param old_rect : old rectangle
* @param parent : parent undo command
*/
QetShapeGeometryCommand::QetShapeGeometryCommand(QetShapeItem *item, const QRectF &old_rect, QUndoCommand *parent):
QUndoCommand(parent),
m_shape_item(item),
m_old_rect(old_rect)
{
setText(QObject::tr("Modifier la géometrie de : %1").arg(m_shape_item->name()));
}
/**
* @brief QetShapeGeometryCommand::QetShapeGeometryCommand
* Constructor for polygon shape
* @param item : item to change the geometry
* @param old_polygon : old polygon
* @param parent : parent undo command
*/
QetShapeGeometryCommand::QetShapeGeometryCommand(QetShapeItem *item, const QPolygonF &old_polygon, QUndoCommand *parent):
QUndoCommand(parent),
m_shape_item(item),
m_old_polygon(old_polygon)
{
setText(QObject::tr("Modifier la géometrie de : %1").arg(m_shape_item->name()));
}
/**
* @brief QetShapeGeometryCommand::mergeWith
* Try to merge this undo command with @other
* @param other
* @return true if the two command was merged
*/
bool QetShapeGeometryCommand::mergeWith(const QUndoCommand *other)
{
if (other->id() != id() || other->childCount()) return false;
const QetShapeGeometryCommand *other_undo = static_cast<const QetShapeGeometryCommand*>(other);
if (other_undo->m_shape_item != m_shape_item) return false;
switch (m_shape_item->shapeType())
{
case QetShapeItem::Line: m_new_line = other_undo->m_new_line; break;
case QetShapeItem::Rectangle: m_new_rect = other_undo->m_new_rect; break;
case QetShapeItem::Ellipse: m_new_rect = other_undo->m_new_rect; break;
case QetShapeItem::Polyline: m_new_polygon = other_undo->m_new_polygon; break;
}
return true;
}
/**
* @brief QetShapeGeometryCommand::redo
* Redo this command
*/
void QetShapeGeometryCommand::redo()
{
switch (m_shape_item->shapeType())
{
case QetShapeItem::Line: m_shape_item->setLine(m_new_line); break;
case QetShapeItem::Rectangle: m_shape_item->setRect(m_new_rect); break;
case QetShapeItem::Ellipse: m_shape_item->setRect(m_new_rect); break;
case QetShapeItem::Polyline: m_shape_item->setPolygon(m_new_polygon); break;
}
QUndoCommand::redo();
}
/**
* @brief QetShapeGeometryCommand::undo
* Undo this command
*/
void QetShapeGeometryCommand::undo()
{
switch (m_shape_item->shapeType())
{
case QetShapeItem::Line: m_shape_item->setLine(m_old_line); break;
case QetShapeItem::Rectangle: m_shape_item->setRect(m_old_rect); break;
case QetShapeItem::Ellipse: m_shape_item->setRect(m_old_rect); break;
case QetShapeItem::Polyline: m_shape_item->setPolygon(m_old_polygon); break;
}
QUndoCommand::undo();
}

View File

@@ -0,0 +1,54 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
#ifndef QETSHAPEGEOMETRYCOMMAND_H
#define QETSHAPEGEOMETRYCOMMAND_H
#include <QUndoCommand>
#include <QLineF>
#include <QPolygonF>
#include <QRectF>
class QetShapeItem;
/**
* @brief The QetShapeGeometryCommand class
* This undo command class manage the geometry change of a QetShapeItem.
*/
class QetShapeGeometryCommand : public QUndoCommand
{
public:
QetShapeGeometryCommand(QetShapeItem *item, const QLineF &old_line, QUndoCommand *parent = nullptr);
QetShapeGeometryCommand(QetShapeItem *item, const QRectF &old_rect, QUndoCommand *parent = nullptr);
QetShapeGeometryCommand(QetShapeItem *item, const QPolygonF &old_polygon, QUndoCommand *parent = nullptr);
void setNewLine (const QLineF &new_line) {m_new_line = new_line;}
void setNewRect (const QRectF &new_rect) {m_new_rect = new_rect;}
void setNewPolygon (const QPolygonF &new_polygon) {m_new_polygon = new_polygon;}
int id() const {return 5;}
bool mergeWith(const QUndoCommand *other);
void redo();
void undo();
private:
QetShapeItem *m_shape_item;
QLineF m_old_line, m_new_line;
QPolygonF m_old_polygon, m_new_polygon;
QRectF m_old_rect, m_new_rect;
};
#endif // QETSHAPEGEOMETRYCOMMAND_H