[qet] qet/qet: [5224] Element text item group : add new property -> hold to bottom of the page

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


Revision: 5224
Author:   blacksun
Date:     2018-02-01 19:40:12 +0100 (Thu, 01 Feb 2018)
Log Message:
-----------
Element text item group : add new property -> hold to bottom of the page

Modified Paths:
--------------
    trunk/sources/qetgraphicsitem/element.cpp
    trunk/sources/qetgraphicsitem/elementtextitemgroup.cpp
    trunk/sources/qetgraphicsitem/elementtextitemgroup.h
    trunk/sources/qetgraphicsitem/qgraphicsitemutility.cpp
    trunk/sources/qetgraphicsitem/qgraphicsitemutility.h
    trunk/sources/ui/dynamicelementtextmodel.cpp
    trunk/sources/ui/dynamicelementtextmodel.h
    trunk/sources/ui/elementpropertieswidget.cpp

Modified: trunk/sources/qetgraphicsitem/element.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/element.cpp	2018-01-28 11:16:09 UTC (rev 5223)
+++ trunk/sources/qetgraphicsitem/element.cpp	2018-02-01 18:40:12 UTC (rev 5224)
@@ -519,7 +519,12 @@
 				//that mean this is the good text
 			if (qFuzzyCompare(qreal(dom_input.attribute("x").toDouble()), m_converted_text_from_xml_description.value(deti).x()) &&
 				qFuzzyCompare(qreal(dom_input.attribute("y").toDouble()), m_converted_text_from_xml_description.value(deti).y()))
-			{	
+			{
+					//Once again this 'if', is only for retrocompatibility with old old old project
+					//when element text with tagg "label" is not null, but the element information "label" is. 
+				if((deti->textFrom() == DynamicElementTextItem::ElementInfo) && (deti->infoName() == "label"))
+					m_element_informations.addValue("label", dom_input.attribute("text"));
+				
 				deti->setText(dom_input.attribute("text"));
 				
 				qreal rotation = deti->rotation();
@@ -605,6 +610,11 @@
 	{
 		dc.addValue("formula", dc["label"]);
 	}
+		//retrocompatibility with older version
+	if(dc.value("label").toString().isEmpty() &&
+	   !m_element_informations.value("label").toString().isEmpty())
+		dc.addValue("label", m_element_informations.value("label"));
+	
 	setElementInformations(dc);
 	
 		/**
@@ -648,52 +658,110 @@
 		bool la = m_element_informations.keyMustShow("label");
 		bool c = m_element_informations.keyMustShow("comment");
 		bool lo = m_element_informations.keyMustShow("location");
-		if(!label.isEmpty() && la &&
-		   ((!comment.isEmpty() && c) || (!location.isEmpty() && lo)))
+		
+		if((m_link_type != Master) ||
+		   ((m_link_type == Master) &&
+			(diagram()->project()->defaultXRefProperties(m_kind_informations["type"].toString()).snapTo() == XRefProperties::Label))
+		   )
 		{
-				//#2 in the converted list one text must have text from = element info and info name = label
-			for(DynamicElementTextItem *deti : successfully_converted)
+			if(!label.isEmpty() && la &&
+			   ((!comment.isEmpty() && c) || (!location.isEmpty() && lo)))
 			{
-				if(deti->textFrom() == DynamicElementTextItem::ElementInfo && deti->infoName() == "label")
+					//#2 in the converted list one text must have text from = element info and info name = label
+				for(DynamicElementTextItem *deti : successfully_converted)
 				{
-						//Create the comment item
-					DynamicElementTextItem *comment_text = nullptr;
-					if(!comment.isEmpty() && c)
+					if(deti->textFrom() == DynamicElementTextItem::ElementInfo && deti->infoName() == "label")
 					{
-						comment_text = new DynamicElementTextItem(this);
-						comment_text->setTextFrom(DynamicElementTextItem::ElementInfo);
-						comment_text->setInfoName("comment");
-						comment_text->setFontSize(6);
-						comment_text->setFrame(true);
-						comment_text->setTextWidth(70);
-						comment_text->setPos(deti->x(), deti->y()+10); //+10 is arbitrary, comment_text must be below deti
-						addDynamicTextItem(comment_text);
+						qreal rotation = deti->rotation();
+						
+							//Create the comment item
+						DynamicElementTextItem *comment_text = nullptr;
+						if(!comment.isEmpty() && c)
+						{
+							comment_text = new DynamicElementTextItem(this);
+							comment_text->setTextFrom(DynamicElementTextItem::ElementInfo);
+							comment_text->setInfoName("comment");
+							comment_text->setFontSize(6);
+							comment_text->setFrame(true);
+							if(comment_text->toPlainText().count() > 17)
+								comment_text->setTextWidth(80);
+							comment_text->setPos(deti->x(), deti->y()+10); //+10 is arbitrary, comment_text must be below deti
+							addDynamicTextItem(comment_text);
+						}
+							//create the location item
+						DynamicElementTextItem *location_text = nullptr;
+						if(!location.isEmpty() && lo)
+						{
+							location_text = new DynamicElementTextItem(this);
+							location_text->setTextFrom(DynamicElementTextItem::ElementInfo);
+							location_text->setInfoName("location");
+							location_text->setFontSize(6);
+							if(comment_text->toPlainText().count() > 17)
+								location_text->setTextWidth(80);
+							location_text->setPos(deti->x(), deti->y()+20); //+20 is arbitrary, location_text must be below deti and comment
+							addDynamicTextItem(location_text);
+						}
+						
+						QPointF pos = deti->pos();
+							//Create the group
+						ElementTextItemGroup *group = addTextGroup(tr("Label + commentaire"));
+						addTextToGroup(deti, group);
+						if(comment_text)
+							addTextToGroup(comment_text, group);
+						if(location_text)
+							addTextToGroup(location_text, group);
+						group->setAlignment(Qt::AlignVCenter);
+						group->setVerticalAdjustment(-4);
+						group->setRotation(rotation);
+							//Change the position of the group, so that the text "label" stay in the same
+							//position in scene coordinate
+						group->setPos(pos - deti->pos());
+						
+						break;
 					}
-						//create the location item
-					DynamicElementTextItem *location_text = nullptr;
-					if(!location.isEmpty() && lo)
-					{
-						location_text = new DynamicElementTextItem(this);
-						location_text->setTextFrom(DynamicElementTextItem::ElementInfo);
-						location_text->setInfoName("location");
-						location_text->setFontSize(6);
-						location_text->setTextWidth(70);
-						location_text->setPos(deti->x(), deti->y()+20); //+20 is arbitrary, location_text must be below deti and comment
-						addDynamicTextItem(location_text);
-					}
-					
-						//Create the group
-					ElementTextItemGroup *group = addTextGroup(tr("Label + commentaire"));
-					addTextToGroup(deti, group);
+				}
+			}
+		}
+		else
+		{
+				//This element is supposed to be a master and Xref property snap to bottom
+			if((!comment.isEmpty() && c) || (!location.isEmpty() && lo))
+			{
+					//Create the comment item
+				DynamicElementTextItem *comment_text = nullptr;
+				if(!comment.isEmpty() && c)
+				{
+					comment_text = new DynamicElementTextItem(this);
+					comment_text->setTextFrom(DynamicElementTextItem::ElementInfo);
+					comment_text->setInfoName("comment");
+					comment_text->setFontSize(6);
+					comment_text->setFrame(true);
+					comment_text->setTextWidth(80);
+					addDynamicTextItem(comment_text);
+				}
+					//create the location item
+				DynamicElementTextItem *location_text = nullptr;
+				if(!location.isEmpty() && lo)
+				{
+					location_text = new DynamicElementTextItem(this);
+					location_text->setTextFrom(DynamicElementTextItem::ElementInfo);
+					location_text->setInfoName("location");
+					location_text->setFontSize(6);
+					location_text->setTextWidth(80);
 					if(comment_text)
-						addTextToGroup(comment_text, group);
-					if(location_text)
-						addTextToGroup(location_text, group);
-					group->setAlignment(Qt::AlignVCenter);
-					group->setVerticalAdjustment(-4);
-					
-					break;
+						location_text->setPos(comment_text->x(), comment_text->y()+10); //+10 is arbitrary, location_text must be below the comment
+					addDynamicTextItem(location_text);
 				}
+				
+					//Create the group
+				ElementTextItemGroup *group = addTextGroup(tr("Label + commentaire"));
+				if(comment_text)
+					addTextToGroup(comment_text, group);
+				if(location_text)
+					addTextToGroup(location_text, group);
+				group->setAlignment(Qt::AlignVCenter);
+				group->setVerticalAdjustment(-4);
+				group->setHoldToBottomPage(true);
 			}
 		}
 	}
@@ -794,6 +862,7 @@
 		//Dynamic texts owned by groups
 	for(ElementTextItemGroup *group : m_texts_group)
 	{
+		group->blockAlignmentUpdate(true);
 			//temporarily remove the texts from group to get the pos relative to element and not group.
 			//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
@@ -818,6 +887,7 @@
 		
 			//Save the group to xml
 		texts_group.appendChild(group->toXml(document));
+		group->blockAlignmentUpdate(false);
 	}
 	
 		//Append the dynamic texts to element

Modified: trunk/sources/qetgraphicsitem/elementtextitemgroup.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/elementtextitemgroup.cpp	2018-01-28 11:16:09 UTC (rev 5223)
+++ trunk/sources/qetgraphicsitem/elementtextitemgroup.cpp	2018-02-01 18:40:12 UTC (rev 5224)
@@ -23,6 +23,8 @@
 #include "QPropertyUndoCommand/qpropertyundocommand.h"
 #include "crossrefitem.h"
 #include "qetapp.h"
+#include "masterelement.h"
+#include "qgraphicsitemutility.h"
 
 #include <QPainter>
 #include <QGraphicsSceneMouseEvent>
@@ -56,18 +58,13 @@
 {
 	if(item->type() == DynamicElementTextItem::Type)
 	{
-			//Befor add text to group we must to set the text and the group to the same rotation
-		item->setRotation(0);
-		item->setFlag(QGraphicsItem::ItemIsSelectable, false);
+			//Befor add text to this group we must to set the text at the same rotation of this group		
+		if((item->rotation() != rotation()) && !m_block_alignment_update)
+			item->setRotation(rotation());
 		
-		qreal rot = this->rotation();
-		this->setRotation(0);
-		
 		QGraphicsItemGroup::addToGroup(item);
 		updateAlignment();
 		
-		this->setRotation(rot);
-		
 		DynamicElementTextItem *deti = qgraphicsitem_cast<DynamicElementTextItem *>(item);
 		connect(deti, &DynamicElementTextItem::fontSizeChanged,      this, &ElementTextItemGroup::updateAlignment);
 		connect(deti, &DynamicElementTextItem::textChanged,          this, &ElementTextItemGroup::updateAlignment);
@@ -116,6 +113,17 @@
 }
 
 /**
+ * @brief ElementTextItemGroup::blockAlignmentUpdate
+ * If true, the texts in this group are never aligned, moved, rotated etc...
+ * the texts stay as it was, until blockAlignmentUpdate is set to false.
+ * @param block
+ */
+void ElementTextItemGroup::blockAlignmentUpdate(bool block)
+{
+	m_block_alignment_update = block;
+}
+
+/**
  * @brief ElementTextItemGroup::setAlignement
  * Set the alignement of this group
  * @param alignement
@@ -140,13 +148,42 @@
  */
 void ElementTextItemGroup::updateAlignment()
 {
+	if(m_block_alignment_update)
+		return;
+	
 	prepareGeometryChange();
 	
 	QList <DynamicElementTextItem *> texts = this->texts();
 	
-	if (texts.size() > 1)
+	qreal rotation_ = rotation();
+	
+		//Set the rotation of this group to 0° relative to the scene
+	qreal rot = rotation();
+	QGraphicsItem *parent = parentItem();
+	while (parent) {
+		rot += parent->rotation();
+		parent = parent->parentItem();
+	}
+	if(rot != 0)
+		setRotation(rotation() - rot);
+	
+	
+	if(texts.size() == 1)
 	{
 		prepareGeometryChange();
+		
+		QGraphicsItem *first = texts.first();
+		setPos(mapFromScene(first->mapToScene(pos())));
+		first->setPos(0,0);
+	}
+	else if (texts.size() > 1)
+	{
+		qreal width = 0;
+		for(QGraphicsItem *item : texts)
+			if(item->boundingRect().width() > width)
+				width = item->boundingRect().width();
+		
+		prepareGeometryChange();
 		std::sort(texts.begin(), texts.end(), sorting);
 		
 		qreal y_offset = 0;
@@ -157,14 +194,13 @@
 				
 			for(QGraphicsItem *item : texts)
 			{
-				item->setPos(ref.x(), ref.y()+y_offset);
+				item->setPos(0, ref.y()+y_offset);
 				y_offset+=item->boundingRect().height() + m_vertical_adjustment;
 			}
 		}
 		else if(m_alignment == Qt::AlignVCenter)
 		{
-			QPointF ref(texts.first()->pos().x() + texts.first()->boundingRect().width()/2,
-						texts.first()->pos().y());
+			QPointF ref(width/2,0);
 			
 			for(QGraphicsItem *item : texts)
 			{
@@ -175,8 +211,7 @@
 		}
 		else if (m_alignment == Qt::AlignRight)
 		{
-			QPointF ref(texts.first()->pos().x() + texts.first()->boundingRect().width(),
-						texts.first()->pos().y());
+			QPointF ref(width,0);
 			
 			for(QGraphicsItem *item : texts)
 			{
@@ -185,14 +220,17 @@
 				y_offset+=item->boundingRect().height() + m_vertical_adjustment;
 			}
 		}
-		
-		setTransformOriginPoint(boundingRect().topLeft());
 	}
 	
+		//Restor the rotation
+	setRotation(rotation_);
+	
 	if(m_Xref_item)
 		m_Xref_item->autoPos();
 	if(m_slave_Xref_item)
 		adjustSlaveXrefPos();
+	if(m_hold_to_bottom_of_page)
+		autoPos();
 }
 
 /**
@@ -219,6 +257,47 @@
 	emit nameChanged(m_name);
 }
 
+void ElementTextItemGroup::setHoldToBottomPage(bool hold)
+{
+	if(m_hold_to_bottom_of_page == hold)
+		return;
+	
+	m_hold_to_bottom_of_page = hold;
+	if(m_hold_to_bottom_of_page)
+	{
+		setFlag(QGraphicsItem::ItemIsSelectable, false);
+		setFlag(QGraphicsItem::ItemIsMovable, false);
+		connect(m_parent_element, &Element::yChanged, this, &ElementTextItemGroup::autoPos);
+		connect(m_parent_element, &Element::rotationChanged, this, &ElementTextItemGroup::autoPos);
+		if(m_parent_element->linkType() == Element::Master)
+		{
+				//We use timer to let the time of the parent element xref to be updated, befor update the position of this group
+				//because the position of this group is related to the size of the parent element Xref
+			m_linked_changed_timer = connect(m_parent_element, &Element::linkedElementChanged,
+											 [this]() {QTimer::singleShot(200, this, &ElementTextItemGroup::autoPos);});
+			if(m_parent_element->diagram())
+				m_XrefChanged_timer = connect(m_parent_element->diagram()->project(), &QETProject::XRefPropertiesChanged,
+											  [this]()	{QTimer::singleShot(200, this, &ElementTextItemGroup::autoPos);});
+		}
+		autoPos();
+	}
+	else
+	{
+		setFlag(QGraphicsItem::ItemIsSelectable, true);
+		setFlag(QGraphicsItem::ItemIsMovable, true);
+		disconnect(m_parent_element, &Element::yChanged, this, &ElementTextItemGroup::autoPos);
+		disconnect(m_parent_element, &Element::rotationChanged, this, &ElementTextItemGroup::autoPos);
+		if(m_parent_element->linkType() == Element::Master)
+		{
+			disconnect(m_linked_changed_timer);
+			if(m_XrefChanged_timer)
+				disconnect(m_XrefChanged_timer);
+		}
+	}
+	
+	emit holdToBottomPageChanged(hold);
+}
+
 /**
  * @brief ElementTextItemGroup::texts
  * @return Every texts in this group
@@ -268,6 +347,9 @@
 {
 	QDomElement dom_element = dom_document.createElement(this->xmlTaggName());
 	dom_element.setAttribute("name", m_name);
+	
+	dom_element.setAttribute("x", QString::number(pos().x()));
+	dom_element.setAttribute("y", QString::number(pos().y()));
 
 	QMetaEnum me = QMetaEnum::fromType<Qt::Alignment>();
 	dom_element.setAttribute("alignment", me.valueToKey(m_alignment));
@@ -275,6 +357,8 @@
 	dom_element.setAttribute("rotation", this->rotation());
 	dom_element.setAttribute("vertical_adjustment", m_vertical_adjustment);
 	
+	dom_element.setAttribute("hold_to_bottom_page", m_hold_to_bottom_of_page == true ? "true" : "false");
+	
 	QDomElement dom_texts = dom_document.createElement("texts");
 	for(DynamicElementTextItem *deti : texts())
 	{
@@ -303,11 +387,18 @@
 	QMetaEnum me = QMetaEnum::fromType<Qt::Alignment>();
 	setAlignment(Qt::Alignment(me.keyToValue(dom_element.attribute("alignment").toStdString().data())));
 	
+	setPos(dom_element.attribute("x", QString::number(0)).toDouble(),
+		   dom_element.attribute("y", QString::number(0)).toDouble());
+	
 	setRotation(dom_element.attribute("rotation", QString::number(0)).toDouble());
 	setVerticalAdjustment(dom_element.attribute("vertical_adjustment").toInt());
 	
+	QString hold = dom_element.attribute("hold_to_bottom_page", "false");
+	setHoldToBottomPage(hold == "true" ? true : false);
+	
 	if(parentElement())
 	{
+		m_block_alignment_update = true;
 		for(QDomElement text : QET::findInDomElement(dom_element, "texts", "text"))
 		{
 			DynamicElementTextItem *deti = nullptr;
@@ -320,6 +411,7 @@
 			if (deti)
 				parentElement()->addTextToGroup(deti, this);
 		}
+		m_block_alignment_update = false;
 	}
 }
 
@@ -342,6 +434,7 @@
 		t.setCosmetic(true);
 		painter->setPen(t);
 		painter->drawRoundRect(boundingRect().adjusted(1, 1, -1, -1), 10, 10);
+		
 		painter->restore();
 	}
 }
@@ -367,7 +460,7 @@
 }
 
 void ElementTextItemGroup::setRotation(qreal angle)
-{
+{	
 	QGraphicsItemGroup::setRotation(angle);
 	emit rotationChanged(angle);
 }
@@ -614,3 +707,31 @@
 	m_slave_Xref_item->setPos(pos);
 }
 
+void ElementTextItemGroup::autoPos()
+{
+	int offset = 5;
+	
+	if(m_parent_element->linkType() == Element::Master)
+	{
+		if(!diagram())
+			return;
+		
+		MasterElement *master = static_cast<MasterElement *>(m_parent_element);
+		XRefProperties xrp = diagram()->project()->defaultXRefProperties(master->kindInformations()["type"].toString());
+		if(xrp.snapTo() == XRefProperties::Bottom)
+		{
+			QRectF rectXref = master->XrefBoundingRect();
+			offset = xrp.offset() <= 40 ? 5 : xrp.offset();
+			
+			offset += (int)rectXref.height();
+		}
+	}
+	qreal r = rotation();
+	centerToBottomDiagram(this, m_parent_element, offset);
+		//centerToBottomDiagram change the rotation of this group if needed,
+		//but setRotation is not a virtual function of QGraphicsItem, and the function centerToBottomDiagram
+		//work with a QGraphicsItem. So we emit the signal if rotation changed
+	if(rotation() != r)
+		emit rotationChanged(rotation());
+}
+

Modified: trunk/sources/qetgraphicsitem/elementtextitemgroup.h
===================================================================
--- trunk/sources/qetgraphicsitem/elementtextitemgroup.h	2018-01-28 11:16:09 UTC (rev 5223)
+++ trunk/sources/qetgraphicsitem/elementtextitemgroup.h	2018-02-01 18:40:12 UTC (rev 5224)
@@ -1,4 +1,4 @@
-/*
+/*
 	Copyright 2006-2017 The QElectroTech Team
 	This file is part of QElectroTech.
 
@@ -41,6 +41,7 @@
 	Q_PROPERTY(int verticalAdjustment READ verticalAdjustment WRITE setVerticalAdjustment NOTIFY verticalAdjustmentChanged)
 	Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged)
 	Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+	Q_PROPERTY(bool holdToBottomPage READ holdToBottomPage WRITE setHoldToBottomPage NOTIFY holdToBottomPageChanged)
 	
 	public:
 	signals:
@@ -48,6 +49,7 @@
 		void verticalAdjustmentChanged(int);
 		void alignmentChanged(Qt::Alignment);
 		void nameChanged(QString);
+		void holdToBottomPageChanged(bool);
 	
 	public:
 		ElementTextItemGroup(const QString &name, Element *parent);
@@ -54,6 +56,7 @@
 		~ElementTextItemGroup() override;
 		void addToGroup(QGraphicsItem *item);
 		void removeFromGroup(QGraphicsItem *item);
+		void blockAlignmentUpdate(bool block);
 		
 		void setAlignment(Qt::Alignment alignement);
 		Qt::Alignment alignment() const;
@@ -62,6 +65,8 @@
 		void setVerticalAdjustment(int v);
 		void setName(QString name);
 		QString name() const {return m_name;}
+		void setHoldToBottomPage(bool hold);
+		bool holdToBottomPage() const {return m_hold_to_bottom_of_page;}
 		QList<DynamicElementTextItem *> texts() const;
 		Diagram *diagram() const;
 		Element *parentElement() const;
@@ -86,11 +91,14 @@
 	private:
 		void updateXref();
 		void adjustSlaveXrefPos();
+		void autoPos();
 
 	private:
 		Qt::Alignment m_alignment = Qt::AlignJustify;
 		QString m_name;
-		bool m_first_move = true;
+		bool m_first_move = true,
+			 m_hold_to_bottom_of_page = false,
+			 m_block_alignment_update = false;
 		QPointF m_initial_position;
 		int m_vertical_adjustment = 0;
 		CrossRefItem *m_Xref_item = nullptr;
@@ -97,6 +105,8 @@
 		Element *m_parent_element = nullptr;
 		QList<QMetaObject::Connection> m_update_slave_Xref_connection;
 		QGraphicsTextItem *m_slave_Xref_item = nullptr;
+		QMetaObject::Connection m_XrefChanged_timer,
+								m_linked_changed_timer;
 };
 
 #endif // ELEMENTTEXTITEMGROUP_H

Modified: trunk/sources/qetgraphicsitem/qgraphicsitemutility.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/qgraphicsitemutility.cpp	2018-01-28 11:16:09 UTC (rev 5223)
+++ trunk/sources/qetgraphicsitem/qgraphicsitemutility.cpp	2018-02-01 18:40:12 UTC (rev 5224)
@@ -49,28 +49,38 @@
  * @param offset
  * @return true if element is centered else false (element_to_follow have not diagram)
  */
-bool centerToBottomDiagram (QGraphicsItem *item_to_center, Element *element_to_follow, int offset) {
+#include "elementtextitemgroup.h"
+#include "crossrefitem.h"
+bool centerToBottomDiagram (QGraphicsItem *item_to_center, Element *element_to_follow, qreal offset) {
 	if (! element_to_follow -> diagram()) {
 		qDebug() << "qgraphicsitemutility centerAtBottomDiagram : Element_to_follow have not diagram";
 		return false;
 	}
-
+	
 	QRectF  border = element_to_follow -> diagram() -> border_and_titleblock.insideBorderRect();
 	QPointF point  = element_to_follow -> sceneBoundingRect().center();
-
+	
 	point.setY(border.bottom() - item_to_center -> boundingRect().height() - offset );
-	point.rx() -= (item_to_center -> boundingRect().width()/2 +
-				   item_to_center -> boundingRect().left()); //< we add boundingrect.left because this value can be négative
-
+	point.rx() -= (item_to_center -> boundingRect().width()/2);
+	
+		//Apply the difference between the pos() of item and his bounding rect
+	QPointF tl = item_to_center->boundingRect().topLeft();
+	point.rx() -= tl.x();
+	point.ry() -= tl.y();
+	
 	item_to_center -> setPos(0,0);	  //Due to a weird behavior or bug, before set the new position and rotation,
 	item_to_center -> setRotation(0); //we must to set the position and rotation at 0.
-
-	item_to_center -> setPos(item_to_center -> mapFromScene(point));
-
-	if (item_to_center -> rotation() != - element_to_follow -> rotation()) {
-		item_to_center -> setRotation(0);
-		item_to_center -> setRotation(- element_to_follow -> rotation());
+	
+	item_to_center->setPos(item_to_center->mapFromScene(point));
+	
+	qreal rot = item_to_center->rotation();
+	QGraphicsItem *parent = item_to_center->parentItem();
+	while (parent) {
+		rot += parent->rotation();
+		parent = parent->parentItem();
 	}
+	if(rot != 0)
+		item_to_center->setRotation(item_to_center->rotation() - rot);
 
 	return true;
 }

Modified: trunk/sources/qetgraphicsitem/qgraphicsitemutility.h
===================================================================
--- trunk/sources/qetgraphicsitem/qgraphicsitemutility.h	2018-01-28 11:16:09 UTC (rev 5223)
+++ trunk/sources/qetgraphicsitem/qgraphicsitemutility.h	2018-02-01 18:40:12 UTC (rev 5224)
@@ -17,11 +17,11 @@
 */
 #ifndef QGRAPHICSITEMUTILITY_H
 #define QGRAPHICSITEMUTILITY_H
-
+#include <QtGlobal>
 class QGraphicsItem;
 class Element;
 
 bool centerToParentBottom  (QGraphicsItem *item);
-bool centerToBottomDiagram (QGraphicsItem *item_to_center, Element *element_to_follow, int offset = 0 );
+bool centerToBottomDiagram (QGraphicsItem *item_to_center, Element *element_to_follow, qreal offset = 0 );
 
 #endif // QGRAPHICSITEMUTILITY_H

Modified: trunk/sources/ui/dynamicelementtextmodel.cpp
===================================================================
--- trunk/sources/ui/dynamicelementtextmodel.cpp	2018-01-28 11:16:09 UTC (rev 5223)
+++ trunk/sources/ui/dynamicelementtextmodel.cpp	2018-02-01 18:40:12 UTC (rev 5224)
@@ -49,6 +49,7 @@
 int align_grp_row  = 0;
 int rot_grp_row    = 1;
 int adjust_grp_row = 2;
+int hold_to_bottom_grp_row = 3;
 
 DynamicElementTextModel::DynamicElementTextModel(Element *element, QObject *parent) :
 	QStandardItemModel(parent),
@@ -544,6 +545,10 @@
 	QString name = group_qsi->data(Qt::DisplayRole).toString();
 	if(group->name() != name)
 		new QPropertyUndoCommand(group, "name", QVariant(group->name()), QVariant(name), undo);
+	
+	bool hold_to_bottom = group_qsi->child(hold_to_bottom_grp_row, 1)->checkState() == Qt::Checked? true : false;
+	if(group->holdToBottomPage() != hold_to_bottom)
+		new QPropertyUndoCommand(group, "holdToBottomPage", QVariant(group->holdToBottomPage()), QVariant(hold_to_bottom), undo);
 		
 	
 	return undo;
@@ -585,7 +590,7 @@
 		default: break;}
 	
 	QStandardItem *alignment_a = new QStandardItem(text);
-	alignment_a->setData(DynamicElementTextModel::grp_alignment, Qt::UserRole+1);
+	alignment_a->setData(DynamicElementTextModel::grpAlignment, Qt::UserRole+1);
 	alignment_a->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
 	qsi_list.clear();
 	qsi_list << alignment << alignment_a;
@@ -597,7 +602,7 @@
 	
 	QStandardItem *rot_a = new QStandardItem;
 	rot_a->setData(group->rotation(), Qt::EditRole);
-	rot_a->setData(DynamicElementTextModel::grp_rotation, Qt::UserRole+1);
+	rot_a->setData(DynamicElementTextModel::grpRotation, Qt::UserRole+1);
 	rot_a->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
 	qsi_list.clear();
 	qsi_list << rot << rot_a;
@@ -609,12 +614,25 @@
 	
 	QStandardItem *v_adj_a = new QStandardItem;
 	v_adj_a->setData(group->verticalAdjustment(), Qt::EditRole);
-	v_adj_a->setData(DynamicElementTextModel::grp_v_adjust, Qt::UserRole+1);
+	v_adj_a->setData(DynamicElementTextModel::grpVAdjust, Qt::UserRole+1);
 	v_adj_a->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
 	qsi_list.clear();
 	qsi_list << v_adj << v_adj_a;
 	grp->appendRow(qsi_list);
 	
+		//Hold to the bottom of the page
+	QStandardItem *hold_bottom = new QStandardItem(tr("Maintenir en bas de page"));
+	hold_bottom->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
+	
+	QStandardItem *hold_bottom_a = new QStandardItem();
+	hold_bottom_a->setCheckable(true);
+	hold_bottom_a->setCheckState(group->holdToBottomPage() ? Qt::Checked : Qt::Unchecked);
+	hold_bottom_a->setData(DynamicElementTextModel::grpHoldBottom, Qt::UserRole+1);
+	hold_bottom_a->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
+	qsi_list.clear();
+	qsi_list << hold_bottom << hold_bottom_a;
+	grp->appendRow(qsi_list);
+	
 
 		//Add the texts of the group
 	for(DynamicElementTextItem *deti : group->texts())
@@ -623,6 +641,7 @@
 		group_item->appendRow(itemsForText(deti));
 	}
 	setConnection(group, true);
+	enableGroupRotation(group);
 }
 
 /**
@@ -990,6 +1009,30 @@
 	qsi->child(compo_txt_row,1)->setEnabled(compo);
 }
 
+/**
+ * @brief DynamicElementTextModel::enableGroupRotation
+ * Enable/disable the item "group rotation" according the option hold to bottom 
+ * @param group
+ */
+void DynamicElementTextModel::enableGroupRotation(ElementTextItemGroup *group)
+{
+	if(!m_groups_list.contains(group))
+		return;
+	
+	QStandardItem *qsi = m_groups_list.value(group);
+	
+	if(group->holdToBottomPage())
+	{
+		qsi->child(rot_grp_row, 0)->setFlags(Qt::ItemIsSelectable);
+		qsi->child(rot_grp_row, 1)->setFlags(Qt::ItemIsSelectable);
+	}
+	else
+	{
+		qsi->child(rot_grp_row, 0)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+		qsi->child(rot_grp_row, 1)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
+	}
+}
+
 void DynamicElementTextModel::itemDataChanged(QStandardItem *qsi)
 {
 	DynamicElementTextItem *deti = textFromItem(qsi);
@@ -1107,10 +1150,11 @@
 			return;
 		
 		QList<QMetaObject::Connection> connection_list;
-		connection_list << connect(group, &ElementTextItemGroup::alignmentChanged, [group, this]() {this->updateDataFromGroup(group, grp_alignment);});
-		connection_list << connect(group, &ElementTextItemGroup::rotationChanged, [group, this]() {this->updateDataFromGroup(group, grp_rotation);});
-		connection_list << connect(group, &ElementTextItemGroup::verticalAdjustmentChanged, [group, this]() {this->updateDataFromGroup(group, grp_v_adjust);});
-		connection_list << connect(group, &ElementTextItemGroup::verticalAdjustmentChanged, [group, this]() {this->updateDataFromGroup(group, grp_name);});
+		connection_list << connect(group, &ElementTextItemGroup::alignmentChanged, [group, this]() {this->updateDataFromGroup(group, grpAlignment);});
+		connection_list << connect(group, &ElementTextItemGroup::rotationChanged, [group, this]() {this->updateDataFromGroup(group, grpRotation);});
+		connection_list << connect(group, &ElementTextItemGroup::verticalAdjustmentChanged, [group, this]() {this->updateDataFromGroup(group, grpVAdjust);});
+		connection_list << connect(group, &ElementTextItemGroup::verticalAdjustmentChanged, [group, this]() {this->updateDataFromGroup(group, grpName);});
+		connection_list << connect(group, &ElementTextItemGroup::holdToBottomPageChanged, [group, this]() {this->updateDataFromGroup(group, grpHoldBottom);});
 		
 		m_hash_group_connect.insert(group, connection_list);
 	}
@@ -1219,7 +1263,7 @@
 	
 	switch (type)
 	{
-		case grp_alignment:
+		case grpAlignment:
 		{
 			switch (group->alignment())
 			{
@@ -1230,15 +1274,21 @@
 			}
 			 break;
 		}
-		case grp_rotation:
+		case grpRotation:
 			qsi->child(rot_grp_row,1)->setData(group->rotation(), Qt::EditRole);
 			break;
-		case grp_v_adjust:
+		case grpVAdjust:
 			qsi->child(adjust_grp_row,1)->setData(group->verticalAdjustment(), Qt::EditRole);
 			break;
-		case grp_name:
+		case grpName:
 			qsi->setData(group->name(), Qt::DisplayRole);
 			break;
+		case grpHoldBottom:
+		{
+			qsi->child(hold_to_bottom_grp_row,1)->setCheckState(group->holdToBottomPage()? Qt::Checked : Qt::Unchecked);
+			enableGroupRotation(group);
+			break;
+		}
 	}
 	
 	m_block_dataChanged = false;
@@ -1350,7 +1400,7 @@
 			sb->setSuffix(" px");
 			return sb;
 		}
-		case DynamicElementTextModel::grp_alignment:
+		case DynamicElementTextModel::grpAlignment:
 		{
 			QComboBox *qcb = new QComboBox(parent);
 			qcb->setFrame(false);
@@ -1360,7 +1410,7 @@
 			qcb->addItem(tr("Droite"));
 			return qcb;
 		}
-		case DynamicElementTextModel::grp_rotation:
+		case DynamicElementTextModel::grpRotation:
 		{
 			QSpinBox *sb = new QSpinBox(parent);
 			sb->setObjectName("group_rotation");
@@ -1370,7 +1420,7 @@
 			sb->setSuffix(" °");
 			return sb;
 		}
-		case DynamicElementTextModel::grp_v_adjust:
+		case DynamicElementTextModel::grpVAdjust:
 		{
 			QSpinBox *sb = new QSpinBox(parent);
 			sb->setObjectName("group_v_adjustment");

Modified: trunk/sources/ui/dynamicelementtextmodel.h
===================================================================
--- trunk/sources/ui/dynamicelementtextmodel.h	2018-01-28 11:16:09 UTC (rev 5223)
+++ trunk/sources/ui/dynamicelementtextmodel.h	2018-02-01 18:40:12 UTC (rev 5224)
@@ -48,10 +48,11 @@
 			frame,
 			rotation,
 			textWidth,
-			grp_alignment,
-			grp_rotation,
-			grp_v_adjust,
-			grp_name
+			grpAlignment,
+			grpRotation,
+			grpVAdjust,
+			grpName,
+			grpHoldBottom
         };
         
 		DynamicElementTextModel(Element *element, QObject *parent = nullptr);
@@ -87,6 +88,7 @@
 		void addTextToGroup(DynamicElementTextItem *deti, ElementTextItemGroup *group);
 		void removeTextFromGroup(DynamicElementTextItem *deti, ElementTextItemGroup *group);
 		void enableSourceText(DynamicElementTextItem *deti, DynamicElementTextItem::TextFrom tf );
+		void enableGroupRotation(ElementTextItemGroup *group);
         void itemDataChanged(QStandardItem *qsi);
 		void setConnection(DynamicElementTextItem *deti, bool set);
 		void setConnection(ElementTextItemGroup *group, bool set);

Modified: trunk/sources/ui/elementpropertieswidget.cpp
===================================================================
--- trunk/sources/ui/elementpropertieswidget.cpp	2018-01-28 11:16:09 UTC (rev 5223)
+++ trunk/sources/ui/elementpropertieswidget.cpp	2018-02-01 18:40:12 UTC (rev 5224)
@@ -361,9 +361,9 @@
 		description_string += QString(tr("Folio : %1\n")).arg(folio_index + 1);
 	}
 	description_string += QString(tr("Position : %1\n")).arg(m_diagram -> convertPosition(m_element -> scenePos()).toString());
+	description_string += QString(tr("Rotation : %1°\n")).arg(m_element.data()->rotation());
 	description_string += QString(tr("Dimensions : %1*%2\n")).arg(m_element -> size().width()).arg(m_element -> size().height());
 	description_string += QString(tr("Bornes : %1\n")).arg(m_element -> terminals().count());
-	description_string += QString(tr("Champs de texte : %1\n")).arg(m_element -> texts().count());
 
 	if (custom_element) {
 		description_string += QString(tr("Emplacement : %1\n")).arg(custom_element -> location().toString());


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