[qet] qet/qet: [5492] 1-Use the "implicite shared" of Qt for the QPicture and QPixmap of element (https://doc.qt.io/qt-5/ implicit-sharing.html).

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


Revision: 5492
Author:   blacksun
Date:     2018-08-23 21:41:58 +0200 (Thu, 23 Aug 2018)
Log Message:
-----------
1-Use the "implicite shared" of Qt for the QPicture and QPixmap of element (https://doc.qt.io/qt-5/implicit-sharing.html).
This avoid to parse the same element definition each time user drop the same element in the diagram.
Only the first element build the picture, all other get the created picture which is shared.

2- For use the "implicite shared" QPicture and QPixmap of element, now this isn't the element who build her picture, but a dedicated class who made only this job : build the QPicture and QPixmap of elements.

3- With the two previous novelty, the class CustomElement and GhostElement are became useless, and so was removed.
Some few member function of CustomElement was moved to Element.

Modified Paths:
--------------
    trunk/sources/ElementsCollection/elementslocation.cpp
    trunk/sources/diagram.cpp
    trunk/sources/diagram.h
    trunk/sources/diagramview.cpp
    trunk/sources/editor/graphicspart/customelementpart.cpp
    trunk/sources/exportdialog.cpp
    trunk/sources/nomenclature.h
    trunk/sources/qetapp.cpp
    trunk/sources/qetdiagrameditor.cpp
    trunk/sources/qetdiagrameditor.h
    trunk/sources/qetgraphicsitem/dynamicelementtextitem.h
    trunk/sources/qetgraphicsitem/element.cpp
    trunk/sources/qetgraphicsitem/element.h
    trunk/sources/qetgraphicsitem/masterelement.cpp
    trunk/sources/qetgraphicsitem/masterelement.h
    trunk/sources/qetgraphicsitem/reportelement.cpp
    trunk/sources/qetgraphicsitem/reportelement.h
    trunk/sources/qetgraphicsitem/simpleelement.cpp
    trunk/sources/qetgraphicsitem/simpleelement.h
    trunk/sources/qetgraphicsitem/slaveelement.cpp
    trunk/sources/qetgraphicsitem/slaveelement.h
    trunk/sources/qetgraphicsitem/terminalelement.cpp
    trunk/sources/qetgraphicsitem/terminalelement.h
    trunk/sources/ui/elementpropertieswidget.cpp

Added Paths:
-----------
    trunk/sources/factory/elementpicturefactory.cpp
    trunk/sources/factory/elementpicturefactory.h

Removed Paths:
-------------
    trunk/sources/qetgraphicsitem/customelement.cpp
    trunk/sources/qetgraphicsitem/customelement.h
    trunk/sources/qetgraphicsitem/ghostelement.cpp
    trunk/sources/qetgraphicsitem/ghostelement.h

Modified: trunk/sources/ElementsCollection/elementslocation.cpp
===================================================================
--- trunk/sources/ElementsCollection/elementslocation.cpp	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/ElementsCollection/elementslocation.cpp	2018-08-23 19:41:58 UTC (rev 5492)
@@ -20,9 +20,10 @@
 #include "xmlelementcollection.h"
 #include "qetproject.h"
 #include "elementscollectioncache.h"
-#include "elementfactory.h"
+#include "elementpicturefactory.h"
 #include "element.h"
 #include "qetxml.h"
+#include <QPicture>
 
 // make this class usable with QVariant
 int ElementsLocation::MetaTypeId = qRegisterMetaType<ElementsLocation>("ElementsLocation");
@@ -645,14 +646,8 @@
 		if (cache->fetchElement(loc))
 			return QIcon(cache->pixmap());
 	}
-	else
-	{
-		ElementFactory *factory = ElementFactory::Instance();
-		int state;
-		Element *elmt = factory->createElement(*this, nullptr, &state);
-
-		if (state == 0)
-			return QIcon(elmt->pixmap());
+	else {
+		return QIcon(ElementPictureFactory::instance()->pixmap(*this));
 	}
 
 	return QIcon();
@@ -664,21 +659,9 @@
  */
 QString ElementsLocation::name() const
 {
-//	if (!m_project)
-//	{
-//		ElementsCollectionCache *cache = QETApp::collectionCache();
-//		ElementsLocation loc(*this); //Make a copy of this to keep this method const
-//		if (cache->fetchElement(loc))
-//			return cache->name();
-//		else
-//			return QString();
-//	}
-//	else
-//	{
-		NamesList nl;
-		nl.fromXml(xml());
-		return nl.name(fileName());
-//	}
+	NamesList nl;
+	nl.fromXml(xml());
+	return nl.name(fileName());
 }
 
 /**

Modified: trunk/sources/diagram.cpp
===================================================================
--- trunk/sources/diagram.cpp	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/diagram.cpp	2018-08-23 19:41:58 UTC (rev 5492)
@@ -18,7 +18,6 @@
 #include <math.h>
 #include "qetgraphicsitem/conductor.h"
 #include "qetgraphicsitem/conductortextitem.h"
-#include "qetgraphicsitem/customelement.h"
 #include "factory/elementfactory.h"
 #include "diagram.h"
 #include "diagramcommands.h"
@@ -25,7 +24,6 @@
 #include "diagramcontent.h"
 #include "diagramposition.h"
 #include "exportdialog.h"
-#include "qetgraphicsitem/ghostelement.h"
 #include "qetgraphicsitem/independenttextitem.h"
 #include "qetgraphicsitem/diagramimageitem.h"
 #include "qetgraphicsitem/qetshapeitem.h"
@@ -900,9 +898,6 @@
 			QString debug_message = QString("Diagram::fromXml() : Le chargement de la description de l'element %1 a echoue avec le code d'erreur %2").arg(element_location.path()).arg(state);
 			qDebug() << qPrintable(debug_message);
 			delete nvel_elmt;
-			
-			qDebug() << "Diagram::fromXml() : Utilisation d'un GhostElement en lieu et place de cet element.";
-			nvel_elmt = new GhostElement(element_location);
 		}
 		
 		addItem(nvel_elmt);
@@ -1450,19 +1445,6 @@
 	return(border_and_titleblock.title());
 }
 
-/**
-	@return la liste des elements de ce schema
-*/
-QList<CustomElement *> Diagram::customElements() const {
-	QList<CustomElement *> elements_list;
-	foreach(QGraphicsItem *qgi, items()) {
-		if (CustomElement *elmt = qgraphicsitem_cast<CustomElement *>(qgi)) {
-			elements_list << elmt;
-		}
-	}
-	return(elements_list);
-}
-
 QList <Element *> Diagram::elements() const {
 	QList<Element *> element_list;
 	foreach (QGraphicsItem *qgi, items()) {
@@ -1498,8 +1480,9 @@
 	@param location Emplacement d'un element
 	@return true si l'element location est utilise sur ce schema, false sinon
 */
-bool Diagram::usesElement(const ElementsLocation &location) {
-	foreach(CustomElement *element, customElements()) {
+bool Diagram::usesElement(const ElementsLocation &location)
+{
+	for(Element *element : elements()) {
 		if (element -> location() == location) {
 			return(true);
 		}

Modified: trunk/sources/diagram.h
===================================================================
--- trunk/sources/diagram.h	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/diagram.h	2018-08-23 19:41:58 UTC (rev 5492)
@@ -184,7 +184,6 @@
 		
 		bool isEmpty() const;
 	
-		QList<CustomElement *> customElements() const;
 		QList<Element *> elements() const;
 		QList<Conductor *> conductors() const;
 		QSet<Conductor *> selectedConductors() const;

Modified: trunk/sources/diagramview.cpp
===================================================================
--- trunk/sources/diagramview.cpp	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/diagramview.cpp	2018-08-23 19:41:58 UTC (rev 5492)
@@ -17,8 +17,6 @@
 */
 #include "diagramview.h"
 #include "diagram.h"
-#include "qetgraphicsitem/customelement.h"
-#include "qetgraphicsitem/ghostelement.h"
 #include "qetgraphicsitem/conductor.h"
 #include "diagramcommands.h"
 #include "diagramposition.h"

Modified: trunk/sources/editor/graphicspart/customelementpart.cpp
===================================================================
--- trunk/sources/editor/graphicspart/customelementpart.cpp	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/editor/graphicspart/customelementpart.cpp	2018-08-23 19:41:58 UTC (rev 5492)
@@ -16,7 +16,6 @@
 	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "customelementpart.h"
-#include "qetgraphicsitem/customelement.h"
 #include "qetelementeditor.h"
 
 /// @return le QETElementEditor auquel cet editeur appartient

Modified: trunk/sources/exportdialog.cpp
===================================================================
--- trunk/sources/exportdialog.cpp	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/exportdialog.cpp	2018-08-23 19:41:58 UTC (rev 5492)
@@ -28,12 +28,12 @@
 #include "qetgraphicsitem/conductor.h"
 #include "qetgraphicsitem/diagramtextitem.h"
 #include "qetgraphicsitem/conductortextitem.h"
-#include "qetgraphicsitem/customelement.h"
-#include "qetgraphicsitem/ghostelement.h"
 #include "qetgraphicsitem/independenttextitem.h"
 #include "qetgraphicsitem/diagramimageitem.h"
 #include "qetgraphicsitem/qetshapeitem.h"
 #include "diagramfoliolist.h"
+#include "elementpicturefactory.h"
+#include "element.h"
 
 /**
 	Constructeur
@@ -496,15 +496,17 @@
 		qreal hotspot_x = (elem_pos_x) * Createdxf::xScale;
 		qreal hotspot_y = Createdxf::sheetHeight - (elem_pos_y) * Createdxf::yScale;
 
-		QList<QLineF *> elmt_line = elmt -> lines();
-		foreach(QLineF *line, elmt_line) {
-			qreal x1 = (elem_pos_x + line -> p1().x()) * Createdxf::xScale;
-			qreal y1 = Createdxf::sheetHeight - (elem_pos_y + line -> p1().y()) * Createdxf::yScale;
+		ElementPictureFactory::primitives primitives = ElementPictureFactory::instance()->getPrimitives(elmt->location());
+		
+		for (QLineF line : primitives.m_lines)
+		{
+			qreal x1 = (elem_pos_x + line.p1().x()) * Createdxf::xScale;
+			qreal y1 = Createdxf::sheetHeight - (elem_pos_y + line.p1().y()) * Createdxf::yScale;
 			QPointF transformed_point = rotation_transformed(x1, y1, hotspot_x, hotspot_y, rotation_angle);
 			x1 = transformed_point.x();
 			y1 = transformed_point.y();
-			qreal x2 = (elem_pos_x + line -> p2().x()) * Createdxf::xScale;
-			qreal y2 = Createdxf::sheetHeight - (elem_pos_y + line -> p2().y()) * Createdxf::yScale;
+			qreal x2 = (elem_pos_x + line.p2().x()) * Createdxf::xScale;
+			qreal y2 = Createdxf::sheetHeight - (elem_pos_y + line.p2().y()) * Createdxf::yScale;
 			transformed_point = rotation_transformed(x2, y2, hotspot_x, hotspot_y, rotation_angle);
 			x2 = transformed_point.x();
 			y2 = transformed_point.y();
@@ -511,12 +513,12 @@
 			Createdxf::drawLine(file_path, x1, y1, x2, y2, 0);
 		}
 
-		QList<QRectF *> elmt_rectangle = elmt -> rectangles();
-		foreach(QRectF *rect, elmt_rectangle) {
-			qreal x1 = (elem_pos_x + rect -> bottomLeft().x()) * Createdxf::xScale;
-			qreal y1 = Createdxf::sheetHeight - (elem_pos_y + rect -> bottomLeft().y()) * Createdxf::yScale;
-			qreal w = rect -> width() * Createdxf::xScale;
-			qreal h = rect -> height() * Createdxf::yScale;
+		for (QRectF rect : primitives.m_rectangles)
+		{
+			qreal x1 = (elem_pos_x + rect.bottomLeft().x()) * Createdxf::xScale;
+			qreal y1 = Createdxf::sheetHeight - (elem_pos_y + rect.bottomLeft().y()) * Createdxf::yScale;
+			qreal w = rect.width() * Createdxf::xScale;
+			qreal h = rect.height() * Createdxf::yScale;
 			// opposite corner
 			qreal x2 = x1 + w;
 			qreal y2 = y1 + h;
@@ -533,11 +535,11 @@
 			Createdxf::drawRectangle(file_path, bottom_left_x, bottom_left_y, w, h, 0);
 		}
 
-		QList<QRectF *> elmt_circle = elmt -> circles();
-		foreach(QRectF *circle_rect, elmt_circle) {
-			qreal x1 = (elem_pos_x + circle_rect ->center().x()) * Createdxf::xScale;
-			qreal y1 = Createdxf::sheetHeight - (elem_pos_y + circle_rect -> center().y()) * Createdxf::yScale;
-			qreal r = circle_rect -> width() * Createdxf::xScale / 2;
+		for (QRectF circle_rect : primitives.m_circles)
+		{
+			qreal x1 = (elem_pos_x + circle_rect.center().x()) * Createdxf::xScale;
+			qreal y1 = Createdxf::sheetHeight - (elem_pos_y + circle_rect.center().y()) * Createdxf::yScale;
+			qreal r = circle_rect.width() * Createdxf::xScale / 2;
 			QPointF transformed_point = rotation_transformed(x1, y1, hotspot_x, hotspot_y, rotation_angle);
 			x1 = transformed_point.x();
 			y1 = transformed_point.y();
@@ -544,18 +546,18 @@
 			Createdxf::drawCircle(file_path, r, x1, y1, 0);
 		}
 
-		QList<QVector<QPointF> *> elmt_polygon = elmt -> polygons();
-		foreach(QVector<QPointF> *polygon, elmt_polygon) {
-			if (polygon -> size() == 0)
+		for (QVector<QPointF> polygon : primitives.m_polygons)
+		{
+			if (polygon.size() == 0)
 				continue;
-			qreal x1 = (elem_pos_x + polygon -> at(0).x()) * Createdxf::xScale;
-			qreal y1 = Createdxf::sheetHeight - (elem_pos_y + polygon -> at(0).y()) * Createdxf::yScale;
+			qreal x1 = (elem_pos_x + polygon.at(0).x()) * Createdxf::xScale;
+			qreal y1 = Createdxf::sheetHeight - (elem_pos_y + polygon.at(0).y()) * Createdxf::yScale;
 			QPointF transformed_point = rotation_transformed(x1, y1, hotspot_x, hotspot_y, rotation_angle);
 			x1 = transformed_point.x();
 			y1 = transformed_point.y();
-			for (int i = 1; i < polygon -> size(); ++i ) {
-				qreal x2 = (elem_pos_x + polygon -> at(i).x()) * Createdxf::xScale;
-				qreal y2 = Createdxf::sheetHeight - (elem_pos_y + polygon -> at(i).y()) * Createdxf::yScale;
+			for (int i = 1; i < polygon.size(); ++i ) {
+				qreal x2 = (elem_pos_x + polygon.at(i).x()) * Createdxf::xScale;
+				qreal y2 = Createdxf::sheetHeight - (elem_pos_y + polygon.at(i).y()) * Createdxf::yScale;
 				QPointF transformed_point = rotation_transformed(x2, y2, hotspot_x, hotspot_y, rotation_angle);
 				x2 = transformed_point.x();
 				y2 = transformed_point.y();
@@ -566,16 +568,16 @@
 		}
 
 		// Draw arcs and ellipses
-		QList<QVector<qreal> *> elmt_arc = elmt -> arcs();
-		foreach(QVector<qreal> *arc, elmt_arc) {
-			if (arc -> size() == 0)
+		for (QVector<qreal> arc : primitives.m_arcs)
+		{
+			if (arc.size() == 0)
 				continue;
-			qreal x = (elem_pos_x + arc -> at(0)) * Createdxf::xScale;
-			qreal y = Createdxf::sheetHeight - (elem_pos_y + arc -> at(1)) * Createdxf::yScale;
-			qreal w = arc -> at(2) * Createdxf::xScale;
-			qreal h = arc -> at(3) * Createdxf::yScale;
-			qreal startAngle = arc -> at(4);
-			qreal spanAngle = arc -> at(5);
+			qreal x = (elem_pos_x + arc.at(0)) * Createdxf::xScale;
+			qreal y = Createdxf::sheetHeight - (elem_pos_y + arc.at(1)) * Createdxf::yScale;
+			qreal w = arc.at(2) * Createdxf::xScale;
+			qreal h = arc.at(3) * Createdxf::yScale;
+			qreal startAngle = arc.at(4);
+			qreal spanAngle = arc .at(5);
 			Createdxf::drawArcEllipse(file_path, x, y, w, h, startAngle, spanAngle, hotspot_x, hotspot_y, rotation_angle, 0);
 		}
 	}

Added: trunk/sources/factory/elementpicturefactory.cpp
===================================================================
--- trunk/sources/factory/elementpicturefactory.cpp	                        (rev 0)
+++ trunk/sources/factory/elementpicturefactory.cpp	2018-08-23 19:41:58 UTC (rev 5492)
@@ -0,0 +1,624 @@
+/*
+	Copyright 2006-2018 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 "elementpicturefactory.h"
+#include "elementslocation.h"
+#include "qet.h"
+#include "qetapp.h"
+#include "partline.h"
+
+#include <QDomElement>
+#include <QPainter>
+#include <QTextDocument>
+#include <QPicture>
+#include <iostream>
+#include <QAbstractTextDocumentLayout>
+
+ElementPictureFactory* ElementPictureFactory::m_factory = nullptr;
+
+/**
+ * @brief ElementPictureFactory::getPictures
+ * Set the picture of the element at location.
+ * Note, picture can be null
+ * @param location
+ * @param picture
+ * @param low_picture
+ */
+void ElementPictureFactory::getPictures(const ElementsLocation &location, QPicture &picture, QPicture &low_picture)
+{
+	if(!location.exist()) {
+		return;
+	}
+	
+	QUuid uuid = location.uuid();
+	
+	if(m_pictures_H.keys().contains(uuid))
+	{
+		picture = m_pictures_H.value(uuid);
+		low_picture = m_low_pictures_H.value(uuid);
+	}
+	else
+	{
+		if (build(location))
+		{
+			picture = m_pictures_H.value(uuid);
+			low_picture = m_low_pictures_H.value(uuid);
+		}
+	}
+}
+
+/**
+ * @brief ElementPictureFactory::pixmap
+ * @param location
+ * @return the pixmap of the element at @location
+ * Note pixmap can be null
+ */
+QPixmap ElementPictureFactory::pixmap(const ElementsLocation &location)
+{
+	QUuid uuid = location.uuid();
+	if (m_pixmap_H.contains(uuid)) {
+		return m_pixmap_H.value(uuid);
+	}
+	
+	if(build(location))
+	{
+		QDomElement dom = location.xml();
+			//size
+		int w = dom.attribute("width").toInt();
+		int h = dom.attribute("height").toInt();
+		while (w % 10) ++ w;
+		while (h % 10) ++ h;
+			//hotspot
+		int hsx = qMin(dom.attribute("hotspot_x").toInt(), w);
+		int hsy = qMin(dom.attribute("hotspot_y").toInt(), h);
+
+		QPixmap pix(w, h);
+		pix.fill(QColor(255, 255, 255, 0));
+		
+		QPainter painter(&pix);
+		painter.setRenderHint(QPainter::Antialiasing, true);
+		painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
+		painter.translate(hsx, hsy);
+		painter.drawPicture(0, 0, m_pictures_H.value(uuid));
+		
+		m_pixmap_H.insert(uuid, pix);
+		return pix;
+	}
+	
+	return QPixmap();
+}
+
+
+/**
+ * @brief ElementPictureFactory::getPrimitives
+ * @param location
+ * @return The primtive used to draw the element at @location
+ */
+ElementPictureFactory::primitives ElementPictureFactory::getPrimitives(const ElementsLocation &location)
+{
+	if(!m_primitives_H.contains(location.uuid()))
+		build(location);
+	
+	return m_primitives_H.value(location.uuid());
+}
+
+
+bool ElementPictureFactory::build(const ElementsLocation &location)
+{
+	QDomElement dom = location.xml();
+	
+		//Check if the curent version can read the xml description
+	if (dom.hasAttribute("version"))
+	{
+		bool conv_ok;
+		qreal element_version = dom.attribute("version").toDouble(&conv_ok);
+		if (conv_ok && QET::version.toDouble() < element_version)
+		{
+			std::cerr << qPrintable(
+			QObject::tr("Avertissement : l'élément "
+			" a été enregistré avec une version"
+			" ultérieure de QElectroTech.")
+			) << std::endl;
+		}
+	}
+	
+		//This attributes must be present and valid
+	int w, h, hot_x, hot_y;
+	if (!QET::attributeIsAnInteger(dom, QString("width"), &w) ||\
+		!QET::attributeIsAnInteger(dom, QString("height"), &h) ||\
+		!QET::attributeIsAnInteger(dom, QString("hotspot_x"), &hot_x) ||\
+		!QET::attributeIsAnInteger(dom, QString("hotspot_y"), &hot_y))
+	{
+		return(false);
+	}
+	
+	QPicture pic;
+	QPicture low_pic;
+	primitives primitives_;
+	
+	m_pictures_H.insert(location.uuid(), pic);
+	m_low_pictures_H.insert(location.uuid(), low_pic);
+	m_primitives_H.insert(location.uuid(), primitives_);
+	
+	QPainter painter;
+	painter.begin(&pic);
+	painter.setRenderHint(QPainter::Antialiasing,         true);
+	painter.setRenderHint(QPainter::TextAntialiasing,     true);
+	painter.setRenderHint(QPainter::SmoothPixmapTransform,true);
+
+	
+	QPainter low_painter;
+	low_painter.begin(&low_pic);
+	low_painter.setRenderHint(QPainter::Antialiasing,         true);
+	low_painter.setRenderHint(QPainter::TextAntialiasing,     true);
+	low_painter.setRenderHint(QPainter::SmoothPixmapTransform,true);
+	QPen tmp;
+	tmp.setWidthF(1.0); //Vaudoo line to take into account the setCosmetic - don't remove
+	tmp.setCosmetic(true);
+	low_painter.setPen(tmp);
+	
+		//scroll of the Children of the Definition: Parts of the Drawing
+	for (QDomNode node = dom.firstChild() ; !node.isNull() ; node = node.nextSibling())
+	{
+		QDomElement elmts = node.toElement();
+		if (elmts.isNull()) {
+			continue;
+		}
+		
+		if (elmts.tagName() == "description")
+		{	
+				//Manage the graphic description = part of drawing
+			for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling())
+			{
+				QDomElement qde = n.toElement();
+				if (qde.isNull()) {
+					continue;
+				}
+				parseElement(qde, painter, primitives_);
+				primitives fake_prim;
+				parseElement(qde, low_painter, fake_prim);
+			}
+		}
+	}
+	
+		//End of the drawing
+	painter.end();
+	low_painter.end();
+	return true;
+}
+
+void ElementPictureFactory::parseElement(const QDomElement &dom, QPainter &painter, primitives &prim) const
+{
+	     if (dom.tagName() == "line")    (parseLine   (dom, painter, prim));
+	else if (dom.tagName() == "rect")    (parseRect   (dom, painter, prim));
+	else if (dom.tagName() == "ellipse") (parseEllipse(dom, painter, prim));
+	else if (dom.tagName() == "circle")  (parseCircle (dom, painter, prim));
+	else if (dom.tagName() == "arc")     (parseArc    (dom, painter, prim));
+	else if (dom.tagName() == "polygon") (parsePolygon(dom, painter, prim));
+	else if (dom.tagName() == "text")    (parseText   (dom, painter, prim));
+}
+
+void ElementPictureFactory::parseLine(const QDomElement &dom, QPainter &painter, primitives &prim) const
+{
+		//This attributes must be present and valid
+	qreal x1, y1, x2, y2;
+	if (!QET::attributeIsAReal(dom, QString("x1"), &x1)) return;
+	if (!QET::attributeIsAReal(dom, QString("y1"), &y1)) return;
+	if (!QET::attributeIsAReal(dom, QString("x2"), &x2)) return;
+	if (!QET::attributeIsAReal(dom, QString("y2"), &y2)) return;
+
+	Qet::EndType first_end = Qet::endTypeFromString(dom.attribute("end1"));
+	Qet::EndType second_end = Qet::endTypeFromString(dom.attribute("end2"));
+	qreal length1, length2;
+	if (!QET::attributeIsAReal(dom, QString("length1"), &length1)) length1 = 1.5;
+	if (!QET::attributeIsAReal(dom, QString("length2"), &length2)) length2 = 1.5;
+
+	painter.save();
+	setPainterStyle(dom, painter);
+	QPen t = painter.pen();
+	t.setJoinStyle(Qt::MiterJoin);
+	painter.setPen(t);
+
+	QLineF line(x1, y1, x2, y2);
+
+	prim.m_lines << line;
+
+	QPointF point1(line.p1());
+	QPointF point2(line.p2());
+
+	qreal line_length(line.length());
+	qreal pen_width = painter.pen().widthF();
+
+		//Check if we must to draw extremity
+	bool draw_1st_end, draw_2nd_end;
+	qreal reduced_line_length = line_length - (length1 * PartLine::requiredLengthForEndType(first_end));
+	draw_1st_end = first_end && reduced_line_length >= 0;
+	if (draw_1st_end) {
+		reduced_line_length -= (length2 * PartLine::requiredLengthForEndType(second_end));
+	} else {
+		reduced_line_length = line_length - (length2 * PartLine::requiredLengthForEndType(second_end));
+	}
+	draw_2nd_end = second_end && reduced_line_length >= 0;
+
+		//Draw first extremity
+	QPointF start_point, stop_point;
+	if (draw_1st_end) {
+		QList<QPointF> four_points1(PartLine::fourEndPoints(point1, point2, length1));
+		if (first_end == Qet::Circle) {
+			painter.drawEllipse(QRectF(four_points1[0] - QPointF(length1, length1), QSizeF(length1 * 2.0, length1 * 2.0)));
+			start_point = four_points1[1];
+		} else if (first_end == Qet::Diamond) {
+			painter.drawPolygon(QPolygonF() << four_points1[1] << four_points1[2] << point1 << four_points1[3]);
+			start_point = four_points1[1];
+		} else if (first_end == Qet::Simple) {
+			painter.drawPolyline(QPolygonF() << four_points1[3] << point1 << four_points1[2]);
+			start_point = point1;
+
+		} else if (first_end == Qet::Triangle) {
+			painter.drawPolygon(QPolygonF() << four_points1[0] << four_points1[2] << point1 << four_points1[3]);
+			start_point = four_points1[0];
+		}
+
+			//Adjust the begining according to the width of the pen
+		if (pen_width && (first_end == Qet::Simple || first_end == Qet::Circle)) {
+			start_point = QLineF(start_point, point2).pointAt(pen_width / 2.0 / line_length);
+		}
+	} else {
+		start_point = point1;
+	}
+
+		//Draw second extremity
+	if (draw_2nd_end) {
+		QList<QPointF> four_points2(PartLine::fourEndPoints(point2, point1, length2));
+		if (second_end == Qet::Circle) {
+			painter.drawEllipse(QRectF(four_points2[0] - QPointF(length2, length2), QSizeF(length2 * 2.0, length2 * 2.0)));
+			stop_point = four_points2[1];
+		} else if (second_end == Qet::Diamond) {
+			painter.drawPolygon(QPolygonF() << four_points2[2] << point2 << four_points2[3] << four_points2[1]);
+			stop_point = four_points2[1];
+		} else if (second_end == Qet::Simple) {
+			painter.drawPolyline(QPolygonF() << four_points2[3] << point2 << four_points2[2]);
+			stop_point = point2;
+		} else if (second_end == Qet::Triangle) {
+			painter.drawPolygon(QPolygonF() << four_points2[0] << four_points2[2] << point2 << four_points2[3] << four_points2[0]);
+			stop_point = four_points2[0];
+		}
+
+			//Adjust the end according to the width of the pen
+		if (pen_width && (second_end == Qet::Simple || second_end == Qet::Circle)) {
+			stop_point = QLineF(point1, stop_point).pointAt((line_length - (pen_width / 2.0)) / line_length);
+		}
+	} else {
+		stop_point = point2;
+	}
+
+	painter.drawLine(start_point, stop_point);
+
+	painter.restore();
+}
+
+void ElementPictureFactory::parseRect(const QDomElement &dom, QPainter &painter, ElementPictureFactory::primitives &prim) const
+{
+		//This attributes must be present and valid
+	qreal rect_x, rect_y, rect_w, rect_h, rect_rx, rect_ry;
+	if (!QET::attributeIsAReal(dom, QString("x"),       &rect_x))  return;
+	if (!QET::attributeIsAReal(dom, QString("y"),       &rect_y))  return;
+	if (!QET::attributeIsAReal(dom, QString("width"),   &rect_w))  return;
+	if (!QET::attributeIsAReal(dom, QString("height"),  &rect_h))  return;
+	rect_rx = dom.attribute("rx", "0").toDouble();
+	rect_ry = dom.attribute("ry", "0").toDouble();
+
+	prim.m_rectangles << QRectF(rect_x, rect_y, rect_w, rect_h);
+
+	painter.save();
+	setPainterStyle(dom, painter);
+
+	QPen p = painter.pen();
+	p.setJoinStyle(Qt::MiterJoin);
+	painter.setPen(p);
+
+	painter.drawRoundedRect(QRectF(rect_x, rect_y, rect_w, rect_h), rect_rx, rect_ry);
+	painter.restore();
+}
+
+void ElementPictureFactory::parseEllipse(const QDomElement &dom, QPainter &painter, ElementPictureFactory::primitives &prim) const
+{
+		//This attributes must be present and valid
+	qreal ellipse_x, ellipse_y, ellipse_l, ellipse_h;
+	if (!QET::attributeIsAReal(dom, QString("x"),      &ellipse_x))  return;
+	if (!QET::attributeIsAReal(dom, QString("y"),      &ellipse_y))  return;
+	if (!QET::attributeIsAReal(dom, QString("width"),  &ellipse_l))  return;
+	if (!QET::attributeIsAReal(dom, QString("height"), &ellipse_h))  return;
+	painter.save();
+	setPainterStyle(dom, painter);
+
+	QVector<qreal> arc;
+	arc.push_back(ellipse_x);
+	arc.push_back(ellipse_y);
+	arc.push_back(ellipse_l);
+	arc.push_back(ellipse_h);
+	arc.push_back(0);
+	arc.push_back(360);
+	prim.m_arcs << arc;
+
+	painter.drawEllipse(QRectF(ellipse_x, ellipse_y, ellipse_l, ellipse_h));
+	painter.restore();
+}
+
+void ElementPictureFactory::parseCircle(const QDomElement &dom, QPainter &painter, ElementPictureFactory::primitives &prim) const
+{
+		//This attributes must be present and valid
+	qreal cercle_x, cercle_y, cercle_r;
+	if (!QET::attributeIsAReal(dom, QString("x"),        &cercle_x)) return;
+	if (!QET::attributeIsAReal(dom, QString("y"),        &cercle_y)) return;
+	if (!QET::attributeIsAReal(dom, QString("diameter"), &cercle_r)) return;
+	painter.save();
+	setPainterStyle(dom, painter);
+	QRectF circle_bounding_rect(cercle_x, cercle_y, cercle_r, cercle_r);
+
+	prim.m_circles << circle_bounding_rect;
+
+	painter.drawEllipse(circle_bounding_rect);
+	painter.restore();
+}
+
+void ElementPictureFactory::parseArc(const QDomElement &dom, QPainter &painter, ElementPictureFactory::primitives &prim) const
+{
+		//This attributes must be present and valid
+	qreal arc_x, arc_y, arc_l, arc_h, arc_s, arc_a;
+	if (!QET::attributeIsAReal(dom, QString("x"),       &arc_x))  return;
+	if (!QET::attributeIsAReal(dom, QString("y"),       &arc_y))  return;
+	if (!QET::attributeIsAReal(dom, QString("width"),   &arc_l))  return;
+	if (!QET::attributeIsAReal(dom, QString("height"),  &arc_h))  return;
+	if (!QET::attributeIsAReal(dom, QString("start"),   &arc_s))  return;
+	if (!QET::attributeIsAReal(dom, QString("angle"),   &arc_a))  return;
+
+	painter.save();
+	setPainterStyle(dom, painter);
+
+	QVector<qreal> arc;
+	arc.push_back(arc_x);
+	arc.push_back(arc_y);
+	arc.push_back(arc_l);
+	arc.push_back(arc_h);
+	arc.push_back(arc_s);
+	arc.push_back(arc_a);
+	prim.m_arcs << arc;
+
+	painter.drawArc(QRectF(arc_x, arc_y, arc_l, arc_h), (int)(arc_s * 16), (int)(arc_a * 16));
+	painter.restore();
+}
+
+void ElementPictureFactory::parsePolygon(const QDomElement &dom, QPainter &painter, ElementPictureFactory::primitives &prim) const
+{
+	int i = 1;
+	while(true) {
+		if (QET::attributeIsAReal(dom, QString("x%1").arg(i)) && QET::attributeIsAReal(dom, QString("y%1").arg(i))) ++ i;
+		else break;
+	}
+	if (i < 3) {
+		return;
+	}
+	
+	QVector<QPointF> points; // empty vector created instead of default initialized vector with i-1 elements.
+	for (int j = 1 ; j < i ; ++ j) {
+		points.insert(
+			j - 1,
+			QPointF(
+				dom.attribute(QString("x%1").arg(j)).toDouble(),
+				dom.attribute(QString("y%1").arg(j)).toDouble()
+			)
+		);
+	}
+
+	painter.save();
+	setPainterStyle(dom, painter);
+	if (dom.attribute("closed") == "false") painter.drawPolyline(points.data(), i-1);
+	else {
+		painter.drawPolygon(points.data(), i-1);
+
+		// insert first point at the end again for DXF export.
+		points.push_back(points[0]);
+	}
+
+	prim.m_polygons << points;
+
+	painter.restore();
+}
+
+void ElementPictureFactory::parseText(const QDomElement &dom, QPainter &painter, ElementPictureFactory::primitives &prim) const
+{
+	Q_UNUSED(prim);
+	
+	qreal pos_x, pos_y;
+	int size;
+	if (!QET::attributeIsAReal(dom, "x", &pos_x) ||\
+		!QET::attributeIsAReal(dom, "y", &pos_y) ||\
+		!QET::attributeIsAnInteger(dom, "size", &size) ||\
+		!dom.hasAttribute("text")) {
+		return;
+	}
+
+	painter.save();
+	setPainterStyle(dom, painter);
+
+		//Get the font and metric
+	QFont used_font = QETApp::diagramTextsFont(size);
+	QFontMetrics qfm(used_font);
+	QColor text_color = (dom.attribute("color") != "white"? Qt::black : Qt::white);
+
+		//Instanciate a QTextDocument (like the QGraphicsTextItem class)
+		//for generate the graphics rendering of the text
+	QTextDocument text_document;
+	text_document.setDefaultFont(used_font);
+	text_document.setPlainText(dom.attribute("text"));
+
+	painter.setTransform(QTransform(), false);
+	painter.translate(pos_x, pos_y);
+
+	qreal default_rotation_angle = 0.0;
+	if (QET::attributeIsAReal(dom, "rotation", &default_rotation_angle)) {
+		painter.rotate(default_rotation_angle);
+	}
+
+	/*
+		Deplace le systeme de coordonnees du QPainter pour effectuer le rendu au
+		bon endroit ; note : on soustrait l'ascent() de la police pour
+		determiner le coin superieur gauche du texte alors que la position
+		indiquee correspond a la baseline.
+	*/
+	QPointF qpainter_offset(0.0, -qfm.ascent());
+
+		//adjusts the offset by the margin of the text document
+	text_document.setDocumentMargin(0.0);
+
+	painter.translate(qpainter_offset);
+
+		// force the palette used to render the QTextDocument
+	QAbstractTextDocumentLayout::PaintContext ctx;
+	ctx.palette.setColor(QPalette::Text, text_color);
+	text_document.documentLayout() -> draw(&painter, ctx);
+
+	painter.restore();
+}
+
+/**
+ * @brief ElementPictureFactory::setPainterStyle
+ * apply the style store in dom to painter.
+ * @param dom
+ * @param painter
+ */
+void ElementPictureFactory::setPainterStyle(const QDomElement &dom, QPainter &painter) const
+{
+	QPen pen = painter.pen();
+	QBrush brush = painter.brush();
+
+	pen.setJoinStyle(Qt::BevelJoin);
+	pen.setCapStyle(Qt::SquareCap);
+
+		//Get the couples style/value
+	const QStringList styles = dom.attribute("style").split(";", QString::SkipEmptyParts);
+
+	QRegExp rx("^\\s*([a-z-]+)\\s*:\\s*([a-z-]+)\\s*$");
+	for (QString style : styles) {
+		if (rx.exactMatch(style)) {
+			QString style_name = rx.cap(1);
+			QString style_value = rx.cap(2);
+			if (style_name == "line-style") {
+				if (style_value == "dashed") pen.setStyle(Qt::DashLine);
+				else if (style_value == "dotted") pen.setStyle(Qt::DotLine);
+				else if (style_value == "dashdotted") pen.setStyle(Qt::DashDotLine);
+				else if (style_value == "normal") pen.setStyle(Qt::SolidLine);
+			} else if (style_name == "line-weight") {
+				if (style_value == "none") pen.setColor(QColor(0, 0, 0, 0));
+				else if (style_value == "thin") pen.setWidth(0);
+				else if (style_value == "normal") pen.setWidthF(1.0);
+				else if (style_value == "hight") pen.setWidthF(2.0);
+				else if (style_value == "eleve") pen.setWidthF(5.0);
+
+			} else if (style_name == "filling") {
+				if (style_value == "white") {
+					brush.setStyle(Qt::SolidPattern);
+					brush.setColor(Qt::white);
+				} else if (style_value == "black") {
+					brush.setStyle(Qt::SolidPattern);
+					brush.setColor(Qt::black);
+				} else if (style_value == "blue") {
+					brush.setStyle(Qt::SolidPattern);
+					brush.setColor(Qt::blue);
+				} else if (style_value == "red") {
+					brush.setStyle(Qt::SolidPattern);
+					brush.setColor(Qt::red);
+				} else if (style_value == "green") {
+					brush.setStyle(Qt::SolidPattern);
+					brush.setColor(Qt::green);
+				} else if (style_value == "gray") {
+					brush.setStyle(Qt::SolidPattern);
+					brush.setColor(Qt::gray);
+				} else if (style_value == "brun") {
+					brush.setStyle(Qt::SolidPattern);
+					brush.setColor(QColor(97, 44, 0));
+				} else if (style_value == "yellow") {
+					brush.setStyle(Qt::SolidPattern);
+					brush.setColor(Qt::yellow);
+				} else if (style_value == "cyan") {
+					brush.setStyle(Qt::SolidPattern);
+					brush.setColor(Qt::cyan);
+				} else if (style_value == "magenta") {
+					brush.setStyle(Qt::SolidPattern);
+					brush.setColor(Qt::magenta);
+				} else if (style_value == "lightgray") {
+					brush.setStyle(Qt::SolidPattern);
+					brush.setColor(Qt::lightGray);
+				} else if (style_value == "orange") {
+					brush.setStyle(Qt::SolidPattern);
+					brush.setColor(QColor(255, 128, 0));
+				} else if (style_value == "purple") {
+					brush.setStyle(Qt::SolidPattern);
+					brush.setColor(QColor(136, 28, 168));
+				}else if (style_value == "hor") {
+					brush.setStyle(Qt::HorPattern);
+					brush.setColor(Qt::black);
+				} else if (style_value == "ver") {
+					brush.setStyle(Qt::VerPattern);
+					brush.setColor(Qt::black);
+				} else if (style_value == "bdiag") {
+					brush.setStyle(Qt::BDiagPattern);
+					brush.setColor(Qt::black);
+				} else if (style_value == "fdiag") {
+					brush.setStyle(Qt::FDiagPattern);
+					brush.setColor(Qt::black);
+				} else if (style_value == "none") {
+					brush.setStyle(Qt::NoBrush);
+				}
+			} else if (style_name == "color") {
+				if (style_value == "black") {
+					pen.setColor(QColor(0, 0, 0, pen.color().alpha()));
+				} else if (style_value == "white") {
+					pen.setColor(QColor(255, 255, 255, pen.color().alpha()));
+				} else if (style_value == "red") {
+					pen.setColor(Qt::red);
+				}else if (style_value == "blue") {
+					pen.setColor(Qt::blue);
+				}else if (style_value == "green") {
+					pen.setColor(Qt::green);
+				}else if (style_value == "gray") {
+					pen.setColor(Qt::gray);
+				}else if (style_value == "brun") {
+					pen.setColor(QColor(97, 44, 0));
+				}else if (style_value == "yellow") {
+					pen.setColor(Qt::yellow);
+				}else if (style_value == "cyan") {
+					pen.setColor(Qt::cyan);
+				}else if (style_value == "magenta") {
+					pen.setColor(Qt::magenta);
+				}else if (style_value == "lightgray") {
+					pen.setColor(Qt::lightGray);
+				}else if (style_value == "orange") {
+					pen.setColor(QColor(255, 128, 0));
+				}else if (style_value == "purple") {
+					pen.setColor(QColor(136, 28, 168));
+				} else if (style_value == "none") {
+					pen.setBrush(Qt::transparent);
+				}
+			}
+		}
+	}
+
+	painter.setPen(pen);
+	painter.setBrush(brush);
+}

Added: trunk/sources/factory/elementpicturefactory.h
===================================================================
--- trunk/sources/factory/elementpicturefactory.h	                        (rev 0)
+++ trunk/sources/factory/elementpicturefactory.h	2018-08-23 19:41:58 UTC (rev 5492)
@@ -0,0 +1,111 @@
+/*
+	Copyright 2006-2018 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 ELEMENTPICTUREFACTORY_H
+#define ELEMENTPICTUREFACTORY_H
+
+#include <QMutex>
+#include <QSharedPointer>
+#include <QHash>
+
+class ElementsLocation;
+class QPicture;
+class QUuid;
+class QDomElement;
+class QPainter;
+
+/**
+ * @brief The ElementPictureFactory class
+ * This class is singleton factory, use
+ * to create and get the picture use by elements
+ */
+class ElementPictureFactory
+{
+	public :
+		struct primitives
+		{
+			QList<QLineF> m_lines;
+			QList<QRectF> m_rectangles;
+			QList<QRectF> m_circles;
+			QList<QVector<QPointF>> m_polygons;
+			QList<QVector<qreal>> m_arcs;
+		};
+		
+		
+		/**
+		 * @brief instance
+		 * @return The instance of the factory
+		 */
+		static ElementPictureFactory* instance()
+		{
+			static QMutex mutex;
+			if (!m_factory)
+			{
+				mutex.lock();
+				if (!m_factory) {
+					m_factory = new ElementPictureFactory();	
+				}
+				mutex.unlock();
+			}
+			return m_factory;
+		}
+		
+		/**
+		 * @brief dropInstance
+		 * Drop the instance of factory
+		 */
+		static void dropInstance()
+		{
+			static QMutex mutex;
+			if (m_factory)
+			{
+				mutex.lock();
+				delete m_factory;
+				m_factory = nullptr;
+				mutex.unlock();
+			}
+		}
+
+		void getPictures(const ElementsLocation &location, QPicture &picture, QPicture &low_picture);
+		QPixmap pixmap(const ElementsLocation &location);
+		ElementPictureFactory::primitives getPrimitives(const ElementsLocation &location);
+		
+	private:
+		ElementPictureFactory() {}
+		ElementPictureFactory (const ElementPictureFactory &);
+		ElementPictureFactory operator= (const ElementPictureFactory &);
+		~ElementPictureFactory() {}
+		
+		bool build(const ElementsLocation &location);
+		void parseElement(const QDomElement &dom, QPainter &painter, primitives &prim) const;
+		void parseLine   (const QDomElement &dom, QPainter &painter, primitives &prim) const;
+		void parseRect   (const QDomElement &dom, QPainter &painter, primitives &prim) const;
+		void parseEllipse(const QDomElement &dom, QPainter &painter, primitives &prim) const;
+		void parseCircle (const QDomElement &dom, QPainter &painter, primitives &prim) const;
+		void parseArc    (const QDomElement &dom, QPainter &painter, primitives &prim) const;
+		void parsePolygon(const QDomElement &dom, QPainter &painter, primitives &prim) const;
+		void parseText   (const QDomElement &dom, QPainter &painter, primitives &prim) const;
+		void setPainterStyle(const QDomElement &dom, QPainter &painter) const;
+		
+		QHash<QUuid, QPicture> m_pictures_H;
+		QHash<QUuid, QPicture> m_low_pictures_H;
+		QHash<QUuid, QPixmap> m_pixmap_H;
+		QHash<QUuid, primitives> m_primitives_H;
+		static ElementPictureFactory* m_factory;
+};
+
+#endif // ELEMENTPICTUREFACTORY_H

Modified: trunk/sources/nomenclature.h
===================================================================
--- trunk/sources/nomenclature.h	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/nomenclature.h	2018-08-23 19:41:58 UTC (rev 5492)
@@ -24,7 +24,6 @@
 #include "diagram.h"
 #include "qetgraphicsitem/element.h"
 #include "diagramcontent.h"
-#include "qetgraphicsitem/customelement.h"
 #include "diagramposition.h"
 
 class QETProject;

Modified: trunk/sources/qetapp.cpp
===================================================================
--- trunk/sources/qetapp.cpp	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetapp.cpp	2018-08-23 19:41:58 UTC (rev 5492)
@@ -32,6 +32,7 @@
 #include "generalconfigurationpage.h"
 #include "qetmessagebox.h"
 #include "projectview.h"
+#include "elementpicturefactory.h"
 
 #include <cstdlib>
 #include <iostream>
@@ -125,6 +126,7 @@
 		delete m_common_tbt_collection;
 	
 	ElementFactory::dropInstance();
+	ElementPictureFactory::dropInstance();
 	
 		//Delete all backup files
 	QDir dir(configDir() + "backup");

Modified: trunk/sources/qetdiagrameditor.cpp
===================================================================
--- trunk/sources/qetdiagrameditor.cpp	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetdiagrameditor.cpp	2018-08-23 19:41:58 UTC (rev 5492)
@@ -23,7 +23,6 @@
 #include "qetgraphicsitem/element.h"
 #include "elementspanelwidget.h"
 #include "conductorpropertieswidget.h"
-#include "qetgraphicsitem/customelement.h"
 #include "qetproject.h"
 #include "projectview.h"
 #include "recentfiles.h"
@@ -1127,17 +1126,6 @@
 }
 
 /**
-	@return the selected element in the current diagram view, or 0 if:
-	  * no diagram is being viewed in this editor.
-	  * no element is selected
-	  * more than one element is selected
-	  * the selected element is not a custom element
-*/
-CustomElement *QETDiagramEditor::currentCustomElement() const {
-	return(dynamic_cast<CustomElement *>(currentElement()));
-}
-
-/**
 	Cette methode permet de retrouver le projet contenant un schema donne.
 	@param diagram_view Schema dont il faut retrouver
 	@return la vue sur le projet contenant ce schema ou 0 s'il n'y en a pas
@@ -1332,8 +1320,8 @@
 	}
 	else if (value == "rotate_selected_text")
 		diagram->undoStack().push(new RotateTextsCommand(diagram));
-	else if (value == "find_selected_element" && currentCustomElement())
-		findElementInPanel(currentCustomElement()->location());
+	else if (value == "find_selected_element" && currentElement())
+		findElementInPanel(currentElement()->location());
 	else if (value == "edit_selected_element")
 		dv->editSelection();
 	else if (value == "group_selected_texts")
@@ -2117,7 +2105,7 @@
 	diagram view.
 */
 void QETDiagramEditor::editSelectedElementInEditor() {
-	if (CustomElement *selected_element = currentCustomElement()) {
+	if (Element *selected_element = currentElement()) {
 		editElementInEditor(selected_element -> location());
 	}
 }

Modified: trunk/sources/qetdiagrameditor.h
===================================================================
--- trunk/sources/qetdiagrameditor.h	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetdiagrameditor.h	2018-08-23 19:41:58 UTC (rev 5492)
@@ -84,7 +84,6 @@
 		ProjectView *currentProjectView() const;
 		DiagramView *currentDiagramView() const;
 		Element *currentElement() const;
-		CustomElement * currentCustomElement() const;
 		ProjectView *findProject(DiagramView *) const;
 		ProjectView *findProject(Diagram *) const;
 		ProjectView *findProject(QETProject *) const;

Deleted: trunk/sources/qetgraphicsitem/customelement.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/customelement.cpp	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetgraphicsitem/customelement.cpp	2018-08-23 19:41:58 UTC (rev 5492)
@@ -1,1049 +0,0 @@
-/*
-	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 "customelement.h"
-#include "diagram.h"
-#include "qetapp.h"
-#include "partline.h"
-#include <iostream>
-#include "terminal.h"
-#include "diagramposition.h"
-#include "diagramcontent.h"
-#include "dynamicelementtextitem.h"
-#include "partdynamictextfield.h"
-
-/**
-	Constructeur de la classe CustomElement. Permet d'instancier un element
-	utilisable comme un element fixe a la difference que l'element perso est
-	construit a partir d'une description au format XML. Celle-ci est recuperee
-	a l'emplacement indique.
-	@param location Emplacement de la definition d'element a utiliser
-	@param qgi Le QGraphicsItem parent de cet element
-	@param s Le Schema affichant cet element
-	@param state Un pointeur facultatif vers un entier. La valeur de cet entier
-	sera changee de maniere a refleter le deroulement de l'instanciation :
-		- 0 : L'instanciation a reussi
-		- 1 : l'emplacement n'a pas permis d'acceder a une definition d'element
-		- 2 : la definition n'etait pas lisible
-		- 3 : la definition n'etait pas valide / exploitable / utilisable
-		- 4 : Le document XML n'est pas un element "definition"
-		- 5 : Les attributs de la definition ne sont pas presents et / ou valides
-		- 6 : La definition est vide
-		- 7 : L'analyse d'un element XML decrivant une partie du dessin de l'element a echoue
-		- 8 : Aucune partie du dessin n'a pu etre chargee
-*/
-CustomElement::CustomElement(const ElementsLocation &location, QGraphicsItem *qgi, int *state) :
-	Element(qgi),
-	location_(location),
-	forbid_antialiasing(false)
-{
-
-	if(Q_UNLIKELY( !(location.isElement() && location.exist()) ))
-	{
-		if (state) *state = 1;
-		return;
-	}
-
-		//Start from empty lists.
-	m_lines.clear();
-	m_rectangles.clear();
-	m_circles.clear();
-	m_polygons.clear();
-	m_arcs.clear();
-	setPrefix(autonum::elementPrefixForLocation(location));
-
-	int elmt_state;
-	buildFromXml(location.xml(), &elmt_state);
-	if (state) *state = elmt_state;
-	if (elmt_state) return;
-
-	if (state) *state = 0;
-}
-
-/**
-	Construit l'element personnalise a partir d'un element XML representant sa
-	definition.
-	@param xml_def_elmt
-	@param state Un pointeur facultatif vers un entier. La valeur de cet entier
-	sera changee de maniere a refleter le deroulement de l'instanciation :
-		- 0 : La construction s'est bien passee
-		- 4 : Le document XML n'est pas un element "definition"
-		- 5 : Les attributs de la definition ne sont pas presents et / ou valides
-		- 6 : La definition est vide
-		- 7 : L'analyse d'un element XML decrivant une partie du dessin de l'element a echoue
-		- 8 : Aucune partie du dessin n'a pu etre chargee
-	@return true si le chargement a reussi, false sinon
-*/
-bool CustomElement::buildFromXml(const QDomElement &xml_def_elmt, int *state)
-{
-	m_state = QET::GIBuildingFromXml;
-
-	if (xml_def_elmt.tagName() != "definition" || xml_def_elmt.attribute("type") != "element")
-	{
-		if (state) *state = 4;
-		m_state = QET::GIOK;
-		return(false);
-	}
-
-		//Check if the curent version can read the xml description
-	if (xml_def_elmt.hasAttribute("version"))
-	{
-		bool conv_ok;
-		qreal element_version = xml_def_elmt.attribute("version").toDouble(&conv_ok);
-		if (conv_ok && QET::version.toDouble() < element_version)
-		{
-			std::cerr << qPrintable(
-				QObject::tr("Avertissement : l'élément "
-				" a été enregistré avec une version"
-				" ultérieure de QElectroTech.")
-			) << std::endl;
-		}
-	}
-
-		//This attribute must be present and valid
-	int w, h, hot_x, hot_y;
-	if (
-		!QET::attributeIsAnInteger(xml_def_elmt, QString("width"), &w) ||\
-		!QET::attributeIsAnInteger(xml_def_elmt, QString("height"), &h) ||\
-		!QET::attributeIsAnInteger(xml_def_elmt, QString("hotspot_x"), &hot_x) ||\
-		!QET::attributeIsAnInteger(xml_def_elmt, QString("hotspot_y"), &hot_y) ||\
-		!validOrientationAttribute(xml_def_elmt)
-	) {
-		if (state) *state = 5;
-		m_state = QET::GIOK;
-		return(false);
-	}
-
-	setSize(w, h);
-	setHotspot(QPoint(hot_x, hot_y));
-
-		//the definition must have childs
-	if (xml_def_elmt.firstChild().isNull())
-	{
-		if (state) *state = 6;
-		m_state = QET::GIOK;
-		return(false);
-	}
-
-		//Init the QPainter for draw the elemennt
-	QPainter qp;
-	qp.begin(&drawing);
-
-	QPainter low_zoom_qp;
-	low_zoom_qp.begin(&low_zoom_drawing);
-	QPen tmp;
-	tmp.setWidthF(1.0); //Vaudoo line to take into account the setCosmetic - don't remove
-	tmp.setCosmetic(true);
-	low_zoom_qp.setPen(tmp);
-
-		//Extract the names
-	names.fromXml(xml_def_elmt);
-	setToolTip(name());
-
-		//load kind informations
-	m_kind_informations.fromXml(xml_def_elmt.firstChildElement("kindInformations"), "kindInformation");
-		//load element information
-	m_element_informations.fromXml(xml_def_elmt.firstChildElement("elementInformations"), "elementInformation");
-
-		//scroll of the Children of the Definition: Parts of the Drawing
-	int parsed_elements_count = 0;
-	for (QDomNode node = xml_def_elmt.firstChild() ; !node.isNull() ; node = node.nextSibling())
-	{
-		QDomElement elmts = node.toElement();
-		if (elmts.isNull())
-			continue;
-		
-		if (elmts.tagName() == "description")
-		{
-				//Minor workaround to find if there is a "input" tagg as label.
-				//If not, we set the tagg "label" to the first "input.
-			QList <QDomElement> input_field;
-			bool have_label = false;
-			for (QDomElement input_node = node.firstChildElement("input") ; !input_node.isNull() ; input_node = input_node.nextSiblingElement("input"))
-			{
-				if (!input_node.isNull())
-				{
-					input_field << input_node;
-					if (input_node.attribute("tagg", "none") == "label")
-						have_label = true;
-				}
-			}
-			if(!have_label && !input_field.isEmpty())
-				input_field.first().setAttribute("tagg", "label");
-			
-				//Manage the graphic description = part of drawing
-			for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling())
-			{
-				QDomElement qde = n.toElement();
-				if (qde.isNull())
-					continue;
-				
-				if (parseElement(qde, qp))
-				{
-					++ parsed_elements_count;
-
-					QString current_tag = qde.tagName();
-					if (current_tag != "terminal" && current_tag != "input" && current_tag != PartDynamicTextField::xmlTaggName())
-					{
-						forbid_antialiasing = true;
-						parseElement(qde, low_zoom_qp, false);
-						forbid_antialiasing = false;
-					}
-				}
-				else
-				{
-					if (state)
-						*state = 7;
-					m_state = QET::GIOK;
-					return(false);
-				}
-			}
-		}
-	}
-
-		//End of the drawing
-	qp.end();
-	low_zoom_qp.end();
-
-
-		//They must be at least one parsed graphics part
-	if (!parsed_elements_count)
-	{
-		if (state)
-			*state = 8;
-		m_state = QET::GIOK;
-		return(false);
-	}
-	else
-	{
-		if (state)
-			*state = 0;
-		m_state = QET::GIOK;
-		return(true);
-	}
-}
-
-/**
-	Destructeur
-*/
-CustomElement::~CustomElement() {
-	qDeleteAll (m_lines);
-	qDeleteAll (m_rectangles);
-	qDeleteAll (m_circles);
-	qDeleteAll (m_polygons);
-	qDeleteAll (m_arcs);
-	qDeleteAll (m_terminals);
-}
-
-/// @return la liste des bornes de cet element
-QList<Terminal *> CustomElement::terminals() const {
-	return(m_terminals);
-}
-
-/**
- * @brief CustomElement::conductors
- * @return The list of conductor docked to this element
- * the list is sorted according to the position of the terminal where the conductor is docked
- * from top to bottom, and left to right.
- */
-QList<Conductor *> CustomElement::conductors() const
-{
-	QList<Conductor *> conductors;
-	
-	for(Terminal *t : m_terminals)
-		conductors << t -> conductors();
-	
-	return(conductors);
-}
-
-/// @return the list of lines
-QList<QLineF *> CustomElement::lines() const {
-	return(m_lines);
-}
-
-/// @return the list of rectangles
-QList<QRectF *> CustomElement::rectangles() const {
-	return(m_rectangles);
-}
-
-/// @return the list of bounding rectangles for circles
-QList<QRectF *> CustomElement::circles() const {
-	return(m_circles);
-}
-
-/// @return the list of bounding rectangles for circles
-QList<QVector<QPointF> *> CustomElement::polygons() const {
-	return(m_polygons);
-}
-
-/// @return the list of arcs
-QList<QVector<qreal> *> CustomElement::arcs() const {
-	return(m_arcs);
-}
-
-/**
-	Dessine le composant sur le Diagram
-	@param qp Le QPainter a utiliser pour dessiner l'element
-	@param options Les options graphiques
-*/
-void CustomElement::paint(QPainter *qp, const QStyleOptionGraphicsItem *options) {
-	if (options && options -> levelOfDetail < 1.0) {
-		low_zoom_drawing.play(qp);
-	} else {
-		drawing.play(qp);
-	}
-}
-
-/**
-	Analyse et prend en compte un element XML decrivant une partie du dessin
-	de l'element perso. Si l'analyse reussit, la partie est ajoutee au dessin.
-	Cette partie peut etre une borne, une ligne, une ellipse, un cercle, un arc
-	de cercle ou un polygone. Cette methode renvoie false si l'analyse
-	d'une de ces formes echoue. Si l'analyse reussit ou dans le cas d'une forme
-	inconnue, cette methode renvoie true. A l'exception des bornes, toutes les
-	formes peuvent avoir un attribut style. @see setPainterStyle
-	@param e L'element XML a analyser
-	@param qp Le QPainter a utiliser pour dessiner l'element perso
-	@return true si l'analyse reussit, false sinon
-*/
-bool CustomElement::parseElement(QDomElement &e, QPainter &qp, bool addtolist)
-{
-	if      (e.tagName() == "terminal")     return(parseTerminal(e));
-	else if (e.tagName() == "line")         return(parseLine(e, qp, addtolist));
-	else if (e.tagName() == "rect")         return(parseRect(e, qp, addtolist));
-	else if (e.tagName() == "ellipse")      return(parseEllipse(e, qp, addtolist));
-	else if (e.tagName() == "circle")       return(parseCircle(e, qp, addtolist));
-	else if (e.tagName() == "arc")          return(parseArc(e, qp, addtolist));
-	else if (e.tagName() == "polygon")      return(parsePolygon(e, qp, addtolist));
-	else if (e.tagName() == "text")         return(parseText(e, qp, addtolist));
-	else if (e.tagName() == "input")        return(parseInput(e));
-	else if (e.tagName() == "dynamic_text") return(parseDynamicText(e));
-	else return(true);
-}
-
-/**
-	Analyse un element XML suppose representer une ligne. Si l'analyse
-	reussit, la ligne est ajoutee au dessin.
-	La ligne est definie par les attributs suivants :
-		- x1, y1 : reels, coordonnees d'une extremite de la ligne
-		- x2, y2 : reels, coordonnees de l'autre extremite de la ligne
-
-	@param e L'element XML a analyser
-	@param qp Le QPainter a utiliser pour dessiner l'element perso
-	@return true si l'analyse reussit, false sinon
-*/
-bool CustomElement::parseLine(QDomElement &e, QPainter &qp, bool addtolist) {
-	// verifie la presence et la validite des attributs obligatoires
-	qreal x1, y1, x2, y2;
-	if (!QET::attributeIsAReal(e, QString("x1"), &x1)) return(false);
-	if (!QET::attributeIsAReal(e, QString("y1"), &y1)) return(false);
-	if (!QET::attributeIsAReal(e, QString("x2"), &x2)) return(false);
-	if (!QET::attributeIsAReal(e, QString("y2"), &y2)) return(false);
-
-	Qet::EndType first_end = Qet::endTypeFromString(e.attribute("end1"));
-	Qet::EndType second_end = Qet::endTypeFromString(e.attribute("end2"));
-	qreal length1, length2;
-	if (!QET::attributeIsAReal(e, QString("length1"), &length1)) length1 = 1.5;
-	if (!QET::attributeIsAReal(e, QString("length2"), &length2)) length2 = 1.5;
-
-	qp.save();
-	setPainterStyle(e, qp);
-	QPen t = qp.pen();
-	t.setJoinStyle(Qt::MiterJoin);
-	qp.setPen(t);
-
-	QLineF line(x1, y1, x2, y2);
-
-	if (addtolist){
-	//Add line to the list
-		QLineF *newLine = new QLineF(line);
-		m_lines << newLine;
-	}
-
-	QPointF point1(line.p1());
-	QPointF point2(line.p2());
-
-	qreal line_length(line.length());
-	qreal pen_width = qp.pen().widthF();
-
-	// determine s'il faut dessiner les extremites
-	bool draw_1st_end, draw_2nd_end;
-	qreal reduced_line_length = line_length - (length1 * PartLine::requiredLengthForEndType(first_end));
-	draw_1st_end = first_end && reduced_line_length >= 0;
-	if (draw_1st_end) {
-		reduced_line_length -= (length2 * PartLine::requiredLengthForEndType(second_end));
-	} else {
-		reduced_line_length = line_length - (length2 * PartLine::requiredLengthForEndType(second_end));
-	}
-	draw_2nd_end = second_end && reduced_line_length >= 0;
-
-	// dessine la premiere extremite
-	QPointF start_point, stop_point;
-	if (draw_1st_end) {
-		QList<QPointF> four_points1(PartLine::fourEndPoints(point1, point2, length1));
-		if (first_end == Qet::Circle) {
-			qp.drawEllipse(QRectF(four_points1[0] - QPointF(length1, length1), QSizeF(length1 * 2.0, length1 * 2.0)));
-			start_point = four_points1[1];
-		} else if (first_end == Qet::Diamond) {
-			qp.drawPolygon(QPolygonF() << four_points1[1] << four_points1[2] << point1 << four_points1[3]);
-			start_point = four_points1[1];
-		} else if (first_end == Qet::Simple) {
-			qp.drawPolyline(QPolygonF() << four_points1[3] << point1 << four_points1[2]);
-			start_point = point1;
-
-		} else if (first_end == Qet::Triangle) {
-			qp.drawPolygon(QPolygonF() << four_points1[0] << four_points1[2] << point1 << four_points1[3]);
-			start_point = four_points1[0];
-		}
-
-		// ajuste le depart selon l'epaisseur du trait
-		if (pen_width && (first_end == Qet::Simple || first_end == Qet::Circle)) {
-			start_point = QLineF(start_point, point2).pointAt(pen_width / 2.0 / line_length);
-		}
-	} else {
-		start_point = point1;
-	}
-
-	// dessine la seconde extremite
-	if (draw_2nd_end) {
-		QList<QPointF> four_points2(PartLine::fourEndPoints(point2, point1, length2));
-		if (second_end == Qet::Circle) {
-			qp.drawEllipse(QRectF(four_points2[0] - QPointF(length2, length2), QSizeF(length2 * 2.0, length2 * 2.0)));
-			stop_point = four_points2[1];
-		} else if (second_end == Qet::Diamond) {
-			qp.drawPolygon(QPolygonF() << four_points2[2] << point2 << four_points2[3] << four_points2[1]);
-			stop_point = four_points2[1];
-		} else if (second_end == Qet::Simple) {
-			qp.drawPolyline(QPolygonF() << four_points2[3] << point2 << four_points2[2]);
-			stop_point = point2;
-		} else if (second_end == Qet::Triangle) {
-			qp.drawPolygon(QPolygonF() << four_points2[0] << four_points2[2] << point2 << four_points2[3] << four_points2[0]);
-			stop_point = four_points2[0];
-		}
-
-		// ajuste l'arrivee selon l'epaisseur du trait
-		if (pen_width && (second_end == Qet::Simple || second_end == Qet::Circle)) {
-			stop_point = QLineF(point1, stop_point).pointAt((line_length - (pen_width / 2.0)) / line_length);
-		}
-	} else {
-		stop_point = point2;
-	}
-
-	qp.drawLine(start_point, stop_point);
-
-	qp.restore();
-	return(true);
-}
-
-/**
-	Analyse un element XML suppose representer un rectangle. Si l'analyse
-	reussit, le rectangle est ajoute au dessin.
-	Le rectangle est defini par les attributs suivants :
-		- x : abscisse du coin superieur gauche du rectangle
-		- y : ordonnee du coin superieur gauche du rectangle
-		- width : largeur du rectangle
-		- height : hauteur du rectangle
-
-	@param e L'element XML a analyser
-	@param qp Le QPainter a utiliser pour dessiner l'element perso
-	@return true si l'analyse reussit, false sinon
-*/
-bool CustomElement::parseRect(QDomElement &e, QPainter &qp, bool addtolist)
-{
-	// verifie la presence des attributs obligatoires
-	qreal rect_x, rect_y, rect_w, rect_h, rect_rx, rect_ry;
-	if (!QET::attributeIsAReal(e, QString("x"),       &rect_x))  return(false);
-	if (!QET::attributeIsAReal(e, QString("y"),       &rect_y))  return(false);
-	if (!QET::attributeIsAReal(e, QString("width"),   &rect_w))  return(false);
-	if (!QET::attributeIsAReal(e, QString("height"),  &rect_h))  return(false);
-	rect_rx = e.attribute("rx", "0").toDouble();
-	rect_ry = e.attribute("ry", "0").toDouble();
-
-	if (addtolist){
-		//Add rectangle to the list
-		QRectF *rect = new QRectF(rect_x, rect_y, rect_w, rect_h);
-		m_rectangles << rect;
-	}
-
-	qp.save();
-	setPainterStyle(e, qp);
-
-	// force le type de jointures pour les rectangles
-	QPen p = qp.pen();
-	p.setJoinStyle(Qt::MiterJoin);
-	qp.setPen(p);
-
-	qp.drawRoundedRect(QRectF(rect_x, rect_y, rect_w, rect_h), rect_rx, rect_ry);
-	qp.restore();
-	return(true);
-}
-
-/**
-	Analyse un element XML suppose representer un cercle. Si l'analyse
-	reussit, le cercle est ajoute au dessin.
-	Le cercle est defini par les attributs suivants :
-		- x : abscisse du coin superieur gauche de la quadrature du cercle
-		- y : ordonnee du coin superieur gauche de la quadrature du cercle
-		- diameter : diametre du cercle
-
-	@param e L'element XML a analyser
-	@param qp Le QPainter a utiliser pour dessiner l'element perso
-	@return true si l'analyse reussit, false sinon
-*/
-bool CustomElement::parseCircle(QDomElement &e, QPainter &qp, bool addtolist) {
-	// verifie la presence des attributs obligatoires
-	qreal cercle_x, cercle_y, cercle_r;
-	if (!QET::attributeIsAReal(e, QString("x"),        &cercle_x)) return(false);
-	if (!QET::attributeIsAReal(e, QString("y"),        &cercle_y)) return(false);
-	if (!QET::attributeIsAReal(e, QString("diameter"), &cercle_r)) return(false);
-	qp.save();
-	setPainterStyle(e, qp);
-	QRectF circle_bounding_rect(cercle_x, cercle_y, cercle_r, cercle_r);
-
-	if (addtolist){
-		// Add circle to list
-		QRectF *circle = new QRectF(circle_bounding_rect);
-		m_circles << circle;
-	}
-
-	qp.drawEllipse(circle_bounding_rect);
-	qp.restore();
-	return(true);
-}
-
-/**
-	Analyse un element XML suppose representer une ellipse. Si l'analyse
-	reussit, l'ellipse est ajoutee au dessin.
-	L'ellipse est definie par les attributs suivants :
-		- x : abscisse du coin superieur gauche du rectangle dans lequel s'inscrit l'ellipse
-		- y : ordonnee du coin superieur gauche du rectangle dans lequel s'inscrit l'ellipse
-		- width : dimension de la diagonale horizontale de l'ellipse
-		- height : dimension de la diagonale verticale de l'ellipse
-
-	@param e L'element XML a analyser
-	@param qp Le QPainter a utiliser pour dessiner l'element perso
-	@return true si l'analyse reussit, false sinon
-*/
-bool CustomElement::parseEllipse(QDomElement &e, QPainter &qp, bool addtolist) {
-	// verifie la presence des attributs obligatoires
-	qreal ellipse_x, ellipse_y, ellipse_l, ellipse_h;
-	if (!QET::attributeIsAReal(e, QString("x"),       &ellipse_x))  return(false);
-	if (!QET::attributeIsAReal(e, QString("y"),       &ellipse_y))  return(false);
-	if (!QET::attributeIsAReal(e, QString("width"), &ellipse_l))  return(false);
-	if (!QET::attributeIsAReal(e, QString("height"), &ellipse_h))  return(false);
-	qp.save();
-	setPainterStyle(e, qp);
-
-	if (addtolist){
-		QVector<qreal> *arc = new QVector<qreal>;
-		arc -> push_back(ellipse_x);
-		arc -> push_back(ellipse_y);
-		arc -> push_back(ellipse_l);
-		arc -> push_back(ellipse_h);
-		arc -> push_back(0);
-		arc -> push_back(360);
-		m_arcs << arc;
-	}
-
-	qp.drawEllipse(QRectF(ellipse_x, ellipse_y, ellipse_l, ellipse_h));
-	qp.restore();
-	return(true);
-}
-
-/**
-	Analyse un element XML suppose representer un arc de cercle. Si l'analyse
-	reussit, l'arc de cercle est ajoute au dessin.
-	L'arc de cercle est defini par les quatres parametres d'une ellipse (en fait
-	l'ellipse dans laquelle s'inscrit l'arc de cercle) auxquels s'ajoutent les
-	attributs suivants :
-		- start : angle de depart : l'angle "0 degre" est a trois heures
-		- angle : etendue (en degres) de l'arc de cercle ; une valeur positive
-		va dans le sens contraire des aiguilles d'une montre
-
-	@param e L'element XML a analyser
-	@param qp Le QPainter a utiliser pour dessiner l'element perso
-	@return true si l'analyse reussit, false sinon
-*/
-bool CustomElement::parseArc(QDomElement &e, QPainter &qp, bool addtolist) {
-	// verifie la presence des attributs obligatoires
-	qreal arc_x, arc_y, arc_l, arc_h, arc_s, arc_a;
-	if (!QET::attributeIsAReal(e, QString("x"),       &arc_x))  return(false);
-	if (!QET::attributeIsAReal(e, QString("y"),       &arc_y))  return(false);
-	if (!QET::attributeIsAReal(e, QString("width"),   &arc_l))  return(false);
-	if (!QET::attributeIsAReal(e, QString("height"),  &arc_h))  return(false);
-	if (!QET::attributeIsAReal(e, QString("start"),   &arc_s))  return(false);
-	if (!QET::attributeIsAReal(e, QString("angle"),   &arc_a))  return(false);
-
-	qp.save();
-	setPainterStyle(e, qp);
-
-	if (addtolist){
-		QVector<qreal> *arc = new QVector<qreal>;
-		arc -> push_back(arc_x);
-		arc -> push_back(arc_y);
-		arc -> push_back(arc_l);
-		arc -> push_back(arc_h);
-		arc -> push_back(arc_s);
-		arc -> push_back(arc_a);
-		m_arcs << arc;
-	}
-
-	qp.drawArc(QRectF(arc_x, arc_y, arc_l, arc_h), (int)(arc_s * 16), (int)(arc_a * 16));
-	qp.restore();
-	return(true);
-}
-
-/**
-	Analyse un element XML suppose representer un polygone. Si l'analyse
-	reussit, le polygone est ajoute au dessin.
-	Le polygone est defini par une serie d'attributs x1, x2, ..., xn et autant
-	d'attributs y1, y2, ..., yn representant les coordonnees des differents
-	points du polygone.
-	Il est possible d'obtenir un polygone non ferme en utilisant closed="false"
-	@param e L'element XML a analyser
-	@param qp Le QPainter a utiliser pour dessiner l'element perso
-	@return true si l'analyse reussit, false sinon
-*/
-bool CustomElement::parsePolygon(QDomElement &e, QPainter &qp, bool addtolist) {
-	int i = 1;
-	while(true) {
-		if (QET::attributeIsAReal(e, QString("x%1").arg(i)) && QET::attributeIsAReal(e, QString("y%1").arg(i))) ++ i;
-		else break;
-	}
-	if (i < 3) return(false);
-	QVector<QPointF> points; // empty vector created instead of default initialized vector with i-1 elements.
-	for (int j = 1 ; j < i ; ++ j) {
-		points.insert(
-			j - 1,
-			QPointF(
-				e.attribute(QString("x%1").arg(j)).toDouble(),
-				e.attribute(QString("y%1").arg(j)).toDouble()
-			)
-		);
-	}
-
-	qp.save();
-	setPainterStyle(e, qp);
-	if (e.attribute("closed") == "false") qp.drawPolyline(points.data(), i-1);
-	else {
-		qp.drawPolygon(points.data(), i-1);
-
-		// insert first point at the end again for DXF export.
-		points.push_back(points[0]);
-	}
-	if (addtolist){
-		// Add to list of polygons.
-		QVector<QPointF> *poly = new QVector<QPointF>(points);
-		m_polygons << poly;
-	}
-
-	qp.restore();
-	return(true);
-}
-
-/**
-	Analyse un element XML suppose representer un texte. Si l'analyse
-	reussit, le texte est ajoute au dessin.
-	Le texte est defini par une position, une chaine de caracteres et une
-	taille.
-	@param e L'element XML a analyser
-	@param qp Le QPainter a utiliser pour dessiner l'element perso
-	@return true si l'analyse reussit, false sinon
-*/
-bool CustomElement::parseText(QDomElement &e, QPainter &qp, bool addtolist) {
-	Q_UNUSED(addtolist);
-	qreal pos_x, pos_y;
-	int size;
-	if (
-		!QET::attributeIsAReal(e, "x", &pos_x) ||\
-		!QET::attributeIsAReal(e, "y", &pos_y) ||\
-		!QET::attributeIsAnInteger(e, "size", &size) ||\
-		!e.hasAttribute("text")
-	) return(false);
-
-	qp.save();
-	setPainterStyle(e, qp);
-
-	// determine la police a utiliser et en recupere les metriques associees
-	QFont used_font = QETApp::diagramTextsFont(size);
-	QFontMetrics qfm(used_font);
-	QColor text_color = (e.attribute("color") != "white"? Qt::black : Qt::white);
-
-	// instancie un QTextDocument (comme la classe QGraphicsTextItem) pour
-	// generer le rendu graphique du texte
-	QTextDocument text_document;
-	text_document.setDefaultFont(used_font);
-	text_document.setPlainText(e.attribute("text"));
-
-	// Se positionne aux coordonnees indiquees dans la description du texte
-	qp.setTransform(QTransform(), false);
-	qp.translate(pos_x, pos_y);
-
-	// Pivote le systeme de coordonnees du QPainter pour effectuer le rendu
-	// dans le bon sens
-	qreal default_rotation_angle = 0.0;
-	if (QET::attributeIsAReal(e, "rotation", &default_rotation_angle)) {
-		qp.rotate(default_rotation_angle);
-	}
-
-	/*
-		Deplace le systeme de coordonnees du QPainter pour effectuer le rendu au
-		bon endroit ; note : on soustrait l'ascent() de la police pour
-		determiner le coin superieur gauche du texte alors que la position
-		indiquee correspond a la baseline.
-	*/
-	QPointF qpainter_offset(0.0, -qfm.ascent());
-
-		//adjusts the offset by the margin of the text document
-	text_document.setDocumentMargin(0.0);
-
-	qp.translate(qpainter_offset);
-
-	// force the palette used to render the QTextDocument
-	QAbstractTextDocumentLayout::PaintContext ctx;
-	ctx.palette.setColor(QPalette::Text, text_color);
-	text_document.documentLayout() -> draw(&qp, ctx);
-
-	qp.restore();
-	return(true);
-}
-
-/**
-	Analyse un element XML suppose representer un champ de texte editable par
-	l'utilisateur. Si l'analyse reussit, le champ est ajoute au dessin.
-	Le texte est defini par :
-		- une position
-		- une chaine de caracteres facultative utilisee comme valeur par defaut
-		- une taille
-		- le fait de subir les rotations de l'element ou non
-	@param dom_element L'element XML a analyser
-	@return Un pointeur vers l'objet ElementTextItem ainsi cree si l'analyse reussit, 0 sinon
-*/
-bool CustomElement::parseInput(QDomElement &dom_element) {
-	qreal pos_x, pos_y;
-	int size;
-	if (
-		!QET::attributeIsAReal(dom_element, "x", &pos_x) ||\
-		!QET::attributeIsAReal(dom_element, "y", &pos_y) ||\
-		!QET::attributeIsAnInteger(dom_element, "size", &size)
-	) return(false);
-	else
-	{
-		DynamicElementTextItem *deti = new DynamicElementTextItem(this);
-		deti->setText(dom_element.attribute("text", "_"));
-		deti->setFontSize(dom_element.attribute("size", QString::number(9)).toInt());
-		deti->setRotation(dom_element.attribute("rotation", QString::number(0)).toDouble());
-
-		if(dom_element.attribute("tagg", "none") != "none")
-		{
-			deti->setTextFrom(DynamicElementTextItem::ElementInfo);
-			deti->setInfoName(dom_element.attribute("tagg"));
-		}
-		
-			//the origin transformation point of PartDynamicTextField is the top left corner, no matter the font size
-			//The origin transformation point of ElementTextItem is the middle of left edge, and so by definition, change with the size of the font
-			//We need to use a QMatrix to find the pos of this text from the saved pos of text item 
-		QMatrix matrix;
-			//First make the rotation
-		matrix.rotate(dom_element.attribute("rotation", "0").toDouble());
-		QPointF pos = matrix.map(QPointF(0, -deti->boundingRect().height()/2));
-		matrix.reset();
-			//Second translate to the pos
-		QPointF p(dom_element.attribute("x", QString::number(0)).toDouble(),
-				  dom_element.attribute("y", QString::number(0)).toDouble());
-		matrix.translate(p.x(), p.y());
-		deti->setPos(matrix.map(pos));
-		m_converted_text_from_xml_description.insert(deti, p);
-		return true;
-	}
-	
-	return false;
-}
-
-/**
- * @brief CustomElement::parseDynamicText
- * Create the dynamic text field describ in @dom_element
- * @param dom_element
- * @return 
- */
-DynamicElementTextItem *CustomElement::parseDynamicText(QDomElement &dom_element)
-{
-	DynamicElementTextItem *deti = new DynamicElementTextItem(this);
-		//Because the xml description of a .elmt file is the same as how a dynamic text field is save to xml in a .qet file
-		//wa call fromXml, we just change the tagg name (.elmt = dynamic_text, .qet = dynamic_elmt_text)
-		//and the uuid (because the uuid, is the uuid of the descritpion and not the uuid of instantiated dynamic text field)
-	
-	QDomElement dom(dom_element.cloneNode(true).toElement());
-	dom.setTagName(DynamicElementTextItem::xmlTaggName());
-	deti->fromXml(dom);
-	deti->m_uuid = QUuid::createUuid();
-	this->addDynamicTextItem(deti);
-	return deti;
-}
-
-/**
-	Analyse un element XML suppose representer une borne. Si l'analyse
-	reussit, la borne est ajoutee a l'element.
-	Une borne est definie par les attributs suivants :
-		- x, y : coordonnees de la borne
-		- orientation  : orientation de la borne = Nord (n), Sud (s), Est (e) ou Ouest (w)
-
-	@param e L'element XML a analyser
-	@return Un pointeur vers l'objet Terminal ainsi cree, 0 sinon
-*/
-Terminal *CustomElement::parseTerminal(QDomElement &e) {
-	// verifie la presence et la validite des attributs obligatoires
-	qreal terminalx, terminaly;
-	Qet::Orientation terminalo;
-	if (!QET::attributeIsAReal(e, QString("x"), &terminalx)) return(nullptr);
-	if (!QET::attributeIsAReal(e, QString("y"), &terminaly)) return(nullptr);
-	if (!e.hasAttribute("orientation")) return(nullptr);
-	if (e.attribute("orientation") == "n") terminalo = Qet::North;
-	else if (e.attribute("orientation") == "s") terminalo = Qet::South;
-	else if (e.attribute("orientation") == "e") terminalo = Qet::East;
-	else if (e.attribute("orientation") == "w") terminalo = Qet::West;
-	else return(nullptr);
-	Terminal *new_terminal = new Terminal(terminalx, terminaly, terminalo, this);
-	m_terminals << new_terminal;
-	
-		//Sort from top to bottom and left to rigth
-	std::sort(m_terminals.begin(), m_terminals.end(), [](Terminal *a, Terminal *b)
-	{
-		if(a->dockConductor().y() == b->dockConductor().y())
-			return (a->dockConductor().x() < b->dockConductor().x());
-		else
-			return (a->dockConductor().y() < b->dockConductor().y());
-	});
-	
-	return(new_terminal);
-}
-
-/**
-	Active / desactive l'antialiasing sur un QPainter
-	@param qp Le QPainter a modifier
-	@param aa Booleen a true pour activer l'antialiasing, a false pour le desactiver
-*/
-void CustomElement::setQPainterAntiAliasing(QPainter &qp, bool aa) {
-	if (forbid_antialiasing) aa = false;
-	qp.setRenderHint(QPainter::Antialiasing,          aa);
-	qp.setRenderHint(QPainter::TextAntialiasing,      aa);
-	qp.setRenderHint(QPainter::SmoothPixmapTransform, aa);
-}
-
-/**
-	Verifie si l'attribut "orientation" de l'element XML e correspond bien a la
-	syntaxe decrivant les orientations possibles pour un element.
-	Cette syntaxe comprend exactement 4 lettres :
-		- une pour le Nord
-		- une pour l'Est
-		- une pour le Sud
-		- une pour l'Ouest
-
-	Pour chaque orientation, on indique si elle est :
-		- l'orientation par defaut : d
-		- une orientation autorisee : y
-		- une orientation interdire : n
-
-	Exemple : "dnny" represente un element par defaut oriente vers le nord et qui
-	peut etre oriente vers l'ouest mais pas vers le sud ou vers l'est.
-	@param e Element XML
-	@return true si l'attribut "orientation" est valide, false sinon
-*/
-bool CustomElement::validOrientationAttribute(const QDomElement &e) {
-	int ori = e.attribute("orientation").toInt();
-	if(ori >= 0 && ori <=3) return true;
-	return false;
-}
-
-/**
-	Applique les parametres de style definis dans l'attribut "style" de
-	l'element XML e au QPainter qp
-	Les styles possibles sont :
-		- line-style : style du trait
-			- dashed : trait en pointilles (tirets)
-			- dashdotted : Traits et points
-			- dotted : trait en pointilles (points)
-			- normal : trait plein [par defaut]
-		- line-weight : epaiseur du trait
-			- thin : trait fin
-			- normal : trait d'epaisseur 1 [par defaut]
-			- none : trait invisible
-			- forte : trait d'epaisseur 2
-			- eleve : trait d'epaisseur 5
-		- filling : remplissage de la forme
-			- white : remplissage blanc
-			- black : remplissage noir
-			 - red   : remplissage rouge
-			- blue  : remplissage bleu
-			- green : remplissage vert
-			- gray : remplissage gris
-			- brun : remplissage marron
-			- yellow : remplissage jaune
-			- cyan : remplissage cyan
-			- lightgray : remplissage gris clair
-			- orange : remplissage orange
-			- purple : remplissage violet
-			- none : pas de remplissage [par defaut]
-		- color : couleur du trait et du texte
-			- white : trait noir [par defaut]
-			- black : trait blanc
-			- red   : trait rouge
-			- blue  : trait bleu
-			- green : trait vert
-			- gray : trait gris
-			- brun : trait marron
-			- yellow : trait jaune
-			- cyan : trait cyan
-			- lightgray : trait gris clair
-			- orange : trait orange
-			- purple : trait violet
-			- lignes Horizontales
-			- lignes Verticales
-			- hachures gauche
-			- hachures  droite
-			- none : pas de contour
-
-	Les autres valeurs ne sont pas prises en compte.
-	@param e L'element XML a parser
-	@param qp Le QPainter a modifier en fonction des styles
-*/
-void CustomElement::setPainterStyle(QDomElement &e, QPainter &qp) {
-	// recupere le QPen et la QBrush du QPainter
-	QPen pen = qp.pen();
-	QBrush brush = qp.brush();
-
-	// attributs par defaut
-	pen.setJoinStyle(Qt::BevelJoin);
-	pen.setCapStyle(Qt::SquareCap);
-
-	// recupere la liste des couples style / valeur
-	QStringList styles = e.attribute("style").split(";", QString::SkipEmptyParts);
-
-	// agit sur le QPen et la QBrush en fonction des valeurs rencontrees
-	QRegExp rx("^\\s*([a-z-]+)\\s*:\\s*([a-z-]+)\\s*$");
-	foreach (QString style, styles) {
-		if (rx.exactMatch(style)) {
-			QString style_name = rx.cap(1);
-			QString style_value = rx.cap(2);
-			if (style_name == "line-style") {
-				if (style_value == "dashed") pen.setStyle(Qt::DashLine);
-				else if (style_value == "dotted") pen.setStyle(Qt::DotLine);
-				else if (style_value == "dashdotted") pen.setStyle(Qt::DashDotLine);
-				else if (style_value == "normal") pen.setStyle(Qt::SolidLine);
-			} else if (style_name == "line-weight") {
-				if (style_value == "none") pen.setColor(QColor(0, 0, 0, 0));
-				else if (style_value == "thin") pen.setWidth(0);
-				else if (style_value == "normal") pen.setWidthF(1.0);
-				else if (style_value == "hight") pen.setWidthF(2.0);
-				else if (style_value == "eleve") pen.setWidthF(5.0);
-
-			} else if (style_name == "filling") {
-				if (style_value == "white") {
-					brush.setStyle(Qt::SolidPattern);
-					brush.setColor(Qt::white);
-				} else if (style_value == "black") {
-					brush.setStyle(Qt::SolidPattern);
-					brush.setColor(Qt::black);
-				} else if (style_value == "blue") {
-					brush.setStyle(Qt::SolidPattern);
-					brush.setColor(Qt::blue);
-				} else if (style_value == "red") {
-					brush.setStyle(Qt::SolidPattern);
-					brush.setColor(Qt::red);
-				} else if (style_value == "green") {
-					brush.setStyle(Qt::SolidPattern);
-					brush.setColor(Qt::green);
-				} else if (style_value == "gray") {
-					brush.setStyle(Qt::SolidPattern);
-					brush.setColor(Qt::gray);
-				} else if (style_value == "brun") {
-					brush.setStyle(Qt::SolidPattern);
-					brush.setColor(QColor(97, 44, 0));
-				} else if (style_value == "yellow") {
-					brush.setStyle(Qt::SolidPattern);
-					brush.setColor(Qt::yellow);
-				} else if (style_value == "cyan") {
-					brush.setStyle(Qt::SolidPattern);
-					brush.setColor(Qt::cyan);
-				} else if (style_value == "magenta") {
-					brush.setStyle(Qt::SolidPattern);
-					brush.setColor(Qt::magenta);
-				} else if (style_value == "lightgray") {
-					brush.setStyle(Qt::SolidPattern);
-					brush.setColor(Qt::lightGray);
-				} else if (style_value == "orange") {
-					brush.setStyle(Qt::SolidPattern);
-					brush.setColor(QColor(255, 128, 0));
-				} else if (style_value == "purple") {
-					brush.setStyle(Qt::SolidPattern);
-					brush.setColor(QColor(136, 28, 168));
-				}else if (style_value == "hor") {
-					brush.setStyle(Qt::HorPattern);
-					brush.setColor(Qt::black);
-				} else if (style_value == "ver") {
-					brush.setStyle(Qt::VerPattern);
-					brush.setColor(Qt::black);
-				} else if (style_value == "bdiag") {
-					brush.setStyle(Qt::BDiagPattern);
-					brush.setColor(Qt::black);
-				} else if (style_value == "fdiag") {
-					brush.setStyle(Qt::FDiagPattern);
-					brush.setColor(Qt::black);
-				} else if (style_value == "none") {
-					brush.setStyle(Qt::NoBrush);
-				}
-			} else if (style_name == "color") {
-				if (style_value == "black") {
-					pen.setColor(QColor(0, 0, 0, pen.color().alpha()));
-				} else if (style_value == "white") {
-					pen.setColor(QColor(255, 255, 255, pen.color().alpha()));
-				} else if (style_value == "red") {
-					pen.setColor(Qt::red);
-				}else if (style_value == "blue") {
-					pen.setColor(Qt::blue);
-				}else if (style_value == "green") {
-					pen.setColor(Qt::green);
-				}else if (style_value == "gray") {
-					pen.setColor(Qt::gray);
-				}else if (style_value == "brun") {
-					pen.setColor(QColor(97, 44, 0));
-				}else if (style_value == "yellow") {
-					pen.setColor(Qt::yellow);
-				}else if (style_value == "cyan") {
-					pen.setColor(Qt::cyan);
-				}else if (style_value == "magenta") {
-					pen.setColor(Qt::magenta);
-				}else if (style_value == "lightgray") {
-					pen.setColor(Qt::lightGray);
-				}else if (style_value == "orange") {
-					pen.setColor(QColor(255, 128, 0));
-				}else if (style_value == "purple") {
-					pen.setColor(QColor(136, 28, 168));
-				} else if (style_value == "none") {
-					pen.setBrush(Qt::transparent);
-				}
-			}
-		}
-	}
-
-	// affectation du QPen et de la QBrush modifies au QPainter
-	qp.setPen(pen);
-	qp.setBrush(brush);
-
-	// mise en place (ou non) de l'antialiasing
-	setQPainterAntiAliasing(qp, e.attribute("antialias") == "true");
-}

Deleted: trunk/sources/qetgraphicsitem/customelement.h
===================================================================
--- trunk/sources/qetgraphicsitem/customelement.h	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetgraphicsitem/customelement.h	2018-08-23 19:41:58 UTC (rev 5492)
@@ -1,118 +0,0 @@
-/*
-	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 CUSTOM_ELEMENT_H
-#define CUSTOM_ELEMENT_H
-#include "element.h"
-#include "nameslist.h"
-#include "elementslocation.h"
-#include <QPicture>
-
-class Terminal;
-
-/**
-	This class represents an electrical element; it may be used like a fixed
-	element, the difference being that the CustomElement reads its description
-	(names, drawing, behavior) from an XML document.
-*/
-class CustomElement : public Element
-{
-	Q_OBJECT
-	
-		// constructors, destructor
-	public:
-		CustomElement (const ElementsLocation &, QGraphicsItem * = nullptr, int * = nullptr);
-
-	~CustomElement() override;
-	
-	private:
-		CustomElement(const CustomElement &);
-	
-		// attributes
-	protected:
-		NamesList names;
-		ElementsLocation location_;
-		QPicture drawing;
-		QPicture low_zoom_drawing;
-		QList<Terminal *> m_terminals;
-		QList<DynamicElementTextItem *> m_dynamic_texts;
-		bool forbid_antialiasing;
-
-
-		QList<QLineF *> m_lines;
-		QList<QRectF *> m_rectangles;
-		QList<QRectF *> m_circles;
-		QList<QVector<QPointF> *> m_polygons;
-		QList<QVector<qreal> *> m_arcs;
-	
-	// methods
-	public:
-		QList<Terminal *> terminals() const override;
-		QList<Conductor *> conductors() const override;
-		QList<QLineF *> lines() const override;
-		QList<QRectF *> rectangles() const override;
-		QList<QRectF *> circles() const override;
-		QList<QVector<QPointF> *> polygons() const override;
-		QList<QVector<qreal> *> arcs() const override;
-		void paint(QPainter *, const QStyleOptionGraphicsItem *) override;
-		QString typeId() const override;
-		ElementsLocation location() const;
-		QString name() const override;
-	
-	protected:
-		virtual bool buildFromXml(const QDomElement &, int * = nullptr);
-		virtual bool parseElement(QDomElement &, QPainter &, bool addtolist = true);
-		virtual bool parseLine(QDomElement &, QPainter &, bool addtolist = true);
-		virtual bool parseRect(QDomElement &, QPainter &, bool addtolist = true);
-		virtual bool parseEllipse(QDomElement &, QPainter &, bool addtolist = true);
-		virtual bool parseCircle(QDomElement &, QPainter &, bool addtolist = true);
-		virtual bool parseArc(QDomElement &, QPainter &, bool addtolist = true);
-		virtual bool parsePolygon(QDomElement &, QPainter &, bool addtolist = true);
-		virtual bool parseText(QDomElement &, QPainter &, bool addtolist = true);
-		virtual bool parseInput(QDomElement &);
-		virtual DynamicElementTextItem *parseDynamicText(QDomElement &);
-		virtual Terminal *parseTerminal(QDomElement &);
-		
-		virtual void setQPainterAntiAliasing(QPainter &, bool);
-		virtual bool validOrientationAttribute(const QDomElement &);
-		virtual void setPainterStyle(QDomElement &, QPainter &);
-};
-
-/**
-	@return The element type ID; considering a CustomElement, this means the
-	@location of its XML description.
-	@see location()
-*/
-inline QString CustomElement::typeId() const {
-	return(location_.path());
-}
-
-/**
-	@return the location of the XML document describing this element.
-*/
-inline ElementsLocation CustomElement::location() const {
-	return(location_);
-}
-
-/**
-	@return The name of this element.
-*/
-inline QString CustomElement::name() const {
-	return(names.name(location_.baseName()));
-}
-
-#endif

Modified: trunk/sources/qetgraphicsitem/dynamicelementtextitem.h
===================================================================
--- trunk/sources/qetgraphicsitem/dynamicelementtextitem.h	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetgraphicsitem/dynamicelementtextitem.h	2018-08-23 19:41:58 UTC (rev 5492)
@@ -38,7 +38,7 @@
 {
 	friend class DynamicTextItemDelegate;
 	friend class CompositeTextEditDialog;
-	friend class CustomElement;
+	friend class Element;
 	
     Q_OBJECT
     

Modified: trunk/sources/qetgraphicsitem/element.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/element.cpp	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetgraphicsitem/element.cpp	2018-08-23 19:41:58 UTC (rev 5492)
@@ -31,6 +31,8 @@
 #include "changeelementinformationcommand.h"
 #include "dynamicelementtextitem.h"
 #include "elementtextitemgroup.h"
+#include "elementpicturefactory.h"
+#include "iostream"
 
 class ElementXmlRetroCompatibility
 {
@@ -62,15 +64,38 @@
 };
 
 /**
-	Constructeur pour un element sans scene ni parent
-*/
-Element::Element(QGraphicsItem *parent) :
+ * @brief Element::Element
+ * @param location, location of this element
+ * @param parent, parent graphics item
+ * @param state, state of the instanciation
+ */
+Element::Element(const ElementsLocation &location, QGraphicsItem *parent, int *state) :
 	QetGraphicsItem(parent),
-	must_highlight_(false),
-	m_mouse_over(false)
+	m_location (location)
 {
+	if(! (location.isElement() && location.exist()))
+	{
+		if (state)
+		{
+			*state = 1;
+			return;
+		}
+	}
+	int elmt_state;
+	buildFromXml(location.xml(), &elmt_state);
+	if (state) {
+		*state = elmt_state;
+	}
+	if (elmt_state) {
+		return;
+	}
+	if (state) {
+		*state = 0;
+	}
+	
+	setPrefix(autonum::elementPrefixForLocation(location));
 	m_link_type = Simple;
-	uuid_ = QUuid::createUuid();
+	m_uuid = QUuid::createUuid();
 	setZValue(10);
 	setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
 	setAcceptHoverEvents(true);
@@ -85,13 +110,39 @@
 }
 
 /**
-	Destructeur
-*/
+ * @brief Element::~Element
+ */
 Element::~Element()
 {
-    qDeleteAll(m_dynamic_text_list);
+	qDeleteAll (m_dynamic_text_list);
+	qDeleteAll (m_terminals);
 }
 
+/**
+ * @brief Element::terminals
+ * @return the list of terminals of this element.
+ */
+QList<Terminal *> Element::terminals() const {
+	return m_terminals;
+}
+
+/**
+ * @brief Element::conductors
+ * @return The list of conductors docked to this element
+ * the list is sorted according to the position of the terminal where the conductor is docked
+ * from top to bottom, and left to right.
+ */
+QList<Conductor *> Element::conductors() const
+{
+	QList<Conductor *> conductors;
+	
+	for (Terminal *t : m_terminals) {
+		conductors << t -> conductors();
+	}
+	
+	return(conductors);
+}
+
 void Element::editProperty()
 {
 	if (diagram() && !diagram()->isReadOnly())
@@ -106,20 +157,11 @@
 	}
 }
 
-
-
 /**
-	@return true si l'element est mis en evidence
-*/
-bool Element::isHighlighted() const {
-	return(must_highlight_);
-}
-
-/**
 	@param hl true pour mettre l'element en evidence, false sinon
 */
 void Element::setHighlighted(bool hl) {
-	must_highlight_ = hl;
+	m_must_highlight = hl;
 	update();
 }
 
@@ -142,14 +184,20 @@
  */
 void Element::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *)
 {
-
-	if (must_highlight_) drawHighlight(painter, options);
+	if (m_must_highlight) {
+		drawHighlight(painter, options);
+	}
 	
-		//Draw the element himself
-	paint(painter, options);
+	if (options && options -> levelOfDetail < 1.0) {
+		painter->drawPicture(0, 0, m_low_zoom_picture);
+	} else {
+		painter->drawPicture(0, 0, m_picture);
+	}
 	
 		//Draw the selection rectangle
-	if ( isSelected() || m_mouse_over ) drawSelection(painter, options);
+	if ( isSelected() || m_mouse_over ) {
+		drawSelection(painter, options);
+	}
 }
 
 /**
@@ -160,20 +208,20 @@
 }
 
 /**
-	Definit la taille de l'element sur le schema. Les tailles doivent etre
-	des multiples de 10 ; si ce n'est pas le cas, les dimensions indiquees
-	seront arrrondies aux dizaines superieures.
-	@param wid Largeur de l'element
-	@param hei Hauteur de l'element
-	@return La taille finale de l'element
-*/
-QSize Element::setSize(int wid, int hei) {
+ * @brief Element::setSize
+ * Define the size of the element.
+ * The size must be a multiple of 10.
+ * If not, the dimensions indicated will be arrrondies to higher tens.
+ * @param wid
+ * @param hei 
+ */
+void Element::setSize(int wid, int hei)
+{
 	prepareGeometryChange();
-	// chaque dimension indiquee est arrondie a la dizaine superieure
+
 	while (wid % 10) ++ wid;
 	while (hei % 10) ++ hei;
-	// les dimensions finales sont conservees et retournees
-	return(dimensions = QSize(wid, hei));
+	dimensions = QSize(wid, hei);
 }
 
 /**
@@ -209,25 +257,11 @@
 }
 
 /**
-	Selectionne l'element
-*/
-void Element::select() {
-	setSelected(true);
-}
-
-/**
-	Deselectionne l'element
-*/
-void Element::deselect() {
-	setSelected(false);
-}
-
-/**
-	@return La pixmap de l'element
-*/
+ * @brief Element::pixmap
+ * @return the pixmap of this element
+ */
 QPixmap Element::pixmap() {
-	if (preview.isNull()) updatePixmap(); // on genere la pixmap si ce n'est deja fait
-	return(preview);
+	return ElementPictureFactory::instance()->pixmap(m_location);
 }
 
 /*** Methodes protegees ***/
@@ -301,23 +335,277 @@
 }
 
 /**
-	Fonction initialisant et dessinant la pixmap de l'element.
-*/
-void Element::updatePixmap() {
-	// Pixmap transparente faisant la taille de base de l'element
-	preview = QPixmap(dimensions);
-	preview.fill(QColor(255, 255, 255, 0));
-	// QPainter sur la pixmap, avec antialiasing
-	QPainter p(&preview);
-	p.setRenderHint(QPainter::Antialiasing, true);
-	p.setRenderHint(QPainter::SmoothPixmapTransform, true);
-	// Translation de l'origine du repere de la pixmap
-	p.translate(hotspot_coord);
-	// L'element se dessine sur la pixmap
-	paint(&p, nullptr);
+ * @brief Element::buildFromXml
+ * Build this element from an xml description
+ * @param xml_def_elmt
+ * @param state
+ * Optional pointer which define the status of build
+ * 0 - evreything all right
+ * 4 - xml isn't a "definition"
+ * 5 - attribute of the definition isn't present or valid
+ * 6 - the definition is empty
+ * 7 - parsing of a xml node who describe a graphical part failed.
+ * 8 - No part of the drawing could be loaded
+ * @return 
+ */
+bool Element::buildFromXml(const QDomElement &xml_def_elmt, int *state)
+{
+	m_state = QET::GIBuildingFromXml;
+
+	if (xml_def_elmt.tagName() != "definition" || xml_def_elmt.attribute("type") != "element")
+	{
+		if (state) *state = 4;
+		m_state = QET::GIOK;
+		return(false);
+	}
+
+		//Check if the curent version can read the xml description
+	if (xml_def_elmt.hasAttribute("version"))
+	{
+		bool conv_ok;
+		qreal element_version = xml_def_elmt.attribute("version").toDouble(&conv_ok);
+		if (conv_ok && QET::version.toDouble() < element_version)
+		{
+			std::cerr << qPrintable(
+				QObject::tr("Avertissement : l'élément "
+				" a été enregistré avec une version"
+				" ultérieure de QElectroTech.")
+			) << std::endl;
+		}
+	}
+
+		//This attribute must be present and valid
+	int w, h, hot_x, hot_y;
+	if (
+		!QET::attributeIsAnInteger(xml_def_elmt, QString("width"), &w) ||\
+		!QET::attributeIsAnInteger(xml_def_elmt, QString("height"), &h) ||\
+		!QET::attributeIsAnInteger(xml_def_elmt, QString("hotspot_x"), &hot_x) ||\
+		!QET::attributeIsAnInteger(xml_def_elmt, QString("hotspot_y"), &hot_y)
+	) {
+		if (state) *state = 5;
+		m_state = QET::GIOK;
+		return(false);
+	}
+
+	setSize(w, h);
+	setHotspot(QPoint(hot_x, hot_y));
+
+		//the definition must have childs
+	if (xml_def_elmt.firstChild().isNull())
+	{
+		if (state) *state = 6;
+		m_state = QET::GIOK;
+		return(false);
+	}
+		//Extract the names
+	m_names.fromXml(xml_def_elmt);
+	setToolTip(name());
+
+		//load kind informations
+	m_kind_informations.fromXml(xml_def_elmt.firstChildElement("kindInformations"), "kindInformation");
+		//load element information
+	m_element_informations.fromXml(xml_def_elmt.firstChildElement("elementInformations"), "elementInformation");
+
+		//scroll of the Children of the Definition: Parts of the Drawing
+	int parsed_elements_count = 0;
+	for (QDomNode node = xml_def_elmt.firstChild() ; !node.isNull() ; node = node.nextSibling())
+	{
+		QDomElement elmts = node.toElement();
+		if (elmts.isNull())
+			continue;
+		
+		if (elmts.tagName() == "description")
+		{
+				//Minor workaround to find if there is a "input" tagg as label.
+				//If not, we set the tagg "label" to the first "input.
+			QList <QDomElement> input_field;
+			bool have_label = false;
+			for (QDomElement input_node = node.firstChildElement("input") ; !input_node.isNull() ; input_node = input_node.nextSiblingElement("input"))
+			{
+				if (!input_node.isNull())
+				{
+					input_field << input_node;
+					if (input_node.attribute("tagg", "none") == "label")
+						have_label = true;
+				}
+			}
+			if(!have_label && !input_field.isEmpty())
+				input_field.first().setAttribute("tagg", "label");
+			
+				//Parse the definition
+			for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling())
+			{
+				QDomElement qde = n.toElement();
+				if (qde.isNull())
+					continue;
+				
+				if (parseElement(qde)) {
+					++ parsed_elements_count;
+				}
+				else
+				{
+					if (state)
+						*state = 7;
+					m_state = QET::GIOK;
+					return(false);
+				}
+			}
+		}
+	}
+
+	ElementPictureFactory *epf = ElementPictureFactory::instance();
+	epf->getPictures(m_location, const_cast<QPicture&>(m_picture), const_cast<QPicture&>(m_low_zoom_picture));
+	
+	if(!m_picture.isNull())
+		++ parsed_elements_count;
+
+		//They must be at least one parsed graphics part
+	if (!parsed_elements_count)
+	{
+		if (state)
+			*state = 8;
+		m_state = QET::GIOK;
+		return(false);
+	}
+	else
+	{
+		if (state)
+			*state = 0;
+		m_state = QET::GIOK;
+		return(true);
+	}
 }
 
 /**
+ * @brief Element::parseElement
+ * Parse the element of the xml description of this element
+ * @param dom
+ * @return 
+ */
+bool Element::parseElement(const QDomElement &dom)
+{
+	if      (dom.tagName() == "terminal")     return(parseTerminal(dom));
+	else if (dom.tagName() == "input")        return(parseInput(dom));
+	else if (dom.tagName() == "dynamic_text") return(parseDynamicText(dom));
+	else return(true);
+}
+
+/**
+ * @brief Element::parseInput
+ * Parse the input (old text field)
+ * the parsed input are converted to dynamic text field, this function
+ * is only here to keep compatibility with old text.
+ * @param dom_element
+ * @return 
+ */
+bool Element::parseInput(const QDomElement &dom_element)
+{
+	qreal pos_x, pos_y;
+	int size;
+	if (
+		!QET::attributeIsAReal(dom_element, "x", &pos_x) ||\
+		!QET::attributeIsAReal(dom_element, "y", &pos_y) ||\
+		!QET::attributeIsAnInteger(dom_element, "size", &size)
+	) return(false);
+	else
+	{
+		DynamicElementTextItem *deti = new DynamicElementTextItem(this);
+		deti->setText(dom_element.attribute("text", "_"));
+		deti->setFontSize(dom_element.attribute("size", QString::number(9)).toInt());
+		deti->setRotation(dom_element.attribute("rotation", QString::number(0)).toDouble());
+
+		if(dom_element.attribute("tagg", "none") != "none")
+		{
+			deti->setTextFrom(DynamicElementTextItem::ElementInfo);
+			deti->setInfoName(dom_element.attribute("tagg"));
+		}
+		
+			//the origin transformation point of PartDynamicTextField is the top left corner, no matter the font size
+			//The origin transformation point of ElementTextItem is the middle of left edge, and so by definition, change with the size of the font
+			//We need to use a QMatrix to find the pos of this text from the saved pos of text item 
+		QMatrix matrix;
+			//First make the rotation
+		matrix.rotate(dom_element.attribute("rotation", "0").toDouble());
+		QPointF pos = matrix.map(QPointF(0, -deti->boundingRect().height()/2));
+		matrix.reset();
+			//Second translate to the pos
+		QPointF p(dom_element.attribute("x", QString::number(0)).toDouble(),
+				  dom_element.attribute("y", QString::number(0)).toDouble());
+		matrix.translate(p.x(), p.y());
+		deti->setPos(matrix.map(pos));
+		m_converted_text_from_xml_description.insert(deti, p);
+		return true;
+	}
+	
+	return false;
+}
+
+/**
+ * @brief Element::parseDynamicText
+ * Create the dynamic text field describ in @dom_element
+ * @param dom_element
+ * @return 
+ */
+DynamicElementTextItem *Element::parseDynamicText(const QDomElement &dom_element)
+{
+	DynamicElementTextItem *deti = new DynamicElementTextItem(this);
+		//Because the xml description of a .elmt file is the same as how a dynamic text field is save to xml in a .qet file
+		//wa call fromXml, we just change the tagg name (.elmt = dynamic_text, .qet = dynamic_elmt_text)
+		//and the uuid (because the uuid, is the uuid of the descritpion and not the uuid of instantiated dynamic text field)
+	
+	QDomElement dom(dom_element.cloneNode(true).toElement());
+	dom.setTagName(DynamicElementTextItem::xmlTaggName());
+	deti->fromXml(dom);
+	deti->m_uuid = QUuid::createUuid();
+	this->addDynamicTextItem(deti);
+	return deti;
+}
+
+Terminal *Element::parseTerminal(const QDomElement &dom_element)
+{
+	qreal terminalx, terminaly;
+	Qet::Orientation terminalo;
+	if (!QET::attributeIsAReal(dom_element, QString("x"), &terminalx)) {
+		return(nullptr);
+	}
+	if (!QET::attributeIsAReal(dom_element, QString("y"), &terminaly)) {
+		return(nullptr);
+	}
+	if (!dom_element.hasAttribute("orientation")) {
+		return(nullptr);
+	}
+	if (dom_element.attribute("orientation") == "n") {
+		terminalo = Qet::North;
+	}
+	else if (dom_element.attribute("orientation") == "s") {
+		terminalo = Qet::South;
+	}
+	else if (dom_element.attribute("orientation") == "e") {
+		terminalo = Qet::East;
+	}
+	else if (dom_element.attribute("orientation") == "w") {
+		terminalo = Qet::West;
+	}
+	else {
+		return(nullptr);
+	}
+	
+	Terminal *new_terminal = new Terminal(terminalx, terminaly, terminalo, this);
+	m_terminals << new_terminal;
+	
+		//Sort from top to bottom and left to rigth
+	std::sort(m_terminals.begin(), m_terminals.end(), [](Terminal *a, Terminal *b)
+	{
+		if(a->dockConductor().y() == b->dockConductor().y())
+			return (a->dockConductor().x() < b->dockConductor().x());
+		else
+			return (a->dockConductor().y() < b->dockConductor().y());
+	});
+	
+	return(new_terminal);
+}
+
+/**
 	Permet de savoir si un element XML (QDomElement) represente bien un element
 	@param e Le QDomElement a valide
 	@return true si l'element XML est un Element, false sinon
@@ -413,7 +701,7 @@
 	foreach (QDomElement qdo, uuid_list) tmp_uuids_link << qdo.attribute("uuid");
 	
 	//uuid of this element
-	uuid_= QUuid(e.attribute("uuid", QUuid::createUuid().toString()));
+	m_uuid= QUuid(e.attribute("uuid", QUuid::createUuid().toString()));
 
 		//load prefix
 	m_prefix = e.attribute("prefix");
@@ -726,7 +1014,7 @@
 	QDomElement element = document.createElement("element");
 	
 		// type
-	element.setAttribute("type", typeId());
+	element.setAttribute("type", m_location.path());
 
 		// uuid
 	element.setAttribute("uuid", uuid().toString());
@@ -1258,3 +1546,15 @@
 	}
 	else return;
 }
+
+/**
+ * @brief Element::name
+ * @return the human name of this element
+ */
+QString Element::name() const {
+	return m_names.name(m_location.baseName());
+}
+
+ElementsLocation Element::location() const {
+	return m_location;
+}

Modified: trunk/sources/qetgraphicsitem/element.h
===================================================================
--- trunk/sources/qetgraphicsitem/element.h	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetgraphicsitem/element.h	2018-08-23 19:41:58 UTC (rev 5492)
@@ -22,13 +22,15 @@
 #include "qetgraphicsitem.h"
 #include "diagramcontext.h"
 #include "assignvariables.h"
+#include "elementslocation.h"
+#include "nameslist.h"
+
 #include <algorithm>
+#include <QPicture>
 
 class QETProject;
 class Terminal;
 class Conductor;
-class NumerotationContext;
-class DiagramTextItem;
 class DynamicElementTextItem;
 class ElementTextItemGroup;
 
@@ -43,7 +45,7 @@
 	
 		// constructors, destructor
 	public:
-		Element(QGraphicsItem * = nullptr);
+		Element(const ElementsLocation &location, QGraphicsItem * = nullptr, int *state = nullptr);
 		~Element() override;
 	private:
 		Element(const Element &);
@@ -68,54 +70,7 @@
 				   Master = 8,
 				   Slave = 16,
 				   Terminale = 32};
-	
-	private:
-		QSize   dimensions;
-		QPoint  hotspot_coord;
-		QPixmap preview;
-
-		// methods
-	public:
-			/// @return the list of terminals for this element
-		virtual QList<Terminal *> terminals() const = 0;
-			/// @return the list of conductors attached to this element
-		virtual QList<Conductor *> conductors() const = 0;
-			/// @return the list of lines items in this element
-		virtual QList<QLineF *> lines() const = 0;
-			/// @return the list of rectangles items in this element
-		virtual QList<QRectF *> rectangles() const = 0;
-			/// @return the list of bounding rectangles for circles items in this element
-		virtual QList<QRectF *> circles() const = 0;
-			/// @return the list of polygons in this element
-		virtual QList<QVector<QPointF> *> polygons() const = 0;
-			/// @return the list of arcs in this element
-		virtual QList<QVector<qreal> *> arcs() const = 0;
-
-		QList <QPair <Terminal *, Terminal *> > AlignedFreeTerminals () const;
-
-	/**
-	 *related method and attributes,
-	 *about none graphic thing
-	 *like the linked element or information about this element
-	 */
-		//METHODS related to linked element
-	public:
-				bool isFree            () const;
-		virtual void linkToElement     (Element *) {}
-		virtual void unlinkAllElements () {}
-		virtual void unlinkElement     (Element *) {}
-		virtual void initLink          (QETProject *);
-		QList<Element *> linkedElements ();
-		virtual kind linkType() const {return m_link_type;} // @return the linkable type
-		void newUuid() {uuid_ = QUuid::createUuid();} 	//create new uuid for this element
-
-		//ATTRIBUTES related to linked element
-	protected:
-		QList <Element *> connected_elements;
-		QList <QUuid>     tmp_uuids_link;
-		QUuid             uuid_;
-		kind              m_link_type;
-
+		
 	signals:
 		void linkedElementChanged(); //This signal is emited when the linked elements with this element change
 		void elementInfoChange(DiagramContext old_info, DiagramContext new_info);
@@ -126,8 +81,13 @@
 		void textAddedToGroup(DynamicElementTextItem *text, ElementTextItemGroup *group);
 		void textRemovedFromGroup(DynamicElementTextItem *text, ElementTextItemGroup *group);
 
-		//METHODS related to information
+		
 	public:
+		QList<Terminal *> terminals() const;
+		QList<Conductor *> conductors() const;
+		QList <QPair <Terminal *, Terminal *> > AlignedFreeTerminals () const;
+		
+			//METHODS related to information
 		DiagramContext  elementInformations    ()const              {return m_element_informations;}
 		virtual void    setElementInformations (DiagramContext dc);
 		DiagramContext  kindInformations       () const             {return m_kind_informations;}	//@kind_information_ is used to store more information
@@ -136,7 +96,6 @@
 
 		autonum::sequentialNumbers sequenceStruct () const {return m_autoNum_seq;}
 		autonum::sequentialNumbers& rSequenceStruct()      {return m_autoNum_seq;}
-
 		void setUpFormula(bool code_letter = true);
 		void setPrefix(QString);
 		QString getPrefix() const;
@@ -143,49 +102,23 @@
 		void freezeLabel(bool freeze);
 		bool isFreezeLabel() const {return m_freeze_label;}
 		void freezeNewAddedElement();
-
-		//ATTRIBUTES
-	protected:
-		DiagramContext m_element_informations, m_kind_informations;
-		autonum::sequentialNumbers m_autoNum_seq;
-		bool m_freeze_label = false;
-		QString m_F_str;
-
-	public:
-		virtual void paint(QPainter *, const QStyleOptionGraphicsItem *) = 0;
-		/// @return This element type ID
-		virtual QString typeId() const = 0;
-		/// @return the human name for this element
-		QString name() const override = 0;
-	
-		virtual bool isHighlighted() const;
+		
+		QString name() const override;
+		ElementsLocation location() const;
 		virtual void setHighlighted(bool);
 		void displayHelpLine(bool b = true);
-		void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) override;
-		QRectF boundingRect() const override;
-		QSize setSize(int, int);
 		QSize size() const;
 		QPixmap pixmap();
-	
-            // methods related to the hotspot
         QPoint setHotspot(QPoint);
-        QPoint hotspot() const;
-        
-            // selection-related methods
-        void select();
-        void deselect();
-        
+        QPoint hotspot() const;     
         void editProperty() override;
-        
-            // 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;
-        
+		
+			//METHODS related to texts
         void addDynamicTextItem(DynamicElementTextItem *deti = nullptr);
         void removeDynamicTextItem(DynamicElementTextItem *deti);
         QList<DynamicElementTextItem *> dynamicTextItems() const;
@@ -196,16 +129,34 @@
 		QList<ElementTextItemGroup *> textGroups() const;
 		bool addTextToGroup(DynamicElementTextItem *text, ElementTextItemGroup *group);
 		bool removeTextFromGroup(DynamicElementTextItem *text, ElementTextItemGroup *group);
+		
+			//METHODS related to linked element
+				bool isFree            () const;
+		virtual void linkToElement     (Element *) {}
+		virtual void unlinkAllElements () {}
+		virtual void unlinkElement     (Element *) {}
+		virtual void initLink          (QETProject *);
+		QList<Element *> linkedElements ();
+		virtual kind linkType() const {return m_link_type;} // @return the linkable type
+		void newUuid() {m_uuid = QUuid::createUuid();} 	//create new uuid for this element
 
 	protected:
 		void drawAxes(QPainter *, const QStyleOptionGraphicsItem *);
+		void setSize(int, int);
 	
 	private:
-		bool must_highlight_;
 		void drawSelection(QPainter *, const QStyleOptionGraphicsItem *);
 		void drawHighlight(QPainter *, const QStyleOptionGraphicsItem *);
-		void updatePixmap();
+		bool buildFromXml(const QDomElement &, int * = nullptr);
+		bool parseElement(const QDomElement &dom);
+		bool parseInput(const QDomElement &dom_element);
+		DynamicElementTextItem *parseDynamicText(const QDomElement &dom_element);
+		Terminal *parseTerminal(const QDomElement &dom_element);
 
+		//Reimplemented from QGraphicsItem
+	public:
+		void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) override;
+		QRectF boundingRect() const override;
 	protected:
 		void mouseMoveEvent    ( QGraphicsSceneMouseEvent *event ) override;
 		void mouseReleaseEvent ( QGraphicsSceneMouseEvent *event ) override;
@@ -217,8 +168,30 @@
 			// are converted to dynamic text field, the QPointF is the original position of the text item, because the origin transformation point of text item
 			// and dynamic text item are not the same, so we must to keep a track of this value, to be use in the function element::fromXml
 		QHash <DynamicElementTextItem *, QPointF> m_converted_text_from_xml_description;
+		
+			//ATTRIBUTES related to linked element
+		QList <Element *> connected_elements;
+		QList <QUuid>     tmp_uuids_link;
+		QUuid             m_uuid;
+		kind              m_link_type;
+		
+			//ATTRIBUTES related to informations
+		DiagramContext m_element_informations, m_kind_informations;
+		autonum::sequentialNumbers m_autoNum_seq;
+		bool m_freeze_label = false;
+		QString m_F_str;
+		
+		ElementsLocation m_location;
+		NamesList m_names;
+		QList <Terminal *> m_terminals;
+		const QPicture m_picture;
+		const QPicture m_low_zoom_picture;
+		
 	private:
-		bool m_mouse_over;
+		bool m_must_highlight = false;
+		QSize   dimensions;
+		QPoint  hotspot_coord;
+		bool m_mouse_over = false;
 		QString m_prefix;
         QList <DynamicElementTextItem *> m_dynamic_text_list;
 		QList <ElementTextItemGroup *> m_texts_group;
@@ -248,7 +221,7 @@
  * @return the uuid of this element
  */
 inline QUuid Element::uuid() const {
-	return uuid_;
+	return m_uuid;
 }
 
 /**

Deleted: trunk/sources/qetgraphicsitem/ghostelement.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/ghostelement.cpp	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetgraphicsitem/ghostelement.cpp	2018-08-23 19:41:58 UTC (rev 5492)
@@ -1,185 +0,0 @@
-/*
-	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 "ghostelement.h"
-#include "qet.h"
-#include "terminal.h"
-#include "diagramcommands.h"
-
-/**
-	Constructeur
-	@param location Emplacement de la definition d'element a utiliser
-	@param qgi Le QGraphicsItem parent de cet element
-	@param d Le schema affichant cet element
-*/
-GhostElement::GhostElement(
-	const ElementsLocation &location,
-	QGraphicsItem *qgi
-) :
-	CustomElement(location, qgi)
-{
-	QString tooltip_string = QString(
-		tr("<u>Élément manquant :</u> %1")
-	).arg(location_.toString());
-	setToolTip(tooltip_string);
-}
-
-/**
-	Destructeur
-*/
-GhostElement::~GhostElement() {
-}
-
-
-/**
-	@param e L'element XML a analyser.
-	@param table_id_adr Reference vers la table de correspondance entre les IDs
-	du fichier XML et les adresses en memoire. Si l'import reussit, il faut y
-	ajouter les bons couples (id, adresse).
-	@return true si l'import a reussi, false sinon
-*/
-bool GhostElement::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr, bool handle_inputs_rotation) {
-	// instancie les bornes decrites dans l'element XML
-	terminalsFromXml(e, table_id_adr);
-	
-	// instancie les champs de texte decrits dans l'element XML
-	foreach(QDomElement qde, QET::findInDomElement(e, "inputs", "input")) {
-		qde.setAttribute("size", 9); // arbitraire
-		CustomElement::parseInput(qde);
-	}
-	
-	/*
-		maintenant que l'element fantome connait toutes les bornes et tous les
-		champs de texte, on peut determiner une taille appropriee
-	*/
-	QRect final_bounding_rect = minimalBoundingRect().united(childrenBoundingRect()).toAlignedRect();
-	setSize(final_bounding_rect.width(), final_bounding_rect.height());
-	setHotspot(QPoint() - final_bounding_rect.topLeft());
-	
-	// on peut desormais confectionner le rendu de l'element
-	generateDrawings();
-	
-	// position, selection
-	setPos(e.attribute("x").toDouble(), e.attribute("y").toDouble());
-	setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
-	
-	// orientation
-	bool conv_ok;
-	int read_ori = e.attribute("orientation").toInt(&conv_ok);
-	if (!conv_ok || read_ori < 0 || read_ori > 3) read_ori = 0;
-	if (handle_inputs_rotation) {
-		setRotation(rotation() + (90*read_ori));
-	} else {
-		setRotation(90*read_ori);
-	}
-	return(true);
-}
-
-/**
-	@return le bounding rect minimum, utilise si l'element fantome n'a ni champ
-	de texte ni borne.
-*/
-QRectF GhostElement::minimalBoundingRect() const {
-	return(
-		QRectF(
-			QPointF(-10.0, -10.0),
-			QSizeF(20.0, 20.0)
-		)
-	);
-}
-
-/**
-	Gere l'import des bornes
-	@param e L'element XML a analyser.
-	@param table_id_adr Reference vers la table de correspondance entre les IDs
-	du fichier XML et les adresses en memoire. Si l'import reussit, il faut y
-	ajouter les bons couples (id, adresse).
-	@return true si l'import a reussi, false sinon
-*/
-bool GhostElement::terminalsFromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr) {
-	// instancie les bornes decrites dans l'element XML
-	foreach(QDomElement qde, QET::findInDomElement(e, "terminals", "terminal")) {
-		if (!Terminal::valideXml(qde)) continue;
-		
-		// modifie certains attributs pour que l'analyse par la classe CustomElement reussisse
-		int previous_x_value   = qde.attribute("x").toInt();
-		int previous_y_value   = qde.attribute("y").toInt();
-		Qet::Orientation previous_ori_value = static_cast<Qet::Orientation>(qde.attribute("orientation").toInt());
-		
-		qreal x_add = 0.0, y_add = 0.0;
-		if (previous_ori_value == Qet::North)      y_add = -Terminal::terminalSize;
-		else if (previous_ori_value == Qet::East)  x_add = Terminal::terminalSize;
-		else if (previous_ori_value == Qet::South) y_add = Terminal::terminalSize;
-		else if (previous_ori_value == Qet::West)  x_add = -Terminal::terminalSize;
-		qde.setAttribute("x",           previous_x_value + x_add);
-		qde.setAttribute("y",           previous_y_value + y_add);
-		qde.setAttribute("orientation", previous_ori_value);
-		
-		if (Terminal *new_terminal = CustomElement::parseTerminal(qde)) {
-			table_id_adr.insert(qde.attribute("id").toInt(), new_terminal);
-		}
-		
-		// restaure les attributs modifies
-		qde.setAttribute("x",           previous_x_value);
-		qde.setAttribute("y",           previous_y_value);
-		qde.setAttribute("orientation", previous_ori_value);
-	}
-	return(true);
-}
-
-/**
-	Genere les rendus de l'element fantome : il s'agit d'un rectangle
-	representant grosso modo l'espace que devait prendre l'element initial.
-	En son centre est dessine un point d'interrogation. Une petite croix indique
-	le point de saisie de l'element.
-*/
-void GhostElement::generateDrawings() {
-	// style de dessin
-	QPen t(QBrush(Qt::black), 1.0);
-	
-	// rendu normal
-	QPainter qp;
-	qp.begin(&drawing);
-	qp.setPen(t);
-	qp.setRenderHint(QPainter::Antialiasing, false);
-	generateDrawing(&qp);
-	qp.end();
-	
-	// rendu low_zoom
-	QPainter low_zoom_qp;
-	low_zoom_qp.begin(&low_zoom_drawing);
-	t.setCosmetic(true);
-	low_zoom_qp.setRenderHint(QPainter::Antialiasing, false);
-	low_zoom_qp.setPen(t);
-	generateDrawing(&low_zoom_qp);
-	low_zoom_qp.end();
-}
-
-/**
-	Genere un rendu de l'element fantome
-	@see generateDrawings
-*/
-void GhostElement::generateDrawing(QPainter *painter) {
-	// une petite croix indique le point de saisie de l'element
-	painter -> drawLine(QLineF(-1.0, 0.0, 1.0, 0.0));
-	painter -> drawLine(QLineF(0.0, -1.0, 0.0, 1.0));
-	
-	// rectangle avec un point d'interrogation au centre
-	QRectF drawn_rect = boundingRect().adjusted(4.0, 4.0, -4.0, -4.0);
-	painter -> drawRect(drawn_rect);
-	painter -> drawText(drawn_rect, Qt::AlignHCenter | Qt::AlignVCenter, "?");
-}

Deleted: trunk/sources/qetgraphicsitem/ghostelement.h
===================================================================
--- trunk/sources/qetgraphicsitem/ghostelement.h	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetgraphicsitem/ghostelement.h	2018-08-23 19:41:58 UTC (rev 5492)
@@ -1,53 +0,0 @@
-/*
-	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 GHOST_ELEMENT_H
-#define GHOST_ELEMENT_H
-#include "customelement.h"
-class QGraphicsItem;
-class ElementsLocation;
-class Terminal;
-/**
-	The GhostElement class inherits CustomElement. A GhostElement aims at
-	visually replacing a CustomElement whose definition could not be loaded.
-	This way, instead of not loading an element, thus potentially losing its
-	position, its orientation, its child text items and conductors, one can
-	substitute a GhostElement. The GhostElement will extrapolate the position
-	of terminals and text items from the rest of the diagram. It is visually
-	rendered using a simple rectangle.
-*/
-class GhostElement : public CustomElement {
-	
-	Q_OBJECT
-	
-	// constructor, destructor
-	public:
-	GhostElement(const ElementsLocation &, QGraphicsItem * = nullptr);
-	~GhostElement() override;
-	
-	// methods
-	public:
-	bool fromXml(QDomElement &, QHash<int, Terminal *> &, bool = false) override;
-	kind linkType() const override {return Simple;}
-	
-	protected:
-	QRectF minimalBoundingRect() const;
-	bool terminalsFromXml(QDomElement &, QHash<int, Terminal *> &);
-	void generateDrawings();
-	void generateDrawing(QPainter *);
-};
-#endif

Modified: trunk/sources/qetgraphicsitem/masterelement.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/masterelement.cpp	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetgraphicsitem/masterelement.cpp	2018-08-23 19:41:58 UTC (rev 5492)
@@ -30,7 +30,7 @@
  * @param state int used to know if the creation of element have error
  */
 MasterElement::MasterElement(const ElementsLocation &location, QGraphicsItem *qgi, int *state) :
-	CustomElement(location, qgi, state)
+	Element(location, qgi, state)
 {
 	m_link_type = Element::Master;
 }
@@ -109,7 +109,7 @@
  */
 void MasterElement::initLink(QETProject *project) {
 	//Create the link with other element if needed
-	CustomElement::initLink(project);
+	Element::initLink(project);
 }
 
 /**
@@ -132,7 +132,7 @@
 		m_first_scene_change = false;
 		connect(diagram()->project(), &QETProject::XRefPropertiesChanged, this, &MasterElement::xrefPropertiesChanged);
 	}
-	return CustomElement::itemChange(change, value);
+	return Element::itemChange(change, value);
 }
 
 void MasterElement::xrefPropertiesChanged()

Modified: trunk/sources/qetgraphicsitem/masterelement.h
===================================================================
--- trunk/sources/qetgraphicsitem/masterelement.h	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetgraphicsitem/masterelement.h	2018-08-23 19:41:58 UTC (rev 5492)
@@ -18,7 +18,7 @@
 #ifndef MASTERELEMENT_H
 #define MASTERELEMENT_H
 
-#include "customelement.h"
+#include "element.h"
 
 class CrossRefItem;
 
@@ -28,7 +28,7 @@
  * to be a master element. Master element can be linked with slave element
  * and display a cross ref item for know with what other element he is linked
  */
-class MasterElement : public CustomElement
+class MasterElement : public Element
 {
 	Q_OBJECT
 	

Modified: trunk/sources/qetgraphicsitem/reportelement.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/reportelement.cpp	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetgraphicsitem/reportelement.cpp	2018-08-23 19:41:58 UTC (rev 5492)
@@ -24,7 +24,7 @@
 #include "dynamicelementtextitem.h"
 
 ReportElement::ReportElement(const ElementsLocation &location, const QString& link_type,QGraphicsItem *qgi, int *state) :
-	CustomElement(location, qgi, state)
+	Element(location, qgi, state)
 {
 	link_type == "next_report"? m_link_type=NextReport : m_link_type=PreviousReport;
 	link_type == "next_report"? m_inverse_report=PreviousReport : m_inverse_report=NextReport;

Modified: trunk/sources/qetgraphicsitem/reportelement.h
===================================================================
--- trunk/sources/qetgraphicsitem/reportelement.h	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetgraphicsitem/reportelement.h	2018-08-23 19:41:58 UTC (rev 5492)
@@ -18,7 +18,7 @@
 #ifndef REPORTELEMENT_H
 #define REPORTELEMENT_H
 
-#include "customelement.h"
+#include "element.h"
 
 /**
  * @brief The ReportElement class
@@ -25,7 +25,7 @@
  *this class represent an element that can be linked to an other ReportElement
  * a folio report in a diagram is a element that show a wire go on an other folio
  */
-class ReportElement : public CustomElement
+class ReportElement : public Element
 {
 	Q_OBJECT
 

Modified: trunk/sources/qetgraphicsitem/simpleelement.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/simpleelement.cpp	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetgraphicsitem/simpleelement.cpp	2018-08-23 19:41:58 UTC (rev 5492)
@@ -26,7 +26,7 @@
  * @param state
  */
 SimpleElement::SimpleElement(const ElementsLocation &location, QGraphicsItem *qgi, int *state) :
-	CustomElement(location, qgi, state)
+	Element(location, qgi, state)
 {
 	m_link_type = Simple;
 }
@@ -43,5 +43,5 @@
  * call update label for setup it.
  */
 void SimpleElement::initLink(QETProject *project) {
-	CustomElement::initLink(project);
+	Element::initLink(project);
 }

Modified: trunk/sources/qetgraphicsitem/simpleelement.h
===================================================================
--- trunk/sources/qetgraphicsitem/simpleelement.h	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetgraphicsitem/simpleelement.h	2018-08-23 19:41:58 UTC (rev 5492)
@@ -18,7 +18,7 @@
 #ifndef SIMPLEELEMENT_H
 #define SIMPLEELEMENT_H
 
-#include "customelement.h"
+#include "element.h"
 
 class QETProject;
 
@@ -26,7 +26,7 @@
  * @brief The SimpleElement class
  *this class represente a simple element with no specific attribute
  */
-class SimpleElement : public CustomElement {
+class SimpleElement : public Element {
 
 	Q_OBJECT
 

Modified: trunk/sources/qetgraphicsitem/slaveelement.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/slaveelement.cpp	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetgraphicsitem/slaveelement.cpp	2018-08-23 19:41:58 UTC (rev 5492)
@@ -30,7 +30,7 @@
  * @param state int used to know if the creation of element have error
  */
 SlaveElement::SlaveElement(const ElementsLocation &location, QGraphicsItem *qgi, int *state) :
-	CustomElement(location, qgi, state)
+	Element(location, qgi, state)
 {
 	m_xref_item = nullptr;
 	m_link_type = Slave;

Modified: trunk/sources/qetgraphicsitem/slaveelement.h
===================================================================
--- trunk/sources/qetgraphicsitem/slaveelement.h	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetgraphicsitem/slaveelement.h	2018-08-23 19:41:58 UTC (rev 5492)
@@ -18,10 +18,10 @@
 #ifndef SLAVEELEMENT_H
 #define SLAVEELEMENT_H
 
-#include "customelement.h"
+#include "element.h"
 #include"properties/xrefproperties.h"
 
-class SlaveElement : public CustomElement
+class SlaveElement : public Element
 {
 	Q_OBJECT
 	public:

Modified: trunk/sources/qetgraphicsitem/terminalelement.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/terminalelement.cpp	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetgraphicsitem/terminalelement.cpp	2018-08-23 19:41:58 UTC (rev 5492)
@@ -26,7 +26,7 @@
  * @param state int used to know if the creation of element have error
  */
 TerminalElement::TerminalElement(const ElementsLocation &location, QGraphicsItem *qgi, int *state) :
-	CustomElement(location, qgi, state)
+	Element(location, qgi, state)
 {m_link_type = Terminale;}
 
 TerminalElement::~TerminalElement() {}
@@ -36,6 +36,6 @@
  * @param project
  */
 void TerminalElement::initLink(QETProject *project) {
-	CustomElement::initLink(project);
+	Element::initLink(project);
 }
 

Modified: trunk/sources/qetgraphicsitem/terminalelement.h
===================================================================
--- trunk/sources/qetgraphicsitem/terminalelement.h	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/qetgraphicsitem/terminalelement.h	2018-08-23 19:41:58 UTC (rev 5492)
@@ -18,11 +18,12 @@
 #ifndef TERMINALELEMENT_H
 #define TERMINALELEMENT_H
 
-#include "customelement.h"
 
+#include "element.h"
+
 class QETProject;
 
-class TerminalElement : public CustomElement
+class TerminalElement : public Element
 {
 		Q_OBJECT
 	public:

Modified: trunk/sources/ui/elementpropertieswidget.cpp
===================================================================
--- trunk/sources/ui/elementpropertieswidget.cpp	2018-08-23 00:22:24 UTC (rev 5491)
+++ trunk/sources/ui/elementpropertieswidget.cpp	2018-08-23 19:41:58 UTC (rev 5492)
@@ -20,7 +20,6 @@
 #include "elementinfowidget.h"
 #include "masterpropertieswidget.h"
 #include "linksingleelementwidget.h"
-#include "ghostelement.h"
 #include "diagram.h"
 #include "diagramposition.h"
 #include "qeticons.h"
@@ -216,10 +215,9 @@
  */
 void ElementPropertiesWidget::findInPanel()
 {
-	CustomElement *custom_element = qobject_cast<CustomElement *>(m_element);
-	if (custom_element && m_diagram)
+	if (m_element && m_diagram)
 	{
-		m_diagram->findElementRequired(custom_element->location());
+		m_diagram->findElementRequired(m_element.data()->location());
 		emit findEditClicked();
 	}
 }
@@ -230,11 +228,10 @@
  */
 void ElementPropertiesWidget::editElement()
 {
-	CustomElement *custom_element = qobject_cast<CustomElement *>(m_element);
-	if (custom_element && m_diagram)
+	if (m_element && m_diagram)
 	{
-		m_diagram->findElementRequired(custom_element->location());
-		m_diagram->editElementRequired(custom_element->location());
+		m_diagram->findElementRequired(m_element.data()->location());
+		m_diagram->editElementRequired(m_element.data()->location());
 		emit findEditClicked();
 	}
 }
@@ -342,19 +339,9 @@
  */
 QWidget *ElementPropertiesWidget::generalWidget()
 {
-	CustomElement *custom_element = qobject_cast<CustomElement *>(m_element);
-	GhostElement  *ghost_element  = qobject_cast<GhostElement  *>(m_element);
+	QString description_string(tr("Élement\n"));
 
-	// type de l'element
-	QString description_string;
-	if (ghost_element) {
-		description_string += tr("Élément manquant");
-	} else {
-		description_string += tr("Élément");
-	}
-	description_string += "\n";
-
-	// some element characteristic
+		// some element characteristic
 	description_string += QString(tr("Nom : %1\n")).arg(m_element -> name());
 	int folio_index = m_diagram -> folioIndex();
 	if (folio_index != -1) {
@@ -364,11 +351,8 @@
 	description_string += QString(tr("Rotation : %1°\n")).arg(m_element.data()->rotation());
 	description_string += QString(tr("Dimensions : %1*%2\n")).arg(m_element -> size().width()).arg(m_element -> size().height());
 	description_string += QString(tr("Bornes : %1\n")).arg(m_element -> terminals().count());
+	description_string += QString(tr("Emplacement : %1\n")).arg(m_element.data()->location().toString());
 
-	if (custom_element) {
-		description_string += QString(tr("Emplacement : %1\n")).arg(custom_element -> location().toString());
-	}
-
 		// widget himself
 	QWidget *general_widget = new QWidget (m_tab);
 	QVBoxLayout *vlayout_ = new QVBoxLayout (general_widget);
@@ -399,12 +383,10 @@
 	int margin = vlayout_->contentsMargins().left() + vlayout_->contentsMargins().right();
 	int widht_ = vlayout_->minimumSize().width()-margin;
 
-	if (pixmap.size().width() > widht_ || pixmap.size().height() > widht_)
-	{
+	if (pixmap.size().width() > widht_ || pixmap.size().height() > widht_) {
 		pix->setPixmap(m_element->pixmap().scaled (widht_, widht_, Qt::KeepAspectRatio, Qt::SmoothTransformation));
 	}
-	else
-	{
+	else {
 		pix->setPixmap(pixmap);
 	}
 


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