[qet] [4046] Add undo command for QetShapeItem geometry change

[ Thread Index | Date Index | More lists.tuxfamily.org/qet Archives ]


Revision: 4046
Author:   blacksun
Date:     2015-07-12 15:35:40 +0200 (Sun, 12 Jul 2015)
Log Message:
-----------
Add undo command for QetShapeItem geometry change

Modified Paths:
--------------
    trunk/dev_doc/ID_of_QUndoCommand.txt
    trunk/sources/qetgraphicsitem/qetshapeitem.cpp
    trunk/sources/qetgraphicsitem/qetshapeitem.h

Added Paths:
-----------
    trunk/sources/undocommand/qetshapegeometrycommand.cpp
    trunk/sources/undocommand/qetshapegeometrycommand.h

Modified: trunk/dev_doc/ID_of_QUndoCommand.txt
===================================================================
--- trunk/dev_doc/ID_of_QUndoCommand.txt	2015-07-12 13:09:36 UTC (rev 4045)
+++ trunk/dev_doc/ID_of_QUndoCommand.txt	2015-07-12 13:35:40 UTC (rev 4046)
@@ -2,3 +2,4 @@
 LinkElementCommand = 2
 ItemResizerCommand = 3
 ChangeShapeStyleCommand = 4
+QetShapeGeometryCommand = 5

Modified: trunk/sources/qetgraphicsitem/qetshapeitem.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/qetshapeitem.cpp	2015-07-12 13:09:36 UTC (rev 4045)
+++ trunk/sources/qetgraphicsitem/qetshapeitem.cpp	2015-07-12 13:35:40 UTC (rev 4046)
@@ -22,6 +22,7 @@
 #include "shapegraphicsitempropertieswidget.h"
 #include "PropertiesEditor/propertieseditordialog.h"
 #include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
+#include "qetshapegeometrycommand.h"
 
 typedef QetGraphicsHandlerUtility QGHU;
 
@@ -40,7 +41,8 @@
 	m_P1 (Diagram::snapToGrid(p1)),
 	m_P2 (Diagram::snapToGrid(p2)),
 	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;
@@ -49,7 +51,9 @@
 }
 
 QetShapeItem::~QetShapeItem()
-{}
+{
+	if (m_undo_command) delete m_undo_command;
+}
 
 /**
  * @brief QetShapeItem::setStyle
@@ -70,15 +74,15 @@
  * the last point of the polyline is replaced by P2.
  * @param P2
  */
-void QetShapeItem::setP2(QPointF P2) {
-	P2 = Diagram::snapToGrid(P2);
-
-	if (m_shapeType == Polyline) {
+void QetShapeItem::setP2(const QPointF &P2)
+{
+	if (m_shapeType == Polyline && m_polygon.last() != P2)
+	{
 		prepareGeometryChange();
 		m_polygon.replace(m_polygon.size()-1, P2);
 	}
-	else {
-		if (P2 == m_P2) return;
+	else if (P2 != m_P2)
+	{
 		prepareGeometryChange();
 		m_P2 = P2;
 	}
@@ -86,6 +90,21 @@
 }
 
 /**
+ * @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
  * Set this item geometry to rect (only available if shape is a rectangle or an ellipse)
  * @param rect : new rect
@@ -110,7 +129,7 @@
  * @param polygon : new polygon
  * @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;
 	prepareGeometryChange();
@@ -173,26 +192,18 @@
  * @brief QetShapeItem::shape
  * @return the shape of this item
  */
-QPainterPath QetShapeItem::shape() const {
+QPainterPath QetShapeItem::shape() const
+{
 	QPainterPath path;
 
-	switch (m_shapeType) {
-		case Line:
-			path.moveTo(m_P1);
-			path.lineTo(m_P2);
-			break;
-		case Rectangle:
-			path.addRect(QRectF(m_P1, m_P2));
-			break;
-		case Ellipse:
-			path.addEllipse(QRectF(m_P1, m_P2));
-			break;
-		case Polyline:
-			path.addPolygon(m_polygon);
-			break;
-		default:
-			Q_ASSERT(false);
-			break;
+	switch (m_shapeType)
+	{
+		case Line:      path.moveTo(m_P1);
+						path.lineTo(m_P2);                   break;
+		case Rectangle: path.addRect(QRectF(m_P1, m_P2));    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;
@@ -371,6 +382,14 @@
 		{
 				//User click on an handler
 			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;
 		}
 	}
@@ -441,7 +460,26 @@
  */
 void QetShapeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
 {
-	m_mouse_grab_handler = false;
+	if (m_mouse_grab_handler)
+	{
+		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);
 }
 

Modified: trunk/sources/qetgraphicsitem/qetshapeitem.h
===================================================================
--- trunk/sources/qetgraphicsitem/qetshapeitem.h	2015-07-12 13:09:36 UTC (rev 4045)
+++ trunk/sources/qetgraphicsitem/qetshapeitem.h	2015-07-12 13:35:40 UTC (rev 4046)
@@ -22,6 +22,7 @@
 
 class QDomElement;
 class QDomDocument;
+class QetShapeGeometryCommand;
 
 /**
  * @brief The QetShapeItem class
@@ -53,6 +54,7 @@
 			///METHODS
 		void setStyle(Qt::PenStyle);
 		Qt::PenStyle penStyle() const { return m_shapeStyle;}
+		ShapeType shapeType() const {return m_shapeType;}
 
 		virtual bool	    fromXml (const QDomElement &);
 		virtual QDomElement toXml	(QDomDocument &document) const;
@@ -61,9 +63,10 @@
 		virtual void editProperty();
 		virtual QString name() const;
 
-		void setP2      (QPointF P2);
+		void setP2      (const QPointF &P2);
+		void setLine    (const QLineF &line);
 		bool setRect    (const QRectF &rect);
-		bool setPolygon (const QPolygon &polygon);
+		bool setPolygon (const QPolygonF &polygon);
 
 			//Methods available for polygon shape
 		int  pointsCount  () const;
@@ -93,5 +96,6 @@
 		bool         m_hovered,
 					 m_mouse_grab_handler;
 		int			 m_vector_index;
+		QetShapeGeometryCommand *m_undo_command;
 };
 #endif // QETSHAPEITEM_H

Added: trunk/sources/undocommand/qetshapegeometrycommand.cpp
===================================================================
--- trunk/sources/undocommand/qetshapegeometrycommand.cpp	                        (rev 0)
+++ trunk/sources/undocommand/qetshapegeometrycommand.cpp	2015-07-12 13:35:40 UTC (rev 4046)
@@ -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();
+}

Added: trunk/sources/undocommand/qetshapegeometrycommand.h
===================================================================
--- trunk/sources/undocommand/qetshapegeometrycommand.h	                        (rev 0)
+++ trunk/sources/undocommand/qetshapegeometrycommand.h	2015-07-12 13:35:40 UTC (rev 4046)
@@ -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


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/