[qet] qet/qet: [5124] Element texts group is fully managed by the undo stack

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


Revision: 5124
Author:   blacksun
Date:     2017-11-29 15:49:12 +0100 (Wed, 29 Nov 2017)
Log Message:
-----------
Element texts group is fully managed by the undo stack

Modified Paths:
--------------
    trunk/dev_doc/ID_of_QUndoCommand.txt
    trunk/sources/elementtextsmover.cpp
    trunk/sources/elementtextsmover.h
    trunk/sources/qetgraphicsitem/element.cpp
    trunk/sources/qetgraphicsitem/element.h
    trunk/sources/qetgraphicsitem/elementtextitemgroup.cpp
    trunk/sources/qetgraphicsitem/elementtextitemgroup.h
    trunk/sources/undocommand/addelementtextcommand.cpp
    trunk/sources/undocommand/addelementtextcommand.h
    trunk/sources/undocommand/deleteqgraphicsitemcommand.cpp
    trunk/sources/undocommand/deleteqgraphicsitemcommand.h

Modified: trunk/dev_doc/ID_of_QUndoCommand.txt
===================================================================
--- trunk/dev_doc/ID_of_QUndoCommand.txt	2017-11-28 16:15:37 UTC (rev 5123)
+++ trunk/dev_doc/ID_of_QUndoCommand.txt	2017-11-29 14:49:12 UTC (rev 5124)
@@ -3,4 +3,5 @@
 ItemResizerCommand = 3
 ChangeShapeStyleCommand = 4
 QetShapeGeometryCommand = 5
+AlignmentTextsGroupCommand = 6
 QPropertyUndoCommand = 10 000

Modified: trunk/sources/elementtextsmover.cpp
===================================================================
--- trunk/sources/elementtextsmover.cpp	2017-11-28 16:15:37 UTC (rev 5123)
+++ trunk/sources/elementtextsmover.cpp	2017-11-29 14:49:12 UTC (rev 5124)
@@ -20,6 +20,8 @@
 #include "diagram.h"
 #include "QPropertyUndoCommand/qpropertyundocommand.h"
 #include "dynamicelementtextitem.h"
+#include "elementtextitemgroup.h"
+#include <QObject>
 
 /**
  * @brief ElementTextsMover::ElementTextsMover
@@ -44,26 +46,54 @@
  */
 int ElementTextsMover::beginMovement(Diagram *diagram, QGraphicsItem *driver_item)
 {
-	if (m_movement_running || !diagram) return(-1);
+	if (m_movement_running || !diagram)
+		return(-1);
 
 	m_diagram = diagram;
 	m_movement_driver = driver_item;
-	m_texts_item_H.clear();
+	m_last_pos = driver_item->pos();
+	m_items_hash.clear();
+	m_text_count = m_group_count =0;
+//	m_texts_hash.clear();
+//	m_grps_hash.clear();
 
+//	for(QGraphicsItem *item : diagram->selectedItems())
+//	{
+//		if (item->type() == ElementTextItem::Type || item->type() == DynamicElementTextItem::Type)
+//		{
+//			DiagramTextItem *dti = static_cast<DiagramTextItem *> (item);
+//			m_texts_hash.insert(dti, dti->pos());
+//		}
+//	}
+	
 	for(QGraphicsItem *item : diagram->selectedItems())
 	{
-		if (item->type() == ElementTextItem::Type || item->type() == DynamicElementTextItem::Type)
-		{
-			DiagramTextItem *dti = static_cast<DiagramTextItem *> (item);
-			m_texts_item_H.insert(dti, dti->pos());
-		}
+		 if(item->type() == ElementTextItem::Type || item->type() == DynamicElementTextItem::Type)
+		 {
+			 m_items_hash.insert(item, item->pos());
+			 m_text_count++;
+		 }
+		 else if(item->type() == QGraphicsItemGroup::Type)
+		 {
+			 if(dynamic_cast<ElementTextItemGroup *>(item))
+			 {
+				 m_items_hash.insert(item, item->pos());
+				 m_group_count++;
+			 }
+		 }
 	}
 	
-	if (!m_texts_item_H.size()) return(-1);
+//	if (!m_texts_hash.size())
+//		return(-1);
 	
+	if(m_items_hash.isEmpty())
+		return -1;
+	
 	m_movement_running = true;
 	
-	return(m_texts_item_H.size());
+	return m_items_hash.size();
+	
+//	return(m_texts_hash.size());
 }
 
 /**
@@ -74,15 +104,28 @@
  */
 void ElementTextsMover::continueMovement(const QPointF &movement)
 {
-	if (!m_movement_running || movement.isNull()) return;
+	if (!m_movement_running || movement.isNull())
+		return;
 	
-	for(DiagramTextItem *text_item : m_texts_item_H.keys())
+	QPointF move = m_movement_driver->pos() - m_last_pos;
+	m_last_pos = m_movement_driver->pos();
+	
+	for(QGraphicsItem *qgi : m_items_hash.keys())
 	{
-		if (text_item == m_movement_driver)
+		if(qgi == m_movement_driver)
 			continue;
-		QPointF applied_movement = text_item->mapMovementToParent(text_item->mapMovementFromScene(movement));
-		text_item->setPos(text_item->pos() + applied_movement);
+		
+		qgi->setPos(qgi->pos() + move);
 	}
+	
+//	for(DiagramTextItem *text_item : m_texts_hash.keys())
+//	{
+//		if (text_item == m_movement_driver)
+//			continue;
+		
+//		QPointF applied_movement = text_item->mapMovementToParent(text_item->mapMovementFromScene(movement));
+//		text_item->setPos(text_item->pos() + applied_movement);
+//	}
 }
 
 /**
@@ -91,23 +134,42 @@
  */
 void ElementTextsMover::endMovement()
 {
-		//No movement running, or no text to move
-	if (!m_movement_running || m_texts_item_H.isEmpty())
+//		//No movement running, or no text to move
+//	if (!m_movement_running || m_texts_hash.isEmpty())
+//		return;
+	
+//		//Movement is null
+//	DiagramTextItem *dti = m_texts_hash.keys().first();
+//	if (dti->pos() == m_texts_hash.value(dti))
+//		return;
+	
+//	QUndoCommand *undo = new QUndoCommand(m_texts_hash.size() == 1 ? QString(QObject::tr("Déplacer un texte d'élément"))  :
+//																	   QString(QObject::tr("Déplacer %1 textes d'élément").arg(m_texts_hash.size())));
+	
+//	for (DiagramTextItem *dti : m_texts_hash.keys())
+//	{
+//		QPropertyUndoCommand *child_undo = new QPropertyUndoCommand(dti, "pos", m_texts_hash.value(dti), dti->pos(), undo);
+//		child_undo->enableAnimation();
+//	}
+	
+		//No movement or no items to move
+	if(!m_movement_running || m_items_hash.isEmpty())
 		return;
-	
+			
 		//Movement is null
-	DiagramTextItem *dti = m_texts_item_H.keys().first();
-	if (dti->pos() == m_texts_item_H.value(dti))
+	QGraphicsItem *qgi = m_items_hash.keys().first();
+	if(qgi->pos() == m_items_hash.value(qgi))
 		return;
+					 
+	QUndoCommand *undo = new QUndoCommand(undoText());
 	
-	QUndoCommand *undo = new QUndoCommand(m_texts_item_H.size() == 1 ? QString(QObject::tr("Déplacer un texte d'élément"))  :
-																	   QString(QObject::tr("Déplacer %1 textes d'élément").arg(m_texts_item_H.size())));
-	
-	for (DiagramTextItem *dti : m_texts_item_H.keys())
+	for (QGraphicsItem *qgi : m_items_hash.keys())
 	{
-		QPropertyUndoCommand *child_undo = new QPropertyUndoCommand(dti, "pos", m_texts_item_H.value(dti), dti->pos(), undo);
-		child_undo->enableAnimation();
-
+		if(QObject *object = dynamic_cast<QObject *>(qgi))
+		{
+			QPropertyUndoCommand *child_undo = new QPropertyUndoCommand(object, "pos", m_items_hash.value(qgi), qgi->pos(), undo);
+			child_undo->enableAnimation();
+		}
 	}
 
 	m_diagram->undoStack().push(undo);
@@ -114,3 +176,28 @@
 	
 	m_movement_running = false;
 }
+
+QString ElementTextsMover::undoText() const
+{
+	QString undo_text;
+	
+	if(m_text_count == 1)
+		undo_text.append(QObject::tr("Déplacer un texte d'élément"));
+	else if(m_text_count > 1)
+		undo_text.append(QObject::tr("Déplacer %1 textes d'élément").arg(m_items_hash.size()));
+	
+	if(m_group_count >= 1)
+	{
+		if(undo_text.isEmpty())
+			undo_text.append(QObject::tr("Déplacer"));
+		else
+			undo_text.append(QObject::tr(" et"));
+		
+		if(m_group_count == 1)
+			undo_text.append(QObject::tr(" un groupe de texte"));
+		else
+			undo_text.append(QObject::tr((" %1 groupes de textes")).arg(m_group_count));
+	}
+	
+	return undo_text;
+}

Modified: trunk/sources/elementtextsmover.h
===================================================================
--- trunk/sources/elementtextsmover.h	2017-11-28 16:15:37 UTC (rev 5123)
+++ trunk/sources/elementtextsmover.h	2017-11-29 14:49:12 UTC (rev 5124)
@@ -24,6 +24,7 @@
 class QGraphicsItem;
 class DiagramTextItem;
 class Diagram;
+class QGraphicsItemGroup;
 
 /**
 	This class manages the interactive movement of element text items on a
@@ -41,11 +42,19 @@
 		int  beginMovement(Diagram *diagram, QGraphicsItem *driver_item = nullptr);
 		void continueMovement(const QPointF &);
 		void endMovement();
+		
+	private:
+		QString undoText() const;
 	
 	private:
 		bool m_movement_running = false;
 		Diagram *m_diagram = nullptr;
 		QGraphicsItem *m_movement_driver = nullptr;
-		QHash <DiagramTextItem *, QPointF> m_texts_item_H;
+		QHash <DiagramTextItem *, QPointF> m_texts_hash;
+		QHash <QGraphicsItemGroup *, QPointF> m_grps_hash;
+		QHash <QGraphicsItem *, QPointF> m_items_hash;
+		QPointF m_last_pos;
+		int m_text_count = 0,
+			m_group_count = 0;
 };
 #endif

Modified: trunk/sources/qetgraphicsitem/element.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/element.cpp	2017-11-28 16:15:37 UTC (rev 5123)
+++ trunk/sources/qetgraphicsitem/element.cpp	2017-11-29 14:49:12 UTC (rev 5124)
@@ -727,7 +727,7 @@
 			//Set the alignment to top, because top is not used by groupand so,
 			//each time a text is removed from the group, the alignement is not updated
 		Qt::Alignment al = group->alignment();
-		group->setAlignement(Qt::AlignTop);
+		group->setAlignment(Qt::AlignTop);
 		
 			//Remove the texts from group
 		QList<DynamicElementTextItem *> deti_list = group->texts();
@@ -743,7 +743,7 @@
 			group->addToGroup(deti);
 		
 			//Restor the alignement
-		group->setAlignement(al);
+		group->setAlignment(al);
 		
 			//Save the group to xml
 		texts_group.appendChild(group->toXml(document));
@@ -759,7 +759,7 @@
 
 /**
  * @brief Element::addDynamiqueTextItem
- * Add @deti as a dynamic text item of this element
+ * Add @deti as a dynamic text item of this element, @deti is reparented to this
  * If @deti is null, a new DynamicElementTextItem is created and added to this element.
  * @param deti
  */
@@ -768,6 +768,7 @@
     if (deti && !m_dynamic_text_list.contains(deti))
 	{
         m_dynamic_text_list.append(deti);
+		deti->setParentItem(this);
 		emit textAdded(deti);
 	}
     else
@@ -780,9 +781,8 @@
 
 /**
  * @brief Element::removeDynamicTextItem
- * Remove @deti, no matter if is a child of this element or
- * a child of a group of this element.
- * The parent item of deti stay this item and deti is not deleted.
+ * Remove @deti, no matter if is a child of this element or a child of a group of this element.
+ * Set he parent item of @deti to 0, @deti is not deleted.
  * @param deti
  */
 void Element::removeDynamicTextItem(DynamicElementTextItem *deti)
@@ -790,6 +790,7 @@
     if (m_dynamic_text_list.contains(deti))
 	{
         m_dynamic_text_list.removeOne(deti);
+		deti->setParentItem(nullptr);
 		emit textRemoved(deti);
 		return;
 	}
@@ -800,6 +801,7 @@
 		{
 			removeTextFromGroup(deti, group);
 			m_dynamic_text_list.removeOne(deti);
+			deti->setParentItem(nullptr);
 			emit textRemoved(deti);
 			return;
 		}
@@ -849,9 +851,25 @@
 }
 
 /**
+ * @brief Element::addTextGroup
+ * @param group add group @group to the group of this element.
+ * the group must not be owned by an element.
+ */
+void Element::addTextGroup(ElementTextItemGroup *group)
+{
+	if(group->parentElement())
+		return;
+	
+	m_texts_group << group;
+	group->setParentItem(this);
+	emit textsGroupAdded(group);
+}
+
+/**
  * @brief Element::removeTextGroup
- * Remove the text group with name @name
- * All text owned by the group will be reparented to this element
+ * Remove the text group @group from this element, and set the parent of group to 0.
+ * group is not deleted.
+ * All texts owned by the group will be reparented to this element
  * @param name
  */
 void Element::removeTextGroup(ElementTextItemGroup *group)
@@ -870,9 +888,10 @@
 		}
 	}
 	
+	
+	emit textsGroupAboutToBeRemoved(group);
 	m_texts_group.removeOne(group);
-	emit textsGroupAboutToBeRemoved(group);
-	delete group;
+	group->setParentItem(nullptr);
 }
 
 /**
@@ -912,10 +931,13 @@
 		return false;
 	if(!m_texts_group.contains(group))
 		return false;
+
+	m_dynamic_text_list.removeOne(text);
+	emit textRemoved(text);
 	
-	removeDynamicTextItem(text);
 	group->addToGroup(text);
 	emit textAddedToGroup(text, group);
+	
 	return true;
 }
 
@@ -929,7 +951,7 @@
 	if(!m_texts_group.contains(group))
 		return false;
 	
-	if(group->childItems().contains(text))
+	if(group->texts().contains(text))
 	{
 		group->removeFromGroup(text);
 		emit textRemovedFromGroup(text, group);

Modified: trunk/sources/qetgraphicsitem/element.h
===================================================================
--- trunk/sources/qetgraphicsitem/element.h	2017-11-28 16:15:37 UTC (rev 5123)
+++ trunk/sources/qetgraphicsitem/element.h	2017-11-29 14:49:12 UTC (rev 5124)
@@ -209,6 +209,7 @@
         void removeDynamicTextItem(DynamicElementTextItem *deti);
         QList<DynamicElementTextItem *> dynamicTextItems() const;
 		ElementTextItemGroup *addTextGroup(const QString &name);
+		void addTextGroup(ElementTextItemGroup *group);
 		void removeTextGroup(ElementTextItemGroup *group);
 		ElementTextItemGroup *textGroup(const QString &name) const;
 		QList<ElementTextItemGroup *> textGroups() const;

Modified: trunk/sources/qetgraphicsitem/elementtextitemgroup.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/elementtextitemgroup.cpp	2017-11-28 16:15:37 UTC (rev 5123)
+++ trunk/sources/qetgraphicsitem/elementtextitemgroup.cpp	2017-11-29 14:49:12 UTC (rev 5124)
@@ -19,6 +19,7 @@
 #include "dynamicelementtextitem.h"
 #include "element.h"
 #include "diagram.h"
+#include "addelementtextcommand.h"
 
 #include <QPainter>
 #include <QGraphicsSceneMouseEvent>
@@ -34,8 +35,7 @@
  */
 ElementTextItemGroup::ElementTextItemGroup(const QString &name, Element *parent) :
 	QGraphicsItemGroup(parent),
-	m_name(name),
-	m_element(parent)
+	m_name(name)
 {
 	setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsFocusable);
 }
@@ -53,14 +53,14 @@
 	{
 		item->setFlag(QGraphicsItem::ItemIsSelectable, false);
 		QGraphicsItemGroup::addToGroup(item);	
-		updateAlignement();
+		updateAlignment();
 		
 		DynamicElementTextItem *deti = qgraphicsitem_cast<DynamicElementTextItem *>(item);
-		connect(deti, &DynamicElementTextItem::fontSizeChanged,      this, &ElementTextItemGroup::updateAlignement);
-		connect(deti, &DynamicElementTextItem::textChanged,          this, &ElementTextItemGroup::updateAlignement);
-		connect(deti, &DynamicElementTextItem::textFromChanged,      this, &ElementTextItemGroup::updateAlignement);
-		connect(deti, &DynamicElementTextItem::infoNameChanged,      this, &ElementTextItemGroup::updateAlignement);
-		connect(deti, &DynamicElementTextItem::compositeTextChanged, this, &ElementTextItemGroup::updateAlignement);	
+		connect(deti, &DynamicElementTextItem::fontSizeChanged,      this, &ElementTextItemGroup::updateAlignment);
+		connect(deti, &DynamicElementTextItem::textChanged,          this, &ElementTextItemGroup::updateAlignment);
+		connect(deti, &DynamicElementTextItem::textFromChanged,      this, &ElementTextItemGroup::updateAlignment);
+		connect(deti, &DynamicElementTextItem::infoNameChanged,      this, &ElementTextItemGroup::updateAlignment);
+		connect(deti, &DynamicElementTextItem::compositeTextChanged, this, &ElementTextItemGroup::updateAlignment);	
 	}
 }
 
@@ -72,15 +72,15 @@
 {
 	QGraphicsItemGroup::removeFromGroup(item);
 	item->setFlag(QGraphicsItem::ItemIsSelectable, true);
-	updateAlignement();
+	updateAlignment();
 	
 	if(DynamicElementTextItem *deti = qgraphicsitem_cast<DynamicElementTextItem *>(item))
 	{
-		disconnect(deti, &DynamicElementTextItem::fontSizeChanged,      this, &ElementTextItemGroup::updateAlignement);
-		disconnect(deti, &DynamicElementTextItem::textChanged,          this, &ElementTextItemGroup::updateAlignement);
-		disconnect(deti, &DynamicElementTextItem::textFromChanged,      this, &ElementTextItemGroup::updateAlignement);
-		disconnect(deti, &DynamicElementTextItem::infoNameChanged,      this, &ElementTextItemGroup::updateAlignement);
-		disconnect(deti, &DynamicElementTextItem::compositeTextChanged, this, &ElementTextItemGroup::updateAlignement);
+		disconnect(deti, &DynamicElementTextItem::fontSizeChanged,      this, &ElementTextItemGroup::updateAlignment);
+		disconnect(deti, &DynamicElementTextItem::textChanged,          this, &ElementTextItemGroup::updateAlignment);
+		disconnect(deti, &DynamicElementTextItem::textFromChanged,      this, &ElementTextItemGroup::updateAlignment);
+		disconnect(deti, &DynamicElementTextItem::infoNameChanged,      this, &ElementTextItemGroup::updateAlignment);
+		disconnect(deti, &DynamicElementTextItem::compositeTextChanged, this, &ElementTextItemGroup::updateAlignment);
 	}
 }
 
@@ -89,25 +89,27 @@
  * Set the alignement of this group
  * @param alignement
  */
-void ElementTextItemGroup::setAlignement(Qt::Alignment alignement)
+void ElementTextItemGroup::setAlignment(Qt::Alignment alignement)
 {
-	m_alignement = alignement;
-	updateAlignement();
+	m_alignment = alignement;
+	updateAlignment();
 }
 
 Qt::Alignment ElementTextItemGroup::alignment() const
 {
-	return m_alignement;
+	return m_alignment;
 }
 
 /**
- * @brief ElementTextItemGroup::setAlignement
+ * @brief ElementTextItemGroup::setAlignment
  * Update the alignement of the items in this group, according
  * to the current alignement.
  * @param alignement
  */
-void ElementTextItemGroup::updateAlignement()
+void ElementTextItemGroup::updateAlignment()
 {
+	prepareGeometryChange();
+	
 	QList <QGraphicsItem *> texts = childItems();
 	if (texts.size() > 1)
 	{
@@ -116,7 +118,7 @@
 		
 		qreal y_offset =0;
 		
-		if(m_alignement == Qt::AlignLeft)
+		if(m_alignment == Qt::AlignLeft)
 		{
 			QPointF ref = texts.first()->pos();
 				
@@ -127,7 +129,7 @@
 			}
 			return;
 		}
-		else if(m_alignement == Qt::AlignVCenter)
+		else if(m_alignment == Qt::AlignVCenter)
 		{
 			QPointF ref(texts.first()->pos().x() + texts.first()->boundingRect().width()/2,
 						texts.first()->pos().y());
@@ -141,7 +143,7 @@
 			return;
 				
 		}
-		else if (m_alignement == Qt::AlignRight)
+		else if (m_alignment == Qt::AlignRight)
 		{
 			QPointF ref(texts.first()->pos().x() + texts.first()->boundingRect().width(),
 						texts.first()->pos().y());
@@ -194,6 +196,18 @@
 }
 
 /**
+ * @brief ElementTextItemGroup::parentElement
+ * @return The parent element of this group or nullptr
+ */
+Element *ElementTextItemGroup::parentElement() const
+{
+	if(parentItem() && parentItem()->type() == Element::Type)
+		return static_cast<Element *>(parentItem());
+	else
+		return nullptr;
+}
+
+/**
  * @brief ElementTextItemGroup::toXml
  * Export data of this group to xml
  * @param dom_document
@@ -205,7 +219,7 @@
 	dom_element.setAttribute("name", m_name);
 
 	QMetaEnum me = QMetaEnum::fromType<Qt::Alignment>();
-	dom_element.setAttribute("alignment", me.valueToKey(m_alignement));
+	dom_element.setAttribute("alignment", me.valueToKey(m_alignment));
 	
 	QDomElement dom_texts = dom_document.createElement("texts");
 	for(DynamicElementTextItem *deti : texts())
@@ -233,19 +247,22 @@
 	
 	m_name = dom_element.attribute("name", "no name");
 	QMetaEnum me = QMetaEnum::fromType<Qt::Alignment>();
-	m_alignement = Qt::Alignment(me.keyToValue(dom_element.attribute("alignment").toStdString().data()));
+	m_alignment = Qt::Alignment(me.keyToValue(dom_element.attribute("alignment").toStdString().data()));
 	
-	for(QDomElement text : QET::findInDomElement(dom_element, "texts", "text"))
+	if(parentElement())
 	{
-		DynamicElementTextItem *deti = nullptr;
-		QUuid uuid(text.attribute("uuid"));
-		
-		for(DynamicElementTextItem *txt : m_element->dynamicTextItems())
-			if(txt->uuid() == uuid)
-				deti = txt;
-		
-		if (deti)
-			m_element->addTextToGroup(deti, this);
+		for(QDomElement text : QET::findInDomElement(dom_element, "texts", "text"))
+		{
+			DynamicElementTextItem *deti = nullptr;
+			QUuid uuid(text.attribute("uuid"));
+			
+			for(DynamicElementTextItem *txt : parentElement()->dynamicTextItems())
+				if(txt->uuid() == uuid)
+					deti = txt;
+			
+			if (deti)
+				parentElement()->addTextToGroup(deti, this);
+		}
 	}
 }
 
@@ -321,7 +338,11 @@
 		
 		QPointF old_pos = pos();
 		if(m_first_move)
+		{
 			m_mouse_to_origin_movement = old_pos - event->buttonDownScenePos(Qt::LeftButton);
+			if(parentElement())
+				parentElement()->setHighlighted(true);
+		}
 		
 		QPointF expected_pos = event->scenePos() + m_mouse_to_origin_movement;
 		setPos(Diagram::snapToGrid(expected_pos));
@@ -344,7 +365,11 @@
 void ElementTextItemGroup::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
 {
 	if(diagram())
+	{
 		diagram()->endMoveElementTexts();
+		if(parentElement())
+			parentElement()->setHighlighted(false);
+	}
 	
 	if(!(event->modifiers() & Qt::ControlModifier))
 		QGraphicsItemGroup::mouseReleaseEvent(event);
@@ -355,13 +380,27 @@
  * @param event
  */
 void ElementTextItemGroup::keyPressEvent(QKeyEvent *event)
-{
-	prepareGeometryChange();
-	if(event->key() == Qt::Key_A)
-		setAlignement(Qt::AlignLeft);
-	else if (event->key() == Qt::Key_Z)
-		setAlignement(Qt::AlignVCenter);
-	else if (event->key() == Qt::Key_E)
-		setAlignement(Qt::AlignRight);
+{	
+	if(event->key() == Qt::Key_A && m_alignment	!= Qt::AlignLeft)
+	{
+		if(diagram())
+			diagram()->undoStack().push(new AlignmentTextsGroupCommand(this, Qt::AlignLeft));
+		else
+			setAlignment(Qt::AlignLeft);
+	}
+	else if (event->key() == Qt::Key_Z && m_alignment	!= Qt::AlignVCenter)
+	{
+		if(diagram())
+			diagram()->undoStack().push(new AlignmentTextsGroupCommand(this, Qt::AlignVCenter));
+		else
+			setAlignment(Qt::AlignVCenter);
+	}
+	else if (event->key() == Qt::Key_E && m_alignment	!= Qt::AlignRight)
+	{
+		if(diagram())
+			diagram()->undoStack().push(new AlignmentTextsGroupCommand(this, Qt::AlignRight));
+		else
+			setAlignment(Qt::AlignRight);
+	}
 }
 

Modified: trunk/sources/qetgraphicsitem/elementtextitemgroup.h
===================================================================
--- trunk/sources/qetgraphicsitem/elementtextitemgroup.h	2017-11-28 16:15:37 UTC (rev 5123)
+++ trunk/sources/qetgraphicsitem/elementtextitemgroup.h	2017-11-29 14:49:12 UTC (rev 5124)
@@ -35,6 +35,8 @@
 {
 	Q_OBJECT
 	
+	Q_PROPERTY(QPointF pos READ pos WRITE setPos)
+	
 	public:
 		ElementTextItemGroup(const QString &name, Element *parent);
 		~ElementTextItemGroup() override;
@@ -41,13 +43,14 @@
 		void addToGroup(QGraphicsItem *item);
 		void removeFromGroup(QGraphicsItem *item);
 		
-		void setAlignement(Qt::Alignment alignement);
+		void setAlignment(Qt::Alignment alignement);
 		Qt::Alignment alignment() const;
-		void updateAlignement();
+		void updateAlignment();
 		void setName(QString name);
 		QString name() const {return m_name;}
 		QList<DynamicElementTextItem *> texts() const;
 		Diagram *diagram() const;
+		Element *parentElement() const;
 		
 		QDomElement toXml(QDomDocument &dom_document) const;
 		void fromXml(QDomElement &dom_element);
@@ -63,11 +66,10 @@
 		void keyPressEvent(QKeyEvent *event) override;
 
 	private:
-		Qt::Alignment m_alignement = Qt::AlignJustify;
+		Qt::Alignment m_alignment = Qt::AlignJustify;
 		QString m_name;
 		bool m_first_move = true;
 		QPointF m_mouse_to_origin_movement;
-		Element *m_element = nullptr;
 };
 
 #endif // ELEMENTTEXTITEMGROUP_H

Modified: trunk/sources/undocommand/addelementtextcommand.cpp
===================================================================
--- trunk/sources/undocommand/addelementtextcommand.cpp	2017-11-28 16:15:37 UTC (rev 5123)
+++ trunk/sources/undocommand/addelementtextcommand.cpp	2017-11-29 14:49:12 UTC (rev 5124)
@@ -18,8 +18,15 @@
 #include "addelementtextcommand.h"
 #include "element.h"
 #include "dynamicelementtextitem.h"
+#include "elementtextitemgroup.h"
+
 #include <QGraphicsScene>
 
+
+/************************
+ * AddElementTextCommand*
+ * **********************/
+
 AddElementTextCommand::AddElementTextCommand(Element *element, DynamicElementTextItem *deti, QUndoCommand *parent):
 	QUndoCommand(parent),
 	m_element(element),
@@ -40,7 +47,6 @@
 void AddElementTextCommand::undo()
 {
 	m_element->removeDynamicTextItem(m_text);
-	m_text->setParentItem(nullptr);
 	if(m_text->scene())
 		m_text->scene()->removeItem(m_text);
 }
@@ -51,36 +57,253 @@
 	m_element->addDynamicTextItem(m_text);
 }
 
-//RemoveElementTextCommand::RemoveElementTextCommand(DynamicElementTextItem *deti, QUndoCommand *parent) :
-//	QUndoCommand(parent),
-//	m_text(deti)
-//{
-//	setText(QObject::tr("Supprimer un texte d'élément"));
-//	m_element = deti->ParentElement();
-//}
 
-//RemoveElementTextCommand::~RemoveElementTextCommand()
-//{
-//	if(m_element && !m_element->dynamicTextItems().contains(m_text))
-//		delete m_text;
-//}
+/***********************
+ * AddTextsGroupCommand*
+ * *********************/
+/**
+ * @brief AddTextsGroupCommand::AddTextsGroupCommand
+ * @param element : the element to add a new group
+ * @param groupe_name : the name of the group
+ * @param parent : parent undo
+ */
+AddTextsGroupCommand::AddTextsGroupCommand(Element *element, QString groupe_name, QUndoCommand *parent) :
+	QUndoCommand(parent),
+	m_element(element),
+	m_name(groupe_name)
+{
+	setText(QObject::tr("Ajouter un groupe de textes d'élément"));
+}
 
-//void RemoveElementTextCommand::undo()
-//{
-//	if(m_element)
-//	{
-//		m_text->setParentItem(m_element);
-//		m_element->addDynamicTextItem(m_text);
-//	}
-//}
+/**
+ * @brief AddTextsGroupCommand::~AddTextsGroupCommand
+ * Destructor
+ */
+AddTextsGroupCommand::~AddTextsGroupCommand()
+{}
 
-//void RemoveElementTextCommand::redo()
-//{
-//	if(m_element && m_text->scene())
-//	{
-		
-//		m_element->removeDynamicTextItem(m_text);
-//		m_text->setParentItem(nullptr);
-//		m_text->scene()->removeItem(m_text);
-//	}
-//}
+void AddTextsGroupCommand::undo()
+{
+	if(m_element && m_group)
+		m_element.data()->removeTextGroup(m_group);
+}
+
+void AddTextsGroupCommand::redo()
+{
+	if(m_element)
+	{
+		if(m_first_undo)
+		{
+			m_group = m_element.data()->addTextGroup(m_name);
+			m_first_undo = false;
+		}
+		else if(m_group)
+			m_element.data()->addTextGroup(m_group.data());
+	}
+}
+
+
+/**************************
+ * RemoveTextsGroupCommand*
+ * ************************/
+/**
+ * @brief RemoveTextsGroupCommand::RemoveTextsGroupCommand
+ * @param element : The element where we remove a group
+ * @param group : the group to remove
+ * @param parent : the parent undo command
+ */
+RemoveTextsGroupCommand::RemoveTextsGroupCommand(Element *element, ElementTextItemGroup *group, QUndoCommand *parent) :
+	QUndoCommand(parent),
+	m_element(element),
+	m_group(group)
+{
+	setText(QObject::tr("Supprimer un groupe de textes d'élément"));
+}
+
+RemoveTextsGroupCommand::~RemoveTextsGroupCommand()
+{}
+	
+void RemoveTextsGroupCommand::undo()
+{
+	if(m_element && m_group)
+		m_element.data()->addTextGroup(m_group.data());
+}
+
+void RemoveTextsGroupCommand::redo()
+{
+	if(m_element && m_group)
+		m_element.data()->removeTextGroup(m_group.data());
+}
+
+
+/************************
+ * AddTextToGroupCommand*
+ * **********************/
+/**
+ * @brief AddTextToGroupCommand::AddTextToGroupCommand
+ * @param text
+ * @param group
+ * @param parent
+ */
+AddTextToGroupCommand::AddTextToGroupCommand(DynamicElementTextItem *text, ElementTextItemGroup *group, QUndoCommand *parent) :
+	QUndoCommand(parent),
+	m_text(text),
+	m_group(group),
+	m_element(group->parentElement())
+{
+	setText(QObject::tr("Insérer un texte d'élément dans un groupe de textes"));
+}
+
+/**
+ * @brief AddTextToGroupCommand::~AddTextToGroupCommand
+ * Destructor
+ */
+AddTextToGroupCommand::~AddTextToGroupCommand()
+{
+	if(m_group && m_text && m_element)
+	{
+		if(!m_group.data()->texts().contains(m_text.data()) &&
+		   !m_element.data()->dynamicTextItems().contains(m_text.data()))
+			delete m_text.data();
+	}
+}
+
+void AddTextToGroupCommand::undo()
+{
+	if(m_element && m_group && m_text)
+		m_element.data()->removeTextFromGroup(m_text, m_group);
+}
+
+void AddTextToGroupCommand::redo()
+{
+	if(m_element && m_group && m_text)
+		m_element.data()->addTextToGroup(m_text, m_group);
+}
+
+/*****************************
+ * RemoveTextFromGroupCommand*
+ * ***************************/
+/**
+ * @brief RemoveTextFromGroupCommand::RemoveTextFromGroupCommand
+ * @param text : text to add to @group
+ * @param group
+ * @param parent : parent undo command
+ */
+RemoveTextFromGroupCommand::RemoveTextFromGroupCommand(DynamicElementTextItem *text, ElementTextItemGroup *group, QUndoCommand *parent):
+	QUndoCommand(parent),
+	m_text(text),
+	m_group(group),
+	m_element(group->parentElement())
+{
+	setText(QObject::tr("Enlever un texte d'élément d'un groupe de textes"));
+}
+
+/**
+ * @brief RemoveTextFromGroupCommand::~RemoveTextFromGroupCommand
+ * Destructor
+ */
+RemoveTextFromGroupCommand::~RemoveTextFromGroupCommand()
+{
+	if(m_group && m_text && m_element)
+	{
+		if(!m_group.data()->texts().contains(m_text.data()) &&
+		   !m_element.data()->dynamicTextItems().contains(m_text.data()))
+			delete m_text.data();
+	}
+}
+
+void RemoveTextFromGroupCommand::undo()
+{
+	if(m_element && m_group && m_text)
+		m_element.data()->addTextToGroup(m_text, m_group);
+}
+
+void RemoveTextFromGroupCommand::redo()
+{
+	if(m_element && m_group && m_text)
+		m_element.data()->removeTextFromGroup(m_text, m_group);
+}
+
+
+/*****************************
+ * AlignmentTextsGroupCommand*
+ * ***************************/
+/**
+ * @brief AlignmentTextsGroupCommand::AlignmentTextsGroupCommand
+ * @param group : Group to change the alignment
+ * @param new_alignment : the new alignment of the group
+ * @param parent : the parent QUndoCommand of this undo
+ */
+AlignmentTextsGroupCommand::AlignmentTextsGroupCommand(ElementTextItemGroup *group, Qt::Alignment new_alignment, QUndoCommand *parent) :
+	QUndoCommand(parent),
+	m_group(group),
+	m_previous_alignment(group->alignment()),
+	m_new_alignment(new_alignment)
+{
+	setText(QObject::tr("Modifier l'alignement d'un groupe de textes"));
+	
+		//Text haven't got alignment
+	if(m_previous_alignment != Qt::AlignLeft ||
+	   m_previous_alignment != Qt::AlignVCenter ||
+	   m_previous_alignment != Qt::AlignRight)
+	{
+		for(DynamicElementTextItem *deti : group->texts())
+			m_texts_pos.insert(deti, deti->pos());
+	}
+}
+
+/**
+ * @brief AlignmentTextsGroupCommand::~AlignmentTextsGroupCommand
+ * Destructor
+ */
+AlignmentTextsGroupCommand::~AlignmentTextsGroupCommand()
+{}
+
+/**
+ * @brief AlignmentTextsGroupCommand::mergeWith
+ * Try to merge this command with other command
+ * @param other
+ * @return true if was merged, else false
+ */
+bool AlignmentTextsGroupCommand::mergeWith(const QUndoCommand *other)
+{
+	if (id() != other->id() || other->childCount())
+		return false;
+	
+	AlignmentTextsGroupCommand const *undo = static_cast<const AlignmentTextsGroupCommand *>(other);
+	if (m_group != undo->m_group)
+		return false;
+	
+	m_new_alignment= undo->m_new_alignment;
+	return true;
+}
+
+/**
+ * @brief AlignmentTextsGroupCommand::undo
+ */
+void AlignmentTextsGroupCommand::undo()
+{
+	if(m_group)
+	{
+		m_group.data()->setAlignment(m_previous_alignment);
+			//The alignment befor this command was free, then we must
+			//to restor the pos of each texts
+		if(!m_texts_pos.isEmpty())
+		{
+			for(DynamicElementTextItem *deti : m_group.data()->texts())
+			{
+				if(m_texts_pos.keys().contains(deti))
+					deti->setPos(m_texts_pos.value(deti));
+			}
+		}
+	}
+}
+
+/**
+ * @brief AlignmentTextsGroupCommand::redo
+ */
+void AlignmentTextsGroupCommand::redo()
+{
+	if(m_group)
+		m_group.data()->setAlignment(m_new_alignment);
+}

Modified: trunk/sources/undocommand/addelementtextcommand.h
===================================================================
--- trunk/sources/undocommand/addelementtextcommand.h	2017-11-28 16:15:37 UTC (rev 5123)
+++ trunk/sources/undocommand/addelementtextcommand.h	2017-11-29 14:49:12 UTC (rev 5124)
@@ -19,10 +19,16 @@
 #define ADDELEMENTTEXTCOMMAND_H
 
 #include <QUndoCommand>
+#include <QPointer>
 
 class Element;
 class DynamicElementTextItem;
+class ElementTextItemGroup;
 
+/**
+ * @brief The AddElementTextCommand class
+ * Manage the adding of element text
+ */
 class AddElementTextCommand : public QUndoCommand
 {
 	public:
@@ -37,18 +43,90 @@
 		DynamicElementTextItem *m_text = nullptr;
 };
 
-//class RemoveElementTextCommand : public QUndoCommand
-//{
-//	public:
-//		RemoveElementTextCommand(DynamicElementTextItem *deti, QUndoCommand *parent = nullptr);
-//		virtual ~RemoveElementTextCommand();
+/**
+ * @brief The AddTextsGroupCommand class
+ * Manage the adding of a texts group
+ */
+class AddTextsGroupCommand : public QUndoCommand
+{
+	public:
+		AddTextsGroupCommand(Element *element, QString groupe_name, QUndoCommand *parent = nullptr);
+		~AddTextsGroupCommand() override;
 		
-//		virtual void undo();
-//		virtual void redo();
-	
-//	private:
-//		Element *m_element = nullptr;
-//		DynamicElementTextItem *m_text = nullptr;
-//};
+		void undo() override;
+		void redo() override;
+		
+	private:
+		QPointer<Element> m_element;
+		QPointer<ElementTextItemGroup> m_group;
+		QString m_name;
+		bool m_first_undo = true;
+};
 
+/**
+ * @brief The RemoveTextsGroupCommand class
+ * Manage the removinf of a texts group
+ */
+class RemoveTextsGroupCommand : public QUndoCommand
+{
+	public:
+		RemoveTextsGroupCommand(Element *element, ElementTextItemGroup *group, QUndoCommand *parent = nullptr);
+		~RemoveTextsGroupCommand() override;
+		
+		void undo() override;
+		void redo() override;
+		
+	private:
+		QPointer<Element> m_element;
+		QPointer<ElementTextItemGroup> m_group;
+};
+
+class AddTextToGroupCommand : public QUndoCommand
+{
+	public:
+		AddTextToGroupCommand(DynamicElementTextItem *text, ElementTextItemGroup *group, QUndoCommand *parent = nullptr);
+		~AddTextToGroupCommand() override;
+		
+		void undo() override;
+		void redo() override;
+		
+	private:
+		QPointer<DynamicElementTextItem> m_text;
+		QPointer<ElementTextItemGroup> m_group;
+		QPointer<Element> m_element;
+};
+
+class RemoveTextFromGroupCommand : public QUndoCommand
+{
+	public:
+		RemoveTextFromGroupCommand(DynamicElementTextItem *text, ElementTextItemGroup *group, QUndoCommand *parent = nullptr);
+		~RemoveTextFromGroupCommand() override;
+		
+		void undo() override;
+		void redo() override;
+		
+	private:
+		QPointer<DynamicElementTextItem> m_text;
+		QPointer<ElementTextItemGroup> m_group;
+		QPointer<Element> m_element;
+};
+
+class AlignmentTextsGroupCommand : public QUndoCommand
+{
+	public:
+		AlignmentTextsGroupCommand(ElementTextItemGroup *group, Qt::Alignment new_alignment, QUndoCommand *parent = nullptr);
+		~AlignmentTextsGroupCommand() override;
+		
+		int id() const override{return 6;}
+		bool mergeWith(const QUndoCommand *other) override;
+		void undo() override;
+		void redo() override;
+		
+	private:
+		QPointer<ElementTextItemGroup> m_group;
+		Qt::Alignment m_previous_alignment,
+					  m_new_alignment;
+		QHash<DynamicElementTextItem *, QPointF> m_texts_pos;
+};
+
 #endif // ADDELEMENTTEXTCOMMAND_H

Modified: trunk/sources/undocommand/deleteqgraphicsitemcommand.cpp
===================================================================
--- trunk/sources/undocommand/deleteqgraphicsitemcommand.cpp	2017-11-28 16:15:37 UTC (rev 5123)
+++ trunk/sources/undocommand/deleteqgraphicsitemcommand.cpp	2017-11-29 14:49:12 UTC (rev 5124)
@@ -21,6 +21,7 @@
 #include "element.h"
 #include "conductor.h"
 #include "conductortextitem.h"
+#include "elementtextitemgroup.h"
 
 /**
  * @brief DeleteQGraphicsItemCommand::DeleteQGraphicsItemCommand
@@ -44,7 +45,12 @@
 	}
 	
 	for(DynamicElementTextItem *deti : m_removed_contents.m_element_texts)
-		m_elmt_text_hash.insert(deti, deti->parentElement());
+	{
+		if(deti->parentGroup())
+			m_grp_texts_hash.insert(deti, deti->parentGroup());
+		else
+			m_elmt_text_hash.insert(deti, deti->parentElement());
+	}
 	
 	setText(QString(QObject::tr("supprimer %1", "undo caption - %1 is a sentence listing the removed content")).arg(m_removed_contents.sentence(DiagramContent::All)));
 	m_diagram->qgiManager().manage(m_removed_contents.items(DiagramContent::All));
@@ -72,8 +78,14 @@
 	
 	for(DynamicElementTextItem *deti : m_removed_contents.m_element_texts)
 	{
-		deti->setParentItem(m_elmt_text_hash.value(deti));
-		m_elmt_text_hash.value(deti)->addDynamicTextItem(deti);
+		if(m_elmt_text_hash.keys().contains(deti))
+			m_elmt_text_hash.value(deti)->addDynamicTextItem(deti);
+		else if (m_grp_texts_hash.keys().contains(deti))
+		{
+			Element *elmt = m_grp_texts_hash.value(deti)->parentElement();
+			elmt->addDynamicTextItem(deti);
+			elmt->addTextToGroup(deti, m_grp_texts_hash.value(deti));
+		}
 	}
 }
 
@@ -109,6 +121,9 @@
 	
 	for(DynamicElementTextItem *deti : m_removed_contents.m_element_texts)
 	{
+		if(deti->parentGroup() && deti->parentGroup()->parentElement())
+			deti->parentGroup()->parentElement()->removeTextFromGroup(deti, deti->parentGroup());
+
 		deti->parentElement()->removeDynamicTextItem(deti);
 		deti->setParentItem(nullptr);
 	}

Modified: trunk/sources/undocommand/deleteqgraphicsitemcommand.h
===================================================================
--- trunk/sources/undocommand/deleteqgraphicsitemcommand.h	2017-11-28 16:15:37 UTC (rev 5123)
+++ trunk/sources/undocommand/deleteqgraphicsitemcommand.h	2017-11-29 14:49:12 UTC (rev 5124)
@@ -22,6 +22,7 @@
 #include "diagramcontent.h"
 
 class Diagram;
+class ElementTextItemGroup;
 
 class DeleteQGraphicsItemCommand : public QUndoCommand
 {
@@ -41,6 +42,7 @@
 		Diagram *m_diagram;
 		QHash <Element *, QList<Element *> > m_link_hash; /// keep linked element for each removed element linked to other element.
 		QHash <DynamicElementTextItem *, Element *> m_elmt_text_hash; /// Keep the parent element of each deleted dynamic element text item
+		QHash <DynamicElementTextItem *, ElementTextItemGroup *> m_grp_texts_hash; ///Keep the parent group of each deleted element text item
 };
 
 #endif // DELETEQGRAPHICSITEMCOMMAND_H


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