[qet] qet/qet: [5005] First step for the dynamic element text : Now user can add directly from the diagram editor an editable text of an element.

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


Revision: 5005
Author:   blacksun
Date:     2017-08-03 19:36:08 +0200 (Thu, 03 Aug 2017)
Log Message:
-----------
First step for the dynamic element text : Now user can add directly from the diagram editor an editable text of an element.

Modified Paths:
--------------
    trunk/dev_doc/enum_type_of_QGraphicsItem
    trunk/sources/diagram.cpp
    trunk/sources/diagram.h
    trunk/sources/diagramcommands.cpp
    trunk/sources/diagramcommands.h
    trunk/sources/diagramcontent.cpp
    trunk/sources/diagramcontent.h
    trunk/sources/diagramview.cpp
    trunk/sources/diagramview.h
    trunk/sources/elementsmover.cpp
    trunk/sources/elementtextsmover.cpp
    trunk/sources/elementtextsmover.h
    trunk/sources/qet.cpp
    trunk/sources/qet.h
    trunk/sources/qetdiagrameditor.cpp
    trunk/sources/qetdiagrameditor.h
    trunk/sources/qetgraphicsitem/diagramtextitem.cpp
    trunk/sources/qetgraphicsitem/diagramtextitem.h
    trunk/sources/qetgraphicsitem/element.cpp
    trunk/sources/qetgraphicsitem/element.h
    trunk/sources/ui/diagrampropertieseditordockwidget.cpp
    trunk/sources/ui/elementpropertieswidget.cpp

Added Paths:
-----------
    trunk/sources/qetgraphicsitem/dynamicelementtextitem.cpp
    trunk/sources/qetgraphicsitem/dynamicelementtextitem.h
    trunk/sources/ui/dynamicelementtextitemeditor.cpp
    trunk/sources/ui/dynamicelementtextitemeditor.h
    trunk/sources/ui/dynamicelementtextitemeditor.ui
    trunk/sources/ui/dynamicelementtextmodel.cpp
    trunk/sources/ui/dynamicelementtextmodel.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/enum_type_of_QGraphicsItem
===================================================================
--- trunk/dev_doc/enum_type_of_QGraphicsItem	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/dev_doc/enum_type_of_QGraphicsItem	2017-08-03 17:36:08 UTC (rev 5005)
@@ -10,6 +10,7 @@
 DiagramImageItem + 1007
 QetShapItem + 1008
 crossRefItem + 1009
+DynamiqueElementTextItem + 1010
 ElementPrimitiveDecorator + 2200
 
 ###ELEMENT EDITOR###
@@ -21,3 +22,6 @@
 part text       + 1107
 part text field + 1108
 part rectangle  + 1109
+
+###QetGraphicsHandlerItem###
+QetGraphicsHandlerItem = 1200

Modified: trunk/sources/diagram.cpp
===================================================================
--- trunk/sources/diagram.cpp	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/diagram.cpp	2017-08-03 17:36:08 UTC (rev 5005)
@@ -38,6 +38,7 @@
 #include "elementcollectionhandler.h"
 #include "element.h"
 #include "diagramview.h"
+#include "dynamicelementtextitem.h"
 
 const int   Diagram::xGrid  = 10;
 const int   Diagram::yGrid  = 10;
@@ -75,7 +76,7 @@
 	
 		//Init object for manage movement
 	elements_mover_      = new ElementsMover();
-	element_texts_mover_ = new ElementTextsMover();
+	m_element_texts_mover = new ElementTextsMover();
 
 	connect(&border_and_titleblock, SIGNAL(needTitleBlockTemplate(const QString &)), this, SLOT(setTitleBlockTemplate(const QString &)));
 	connect(&border_and_titleblock, SIGNAL(diagramTitleChanged(const QString &)),    this, SLOT(titleChanged(const QString &)));
@@ -91,31 +92,30 @@
  * @brief Diagram::~Diagram
  * Destructor
  */
-Diagram::~Diagram() {
-	// clear undo stack to prevent errors, because contains pointers to this diagram and is elements.
+Diagram::~Diagram()
+{
+        //First clear every selection to close an hypothetical editor
+    clearSelection();
+        // clear undo stack to prevent errors, because contains pointers to this diagram and is elements.
 	undoStack().clear();
-	//delete of QGIManager, every elements he knows are removed
+        //delete of QGIManager, every elements he knows are removed
 	delete qgi_manager_;
-	// remove of conductor setter
+        // remove of conductor setter
 	delete conductor_setter_;
 	
-	// delete of object for manage movement
+        // delete of object for manage movement
 	delete elements_mover_;
-	delete element_texts_mover_;
+	delete m_element_texts_mover;
 
-	if (m_event_interface) delete m_event_interface;
+	if (m_event_interface)
+        delete m_event_interface;
 	
-	// list removable items
+        // list removable items
 	QList<QGraphicsItem *> deletable_items;
 	for(QGraphicsItem *qgi : items())
-	{
-		if (qgi->parentItem())
-			continue;
-		if (qgi->type() == Conductor::Type)
-			continue;
-		if (qgi->type() == QetGraphicsHandlerItem::Type)
-			continue;
-		
+    {
+		if (qgi -> parentItem()) continue;
+		if (qgraphicsitem_cast<Conductor *>(qgi)) continue;
 		deletable_items << qgi;
 	}
 
@@ -302,10 +302,10 @@
 		qreal top_position = 0;
 		qreal left_position = 0;
 		QList<QGraphicsItem*> selected_elmts = this->selectedContent().items();
-		if (!this->selectedContent().items(255).isEmpty()) {
+		if (!this->selectedContent().items(DiagramContent::All).isEmpty()) {
 		switch(e -> key()) {
 			case Qt::Key_Left:
-				foreach (Element *item, selectedContent().elements) {
+				foreach (Element *item, selectedContent().m_elements) {
 					left_position = item->mapRectFromScene(item->boundingRect()).x();
 					if (left_position >= this->sceneRect().left() - item->boundingRect().width())
 					return;
@@ -314,7 +314,7 @@
 				break;
 			case Qt::Key_Right: movement = QPointF(+xGrid, 0.0); break;
 			case Qt::Key_Up:
-				foreach (Element *item, selectedContent().elements) {
+				foreach (Element *item, selectedContent().m_elements) {
 					top_position = item->mapRectFromScene(item->boundingRect()).y();
 					if (top_position >= this->sceneRect().top() - item->boundingRect().height())
 						return;
@@ -378,8 +378,6 @@
  * Diagram become the ownership of event_interface
  * If there is a previous interface, they will be delete before
  * and call init() to the new interface.
- * The derivated class of DiagramEventInterface need to emit the signal "finish" when the job is done,
- * diagram use this signal to delete the interface. If the signal isn't send, the interface will never be deleted.
  * @param event_interface
  */
 void Diagram::setEventInterface(DiagramEventInterface *event_interface)
@@ -968,20 +966,14 @@
 			qgi -> setPos( qgi -> pos() += pos_);
 	}
 	
-        //Filling of optional lists
+	// remplissage des listes facultatives
 	if (content_ptr) {
-		content_ptr -> elements         = added_elements.toSet();
-		content_ptr -> conductorsToMove = added_conductors.toSet();
-		content_ptr -> textFields       = added_texts.toSet();
-		content_ptr -> images			= added_images.toSet();
-		content_ptr -> shapes			= added_shapes.toSet();
+		content_ptr -> m_elements         = added_elements.toSet();
+		content_ptr -> m_conductors_to_move = added_conductors.toSet();
+		content_ptr -> m_text_fields       = added_texts.toSet();
+		content_ptr -> m_images			= added_images.toSet();
+		content_ptr -> m_shapes			= added_shapes.toSet();
 	}
-    
-        //Ensure the texts of conductor are inside the border of the folio
-        //and so don't cause the annoying margin on the left border of the folio.
-    for(Conductor *cond : added_conductors)
-        cond->textItem()->setPos(cond->textItem()->pos());
-    
 	adjustSceneRect();
 	return(true);
 }
@@ -1438,7 +1430,7 @@
 	@see ElementTextsMover
 */
 int Diagram::beginMoveElementTexts(QGraphicsItem *driver_item) {
-	return(element_texts_mover_ -> beginMovement(this, driver_item));
+	return(m_element_texts_mover -> beginMovement(this, driver_item));
 }
 
 /**
@@ -1447,7 +1439,7 @@
 	@see ElementTextsMover
 */
 void Diagram::continueMoveElementTexts(const QPointF &movement) {
-	element_texts_mover_ -> continueMovement(movement);
+	m_element_texts_mover -> continueMovement(movement);
 }
 
 /**
@@ -1455,7 +1447,7 @@
 	@see ElementTextsMover
 */
 void Diagram::endMoveElementTexts() {
-	element_texts_mover_ -> endMovement();
+	m_element_texts_mover -> endMovement();
 }
 
 /**
@@ -1656,53 +1648,24 @@
 }
 
 /**
-	@return la liste de tous les textes selectionnes : les textes independants,
-	mais aussi ceux rattaches a des conducteurs ou des elements
-*/
-QSet<DiagramTextItem *> Diagram::selectedTexts() const {
+ * @brief Diagram::selectedTexts
+ * @return A list of every selected texts (every kind of texts)
+ */
+QSet<DiagramTextItem *> Diagram::selectedTexts() const
+{
 	QSet<DiagramTextItem *> selected_texts;
-	foreach(QGraphicsItem *item, selectedItems()) {
-		if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item)) {
-			selected_texts << cti;
-		} else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item)) {
-			selected_texts << eti;
-		} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item)) {
-			selected_texts << iti;
-		}
+	for(QGraphicsItem *qgi : selectedItems())
+	{
+		if (qgi->type() == ConductorTextItem::Type ||
+			qgi->type() == ElementTextItem::Type ||
+			qgi->type() == IndependentTextItem::Type ||
+			qgi->type() == DynamicElementTextItem::Type)
+				selected_texts << static_cast<DiagramTextItem *>(qgi);
 	}
+	
 	return(selected_texts);
 }
 
-/**
- * @brief Diagram::selectedConductorTexts
- * @return the list of conductor texts selected
- */
-QSet<ConductorTextItem *> Diagram::selectedConductorTexts() const {
-	QSet<ConductorTextItem *> selected_texts;
-	foreach(QGraphicsItem *item, selectedItems()) {
-		if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item)) {
-			selected_texts << cti;
-		}
-	}
-	return(selected_texts);
-}
-
-/**
- * @brief Diagram::selectedElementTexts
- * @return the list of element texts selected
- */
-QSet<ElementTextItem*> Diagram::selectedElementTexts() const {
-	QSet<ElementTextItem *> selected_texts;
-	foreach(QGraphicsItem *item, selectedItems()) {
-		if (ElementTextItem *cti = qgraphicsitem_cast< ElementTextItem*>(item)) {
-			selected_texts << cti;
-		}
-	}
-	return(selected_texts);
-}
-
-
-
 /// @return true si le presse-papier semble contenir un schema
 bool Diagram::clipboardMayContainDiagram() {
 	QString clipboard_text = QApplication::clipboard() -> text().trimmed();
@@ -1775,11 +1738,11 @@
 	DiagramContent dc;
 	foreach(QGraphicsItem *qgi, items()) {
 		if (Element *e = qgraphicsitem_cast<Element *>(qgi)) {
-			dc.elements << e;
+			dc.m_elements << e;
 		} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(qgi)) {
-			dc.textFields << iti;
+			dc.m_text_fields << iti;
 		} else if (Conductor *c = qgraphicsitem_cast<Conductor *>(qgi)) {
-			dc.conductorsToMove << c;
+			dc.m_conductors_to_move << c;
 		}
 	}
 	return(dc);
@@ -1786,36 +1749,42 @@
 }
 
 /**
-	@return le contenu selectionne du schema.
-*/
-DiagramContent Diagram::selectedContent() {
+ * @brief Diagram::selectedContent
+ * @return the selected items, stored in a DiagramContent
+ */
+DiagramContent Diagram::selectedContent()
+{
 	DiagramContent dc;
-	
-	// recupere les elements deplaces
-	foreach (QGraphicsItem *item, selectedItems()) {
-		if (Element *elmt = qgraphicsitem_cast<Element *>(item)) {
-			dc.elements << elmt;
-		} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item)) {
-			dc.textFields << iti;
-		} else if (Conductor *c = qgraphicsitem_cast<Conductor *>(item)) {
+
+		//Get the selected items
+	for (QGraphicsItem *item : selectedItems())
+	{
+		if (Element *elmt = qgraphicsitem_cast<Element *>(item))
+			dc.m_elements << elmt;
+		else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item))
+			dc.m_text_fields << iti;
+		else if (Conductor *c = qgraphicsitem_cast<Conductor *>(item))
+		{
 			// recupere les conducteurs selectionnes isoles (= non deplacables mais supprimables)
 			if (
 				!c -> terminal1 -> parentItem() -> isSelected() &&\
 				!c -> terminal2 -> parentItem() -> isSelected()
 			) {
-				dc.otherConductors << c;
+				dc.m_other_conductors << c;
 			}
-		} else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(item)) {
-			dc.images << dii;
-		} else if (QetShapeItem *dsi = qgraphicsitem_cast<QetShapeItem *>(item)) {
-			dc.shapes << dsi;
 		}
+		else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(item))
+			dc.m_images << dii;
+		else if (QetShapeItem *dsi = qgraphicsitem_cast<QetShapeItem *>(item))
+			dc.m_shapes << dsi;
+		else if (DynamicElementTextItem *deti = qgraphicsitem_cast<DynamicElementTextItem *>(item))
+			dc.m_element_texts << deti;
 	}
 	
-	// pour chaque element deplace, determine les conducteurs qui seront modifies
-	foreach(Element *elmt, dc.elements) {
-		foreach(Terminal *terminal, elmt -> terminals()) {
-			foreach(Conductor *conductor, terminal -> conductors()) {
+		//For each selected element, we determine if conductors must be moved or updated.
+	for(Element *elmt : dc.m_elements) {
+		for(Terminal *terminal : elmt -> terminals()) {
+			for(Conductor *conductor : terminal -> conductors()) {
 				Terminal *other_terminal;
 				if (conductor -> terminal1 == terminal) {
 					other_terminal = conductor -> terminal2;
@@ -1823,10 +1792,10 @@
 					other_terminal = conductor -> terminal1;
 				}
 				// si les deux elements du conducteur sont deplaces
-				if (dc.elements.contains(other_terminal -> parentElement())) {
-					dc.conductorsToMove << conductor;
+				if (dc.m_elements.contains(other_terminal -> parentElement())) {
+					dc.m_conductors_to_move << conductor;
 				} else {
-					dc.conductorsToUpdate << conductor;
+					dc.m_conductors_to_update << conductor;
 				}
 			}
 		}
@@ -1836,17 +1805,20 @@
 }
 
 /**
-	@return true s'il est possible de tourner les elements selectionnes.
-	Concretement, cette methode retourne true s'il y a des elements selectionnes
-	et qu'au moins l'un d'entre eux peut etre pivote.
-*/
-bool Diagram::canRotateSelection() const {
-	foreach(QGraphicsItem * qgi, selectedItems()) {
-		if (qgraphicsitem_cast<IndependentTextItem *>(qgi) ||
-		qgraphicsitem_cast<ConductorTextItem *>(qgi) ||
-		qgraphicsitem_cast<DiagramImageItem *>(qgi) ||
-		qgraphicsitem_cast<ElementTextItem *>(qgi) ||
-		qgraphicsitem_cast<Element *>(qgi)) return (true);
+ * @brief Diagram::canRotateSelection
+ * @return True if a least one of selected items can be rotated
+ */
+bool Diagram::canRotateSelection() const
+{
+	for (QGraphicsItem *qgi : selectedItems())
+	{
+		if (qgi->type() == IndependentTextItem::Type ||
+			qgi->type() == ConductorTextItem::Type ||
+			qgi->type() == DiagramImageItem::Type ||
+			qgi->type() == ElementTextItem::Type ||
+			qgi->type() == Element::Type ||
+			qgi->type() == DynamicElementTextItem::Type) return true;
 	}
-	return(false);
+	
+	return false;
 }

Modified: trunk/sources/diagram.h
===================================================================
--- trunk/sources/diagram.h	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/diagram.h	2017-08-03 17:36:08 UTC (rev 5005)
@@ -36,11 +36,8 @@
 class Element;
 class ElementsLocation;
 class ElementsMover;
-class ElementTextItem;
-class IndependentTextItem;
 class QETProject;
 class Terminal;
-class ConductorTextItem;
 class DiagramImageItem;
 class ElementTextsMover;
 class DiagramEventInterface;
@@ -96,7 +93,7 @@
 	private:
 		QGraphicsLineItem *conductor_setter_;
 		ElementsMover     *elements_mover_;
-		ElementTextsMover *element_texts_mover_;
+		ElementTextsMover *m_element_texts_mover;
 		QGIManager        *qgi_manager_;
 		QETProject        *m_project;
 
@@ -191,8 +188,6 @@
 		QList<Element *> elements() const;
 		QList<Conductor *> conductors() const;
 		QSet<DiagramTextItem *> selectedTexts() const;
-		QSet<ConductorTextItem *> selectedConductorTexts() const;
-		QSet<ElementTextItem*> selectedElementTexts() const;
 		QSet<Conductor *> selectedConductors() const;
 		DiagramContent content() const;
 		DiagramContent selectedContent();

Modified: trunk/sources/diagramcommands.cpp
===================================================================
--- trunk/sources/diagramcommands.cpp	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/diagramcommands.cpp	2017-08-03 17:36:08 UTC (rev 5005)
@@ -43,88 +43,6 @@
 }
 
 /**
-	Constructeur
-	@param dia Schema dont on supprime des elements et conducteurs
-	@param content Contenu supprime
-	@param parent QUndoCommand parent
-*/
-DeleteElementsCommand::DeleteElementsCommand(
-	Diagram *dia,
-	const DiagramContent &content,
-	QUndoCommand *parent
-) :
-	QUndoCommand(parent),
-	removed_content(content),
-	diagram(dia)
-{
-	setText(
-		QString(
-			QObject::tr(
-				"supprimer %1",
-				"undo caption - %1 is a sentence listing the removed content"
-			)
-		).arg(removed_content.sentence(DiagramContent::All))
-	);
-	diagram -> qgiManager().manage(removed_content.items(DiagramContent::All));
-}
-
-/// Destructeur
-DeleteElementsCommand::~DeleteElementsCommand() {
-	diagram -> qgiManager().release(removed_content.items(DiagramContent::All));
-}
-
-/**
- * @brief DeleteElementsCommand::undo
- * Undo this command
- */
-void DeleteElementsCommand::undo()
-{
-	diagram -> showMe();
-
-	foreach(QGraphicsItem *item, removed_content.items())
-		diagram->addItem(item);
-
-		//We relink element after every element was added to diagram
-	foreach(Element *e, removed_content.elements)
-		foreach (Element *elmt, m_link_hash[e])
-				e -> linkToElement(elmt);
-}
-
-/**
- * @brief DeleteElementsCommand::redo
- * Redo the delete command
- */
-void DeleteElementsCommand::redo()
-{
-	diagram -> showMe();
-
-	foreach(Conductor *c, removed_content.conductors(DiagramContent::AnyConductor))
-	{
-			//If option one text per folio is enable, and the text item of
-			//current conductor is visible (that mean the conductor have the single displayed text)
-			//We call adjustTextItemPosition to other conductor at the same potential to keep
-			//a visible text on this potential.
-		if (diagram -> defaultConductorProperties.m_one_text_per_folio && c -> textItem() -> isVisible())
-		{
-			QList <Conductor *> conductor_list;
-			conductor_list << c -> relatedPotentialConductors(false).toList();
-			if (conductor_list.count())
-				conductor_list.first() -> calculateTextItemPosition();
-		}
-	}
-	
-	foreach(Element *e, removed_content.elements)
-	{
-			//Get linked element, for relink it at undo
-		if (!e->linkedElements().isEmpty())
-			m_link_hash.insert(e, e->linkedElements());
-	}
-
-	foreach(QGraphicsItem *item, removed_content.items())
-		diagram->removeItem(item);
-}
-
-/**
  * @brief PasteDiagramCommand::PasteDiagramCommand
  * Constructor
  * @param dia : diagram where we must to paste
@@ -176,7 +94,7 @@
 		first_redo = false;
 
 			//this is the first paste, we do some actions for the new element
-		const QList <Element *> elmts_list = content.elements.toList();
+		const QList <Element *> elmts_list = content.m_elements.toList();
 		for (Element *e : elmts_list)
 		{
 				//make new uuid, because old uuid are the uuid of the copied element
@@ -211,7 +129,7 @@
 					eti -> setPlainText("_");
 				
 					//Reset the text of conductors
-				const QList <Conductor *> conductors_list = content.conductorsToMove.toList();
+				const QList <Conductor *> conductors_list = content.m_conductors_to_move.toList();
 				for (Conductor *c : conductors_list)
 				{
 					ConductorProperties cp = c -> properties();
@@ -253,7 +171,7 @@
 	const DiagramContent &content,
 	QUndoCommand *parent
 ) : 
-	DeleteElementsCommand(dia, content, parent)
+	DeleteQGraphicsItemCommand(dia, content, parent)
 {
 	setText(
 		QString(
@@ -366,12 +284,12 @@
 	}
 	
 	// Move some conductors
-	foreach(Conductor *conductor, content_to_move.conductorsToMove) {
+	foreach(Conductor *conductor, content_to_move.m_conductors_to_move) {
 		setupAnimation(conductor, "pos", conductor->pos(), conductor->pos() + actual_movement);
 	}
 	
 	// Recalcul the path of other conductor
-	foreach(Conductor *conductor, content_to_move.conductorsToUpdate) {
+	foreach(Conductor *conductor, content_to_move.m_conductors_to_update) {
 		setupAnimation(conductor, "animPath", 1, 1);
 	}
 }
@@ -590,21 +508,6 @@
 
 /**
 	Constructeur
-	@param previous_state Hash associant les textes impactes par l'action et leur angle de rotation avant l'action
-	@param applied_rotation Nouvel angle de rotation, a appliquer au textes concernes
-	@param parent QUndoCommand parent
-*/
-RotateTextsCommand::RotateTextsCommand(const QHash<DiagramTextItem *, double> &previous_state, double applied_rotation, QUndoCommand *parent) :
-	QUndoCommand(parent),
-	texts_to_rotate(previous_state),
-	applied_rotation_angle_(applied_rotation),
-	diagram(previous_state.key(0)->diagram())
-{
-	defineCommandName();
-}
-
-/**
-	Constructeur
 	@param texts Liste des textes impactes par l'action. L'objet retiendra leur angle de rotation au moment de sa construction.
 	@param applied_rotation Nouvel angle de rotation, a appliquer au textes concernes
 	@param parent QUndoCommand parent
@@ -611,11 +514,11 @@
 */
 RotateTextsCommand::RotateTextsCommand(const QList<DiagramTextItem *> &texts, double applied_rotation, QUndoCommand *parent) :
 	QUndoCommand(parent),
-	applied_rotation_angle_(applied_rotation),
-	diagram(texts.first()->diagram())
+	m_applied_rotation_angle(applied_rotation),
+	m_diagram(texts.first()->diagram())
 {
 	foreach(DiagramTextItem *text, texts) {
-		texts_to_rotate.insert(text, text -> rotationAngle());
+		m_texts_to_rotate.insert(text, text -> rotationAngle());
 	}
 	defineCommandName();
 }
@@ -630,11 +533,11 @@
 	Annule la rotation des textes
 */
 void RotateTextsCommand::undo() {
-	diagram -> showMe();
-	foreach(DiagramTextItem *text, texts_to_rotate.keys()) {
+	m_diagram -> showMe();
+	foreach(DiagramTextItem *text, m_texts_to_rotate.keys()) {
 		if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(text))
-			cti -> forceRotateByUser(previous_rotate_by_user_[cti]);
-		text -> setRotationAngle(texts_to_rotate[text]);
+			cti -> forceRotateByUser(m_previous_rotate_by_user[cti]);
+		text -> setRotationAngle(m_texts_to_rotate[text]);
 	}
 }
 
@@ -642,14 +545,14 @@
 	Applique l'angle de rotation aux textes
 */
 void RotateTextsCommand::redo() {
-	diagram -> showMe();
-	foreach(DiagramTextItem *text, texts_to_rotate.keys()) {
+	m_diagram -> showMe();
+	foreach(DiagramTextItem *text, m_texts_to_rotate.keys()) {
 		if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(text)) {
 			//we grab the previous rotation by user of each ConductorTextItem
-			previous_rotate_by_user_.insert(cti, cti -> wasRotateByUser());
+			m_previous_rotate_by_user.insert(cti, cti -> wasRotateByUser());
 			cti -> forceRotateByUser(true);
 		}
-		text -> setRotationAngle(applied_rotation_angle_);
+		text -> setRotationAngle(m_applied_rotation_angle);
 	}
 }
 
@@ -663,8 +566,8 @@
 				"orienter %1 à %2°",
 				"undo caption - %1 looks like '42 texts', %2 is a rotation angle"
 			)
-		).arg(QET::ElementsAndConductorsSentence(0, 0, texts_to_rotate.count()))
-		.arg(applied_rotation_angle_)
+		).arg(QET::ElementsAndConductorsSentence(0, 0, m_texts_to_rotate.count()))
+		.arg(m_applied_rotation_angle)
 	);
 }
 

Modified: trunk/sources/diagramcommands.h
===================================================================
--- trunk/sources/diagramcommands.h	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/diagramcommands.h	2017-08-03 17:36:08 UTC (rev 5005)
@@ -26,6 +26,7 @@
 #include "qetgraphicsitem/qetshapeitem.h"
 #include "conductorprofile.h"
 #include "diagram.h"
+#include "undocommand/deleteqgraphicsitemcommand.h"
 
 class DiagramTextItem;
 class Element;
@@ -81,32 +82,6 @@
 QString itemText(const Conductor           *item);
 
 /**
-	This command removes content from a particular diagram.
-*/
-class DeleteElementsCommand : public QUndoCommand {
-	// constructors, destructor
-	public:
-	DeleteElementsCommand(Diagram *, const DiagramContent &, QUndoCommand * = 0);
-	virtual ~DeleteElementsCommand();
-	private:
-	DeleteElementsCommand(const DeleteElementsCommand &);
-	
-	// methods
-	public:
-	virtual void undo();
-	virtual void redo();
-	
-	// attributes
-	private:
-	/// removed content
-	DiagramContent removed_content;
-	/// diagram which the content is removed from
-	Diagram *diagram;
-	/// keep linked element for each removed element linked to other element.
-	QHash <Element *, QList<Element *> > m_link_hash;
-};
-
-/**
 	This command pastes some content onto a particular diagram.
 */
 class PasteDiagramCommand : public QUndoCommand {
@@ -137,7 +112,7 @@
 /**
 	This command cuts content from a particular diagram.
 */
-class CutDiagramCommand : public DeleteElementsCommand {
+class CutDiagramCommand : public DeleteQGraphicsItemCommand {
 	// constructors, destructor
 	public:
 	CutDiagramCommand(Diagram *, const DiagramContent &, QUndoCommand * = 0);
@@ -275,32 +250,32 @@
 	This command directs several text items to a same particular angle of
 	rotation.
 */
-class RotateTextsCommand : public QUndoCommand {
+class RotateTextsCommand : public QUndoCommand
+{
 	// constructors, destructor
 	public:
-	RotateTextsCommand(const QHash<DiagramTextItem *, double> &, double, QUndoCommand * = 0);
-	RotateTextsCommand(const QList<DiagramTextItem *> &,         double, QUndoCommand * = 0);
-	virtual ~RotateTextsCommand();
+		RotateTextsCommand(const QList<DiagramTextItem *> &, double, QUndoCommand * = nullptr);
+		virtual ~RotateTextsCommand() override;
 	private:
-	RotateTextsCommand(const RotateTextsCommand &);
+		RotateTextsCommand(const RotateTextsCommand &);
 	
 	// methods
 	public:
-	virtual void undo();
-	virtual void redo();
+		virtual void undo() override;
+		virtual void redo() override;
 	
 	private:
-	void defineCommandName();
+		void defineCommandName();
 	
 	// attributes
 	private:
-	/// hold rotated text items along with their former angle of rotation
-	QHash<DiagramTextItem *, double> texts_to_rotate;
-	/// angle of rotation of all text items after the command
-	double applied_rotation_angle_;
-	/// previous state of each conductor text item
-	QHash<ConductorTextItem *, bool> previous_rotate_by_user_;
-	Diagram *diagram;
+		/// hold rotated text items along with their former angle of rotation
+		QHash<DiagramTextItem *, double> m_texts_to_rotate;
+		/// angle of rotation of all text items after the command
+		double m_applied_rotation_angle;
+		/// previous state of each conductor text item
+		QHash<ConductorTextItem *, bool> m_previous_rotate_by_user;
+		Diagram *m_diagram;
 };
 
 /**

Modified: trunk/sources/diagramcontent.cpp
===================================================================
--- trunk/sources/diagramcontent.cpp	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/diagramcontent.cpp	2017-08-03 17:36:08 UTC (rev 5005)
@@ -23,45 +23,48 @@
 #include "diagramimageitem.h"
 #include "elementtextitem.h"
 #include "qetshapeitem.h"
+#include "dynamicelementtextitem.h"
 
 /**
-	Constructeur par defaut. Ne contient rien.
-*/
-DiagramContent::DiagramContent() {
-}
+ * @brief DiagramContent::DiagramContent
+ */
+DiagramContent::DiagramContent() {}
 
 /**
-	Constructeur de copie.
-*/
+ * @brief DiagramContent::DiagramContent
+ * Copy constructor
+ * @param other
+ */
 DiagramContent::DiagramContent(const DiagramContent &other) :
-	elements(other.elements),
-	textFields(other.textFields),
-	images(other.images),
-	shapes(other.shapes),
-	conductorsToUpdate(other.conductorsToUpdate),
-	conductorsToMove(other.conductorsToMove),
-	otherConductors(other.otherConductors)
-{
-}
+	m_elements(other.m_elements),
+	m_text_fields(other.m_text_fields),
+	m_images(other.m_images),
+	m_shapes(other.m_shapes),
+	m_conductors_to_update(other.m_conductors_to_update),
+	m_conductors_to_move(other.m_conductors_to_move),
+	m_other_conductors(other.m_other_conductors),
+	m_element_texts(other.m_element_texts)
+{}
 
 /**
-	Constructeur
-*/
-DiagramContent::~DiagramContent() {
-}
+ * @brief DiagramContent::~DiagramContent
+ */
+DiagramContent::~DiagramContent() {}
 
 /**
-	@param filter Types de conducteurs desires
-	@return tous les conducteurs
-*/
-QList<Conductor *> DiagramContent::conductors(int filter) const {
+ * @brief DiagramContent::conductors
+ * @param filter
+ * @return Every conductors according to the filter
+ */
+QList<Conductor *> DiagramContent::conductors(int filter) const
+{
 	QSet<Conductor *> result;
-	if (filter & ConductorsToMove)   result += conductorsToMove;
-	if (filter & ConductorsToUpdate) result += conductorsToUpdate;
-	if (filter & OtherConductors)    result += otherConductors;
+	if (filter & ConductorsToMove)   result += m_conductors_to_move;
+	if (filter & ConductorsToUpdate) result += m_conductors_to_update;
+	if (filter & OtherConductors)    result += m_other_conductors;
 	if (filter & SelectedOnly) {
-		foreach(Conductor *conductor, result) {
-			if (!conductor -> isSelected()) result.remove(conductor);
+		for(Conductor *conductor : result) {
+			if (!conductor->isSelected()) result.remove(conductor);
 		}
 	}
 	return(result.toList());
@@ -68,16 +71,19 @@
 }
 
 /**
-	Vide le conteneur
-*/
-void DiagramContent::clear() {
-	elements.clear();
-	textFields.clear();
-	images.clear();
-	shapes.clear();
-	conductorsToUpdate.clear();
-	conductorsToMove.clear();
-	otherConductors.clear();
+ * @brief DiagramContent::clear
+ * Remove all items from the diagram content
+ */
+void DiagramContent::clear()
+{
+	m_elements.clear();
+	m_text_fields.clear();
+	m_images.clear();
+	m_shapes.clear();
+	m_conductors_to_update.clear();
+	m_conductors_to_move.clear();
+	m_other_conductors.clear();
+	m_element_texts.clear();
 }
 
 /**
@@ -89,21 +95,21 @@
 {
 	int count_ = 0;
 
-	foreach(Element *elmt, elements) {
+	for(Element *elmt : m_elements) {
 		if (!elmt->isMovable()) {
-			elements.remove(elmt);
+			m_elements.remove(elmt);
 			++count_;
 		}
 	}
-	foreach(DiagramImageItem *img, images) {
+	for(DiagramImageItem *img : m_images) {
 		if (!img->isMovable()) {
-			images.remove(img);
+			m_images.remove(img);
 			++count_;
 		}
 	}
-	foreach (QetShapeItem *shape, shapes) {
+	for(QetShapeItem *shape : m_shapes) {
 		if (!shape->isMovable()) {
-			shapes.remove(shape);
+			m_shapes.remove(shape);
 			++count_;
 		}
 	}
@@ -110,21 +116,26 @@
 
 	return count_;
 }
+
 /**
-	@param filter Types desires
-	@return la liste des items formant le contenu du schema
-*/
-QList<QGraphicsItem *> DiagramContent::items(int filter) const {
+ * @brief DiagramContent::items
+ * @param filter
+ * @return The items of this diagram content according to @filter
+ */
+QList<QGraphicsItem *> DiagramContent::items(int filter) const
+{
 	QList<QGraphicsItem *> items_list;
-	foreach(QGraphicsItem *qgi, conductors(filter)) items_list << qgi;
+	
+	for(QGraphicsItem *qgi : conductors(filter)) items_list << qgi;
 
-	if (filter & Elements)          foreach(QGraphicsItem *qgi, elements)           items_list << qgi;
-	if (filter & TextFields)        foreach(QGraphicsItem *qgi, textFields)         items_list << qgi;
-	if (filter & Images)            foreach(QGraphicsItem *qgi, images)             items_list << qgi;
-	if (filter & Shapes)            foreach(QGraphicsItem *qgi, shapes)             items_list << qgi;
+	if (filter & Elements)          for(QGraphicsItem *qgi : m_elements)      items_list << qgi;
+	if (filter & TextFields)        for(QGraphicsItem *qgi : m_text_fields)   items_list << qgi;
+	if (filter & Images)            for(QGraphicsItem *qgi : m_images)        items_list << qgi;
+	if (filter & Shapes)            for(QGraphicsItem *qgi : m_shapes)        items_list << qgi;
+	if (filter & ElementTextFields) for(QGraphicsItem *qgi : m_element_texts) items_list << qgi;
 
 	if (filter & SelectedOnly) {
-		foreach(QGraphicsItem *qgi, items_list) {
+		for(QGraphicsItem *qgi : items_list) {
 			if (!qgi -> isSelected()) items_list.removeOne(qgi);
 		}
 	}
@@ -132,44 +143,50 @@
 }
 
 /**
-	@param filter Types desires
-	@return le nombre d'items formant le contenu du schema
-*/
-int DiagramContent::count(int filter) const {
+ * @brief DiagramContent::count
+ * @param filter
+ * @return The number of items, according to @filter
+ */
+int DiagramContent::count(int filter) const
+{
 	int count = 0;
 	if (filter & SelectedOnly) {
-		if (filter & Elements)           foreach(Element *element,     elements)                  { if (element   -> isSelected()) ++ count; }
-		if (filter & TextFields)         foreach(DiagramTextItem *dti, textFields)                { if (dti       -> isSelected()) ++ count; }
-		if (filter & Images)             foreach(DiagramImageItem *dii, images)                   { if (dii       -> isSelected()) ++ count; }
-		if (filter & Shapes)             foreach(QetShapeItem *dsi, shapes)                       { if (dsi       -> isSelected()) ++ count; }
-		if (filter & ConductorsToMove)   foreach(Conductor *conductor, conductorsToMove)          { if (conductor -> isSelected()) ++ count; }
-		if (filter & ConductorsToUpdate) foreach(Conductor *conductor, conductorsToUpdate)        { if (conductor -> isSelected()) ++ count; }
-		if (filter & OtherConductors)    foreach(Conductor *conductor, otherConductors)           { if (conductor -> isSelected()) ++ count; }
+		if (filter & Elements)           for(Element *element :     m_elements)               { if (element   -> isSelected()) ++ count; }
+		if (filter & TextFields)         for(DiagramTextItem *dti : m_text_fields)            { if (dti       -> isSelected()) ++ count; }
+		if (filter & Images)             for(DiagramImageItem *dii : m_images)                { if (dii       -> isSelected()) ++ count; }
+		if (filter & Shapes)             for(QetShapeItem *dsi : m_shapes)                    { if (dsi       -> isSelected()) ++ count; }
+		if (filter & ConductorsToMove)   for(Conductor *conductor : m_conductors_to_move)     { if (conductor -> isSelected()) ++ count; }
+		if (filter & ConductorsToUpdate) for(Conductor *conductor : m_conductors_to_update)   { if (conductor -> isSelected()) ++ count; }
+		if (filter & OtherConductors)    for(Conductor *conductor : m_other_conductors)       { if (conductor -> isSelected()) ++ count; }
+		if (filter & ElementTextFields)   for(DynamicElementTextItem *deti : m_element_texts) { if (deti      -> isSelected()) ++ count; }
 	}
 	else {
-		if (filter & Elements)           count += elements.count();
-		if (filter & TextFields)         count += textFields.count();
-		if (filter & Images)             count += images.count();
-		if (filter & Shapes)             count += shapes.count();
-		if (filter & ConductorsToMove)   count += conductorsToMove.count();
-		if (filter & ConductorsToUpdate) count += conductorsToUpdate.count();
-		if (filter & OtherConductors)    count += otherConductors.count();
+		if (filter & Elements)           count += m_elements.count();
+		if (filter & TextFields)         count += m_text_fields.count();
+		if (filter & Images)             count += m_images.count();
+		if (filter & Shapes)             count += m_shapes.count();
+		if (filter & ConductorsToMove)   count += m_conductors_to_move.count();
+		if (filter & ConductorsToUpdate) count += m_conductors_to_update.count();
+		if (filter & OtherConductors)    count += m_other_conductors.count();
+		if (filter & ElementTextFields)  count += m_element_texts.count();
 	}
 	return(count);
 }
 
 /**
-	Permet de composer rapidement la proposition "x elements, y conducteurs et
-	z champs de texte".
-	@param filter Types desires
-	@return la proposition decrivant le contenu.
-*/
-QString DiagramContent::sentence(int filter) const {
-	int elements_count   = (filter & Elements) ? elements.count() : 0;
+ * @brief DiagramContent::sentence
+ * @param filter
+ * @return A string that describe the items of the diagram content according to @filter.
+ * Exemple : X elements, Y conductors etc....
+ */
+QString DiagramContent::sentence(int filter) const
+{
+	int elements_count   = (filter & Elements) ? m_elements.count() : 0;
 	int conductors_count = conductors(filter).count();
-	int textfields_count = (filter & TextFields) ? (textFields.count()) : 0;
-	int images_count	 = (filter & Images) ? images.count() : 0;
-	int shapes_count	 = (filter & Shapes) ? shapes.count() : 0;
+	int textfields_count = (filter & TextFields) ? (m_text_fields.count()) : 0;
+	int images_count	 = (filter & Images) ? m_images.count() : 0;
+	int shapes_count	 = (filter & Shapes) ? m_shapes.count() : 0;
+	int elmt_text_count  = (filter & ElementTextFields) ? m_element_texts.count() : 0;
 	
 	return(
 		QET::ElementsAndConductorsSentence(
@@ -177,16 +194,18 @@
 			conductors_count,
 			textfields_count,
 			images_count,
-			shapes_count
+			shapes_count,
+			elmt_text_count		
 		)
 	);
 }
 
 /**
-	Permet de debugger un contenu de schema
-	@param d Object QDebug a utiliser pour l'affichage des informations de debug
-	@param content Contenu de schema a debugger
-*/
+ * @brief operator << Use to debug a diagram content
+ * @param d : QDebug to use for display the debug info
+ * @param content : content to debug
+ * @return 
+ */
 QDebug &operator<<(QDebug d, DiagramContent &content) {
 	Q_UNUSED(content);
 	d << "DiagramContent {" << "\n";

Modified: trunk/sources/diagramcontent.h
===================================================================
--- trunk/sources/diagramcontent.h	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/diagramcontent.h	2017-08-03 17:36:08 UTC (rev 5005)
@@ -27,6 +27,7 @@
 class DiagramImageItem;
 class ElementTextItem;
 class QetShapeItem;
+class DynamicElementTextItem;
 
 /**
 	This class provides a container that makes the transmission of diagram content
@@ -37,48 +38,43 @@
 	Please note this container does not systematically contains a whole
 	diagram: it may describe only a part of it, e.g. selected items.
 */
-class DiagramContent {
+class DiagramContent
+{
 	public:
-	DiagramContent();
-	DiagramContent(const DiagramContent &);
-	~DiagramContent();
-	
-	/// Used to filter the different items carried by this container.
-	enum Filter {
-		Elements = 1,
-		TextFields = 2,
-		ElementTextFields = 4,
-		Images = 8,
-		ConductorsToMove = 16,
-		ConductorsToUpdate = 32,
-		OtherConductors = 64,
-		AnyConductor = 112,
-		Shapes = 128,
-		All = 255,
-		SelectedOnly = 256
-	};
-	
-	/// Hold electrical elements
-	QSet<Element *> elements;
-	/// Hold independent text items
-	QSet<IndependentTextItem *> textFields;
-	/// Hold image
-	QSet<DiagramImageItem *> images;
-	/// Hold shape
-	QSet<QetShapeItem *> shapes;
-	/// Hold conductors that would get updated considering electrical elements are moved
-	QSet<Conductor *> conductorsToUpdate;
-	/// Hold conductors that would be moved as is considering electrical elements are moved
-	QSet<Conductor *> conductorsToMove;
-	/// Hold conductors that would be left untouched considering electrical elements are moved
-	QSet<Conductor *> otherConductors;
-	
-	QList<Conductor *> conductors(int = AnyConductor) const;
-	QList<QGraphicsItem *> items(int = All) const;
-	QString sentence(int = All) const;
-	int count(int = All) const;
-	void clear();
-	int removeNonMovableItems();
+		DiagramContent();
+		DiagramContent(const DiagramContent &);
+		~DiagramContent();
+		
+		/// Used to filter the different items carried by this container.
+		enum Filter {
+			Elements = 1,
+			TextFields = 2,
+			ElementTextFields = 4,
+			Images = 8,
+			ConductorsToMove = 16,
+			ConductorsToUpdate = 32,
+			OtherConductors = 64,
+			AnyConductor = 112,
+			Shapes = 128,
+			All = 255,
+			SelectedOnly = 256
+		};
+		
+		QSet<Element *> m_elements;
+		QSet<IndependentTextItem *> m_text_fields;
+		QSet<DiagramImageItem *> m_images;
+		QSet<QetShapeItem *> m_shapes;
+		QSet<Conductor *> m_conductors_to_update;
+		QSet<Conductor *> m_conductors_to_move;
+		QSet<Conductor *> m_other_conductors;
+		QSet<DynamicElementTextItem *> m_element_texts;
+		
+		QList<Conductor *> conductors(int = AnyConductor) const;
+		QList<QGraphicsItem *> items(int = All) const;
+		QString sentence(int = All) const;
+		int count(int = All) const;
+		void clear();
+		int removeNonMovableItems();
 };
 QDebug &operator<<(QDebug, DiagramContent &);
 #endif

Modified: trunk/sources/diagramview.cpp
===================================================================
--- trunk/sources/diagramview.cpp	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/diagramview.cpp	2017-08-03 17:36:08 UTC (rev 5005)
@@ -45,6 +45,8 @@
 #include "diagrameventaddelement.h"
 #include "QPropertyUndoCommand/qpropertyundocommand.h"
 #include "qetshapeitem.h"
+#include "undocommand/deleteqgraphicsitemcommand.h"
+#include "dynamicelementtextitem.h"
 
 /**
 	Constructeur
@@ -52,10 +54,8 @@
 	@param parent Le QWidget parent de cette vue de schema
 */
 DiagramView::DiagramView(Diagram *diagram, QWidget *parent) :
-	QGraphicsView     (parent),
-	m_scene             (diagram),
-	m_event_interface (nullptr),
-	m_first_activation (true)
+	QGraphicsView (parent),
+	m_diagram (diagram)
 {
 	grabGesture(Qt::PinchGesture);
 	setAttribute(Qt::WA_DeleteOnClose, true);
@@ -74,8 +74,8 @@
 	setRenderHint(QPainter::TextAntialiasing, true);
 	setRenderHint(QPainter::SmoothPixmapTransform, true);
 
-	setScene(m_scene);
-	m_scene -> undoStack().setClean();
+	setScene(m_diagram);
+	m_diagram -> undoStack().setClean();
 	setWindowIcon(QET::Icons::QETLogo);
 	setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
 	setResizeAnchor(QGraphicsView::AnchorUnderMouse);
@@ -83,17 +83,17 @@
 	setSelectionMode();
 	adjustSceneRect();
 	updateWindowTitle();
-	m_scene->loadElmtFolioSeq();
-	m_scene->loadCndFolioSeq();
+	m_diagram->loadElmtFolioSeq();
+	m_diagram->loadCndFolioSeq();
 
-	context_menu = new QMenu(this);
-	paste_here = new QAction(QET::Icons::EditPaste, tr("Coller ici", "context menu action"), this);
-	connect(paste_here, SIGNAL(triggered()), this, SLOT(pasteHere()));
+	m_context_menu = new QMenu(this);
+	m_paste_here = new QAction(QET::Icons::EditPaste, tr("Coller ici", "context menu action"), this);
+	connect(m_paste_here, SIGNAL(triggered()), this, SLOT(pasteHere()));
 
-	connect(m_scene, SIGNAL(showDiagram(Diagram*)), this, SIGNAL(showDiagram(Diagram*)));
-	connect(m_scene, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
-	connect(m_scene, SIGNAL(sceneRectChanged(QRectF)), this, SLOT(adjustSceneRect()));
-	connect(&(m_scene -> border_and_titleblock), SIGNAL(diagramTitleChanged(const QString &)), this, SLOT(updateWindowTitle()));
+	connect(m_diagram, SIGNAL(showDiagram(Diagram*)), this, SIGNAL(showDiagram(Diagram*)));
+	connect(m_diagram, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
+	connect(m_diagram, SIGNAL(sceneRectChanged(QRectF)), this, SLOT(adjustSceneRect()));
+	connect(&(m_diagram -> border_and_titleblock), SIGNAL(diagramTitleChanged(const QString &)), this, SLOT(updateWindowTitle()));
 	connect(diagram, SIGNAL(editElementRequired(ElementsLocation)), this, SIGNAL(editElementRequired(ElementsLocation)));
 	connect(diagram, SIGNAL(findElementRequired(ElementsLocation)), this, SIGNAL(findElementRequired(ElementsLocation)));
 
@@ -111,7 +111,7 @@
 	Selectionne tous les objets du schema
 */
 void DiagramView::selectAll() {
-	m_scene -> selectAll();
+	m_diagram -> selectAll();
 }
 
 /**
@@ -118,7 +118,7 @@
 	Deslectionne tous les objets selectionnes
 */
 void DiagramView::selectNothing() {
-	m_scene -> deselectAll();
+	m_diagram -> deselectAll();
 }
 
 /**
@@ -125,72 +125,93 @@
 	Inverse l'etat de selection de tous les objets du schema
 */
 void DiagramView::selectInvert() {
-	m_scene -> invertSelection();
+	m_diagram -> invertSelection();
 }
 
 /**
-	Supprime les composants selectionnes
-*/
-void DiagramView::deleteSelection() {
-	if (m_scene -> isReadOnly()) return;
-	DiagramContent removed_content = m_scene -> selectedContent();
-	m_scene -> clearSelection();
-	m_scene -> undoStack().push(new DeleteElementsCommand(m_scene, removed_content));
+ * @brief DiagramView::deleteSelection
+ * Delete the selected items
+ */
+void DiagramView::deleteSelection()
+{
+	if (m_diagram -> isReadOnly())
+		return;
+	DiagramContent removed_content = m_diagram->selectedContent();
+	m_diagram->clearSelection();
+	m_diagram->undoStack().push(new DeleteQGraphicsItemCommand(m_diagram, removed_content));
 	adjustSceneRect();
 }
 
 /**
-	Pivote les composants selectionnes
-*/
-void DiagramView::rotateSelection() {
-	if (m_scene -> isReadOnly()) return;
+ * @brief DiagramView::rotateSelection
+ * Rotate the selected items
+ */
+void DiagramView::rotateSelection()
+{
+	if (m_diagram->isReadOnly())
+		return;
 
-	// recupere les elements et les champs de texte a pivoter
 	QList<Element *> elements_to_rotate;
 	QList<DiagramTextItem *> texts_to_rotate;
 	QList<DiagramImageItem *> images_to_rotate;
-	foreach (QGraphicsItem *item, m_scene -> selectedItems()) {
-		if (Element *e = qgraphicsitem_cast<Element *>(item)) {
+	
+	for (QGraphicsItem *item : m_diagram->selectedItems())
+	{
+		if (Element *e = qgraphicsitem_cast<Element *>(item))
 			elements_to_rotate << e;
-		} else if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item)) {
+		else if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item))
 			texts_to_rotate << cti;
-		} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item)) {
+		else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item))
 			texts_to_rotate << iti;
-		} else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item)) {
-			// on ne pivote un texte d'element que si son parent n'est pas selectionne
-			if (eti -> parentItem() && !eti -> parentItem() -> isSelected()) {
+		else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item))
+		{
+				//We rotate element text item only if is parent element is not selected
+			if (eti->parentItem() && !eti->parentItem()->isSelected())
 				texts_to_rotate << eti;
-			}
-		} else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(item)) {
+		}
+		else if (DynamicElementTextItem *deti = qgraphicsitem_cast<DynamicElementTextItem *>(item))
+		{
+				//We rotate dynamic element text item only if is parent element is not selected
+			if (deti->parentItem() && !deti->parentItem()->isSelected())
+				texts_to_rotate << deti;
+		}
+		else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(item))
 			images_to_rotate << dii;
-		}
 	}
 
-	// effectue les rotations s'il y a quelque chose a pivoter
-	if (elements_to_rotate.isEmpty() && texts_to_rotate.isEmpty() && images_to_rotate.isEmpty()) return;
-	m_scene -> undoStack().push(new RotateElementsCommand(elements_to_rotate, texts_to_rotate, images_to_rotate));
+		//Do the rotation
+	if (elements_to_rotate.isEmpty() && texts_to_rotate.isEmpty() && images_to_rotate.isEmpty())
+		return;
+	m_diagram->undoStack().push(new RotateElementsCommand(elements_to_rotate, texts_to_rotate, images_to_rotate));
 }
 
-void DiagramView::rotateTexts() {
-	if (m_scene -> isReadOnly()) return;
+/**
+ * @brief DiagramView::rotateTexts
+ * Open a dialog to set the rotation angle, and apply it to the selected texts.
+ */
+void DiagramView::rotateTexts()
+{
+	if (m_diagram->isReadOnly())
+		return;
 
-	// recupere les champs de texte a orienter
+		//Get the texts fields
 	QList<DiagramTextItem *> texts_to_rotate;
-	foreach (QGraphicsItem *item, m_scene -> selectedItems()) {
-		if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item)) {
+	for (QGraphicsItem *item : m_diagram->selectedItems())
+	{
+		if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item))
 			texts_to_rotate << cti;
-		} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item)) {
+		else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item))
 			texts_to_rotate << iti;
-		} else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item)) {
-			// ici, on pivote un texte d'element meme si son parent est selectionne
+		else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item))
 			texts_to_rotate << eti;
-		}
+		else if (DynamicElementTextItem *deti = qgraphicsitem_cast<DynamicElementTextItem *>(item))
+			texts_to_rotate << deti;
 	}
+	
+	if (texts_to_rotate.isEmpty())
+		return;
 
-	// effectue les rotations s'il y a quelque chose a pivoter
-	if (texts_to_rotate.isEmpty()) return;
-
-	// demande un angle a l'utilisateur
+		//Open the dialog
 	QDialog ori_text_dialog(diagramEditor());
 	ori_text_dialog.setSizeGripEnabled(false);
 #ifdef Q_OS_MAC
@@ -197,7 +218,6 @@
 	ori_text_dialog.setWindowFlags(Qt::Sheet);
 #endif
 	ori_text_dialog.setWindowTitle(tr("Orienter les textes sélectionnés", "window title"));
-// 	ori_text_dialog.setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
 
 
 	QTextOrientationSpinBoxWidget *ori_widget = QETApp::createTextOrientationSpinBoxWidget();
@@ -207,12 +227,10 @@
 	}
 	ori_widget -> spinBox() -> selectAll();
 
-	// boutons
 	QDialogButtonBox buttons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
 	connect(&buttons, SIGNAL(accepted()), &ori_text_dialog, SLOT(accept()));
 	connect(&buttons, SIGNAL(rejected()), &ori_text_dialog, SLOT(reject()));
-
-	// ajout dans une disposition verticale
+	
 	QVBoxLayout layout_v(&ori_text_dialog);
 	layout_v.setSizeConstraint(QLayout::SetFixedSize);
 	layout_v.addWidget(ori_widget);
@@ -219,10 +237,8 @@
 	layout_v.addStretch();
 	layout_v.addWidget(&buttons);
 
-	// si le dialogue est accepte
-	if (ori_text_dialog.exec() == QDialog::Accepted) {
-		m_scene -> undoStack().push(new RotateTextsCommand(texts_to_rotate, ori_widget -> orientation()));
-	}
+	if (ori_text_dialog.exec() == QDialog::Accepted)
+		m_diagram -> undoStack().push(new RotateTextsCommand(texts_to_rotate, ori_widget -> orientation()));
 }
 
 /**
@@ -307,11 +323,11 @@
 	if (tbt_loc.isValid())
 	{
 			// fetch the current title block properties
-		TitleBlockProperties titleblock_properties_before = m_scene->border_and_titleblock.exportTitleBlock();
+		TitleBlockProperties titleblock_properties_before = m_diagram->border_and_titleblock.exportTitleBlock();
 
 			// check the provided template is not already applied
 		QETProject *tbt_parent_project = tbt_loc.parentProject();
-		if (tbt_parent_project && tbt_parent_project == m_scene -> project())
+		if (tbt_parent_project && tbt_parent_project == m_diagram -> project())
 		{
 				// same parent project and same name = same title block template
 			if (tbt_loc.name() == titleblock_properties_before.template_name)
@@ -324,7 +340,7 @@
 		{
 			IntegrationMoveTitleBlockTemplatesHandler *handler = new IntegrationMoveTitleBlockTemplatesHandler(this);
 			//QString error_message;
-			integrated_template_name = m_scene->project()->integrateTitleBlockTemplate(tbt_loc, handler);
+			integrated_template_name = m_diagram->project()->integrateTitleBlockTemplate(tbt_loc, handler);
 
 			if (integrated_template_name.isEmpty())
 				return;
@@ -336,7 +352,7 @@
 
 		TitleBlockProperties titleblock_properties_after = titleblock_properties_before;
 		titleblock_properties_after.template_name = integrated_template_name;
-		m_scene->undoStack().push(new ChangeTitleBlockCommand(m_scene, titleblock_properties_before, titleblock_properties_after));
+		m_diagram->undoStack().push(new ChangeTitleBlockCommand(m_diagram, titleblock_properties_before, titleblock_properties_after));
 
 		adjustSceneRect();
 	}
@@ -348,7 +364,7 @@
  * @param e the QDropEvent describing the current drag'n drop
  */
 void DiagramView::handleTextDrop(QDropEvent *e) {
-	if (m_scene -> isReadOnly() || (e -> mimeData() -> hasText() == false) ) return;
+	if (m_diagram -> isReadOnly() || (e -> mimeData() -> hasText() == false) ) return;
 
 	IndependentTextItem *iti = new IndependentTextItem (e -> mimeData() -> text());
 
@@ -356,7 +372,7 @@
 		iti -> setHtml (e -> mimeData() -> text());
 	}
 
-	m_scene -> undoStack().push(new AddItemCommand<IndependentTextItem *>(iti, m_scene, mapToScene(e->pos())));
+	m_diagram -> undoStack().push(new AddItemCommand<IndependentTextItem *>(iti, m_diagram, mapToScene(e->pos())));
 }
 
 /**
@@ -398,9 +414,8 @@
 			(horizontalScrollBar()->maximum() || verticalScrollBar()->maximum()) )
 			scale(zoom_factor, zoom_factor);
 	}
-	m_scene->adjustSceneRect();
+	m_diagram->adjustSceneRect();
 	adjustGridToZoom();
-	adjustSceneRect();
 }
 
 /**
@@ -410,7 +425,7 @@
 */
 void DiagramView::zoomFit() {
 	adjustSceneRect();
-	fitInView(m_scene->sceneRect(), Qt::KeepAspectRatio);
+	fitInView(m_diagram->sceneRect(), Qt::KeepAspectRatio);
 	adjustGridToZoom();
 }
 
@@ -418,7 +433,7 @@
 	Adjust zoom to fit all elements in the view, regardless of diagram borders.
 */
 void DiagramView::zoomContent() {
-	fitInView(m_scene -> itemsBoundingRect(), Qt::KeepAspectRatio);
+	fitInView(m_diagram -> itemsBoundingRect(), Qt::KeepAspectRatio);
 	adjustGridToZoom();
 }
 
@@ -435,9 +450,9 @@
 */
 void DiagramView::cut() {
 	copy();
-	DiagramContent cut_content = m_scene -> selectedContent();
-	m_scene -> clearSelection();
-	m_scene -> undoStack().push(new CutDiagramCommand(m_scene, cut_content));
+	DiagramContent cut_content = m_diagram -> selectedContent();
+	m_diagram -> clearSelection();
+	m_diagram -> undoStack().push(new CutDiagramCommand(m_diagram, cut_content));
 }
 
 /**
@@ -445,7 +460,7 @@
 */
 void DiagramView::copy() {
 	QClipboard *presse_papier = QApplication::clipboard();
-	QString contenu_presse_papier = m_scene -> toXml(false).toString(4);
+	QString contenu_presse_papier = m_diagram -> toXml(false).toString(4);
 	if (presse_papier -> supportsSelection()) presse_papier -> setText(contenu_presse_papier, QClipboard::Selection);
 	presse_papier -> setText(contenu_presse_papier);
 }
@@ -457,7 +472,7 @@
 	@param clipboard_mode Type de presse-papier a prendre en compte
 */
 void DiagramView::paste(const QPointF &pos, QClipboard::Mode clipboard_mode) {
-	if (!isInteractive() || m_scene -> isReadOnly()) return;
+	if (!isInteractive() || m_diagram -> isReadOnly()) return;
 
 	QString texte_presse_papier = QApplication::clipboard() -> text(clipboard_mode);
 	if ((texte_presse_papier).isEmpty()) return;
@@ -468,12 +483,12 @@
 	// objet pour recuperer le contenu ajoute au schema par le coller
 	DiagramContent content_pasted;
 	this->diagram()->item_paste = true;
-	m_scene -> fromXml(document_xml, pos, false, &content_pasted);
+	m_diagram -> fromXml(document_xml, pos, false, &content_pasted);
 
 	// si quelque chose a effectivement ete ajoute au schema, on cree un objet d'annulation
 	if (content_pasted.count()) {
-		m_scene -> clearSelection();
-		m_scene -> undoStack().push(new PasteDiagramCommand(m_scene, content_pasted));
+		m_diagram -> clearSelection();
+		m_diagram -> undoStack().push(new PasteDiagramCommand(m_diagram, content_pasted));
 		adjustSceneRect();
 	}
 	this->diagram()->item_paste = false;
@@ -483,7 +498,7 @@
 	Colle le contenu du presse-papier sur le schema a la position de la souris
 */
 void DiagramView::pasteHere() {
-	paste(mapToScene(paste_here_pos));
+	paste(mapToScene(m_paste_here_pos));
 }
 
 /**
@@ -492,10 +507,10 @@
 */
 void DiagramView::mousePressEvent(QMouseEvent *e)
 {
-	if (fresh_focus_in_)
+	if (m_fresh_focus_in)
 	{
 		switchToVisualisationModeIfNeeded(e);
-		fresh_focus_in_ = false;
+		m_fresh_focus_in = false;
 	}
 
 	if (m_event_interface && m_event_interface->mousePressEvent(e)) return;
@@ -503,7 +518,7 @@
 		//Start drag view when hold the middle button
 	if (e->button() == Qt::MidButton)
 	{
-		rubber_band_origin = e->pos();
+		m_rubber_band_origin = e->pos();
 		viewport()->setCursor(Qt::ClosedHandCursor);
 	}
 
@@ -523,11 +538,10 @@
 	{
 		QScrollBar *h = horizontalScrollBar();
 		QScrollBar *v = verticalScrollBar();
-		QPointF pos = rubber_band_origin - e -> pos();
-		rubber_band_origin = e -> pos();
+		QPointF pos = m_rubber_band_origin - e -> pos();
+		m_rubber_band_origin = e -> pos();
 		h -> setValue(h -> value() + pos.x());
 		v -> setValue(v -> value() + pos.y());
-		adjustSceneRect();
 	}
 
 	else QGraphicsView::mouseMoveEvent(e);
@@ -619,7 +633,7 @@
 */
 void DiagramView::focusInEvent(QFocusEvent *e) {
 	if (e -> reason() == Qt::MouseFocusReason) {
-		fresh_focus_in_ = true;
+		m_fresh_focus_in = true;
 	}
 }
 
@@ -641,10 +655,10 @@
 		case Qt::Key_Home:
 			if (!hasTextItems()) {
 				if (
-					qgraphicsitem_cast<IndependentTextItem *>(m_scene->focusItem()) ||
-					qgraphicsitem_cast<ElementTextItem *>(m_scene->focusItem()) ||
-					qgraphicsitem_cast<ConductorTextItem *>(m_scene->focusItem()) ||
-					qgraphicsitem_cast<DiagramTextItem *>(m_scene->focusItem())
+					qgraphicsitem_cast<IndependentTextItem *>(m_diagram->focusItem()) ||
+					qgraphicsitem_cast<ElementTextItem *>(m_diagram->focusItem()) ||
+					qgraphicsitem_cast<ConductorTextItem *>(m_diagram->focusItem()) ||
+					qgraphicsitem_cast<DiagramTextItem *>(m_diagram->focusItem())
 					)
 					break;
 				current_project->changeFirstTab();
@@ -654,10 +668,10 @@
 		case Qt::Key_End:
 			if (!hasTextItems()) {
 				if (
-					qgraphicsitem_cast<IndependentTextItem *>(m_scene->focusItem()) ||
-					qgraphicsitem_cast<ElementTextItem *>(m_scene->focusItem()) ||
-					qgraphicsitem_cast<ConductorTextItem *>(m_scene->focusItem()) ||
-					qgraphicsitem_cast<DiagramTextItem *>(m_scene->focusItem())
+					qgraphicsitem_cast<IndependentTextItem *>(m_diagram->focusItem()) ||
+					qgraphicsitem_cast<ElementTextItem *>(m_diagram->focusItem()) ||
+					qgraphicsitem_cast<ConductorTextItem *>(m_diagram->focusItem()) ||
+					qgraphicsitem_cast<DiagramTextItem *>(m_diagram->focusItem())
 					)
 					break;
 				current_project->changeLastTab();
@@ -677,19 +691,19 @@
 			if (e->modifiers() & Qt::ControlModifier)
 				zoom(1.15);
 		case Qt::Key_Up:
-			if(!(m_scene->selectedContent().items(255).isEmpty())){
+			if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty())){
 				scrollOnMovement(e);
 			}
 		case Qt::Key_Down:
-			if(!(m_scene->selectedContent().items(255).isEmpty())){
+			if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty())){
 				scrollOnMovement(e);
 			}
 		case Qt::Key_Left:
-			if(!(m_scene->selectedContent().items(255).isEmpty())){
+			if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty())){
 				scrollOnMovement(e);
 			}
 		case Qt::Key_Right:
-			if(!(m_scene->selectedContent().items(255).isEmpty())){
+			if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty())){
 				scrollOnMovement(e);
 			}
 	}
@@ -714,7 +728,7 @@
 	or below the editor SceneRect is expanded
 */
 void DiagramView::scrollOnMovement(QKeyEvent *e){
-			QList<QGraphicsItem *> selected_elmts = m_scene->selectedContent().items(255);
+			QList<QGraphicsItem *> selected_elmts = m_diagram->selectedContent().items(DiagramContent::All);
 			QRectF viewed_scene = viewedSceneRect();
 			foreach (QGraphicsItem *qgi, selected_elmts){
 				if (qgraphicsitem_cast<Conductor *>(qgi)) continue;
@@ -755,10 +769,10 @@
 							h_increment = 2*qgi->boundingRect().right();
 							if (h_increment == 0) h_increment = -2*qgi->boundingRect().width();
 						}
-						if (((elmt_right  >= m_scene->sceneRect().right() -  qgi->boundingRect().right())  ||
-							(elmt_bottom >= m_scene->sceneRect().bottom() - qgi->boundingRect().bottom())) &&
+						if (((elmt_right  >= m_diagram->sceneRect().right() -  qgi->boundingRect().right())  ||
+							(elmt_bottom >= m_diagram->sceneRect().bottom() - qgi->boundingRect().bottom())) &&
 							(e->key()==Qt::Key_Right || e->key()==Qt::Key_Down)){
-							m_scene->adjustSceneRect();
+							m_diagram->adjustSceneRect();
 						}
 						h -> setValue(h -> value() + h_increment);
 						v -> setValue(v -> value() + v_increment);
@@ -775,7 +789,7 @@
 */
 QString DiagramView::title() const {
 	QString view_title;
-	QString diagram_title(m_scene -> title());
+	QString diagram_title(m_diagram -> title());
 	if (diagram_title.isEmpty()) {
 		view_title = tr("Sans titre", "what to display for untitled diagrams");
 	} else {
@@ -789,7 +803,7 @@
  * Edit the properties of the viewed digram
  */
 void DiagramView::editDiagramProperties() {
-	DiagramPropertiesDialog::diagramPropertiesDialog(m_scene, diagramEditor());
+	DiagramPropertiesDialog::diagramPropertiesDialog(m_diagram, diagramEditor());
 }
 
 /**
@@ -796,7 +810,7 @@
 	@return true s'il y a des items selectionnes sur le schema, false sinon
 */
 bool DiagramView::hasSelectedItems() {
-	return(m_scene -> selectedItems().size() > 0);
+	return(m_diagram -> selectedItems().size() > 0);
 }
 
 /**
@@ -804,7 +818,7 @@
 	peuvent etre copies dans le presse-papier, false sinon
 */
 bool DiagramView::hasCopiableItems() {
-	foreach(QGraphicsItem *qgi, m_scene -> selectedItems()) {
+	foreach(QGraphicsItem *qgi, m_diagram -> selectedItems()) {
 		if (
 			qgraphicsitem_cast<Element *>(qgi) ||
 			qgraphicsitem_cast<IndependentTextItem *>(qgi) ||
@@ -821,7 +835,7 @@
 	@return true if there is any Text Item selected
 */
 bool DiagramView::hasTextItems() {
-	foreach(QGraphicsItem *qgi, m_scene -> selectedItems()) {
+	foreach(QGraphicsItem *qgi, m_diagram -> selectedItems()) {
 		if (
 			qgraphicsitem_cast<IndependentTextItem *>(qgi) ||
 			qgraphicsitem_cast<ElementTextItem *>(qgi) ||
@@ -835,20 +849,20 @@
 }
 
 /**
-	@return true s'il y a des items selectionnes sur le schema et que ceux-ci
-	peuvent etre supprimes, false sinon
-*/
-bool DiagramView::hasDeletableItems() {
-	foreach(QGraphicsItem *qgi, m_scene -> selectedItems()) {
-		if (
-			qgraphicsitem_cast<Element *>(qgi) ||
-			qgraphicsitem_cast<Conductor *>(qgi) ||
-			qgraphicsitem_cast<IndependentTextItem *>(qgi) ||
-			qgraphicsitem_cast<QetShapeItem *>(qgi) ||
-			qgraphicsitem_cast<DiagramImageItem *>(qgi)
-		) {
-			return(true);
-		}
+ * @brief DiagramView::hasDeletableItems
+ * @return True if a least on of selected item can be deleted
+ */
+bool DiagramView::hasDeletableItems()
+{
+	for(QGraphicsItem *qgi : m_diagram->selectedItems())
+	{
+		if (qgi->type() == Element::Type ||
+			qgi->type() == Conductor::Type ||
+			qgi->type() == IndependentTextItem::Type ||
+			qgi->type() == QetShapeItem::Type ||
+			qgi->type() == DiagramImageItem::Type ||
+			qgi->type() == DynamicElementTextItem::Type)
+			return true;
 	}
 	return(false);
 }
@@ -857,11 +871,11 @@
 	Ajoute une colonne au schema.
 */
 void DiagramView::addColumn() {
-	if (m_scene -> isReadOnly()) return;
-	BorderProperties old_bp = m_scene -> border_and_titleblock.exportBorder();
-	BorderProperties new_bp = m_scene -> border_and_titleblock.exportBorder();
+	if (m_diagram -> isReadOnly()) return;
+	BorderProperties old_bp = m_diagram -> border_and_titleblock.exportBorder();
+	BorderProperties new_bp = m_diagram -> border_and_titleblock.exportBorder();
 	new_bp.columns_count += 1;
-	m_scene -> undoStack().push(new ChangeBorderCommand(m_scene, old_bp, new_bp));
+	m_diagram -> undoStack().push(new ChangeBorderCommand(m_diagram, old_bp, new_bp));
 }
 
 /**
@@ -868,11 +882,11 @@
 	Enleve une colonne au schema.
 */
 void DiagramView::removeColumn() {
-	if (m_scene -> isReadOnly()) return;
-	BorderProperties old_bp = m_scene -> border_and_titleblock.exportBorder();
-	BorderProperties new_bp = m_scene -> border_and_titleblock.exportBorder();
+	if (m_diagram -> isReadOnly()) return;
+	BorderProperties old_bp = m_diagram -> border_and_titleblock.exportBorder();
+	BorderProperties new_bp = m_diagram -> border_and_titleblock.exportBorder();
 	new_bp.columns_count -= 1;
-	m_scene -> undoStack().push(new ChangeBorderCommand(m_scene, old_bp, new_bp));
+	m_diagram -> undoStack().push(new ChangeBorderCommand(m_diagram, old_bp, new_bp));
 }
 
 /**
@@ -879,11 +893,11 @@
 	Agrandit le schema en hauteur
 */
 void DiagramView::addRow() {
-	if (m_scene -> isReadOnly()) return;
-	BorderProperties old_bp = m_scene -> border_and_titleblock.exportBorder();
-	BorderProperties new_bp = m_scene -> border_and_titleblock.exportBorder();
+	if (m_diagram -> isReadOnly()) return;
+	BorderProperties old_bp = m_diagram -> border_and_titleblock.exportBorder();
+	BorderProperties new_bp = m_diagram -> border_and_titleblock.exportBorder();
 	new_bp.rows_count += 1;
-	m_scene -> undoStack().push(new ChangeBorderCommand(m_scene, old_bp, new_bp));
+	m_diagram -> undoStack().push(new ChangeBorderCommand(m_diagram, old_bp, new_bp));
 }
 
 /**
@@ -890,31 +904,22 @@
 	Retrecit le schema en hauteur
 */
 void DiagramView::removeRow() {
-	if (m_scene -> isReadOnly()) return;
-	BorderProperties old_bp = m_scene -> border_and_titleblock.exportBorder();
-	BorderProperties new_bp = m_scene -> border_and_titleblock.exportBorder();
+	if (m_diagram -> isReadOnly()) return;
+	BorderProperties old_bp = m_diagram -> border_and_titleblock.exportBorder();
+	BorderProperties new_bp = m_diagram -> border_and_titleblock.exportBorder();
 	new_bp.rows_count -= 1;
-	m_scene -> undoStack().push(new ChangeBorderCommand(m_scene, old_bp, new_bp));
+	m_diagram -> undoStack().push(new ChangeBorderCommand(m_diagram, old_bp, new_bp));
 }
 
 /**
  * @brief DiagramView::adjustSceneRect
  * Calcul and set the area of the scene visualized by this view
+ * The area are diagram sceneRect * 2.
  */
 void DiagramView::adjustSceneRect()
 {
-	QRectF scene_rect = m_scene->sceneRect();
+	QRectF scene_rect = m_diagram->sceneRect();
 	scene_rect.adjust(-Diagram::margin, -Diagram::margin, Diagram::margin, Diagram::margin);
-	
-	QSettings settings;
-	if (settings.value("diagrameditor/zoom-out-beyond-of-folio", false).toBool())
-	{
-			//When zoom out beyong of folio is active,
-			//we always adjust the scene rect to be 1/3 bigger than the wiewport
-		QRectF vpbr = mapToScene(viewport()->rect()).boundingRect();
-		vpbr.adjust(0, 0, vpbr.width()/3, vpbr.height()/3);
-		scene_rect = scene_rect.united(vpbr);
-	}
 	setSceneRect(scene_rect);
 }
 
@@ -931,9 +936,9 @@
 void DiagramView::adjustGridToZoom() {
 	QRectF viewed_scene = viewedSceneRect();
 	if (diagramEditor()->drawGrid())
-		m_scene->setDisplayGrid(viewed_scene.width() < 2000 || viewed_scene.height() < 2000);
+		m_diagram->setDisplayGrid(viewed_scene.width() < 2000 || viewed_scene.height() < 2000);
 	else
-		m_scene->setDisplayGrid(false);
+		m_diagram->setDisplayGrid(false);
 }
 
 /**
@@ -965,7 +970,7 @@
 	QETProject *tbt_parent_project = tbt_loc.parentProject();
 	if (!tbt_parent_project) return(true);
 
-	return(tbt_parent_project != m_scene -> project());
+	return(tbt_parent_project != m_diagram -> project());
 }
 
 /**
@@ -973,9 +978,9 @@
 	seule
 */
 void DiagramView::applyReadOnly() {
-	if (!m_scene) return;
+	if (!m_diagram) return;
 
-	bool is_writable = !m_scene -> isReadOnly();
+	bool is_writable = !m_diagram -> isReadOnly();
 	setInteractive(is_writable);
 	setAcceptDrops(is_writable);
 }
@@ -985,7 +990,7 @@
 */
 void DiagramView::editSelectionProperties() {
 	// get selection
-	DiagramContent selection = m_scene -> selectedContent();
+	DiagramContent selection = m_diagram -> selectedContent();
 
 	// if selection contains nothing return
 	int selected_items_count = selection.count(DiagramContent::All | DiagramContent::SelectedOnly);
@@ -999,8 +1004,8 @@
 		if (selection.conductors(DiagramContent::AnyConductor | DiagramContent::SelectedOnly).size())
 			selection.conductors().first()->editProperty();
 		// edit element
-		else if (selection.elements.size())
-			selection.elements.toList().first() -> editProperty();
+		else if (selection.m_elements.size())
+			selection.m_elements.toList().first() -> editProperty();
 	}
 
 	else {
@@ -1022,7 +1027,7 @@
 */
 void DiagramView::editSelectedConductorColor() {
 	// retrieve selected content
-	DiagramContent selection = m_scene -> selectedContent();
+	DiagramContent selection = m_diagram -> selectedContent();
 
 	// we'll focus on the selected conductor (we do not handle multiple conductors edition)
 	QList<Conductor *> selected_conductors = selection.conductors(DiagramContent::AnyConductor | DiagramContent::SelectedOnly);
@@ -1037,7 +1042,7 @@
 */
 void DiagramView::editConductorColor(Conductor *edited_conductor)
 {
-	if (m_scene -> isReadOnly() || !edited_conductor) return;
+	if (m_diagram -> isReadOnly() || !edited_conductor) return;
 
 		// store the initial properties of the provided conductor
 	ConductorProperties initial_properties = edited_conductor -> properties();
@@ -1073,9 +1078,9 @@
 	Reinitialise le profil des conducteurs selectionnes
 */
 void DiagramView::resetConductors() {
-	if (m_scene -> isReadOnly()) return;
+	if (m_diagram -> isReadOnly()) return;
 	// recupere les conducteurs selectionnes
-	QSet<Conductor *> selected_conductors = m_scene -> selectedConductors();
+	QSet<Conductor *> selected_conductors = m_diagram -> selectedConductors();
 
 	// repere les conducteurs modifies (= profil non nul)
 	QHash<Conductor *, ConductorProfilesGroup> conductors_and_profiles;
@@ -1092,7 +1097,7 @@
 	}
 
 	if (conductors_and_profiles.isEmpty()) return;
-	m_scene -> undoStack().push(new ResetConductorCommand(conductors_and_profiles));
+	m_diagram -> undoStack().push(new ResetConductorCommand(conductors_and_profiles));
 }
 
 /**
@@ -1186,9 +1191,9 @@
 */
 bool DiagramView::selectedItemHasFocus() {
 	return(
-		m_scene -> hasFocus() &&
-		m_scene -> focusItem() &&
-		m_scene -> focusItem() -> isSelected()
+		m_diagram -> hasFocus() &&
+		m_diagram -> focusItem() &&
+		m_diagram -> focusItem() -> isSelected()
 	);
 }
 
@@ -1197,9 +1202,9 @@
  * Edit the selected item if he can be edited and if only  one item is selected
  */
 void DiagramView::editSelection() {
-	if (m_scene -> isReadOnly() || m_scene -> selectedItems().size() != 1 ) return;
+	if (m_diagram -> isReadOnly() || m_diagram -> selectedItems().size() != 1 ) return;
 
-	QGraphicsItem *item = m_scene->selectedItems().first();
+	QGraphicsItem *item = m_diagram->selectedItems().first();
 
 		//We use dynamic_cast instead of qgraphicsitem_cast for QetGraphicsItem
 		//because they haven't got they own type().
@@ -1230,31 +1235,31 @@
 	@param e Evenement decrivant la demande de menu contextuel
 */
 void DiagramView::contextMenuEvent(QContextMenuEvent *e) {
-	if (QGraphicsItem *qgi = m_scene -> itemAt(mapToScene(e -> pos()), transform())) {
-		if (!qgi -> isSelected()) m_scene -> clearSelection();
+	if (QGraphicsItem *qgi = m_diagram -> itemAt(mapToScene(e -> pos()), transform())) {
+		if (!qgi -> isSelected()) m_diagram -> clearSelection();
 		qgi -> setSelected(true);
 	}
 
 	if (QETDiagramEditor *qde = diagramEditor()) {
-		context_menu -> clear();
-		if (m_scene -> selectedItems().isEmpty()) {
-			paste_here_pos = e -> pos();
-			paste_here -> setEnabled(Diagram::clipboardMayContainDiagram());
-			context_menu -> addAction(paste_here);
-			context_menu -> addSeparator();
-			context_menu -> addAction(qde -> infos_diagram);
-			context_menu -> addActions(qde -> m_row_column_actions_group.actions());
+		m_context_menu -> clear();
+		if (m_diagram -> selectedItems().isEmpty()) {
+			m_paste_here_pos = e -> pos();
+			m_paste_here -> setEnabled(Diagram::clipboardMayContainDiagram());
+			m_context_menu -> addAction(m_paste_here);
+			m_context_menu -> addSeparator();
+			m_context_menu -> addAction(qde -> infos_diagram);
+			m_context_menu -> addActions(qde -> m_row_column_actions_group.actions());
 		} else {
-			context_menu -> addAction(qde -> cut);
-			context_menu -> addAction(qde -> copy);
-			context_menu -> addSeparator();
-			context_menu -> addAction(qde -> conductor_reset);
-			context_menu -> addSeparator();
-			context_menu -> addActions(qde -> m_selection_actions_group.actions());
+			m_context_menu -> addAction(qde -> m_cut);
+			m_context_menu -> addAction(qde -> m_copy);
+			m_context_menu -> addSeparator();
+			m_context_menu -> addAction(qde -> m_conductor_reset);
+			m_context_menu -> addSeparator();
+			m_context_menu -> addActions(qde -> m_selection_actions_group.actions());
 		}
 
 		// affiche le menu contextuel
-		context_menu -> popup(e -> globalPos());
+		m_context_menu -> popup(e -> globalPos());
 	}
 	e -> accept();
 }
@@ -1280,7 +1285,7 @@
 {
 	if (m_event_interface && m_event_interface -> mouseDoubleClickEvent(e)) return;
 
-	BorderTitleBlock &bi = m_scene -> border_and_titleblock;
+	BorderTitleBlock &bi = m_diagram -> border_and_titleblock;
 
 	//Get the click pos on the diagram
 	QPointF click_pos = viewportTransform().inverted().map(e -> pos());

Modified: trunk/sources/diagramview.h
===================================================================
--- trunk/sources/diagramview.h	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/diagramview.h	2017-08-03 17:36:08 UTC (rev 5005)
@@ -49,15 +49,14 @@
 	
 		// attributes
 
-		Diagram          *m_scene;
-		DVEventInterface *m_event_interface;
-		QMenu            *context_menu;
-		QAction          *paste_here;
-		QPoint            paste_here_pos;
-		QPointF           rubber_band_origin;
-		bool              fresh_focus_in_;    ///< Indicate the focus was freshly gained
-		bool m_first_activation;
-
+		Diagram          *m_diagram;
+		DVEventInterface *m_event_interface = nullptr;
+		QMenu            *m_context_menu;
+		QAction          *m_paste_here;
+		QPoint            m_paste_here_pos;
+		QPointF           m_rubber_band_origin;
+		bool              m_fresh_focus_in,
+						  m_first_activation = true;
 	public:
 		QString title() const;
 		void editDiagramProperties();
@@ -66,7 +65,7 @@
 		void addRow();
 		void removeRow();
 		/// @return the diagram rendered by this view
-		Diagram *diagram() { return(m_scene); }
+		Diagram *diagram() { return(m_diagram); }
 		QETDiagramEditor *diagramEditor() const;
 		bool hasSelectedItems();
 		bool hasCopiableItems();

Modified: trunk/sources/elementsmover.cpp
===================================================================
--- trunk/sources/elementsmover.cpp	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/elementsmover.cpp	2017-08-03 17:36:08 UTC (rev 5005)
@@ -105,12 +105,12 @@
 	}
 	
 	// Move some conductors
-	foreach(Conductor *conductor, moved_content_.conductorsToMove) {
+	foreach(Conductor *conductor, moved_content_.m_conductors_to_move) {
 		conductor -> setPos(conductor -> pos() + movement);
 	}
 	
 	// Recalcul the path of other conductors
-	foreach(Conductor *conductor, moved_content_.conductorsToUpdate) {
+	foreach(Conductor *conductor, moved_content_.m_conductors_to_update) {
 		conductor -> updatePath();
 	}
 }
@@ -142,7 +142,7 @@
 		moved_content_.items(dc::Elements).size() == 1 &&
 		diagram_ -> project() -> autoConductor())
 	{
-		Element *elmt = moved_content_.elements.toList().first();
+		Element *elmt = moved_content_.m_elements.toList().first();
 
 		int acc = elmt->AlignedFreeTerminals().size();
 

Modified: trunk/sources/elementtextsmover.cpp
===================================================================
--- trunk/sources/elementtextsmover.cpp	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/elementtextsmover.cpp	2017-08-03 17:36:08 UTC (rev 5005)
@@ -19,15 +19,12 @@
 #include "elementtextitem.h"
 #include "diagram.h"
 #include "QPropertyUndoCommand/qpropertyundocommand.h"
+#include "dynamicelementtextitem.h"
 
 /**
  * @brief ElementTextsMover::ElementTextsMover
  */
-ElementTextsMover::ElementTextsMover() :
-	movement_running_(false),
-	diagram_(nullptr),
-	movement_driver_(nullptr)
-{}
+ElementTextsMover::ElementTextsMover() {}
 
 /**
  * @brief ElementTextsMover::isReady
@@ -35,7 +32,7 @@
  * False if this ElementTextsMover is actually process a movement
  */
 bool ElementTextsMover::isReady() const {
-	return(!movement_running_);
+	return(!m_movement_running);
 }
 
 /**
@@ -47,24 +44,24 @@
  */
 int ElementTextsMover::beginMovement(Diagram *diagram, QGraphicsItem *driver_item)
 {
-	if (movement_running_ || !diagram) return(-1);
+	if (m_movement_running || !diagram) return(-1);
 
-	diagram_ = diagram;
-	movement_driver_ = driver_item;
+	m_diagram = diagram;
+	m_movement_driver = driver_item;
 	m_texts_item_H.clear();
 
-	foreach(QGraphicsItem *item, diagram -> selectedItems())
+	for(QGraphicsItem *item : diagram->selectedItems())
 	{
-		if (item->type() == ElementTextItem::Type)
+		if (item->type() == ElementTextItem::Type || item->type() == DynamicElementTextItem::Type)
 		{
-			ElementTextItem *eti = static_cast<ElementTextItem *> (item);
-			m_texts_item_H.insert(eti, eti->pos());
+			DiagramTextItem *dti = static_cast<DiagramTextItem *> (item);
+			m_texts_item_H.insert(dti, dti->pos());
 		}
 	}
 	
 	if (!m_texts_item_H.size()) return(-1);
 	
-	movement_running_ = true;
+	m_movement_running = true;
 	
 	return(m_texts_item_H.size());
 }
@@ -77,13 +74,14 @@
  */
 void ElementTextsMover::continueMovement(const QPointF &movement)
 {
-	if (!movement_running_ || movement.isNull()) return;
+	if (!m_movement_running || movement.isNull()) return;
 	
-	foreach(ElementTextItem *text_item, m_texts_item_H.keys())
+	for(DiagramTextItem *text_item : m_texts_item_H.keys())
 	{
-		if (text_item == movement_driver_) continue;
-		QPointF applied_movement = text_item -> mapMovementToParent(text_item-> mapMovementFromScene(movement));
-		text_item -> setPos(text_item -> pos() + applied_movement);
+		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);
 	}
 }
 
@@ -94,31 +92,25 @@
 void ElementTextsMover::endMovement()
 {
 		//No movement running, or no text to move
-	if (!movement_running_ || m_texts_item_H.isEmpty()) return;
+	if (!m_movement_running || m_texts_item_H.isEmpty())
+		return;
+	
 		//Movement is null
-	ElementTextItem *eti = m_texts_item_H.keys().first();
-	if (eti->pos() == m_texts_item_H.value(eti)) return;
+	DiagramTextItem *dti = m_texts_item_H.keys().first();
+	if (dti->pos() == m_texts_item_H.value(dti))
+		return;
 	
-	QPropertyUndoCommand *undo = nullptr;
+	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())
+	{
+		QPropertyUndoCommand *child_undo = new QPropertyUndoCommand(dti, "pos", m_texts_item_H.value(dti), dti->pos(), undo);
+		child_undo->enableAnimation();
 
-	foreach (ElementTextItem *eti, m_texts_item_H.keys())
-	{
-		if (undo)
-		{
-			QPropertyUndoCommand *child_undo = new QPropertyUndoCommand(eti, "pos", m_texts_item_H.value(eti), eti->pos(), undo);
-			child_undo->enableAnimation();
-		}
-		else
-		{
-			undo = new QPropertyUndoCommand(eti, "pos", m_texts_item_H.value(eti), eti->pos());
-			undo->enableAnimation();
-			QString txt = 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()));
-			undo->setText(txt);
-		}
 	}
 
-	diagram_->undoStack().push(undo);
+	m_diagram->undoStack().push(undo);
 	
-	movement_running_ = false;
+	m_movement_running = false;
 }

Modified: trunk/sources/elementtextsmover.h
===================================================================
--- trunk/sources/elementtextsmover.h	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/elementtextsmover.h	2017-08-03 17:36:08 UTC (rev 5005)
@@ -22,7 +22,7 @@
 #include <QPointF>
 
 class QGraphicsItem;
-class ElementTextItem;
+class DiagramTextItem;
 class Diagram;
 
 /**
@@ -38,14 +38,14 @@
 	
 	public:
 		bool isReady() const;
-		int  beginMovement(Diagram *, QGraphicsItem * = 0);
+		int  beginMovement(Diagram *diagram, QGraphicsItem *driver_item = nullptr);
 		void continueMovement(const QPointF &);
 		void endMovement();
 	
 	private:
-		bool movement_running_;
-		Diagram *diagram_;
-		QGraphicsItem *movement_driver_;
-		QHash <ElementTextItem *, QPointF> m_texts_item_H;
+		bool m_movement_running = false;
+		Diagram *m_diagram = nullptr;
+		QGraphicsItem *m_movement_driver = nullptr;
+		QHash <DiagramTextItem *, QPointF> m_texts_item_H;
 };
 #endif

Modified: trunk/sources/qet.cpp
===================================================================
--- trunk/sources/qet.cpp	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/qet.cpp	2017-08-03 17:36:08 UTC (rev 5005)
@@ -232,7 +232,7 @@
 	@return la proposition decrivant le nombre d'elements, de conducteurs et de
 	textes
 */
-QString QET::ElementsAndConductorsSentence(int elements_count, int conductors_count, int texts_count, int images_count, int shapes_count) {
+QString QET::ElementsAndConductorsSentence(int elements_count, int conductors_count, int texts_count, int images_count, int shapes_count, int element_text_count) {
 	QString text;
 	if (elements_count) {
 		text += QObject::tr(
@@ -240,61 +240,28 @@
 			"part of a sentence listing the content of a diagram",
 			elements_count
 		);
-		if ((conductors_count && texts_count) ||
-			(conductors_count && images_count) ||
-			(texts_count && images_count)) {
-			text += QObject::tr(
-				", ",
-				"separator between elements and conductors in a sentence "
-				"listing the content of a diagram"
-			);
-		} else if (conductors_count || texts_count || images_count) {
-			text += QObject::tr(
-				" et ",
-				"separator between elements and conductors (or texts) in a "
-				"sentence listing the content of a diagram"
-			);
-		}
 	}
 	
 	if (conductors_count) {
+		if (!text.isEmpty()) text += ", ";
 		text += QObject::tr(
 			"%n conducteur(s)",
 			"part of a sentence listing the content of a diagram",
 			conductors_count
 		);
-		if (texts_count && images_count) {
-			text += QObject::tr(
-				", ",
-				"separator between elements and conductors in a sentence "
-				"listing the content of a diagram"
-			);
-		}
-		else if (texts_count || images_count) {
-			text += QObject::tr(
-				" et ",
-				"separator between conductors and texts in a sentence listing "
-				"the content of a diagram"
-			);
-		}
 	}
 	
 	if (texts_count) {
+		if (!text.isEmpty()) text += ", ";
 		text += QObject::tr(
 			"%n champ(s) de texte",
 			"part of a sentence listing the content of a diagram",
 			texts_count
 		);
-		if (images_count) {
-			text += QObject::tr(
-				" et ",
-				"separator between conductors and texts in a sentence listing "
-				"the content of a diagram"
-			);
-		}
 	}
 
 	if (images_count) {
+		if (!text.isEmpty()) text += ", ";
 		text += QObject::tr(
 			"%n image(s)",
 			"part of a sentence listing the content of a diagram",
@@ -303,6 +270,7 @@
 	}
 
 	if (shapes_count) {
+		if (!text.isEmpty()) text += ", ";
 		text += QObject::tr(
 			"%n forme(s)",
 			"part of a sentence listing the content of a diagram",
@@ -309,6 +277,15 @@
 			shapes_count
 		);
 	}
+	
+	if (element_text_count) {
+		if (!text.isEmpty()) text += ", ";
+		text += QObject::tr(
+					"%n texte(s) d'élément",
+					"part of a sentence listing the content of a diagram",
+					element_text_count);
+	}
+	
 	return(text);
 }
 

Modified: trunk/sources/qet.h
===================================================================
--- trunk/sources/qet.h	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/qet.h	2017-08-03 17:36:08 UTC (rev 5005)
@@ -143,7 +143,7 @@
 	bool orthogonalProjection(const QPointF &, const QLineF &, QPointF * = 0);
 	bool attributeIsAnInteger(const QDomElement &, QString , int * = NULL);
 	bool attributeIsAReal(const QDomElement &, QString , qreal * = NULL);
-	QString ElementsAndConductorsSentence(int, int, int = 0, int = 0, int = 0);
+	QString ElementsAndConductorsSentence(int, int, int = 0, int = 0, int = 0, int = 0);
 	QList<QDomElement> findInDomElement(const QDomElement &, const QString &);
 	QList<QDomElement> findInDomElement(const QDomElement &, const QString &, const QString &);
 	QList<QChar> forbiddenCharacters();

Modified: trunk/sources/qetdiagrameditor.cpp
===================================================================
--- trunk/sources/qetdiagrameditor.cpp	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/qetdiagrameditor.cpp	2017-08-03 17:36:08 UTC (rev 5005)
@@ -42,6 +42,9 @@
 #include "diagrameventaddtext.h"
 #include "elementscollectionwidget.h"
 #include "autonumberingdockwidget.h"
+#include "dynamicelementtextitem.h"
+#include "conductortextitem.h"
+#include "elementtextitem.h"
 
 #include <QMessageBox>
 #include <QStandardPaths>
@@ -242,24 +245,24 @@
 	redo -> setStatusTip(tr("Restaure l'action annulée", "status bar tip"));
 
 		//cut copy past action
-	cut   = new QAction(QET::Icons::EditCut,   tr("Co&uper"), this);
-	copy  = new QAction(QET::Icons::EditCopy,  tr("Cop&ier"), this);
+	m_cut   = new QAction(QET::Icons::EditCut,   tr("Co&uper"), this);
+	m_copy  = new QAction(QET::Icons::EditCopy,  tr("Cop&ier"), this);
 	paste = new QAction(QET::Icons::EditPaste, tr("C&oller"), this);
 
-	cut   -> setShortcut(QKeySequence::Cut);
-	copy  -> setShortcut(QKeySequence::Copy);
+	m_cut   -> setShortcut(QKeySequence::Cut);
+	m_copy  -> setShortcut(QKeySequence::Copy);
 	paste -> setShortcut(QKeySequence::Paste);
 
-	cut   -> setStatusTip(tr("Transfère les éléments sélectionnés dans le presse-papier", "status bar tip"));
-	copy  -> setStatusTip(tr("Copie les éléments sélectionnés dans le presse-papier", "status bar tip"));
+	m_cut   -> setStatusTip(tr("Transfère les éléments sélectionnés dans le presse-papier", "status bar tip"));
+	m_copy  -> setStatusTip(tr("Copie les éléments sélectionnés dans le presse-papier", "status bar tip"));
 	paste -> setStatusTip(tr("Place les éléments du presse-papier sur le folio", "status bar tip"));
 
-	connect(cut,   SIGNAL(triggered()), this, SLOT(slot_cut()));
-	connect(copy,  SIGNAL(triggered()), this, SLOT(slot_copy()));
+	connect(m_cut,   SIGNAL(triggered()), this, SLOT(slot_cut()));
+	connect(m_copy,  SIGNAL(triggered()), this, SLOT(slot_copy()));
 	connect(paste, SIGNAL(triggered()), this, SLOT(slot_paste()));
 
-	conductor_reset   = new QAction(QET::Icons::ConductorSettings,     tr("Réinitialiser les conducteurs"),        this);
-	conductor_reset  -> setShortcut( QKeySequence( tr("Ctrl+K")		) );
+	m_conductor_reset   = new QAction(QET::Icons::ConductorSettings,     tr("Réinitialiser les conducteurs"),        this);
+	m_conductor_reset  -> setShortcut( QKeySequence( tr("Ctrl+K")		) );
 
 	m_auto_conductor = new QAction   (QET::Icons::Autoconnect, tr("Création automatique de conducteur(s)","Tool tip of auto conductor"), this);
 	m_auto_conductor -> setStatusTip (tr("Utiliser la création automatique de conducteur(s) quand cela est possible", "Status tip of auto conductor"));
@@ -348,27 +351,27 @@
 	connect(&m_row_column_actions_group, &QActionGroup::triggered, this, &QETDiagramEditor::rowColumnGroupTriggered);
 
 		//Selections Actions (related to a selected item)
-	delete_selection  = m_selection_actions_group.addAction( QET::Icons::EditDelete,        tr("Supprimer")							  );
-	rotate_selection  = m_selection_actions_group.addAction( QET::Icons::ObjectRotateRight, tr("Pivoter")							  );
-	rotate_texts      = m_selection_actions_group.addAction( QET::Icons::ObjectRotateRight, tr("Orienter les textes")				  );
-	find_element      = m_selection_actions_group.addAction(                                tr("Retrouver dans le panel")			  );
-	edit_selection    = m_selection_actions_group.addAction( QET::Icons::ElementEdit,       tr("Éditer l'item sélectionné")  );
+	m_delete_selection  = m_selection_actions_group.addAction( QET::Icons::EditDelete,        tr("Supprimer")							  );
+	m_rotate_selection  = m_selection_actions_group.addAction( QET::Icons::ObjectRotateRight, tr("Pivoter")							  );
+	m_rotate_texts      = m_selection_actions_group.addAction( QET::Icons::ObjectRotateRight, tr("Orienter les textes")				  );
+	m_find_element      = m_selection_actions_group.addAction(                                tr("Retrouver dans le panel")			  );
+	m_edit_selection    = m_selection_actions_group.addAction( QET::Icons::ElementEdit,       tr("Éditer l'item sélectionné")  );
 
-	delete_selection -> setShortcut( QKeySequence::Delete);
-	rotate_selection -> setShortcut( QKeySequence( tr("Space")		) );
-	rotate_texts     -> setShortcut( QKeySequence( tr("Ctrl+Space") ) );
-	edit_selection	 -> setShortcut( QKeySequence( tr("Ctrl+E")		) );
+	m_delete_selection -> setShortcut( QKeySequence::Delete);
+	m_rotate_selection -> setShortcut( QKeySequence( tr("Space")		) );
+	m_rotate_texts     -> setShortcut( QKeySequence( tr("Ctrl+Space") ) );
+	m_edit_selection	 -> setShortcut( QKeySequence( tr("Ctrl+E")		) );
 
-	delete_selection -> setStatusTip( tr("Enlève les éléments sélectionnés du folio", "status bar tip"));
-	rotate_selection -> setStatusTip( tr("Pivote les éléments et textes sélectionnés", "status bar tip"));
-	rotate_texts     -> setStatusTip( tr("Pivote les textes sélectionnés à un angle précis", "status bar tip"));
-	find_element     -> setStatusTip( tr("Retrouve l'élément sélectionné dans le panel", "status bar tip"));
+	m_delete_selection -> setStatusTip( tr("Enlève les éléments sélectionnés du folio", "status bar tip"));
+	m_rotate_selection -> setStatusTip( tr("Pivote les éléments et textes sélectionnés", "status bar tip"));
+	m_rotate_texts     -> setStatusTip( tr("Pivote les textes sélectionnés à un angle précis", "status bar tip"));
+	m_find_element     -> setStatusTip( tr("Retrouve l'élément sélectionné dans le panel", "status bar tip"));
 
-	delete_selection ->setData("delete_selection");
-	rotate_selection ->setData("rotate_selection");
-	rotate_texts     ->setData("rotate_selected_text");
-	find_element     ->setData("find_selected_element");
-	edit_selection   ->setData("edit_selected_element");
+	m_delete_selection ->setData("delete_selection");
+	m_rotate_selection ->setData("rotate_selection");
+	m_rotate_texts     ->setData("rotate_selected_text");
+	m_find_element     ->setData("find_selected_element");
+	m_edit_selection   ->setData("edit_selected_element");
 
 	connect(&m_selection_actions_group, &QActionGroup::triggered, this, &QETDiagramEditor::selectionGroupTriggered);
 
@@ -452,7 +455,7 @@
 	export_diagram    -> setStatusTip(tr("Exporte le folio courant dans un autre format", "status bar tip"));
 	print             -> setStatusTip(tr("Imprime un ou plusieurs folios du projet courant", "status bar tip"));
 	quit_editor       -> setStatusTip(tr("Ferme l'application QElectroTech", "status bar tip"));
-	conductor_reset   -> setStatusTip(tr("Recalcule les chemins des conducteurs sans tenir compte des modifications", "status bar tip"));
+	m_conductor_reset   -> setStatusTip(tr("Recalcule les chemins des conducteurs sans tenir compte des modifications", "status bar tip"));
 	infos_diagram     -> setStatusTip(tr("Édite les propriétés du folio (dimensions, informations du cartouche, propriétés des conducteurs...)", "status bar tip"));
 
 	windowed_view_mode -> setStatusTip(tr("Présente les différents projets ouverts dans des sous-fenêtres", "status bar tip"));
@@ -503,7 +506,7 @@
 	connect(cascade_window,     SIGNAL(triggered()), &workspace, SLOT(cascadeSubWindows())         );
 	connect(next_window,        SIGNAL(triggered()), &workspace, SLOT(activateNextSubWindow())     );
 	connect(prev_window,        SIGNAL(triggered()), &workspace, SLOT(activatePreviousSubWindow()) );
-	connect(conductor_reset,    SIGNAL(triggered()), this,       SLOT(slot_resetConductors())      );
+	connect(m_conductor_reset,    SIGNAL(triggered()), this,       SLOT(slot_resetConductors())      );
 	connect(infos_diagram,      SIGNAL(triggered()), this,       SLOT(editCurrentDiagramProperties()));
 }
 
@@ -526,12 +529,12 @@
 	main_bar -> addAction(undo);
 	main_bar -> addAction(redo);
 	main_bar -> addSeparator();
-	main_bar -> addAction(cut);
-	main_bar -> addAction(copy);
+	main_bar -> addAction(m_cut);
+	main_bar -> addAction(m_copy);
 	main_bar -> addAction(paste);
 	main_bar -> addSeparator();
-	main_bar -> addAction(delete_selection);
-	main_bar -> addAction(rotate_selection);
+	main_bar -> addAction(m_delete_selection);
+	main_bar -> addAction(m_rotate_selection);
 
 	// Modes selection / visualisation et zoom
 	view_bar -> addAction(mode_selection);
@@ -543,7 +546,7 @@
 	view_bar -> addActions(m_zoom_action_toolBar);
 
 	diagram_bar -> addAction (infos_diagram);
-	diagram_bar -> addAction (conductor_reset);
+	diagram_bar -> addAction (m_conductor_reset);
 	diagram_bar -> addAction (m_auto_conductor);
 
 	m_add_item_toolBar = new QToolBar(tr("Ajouter"), this);
@@ -592,8 +595,8 @@
 	menu_edition -> addAction(undo);
 	menu_edition -> addAction(redo);
 	menu_edition -> addSeparator();
-	menu_edition -> addAction(cut);
-	menu_edition -> addAction(copy);
+	menu_edition -> addAction(m_cut);
+	menu_edition -> addAction(m_copy);
 	menu_edition -> addAction(paste);
 	menu_edition -> addSeparator();
 	menu_edition -> addActions(m_select_actions_group.actions());
@@ -600,7 +603,7 @@
 	menu_edition -> addSeparator();
 	menu_edition -> addActions(m_selection_actions_group.actions());
 	menu_edition -> addSeparator();
-	menu_edition -> addAction(conductor_reset);
+	menu_edition -> addAction(m_conductor_reset);
 	menu_edition -> addSeparator();
 	menu_edition -> addAction(infos_diagram);
 	menu_edition -> addActions(m_row_column_actions_group.actions());
@@ -1039,7 +1042,7 @@
 	DiagramView *dv = currentDiagram();
 	if (!dv) return(0);
 	
-	QList<Element *> selected_elements = dv -> diagram() -> selectedContent().elements.toList();
+	QList<Element *> selected_elements = dv -> diagram() -> selectedContent().m_elements.toList();
 	if (selected_elements.count() != 1) return(0);
 	
 	return(selected_elements.first());
@@ -1383,38 +1386,52 @@
  * Manage the actions who need some conditions to be enable or not.
  * This method does nothing if there is no project opened
  */
-void QETDiagramEditor::slot_updateComplexActions() {
+void QETDiagramEditor::slot_updateComplexActions()
+{
 	DiagramView *dv = currentDiagram();
-	bool editable_diagram = (dv && !dv -> diagram() -> isReadOnly());
+	if(!dv)
+	{
+		QList <QAction *> action_list;
+		action_list << m_conductor_reset << m_find_element << m_cut << m_copy << m_delete_selection << m_rotate_selection << m_edit_selection;
+		for(QAction *action : action_list)
+			action->setEnabled(false);
+		
+		return;
+	}
+	
+	Diagram *diagram_ = dv->diagram();
+	bool ro = diagram_->isReadOnly();
+	
 
 		//Number of selected conductors
-	int selected_conductors_count = dv ? dv -> diagram() -> selectedConductors().count() : 0;
-	conductor_reset  -> setEnabled(editable_diagram && selected_conductors_count);
+	int selected_conductors_count = diagram_->selectedConductors().count();
+	m_conductor_reset->setEnabled(!ro && selected_conductors_count);
 	
 		// number of selected elements
-	int selected_elements_count = dv ? dv -> diagram() -> selectedContent().count(DiagramContent::Elements) : 0;
-	find_element -> setEnabled(selected_elements_count == 1);
+	int selected_elements_count = diagram_->selectedContent().count(DiagramContent::Elements);
+	m_find_element->setEnabled(selected_elements_count == 1);
 	
 		//Action that need items (elements, conductors, texts...) selected, to be enabled
-	bool copiable_items  = dv ? (dv -> hasCopiableItems()) : false;
-	bool deletable_items = dv ? (dv -> hasDeletableItems()) : false;
-	cut              -> setEnabled(editable_diagram && copiable_items);
-	copy             -> setEnabled(copiable_items);
-	delete_selection -> setEnabled(editable_diagram && deletable_items);
-	rotate_selection -> setEnabled(editable_diagram && dv -> diagram() -> canRotateSelection());
+	bool copiable_items  = dv->hasCopiableItems();
+	bool deletable_items = dv->hasDeletableItems();
+	m_cut              -> setEnabled(!ro && copiable_items);
+	m_copy             -> setEnabled(copiable_items);
+	m_delete_selection -> setEnabled(!ro && deletable_items);
+	m_rotate_selection -> setEnabled(!ro && diagram_->canRotateSelection());
 
 		//Action that need selected texts
-	int selected_texts = dv ? (dv -> diagram() -> selectedTexts().count()) : 0;
-	int selected_conductor_texts = dv ? (dv -> diagram() -> selectedConductorTexts().count()) : 0;
-	int selected_element_texts = dv ? (dv -> diagram() -> selectedElementTexts().count()) : 0;
-	rotate_texts -> setEnabled(editable_diagram && selected_texts);
+	int selected_texts = diagram_->selectedTexts().count();
+	int selected_conductor_texts   = 0; for(DiagramTextItem *dti : diagram_->selectedTexts()) {if(dti->type() == ConductorTextItem::Type) selected_conductor_texts++;}
+	int selected_element_texts     = 0; for(DiagramTextItem *dti : diagram_->selectedTexts()) {if(dti->type() == ElementTextItem::Type) selected_element_texts++;}
+	int selected_dynamic_elmt_text = 0; for(DiagramTextItem *dti : diagram_->selectedTexts()) {if(dti->type() == DynamicElementTextItem::Type) selected_dynamic_elmt_text++;}
+	m_rotate_texts -> setEnabled(!ro && selected_texts);
 
 		// actions need only one editable item
-	int selected_image = dv ? dv -> diagram() -> selectedContent().count(DiagramContent::Images) : 0;
+	int selected_image = diagram_-> selectedContent().count(DiagramContent::Images);
 
-	int selected_shape = dv ? dv -> diagram() -> selectedContent().count(DiagramContent::Shapes) : 0;
+	int selected_shape = diagram_-> selectedContent().count(DiagramContent::Shapes);
 	int selected_editable = selected_elements_count +
-							(selected_texts - selected_conductor_texts - selected_element_texts) +
+							(selected_texts - selected_conductor_texts - selected_element_texts - selected_dynamic_elmt_text) +
 							selected_image +
 							selected_shape +
 							selected_conductors_count;
@@ -1421,38 +1438,38 @@
 
 	if (selected_editable == 1)
 	{
-		edit_selection -> setEnabled(true);
+		m_edit_selection -> setEnabled(true);
 			//edit element
 		if (selected_elements_count)
 		{
-			edit_selection -> setText(tr("Éditer l'élement", "edit element"));
-			edit_selection -> setIcon(QET::Icons::ElementEdit);
+			m_edit_selection -> setText(tr("Éditer l'élement", "edit element"));
+			m_edit_selection -> setIcon(QET::Icons::ElementEdit);
 		}
 			//edit text field
 		else if (selected_texts)
 		{
-			edit_selection -> setText(tr("Éditer le champ de texte", "edit text field"));
-			edit_selection -> setIcon(QET::Icons::EditText);
+			m_edit_selection -> setText(tr("Éditer le champ de texte", "edit text field"));
+			m_edit_selection -> setIcon(QET::Icons::EditText);
 		}
 			//edit image
 		else if (selected_image)
 		{
-			edit_selection -> setText(tr("Éditer l'image", "edit image"));
-			edit_selection -> setIcon(QET::Icons::resize_image);
+			m_edit_selection -> setText(tr("Éditer l'image", "edit image"));
+			m_edit_selection -> setIcon(QET::Icons::resize_image);
 		}
 			//edit conductor
 		else if (selected_conductors_count)
 		{
-			edit_selection -> setText(tr("Éditer le conducteur", "edit conductor"));
-			edit_selection -> setIcon(QET::Icons::ElementEdit);
+			m_edit_selection -> setText(tr("Éditer le conducteur", "edit conductor"));
+			m_edit_selection -> setIcon(QET::Icons::ElementEdit);
 		}
 	}
 		//not an editable item
 	else
 	{
-		edit_selection -> setText(tr("Éditer l'objet sélectionné", "edit selected item"));
-		edit_selection -> setIcon(QET::Icons::ElementEdit);
-		edit_selection -> setEnabled(false);
+		m_edit_selection -> setText(tr("Éditer l'objet sélectionné", "edit selected item"));
+		m_edit_selection -> setIcon(QET::Icons::ElementEdit);
+		m_edit_selection -> setEnabled(false);
 	}
 }
 

Modified: trunk/sources/qetdiagrameditor.h
===================================================================
--- trunk/sources/qetdiagrameditor.h	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/qetdiagrameditor.h	2017-08-03 17:36:08 UTC (rev 5005)
@@ -174,9 +174,9 @@
 		QAction *redo;               ///< Redo the latest cancelled operation
 	public:
 		QAction *infos_diagram;      ///< Show a dialog to edit diagram properties
-		QAction *conductor_reset;    ///< Reset paths of selected conductors
-		QAction *cut;                ///< Cut selection to clipboard
-		QAction *copy;               ///< Copy selection to clipboard
+		QAction *m_conductor_reset;    ///< Reset paths of selected conductors
+		QAction *m_cut;                ///< Cut selection to clipboard
+		QAction *m_copy;               ///< Copy selection to clipboard
 	private:
 		QAction *paste;              ///< Paste clipboard content on the current diagram
 		QAction *m_auto_conductor;   ///< Enable/Disable the use of auto conductor
@@ -194,7 +194,7 @@
 		QAction *cascade_window;     ///< Show MDI subwindows as cascade
 		QAction *prev_window;        ///< Switch to the previous document
 		QAction *next_window;        ///< Switch to the next document
-		QAction *edit_selection;	 ///< To edit selected item
+		QAction *m_edit_selection;	 ///< To edit selected item
 
 		QActionGroup m_add_item_actions_group; ///Action related to adding (add text image shape...)
 
@@ -207,10 +207,10 @@
 		QActionGroup m_row_column_actions_group; /// Action related to add/remove rows/column in diagram
 		QActionGroup m_selection_actions_group; ///Action related to edit a selected item
 	private:
-		QAction *delete_selection;				///< Delete selection
-		QAction *rotate_selection;				///< Rotate selected elements and text items by 90 degrees
-		QAction *rotate_texts;					///< Direct selected text items to a specific angle
-		QAction *find_element;					///< Find the selected element in the panel
+		QAction *m_delete_selection;				///< Delete selection
+		QAction *m_rotate_selection;				///< Rotate selected elements and text items by 90 degrees
+		QAction *m_rotate_texts;					///< Direct selected text items to a specific angle
+		QAction *m_find_element;					///< Find the selected element in the panel
 
 		QActionGroup m_file_actions_group; ///Actions related to file (open, close, save...)
 		QAction *close_file;			   ///< Close current project file

Modified: trunk/sources/qetgraphicsitem/diagramtextitem.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/diagramtextitem.cpp	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/qetgraphicsitem/diagramtextitem.cpp	2017-08-03 17:36:08 UTC (rev 5005)
@@ -27,10 +27,7 @@
  */
 DiagramTextItem::DiagramTextItem(QGraphicsItem *parent) :
 	QGraphicsTextItem(parent),
-	m_mouse_hover(false),
-	previous_text_(),
-	rotation_angle_(0.0),
-	m_first_move (true)
+	m_rotation_angle(0.0)
 { build(); }
 
 /**
@@ -41,8 +38,8 @@
 DiagramTextItem::DiagramTextItem(const QString &text, QGraphicsItem *parent) :
 	QGraphicsTextItem(text, parent),
 	m_mouse_hover(false),
-	previous_text_(text),
-	rotation_angle_(0.0)
+	m_previous_html_text(text),
+	m_rotation_angle(0.0)
 { build(); }
 
 /**
@@ -83,7 +80,7 @@
 	@return l'angle de rotation actuel de ce texte
 */
 qreal DiagramTextItem::rotationAngle() const {
-	return(rotation_angle_);
+	return(m_rotation_angle);
 }
 
 /**
@@ -94,8 +91,8 @@
 */
 void DiagramTextItem::setRotationAngle(const qreal &rotation) {
 	qreal applied_rotation = QET::correctAngle(rotation);
-	applyRotation(applied_rotation - rotation_angle_);
-	rotation_angle_ = applied_rotation;
+	applyRotation(applied_rotation - m_rotation_angle);
+	m_rotation_angle = applied_rotation;
 }
 
 /**
@@ -106,7 +103,7 @@
 */
 void DiagramTextItem::rotateBy(const qreal &added_rotation) {
 	qreal applied_added_rotation = QET::correctAngle(added_rotation);
-	rotation_angle_ = QET::correctAngle(rotation_angle_ + applied_added_rotation);
+	m_rotation_angle = QET::correctAngle(m_rotation_angle + applied_added_rotation);
 	applyRotation(applied_added_rotation);
 }
 
@@ -186,10 +183,27 @@
 	return(local_movement_point - local_origin);
 }
 
-void DiagramTextItem::setFontSize(int &s) {
-	setFont(QETApp::diagramTextsFont(s));
+void DiagramTextItem::setFontSize(int s)
+{
+    setFont(QETApp::diagramTextsFont(s));
+	emit fontSizeChanged(s);
 }
 
+int DiagramTextItem::fontSize() const
+{
+    return font().pointSize();
+}
+
+void DiagramTextItem::setColor(QColor color)
+{
+    setDefaultTextColor(color);
+	emit colorChanged(color);
+}
+
+QColor DiagramTextItem::color() const {
+	return defaultTextColor();
+}
+
 /**
  * @brief DiagramTextItem::paint
  * Draw this text field. This method draw the text by calling QGraphicsTextItem::paint.
@@ -226,42 +240,39 @@
 }
 
 /**
-	Gere la prise de focus du champ de texte
-	@param e Objet decrivant la prise de focus
-*/
-void DiagramTextItem::focusInEvent(QFocusEvent *e) {
-	QGraphicsTextItem::focusInEvent(e);
-	
-	// empeche le deplacement du texte pendant son edition
+ * @brief DiagramTextItem::focusInEvent
+ * @param e
+ */
+void DiagramTextItem::focusInEvent(QFocusEvent *event)
+{
+	QGraphicsTextItem::focusInEvent(event);
+
 	setFlag(QGraphicsItem::ItemIsMovable, false);
 	
-	// memorise le texte avant que l'utilisateur n'y touche
-	previous_text_ = toHtml();
-	// cela permettra de determiner si l'utilisateur a modifie le texte a la fin de l'edition
+	m_previous_html_text = toHtml();
+	m_previous_text = toPlainText();
 }
 
 /**
-	Gere la perte de focus du champ de texte
-	@param e Objet decrivant la perte de focus
-*/
-void DiagramTextItem::focusOutEvent(QFocusEvent *e) {
-	QGraphicsTextItem::focusOutEvent(e);
+ * @brief DiagramTextItem::focusOutEvent
+ * @param event
+ */
+void DiagramTextItem::focusOutEvent(QFocusEvent *event)
+{
+	QGraphicsTextItem::focusOutEvent(event);
+
+	if (toHtml() != m_previous_html_text)
+		emit(diagramTextChanged(this, m_previous_html_text, toHtml()));
+	if(toPlainText() != m_previous_text)
+		emit textEdited(m_previous_text, toPlainText());
 	
-	// signale la modification du texte si besoin
-	if (toPlainText() != previous_text_) {
-		emit(diagramTextChanged(this, previous_text_, toHtml()));
-		previous_text_ = toHtml();
-	}
-	
-	// deselectionne le texte
 	QTextCursor cursor = textCursor();
 	cursor.clearSelection();
 	setTextCursor(cursor);
-	
-	// hack a la con pour etre re-entrant
+
+		//Bad hack to be re-entrant
 	setTextInteractionFlags(Qt::NoTextInteraction);
-	
-	// autorise de nouveau le deplacement du texte
+
 	setFlag(QGraphicsItem::ItemIsMovable, true);
 	setFlag(QGraphicsTextItem::ItemIsFocusable, false);
 }
@@ -271,7 +282,7 @@
 	@param event un QGraphicsSceneMouseEvent decrivant le double-clic
 */
 void DiagramTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) {
-	if (!(textInteractionFlags() & Qt::TextEditable) && !no_editable) {
+	if (!(textInteractionFlags() & Qt::TextEditable) && !m_no_editable) {
 		// rend le champ de texte editable
 		setTextInteractionFlags(Qt::TextEditorInteraction);
 		

Modified: trunk/sources/qetgraphicsitem/diagramtextitem.h
===================================================================
--- trunk/sources/qetgraphicsitem/diagramtextitem.h	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/qetgraphicsitem/diagramtextitem.h	2017-08-03 17:36:08 UTC (rev 5005)
@@ -32,6 +32,13 @@
 class DiagramTextItem : public QGraphicsTextItem
 {
 	Q_OBJECT
+    
+    Q_PROPERTY(int fontSize READ fontSize WRITE setFontSize NOTIFY fontSizeChanged)
+    Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
+	
+	signals:
+		void fontSizeChanged(int size);
+		void colorChanged(QColor color);
 
 	public:
 		DiagramTextItem(QGraphicsItem * = 0);
@@ -42,7 +49,7 @@
 	
 	public:
 		enum { Type = UserType + 1004 };
-		virtual int type() const { return Type; }
+		virtual int type() const override { return Type; }
 
 		Diagram *diagram() const;
 		virtual void fromXml(const QDomElement &) = 0;
@@ -57,35 +64,43 @@
 		QPointF mapMovementToParent   (const QPointF &) const;
 		QPointF mapMovementFromParent (const QPointF &) const;
 
-		void setFontSize(int &s);
-		void setNoEditable(bool e = true) {no_editable = e;}
+		void setFontSize(int s);
+        int fontSize()const;
+        
+        void setColor(QColor color);
+        QColor color() const;
+        
+		void setNoEditable(bool e = true) {m_no_editable = e;}
 
 	protected:
-		virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
-		virtual void focusInEvent(QFocusEvent *);
-		virtual void focusOutEvent(QFocusEvent *);
+		virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) override;
+		virtual void focusInEvent(QFocusEvent *) override;
+		virtual void focusOutEvent(QFocusEvent *) override;
 
-		virtual void mouseDoubleClickEvent (QGraphicsSceneMouseEvent *event);
-		virtual void mousePressEvent       (QGraphicsSceneMouseEvent *event);
-		virtual void mouseMoveEvent        (QGraphicsSceneMouseEvent *event);
-		virtual void mouseReleaseEvent     (QGraphicsSceneMouseEvent *event);
+		virtual void mouseDoubleClickEvent (QGraphicsSceneMouseEvent *event) override;
+		virtual void mousePressEvent       (QGraphicsSceneMouseEvent *event) override;
+		virtual void mouseMoveEvent        (QGraphicsSceneMouseEvent *event) override;
+		virtual void mouseReleaseEvent     (QGraphicsSceneMouseEvent *event) override;
 
-		virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *);
-		virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *);
-		virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *);
+		virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *) override;
+		virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *) override;
+		virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *) override;
 
 		virtual void applyRotation(const qreal &);
 
 	signals:
-			/// signal emitted after text was changed
 		void diagramTextChanged(DiagramTextItem *, const QString &, const QString &);
+		void textEdited(const QString &old_str, const QString &new_str);
 	
 	protected:
-		bool m_mouse_hover;
-		QString previous_text_;
-		qreal rotation_angle_;
-		bool no_editable;
-		bool m_first_move;
+		bool m_mouse_hover = false,
+			 m_first_move = true,
+		     m_no_editable;
+
+		QString m_previous_html_text,
+				m_previous_text;
+		
+		qreal m_rotation_angle;
 		QPointF m_mouse_to_origin_movement;
 };
 #endif

Added: trunk/sources/qetgraphicsitem/dynamicelementtextitem.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/dynamicelementtextitem.cpp	                        (rev 0)
+++ trunk/sources/qetgraphicsitem/dynamicelementtextitem.cpp	2017-08-03 17:36:08 UTC (rev 5005)
@@ -0,0 +1,255 @@
+/*
+	Copyright 2006-2017 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 "dynamicelementtextitem.h"
+#include "qet.h"
+#include "element.h"
+#include "qetapp.h"
+#include "diagram.h"
+#include "QPropertyUndoCommand/qpropertyundocommand.h"
+
+#include <QDomDocument>
+#include <QDomElement>
+#include <QGraphicsSceneMouseEvent>
+
+/**
+ * @brief DynamicElementTextItem::DynamicElementTextItem
+ * Constructor
+ * @param parent_element
+ */
+DynamicElementTextItem::DynamicElementTextItem(Element *parent_element) :
+	m_parent_element(parent_element),
+	m_uuid(QUuid::createUuid())
+{
+	setFont(QETApp::diagramTextsFont(9));
+	setText(tr("Texte"));
+    setParentItem(parent_element);
+	
+	connect(this, &DynamicElementTextItem::textEdited, [this](const QString &old_str, const QString &new_str)
+	{
+		if(this->m_parent_element && this->m_parent_element->diagram())
+		{
+			QUndoCommand *undo = new QPropertyUndoCommand(this, "text", old_str, new_str);
+			undo->setText(tr("Éditer un texte d'élément"));
+			this->m_parent_element->diagram()->undoStack().push(undo);
+		}
+		
+	});
+}
+
+DynamicElementTextItem::~DynamicElementTextItem()
+{}
+
+/**
+ * @brief DynamicElementTextItem::toXml
+ * Export this text to xml
+ * @param dom_doc
+ * @return 
+ */
+QDomElement DynamicElementTextItem::toXml(QDomDocument &dom_doc) const
+{
+	QDomElement root_element = dom_doc.createElement(xmlTaggName());
+	
+	root_element.setAttribute("x", QString::number(pos().x()));
+	root_element.setAttribute("y", QString::number(pos().y()));
+	root_element.setAttribute("rotation", QString::number(QET::correctAngle(rotation())));
+	root_element.setAttribute("font_size", font().pointSize());
+	root_element.setAttribute("uuid", m_uuid.toString());
+	
+	QMetaEnum me = metaObject()->enumerator(metaObject()->indexOfEnumerator("TextFrom"));
+	root_element.setAttribute("text_from", me.valueToKey(m_text_from));
+	
+    QDomElement dom_text = dom_doc.createElement("text");
+    dom_text.appendChild(dom_doc.createTextNode(toPlainText()));
+    root_element.appendChild(dom_text);
+    
+		//tagg
+	if (!m_tagg.isEmpty())
+	{
+		QDomElement dom_tagg = dom_doc.createElement("tagg");
+		dom_tagg.appendChild(dom_doc.createTextNode(m_tagg));
+		root_element.appendChild(dom_tagg);
+	}
+	
+		//Color
+	if(color() != QColor(Qt::black))
+	{
+		QDomElement dom_color = dom_doc.createElement("color");
+		dom_color.appendChild(dom_doc.createTextNode(color().name()));
+		root_element.appendChild(dom_color);
+	}
+    
+    return root_element;
+}
+
+/**
+ * @brief DynamicElementTextItem::fromXml
+ * Import this text from xml
+ * @param dom_elmt
+ */
+void DynamicElementTextItem::fromXml(const QDomElement &dom_elmt)
+{
+	if (dom_elmt.tagName() != xmlTaggName()) {
+		qDebug() << "DynamicElementTextItem::fromXml : Wrong tagg name";
+		return;
+	}
+	
+	QGraphicsTextItem::setPos(dom_elmt.attribute("x", QString::number(0)).toDouble(),
+							  dom_elmt.attribute("y", QString::number(0)).toDouble());
+	QGraphicsTextItem::setRotation(dom_elmt.attribute("rotation", QString::number(0)).toDouble());
+	setFont(QETApp::diagramTextsFont(dom_elmt.attribute("font_size", QString::number(9)).toInt()));
+	m_uuid = QUuid(dom_elmt.attribute("uuid", QUuid::createUuid().toString()));
+	
+	QMetaEnum me = metaObject()->enumerator(metaObject()->indexOfEnumerator("TextFrom"));
+	m_text_from = DynamicElementTextItem::TextFrom(me.keyToValue(dom_elmt.attribute("text_from").toStdString().data()));
+	setNoEditable(m_text_from == ElementInfo? true : false);
+
+		//Text
+    QDomElement dom_text = dom_elmt.firstChildElement("text");
+	if (!dom_text.isNull())
+        setPlainText(dom_text.text());
+    
+		//tagg
+    QDomElement dom_tagg = dom_elmt.firstChildElement("tagg");
+	if (!dom_tagg.isNull())
+		m_tagg = dom_tagg.text();
+
+		//Color
+	QDomElement dom_color = dom_elmt.firstChildElement("color");
+	if(!dom_color.isNull())
+		setColor(QColor(dom_color.text()));
+}
+
+/**
+ * @brief DynamicElementTextItem::ParentElement
+ * @return a pointer to the parent element. Note the pointer can be null.
+ */
+Element *DynamicElementTextItem::ParentElement() const {
+	return m_parent_element;
+}
+
+/**
+ * @brief DynamicElementTextItem::textFrom
+ * @return what the final text is created from.
+ */
+DynamicElementTextItem::TextFrom DynamicElementTextItem::textFrom() const {
+	return m_text_from;
+}
+
+/**
+ * @brief DynamicElementTextItem::setTextFrom
+ * Set the final text is created from.
+ * @param text_from
+ */
+void DynamicElementTextItem::setTextFrom(DynamicElementTextItem::TextFrom text_from)
+{
+	m_text_from = text_from;
+	setNoEditable(m_text_from == ElementInfo? true : false);
+	emit TextFromChanged(m_text_from);
+}
+
+/**
+ * @brief DynamicElementTextItem::tagg
+ * @return the tagg of this text
+ */
+QString DynamicElementTextItem::tagg() const {
+	return m_tagg;
+}
+
+/**
+ * @brief DynamicElementTextItem::setTagg
+ * set the taggof this text
+ * @param tagg
+ */
+void DynamicElementTextItem::setTagg(const QString &tagg)
+{
+	m_tagg = tagg;
+	emit taggChanged(m_tagg);
+}
+
+/**
+ * @brief DynamicElementTextItem::text
+ * @return the text of this text
+ */
+QString DynamicElementTextItem::text() const {
+	return m_text;
+}
+
+/**
+ * @brief DynamicElementTextItem::setText
+ * Set the text of this text
+ * @param formula
+ */
+void DynamicElementTextItem::setText(const QString &text)
+{
+	m_text = text;
+	setPlainText(m_text);
+	emit textChanged(m_text);
+}
+
+/**
+ * @brief DynamicElementTextItem::mouseMoveEvent
+ * @param event
+ */
+void DynamicElementTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+	if(event->buttons() & Qt::LeftButton)
+	{
+		QPointF old_pos = pos(); //The old pos
+		QPointF movement = event->pos() - event->buttonDownPos(Qt::LeftButton); //The movement since the button down pos
+		QPointF new_pos = pos() + mapMovementToParent(movement); //The new pos with this event
+		event->modifiers() == Qt::ControlModifier ? setPos(new_pos) : setPos(Diagram::snapToGrid(new_pos));
+		
+		if(m_parent_element && m_parent_element->diagram())
+		{
+			Diagram *diagram = m_parent_element->diagram();
+			
+			if(m_first_move)
+			{
+				if(diagram->beginMoveElementTexts(this) == 1)
+					m_parent_element->setHighlighted(true);
+			}
+			
+				//Because setPos() can be snaped to grid or not, we calcule the real movement
+			QPointF effective_movement = pos() - old_pos;
+			QPointF scene_effective_movement = mapMovementToScene(mapMovementFromParent(effective_movement));
+			diagram->continueMoveElementTexts(scene_effective_movement);
+		}
+	}
+	else
+		event->ignore();
+		
+	if(m_first_move)
+		m_first_move = false;
+}
+
+/**
+ * @brief DynamicElementTextItem::mouseReleaseEvent
+ * @param event
+ */
+void DynamicElementTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+	if (m_parent_element)
+		m_parent_element->setHighlighted(false);
+	
+	if(m_parent_element && m_parent_element->diagram())
+		m_parent_element->diagram()->endMoveElementTexts();
+	
+	if(!(event->modifiers() & Qt::ControlModifier))
+		QGraphicsTextItem::mouseReleaseEvent(event);
+}
+

Added: trunk/sources/qetgraphicsitem/dynamicelementtextitem.h
===================================================================
--- trunk/sources/qetgraphicsitem/dynamicelementtextitem.h	                        (rev 0)
+++ trunk/sources/qetgraphicsitem/dynamicelementtextitem.h	2017-08-03 17:36:08 UTC (rev 5005)
@@ -0,0 +1,87 @@
+/*
+	Copyright 2006-2017 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 DYNAMICELEMENTTEXTITEM_H
+#define DYNAMICELEMENTTEXTITEM_H
+
+#include "diagramtextitem.h"
+#include <QUuid>
+
+class Element;
+
+/**
+ * @brief The DynamicElementTextItem class
+ * This class provide a simple text field of element who can be added or removed directly from the diagram editor.
+ * This text is created to compensate a big lack of the ElementTextItem : ElementTextItem can't be added or removed directly in the diagram editor
+ * 
+ */
+class DynamicElementTextItem : public DiagramTextItem
+{
+    Q_OBJECT
+    
+	Q_PROPERTY(QString tagg READ tagg WRITE setTagg NOTIFY taggChanged)
+	Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
+	Q_PROPERTY(TextFrom textFrom READ textFrom WRITE setTextFrom NOTIFY TextFromChanged)
+	
+	public:
+		Q_ENUMS(TextFrom)
+		enum TextFrom {
+			UserText,
+			ElementInfo
+		};
+		enum {Type = UserType + 1010};
+		virtual int type() const override {return Type;}
+		
+	signals:
+		void taggChanged(QString tagg);
+		void textChanged(QString text);
+		void TextFromChanged(DynamicElementTextItem::TextFrom text_from);
+	
+	public:
+		DynamicElementTextItem(Element *parent_element);
+		virtual ~DynamicElementTextItem() override;
+	private:
+		DynamicElementTextItem(const DynamicElementTextItem &);
+		
+	public:
+		virtual QDomElement toXml(QDomDocument &dom_doc) const override;
+		virtual void fromXml(const QDomElement &dom_elmt) override;
+		
+		Element *ParentElement() const;
+		
+		DynamicElementTextItem::TextFrom textFrom() const;
+		void setTextFrom (DynamicElementTextItem::TextFrom text_from);
+		QString tagg() const;
+		void setTagg(const QString &tagg);
+		QString text() const;
+		void setText(const QString &text);
+        static QString xmlTaggName() {return QString("dynamic_elmt_text");}
+		
+	protected:
+		virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
+		virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
+		
+	private:
+		Element *m_parent_element = nullptr;
+		QString m_tagg,
+				m_text,
+				m_elmt_info_name;
+		DynamicElementTextItem::TextFrom m_text_from = UserText;
+		QUuid m_uuid;		
+};
+
+#endif // DYNAMICELEMENTTEXTITEM_H

Modified: trunk/sources/qetgraphicsitem/element.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/element.cpp	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/qetgraphicsitem/element.cpp	2017-08-03 17:36:08 UTC (rev 5005)
@@ -29,6 +29,7 @@
 #include "numerotationcontextcommands.h"
 #include "diagramcontext.h"
 #include "changeelementinformationcommand.h"
+#include "dynamicelementtextitem.h"
 
 class ElementXmlRetroCompatibility
 {
@@ -77,7 +78,9 @@
 /**
 	Destructeur
 */
-Element::~Element() {
+Element::~Element()
+{
+    qDeleteAll(m_dynamic_text_list);
 }
 
 void Element::editProperty()
@@ -529,6 +532,15 @@
 	} else {
 		applyRotation(90*read_ori);
 	}
+    
+        //Dynamic texts
+    for (QDomElement qde : QET::findInDomElement(e, "dynamic_texts", DynamicElementTextItem::xmlTaggName()))
+    {
+        DynamicElementTextItem *deti = new DynamicElementTextItem(this);
+        addDynamicTextItem(deti);
+        deti->fromXml(qde);
+    }
+    
 	return(true);
 }
 
@@ -608,17 +620,62 @@
 		element.appendChild(links_uuids);
 	}
 
-	//save information of this element
+        //save information of this element
 	if (! m_element_informations.keys().isEmpty()) {
 		QDomElement infos = document.createElement("elementInformations");
 		m_element_informations.toXml(infos, "elementInformation");
 		element.appendChild(infos);
 	}
+    
+        //Dynamic texts
+    QDomElement dyn_text = document.createElement("dynamic_texts");
+    for (DynamicElementTextItem *deti : m_dynamic_text_list)
+        dyn_text.appendChild(deti->toXml(document));
+    element.appendChild(dyn_text);
 
-	return(element);
+    return(element);
 }
 
 /**
+ * @brief Element::addDynamiqueTextItem
+ * Add @deti as a dynamic text item of this element
+ * If @deti is null, a new DynamicElementTextItem is created and added to this element.
+ * @param deti
+ */
+void Element::addDynamicTextItem(DynamicElementTextItem *deti)
+{
+    if (deti && !m_dynamic_text_list.contains(deti))
+	{
+        m_dynamic_text_list.append(deti);
+	}
+    else
+    {
+        DynamicElementTextItem *text = new DynamicElementTextItem(this);
+        m_dynamic_text_list.append(text);
+    }
+}
+
+/**
+ * @brief Element::removeDynamicTextItem
+ * Remove @deti as dynamic text item of this element.
+ * The parent item of deti stay this item.
+ * @param deti
+ */
+void Element::removeDynamicTextItem(DynamicElementTextItem *deti)
+{
+    if (m_dynamic_text_list.contains(deti))
+        m_dynamic_text_list.removeOne(deti);
+}
+
+/**
+ * @brief Element::dynamicTextItems
+ * @return all dynamic text items of this element
+ */
+QList<DynamicElementTextItem *> Element::dynamicTextItems() const {
+    return m_dynamic_text_list;
+}
+
+/**
  * @brief Element::AlignedFreeTerminals
  * @return a list of terminal (owned by this element) aligned to other terminal (from other element)
  * The first Terminal of QPair is a Terminal owned by this element,

Modified: trunk/sources/qetgraphicsitem/element.h
===================================================================
--- trunk/sources/qetgraphicsitem/element.h	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/qetgraphicsitem/element.h	2017-08-03 17:36:08 UTC (rev 5005)
@@ -30,6 +30,7 @@
 class Conductor;
 class NumerotationContext;
 class DiagramTextItem;
+class DynamicElementTextItem;
 
 /**
 	This is the base class for electrical elements.
@@ -158,9 +159,6 @@
 		bool m_freeze_label = false;
 		QString m_F_str;
 
-	/**
-		Draw this element
-	*/
 	public:
 		virtual void paint(QPainter *, const QStyleOptionGraphicsItem *) = 0;
 		/// @return This element type ID
@@ -177,26 +175,30 @@
 		QSize size() const;
 		QPixmap pixmap();
 	
-	// methods related to the hotspot
-	QPoint setHotspot(QPoint);
-	QPoint hotspot() const;
-	
-	// selection-related methods
-	void select();
-	void deselect();
-	
-	virtual void rotateBy(const qreal &);
-	virtual void editProperty();
-	
-	// methods related to XML import/export
-	static bool valideXml(QDomElement &);
-	virtual bool fromXml(QDomElement &, QHash<int, Terminal *> &, bool = false);
-	virtual QDomElement toXml(QDomDocument &, QHash<Terminal *, int> &) const;
-	QUuid uuid() const;
+            // methods related to the hotspot
+        QPoint setHotspot(QPoint);
+        QPoint hotspot() const;
+        
+            // selection-related methods
+        void select();
+        void deselect();
+        
+        virtual void rotateBy(const qreal &);
+        virtual void editProperty();
+        
+            // methods related to XML import/export
+        static bool valideXml(QDomElement &);
+        virtual bool fromXml(QDomElement &, QHash<int, Terminal *> &, bool = false);
+        virtual QDomElement toXml(QDomDocument &, QHash<Terminal *, int> &) const;
+        QUuid uuid() const;
+        
+            // orientation-related methods
+        int orientation() const;
+        
+        void addDynamicTextItem(DynamicElementTextItem *deti = nullptr);
+        void removeDynamicTextItem(DynamicElementTextItem *deti);
+        QList<DynamicElementTextItem *> dynamicTextItems() const;
 
-	// orientation-related methods
-	int orientation() const;
-
 	protected:
 		void drawAxes(QPainter *, const QStyleOptionGraphicsItem *);
 	
@@ -216,6 +218,7 @@
 	private:
 		bool m_mouse_over;
 		QString m_prefix;
+        QList <DynamicElementTextItem *> m_dynamic_text_list;
 
 };
 

Modified: trunk/sources/ui/diagrampropertieseditordockwidget.cpp
===================================================================
--- trunk/sources/ui/diagrampropertieseditordockwidget.cpp	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/ui/diagrampropertieseditordockwidget.cpp	2017-08-03 17:36:08 UTC (rev 5005)
@@ -23,6 +23,7 @@
 #include "imagepropertieswidget.h"
 #include "qetshapeitem.h"
 #include "shapegraphicsitempropertieswidget.h"
+#include "dynamicelementtextitem.h"
 
 /**
  * @brief DiagramPropertiesEditorDockWidget::DiagramPropertiesEditorDockWidget
@@ -56,7 +57,7 @@
 	if (diagram)
 	{
 		m_diagram = diagram;
-		connect(m_diagram, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
+		connect(m_diagram, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()), Qt::QueuedConnection);
 		connect(m_diagram, SIGNAL(destroyed()),        this, SLOT(diagramWasDeleted()));
 		selectionChanged();
 	}
@@ -119,6 +120,22 @@
 			m_edited_qgi_type = type_;
 			addEditor(new ShapeGraphicsItemPropertiesWidget(static_cast<QetShapeItem*>(item), this));
 			break; }
+			
+		case DynamicElementTextItem::Type: {
+			DynamicElementTextItem *deti = static_cast<DynamicElementTextItem *>(item);
+			
+				//For dynamic element text, we open the element editor
+				//We already edit an element, just update the editor with a new element
+			if (m_edited_qgi_type == Element::Type)
+			{
+				static_cast<ElementPropertiesWidget*>(editors().first())->setElement(deti->ParentElement());
+				return;
+			}
+			
+			clear();
+			m_edited_qgi_type = Element::Type;
+			addEditor(new ElementPropertiesWidget(deti->ParentElement(), this));
+			break; }
 
 		default:
 			m_edited_qgi_type = -1;

Added: trunk/sources/ui/dynamicelementtextitemeditor.cpp
===================================================================
--- trunk/sources/ui/dynamicelementtextitemeditor.cpp	                        (rev 0)
+++ trunk/sources/ui/dynamicelementtextitemeditor.cpp	2017-08-03 17:36:08 UTC (rev 5005)
@@ -0,0 +1,152 @@
+/*
+	Copyright 2006-2017 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 "dynamicelementtextitemeditor.h"
+#include "ui_dynamicelementtextitemeditor.h"
+#include "dynamicelementtextitem.h"
+#include "element.h"
+#include "dynamicelementtextmodel.h"
+#include "diagram.h"
+#include "undocommand/deleteqgraphicsitemcommand.h"
+#include "undocommand/addelementtextcommand.h"
+
+#include <QTreeView>
+#include <QUndoCommand>
+
+DynamicElementTextItemEditor::DynamicElementTextItemEditor(Element *element, QWidget *parent) :
+    AbstractElementPropertiesEditorWidget(parent),
+    ui(new Ui::DynamicElementTextItemEditor)
+{
+    ui->setupUi(this);
+    m_tree_view = new QTreeView(this);
+    m_tree_view->header()->setDefaultSectionSize(150);
+    m_tree_view->setItemDelegate(new DynamicTextItemDelegate(m_tree_view));
+	m_tree_view->setAlternatingRowColors(true);
+    ui->verticalLayout->addWidget(m_tree_view);
+    setElement(element);
+}
+
+DynamicElementTextItemEditor::~DynamicElementTextItemEditor()
+{
+	delete ui;
+}
+
+void DynamicElementTextItemEditor::setElement(Element *element)
+{
+    if (m_element == element)
+        return;
+    
+     m_element = element;
+    
+    DynamicElementTextModel *old_model = m_model;
+    m_model = new DynamicElementTextModel(m_tree_view);
+	connect(m_model, &DynamicElementTextModel::itemChanged, this, &DynamicElementTextItemEditor::dataEdited);
+    
+    for (DynamicElementTextItem *deti : m_element->dynamicTextItems())
+        m_model->addText(deti);
+    
+    m_tree_view->setModel(m_model);
+    
+    if(old_model)
+		delete old_model;
+}
+
+bool DynamicElementTextItemEditor::setLiveEdit(bool live_edit)
+{
+	m_live_edit = live_edit;
+	return true;
+}
+
+void DynamicElementTextItemEditor::apply()
+{
+	QList <QUndoCommand *> undo_list;
+	for (DynamicElementTextItem *deti : m_element->dynamicTextItems())
+	{
+		QUndoCommand *undo = m_model->undoForEditedText(deti);
+		if(undo->childCount())
+			undo_list << undo;
+		else
+			delete undo;
+	}
+	
+	for (DynamicElementTextItem *deti : m_element->dynamicTextItems())
+		deti->blockSignals(true);
+	
+	if(!undo_list.isEmpty() && m_element->diagram())
+	{
+		if (undo_list.size() == 1)
+			m_element->diagram()->undoStack().push(undo_list.first());
+		else
+		{
+			QUndoStack &us = m_element->diagram()->undoStack();
+			us.beginMacro(tr("Modifier des texte d'élément"));
+			for (QUndoCommand *quc : undo_list)
+				us.push(quc);
+			us.endMacro();
+		}
+	}
+	
+	for (DynamicElementTextItem *deti : m_element->dynamicTextItems())
+		deti->blockSignals(false);
+}
+
+void DynamicElementTextItemEditor::dataEdited(QStandardItem *qsi)
+{
+	Q_UNUSED(qsi)
+	if (m_live_edit)
+		apply();
+}
+
+/**
+ * @brief DynamicElementTextItemEditor::on_m_add_text_clicked
+ * Add a new dynamic text
+ */
+void DynamicElementTextItemEditor::on_m_add_text_clicked()
+{
+    if (!m_element)
+        return;
+	
+    DynamicElementTextItem *deti = new DynamicElementTextItem(m_element);
+	if (m_element->diagram())
+	{
+		m_element->diagram()->undoStack().push(new AddElementTextCommand(m_element, deti));
+		m_model->addText(deti);
+	}
+	else
+	{
+		delete deti;
+	}
+}
+
+/**
+ * @brief DynamicElementTextItemEditor::on_m_remove_text_clicked
+ * Remove the selected text field
+ */
+void DynamicElementTextItemEditor::on_m_remove_text_clicked()
+{
+    DynamicElementTextItem *deti = m_model->textFromIndex(m_tree_view->currentIndex());
+    if(deti)
+    {
+		if(m_element->diagram())
+		{
+			DiagramContent dc;
+			dc.m_element_texts << deti;
+			m_element->diagram()->undoStack().push(new DeleteQGraphicsItemCommand(m_element->diagram(), dc));
+			m_model->removeText(deti);
+		}
+    }
+}

Added: trunk/sources/ui/dynamicelementtextitemeditor.h
===================================================================
--- trunk/sources/ui/dynamicelementtextitemeditor.h	                        (rev 0)
+++ trunk/sources/ui/dynamicelementtextitemeditor.h	2017-08-03 17:36:08 UTC (rev 5005)
@@ -0,0 +1,59 @@
+/*
+	Copyright 2006-2017 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 DYNAMICELEMENTTEXTITEMEDITOR_H
+#define DYNAMICELEMENTTEXTITEMEDITOR_H
+
+#include "abstractelementpropertieseditorwidget.h"
+
+class DynamicElementTextItem;
+class DynamicElementTextModel;
+class QTreeView;
+class QStandardItem;
+
+namespace Ui {
+	class DynamicElementTextItemEditor;
+}
+
+class DynamicElementTextItemEditor : public AbstractElementPropertiesEditorWidget
+{
+    Q_OBJECT
+    
+	public:
+	   explicit DynamicElementTextItemEditor(Element *element, QWidget *parent = 0);
+		~DynamicElementTextItemEditor();
+	
+		virtual void setElement(Element *element);
+        virtual QString title() const {return tr("Textes");}
+		virtual bool setLiveEdit(bool live_edit);
+		virtual void apply();
+	
+	private:
+		void dataEdited(QStandardItem *qsi);
+    
+    private slots:
+        void on_m_add_text_clicked();
+        void on_m_remove_text_clicked();
+        
+    private:
+		Ui::DynamicElementTextItemEditor *ui;
+        QTreeView *m_tree_view = nullptr;
+        DynamicElementTextModel *m_model = nullptr;
+        
+};
+
+#endif // DYNAMICELEMENTTEXTITEMEDITOR_H

Added: trunk/sources/ui/dynamicelementtextitemeditor.ui
===================================================================
--- trunk/sources/ui/dynamicelementtextitemeditor.ui	                        (rev 0)
+++ trunk/sources/ui/dynamicelementtextitemeditor.ui	2017-08-03 17:36:08 UTC (rev 5005)
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DynamicElementTextItemEditor</class>
+ <widget class="QWidget" name="DynamicElementTextItemEditor">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="m_add_text">
+       <property name="text">
+        <string/>
+       </property>
+       <property name="icon">
+        <iconset resource="../../qelectrotech.qrc">
+         <normaloff>:/ico/16x16/list-add.png</normaloff>:/ico/16x16/list-add.png</iconset>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="m_remove_text">
+       <property name="text">
+        <string/>
+       </property>
+       <property name="icon">
+        <iconset resource="../../qelectrotech.qrc">
+         <normaloff>:/ico/16x16/list-remove.png</normaloff>:/ico/16x16/list-remove.png</iconset>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="../../qelectrotech.qrc"/>
+ </resources>
+ <connections/>
+</ui>

Added: trunk/sources/ui/dynamicelementtextmodel.cpp
===================================================================
--- trunk/sources/ui/dynamicelementtextmodel.cpp	                        (rev 0)
+++ trunk/sources/ui/dynamicelementtextmodel.cpp	2017-08-03 17:36:08 UTC (rev 5005)
@@ -0,0 +1,407 @@
+/*
+	Copyright 2006-2017 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 "dynamicelementtextmodel.h"
+#include "dynamicelementtextitem.h"
+#include <QStandardItem>
+#include <QHash>
+#include <QColorDialog>
+#include <QModelIndex>
+#include <QComboBox>
+#include <QUndoCommand>
+#include "QPropertyUndoCommand/qpropertyundocommand.h"
+
+DynamicElementTextModel::DynamicElementTextModel(QObject *parent) :
+QStandardItemModel(parent)
+{
+    setColumnCount(2);
+    setHeaderData(0, Qt::Horizontal, tr("Propriété"), Qt::DisplayRole);
+    setHeaderData(1, Qt::Horizontal, tr("Valeur"), Qt::DisplayRole);
+    
+    connect(this, &DynamicElementTextModel::itemChanged, this, &DynamicElementTextModel::dataEdited);
+}
+
+DynamicElementTextModel::~DynamicElementTextModel()
+{
+		//Connection is not destroy automaticaly,
+		//because was not connected to a slot, but a lambda
+	for(DynamicElementTextItem *deti : m_hash_text_connect.keys())
+		setConnection(deti, false);
+}
+
+/**
+ * @brief DynamicElementTextModel::addText
+ * @param deti
+ */
+void DynamicElementTextModel::addText(DynamicElementTextItem *deti)
+{
+    if(m_texts_list.keys().contains(deti))
+        return;
+    
+    QList <QStandardItem *> qsi_list;
+    
+	QStandardItem *qsi = new QStandardItem(deti->toPlainText());
+    qsi->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+	
+	
+        //Source of text
+    QStandardItem *src = new QStandardItem(tr("Source du texte"));
+    src->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+    
+    QStandardItem *srca = new QStandardItem(deti->textFrom() == DynamicElementTextItem::UserText ? tr("Texte utilisateur") : tr("Information de l'élément"));
+    srca->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
+    srca->setData(textFrom, Qt::UserRole+1);
+    
+    qsi_list << src << srca;
+    qsi->appendRow(qsi_list);
+	
+		//User text
+	QStandardItem *usr = new QStandardItem(tr("Texte"));
+    usr->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+    
+    QStandardItem *usra = new QStandardItem(deti->toPlainText());
+    usra->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
+    usra->setData(DynamicElementTextModel::userText, Qt::UserRole+1);
+   
+	qsi_list.clear();
+    qsi_list << usr << usra;
+    src->appendRow(qsi_list);
+	
+		//Info text
+	QStandardItem *info = new QStandardItem(tr("Information"));
+    info->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+    
+    QStandardItem *infoa = new QStandardItem(deti->toPlainText());
+    infoa->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
+    infoa->setData(DynamicElementTextModel::infoText, Qt::UserRole+1);
+    
+	qsi_list.clear();
+    qsi_list << info << infoa;
+    src->appendRow(qsi_list);
+
+    
+        //Size
+	QStandardItem *size = new QStandardItem(tr("Taille"));
+    size->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+    
+    QStandardItem *siza = new QStandardItem();
+    siza->setData(deti->fontSize(), Qt::EditRole);
+    siza->setData(DynamicElementTextModel::size, Qt::UserRole+1);
+    siza->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
+    
+    qsi_list.clear();
+    qsi_list << size << siza;
+	qsi->appendRow(qsi_list);
+    
+        //Tagg
+    QStandardItem *tagg = new QStandardItem(tr("Tagg"));
+    tagg->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+    
+    QStandardItem *tagga = new QStandardItem(deti->tagg());
+    tagga->setData(DynamicElementTextModel::tagg, Qt::UserRole+1);
+    tagga->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
+    
+    qsi_list.clear();
+    qsi_list << tagg << tagga;
+	qsi->appendRow(qsi_list);
+    
+        //Color
+    QStandardItem *color = new QStandardItem(tr("Couleur"));
+    color->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+    
+    QStandardItem *colora = new QStandardItem;
+    colora->setData(deti->color(), Qt::ForegroundRole);
+    colora->setData(deti->color(), Qt::EditRole);
+    colora->setData(DynamicElementTextModel::color, Qt::UserRole+1);
+    colora->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
+    
+    qsi_list.clear();
+    qsi_list << color << colora;
+	qsi->appendRow(qsi_list);
+    
+	qsi_list.clear();
+	QStandardItem *empty_qsi = new QStandardItem(0);
+	empty_qsi->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+	qsi_list << qsi << empty_qsi;
+    this->appendRow(qsi_list);
+	
+    m_texts_list.insert(deti, qsi);
+	blockSignals(true);
+	enableSourceText(deti, deti->textFrom());
+	blockSignals(false);
+	setConnection(deti, true);
+}
+
+/**
+ * @brief DynamicElementTextModel::removeText
+ * @param deti
+ */
+void DynamicElementTextModel::removeText(DynamicElementTextItem *deti)
+{
+	if (!m_texts_list.contains(deti))
+        return;
+    
+    QModelIndex text_index = m_texts_list.value(deti)->index();
+    this->removeRow(text_index.row(), text_index.parent());
+    m_texts_list.remove(deti);
+	setConnection(deti, false);
+}
+
+/**
+ * @brief DynamicElementTextModel::textFromIndex
+ * @param index
+ * @return the text associated with @index. Return value can be nullptr
+ * @Index can be a child of an index associated with a text
+ */
+DynamicElementTextItem *DynamicElementTextModel::textFromIndex(const QModelIndex &index) const
+{
+    if(!index.isValid())
+        return nullptr;
+    
+    if (QStandardItem *item = itemFromIndex(index))
+        return textFromItem(item);
+    else
+        return nullptr;
+}
+
+/**
+ * @brief DynamicElementTextModel::textFromItem
+ * @param item
+ * @return the text associated with @item. Return value can be nullptr
+ * @item can be a child of an item associated with a text
+ */
+DynamicElementTextItem *DynamicElementTextModel::textFromItem(QStandardItem *item) const
+{
+	QStandardItem *text_item = item;
+	while (text_item->parent())
+		text_item = text_item->parent();
+	
+	if (m_texts_list.values().contains(text_item))
+		return m_texts_list.key(text_item);
+	else
+		return nullptr;
+}
+
+/**
+ * @brief DynamicElementTextModel::undoForEditedText
+ * @param deti
+ * @return A QUndoCommand that describe all changes made for @deti.
+ * Each change made for @deti is append as a child of the returned QUndoCommand.
+ * In other word, if the returned QUndoCommand have no child, that mean there is no change.
+ */
+QUndoCommand *DynamicElementTextModel::undoForEditedText(DynamicElementTextItem *deti) const
+{
+	QUndoCommand *undo = new QUndoCommand(tr("Éditer un texte d'élément"));
+	
+	if (!m_texts_list.contains(deti))
+		return undo;
+	
+	QStandardItem *text_qsi = m_texts_list.value(deti);
+	
+	QString from = text_qsi->child(0,1)->data(Qt::DisplayRole).toString();
+	if ((from == tr("Texte utilisateur")) && (deti->textFrom() != DynamicElementTextItem::UserText))
+		new QPropertyUndoCommand(deti, "textFrom", QVariant(deti->textFrom()), QVariant(DynamicElementTextItem::UserText), undo);
+	else if ((from == tr("Information de l'élément")) && (deti->textFrom() != DynamicElementTextItem::ElementInfo))
+		new QPropertyUndoCommand(deti, "textFrom", QVariant(deti->textFrom()), QVariant(DynamicElementTextItem::ElementInfo), undo);
+	
+	QString text = text_qsi->child(0,0)->child(0,1)->data(Qt::DisplayRole).toString();
+	if (text != deti->text())
+		new QPropertyUndoCommand(deti, "text", QVariant(deti->text()), QVariant(text), undo);
+	
+	int fs = text_qsi->child(1,1)->data(Qt::EditRole).toInt();
+	if (fs != deti->fontSize()) 
+		new QPropertyUndoCommand(deti, "fontSize", QVariant(deti->fontSize()), QVariant(fs), undo);
+	
+	QString tagg = text_qsi->child(2,1)->data(Qt::DisplayRole).toString();
+	if(tagg != deti->tagg())
+		new QPropertyUndoCommand(deti, "tagg", QVariant(deti->tagg()), QVariant(tagg), undo);
+	
+	QColor color = text_qsi->child(3,1)->data(Qt::EditRole).value<QColor>();
+	if(color != deti->color())
+		new QPropertyUndoCommand(deti, "color", QVariant(deti->color()), QVariant(color), undo);
+	
+	return undo;
+}
+
+/**
+ * @brief DynamicElementTextModel::enableSourceText
+ * Enable the good field, according to the current source of text, for the edited text @deti
+ * @param deti
+ * @param tf
+ */
+void DynamicElementTextModel::enableSourceText(DynamicElementTextItem *deti, DynamicElementTextItem::TextFrom tf)
+{
+	if (!m_texts_list.contains(deti))
+		return;
+	
+	QStandardItem *qsi = m_texts_list.value(deti)->child(0,0);
+	
+	bool usr = true, info = false;
+	if(tf == DynamicElementTextItem::ElementInfo) {
+		usr = false; info = true;}
+	
+		//User text
+	qsi->child(0,0)->setEnabled(usr);
+	qsi->child(0,1)->setEnabled(usr);
+		//Info text
+	qsi->child(1,0)->setEnabled(info);
+	qsi->child(1,1)->setEnabled(info);
+}
+
+void DynamicElementTextModel::dataEdited(QStandardItem *qsi)
+{
+	DynamicElementTextItem *deti = textFromItem(qsi);
+	if (!deti)
+		return;
+	
+	if (qsi->data().toInt() == textFrom)
+	{
+		QString from = qsi->data(Qt::DisplayRole).toString();
+		if (from == tr("Texte utilisateur"))
+			enableSourceText(deti, DynamicElementTextItem::UserText);
+		else
+			enableSourceText(deti, DynamicElementTextItem::ElementInfo);
+	}
+	else if (qsi->data().toInt() == userText)
+	{
+		QString text = qsi->data(Qt::DisplayRole).toString();
+		m_texts_list.value(deti)->setData(text, Qt::DisplayRole);
+	}
+}
+
+/**
+ * @brief DynamicElementTextModel::setConnection
+ * Set up the connection for @deti to keep up to date the data of this model and the text.
+ * Is notably use with the use of QUndoCommand.
+ * @param deti - text to setup connection
+ * @param set - true = set connection - false unset connection
+ */
+void DynamicElementTextModel::setConnection(DynamicElementTextItem *deti, bool set)
+{
+	if(set)
+	{
+		if(m_hash_text_connect.keys().contains(deti))
+			return;
+		
+		QList<QMetaObject::Connection> connection_list;
+		connection_list << connect(deti, &DynamicElementTextItem::colorChanged,    [deti,this](){this->updateDataFromText(deti, color);});
+		connection_list << connect(deti, &DynamicElementTextItem::fontSizeChanged, [deti,this](){this->updateDataFromText(deti, size);});
+		connection_list << connect(deti, &DynamicElementTextItem::taggChanged,     [deti,this](){this->updateDataFromText(deti, tagg);});
+		connection_list << connect(deti, &DynamicElementTextItem::textChanged,     [deti,this](){this->updateDataFromText(deti, userText);});
+		connection_list << connect(deti, &DynamicElementTextItem::TextFromChanged, [deti,this](){this->updateDataFromText(deti, textFrom);});
+		
+		m_hash_text_connect.insert(deti, connection_list);
+	}
+	else
+	{
+		if(!m_hash_text_connect.keys().contains(deti))
+			return;
+		
+		for (QMetaObject::Connection con : m_hash_text_connect.value(deti))
+			disconnect(con);
+		
+		m_hash_text_connect.remove(deti);
+	}
+}
+
+void DynamicElementTextModel::updateDataFromText(DynamicElementTextItem *deti, ValueType type)
+{
+	QStandardItem *qsi = m_texts_list.value(deti);
+	if (!qsi)
+		return;
+	
+	switch (type)
+	{
+		case textFrom:
+			qsi->child(0,1)->setData(deti->textFrom() == DynamicElementTextItem::UserText ? tr("Texte utilisateur") : tr("Information de l'élément"), Qt::DisplayRole);
+			break;
+		case userText:
+		{
+			QStandardItem *qsia = qsi->child(0,0);
+			qsia->child(0,1)->setData(deti->toPlainText(), Qt::DisplayRole);
+			qsi->setData(deti->toPlainText(), Qt::DisplayRole);
+			break;
+		}
+		case infoText:
+			break;
+		case size:
+			qsi->child(1,1)->setData(deti->fontSize(), Qt::EditRole);
+			break;
+		case tagg:
+			qsi->child(2,1)->setData(deti->tagg(), Qt::DisplayRole);
+			break;
+		case color:
+		{
+			qsi->child(3,1)->setData(deti->color(), Qt::EditRole);
+			qsi->child(3,1)->setData(deti->color(), Qt::ForegroundRole);
+			break;
+		}
+	}
+}
+
+
+/***************************************************
+ * A little delegate only for add a combobox and a color dialog,
+ * for use with the model
+ ***************************************************/
+
+DynamicTextItemDelegate::DynamicTextItemDelegate(QObject *parent) :
+    QStyledItemDelegate(parent)
+{}
+
+QWidget *DynamicTextItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+	switch (index.data(Qt::UserRole+1).toInt())
+	{
+		case DynamicElementTextModel::textFrom:
+		{
+			QComboBox *qcb = new QComboBox(parent);
+			qcb->addItem(tr("Texte utilisateur"));
+			qcb->addItem(tr("Information de l'élément"));
+			return qcb;
+		}
+		case DynamicElementTextModel::color:
+		{
+			QColorDialog *cd = new QColorDialog(index.data(Qt::EditRole).value<QColor>());
+			return cd;
+		}
+	}
+	return QStyledItemDelegate::createEditor(parent, option, index);
+}
+
+void DynamicTextItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
+{
+	if (index.isValid())
+	{        
+		if (QStandardItemModel *qsim = dynamic_cast<QStandardItemModel *>(model))
+		{
+			QStandardItem *qsi = qsim->itemFromIndex(index);
+			if(qsi)
+			{
+				if(QColorDialog *cd = dynamic_cast<QColorDialog *> (editor))
+				{
+					qsi->setData(cd->selectedColor(), Qt::EditRole);
+					qsi->setData(cd->selectedColor(), Qt::ForegroundRole);
+					return;
+				}
+			}
+			
+		}
+	}
+	
+	QStyledItemDelegate::setModelData(editor, model, index);
+}

Added: trunk/sources/ui/dynamicelementtextmodel.h
===================================================================
--- trunk/sources/ui/dynamicelementtextmodel.h	                        (rev 0)
+++ trunk/sources/ui/dynamicelementtextmodel.h	2017-08-03 17:36:08 UTC (rev 5005)
@@ -0,0 +1,76 @@
+/*
+	Copyright 2006-2017 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 DYNAMICELEMENTTEXTMODEL_H
+#define DYNAMICELEMENTTEXTMODEL_H
+
+#include <QStandardItemModel>
+#include <qstyleditemdelegate.h>
+#include "dynamicelementtextitem.h"
+
+class QUndoCommand;
+
+/**
+ * @brief The DynamicElementTextModel class
+ * A model to use with QtView.
+ * This model display and can edit the value of dynamic text of an element.
+ * Set the delegate DynamicTextItemDelegate as delegate of this model.
+ */
+class DynamicElementTextModel : public QStandardItemModel
+{
+	Q_OBJECT
+	
+	public:
+        enum ValueType {
+            textFrom =1,
+			userText,
+			infoText,
+            size,
+            tagg,
+            color
+        };
+        
+		DynamicElementTextModel(QObject *parent = nullptr);
+		~DynamicElementTextModel();
+		
+		void addText(DynamicElementTextItem *deti);
+		void removeText(DynamicElementTextItem *deti);
+        DynamicElementTextItem *textFromIndex(const QModelIndex &index) const;
+        DynamicElementTextItem *textFromItem(QStandardItem *item) const;
+		QUndoCommand *undoForEditedText(DynamicElementTextItem *deti) const;
+        
+    private:
+		void enableSourceText(DynamicElementTextItem *deti, DynamicElementTextItem::TextFrom tf );
+        void dataEdited(QStandardItem *qsi);
+		void setConnection(DynamicElementTextItem *deti, bool set);
+		void updateDataFromText(DynamicElementTextItem *deti, DynamicElementTextModel::ValueType type);
+		
+	private:
+		QHash <DynamicElementTextItem *, QStandardItem *> m_texts_list;
+		QHash <DynamicElementTextItem *, QList<QMetaObject::Connection>> m_hash_text_connect;
+};
+
+class DynamicTextItemDelegate : public QStyledItemDelegate
+{
+    public:
+        DynamicTextItemDelegate(QObject *parent = Q_NULLPTR);
+        
+        virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+        virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
+};
+
+#endif // DYNAMICELEMENTTEXTMODEL_H

Modified: trunk/sources/ui/elementpropertieswidget.cpp
===================================================================
--- trunk/sources/ui/elementpropertieswidget.cpp	2017-08-03 17:04:08 UTC (rev 5004)
+++ trunk/sources/ui/elementpropertieswidget.cpp	2017-08-03 17:36:08 UTC (rev 5005)
@@ -24,6 +24,7 @@
 #include "diagram.h"
 #include "diagramposition.h"
 #include "qeticons.h"
+#include "dynamicelementtextitemeditor.h"
 
 #include <QVBoxLayout>
 #include <QLabel>
@@ -203,9 +204,10 @@
 		default:
 			break;
 	}
+    m_list_editor << new DynamicElementTextItemEditor(m_element, this);
 
 		//Add each editors in tab widget
-	foreach (AbstractElementPropertiesEditorWidget *aepew, m_list_editor)
+	for (AbstractElementPropertiesEditorWidget *aepew : m_list_editor)
 	{
 		aepew->setLiveEdit(m_live_edit);
 		m_tab->addTab(aepew, aepew->title());
@@ -296,7 +298,7 @@
 	connect(find_in_panel, SIGNAL(clicked()), this, SLOT(findInPanel()));
 	QPushButton *edit_element = new QPushButton(QET::Icons::ElementEdit, tr("Éditer l'élément"), general_widget);
 	connect(edit_element, SIGNAL(clicked()), this, SLOT(editElement()));
-	QHBoxLayout *hlayout_ = new QHBoxLayout;
+    QHBoxLayout *hlayout_ = new QHBoxLayout;
 	hlayout_->addWidget(find_in_panel);
 	hlayout_->addWidget(edit_element);
 	vlayout_->addLayout(hlayout_);

Added: trunk/sources/undocommand/addelementtextcommand.cpp
===================================================================
--- trunk/sources/undocommand/addelementtextcommand.cpp	                        (rev 0)
+++ trunk/sources/undocommand/addelementtextcommand.cpp	2017-08-03 17:36:08 UTC (rev 5005)
@@ -0,0 +1,83 @@
+/*
+	Copyright 2006-2017 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 "addelementtextcommand.h"
+#include "element.h"
+#include "dynamicelementtextitem.h"
+#include <QGraphicsScene>
+
+AddElementTextCommand::AddElementTextCommand(Element *element, DynamicElementTextItem *deti, QUndoCommand *parent):
+	QUndoCommand(parent),
+	m_element(element),
+	m_text(deti)
+{
+	setText(QObject::tr("Ajouter un texte d'élément"));	
+}
+
+AddElementTextCommand::~AddElementTextCommand()
+{
+	if(!m_element->dynamicTextItems().contains(m_text))
+		delete m_text;
+}
+
+void AddElementTextCommand::undo()
+{
+	m_element->removeDynamicTextItem(m_text);
+	m_text->setParentItem(nullptr);
+	if(m_text->scene())
+		m_text->scene()->removeItem(m_text);
+}
+
+void AddElementTextCommand::redo()
+{
+	m_text->setParentItem(m_element);
+	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;
+//}
+
+//void RemoveElementTextCommand::undo()
+//{
+//	if(m_element)
+//	{
+//		m_text->setParentItem(m_element);
+//		m_element->addDynamicTextItem(m_text);
+//	}
+//}
+
+//void RemoveElementTextCommand::redo()
+//{
+//	if(m_element && m_text->scene())
+//	{
+		
+//		m_element->removeDynamicTextItem(m_text);
+//		m_text->setParentItem(nullptr);
+//		m_text->scene()->removeItem(m_text);
+//	}
+//}

Added: trunk/sources/undocommand/addelementtextcommand.h
===================================================================
--- trunk/sources/undocommand/addelementtextcommand.h	                        (rev 0)
+++ trunk/sources/undocommand/addelementtextcommand.h	2017-08-03 17:36:08 UTC (rev 5005)
@@ -0,0 +1,54 @@
+/*
+	Copyright 2006-2017 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 ADDELEMENTTEXTCOMMAND_H
+#define ADDELEMENTTEXTCOMMAND_H
+
+#include <QUndoCommand>
+
+class Element;
+class DynamicElementTextItem;
+
+class AddElementTextCommand : public QUndoCommand
+{
+	public:
+		AddElementTextCommand(Element *element, DynamicElementTextItem *deti, QUndoCommand *parent = nullptr);
+		virtual ~AddElementTextCommand();
+		
+		virtual void undo();
+		virtual void redo();
+		
+	private:
+		Element *m_element = nullptr;
+		DynamicElementTextItem *m_text = nullptr;
+};
+
+//class RemoveElementTextCommand : public QUndoCommand
+//{
+//	public:
+//		RemoveElementTextCommand(DynamicElementTextItem *deti, QUndoCommand *parent = nullptr);
+//		virtual ~RemoveElementTextCommand();
+		
+//		virtual void undo();
+//		virtual void redo();
+	
+//	private:
+//		Element *m_element = nullptr;
+//		DynamicElementTextItem *m_text = nullptr;
+//};
+
+#endif // ADDELEMENTTEXTCOMMAND_H

Added: trunk/sources/undocommand/deleteqgraphicsitemcommand.cpp
===================================================================
--- trunk/sources/undocommand/deleteqgraphicsitemcommand.cpp	                        (rev 0)
+++ trunk/sources/undocommand/deleteqgraphicsitemcommand.cpp	2017-08-03 17:36:08 UTC (rev 5005)
@@ -0,0 +1,119 @@
+/*
+	Copyright 2006-2017 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 "deleteqgraphicsitemcommand.h"
+#include "dynamicelementtextitem.h"
+#include "diagram.h"
+#include "element.h"
+#include "conductor.h"
+#include "conductortextitem.h"
+
+/**
+ * @brief DeleteQGraphicsItemCommand::DeleteQGraphicsItemCommand
+ * @param diagram : deigram where this undo work
+ * @param content : content to remove
+ * @param parent : parent undo
+ */
+DeleteQGraphicsItemCommand::DeleteQGraphicsItemCommand(Diagram *diagram, const DiagramContent &content, QUndoCommand *parent) :
+	QUndoCommand(parent),
+	m_removed_contents(content),
+	m_diagram(diagram)
+{
+		//If parent element of a dynamic element text item is also in @m_removed_content,
+		//we remove it, because when the element will be removed from the scene every child's will also be removed.
+	const QSet<DynamicElementTextItem *> elmt_set = m_removed_contents.m_element_texts;
+	for(DynamicElementTextItem *deti : elmt_set)
+	{
+		if (m_removed_contents.m_elements.contains(deti->ParentElement()))
+			m_removed_contents.m_element_texts.remove(deti);
+			
+	}
+	
+	for(DynamicElementTextItem *deti : m_removed_contents.m_element_texts)
+		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));
+}
+
+DeleteQGraphicsItemCommand::~DeleteQGraphicsItemCommand() {
+	m_diagram->qgiManager().release(m_removed_contents.items(DiagramContent::All));
+}
+
+/**
+ * @brief DeleteQGraphicsItemCommand::undo
+ * Undo this command
+ */
+void DeleteQGraphicsItemCommand::undo()
+{
+	m_diagram->showMe();
+
+	for(QGraphicsItem *item : m_removed_contents.items())
+		m_diagram->addItem(item);
+
+		//We relink element after every element was added to diagram
+	for(Element *e : m_removed_contents.m_elements)
+		for(Element *elmt : m_link_hash[e])
+				e->linkToElement(elmt);
+	
+	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);
+	}
+}
+
+/**
+ * @brief DeleteQGraphicsItemCommand::redo
+ * Redo the delete command
+ */
+void DeleteQGraphicsItemCommand::redo()
+{
+	m_diagram -> showMe();
+
+	for(Conductor *c : m_removed_contents.conductors(DiagramContent::AnyConductor))
+	{
+			//If option one text per folio is enable, and the text item of
+			//current conductor is visible (that mean the conductor have the single displayed text)
+			//We call adjustTextItemPosition to other conductor at the same potential to keep
+			//a visible text on this potential.
+		if (m_diagram -> defaultConductorProperties.m_one_text_per_folio && c -> textItem() -> isVisible())
+		{
+			QList <Conductor *> conductor_list;
+			conductor_list << c -> relatedPotentialConductors(false).toList();
+			if (conductor_list.count())
+				conductor_list.first() -> calculateTextItemPosition();
+		}
+	}
+	
+	for(Element *e : m_removed_contents.m_elements)
+	{
+			//Get linked element, for relink it at undo
+		if (!e->linkedElements().isEmpty())
+			m_link_hash.insert(e, e->linkedElements());
+	}
+	
+	for(DynamicElementTextItem *deti : m_removed_contents.m_element_texts)
+	{
+		deti->ParentElement()->removeDynamicTextItem(deti);
+		deti->setParentItem(nullptr);
+	}
+
+	
+	for(QGraphicsItem *item : m_removed_contents.items())
+		m_diagram->removeItem(item);
+}

Added: trunk/sources/undocommand/deleteqgraphicsitemcommand.h
===================================================================
--- trunk/sources/undocommand/deleteqgraphicsitemcommand.h	                        (rev 0)
+++ trunk/sources/undocommand/deleteqgraphicsitemcommand.h	2017-08-03 17:36:08 UTC (rev 5005)
@@ -0,0 +1,46 @@
+/*
+	Copyright 2006-2017 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 DELETEQGRAPHICSITEMCOMMAND_H
+#define DELETEQGRAPHICSITEMCOMMAND_H
+
+#include <QUndoCommand>
+#include "diagramcontent.h"
+
+class Diagram;
+
+class DeleteQGraphicsItemCommand : public QUndoCommand
+{
+	public:
+		DeleteQGraphicsItemCommand(Diagram *diagram, const DiagramContent &content, QUndoCommand * parent = nullptr);
+		virtual ~DeleteQGraphicsItemCommand() override;
+	private:
+		DeleteQGraphicsItemCommand(const DeleteQGraphicsItemCommand &);
+
+	public:
+		virtual void undo() override;
+		virtual void redo() override;
+		
+		// attributes
+	private:
+		DiagramContent m_removed_contents;
+		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
+};
+
+#endif // DELETEQGRAPHICSITEMCOMMAND_H


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