[qet] [3694] Element editor : hover a primitve will highlight it with a blue halo

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


Revision: 3694
Author:   blacksun
Date:     2015-02-09 09:57:40 +0100 (Mon, 09 Feb 2015)
Log Message:
-----------
Element editor : hover a primitve will highlight it with a blue halo

Modified Paths:
--------------
    trunk/sources/editor/arceditor.cpp
    trunk/sources/editor/editorcommands.cpp
    trunk/sources/editor/elementscene.cpp
    trunk/sources/editor/ellipseeditor.cpp
    trunk/sources/editor/esevent/eseventaddarc.cpp
    trunk/sources/editor/esevent/eseventaddellipse.cpp
    trunk/sources/editor/esevent/eseventaddellipse.h
    trunk/sources/editor/esevent/eseventaddline.cpp
    trunk/sources/editor/esevent/eseventaddpolygon.cpp
    trunk/sources/editor/esevent/eseventaddrect.cpp
    trunk/sources/editor/esevent/eseventaddrect.h
    trunk/sources/editor/esevent/eseventaddterminal.cpp
    trunk/sources/editor/graphicspart/customelementgraphicpart.cpp
    trunk/sources/editor/graphicspart/customelementgraphicpart.h
    trunk/sources/editor/graphicspart/partarc.cpp
    trunk/sources/editor/graphicspart/partarc.h
    trunk/sources/editor/graphicspart/partellipse.cpp
    trunk/sources/editor/graphicspart/partellipse.h
    trunk/sources/editor/graphicspart/partline.cpp
    trunk/sources/editor/graphicspart/partline.h
    trunk/sources/editor/graphicspart/partpolygon.cpp
    trunk/sources/editor/graphicspart/partpolygon.h
    trunk/sources/editor/graphicspart/partrectangle.cpp
    trunk/sources/editor/graphicspart/partrectangle.h
    trunk/sources/editor/graphicspart/partterminal.cpp
    trunk/sources/editor/graphicspart/partterminal.h
    trunk/sources/editor/lineeditor.cpp
    trunk/sources/editor/lineeditor.h
    trunk/sources/editor/rectangleeditor.cpp
    trunk/sources/editor/rectangleeditor.h

Added Paths:
-----------
    trunk/sources/editor/graphicspart/abstractpartellipse.cpp
    trunk/sources/editor/graphicspart/abstractpartellipse.h

Modified: trunk/sources/editor/arceditor.cpp
===================================================================
--- trunk/sources/editor/arceditor.cpp	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/arceditor.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -110,26 +110,26 @@
 */
 void ArcEditor::updateArc() {
 	if (!part) return;
-	part -> setProperty("x",           x  -> value());
-	part -> setProperty("y",           y  -> value());
-	part -> setProperty("diameter_h",  h  -> value());
-	part -> setProperty("diameter_v",  v  -> value());
-	part -> setProperty("start_angle", -start_angle -> value() + 90);
-	part -> setProperty("angle",       -angle -> value());
+	part -> setProperty("centerX",    x  -> value());
+	part -> setProperty("centerY",    y  -> value());
+	part -> setProperty("diameter_h", h  -> value());
+	part -> setProperty("diameter_v", v  -> value());
+	part -> setProperty("startAngle", ((start_angle -> value() * -1) + 90) * 16);
+	part -> setProperty("spanAngle",  angle -> value() * -16);
 }
 
 /// Met a jour l'abscisse du centre de l'arc et cree un objet d'annulation
-void ArcEditor::updateArcX() { addChangePartCommand(tr("abscisse"),               part, "x",           x  -> value());       }
+void ArcEditor::updateArcX() { addChangePartCommand(tr("abscisse"),               part, "centerX",     x  -> value()); }
 /// Met a jour l'ordonnee du centre de l'arc et cree un objet d'annulation
-void ArcEditor::updateArcY() { addChangePartCommand(tr("ordonn\351e"),            part, "y",           y  -> value());       }
+void ArcEditor::updateArcY() { addChangePartCommand(tr("ordonn\351e"),            part, "centerY",     y  -> value()); }
 /// Met a jour le diametre horizontal de l'arc et cree un objet d'annulation
-void ArcEditor::updateArcH() { addChangePartCommand(tr("diam\350tre horizontal"), part, "diameter_h",  h  -> value());       }
+void ArcEditor::updateArcH() { addChangePartCommand(tr("diam\350tre horizontal"), part, "diameter_h",  h  -> value()); }
 /// Met a jour le diametre vertical de l'arc et cree un objet d'annulation
-void ArcEditor::updateArcV() { addChangePartCommand(tr("diam\350tre vertical"),   part, "diameter_v",  v  -> value());       }
+void ArcEditor::updateArcV() { addChangePartCommand(tr("diam\350tre vertical"),   part, "diameter_v",  v  -> value()); }
 /// Met a jour l'angle de depart de l'arc et cree un objet d'annulation
-void ArcEditor::updateArcS() { addChangePartCommand(tr("angle de d\351part"),     part, "start_angle", -start_angle -> value() + 90); }
+void ArcEditor::updateArcS() { addChangePartCommand(tr("angle de d\351part"),     part, "startAngle", ((start_angle -> value() * -1) + 90) * 16); }
 /// Met a jour l'etendue de l'arc et cree un objet d'annulation
-void ArcEditor::updateArcA() { addChangePartCommand(tr("angle"),                  part, "angle",       -angle -> value());            }
+void ArcEditor::updateArcA() { addChangePartCommand(tr("angle"),                  part, "spanAngle",  angle -> value() * -16); }
 
 /**
 	Met a jour le formulaire d'edition
@@ -141,8 +141,8 @@
 	y->setValue(part->property("y").toReal());
 	h->setValue(part->property("diameter_h").toReal());
 	v->setValue(part->property("diameter_v").toReal());
-	start_angle -> setValue(-part -> startAngle() + 90);
-	angle -> setValue(-part -> angle());
+	start_angle -> setValue(((part->property("startAngle").toInt() / 16) - 90) * -1);
+	angle -> setValue(part->property("spanAngle").toInt() / -16);
 	activeConnections(true);
 }
 

Modified: trunk/sources/editor/editorcommands.cpp
===================================================================
--- trunk/sources/editor/editorcommands.cpp	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/editorcommands.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -567,8 +567,7 @@
 ScalePartsCommand::ScalePartsCommand(ElementScene *scene, QUndoCommand * parent) :
 	ElementEditionCommand(scene, 0, parent),
 	first_redo(true)
-{
-}
+{}
 
 /**
 	Destructor

Modified: trunk/sources/editor/elementscene.cpp
===================================================================
--- trunk/sources/editor/elementscene.cpp	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/elementscene.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -849,15 +849,15 @@
 				QDomElement qde = n.toElement();
 				if (qde.isNull()) continue;
 				CustomElementPart *cep;
-				if      (qde.tagName() == "line")     cep = new PartLine     (element_editor, 0, 0);
-				else if (qde.tagName() == "rect")     cep = new PartRectangle(element_editor, 0, 0);
-				else if (qde.tagName() == "ellipse")  cep = new PartEllipse  (element_editor, 0, 0);
-				else if (qde.tagName() == "circle")   cep = new PartEllipse  (element_editor, 0, 0);
-				else if (qde.tagName() == "polygon")  cep = new PartPolygon  (element_editor, 0, 0);
-				else if (qde.tagName() == "terminal") cep = new PartTerminal (element_editor, 0, 0);
-				else if (qde.tagName() == "text")     cep = new PartText     (element_editor, 0, 0);
-				else if (qde.tagName() == "input")    cep = new PartTextField(element_editor, 0, 0);
-				else if (qde.tagName() == "arc")      cep = new PartArc      (element_editor, 0, 0);
+				if      (qde.tagName() == "line")     cep = new PartLine     (element_editor);
+				else if (qde.tagName() == "rect")     cep = new PartRectangle(element_editor);
+				else if (qde.tagName() == "ellipse")  cep = new PartEllipse  (element_editor);
+				else if (qde.tagName() == "circle")   cep = new PartEllipse  (element_editor);
+				else if (qde.tagName() == "polygon")  cep = new PartPolygon  (element_editor);
+				else if (qde.tagName() == "terminal") cep = new PartTerminal (element_editor);
+				else if (qde.tagName() == "text")     cep = new PartText     (element_editor);
+				else if (qde.tagName() == "input")    cep = new PartTextField(element_editor);
+				else if (qde.tagName() == "arc")      cep = new PartArc      (element_editor);
 				else continue;
 				if (QGraphicsItem *qgi = dynamic_cast<QGraphicsItem *>(cep)) {
 					if (!qgi -> zValue()) qgi -> setZValue(z++);

Modified: trunk/sources/editor/ellipseeditor.cpp
===================================================================
--- trunk/sources/editor/ellipseeditor.cpp	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/ellipseeditor.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -102,16 +102,16 @@
 */
 void EllipseEditor::updateEllipse() {
 	if (!part) return;
-	part -> setProperty("x",           x  -> value());
-	part -> setProperty("y",           y  -> value());
+	part -> setProperty("centerX",     x  -> value());
+	part -> setProperty("centerY",     y  -> value());
 	part -> setProperty("diameter_h",  h  -> value());
 	part -> setProperty("diameter_v",  v  -> value());
 }
 
 /// Met a jour l'abscisse du centre de l'ellipse et cree un objet d'annulation
-void EllipseEditor::updateEllipseX() { addChangePartCommand(tr("abscisse"),               part, "x",           x -> value());       }
+void EllipseEditor::updateEllipseX() { addChangePartCommand(tr("abscisse"),               part, "centerX",           x -> value());       }
 /// Met a jour l'ordonnee du centre de l'ellipse et cree un objet d'annulation
-void EllipseEditor::updateEllipseY() { addChangePartCommand(tr("ordonn\351e"),            part, "y",           y -> value());       }
+void EllipseEditor::updateEllipseY() { addChangePartCommand(tr("ordonn\351e"),            part, "centerY",           y -> value());       }
 /// Met a jour le diametre horizontal de l'ellipse et cree un objet d'annulation
 void EllipseEditor::updateEllipseH() { addChangePartCommand(tr("diam\350tre horizontal"), part, "diameter_h",  h -> value());       }
 /// Met a jour le diametre vertical de l'ellipse et cree un objet d'annulation
@@ -123,8 +123,8 @@
 void EllipseEditor::updateForm() {
 	if (!part) return;
 	activeConnections(false);
-	x->setValue(part->property("x").toReal());
-	y->setValue(part->property("y").toReal());
+	x->setValue(part->property("centerX").toReal());
+	y->setValue(part->property("centerY").toReal());
 	h->setValue(part->property("diameter_h").toReal());
 	v->setValue(part->property("diameter_v").toReal());
 	activeConnections(true);

Modified: trunk/sources/editor/esevent/eseventaddarc.cpp
===================================================================
--- trunk/sources/editor/esevent/eseventaddarc.cpp	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/esevent/eseventaddarc.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -45,30 +45,36 @@
  * @param event
  * @return
  */
-bool ESEventAddArc::mousePressEvent(QGraphicsSceneMouseEvent *event) {
-	if (event -> button() == Qt::LeftButton) {
+bool ESEventAddArc::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+	if (event -> button() == Qt::LeftButton)
+	{
 		if(!m_running) m_running = true;
 		QPointF pos = m_scene->snapToGrid(event -> scenePos());
 
-		//create new arc
-		if (!m_arc) {
-			m_arc = new PartArc(m_editor, 0, m_scene);
-			m_arc -> setRect(QRectF(pos, pos));
-			m_arc -> setAngle(90);
+			//create new arc
+		if (!m_arc)
+		{
+			m_arc = new PartArc(m_editor);
+			m_scene -> addItem(m_arc);
+			m_arc -> setPos(pos);
+			m_arc -> setProperty("startAngle", 0);
+			m_arc -> setProperty("spanAngle", 1440);
 			m_arc -> setProperty("antialias", true);
 			m_origin = pos;
 			return true;
 		}
 
-		//Add arc to scene
+			//At this point, m_arc is finish, we add it with an undo command
 		m_arc -> setRect(m_arc->rect().normalized());
 		m_scene -> undoStack().push(new AddPartCommand(QObject::tr("Arc"), m_scene, m_arc));
 
-		//Set m_arc to nullptr for create new ellipse at next mouse press
+			//Set m_arc to nullptr for create new ellipse at next mouse press
 		m_arc = nullptr;
 
 		return true;
 	}
+
 	return false;
 }
 
@@ -120,67 +126,78 @@
  * @brief ESEventAddArc::updateArc
  * Redraw the arc with curent value
  */
-void ESEventAddArc::updateArc() {
-
+void ESEventAddArc::updateArc()
+{
 	qreal width  = (m_mouse_pos.x() - m_origin.x())*2;
 	if (width < 0) width *= -1;
 	qreal height = (m_mouse_pos.y() - m_origin.y())*2;
 	if (height < 0) height *= -1;
 
-	QPointF pos_ = m_origin;
+	QPointF pos_ = m_arc -> mapFromScene(m_origin);
 
 	//Draw arc inverted
-	if (m_inverted) {
+	if (m_inverted)
+	{
 		//Adjust the start angle to be snapped at the origin point of draw
-		if (m_mouse_pos.y() > m_origin.y()) {
-
-			if (m_mouse_pos.x() > m_origin.x()) {
+		if (m_mouse_pos.y() > m_origin.y())
+		{
+			if (m_mouse_pos.x() > m_origin.x())
+			{
 				pos_.ry() -= height/2;
-				m_arc->setStartAngle(180);
+				m_arc->setStartAngle(2880);
 			}
-			else {
+			else
+			{
 				pos_.rx() -= width/2;
-				m_arc->setStartAngle(90);
+				m_arc->setStartAngle(1440);
 			}
 		}
-		else {
-			if (m_mouse_pos.x() > m_origin.x()) {
+		else
+		{
+			if (m_mouse_pos.x() > m_origin.x())
+			{
 				pos_.ry() -= height;
 				pos_.rx() -= width/2;
-				m_arc->setStartAngle(270);
+				m_arc->setStartAngle(4320);
 			}
-			else {
+			else
+			{
 				pos_.rx() -= width;
 				pos_.ry() -= height/2;
 				m_arc->setStartAngle(0);
 			}
 		}
 	}
-
-	//Draw arc non inverted
-	else {
-		//Adjust the start angle to be snapped at the origin point of draw
-		if (m_mouse_pos.y() > m_origin.y()) {
-
-			if (m_mouse_pos.x() > m_origin.x()) {
+		//Draw arc non inverted
+	else
+	{
+			//Adjust the start angle to be snapped at the origin point of draw
+		if (m_mouse_pos.y() > m_origin.y())
+		{
+			if (m_mouse_pos.x() > m_origin.x())
+			{
 				pos_.rx() -= width/2;
 				m_arc->setStartAngle(0);
 			}
-			else {
+			else
+			{
 				pos_.rx() -= width;
 				pos_.ry() -= height/2;
-				m_arc->setStartAngle(270);
+				m_arc->setStartAngle(4320);
 			}
 		}
-		else {
-			if (m_mouse_pos.x() > m_origin.x()) {
+		else
+		{
+			if (m_mouse_pos.x() > m_origin.x())
+			{
 				pos_.ry() -= height/2;
-				m_arc->setStartAngle(90);
+				m_arc->setStartAngle(1440);
 			}
-			else {
+			else
+			{
 				pos_.rx() -= width/2;
 				pos_.ry() -= height;
-				m_arc->setStartAngle(180);
+				m_arc->setStartAngle(2880);
 			}
 		}
 	}

Modified: trunk/sources/editor/esevent/eseventaddellipse.cpp
===================================================================
--- trunk/sources/editor/esevent/eseventaddellipse.cpp	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/esevent/eseventaddellipse.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -50,19 +50,20 @@
 		if(!m_running) m_running = true;
 		QPointF pos = m_scene->snapToGrid(event -> scenePos());
 
-		//create new ellpise
+			//create new ellpise
 		if (!m_ellipse) {
-			m_ellipse = new PartEllipse(m_editor, 0, m_scene);
-			m_ellipse -> setRect(QRectF(pos, pos));
-			m_origin = pos;
+			m_ellipse = new PartEllipse(m_editor);
+			m_scene -> addItem(m_ellipse);
+			m_ellipse -> setPos(pos);
+			m_origin = m_new_pos = pos;
 			return true;
 		}
 
-		//Add ellipse to scene
-		m_ellipse  -> setRect(m_ellipse -> rect().normalized());
+			//Add ellipse to scene
+		m_ellipse -> setRect(m_ellipse -> rect().normalized());
 		m_scene -> undoStack().push(new AddPartCommand(QObject::tr("Ellipse"), m_scene, m_ellipse));
 
-		//Set m_ellipse to nullptr for create new ellipse at next mouse press
+			//Set m_ellipse to nullptr for create new ellipse at next mouse press
 		m_ellipse = nullptr;
 
 		return true;
@@ -79,15 +80,16 @@
 	updateHelpCross(event -> scenePos());
 	if (!m_ellipse) return false;
 
-	QPointF mouse_pos = m_scene -> snapToGrid(event -> scenePos());
+	QPointF pos = m_scene -> snapToGrid(event -> scenePos());
+	if (pos == m_new_pos) return true;
+	m_new_pos = pos;
 
-	qreal width  = (mouse_pos.x() - m_origin.x())*2;
-	qreal height = (mouse_pos.y() - m_origin.y())*2;
+	qreal width  = (m_new_pos.x() - m_origin.x())*2;
+	qreal height = (m_new_pos.y() - m_origin.y())*2;
+		//calculates the position of the rectangle so that its center is at position (0,0) of m_ellipse
+	QPointF center(-width/2, -height/2);
 
-	QPointF pos(m_origin.x() - width/2,
-				m_origin.y() - height/2);
-
-	m_ellipse -> setRect(QRectF(pos, QSizeF(width, height)));
+	m_ellipse -> setRect(QRectF(center, QSizeF(width, height)));
 	return true;
 }
 

Modified: trunk/sources/editor/esevent/eseventaddellipse.h
===================================================================
--- trunk/sources/editor/esevent/eseventaddellipse.h	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/esevent/eseventaddellipse.h	2015-02-09 08:57:40 UTC (rev 3694)
@@ -41,7 +41,7 @@
 
 	private:
 		PartEllipse *m_ellipse;
-		QPointF      m_origin;
+		QPointF      m_origin, m_new_pos;
 };
 
 #endif // ESEVENTADDELLIPSE_H

Modified: trunk/sources/editor/esevent/eseventaddline.cpp
===================================================================
--- trunk/sources/editor/esevent/eseventaddline.cpp	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/esevent/eseventaddline.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -57,8 +57,10 @@
 
 		//Create new line
 		if (!m_line) {
-			m_line = new PartLine(m_editor, 0, m_scene);
-			m_line  -> setLine(QLineF(pos, pos));
+			m_line = new PartLine(m_editor);
+			m_scene -> addItem(m_line);
+			m_line -> setP1(pos);
+			m_line -> setP2(pos);
 			return true;
 		}
 

Modified: trunk/sources/editor/esevent/eseventaddpolygon.cpp
===================================================================
--- trunk/sources/editor/esevent/eseventaddpolygon.cpp	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/esevent/eseventaddpolygon.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -51,7 +51,8 @@
 
 		//create new polygon
 		if (!m_polygon) {
-			m_polygon = new PartPolygon(m_editor, 0, m_scene);
+			m_polygon = new PartPolygon(m_editor);
+			m_scene -> addItem(m_polygon);
 			m_polygon -> addPoint(pos);
 		}
 

Modified: trunk/sources/editor/esevent/eseventaddrect.cpp
===================================================================
--- trunk/sources/editor/esevent/eseventaddrect.cpp	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/esevent/eseventaddrect.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -44,23 +44,29 @@
  * @param event
  * @return
  */
-bool ESEventAddRect::mousePressEvent(QGraphicsSceneMouseEvent *event) {
-	if (event -> button() == Qt::LeftButton) {
+bool ESEventAddRect::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+	if (event -> button() == Qt::LeftButton)
+	{
 		if(!m_running) m_running = true;
 		QPointF pos = m_scene->snapToGrid(event -> scenePos());
 
-		//create new rectangle
-		if (!m_rect) {
-			m_rect = new PartRectangle(m_editor, 0, m_scene);
+			//create new rectangle, pos isn't define,
+			//so m_rect.pos = 0,0 , that mean event.scenePos is in same coordinate of item
+			//we don't need to map point for m_rect
+		if (!m_rect)
+		{
+			m_rect = new PartRectangle(m_editor);
+			m_scene -> addItem(m_rect);
 			m_rect -> setRect(QRectF(pos, pos));
 			return true;
 		}
 
-		//Add rectangle to scene
+			//Add rectangle to scene
 		m_rect  -> setRect(m_rect -> rect().normalized());
 		m_scene -> undoStack().push(new AddPartCommand(QObject::tr("Rectangle"), m_scene, m_rect));
 
-		//Set m_rect to nullptr for create new rectangle at next mouse press
+			//Set m_rect to nullptr for create new rectangle at next mouse press
 		m_rect = nullptr;
 
 		return true;
@@ -77,7 +83,7 @@
 	updateHelpCross(event -> scenePos());
 	if (!m_rect) return false;
 
-	QRectF rect(m_rect -> rect().topLeft(), m_scene->snapToGrid(event -> scenePos()));
+	QRectF rect(m_rect->rectTopLeft(), m_scene->snapToGrid(event -> scenePos()));
 	m_rect -> setRect(rect);
 	return true;
 }

Modified: trunk/sources/editor/esevent/eseventaddrect.h
===================================================================
--- trunk/sources/editor/esevent/eseventaddrect.h	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/esevent/eseventaddrect.h	2015-02-09 08:57:40 UTC (rev 3694)
@@ -19,6 +19,7 @@
 #define ESEVENTADDRECT_H
 
 #include "eseventinterface.h"
+#include <QPointF>
 
 class ElementScene;
 class PartRectangle;

Modified: trunk/sources/editor/esevent/eseventaddterminal.cpp
===================================================================
--- trunk/sources/editor/esevent/eseventaddterminal.cpp	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/esevent/eseventaddterminal.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -29,7 +29,8 @@
 ESEventAddTerminal::ESEventAddTerminal(ElementScene *scene) :
 	ESEventInterface(scene)
 {
-	m_terminal = new PartTerminal(m_editor, 0, m_scene);
+	m_terminal = new PartTerminal(m_editor);
+	m_scene -> addItem(m_terminal);
 	m_running  = true;
 }
 
@@ -63,7 +64,8 @@
 
 		//Set new terminal with same rotation
 		Qet::Orientation ori = m_terminal -> orientation();
-		m_terminal = new PartTerminal(m_editor, 0, m_scene);
+		m_terminal = new PartTerminal(m_editor);
+		m_scene -> addItem(m_terminal);
 		m_terminal -> setOrientation(ori);
 		m_terminal -> setPos(m_scene -> snapToGrid(event -> scenePos()));
 

Added: trunk/sources/editor/graphicspart/abstractpartellipse.cpp
===================================================================
--- trunk/sources/editor/graphicspart/abstractpartellipse.cpp	                        (rev 0)
+++ trunk/sources/editor/graphicspart/abstractpartellipse.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -0,0 +1,229 @@
+/*
+	Copyright 2006-2015 The QElectroTech Team
+	This file is part of QElectroTech.
+
+	QElectroTech is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 2 of the License, or
+	(at your option) any later version.
+
+	QElectroTech is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "abstractpartellipse.h"
+
+/**
+ * @brief AbstractPartEllipse::AbstractPartEllipse
+ * Constructor
+ * @param editor : QETElementEditor of this part
+ * @param parent : parent item
+ */
+AbstractPartEllipse::AbstractPartEllipse(QETElementEditor *editor, QGraphicsItem *parent) :
+	CustomElementGraphicPart(editor, parent),
+	m_rect                  (QRectF(0, 0, 0, 0)),
+	m_start_angle           (0),
+	m_span_angle            (5760)
+{}
+
+/**
+ * @brief AbstractPartEllipse::~AbstractPartEllipse
+ * Destructor
+ */
+AbstractPartEllipse::~AbstractPartEllipse() {}
+
+/**
+ * @brief AbstractPartEllipse::startUserTransformation
+ * Start the user-induced transformation, provided this primitive is contained
+ * within the initial_selection_rect bounding rectangle.
+ * @param initial_selection_rect
+ */
+void AbstractPartEllipse::startUserTransformation(const QRectF &initial_selection_rect)
+{
+	Q_UNUSED(initial_selection_rect)
+		// we keep track of our own rectangle at the moment in scene coordinates too
+	saved_points_.clear();
+	saved_points_ << mapToScene(rect().topLeft()) << mapToScene(rect().bottomRight());
+}
+
+/**
+ * @brief AbstractPartEllipse::handleUserTransformation
+ * Handle the user-induced transformation from \a initial_selection_rect to \a new_selection_rect
+ * @param initial_selection_rect
+ * @param new_selection_rect
+ */
+void AbstractPartEllipse::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect)
+{
+	QList<QPointF> mapped_points = mapPoints(initial_selection_rect, new_selection_rect, saved_points_);
+	setRect(QRectF(mapFromScene(mapped_points.at(0)), mapFromScene(mapped_points.at(1))));
+}
+
+/**
+ * @brief AbstractPartEllipse::boundingRect
+ * Bounding rectangle this part can fit into
+ * @return
+ */
+QRectF AbstractPartEllipse::boundingRect() const
+{
+	qreal adjust = (SHADOWS_HEIGHT + penWeight()) / 2;
+		//We add 0.5 because CustomElementGraphicPart::drawShadowShape
+		//draw a shape bigger of 0.5 when pen weight is to 0.
+	if (penWeight() == 0) adjust += 0.5;
+	QRectF r(m_rect.normalized());
+	r.adjust(-adjust, -adjust, adjust, adjust);
+	return(r);
+}
+
+/**
+ * @brief AbstractPartEllipse::sceneGeometricRect
+ * @return the minimum, margin-less rectangle this part can fit into in scene coordinates.
+ * It is different from boundingRect() because it is not supposed
+ * to imply any margin, and it is different from shape because it is a regular
+ * rectangle, not a complex shape.
+ */
+QRectF AbstractPartEllipse::sceneGeometricRect() const {
+	return(mapToScene(rect()).boundingRect());
+}
+
+/**
+ * @brief AbstractPartEllipse::sceneTopLeft
+ * @return return the top left of rectangle, in scene coordinate
+ */
+QPointF AbstractPartEllipse::sceneTopLeft() const {
+	return(mapToScene(rect().topLeft()));
+}
+
+/**
+ * @brief AbstractPartEllipse::rect
+ * Returns the item's ellipse geometry as a QRectF.
+ */
+QRectF AbstractPartEllipse::rect() const {
+	return m_rect;
+}
+
+/**
+ * @brief AbstractPartEllipse::setRect
+ * Sets the item's ellipse geometry to rect.
+ * The rectangle's left edge defines the left edge of the ellipse,
+ * and the rectangle's top edge describes the top of the ellipse
+ * The height and width of the rectangle describe the height and width of the ellipse.
+ * @param rect
+ */
+void AbstractPartEllipse::setRect(const QRectF &rect)
+{
+	if (rect == m_rect) return;
+	prepareGeometryChange();
+	m_rect = rect;
+}
+
+/**
+ * @brief AbstractPartEllipse::isUseless
+ * @return true if this part is irrelevant and does not deserve to be Retained / registered.
+ * An ellipse is relevant when is rect is not null.
+ */
+bool AbstractPartEllipse::isUseless() const {
+	return(rect().isNull());
+}
+
+/**
+ * @brief AbstractPartEllipse::setStartAngle
+ * Sets the start angle for an ellipse segment to angle, which is in 16ths of a degree.
+ * This angle is used together with spanAngle() for representing an ellipse segment (a pie).
+ * By default, the start angle is 0.
+ * @param start_angle
+ */
+void AbstractPartEllipse::setStartAngle(const int &start_angle)
+{
+	if (m_start_angle == start_angle) return;
+	m_start_angle = start_angle;
+	update();
+}
+
+/**
+ * @brief AbstractPartEllipse::setSpanAngle
+ * Returns the span angle of an ellipse segment in 16ths of a degree.
+ * This angle is used together with startAngle() for representing an ellipse segment (a pie).
+ * By default, this function returns 5760 (360 * 16, a full ellipse).
+ * @param span_angle
+ */
+void AbstractPartEllipse::setSpanAngle(const int &span_angle)
+{
+	if (m_span_angle == span_angle) return;
+	m_span_angle = span_angle;
+	update();
+}
+
+/**
+ * @brief AbstractPartEllipse::setCenterX
+ * Like setCenter but Y keep unchanged
+ * See setCenter(const QPointF &center)
+ * @param x
+ */
+void AbstractPartEllipse::setCenterX(const qreal x)
+{
+	QPointF pos = mapToParent(m_rect.center());
+	pos.setX(x);
+	setCenter(pos);
+}
+
+/**
+ * @brief AbstractPartEllipse::setCenterY
+ * Like setCenter but X keep unchanged
+ * See setCenter(const QPointF &center)
+ * @param y
+ */
+void AbstractPartEllipse::setCenterY(const qreal y)
+{
+	QPointF pos = mapToParent(m_rect.center());
+	pos.setY(y);
+	setCenter(pos);
+}
+
+/**
+ * @brief AbstractPartEllipse::setCenter
+ * This is a convenience method to setPos().
+ * Adjust the position of this item,
+ * so that the center of the rectangle is at the given position(position in parent coordinates).
+ * @param center
+ */
+void AbstractPartEllipse::setCenter(const QPointF &center)
+{
+	QPointF pos = center - m_rect.center();
+	setPos(pos);
+}
+
+/**
+ * @brief AbstractPartEllipse::setWidth
+ * Set new width for rectangle.
+ * The center of rectangle is unchanged,
+ * The coordinates of the left side and right side of the rectangle change
+ * @param w
+ */
+void AbstractPartEllipse::setWidth(const qreal w)
+{
+	qreal new_width = qAbs(w);
+	QRectF current_rect = rect();
+	current_rect.translate((new_width - current_rect.width()) / -2.0, 0.0);
+	current_rect.setWidth(new_width);
+	setRect(current_rect);
+}
+
+/**
+ * @brief AbstractPartEllipse::setHeight
+ * Set new height for rectangle
+ * The center of rectangle is unchanged
+ * The coordinates of the top side and bottom side of the rectangle change
+ * @param h
+ */
+void AbstractPartEllipse::setHeight(const qreal h)
+{
+	qreal new_height = qAbs(h);
+	QRectF current_rect = rect();
+	current_rect.translate(0.0, (new_height - current_rect.height()) / -2.0);
+	current_rect.setHeight(new_height);
+	setRect(current_rect);
+}

Added: trunk/sources/editor/graphicspart/abstractpartellipse.h
===================================================================
--- trunk/sources/editor/graphicspart/abstractpartellipse.h	                        (rev 0)
+++ trunk/sources/editor/graphicspart/abstractpartellipse.h	2015-02-09 08:57:40 UTC (rev 3694)
@@ -0,0 +1,92 @@
+/*
+	Copyright 2006-2015 The QElectroTech Team
+	This file is part of QElectroTech.
+
+	QElectroTech is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 2 of the License, or
+	(at your option) any later version.
+
+	QElectroTech is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef ABSTRACTPARTELLIPSE_H
+#define ABSTRACTPARTELLIPSE_H
+
+#include "customelementgraphicpart.h"
+
+/**
+ * @brief The AbstractPartEllipse class
+ * This is the base class for all ellipse based item like ellipse, circle, arc.
+ * This class only provide common method for edit the ellipse like rect that contain the ellipse.
+ * All coordinates is in item coordinate, except pos(), center(), centerX() and centerY()
+ * which are in parent coordinate (or scene if no parent).
+ *
+ * In several points, this class is a copy of QGraphicsEllipseItem with some change,
+ * (the use of Q_PROPERTY) to be easily used with Element editor.
+ */
+class AbstractPartEllipse : public CustomElementGraphicPart
+{
+		Q_OBJECT
+		Q_PROPERTY(int startAngle   READ startAngle WRITE setStartAngle)
+		Q_PROPERTY(int spanAngle    READ spanAngle  WRITE setSpanAngle)
+		Q_PROPERTY(qreal centerX    READ centerX    WRITE setCenterX)
+		Q_PROPERTY(qreal centerY    READ centerY    WRITE setCenterY)
+		Q_PROPERTY(qreal diameter_h READ width      WRITE setWidth)
+		Q_PROPERTY(qreal diameter_v READ height     WRITE setHeight)
+
+		// constructors, destructor
+	public:
+		AbstractPartEllipse(QETElementEditor *editor, QGraphicsItem * parent = 0);
+		virtual ~AbstractPartEllipse();
+
+	private:
+		AbstractPartEllipse(const AbstractPartEllipse &);
+
+		// methods
+	public:
+		virtual void startUserTransformation  (const QRectF &);
+		virtual void handleUserTransformation (const QRectF &, const QRectF &);
+
+			//Coordinates
+		virtual QRectF  boundingRect()       const;
+		virtual QRectF  sceneGeometricRect() const;
+		virtual QPointF sceneTopLeft()       const;
+
+		QRectF rect() const;
+		void   setRect (const QRectF &rect);
+		virtual bool isUseless() const;
+
+		int  startAngle() const {return m_start_angle;}
+		void setStartAngle (const int &start_angle);
+
+		int  spanAngle () const {return m_span_angle;}
+		void setSpanAngle (const int &span_angle);
+
+		qreal centerX() const {return mapToScene(rect().center()).x() ;}
+		void  setCenterX(const qreal x);
+
+		qreal centerY() const {return mapToScene(rect().center()).y();}
+		void  setCenterY(const qreal y);
+
+		void setCenter (const QPointF &center);
+
+		qreal width() const {return rect().width();}
+		void  setWidth(const qreal w);
+
+		qreal height() const {return rect().height();}
+		void  setHeight (const qreal h);
+
+	protected:
+		QList<QPointF> saved_points_;
+		QRectF m_rect;
+		int m_start_angle;
+		int m_span_angle;
+};
+
+#endif // ABSTRACTPARTELLIPSE_H

Modified: trunk/sources/editor/graphicspart/customelementgraphicpart.cpp
===================================================================
--- trunk/sources/editor/graphicspart/customelementgraphicpart.cpp	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/customelementgraphicpart.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -20,16 +20,27 @@
 /**
  * @brief CustomElementGraphicPart::CustomElementGraphicPart
  * Default constructor.
+ * By default, item is selectable, send geometry change (Qt > 4.6),
+ * accept mouse left button and accept hover event
  * @param editor QETElement editor that belong this.
  */
-CustomElementGraphicPart::CustomElementGraphicPart(QETElementEditor *editor) :
+CustomElementGraphicPart::CustomElementGraphicPart(QETElementEditor *editor, QGraphicsItem *parent) :
+	QGraphicsObject (parent),
 	CustomElementPart(editor),
+	m_hovered (false),
 	_linestyle(NormalStyle),
 	_lineweight(NormalWeight),
 	_filling(NoneFilling),
 	_color(BlackColor),
 	_antialiased(false)
-{}
+{
+	setFlags(QGraphicsItem::ItemIsSelectable);
+#if QT_VERSION >= 0x040600
+	setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
+#endif
+	setAcceptedMouseButtons(Qt::LeftButton);
+	setAcceptHoverEvents(true);
+}
 
 /**
  * @brief CustomElementGraphicPart::~CustomElementGraphicPart
@@ -38,6 +49,36 @@
 CustomElementGraphicPart::~CustomElementGraphicPart() {}
 
 /**
+ * @brief CustomElementGraphicPart::drawCross
+ * Draw a cross at pos center
+ * @param center : center of cross
+ * @param painter : painter to use for draw cross,
+ * the painter state is restored at end of this method.
+ */
+void CustomElementGraphicPart::drawCross(const QPointF &center, QPainter *painter)
+{
+	painter -> save();
+	painter -> setRenderHint(QPainter::Antialiasing, false);
+	painter -> setPen((painter -> brush().color() == QColor(Qt::black) && painter -> brush().isOpaque()) ? Qt::yellow : Qt::blue);
+	painter -> drawLine(QLineF(center.x() - 2.0, center.y(), center.x() + 2.0, center.y()));
+	painter -> drawLine(QLineF(center.x(), center.y() - 2.0, center.x(), center.y() + 2.0));
+	painter -> restore();
+}
+
+/**
+ * @brief CustomElementGraphicPart::penWeight
+ * @return the weight of pen
+ */
+qreal CustomElementGraphicPart::penWeight() const
+{
+	if      (_lineweight == NoneWeight || _lineweight == ThinWeight) return 0;
+	else if (_lineweight == NormalWeight) return 1;
+	else if (_lineweight == UltraWeight)  return 2;
+	else if (_lineweight == BigWeight)    return 5;
+	return 1;
+}
+
+/**
  * @brief CustomElementGraphicPart::stylesToXml
  * Write the curent style to xml element.
  * The style are stored like this:
@@ -206,3 +247,69 @@
 	painter.setPen(pen);
 	painter.setBrush(brush);
 }
+
+/**
+ * @brief CustomElementGraphicPart::drawShadowShape
+ * Draw a transparent blue shadow arround the shape of this item.
+ * The QPainterPathStroker used to draw shadows have a width of SHADOWS_HEIGHT
+ * Be carefull if penWeight of this item is to 0 the outline of strock is bigger of 0.5
+ * @param painter : painter to use for draw this shadows
+ */
+void CustomElementGraphicPart::drawShadowShape(QPainter *painter)
+{
+		//@FIXME if pen weight is 0, the strock outline is SHADOWS_HEIGHT/2 + 0.5
+		//may be because shape have no line weight
+	QPainterPathStroker strock;
+	strock.setWidth(SHADOWS_HEIGHT);
+	strock.setJoinStyle(Qt::RoundJoin);
+
+	painter->save();
+	QColor color(Qt::darkBlue);
+	color.setAlpha(50);
+	painter -> setBrush (QBrush (color));
+	painter -> setPen   (Qt::NoPen);
+	painter -> drawPath (strock.createStroke(shape()));
+	painter -> restore  ();
+}
+
+/**
+ * @brief CustomElementGraphicPart::itemChange
+ * Reimplemented from QGraphicsObject.
+ * If the item position change call updateCurrentPartEditor()
+ * the change is always send to QGraphicsObject
+ * @param change
+ * @param value
+ * @return the returned value of QGraphicsObject::itemChange
+ */
+QVariant CustomElementGraphicPart::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+	if (scene())
+		if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged)
+			updateCurrentPartEditor();
+
+	return(QGraphicsObject::itemChange(change, value));
+}
+
+/**
+ * @brief CustomElementGraphicPart::hoverEnterEvent
+ * Reimplemented from QGraphicsObject.
+ * Set m_hovered to true
+ * @param event
+ */
+void CustomElementGraphicPart::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
+{
+	m_hovered = true;
+	QGraphicsObject::hoverEnterEvent(event);
+}
+
+/**
+ * @brief CustomElementGraphicPart::hoverLeaveEvent
+ * Reimplemented from QGraphicsObject.
+ * Set m_hovered to false
+ * @param event
+ */
+void CustomElementGraphicPart::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
+{
+	m_hovered = false;
+	QGraphicsObject::hoverLeaveEvent(event);
+}

Modified: trunk/sources/editor/graphicspart/customelementgraphicpart.h
===================================================================
--- trunk/sources/editor/graphicspart/customelementgraphicpart.h	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/customelementgraphicpart.h	2015-02-09 08:57:40 UTC (rev 3694)
@@ -18,19 +18,22 @@
 #ifndef CUSTOM_ELEMENT_GRAPHIC_PART_H
 #define CUSTOM_ELEMENT_GRAPHIC_PART_H
 
-#include <QObject>
+#include <QGraphicsObject>
 #include "customelementpart.h"
 
 class QETElementEditor;
 class QPainter;
 
+
 /**
  * @brief The CustomElementGraphicPart class
  * This class is the base for all home-made primitive like line, rectangle, ellipse etc....
  * It provides methods and enums to manage style attributes available for primitive (color, pen style, etc...)
  */
-class CustomElementGraphicPart : public QObject, public CustomElementPart
+class CustomElementGraphicPart : public QGraphicsObject, public CustomElementPart
 {
+		#define SHADOWS_HEIGHT 4.0
+
 		Q_OBJECT
 
 			//Made this Q_ENUMS to be used by the Q_PROPERTY system.
@@ -62,15 +65,18 @@
 		// constructors, destructor
 	public:
 
-		CustomElementGraphicPart(QETElementEditor *editor);
+		CustomElementGraphicPart(QETElementEditor *editor, QGraphicsItem *parent = 0);
 		virtual ~CustomElementGraphicPart();
 
+		static void drawCross (const QPointF &center, QPainter *painter);
+
 			//Getter and setter
 		LineStyle lineStyle    () const             {return _linestyle;}
 		void      setLineStyle (const LineStyle ls) {_linestyle = ls;}
 
 		LineWeight lineWeight    () const              {return _lineweight;}
 		void       setLineWeight (const LineWeight lw) {_lineweight = lw;}
+		qreal      penWeight     () const;
 
 		Filling filling   () const          {return _filling;}
 		void    setFilling(const Filling f) {_filling = f;}
@@ -92,8 +98,14 @@
 		void stylesFromXml(const QDomElement &);
 		void resetStyles  ();
 		void applyStylesToQPainter(QPainter &) const;
-	
+		void drawShadowShape (QPainter *painter);
+
+		QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+		void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
+		void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
+
 		// attributes
+		bool m_hovered;
 	private:
 		LineStyle _linestyle;
 		LineWeight _lineweight;

Modified: trunk/sources/editor/graphicspart/partarc.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partarc.cpp	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partarc.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -18,68 +18,68 @@
 #include "partarc.h"
 
 /**
-	Constructeur
-	@param editor L'editeur d'element concerne
-	@param parent Le QGraphicsItem parent de cet arc
-	@param scene La scene sur laquelle figure cet arc
-*/
-PartArc::PartArc(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) :
-	CustomElementGraphicPart(editor),
-	QGraphicsEllipseItem(parent, scene),
-	_angle(-90),
-	start_angle(0)
+ * @brief PartArc::PartArc
+ * Constructor
+ * @param editor : QETElementEditor of this part
+ * @param parent : parent item
+ */
+PartArc::PartArc(QETElementEditor *editor, QGraphicsItem *parent) :
+	AbstractPartEllipse(editor, parent)
 {
-	setFlags(QGraphicsItem::ItemIsSelectable);
-#if QT_VERSION >= 0x040600
-	setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
-#endif
-	setAcceptedMouseButtons(Qt::LeftButton);
+	m_start_angle = 0;
+	m_span_angle = -1440;
 }
 
-/// Destructeur
-PartArc::~PartArc() {
-}
+/**
+ * @brief PartArc::~PartArc
+ * Destructor
+ */
+PartArc::~PartArc() {}
 
 /**
-	Dessine l'arc de cercle
-	@param painter QPainter a utiliser pour rendre le dessin
-	@param options Options pour affiner le rendu
-	@param widget Widget sur lequel le rendu est effectue
-*/
-void PartArc::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
+ * @brief PartArc::paint
+ * Draw this arc
+ * @param painter
+ * @param options
+ * @param widget
+ */
+void PartArc::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget)
+{
 	Q_UNUSED(widget);
+
 	applyStylesToQPainter(*painter);
-	// enleve systematiquement la couleur de fond
+
+		//Always remove the brush
 	painter -> setBrush(Qt::NoBrush);
 	QPen t = painter -> pen();
 	t.setCosmetic(options && options -> levelOfDetail < 1.0);
 	painter -> setPen(t);
 	
-	if (isSelected()) {
-		// dessine l'ellipse en noir
+	if (isSelected())
+	{
+			//Draw the ellipse in black
 		painter -> drawEllipse(rect());
-		
-		// dessine l'arc en rouge
+
+			//Draw the arc in red
 		t.setColor(Qt::red);
 		painter -> setPen(t);
 	}
 	
-	painter -> drawArc(rect(), start_angle * 16, _angle * 16);
-	if (isSelected()) {
-		// dessine la croix au centre de l'ellipse
-		painter -> setRenderHint(QPainter::Antialiasing, false);
-		painter -> setPen((painter -> brush().color() == QColor(Qt::black) && painter -> brush().isOpaque()) ? Qt::yellow : Qt::blue);
-		QPointF center = rect().center();
-		painter -> drawLine(QLineF(center.x() - 2.0, center.y(), center.x() + 2.0, center.y()));
-		painter -> drawLine(QLineF(center.x(), center.y() - 2.0, center.x(), center.y() + 2.0));
-	}
+	painter -> drawArc(m_rect, m_start_angle, m_span_angle);
+
+	if (m_hovered)
+		drawShadowShape(painter);
+
+	if (isSelected())
+		drawCross(m_rect.center(), painter);
 }
 
 /**
-	Exporte l'arc de cercle en XML
-	@param xml_document Document XML a utiliser pour creer l'element XML
-	@return un element XML decrivant l'arc de cercle
-*/
+ * @brief PartArc::toXml
+ * Export this arc in xml
+ * @param xml_document : Xml document to use for create the xml element.
+ * @return : an xml element that describe this arc
+ */
 const QDomElement PartArc::toXml(QDomDocument &xml_document) const {
 	QDomElement xml_element = xml_document.createElement("arc");
 	QPointF top_left(sceneTopLeft());
@@ -87,144 +87,41 @@
 	xml_element.setAttribute("y", QString("%1").arg(top_left.y()));
 	xml_element.setAttribute("width",  QString("%1").arg(rect().width()));
 	xml_element.setAttribute("height", QString("%1").arg(rect().height()));
-	xml_element.setAttribute("start", QString("%1").arg(start_angle));
-	xml_element.setAttribute("angle", QString("%1").arg(_angle));
+		//to maintain compatibility with the previous version, we write the angle in degrees.
+	xml_element.setAttribute("start", QString("%1").arg(m_start_angle / 16));
+	xml_element.setAttribute("angle", QString("%1").arg(m_span_angle / 16));
 	stylesToXml(xml_element);
 	return(xml_element);
 }
 
 /**
-	Importe les proprietes d'un arc de cercle depuis un element XML
-	@param qde Element XML a lire
-*/
+ * @brief PartArc::fromXml
+ * Import the properties of this arc from a xml element.
+ * @param qde : Xml document to use.
+ */
 void PartArc::fromXml(const QDomElement &qde) {
 	stylesFromXml(qde);
-	setRect(
-		QRectF(
-			mapFromScene(
-				qde.attribute("x", "0").toDouble(),
-				qde.attribute("y", "0").toDouble()
-			),
-			QSizeF(
-				qde.attribute("width",  "0").toDouble(),
-				qde.attribute("height", "0").toDouble()
-			)
-		)
-	);
-	setStartAngle(qde.attribute("start", "0").toInt());
-	setAngle(qde.attribute("angle", "-90").toInt());
-}
+	m_rect = QRectF(mapFromScene(qde.attribute("x", "0").toDouble(),
+								 qde.attribute("y", "0").toDouble()),
+					QSizeF(qde.attribute("width",  "0").toDouble(),
+						   qde.attribute("height", "0").toDouble()) );
 
-/**
-	@return le coin superieur gauche du rectangle dans lequel s'inscrit
-	l'ellipse dont fait partie cet arc, dans les coordonnees de la scene.
-*/
-QPointF PartArc::sceneTopLeft() const {
-	return(mapToScene(rect().topLeft()));
+	m_start_angle = qde.attribute("start", "0").toInt() * 16;
+	m_span_angle  = qde.attribute("angle", "-1440").toInt() * 16;
 }
 
 /**
- * @brief PartArc::setX
- * @param x is the center of the rect bounding this ellipse
+ * @brief PartArc::shape
+ * @return the shape of this item
  */
-void PartArc::setX(const qreal x) {
-	QRectF current_rect = rect();
-	QPointF current_pos = mapToScene(current_rect.center());
-	setRect(current_rect.translated(x - current_pos.x(), 0.0));
-}
+QPainterPath PartArc::shape() const
+{
+	QPainterPath shape;
+	shape.arcMoveTo(m_rect, m_start_angle/16);
+	shape.arcTo(m_rect, m_start_angle/16, m_span_angle/16);
 
-/**
- * @brief PartArc::setY
- * @param y is the center of the rect bounding this ellipse
- */
-void PartArc::setY(const qreal y) {
-	QRectF current_rect = rect();
-	QPointF current_pos = mapToScene(current_rect.center());
-	setRect(current_rect.translated(0.0, y - current_pos.y()));
-}
+	QPainterPathStroker pps;
+	pps.setWidth(penWeight());
 
-/**
- * @brief PartArc::setWidth
- * @param w is the width of the rect bounding this ellipse
- */
-void PartArc::setWidth(const qreal w) {
-	qreal new_width = qAbs(w);
-	QRectF current_rect = rect();
-	current_rect.translate((new_width - current_rect.width()) / -2.0, 0.0);
-	current_rect.setWidth(new_width);
-	setRect(current_rect);
+	return (pps.createStroke(shape));
 }
-
-/**
- * @brief PartArc::setHeight
- * @param h is the heigth of the rect bounding this ellipse
- */
-void PartArc::setHeight(const qreal h) {
-	qreal new_height = qAbs(h);
-	QRectF current_rect = rect();
-	current_rect.translate(0.0, (new_height - current_rect.height()) / -2.0);
-	current_rect.setHeight(new_height);
-	setRect(current_rect);
-}
-
-/**
-	Gere les changements intervenant sur cette partie
-	@param change Type de changement
-	@param value Valeur numerique relative au changement
-*/
-QVariant PartArc::itemChange(GraphicsItemChange change, const QVariant &value) {
-	if (scene()) {
-		if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged) {
-			updateCurrentPartEditor();
-		}
-	}
-	return(QGraphicsEllipseItem::itemChange(change, value));
-}
-
-/**
-	@return true si cette partie n'est pas pertinente et ne merite pas d'etre
-	conservee / enregistree.
-	Un arc est pertinent des lors que ses dimensions et son etendue ne sont
-	pas nulles.
-*/
-bool PartArc::isUseless() const {
-	return(rect().isNull() || !angle());
-}
-
-/**
-	@return the minimum, margin-less rectangle this part can fit into, in scene
-	coordinates. It is different from boundingRect() because it is not supposed
-	to imply any margin, and it is different from shape because it is a regular
-	rectangle, not a complex shape.
-*/
-QRectF PartArc::sceneGeometricRect() const {
-	return(mapToScene(rect()).boundingRect());
-}
-
-/**
-	Start the user-induced transformation, provided this primitive is contained
-	within the \a initial_selection_rect bounding rectangle.
-*/
-void PartArc::startUserTransformation(const QRectF &initial_selection_rect) {
-	Q_UNUSED(initial_selection_rect)
-	saved_points_.clear();
-	saved_points_ << mapToScene(rect().topLeft()) << mapToScene(rect().bottomRight());
-}
-
-/**
-	Handle the user-induced transformation from \a initial_selection_rect to \a new_selection_rect
-*/
-void PartArc::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect) {
-	QList<QPointF> mapped_points = mapPoints(initial_selection_rect, new_selection_rect, saved_points_);
-	setRect(QRectF(mapFromScene(mapped_points.at(0)), mapFromScene(mapped_points.at(1))));
-}
-
-/**
-	@return le rectangle delimitant cette partie.
-*/
-QRectF PartArc::boundingRect() const {
-	qreal adjust = 1.5;
-	QRectF r(QGraphicsEllipseItem::boundingRect().normalized());
-	r.adjust(-adjust, -adjust, adjust, adjust);
-	return(r);
-}

Modified: trunk/sources/editor/graphicspart/partarc.h
===================================================================
--- trunk/sources/editor/graphicspart/partarc.h	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partarc.h	2015-02-09 08:57:40 UTC (rev 3694)
@@ -17,79 +17,41 @@
 */
 #ifndef PART_ARC_H
 #define PART_ARC_H
-#include <QtGui>
-#include "customelementgraphicpart.h"
+
+#include "abstractpartellipse.h"
+
 /**
-	This class represents an elliptical arc primitive which may be used to
-	compose the drawing of an electrical element within the element editor.
-*/
-class PartArc : public CustomElementGraphicPart, public QGraphicsEllipseItem {
-	Q_OBJECT
-	// constructors, destructor
+ * @brief The PartArc class
+ * This class represents an elliptical arc primitive which may be used to
+ * compose the drawing of an electrical element within the element editor.
+ */
+class PartArc : public AbstractPartEllipse
+{
+		Q_OBJECT
+
 	public:
-	PartArc(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
-	virtual ~PartArc();
+		PartArc(QETElementEditor *editor, QGraphicsItem *parent = 0);
+		virtual ~PartArc();
 	
 	private:
-	PartArc(const PartArc &);
-	
-	// attributes
-	private:
-	int _angle;
-	int start_angle;
-	
-	// methods
+		PartArc(const PartArc &);
+		
+		// methods
 	public:
-	enum { Type = UserType + 1101 };
-	/**
-		Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
-		PartArc.
-		@return the QGraphicsItem type
-	*/
-	virtual int type() const { return Type; }
-	virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
-	virtual QString name() const { return(QObject::tr("arc", "element part name")); }
-	virtual QString xmlName() const { return(QString("arc")); }
-	virtual const QDomElement toXml(QDomDocument &) const;
-	virtual void fromXml(const QDomElement &);
-	virtual QPointF sceneTopLeft() const;
-	virtual QRectF boundingRect() const;
-	virtual bool isUseless() const;
-	virtual QRectF sceneGeometricRect() const;
-	virtual void startUserTransformation(const QRectF &);
-	virtual void handleUserTransformation(const QRectF &, const QRectF &);
+		enum { Type = UserType + 1101 };
+			/**
+			 * Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a PartArc.
+			 * @return the QGraphicsItem type
+			 */
+		virtual int type() const { return Type; }
+		virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
 
-	///PROPERT
-	// X value
-	Q_PROPERTY(qreal x READ x WRITE setX)
-		qreal x() const {return mapToScene(rect().center()).x() ;}
-		void setX(const qreal x);
-	//Y value
-	Q_PROPERTY(qreal y READ y WRITE setY)
-		qreal y() const {return mapToScene(rect().center()).y();}
-		void setY(const qreal y);
-	// horizontal diameter
-	Q_PROPERTY(qreal diameter_h READ width WRITE setWidth)
-		qreal width() const {return rect().width();}
-		void setWidth(const qreal w);
-	// vertical diameter
-	Q_PROPERTY(qreal diameter_v READ height WRITE setHeight)
-		qreal height() const {return rect().height();}
-		void setHeight (const qreal h);
-	// start angle
-	Q_PROPERTY(int start_angle READ startAngle WRITE setStartAngle)
-		int startAngle() const {return start_angle;}
-		void setStartAngle(const int sa){start_angle = sa;}
-	// angle value
-	Q_PROPERTY(int angle READ angle WRITE setAngle)
-		int angle() const {return _angle;}
-		void setAngle(const int a) {_angle = a;}
+			//Name and XML
+		virtual QString name()    const { return(QObject::tr("arc", "element part name")); }
+		virtual QString xmlName() const { return(QString("arc")); }
+		virtual const QDomElement toXml   (QDomDocument &) const;
+		virtual void              fromXml (const QDomElement &);
 
-	
-	protected:
-	QVariant itemChange(GraphicsItemChange, const QVariant &);
-	
-	private:
-	QList<QPointF> saved_points_;
+		virtual QPainterPath shape() const;
 };
 #endif

Modified: trunk/sources/editor/graphicspart/partellipse.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partellipse.cpp	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partellipse.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -18,188 +18,113 @@
 #include "partellipse.h"
 
 /**
-	Constructeur
-	@param editor L'editeur d'element concerne
-	@param parent Le QGraphicsItem parent de cette ellipse
-	@param scene La scene sur laquelle figure cette ellipse
-*/
-PartEllipse::PartEllipse(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) : CustomElementGraphicPart(editor), QGraphicsEllipseItem(parent, scene) {
-	setFlags(QGraphicsItem::ItemIsSelectable);
-#if QT_VERSION >= 0x040600
-	setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
-#endif
-	setAcceptedMouseButtons(Qt::LeftButton);
-}
+ * @brief PartEllipse::PartEllipse
+ * Constructor
+ * @param editor : QETElementEditor of this part
+ * @param parent : parent item
+ */
+PartEllipse::PartEllipse(QETElementEditor *editor, QGraphicsItem *parent) :
+	AbstractPartEllipse(editor, parent)
+{}
 
-/// Destructeur
-PartEllipse::~PartEllipse() {
-}
+/**
+ * @brief PartEllipse::~PartEllipse
+ * Destructor
+ */
+PartEllipse::~PartEllipse() {}
 
 /**
-	Dessine l'ellipse
-	@param painter QPainter a utiliser pour rendre le dessin
-	@param options Options pour affiner le rendu
-	@param widget Widget sur lequel le rendu est effectue
-*/
-void PartEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
+ * @brief PartEllipse::paint
+ * Draw this ellpise
+ * @param painter
+ * @param options
+ * @param widget
+ */
+void PartEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget)
+{
 	Q_UNUSED(widget);
 	applyStylesToQPainter(*painter);
+
 	QPen t = painter -> pen();
 	t.setCosmetic(options && options -> levelOfDetail < 1.0);
-	if (isSelected()) {
+
+	if (isSelected())
 		t.setColor(Qt::red);
-	}
+
 	painter -> setPen(t);
 	painter -> drawEllipse(rect());
-	if (isSelected()) {
-		painter -> setRenderHint(QPainter::Antialiasing, false);
-		painter -> setPen((painter -> brush().color() == QColor(Qt::black) && painter -> brush().isOpaque()) ? Qt::yellow : Qt::blue);
-		QPointF center = rect().center();
-		painter -> drawLine(QLineF(center.x() - 2.0, center.y(), center.x() + 2.0, center.y()));
-		painter -> drawLine(QLineF(center.x(), center.y() - 2.0, center.x(), center.y() + 2.0));
-	}
+
+	if (m_hovered)
+		drawShadowShape(painter);
+
+	if (isSelected())
+		drawCross(m_rect.center(), painter);
 }
 
 /**
-	Exporte l'ellipse en XML
-	@param xml_document Document XML a utiliser pour creer l'element XML
-	@return un element XML decrivant l'ellipse
-*/
-const QDomElement PartEllipse::toXml(QDomDocument &xml_document) const {
+ * @brief PartEllipse::toXml
+ * Export this ellipse in xml
+ * @param xml_document : Xml document to use for create the xml element.
+ * @return : an xml element that describe this ellipse
+ */
+const QDomElement PartEllipse::toXml(QDomDocument &xml_document) const
+{
 	QDomElement xml_element;
-	if (qFuzzyCompare(rect().width(), rect().height())) {
+	if (qFuzzyCompare(rect().width(), rect().height()))
+	{
 		xml_element = xml_document.createElement("circle");
 		xml_element.setAttribute("diameter", QString("%1").arg(rect().width()));
-	} else {
+	}
+	else
+	{
 		xml_element = xml_document.createElement("ellipse");
 		xml_element.setAttribute("width",  QString("%1").arg(rect().width()));
 		xml_element.setAttribute("height", QString("%1").arg(rect().height()));
 	}
+
 	QPointF top_left(sceneTopLeft());
 	xml_element.setAttribute("x", QString("%1").arg(top_left.x()));
 	xml_element.setAttribute("y", QString("%1").arg(top_left.y()));
+
 	stylesToXml(xml_element);
+
 	return(xml_element);
 }
 
 /**
-	Importe les proprietes d'une ellipse depuis un element XML
-	@param qde Element XML a lire
-*/
-void PartEllipse::fromXml(const QDomElement &qde) {
+ * @brief PartEllipse::fromXml
+ * Import the properties of this ellipse from a xml element.
+ * @param qde : Xml document to use.
+ */
+void PartEllipse::fromXml(const QDomElement &qde)
+{
 	stylesFromXml(qde);
 	qreal width, height;
-	if (qde.tagName() == "ellipse") {
+
+	if (qde.tagName() == "ellipse")
+	{
 		width = qde.attribute("width",  "0").toDouble();
 		height = qde.attribute("height", "0").toDouble();
-	} else {
-		width = height = qde.attribute("diameter", "0").toDouble();
 	}
-	setRect(
-		QRectF(
-			mapFromScene(
-				qde.attribute("x", "0").toDouble(),
-				qde.attribute("y", "0").toDouble()
-			),
-			QSizeF(width, height)
-		)
-	);
-}
+	else
+		width = height = qde.attribute("diameter", "0").toDouble();
 
-void PartEllipse::setX(const qreal x) {
-	QRectF current_rect = rect();
-	QPointF current_pos = mapToScene(current_rect.center());
-	setRect(current_rect.translated(x - current_pos.x(), 0.0));
+	m_rect = QRectF(mapFromScene(qde.attribute("x", "0").toDouble(),
+								 qde.attribute("y", "0").toDouble()),
+					QSizeF(width, height));
 }
 
-void PartEllipse::setY(const qreal y) {
-	QRectF current_rect = rect();
-	QPointF current_pos = mapToScene(current_rect.center());
-	setRect(current_rect.translated(0.0, y - current_pos.y()));
-}
-
-void PartEllipse::setWidth(const qreal w) {
-	qreal new_width = qAbs(w);
-	QRectF current_rect = rect();
-	current_rect.translate((new_width - current_rect.width()) / -2.0, 0.0);
-	current_rect.setWidth(new_width);
-	setRect(current_rect);
-}
-
-void PartEllipse::setHeight(const qreal h) {
-	qreal new_height = qAbs(h);
-	QRectF current_rect = rect();
-	current_rect.translate(0.0, (new_height - current_rect.height()) / -2.0);
-	current_rect.setHeight(new_height);
-	setRect(current_rect);
-}
-
 /**
-	Gere les changements intervenant sur cette partie
-	@param change Type de changement
-	@param value Valeur numerique relative au changement
-*/
-QVariant PartEllipse::itemChange(GraphicsItemChange change, const QVariant &value) {
-	if (scene()) {
-		if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged) {
-			updateCurrentPartEditor();
-		}
-	}
-	return(QGraphicsEllipseItem::itemChange(change, value));
-}
+ * @brief PartEllipse::shape
+ * @return the shape of this item
+ */
+QPainterPath PartEllipse::shape() const
+{
+	QPainterPath shape;
+	shape.addEllipse(m_rect);
 
-/**
-	@return le coin superieur gauche du rectangle dans lequel s'inscrit
-	l'ellipse, dans les coordonnees de la scene.
-*/
-QPointF PartEllipse::sceneTopLeft() const {
-	return(mapToScene(rect().topLeft()));
-}
+	QPainterPathStroker pps;
+	pps.setWidth(penWeight());
 
-/**
-	@return true si cette partie n'est pas pertinente et ne merite pas d'etre
-	conservee / enregistree.
-	Une ellipse est pertinente des lors que ses dimensions ne sont pas nulles
-*/
-bool PartEllipse::isUseless() const {
-	return(rect().isNull());
+	return (pps.createStroke(shape));
 }
-
-/**
-	@return the minimum, margin-less rectangle this part can fit into, in scene
-	coordinates. It is different from boundingRect() because it is not supposed
-	to imply any margin, and it is different from shape because it is a regular
-	rectangle, not a complex shape.
-*/
-QRectF PartEllipse::sceneGeometricRect() const {
-	return(mapToScene(rect()).boundingRect());
-}
-
-/**
-	Start the user-induced transformation, provided this primitive is contained
-	within the \a initial_selection_rect bounding rectangle.
-*/
-void PartEllipse::startUserTransformation(const QRectF &initial_selection_rect) {
-	Q_UNUSED(initial_selection_rect)
-	// we keep track of our own rectangle at the moment in scene coordinates too
-	saved_points_.clear();
-	saved_points_ << mapToScene(rect().topLeft()) << mapToScene(rect().bottomRight());
-}
-
-/**
-	Handle the user-induced transformation from \a initial_selection_rect to \a new_selection_rect
-*/
-void PartEllipse::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect) {
-	QList<QPointF> mapped_points = mapPoints(initial_selection_rect, new_selection_rect, saved_points_);
-	setRect(QRectF(mapFromScene(mapped_points.at(0)), mapFromScene(mapped_points.at(1))));
-}
-
-/**
-	@return le rectangle delimitant cette partie.
-*/
-QRectF PartEllipse::boundingRect() const {
-	qreal adjust = 1.5;
-	QRectF r(QGraphicsEllipseItem::boundingRect().normalized());
-	r.adjust(-adjust, -adjust, adjust, adjust);
-	return(r);
-}

Modified: trunk/sources/editor/graphicspart/partellipse.h
===================================================================
--- trunk/sources/editor/graphicspart/partellipse.h	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partellipse.h	2015-02-09 08:57:40 UTC (rev 3694)
@@ -17,65 +17,42 @@
 */
 #ifndef PART_ELLIPSE_H
 #define PART_ELLIPSE_H
-#include <QtGui>
-#include "customelementgraphicpart.h"
+
+#include "abstractpartellipse.h"
+
 /**
-	This class represents an ellipse primitive which may be used to compose the
-	drawing of an electrical element within the element editor.
-*/
-class PartEllipse : public CustomElementGraphicPart, public QGraphicsEllipseItem {
-	Q_OBJECT
-	// constructors, destructor
+ * @brief The PartEllipse class
+ * This class represents an ellipse primitive which may be used to compose the
+ * drawing of an electrical element within the element editor.
+ */
+class PartEllipse : public  AbstractPartEllipse
+{
+		Q_OBJECT
+
+		// constructors, destructor
 	public:
-	PartEllipse(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
-	virtual ~PartEllipse();
+		PartEllipse(QETElementEditor *editor, QGraphicsItem * parent = 0);
+		virtual ~PartEllipse();
 	
 	private:
-	PartEllipse(const PartEllipse &);
+		PartEllipse(const PartEllipse &);
 	
-	// methods
+		// methods
 	public:
-	enum { Type = UserType + 1103 };
-	/**
-		Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
-		PartEllipse.
-		@return the QGraphicsItem type
-	*/
-	virtual int type() const { return Type; }
-	virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
-	virtual QString name() const { return(QObject::tr("ellipse", "element part name")); }
-	virtual QString xmlName() const { return(QString("ellipse")); }
-	virtual const QDomElement toXml(QDomDocument &) const;
-	virtual void fromXml(const QDomElement &);
-	virtual QPointF sceneTopLeft() const;
-	virtual QRectF boundingRect() const;
-	virtual bool isUseless() const;
-	virtual QRectF sceneGeometricRect() const;
-	virtual void startUserTransformation(const QRectF &);
-	virtual void handleUserTransformation(const QRectF &, const QRectF &);
+		enum { Type = UserType + 1103 };
+			/**
+			 * Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a PartEllipse.
+			 * @return the QGraphicsItem type
+			 */
+		virtual int type() const { return Type; }	
+		virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
 
-	///PROPERTY
-	// X value
-	Q_PROPERTY(qreal x READ x WRITE setX)
-		qreal x() const {return mapToScene(rect().center()).x() ;}
-		void setX(const qreal x);
-	// Y value
-	Q_PROPERTY(qreal y READ y WRITE setY)
-		qreal y() const {return mapToScene(rect().center()).y();}
-		void setY(const qreal y);
-	// horizontal diameter
-	Q_PROPERTY(qreal diameter_h READ width WRITE setWidth)
-		qreal width() const {return rect().width();}
-		void setWidth(const qreal w);
-	// vertical diameter
-	Q_PROPERTY(qreal diameter_v READ height WRITE setHeight)
-		qreal height() const {return rect().height();}
-		void setHeight (const qreal h);
-	
-	protected:
-	QVariant itemChange(GraphicsItemChange, const QVariant &);
-	
-	private:
-	QList<QPointF> saved_points_;
+			//Name and XML
+		virtual QString name()    const { return(QObject::tr("ellipse", "element part name")); }
+		virtual QString xmlName() const { return(QString("ellipse")); }
+		virtual const QDomElement toXml   (QDomDocument &) const;
+		virtual void              fromXml (const QDomElement &);
+
+		virtual QPainterPath shape() const;
 };
 #endif

Modified: trunk/sources/editor/graphicspart/partline.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partline.cpp	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partline.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -18,148 +18,80 @@
 #include "partline.h"
 #include <cmath>
 
+
 /**
-	Constructeur
-	@param editor L'editeur d'element concerne
-	@param parent Le QGraphicsItem parent de cette ligne
-	@param scene La scene sur laquelle figure cette ligne
-*/
-PartLine::PartLine(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) :
-	CustomElementGraphicPart(editor),
-	QGraphicsLineItem(parent, scene),
+ * @brief PartLine::PartLine
+ * Constructor
+ * @param editor : QETElementEditor of this part
+ * @param parent : parent item
+ */
+PartLine::PartLine(QETElementEditor *editor, QGraphicsItem *parent) :
+	CustomElementGraphicPart(editor, parent),
 	first_end(Qet::None),
 	first_length(1.5),
 	second_end(Qet::None),
 	second_length(1.5)
-{
-	setFlags(QGraphicsItem::ItemIsSelectable);
-#if QT_VERSION >= 0x040600
-	setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
-#endif
-	setAcceptedMouseButtons(Qt::LeftButton);
-}
+{}
 
 /// Destructeur
-PartLine::~PartLine() {
-}
+PartLine::~PartLine() {}
 
 /**
-	@param end_type Type d'extremite
-	@return Le nombre de "longueurs" requises pour dessiner une extremite de type end_type
-*/
-uint PartLine::requiredLengthForEndType(const Qet::EndType &end_type) {
+ * @brief PartLine::requiredLengthForEndType
+ * @param end_type
+ * @return the number of "length" needed to draw a extremity of type Qet::EndType.
+ */
+uint PartLine::requiredLengthForEndType(const Qet::EndType &end_type)
+{
 	uint length_count_required = 0;
-	if (end_type == Qet::Circle || end_type == Qet::Diamond) {
+
+	if (end_type == Qet::Circle || end_type == Qet::Diamond)
 		length_count_required = 2;
-	} else if (end_type == Qet::Simple || end_type == Qet::Triangle) {
+	else if (end_type == Qet::Simple || end_type == Qet::Triangle)
 		length_count_required = 1;
-	}
+
 	return(length_count_required);
 }
 
 /**
-	Dessine la ligne
-	@param painter QPainter a utiliser pour rendre le dessin
-	@param options Options pour affiner le rendu
-	@param widget Widget sur lequel le rendu est effectue
-*/
-void PartLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
+ * @brief PartLine::paint
+ * Draw this line
+ * @param painter
+ * @param options
+ * @param widget
+ */
+void PartLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget)
+{
 	Q_UNUSED(widget);
-	// inutile de dessiner une ligne nulle
-	if (line().p1() == line().p2()) return;
+	if (isUseless()) return;
+
 	applyStylesToQPainter(*painter);
 	QPen t = painter -> pen();
 	t.setJoinStyle(Qt::MiterJoin);
 	t.setCosmetic(options && options -> levelOfDetail < 1.0);
-	if (isSelected()) {
+
+	if (isSelected())
 		t.setColor(Qt::red);
-	}
+
 	painter -> setPen(t);
 	
-	QPointF point1(line().p1());
-	QPointF point2(line().p2());
-	
-	qreal line_length(line().length());
-	qreal pen_width = painter -> pen().widthF();
-	
-	qreal length1 = first_length;
-	qreal length2 = second_length;
-	
-	//debugPaint(painter);
-	
-	// determine s'il faut dessiner les extremites
-	bool draw_1st_end, draw_2nd_end;
-	qreal reduced_line_length = line_length - (length1 * requiredLengthForEndType(first_end));
-	draw_1st_end = first_end && reduced_line_length >= 0;
-	if (draw_1st_end) {
-		reduced_line_length -= (length2 * requiredLengthForEndType(second_end));
-	} else {
-		reduced_line_length = line_length - (length2 * 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(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];
-		}
-		
-		// 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(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];
-		}
-		
-		// 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;
-	}
-	
-	painter -> drawLine(start_point, stop_point);
+	if (first_end || second_end)
+		painter -> drawPath(path());
+	else
+		painter -> drawLine(m_line);
+
+	if (m_hovered)
+		drawShadowShape(painter);
 }
 
 /**
-	Exporte la ligne en XML
-	@param xml_document Document XML a utiliser pour creer l'element XML
-	@return un element XML decrivant la ligne
-*/
-const QDomElement PartLine::toXml(QDomDocument &xml_document) const {
-	
+ * @brief PartLine::toXml
+ * Export this line in xml
+ * @param xml_document : Xml document to use for create the xml element.
+ * @return an xml element that describe this line
+ */
+const QDomElement PartLine::toXml(QDomDocument &xml_document) const
+{
 	QPointF p1(sceneP1());
 	QPointF p2(sceneP2());
 	
@@ -178,186 +110,141 @@
 }
 
 /**
-	Importe les proprietes d'une ligne depuis un element XML
-	@param qde Element XML a lire
-*/
+ * @brief PartLine::fromXml
+ * Import the properties of this line from a xml element.
+ * @param qde : Xml document to use
+ */
 void PartLine::fromXml(const QDomElement &qde) {
 	stylesFromXml(qde);
-	setLine(
-		QLineF(
-			mapFromScene(
-				qde.attribute("x1", "0").toDouble(),
-				qde.attribute("y1", "0").toDouble()
-			),
-			mapFromScene(
-				qde.attribute("x2", "0").toDouble(),
-				qde.attribute("y2", "0").toDouble()
-			)
-		)
-	);
-	first_end    = Qet::endTypeFromString(qde.attribute("end1"));
-	first_length = qde.attribute("length1", "1.5").toDouble();
-	second_end   = Qet::endTypeFromString(qde.attribute("end2"));
+	m_line = QLineF(mapFromScene(qde.attribute("x1", "0").toDouble(),
+								 qde.attribute("y1", "0").toDouble()),
+					mapFromScene(qde.attribute("x2", "0").toDouble(),
+								 qde.attribute("y2", "0").toDouble()));
+
+	first_end     = Qet::endTypeFromString(qde.attribute("end1"));
+	first_length  = qde.attribute("length1", "1.5").toDouble();
+	second_end    = Qet::endTypeFromString(qde.attribute("end2"));
 	second_length = qde.attribute("length2", "1.5").toDouble();
 }
 
 /**
- * @brief PartLine::setX1
- * set X of P1
- * @param x1
+ * @brief PartLine::p1
+ * @return the point p1 of line.
  */
-void PartLine::setX1(qreal x1) {
-	QPointF p = line().p1();
-	p.setX(x1);
-	setLine(QLineF(p, line().p2()));
+QPointF PartLine::p1() const {
+	return m_line.p1();
 }
 
 /**
- * @brief PartLine::setY1
- * set y of P1
- * @param y1
- */
-void PartLine::setY1(qreal y1) {
-	QPointF p = line().p1();
-	p.setY(y1);
-	setLine(QLineF(p, line().p2()));
-}
-
-/**
  * @brief PartLine::setP1
  * set first point to P1
  * @param p1
  */
-void PartLine::setP1(QPointF p1) {
-	setLine(QLineF(p1, line().p2()));
+void PartLine::setP1(const QPointF &p1)
+{
+	if (p1 == m_line.p1()) return;
+	prepareGeometryChange();
+	m_line.setP1(p1);
 }
 
 /**
- * @brief PartLine::setX2
- * set x of P2
- * @param x2
+ * @brief PartLine::p2
+ * @return  the point p2 of line
  */
-void PartLine::setX2(qreal x2) {
-	QPointF p = line().p2();
-	p.setX(x2);
-	setLine(QLineF(line().p1(), p));
+QPointF PartLine::p2() const {
+	return m_line.p2();
 }
 
 /**
- * @brief PartLine::setY2
- * set y of P2
- * @param y2
- */
-void PartLine::setY2(qreal y2) {
-	QPointF p = line().p2();
-	p.setY(y2);
-	setLine(QLineF(line().p1(), p));
-}
-
-/**
  * @brief PartLine::setP2
  * set second point to P2
  * @param p2
  */
-void PartLine::setP2(QPointF p2) {
-	setLine(QLineF(line().p1(), p2));
+void PartLine::setP2(const QPointF &p2)
+{
+	if (p2 == m_line.p2()) return;
+	prepareGeometryChange();
+	m_line.setP2(p2);
 }
 
 /**
-	Gere les changements intervenant sur cette partie
-	@param change Type de changement
-	@param value Valeur numerique relative au changement
-*/
-QVariant PartLine::itemChange(GraphicsItemChange change, const QVariant &value) {
-	if (scene()) {
-		if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged) {
-			updateCurrentPartEditor();
-		}
-	}
-	return(QGraphicsLineItem::itemChange(change, value));
-}
-
-/**
-	@return le premier point, dans les coordonnees de la scene.
-*/
+ * @brief PartLine::sceneP1
+ * @return the point p1 in scene coordinate
+ */
 QPointF PartLine::sceneP1() const {
-	return(mapToScene(line().p1()));
+	return(mapToScene(p1()));
 }
 
 /**
-	@return le second point, dans les coordonnees de la scene.
-*/
+ * @brief PartLine::sceneP2
+ * @return the point p2 in scen coordinate
+ */
 QPointF PartLine::sceneP2() const {
-	return(mapToScene(line().p2()));
+	return(mapToScene(p2()));
 }
 
 /**
-	@return la forme selectionnable de la ligne
-*/
-QPainterPath PartLine::shape() const {
-	QList<QPointF> points = fourShapePoints();
-	QPainterPath t;
-	t.setFillRule(Qt::WindingFill);
-	t.moveTo(points.at(0));
-	t.lineTo(points.at(1));
-	t.lineTo(points.at(2));
-	t.lineTo(points.at(3));
-	t.lineTo(points.at(0));
-	
-	// n'en fait pas plus si la ligne se ramene a un point
-	if (line().p1() == line().p2()) return(t);
-	
-	// ajoute un cercle pour l'extremite 1 si besoin
-	if (first_end) {
-		QPainterPath t2;
-		t2.addEllipse(firstEndCircleRect());
-		t.addPath(t2.subtracted(t));
+ * @brief PartLine::shape
+ * @return the shape of this item
+ */
+QPainterPath PartLine::shape() const
+{
+	QPainterPath shape;
+
+		//We calcul path only if there is an end type
+		//Else we just draw a line
+	if (first_end || second_end)
+		shape.addPath(path());
+	else
+	{
+		shape.moveTo(m_line.p1());
+		shape.lineTo(m_line.p2());
 	}
-	
-	// ajoute un cercle pour l'extremite 2 si besoin
-	if (second_end) {
-		QPainterPath t2;
-		t2.addEllipse(secondEndCircleRect());
-		t.addPath(t2.subtracted(t));
-	}
-	
-	return(t);
+
+	QPainterPathStroker pps;
+	pps.setWidth(penWeight());
+
+	return (pps.createStroke(shape));
 }
 
 /**
-	@return une liste contenant les deux points de la droite + les 4 points entourant ces deux points
-*/
-QList<QPointF> PartLine::fourShapePoints() const {
+ * @brief PartLine::fourShapePoints
+ * @return a list with the two points that delimite the line
+ * + the four points surrounding these two points
+ */
+QList<QPointF> PartLine::fourShapePoints() const
+{
 	const qreal marge = 2.0;
-	// on a donc A(xa , ya) et B(xb, yb)
-	QPointF a = line().p1();
-	QPointF b = line().p2();
+
+	QPointF a = m_line.p1();
+	QPointF b = m_line.p2();
 	
 	QList<QPointF> result;
 	
-	// cas particulier : la droite se ramene a un point
-	if (a == b) {
+		//Special case, the line is defined by one point
+	if (a == b)
+	{
 		result << QPointF(a.x() - marge, a.y() - marge);
 		result << QPointF(a.x() - marge, a.y() + marge);
 		result << QPointF(a.x() + marge, a.y() + marge);
 		result << QPointF(a.x() + marge, a.y() - marge);
-	} else {
-		
-		// on calcule le vecteur AB : (xb-xa, yb-ya)
+	}
+	else
+	{
+			//We calcule the vector AB : (xb-xa, yb-ya)
 		QPointF v_ab = b - a;
 		
-		// et la distance AB : racine des coordonnees du vecteur au carre
+			//And the distance AB: root of the coordinates of the vector squared
 		qreal ab = sqrt(pow(v_ab.x(), 2) + pow(v_ab.y(), 2));
 		
-		// ensuite on definit le vecteur u(a, b) qui est egal au vecteur AB divise
-		// par sa longueur et multiplie par la longueur de la marge  que tu veux
-		// laisser
+			//Next, we define the vector u(a, b) wich is equal to the vector AB divided
+			//by is length and multiplied by the length of marge.
 		QPointF u = v_ab / ab * marge;
 		
-		// on definit le vecteur v(-b , a) qui est perpendiculaire a AB
+			//We define the vector v(-b, a) wich is perpendicular to AB
 		QPointF v(-u.y(), u.x());
-		QPointF m = -u + v; // on a le vecteur M = -u + v
-		QPointF n = -u - v; // et le vecteur N=-u-v
+		QPointF m = -u + v; // we have vector M = -u + v
+		QPointF n = -u - v; // and vector N=-u-v
 		QPointF h =  a + m; // H = A + M
 		QPointF k =  a + n; // K = A + N
 		QPointF i =  b - n; // I = B - N
@@ -369,14 +256,14 @@
 }
 
 /**
-	@return le rectangle encadrant l'integralite de la premiere extremite
-*/
-QRectF PartLine::firstEndCircleRect() const {
-	QList<QPointF> interesting_points = fourEndPoints(
-		line().p1(),
-		line().p2(),
-		first_length
-	);
+ * @brief PartLine::firstEndCircleRect
+ * @return the rectangle bordering the entirety of the first extremity
+ */
+QRectF PartLine::firstEndCircleRect() const
+{
+	QList<QPointF> interesting_points = fourEndPoints(m_line.p1(),
+													  m_line.p2(),
+													  first_length);
 	
 	QRectF end_rect(
 		interesting_points[0] - QPointF(first_length, first_length),
@@ -387,14 +274,13 @@
 }
 
 /**
-	@return le rectangle encadrant l'integralite de la seconde extremite
-*/
+ * @brief PartLine::secondEndCircleRect
+ * @return the rectangle bordering the entirety of the second extremity
+ */
 QRectF PartLine::secondEndCircleRect() const {
-	QList<QPointF> interesting_points = fourEndPoints(
-		line().p2(),
-		line().p1(),
-		second_length
-	);
+	QList<QPointF> interesting_points = fourEndPoints(m_line.p2(),
+													  m_line.p1(),
+													  second_length);
 	
 	QRectF end_rect(
 		interesting_points[0] - QPointF(second_length, second_length),
@@ -405,13 +291,15 @@
 }
 
 /**
-	Affiche differentes composantes du dessin :
-	  - le boundingRect
-	  - les point speciaux a chaque extremite
-	  - la quadrature du cercle a chaque extremite, meme si celle-ci est d'un
-	  autre type
-*/
-void PartLine::debugPaint(QPainter *painter) {
+ * @brief PartLine::debugPaint
+ * Display several composante of the drawing
+ * -the bounding rect
+ * -special points at each extremity
+ * -the quadrature of the circle at each extremity, even if itself is an other type
+ * @param painter
+ */
+void PartLine::debugPaint(QPainter *painter)
+{
 	painter -> save();
 	painter -> setPen(Qt::gray);
 	painter -> drawRect(boundingRect());
@@ -421,99 +309,109 @@
 	painter -> drawRect(secondEndCircleRect());
 	
 	painter -> setPen(Qt::red);
-	foreach(QPointF pointy, fourEndPoints(line().p1(), line().p2(), first_length)) {
+
+	foreach(QPointF pointy, fourEndPoints(p1(), p2(), first_length))
 		painter -> drawEllipse(pointy, 0.1, 0.1);
-	}
-	foreach(QPointF pointy, fourEndPoints(line().p2(), line().p1(), second_length)) {
+
+	foreach(QPointF pointy, fourEndPoints(p2(), p1(), second_length))
 		painter -> drawEllipse(pointy, 0.1, 0.1);
-	}
 	
 	painter -> restore();
 }
 
 /**
-	@return le rectangle delimitant cette partie.
-*/
-QRectF PartLine::boundingRect() const {
-	QRectF r(QGraphicsLineItem::boundingRect());
-	
-	// le rectangle ainsi obtenu ne doit pas avoir une dimension nulle
-	r.adjust(0.0, 0.0, 0.1, 0.1);
-	
-	// cas special : les embouts sortent largement du bounding rect originel
-	if (first_end != Qet::None) {
-		r = r.united(firstEndCircleRect());
-	}
-	
-	if (second_end != Qet::None) {
-		r = r.united(secondEndCircleRect());
-	}
-	
-	// la taille du bounding rect est ajustee avec une certaine marge
-	qreal adjust = 1.2;
-	r.adjust(-adjust, -adjust, adjust, adjust);
-	return(r);
+ * @brief PartLine::boundingRect
+ * @return the bounding rect of this part
+ */
+QRectF PartLine::boundingRect() const
+{	
+	QRectF bound;
+	if (first_end || second_end)
+		bound = path().boundingRect();
+	else
+		bound = QRectF (m_line.p1(), m_line.p2());
+
+	qreal adjust = (SHADOWS_HEIGHT + penWeight()) / 2;
+		//We add 0.5 because CustomElementGraphicPart::drawShadowShape
+		//draw a shape bigger of 0.5 when pen weight is to 0.
+	if (penWeight() == 0) adjust += 0.5;
+
+	bound = bound.normalized();
+	bound.adjust(-adjust, -adjust, adjust, adjust);
+	return bound;
 }
 
 /**
-	@return true si cette partie n'est pas pertinente et ne merite pas d'etre
-	conservee / enregistree.
-	Une ligne est pertinente des lors que ses deux points sont differents
-*/
+ * @brief PartLine::isUseless
+ * @return true if this part is irrelevant and does not deserve to be Retained / registered.
+ * A line is relevant when is two point is different
+ */
 bool PartLine::isUseless() const {
-	return(sceneP1() == sceneP2());
+	return(m_line.p1() == m_line.p2());
 }
 
 /**
-	@return the minimum, margin-less rectangle this part can fit into, in scene
-	coordinates. It is different from boundingRect() because it is not supposed
-	to imply any margin, and it is different from shape because it is a regular
-	rectangle, not a complex shape.
-*/
+ * @brief PartLine::sceneGeometricRect
+ * @return the minimum, margin-less rectangle this part can fit into, in scene
+ * coordinates. It is different from boundingRect() because it is not supposed
+ * to imply any margin, and it is different from shape because it is a regular
+ * rectangle, not a complex shape.
+ */
 QRectF PartLine::sceneGeometricRect() const {
 	return(QRectF(sceneP1(), sceneP2()));
 }
 
 /**
-	Start the user-induced transformation, provided this primitive is contained
-	within the \a initial_selection_rect bounding rectangle.
-*/
-void PartLine::startUserTransformation(const QRectF &initial_selection_rect) {
+ * @brief PartLine::startUserTransformation
+ * Start the user-induced transformation, provided this primitive is contained
+ * within the \a initial_selection_rect bounding rectangle.
+ * @param initial_selection_rect
+ */
+void PartLine::startUserTransformation(const QRectF &initial_selection_rect)
+{
 	Q_UNUSED(initial_selection_rect)
 	saved_points_.clear();
 	saved_points_ << sceneP1() << sceneP2();
 }
 
 /**
-	Handle the user-induced transformation from \a initial_selection_rect to \a new_selection_rect
-*/
-void PartLine::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect) {
+ * @brief PartLine::handleUserTransformation
+ * Handle the user-induced transformation from \a initial_selection_rect to \a new_selection_rect
+ * @param initial_selection_rect
+ * @param new_selection_rect
+ */
+void PartLine::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect)
+{
 	QList<QPointF> mapped_points = mapPoints(initial_selection_rect, new_selection_rect, saved_points_);
-	setLine(QLineF(mapFromScene(mapped_points.at(0)), mapFromScene(mapped_points.at(1))));
+	prepareGeometryChange();
+	m_line = QLineF(mapFromScene(mapped_points.at(0)), mapFromScene(mapped_points.at(1)));
 }
 
 /**
-	@return Les quatre points interessants a l'extremite d'une droite
-	Ces points sont, dans l'ordre :
-		* O : point sur la ligne, a une distance length de l'extremite
-		* A : point sur la ligne a une distance 2 x length de l'extremite
-		* B : point a une distance length de O - O est le projete de B sur la droite
-		* C : point a une distance length de O - O est le projete de C sur la droite
-		B et C sont situes de part et d'autre de la ligne
-	@param end_point Extremite concernee
-	@param other_point Autre point permettant de definir une ligne
-	@param length Longueur a utiliser entre l'extremite et le point O
-*/
-QList<QPointF> PartLine::fourEndPoints(const QPointF &end_point, const QPointF &other_point, const qreal &length) {
-	// vecteur et longueur de la ligne 
+ * @brief PartLine::fourEndPoints
+ * Return the four interesting point needed to draw the shape
+ * at extremity of line (circle, diamond, arrow, triangle)
+ * This points are in order :
+ *		O : point on the line, at a distance 'length' of the extremity
+ *		A : point on the line at a 'length' of 2x the extremity length
+ *		B : point at a distance of length O - O is the projection of B on the line
+ *		C : point at a distance of length O - O is the projection of C on the line
+ * @param end_point : The concerned extremity
+ * @param other_point : other needed point to define the line
+ * @param length : length to use between the extremity and the point O
+ * @return
+ */
+QList<QPointF> PartLine::fourEndPoints(const QPointF &end_point, const QPointF &other_point, const qreal &length)
+{
+		//Vector and length of the line
 	QPointF line_vector = end_point - other_point;
 	qreal line_length = sqrt(pow(line_vector.x(), 2) + pow(line_vector.y(), 2));
-	
-	// vecteur unitaire et vecteur perpendiculaire
+
+		//Unitary vector and perpendicular vector
 	QPointF u(line_vector / line_length * length);
 	QPointF v(-u.y(), u.x());
 	
-	// points O, A, B et C
+		// points O, A, B, C
 	QPointF o(end_point - u);
 	QPointF a(o - u);
 	QPointF b(o + v);
@@ -521,3 +419,119 @@
 	
 	return(QList<QPointF>() << o << a << b << c);
 }
+
+/**
+ * @brief PartLine::path
+ * @return this line has a QPainterPath.
+ * It's notably use when this line have an end type (circle, triangle etc....),
+ * because return a QPainterPath with end already draw.
+ * Else if there isn't an end type get P1 and P2 of line is better (faster).
+ */
+QPainterPath PartLine::path() const
+{
+	QPainterPath path;
+
+	QPointF point1(m_line.p1());
+	QPointF point2(m_line.p2());
+
+	qreal line_length(m_line.length());
+	qreal pen_width = penWeight();
+
+	qreal length1 = first_length;
+	qreal length2 = second_length;
+
+	//debugPaint(painter);
+
+		//Determine if we must to draw extremity
+	qreal reduced_line_length = line_length - (length1 * requiredLengthForEndType(first_end));
+	bool draw_1st_end = first_end && reduced_line_length >= 0;
+
+	if (draw_1st_end)
+		reduced_line_length -= (length2 * requiredLengthForEndType(second_end));
+	else
+		reduced_line_length = line_length - (length2 * requiredLengthForEndType(second_end));
+
+
+		//Draw the first extremity
+	QPointF start_point;
+	if (draw_1st_end)
+	{
+		QList<QPointF> four_points1(fourEndPoints(point1, point2, length1));
+
+		if (first_end == Qet::Circle)
+		{
+			path.addEllipse(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)
+		{
+			path.addPolygon(QPolygonF() << four_points1[1] << four_points1[2] << point1 << four_points1[3] << four_points1[1]);
+			start_point = four_points1[1];
+		}
+		else if (first_end == Qet::Simple)
+		{
+			path.addPolygon(QPolygonF() << four_points1[3] << point1 << four_points1[2]);
+			start_point = point1;
+
+		}
+		else if (first_end == Qet::Triangle)
+		{
+			path.addPolygon(QPolygonF() << four_points1[0] << four_points1[2] << point1 << four_points1[3] << four_points1[0]);
+			start_point = four_points1[0];
+		}
+
+			//Adjust the start point according to the pen width
+		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 the second extremity
+	QPointF stop_point;
+	bool draw_2nd_end = second_end && reduced_line_length >= 0;
+	if (draw_2nd_end)
+	{
+		QList<QPointF> four_points2(fourEndPoints(point2, point1, length2));
+
+		if (second_end == Qet::Circle)
+		{
+			path.addEllipse(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)
+		{
+			path.addPolygon(QPolygonF() << four_points2[2] << point2 << four_points2[3] << four_points2[1] << four_points2[2]);
+			stop_point = four_points2[1];
+		}
+		else if (second_end == Qet::Simple)
+		{
+			path.addPolygon(QPolygonF() << four_points2[3] << point2 << four_points2[2]);
+			stop_point = point2;
+		}
+		else if (second_end == Qet::Triangle)
+		{/**
+	@return true si cette partie n'est pas pertinente et ne merite pas d'etre
+	conservee / enregistree.
+	Une ligne est pertinente des lors que ses deux points sont differents
+*/
+			path.addPolygon(QPolygonF() << four_points2[0] << four_points2[2] << point2 << four_points2[3] << four_points2[0]);
+			stop_point = four_points2[0];
+		}
+
+			//Adjust the end point accordint to the pen width
+		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;
+	}
+
+	path.moveTo(start_point);
+	path.lineTo(stop_point);
+
+	return path;
+}

Modified: trunk/sources/editor/graphicspart/partline.h
===================================================================
--- trunk/sources/editor/graphicspart/partline.h	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partline.h	2015-02-09 08:57:40 UTC (rev 3694)
@@ -17,7 +17,7 @@
 */
 #ifndef PART_LINE_H
 #define PART_LINE_H
-#include <QtGui>
+
 #include "customelementgraphicpart.h"
 #include "qet.h"
 /**
@@ -29,11 +29,20 @@
 	drawn if the required length for their drawing is longer than the line itself.
 	In case there is room for a single end only, the first one get priority.
 */
-class PartLine : public CustomElementGraphicPart, public QGraphicsLineItem  {
-	Q_OBJECT
+class PartLine : public CustomElementGraphicPart
+{
+		Q_OBJECT
+
+		Q_PROPERTY(QPointF p1 READ p1 WRITE setP1)
+		Q_PROPERTY(QPointF p2 READ p2 WRITE setP2)
+		Q_PROPERTY(Qet::EndType end1 READ firstEndType WRITE setFirstEndType)
+		Q_PROPERTY(Qet::EndType end2 READ secondEndType WRITE setSecondEndType)
+		Q_PROPERTY(qreal length1 READ firstEndLength WRITE setFirstEndLength)
+		Q_PROPERTY(qreal length2 READ secondEndLength WRITE setSecondEndLength)
+
 	// constructors, destructor
 	public:
-	PartLine(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
+	PartLine(QETElementEditor *, QGraphicsItem * = 0);
 	virtual ~PartLine();
 	
 	private:
@@ -41,95 +50,60 @@
 	
 	// attributes
 	private:
-	Qet::EndType first_end;
-	qreal first_length;
-	Qet::EndType second_end;
-	qreal second_length;
-	QList<QPointF> saved_points_;
+
 	
 	// methods
 	public:
-	enum { Type = UserType + 1104 };
+		enum { Type = UserType + 1104 };
 	
-	/**
-		Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
-		PartLine.
-		@return the QGraphicsItem type
-	*/
-	virtual int type() const { return Type; }
-	virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
-	virtual QString name() const { return(QObject::tr("ligne", "element part name")); }
-	virtual QString xmlName() const { return(QString("line")); }
-	virtual const QDomElement toXml(QDomDocument &) const;
-	virtual void fromXml(const QDomElement &);
-	virtual QPointF sceneP1() const;
-	virtual QPointF sceneP2() const;
-	virtual QPainterPath shape() const;
-	virtual QRectF boundingRect() const;
-	virtual bool isUseless() const;
-	virtual QRectF sceneGeometricRect() const;
-	virtual void startUserTransformation(const QRectF &);
-	virtual void handleUserTransformation(const QRectF &, const QRectF &);
-	static uint requiredLengthForEndType(const Qet::EndType &);
-	static QList<QPointF> fourEndPoints(const QPointF &, const QPointF &, const qreal &);
+		 /**
+		  * Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a PartLine.
+		  * @return the QGraphicsItem type
+		  */
+		virtual int type() const { return Type; }
+		virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
+		virtual QString name() const { return(QObject::tr("ligne", "element part name")); }
+		virtual QString xmlName() const { return(QString("line")); }
+		virtual const QDomElement toXml(QDomDocument &) const;
+		virtual void fromXml(const QDomElement &);
+		virtual QPointF sceneP1() const;
+		virtual QPointF sceneP2() const;
+		virtual QPainterPath shape() const;
+		virtual QRectF boundingRect() const;
+		virtual bool isUseless() const;
+		virtual QRectF sceneGeometricRect() const;
+		virtual void startUserTransformation(const QRectF &);
+		virtual void handleUserTransformation(const QRectF &, const QRectF &);
+		static uint requiredLengthForEndType(const Qet::EndType &);
+		static QList<QPointF> fourEndPoints(const QPointF &, const QPointF &, const qreal &);
 
-	///PROPERTY
-		// X value of the first point
-	Q_PROPERTY(qreal x1 READ x1 WRITE setX1)
-		qreal x1() const {return sceneP1().x();}
-		void setX1(qreal x1);
-
-		// Y value of the first point
-	Q_PROPERTY(qreal y1 READ y1 WRITE setY1)
-		qreal y1() const {return sceneP1().y();}
-		void setY1(qreal y1);
-
-		//pos of firts point
-	Q_PROPERTY(QPointF p1 READ sceneP1 WRITE setP1)
-		void setP1 (QPointF p1);
-
-		// X value of the second point
-	Q_PROPERTY(qreal x2 READ x2 WRITE setX2)
-		qreal x2() const {return sceneP2().x();}
-		void setX2(qreal x2);
-
-		// Y value of the second point
-	Q_PROPERTY(qreal y2 READ y2 WRITE setY2)
-		qreal y2() const {return sceneP2().y();}
-		void setY2(qreal y2);
-
-		//pos of second point
-	Q_PROPERTY(QPointF p2 READ sceneP2 WRITE setP2)
-		void setP2 (QPointF p2);
-
-		// End type of the first point
-	Q_PROPERTY(Qet::EndType end1 READ firstEndType WRITE setFirstEndType)
+		QPointF p1() const;
+		void setP1 (const QPointF &p1);
+		QPointF p2 () const;
+		void setP2 (const QPointF &p2);
 		Qet::EndType firstEndType() const {return first_end;}
 		void setFirstEndType(const Qet::EndType &et) {first_end = et;}
-
-		// End type of the second point
-	Q_PROPERTY(Qet::EndType end2 READ secondEndType WRITE setSecondEndType)
 		Qet::EndType secondEndType() const {return second_end;}
 		void setSecondEndType(const Qet::EndType &et) {second_end = et;}
-
-		// Size of end type of first point
-	Q_PROPERTY(qreal length1 READ firstEndLength WRITE setFirstEndLength)
 		qreal firstEndLength() const {return first_length;}
-		void setFirstEndLength(const qreal &l) {first_length = qMin(qAbs(l), line().length());}
-
-		// Size of end type of the second point
-	Q_PROPERTY(qreal length2 READ secondEndLength WRITE setSecondEndLength)
+		void setFirstEndLength(const qreal &l) {first_length = qMin(qAbs(l), m_line.length());}
 		qreal secondEndLength() const {return second_length;}
-		void setSecondEndLength(const qreal &l) {second_length = qMin(qAbs(l), line().length());}
-
-
-	protected:
-	QVariant itemChange(GraphicsItemChange, const QVariant &);
+		void setSecondEndLength(const qreal &l) {second_length = qMin(qAbs(l), m_line.length());}
 	
 	private:
-	QList<QPointF> fourShapePoints() const;
-	QRectF firstEndCircleRect() const;
-	QRectF secondEndCircleRect() const;
-	void debugPaint(QPainter *);
+		QPainterPath path() const;
+
+		QList<QPointF> fourShapePoints() const;
+		QRectF firstEndCircleRect() const;
+		QRectF secondEndCircleRect() const;
+		void debugPaint(QPainter *);
+
+		Qet::EndType first_end;
+		qreal        first_length;
+
+		Qet::EndType second_end;
+		qreal        second_length;
+		QList<QPointF> saved_points_;
+		QLineF m_line;
 };
 #endif

Modified: trunk/sources/editor/graphicspart/partpolygon.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partpolygon.cpp	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partpolygon.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -16,66 +16,89 @@
 	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "partpolygon.h"
-#include "qet.h"
 
 /**
-	Constructeur
-	@param editor L'editeur d'element concerne
-	@param parent Le QGraphicsItem parent de ce polygone
-	@param scene La scene sur laquelle figure ce polygone
-*/
-PartPolygon::PartPolygon(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) : 
-	CustomElementGraphicPart(editor),
-	QGraphicsPolygonItem(parent, scene),
+ * @brief PartPolygon::PartPolygon
+ * Constructor
+ * @param editor : editor of this item
+ * @param parent : parent item
+ */
+PartPolygon::PartPolygon(QETElementEditor *editor, QGraphicsItem *parent) :
+	CustomElementGraphicPart(editor, parent),
 	m_closed(false)
+{}
+
+/**
+ * @brief PartPolygon::~PartPolygon
+ */
+PartPolygon::~PartPolygon() {}
+
+/**
+ * @brief PartPolygon::paint
+ * Draw this polygon
+ * @param painter
+ * @param options
+ * @param widget
+ */
+void PartPolygon::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget)
 {
-	setFlags(QGraphicsItem::ItemIsSelectable);
-#if QT_VERSION >= 0x040600
-	setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
-#endif
-	setAcceptedMouseButtons(Qt::LeftButton);
-}
+	Q_UNUSED(widget);
 
-/// Destructeur
-PartPolygon::~PartPolygon() {
+	applyStylesToQPainter(*painter);
+
+	QPen t = painter -> pen();
+	t.setCosmetic(options && options -> levelOfDetail < 1.0);
+	if (isSelected()) t.setColor(Qt::red);
+	painter -> setPen(t);
+
+	m_closed ? painter -> drawPolygon (m_polygon) :
+			   painter -> drawPolyline(m_polygon);
+
+	if (m_hovered)
+		drawShadowShape(painter);
 }
 
 /**
-	Importe les proprietes d'un polygone depuis un element XML
-	@param qde Element XML a lire
-*/
-void PartPolygon::fromXml(const QDomElement &qde) {
+ * @brief PartPolygon::fromXml
+ * Import the properties of this polygon from a xml element
+ * @param qde : Xml document to use
+ */
+void PartPolygon::fromXml(const QDomElement &qde)
+{
 	stylesFromXml(qde);
+
 	int i = 1;
-	while(true) {
-		if (
-			QET::attributeIsAReal(qde, QString("x%1").arg(i)) &&\
-			QET::attributeIsAReal(qde, QString("y%1").arg(i))
-		) ++ i;
+	while(true)
+	{
+		if (QET::attributeIsAReal(qde, QString("x%1").arg(i)) &&\
+			QET::attributeIsAReal(qde, QString("y%1").arg(i)))
+			++ i;
+
 		else break;
 	}
 	
 	QPolygonF temp_polygon;
-	for (int j = 1 ; j < i ; ++ j) {
-		temp_polygon << QPointF(
-			qde.attribute(QString("x%1").arg(j)).toDouble(),
-			qde.attribute(QString("y%1").arg(j)).toDouble()
-		);
+	for (int j = 1 ; j < i ; ++ j)
+	{
+		temp_polygon << QPointF(qde.attribute(QString("x%1").arg(j)).toDouble(),
+								qde.attribute(QString("y%1").arg(j)).toDouble());
 	}
-	setPolygon(temp_polygon);
+	m_polygon = temp_polygon;
 	
 	m_closed = qde.attribute("closed") != "false";
 }
 
 /**
-	Exporte le polygone en XML
-	@param xml_document Document XML a utiliser pour creer l'element XML
-	@return un element XML decrivant le polygone
-*/
-const QDomElement PartPolygon::toXml(QDomDocument &xml_document) const {
+ * @brief PartPolygon::toXml
+ * Export this polygin in xml
+ * @param xml_document : Xml document to use for create the xml element
+ * @return an xml element that describe this polygon
+ */
+const QDomElement PartPolygon::toXml(QDomDocument &xml_document) const
+{
 	QDomElement xml_element = xml_document.createElement("polygon");
 	int i = 1;
-	foreach(QPointF point, polygon()) {
+	foreach(QPointF point, m_polygon) {
 		point = mapToScene(point);
 		xml_element.setAttribute(QString("x%1").arg(i), QString("%1").arg(point.x()));
 		xml_element.setAttribute(QString("y%1").arg(i), QString("%1").arg(point.y()));
@@ -87,101 +110,95 @@
 }
 
 /**
-	Dessine le polygone
-	@param painter QPainter a utiliser pour rendre le dessin
-	@param options Options pour affiner le rendu
-	@param widget Widget sur lequel le rendu est effectue
-*/
-void PartPolygon::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
-	Q_UNUSED(widget);
-	applyStylesToQPainter(*painter);
-	QPen t = painter -> pen();
-	t.setCosmetic(options && options -> levelOfDetail < 1.0);
-	if (isSelected()) t.setColor(Qt::red);
-	painter -> setPen(t);
-	if (m_closed) painter -> drawPolygon(polygon());
-	else painter -> drawPolyline(polygon());
-}
+ * @brief PartPolygon::isUseless
+ * @return true if this part is irrelevant and does not deserve to be Retained / registered.
+ * A polygon is relevant when he have 2 differents points
+ */
+bool PartPolygon::isUseless() const
+{
+	if (m_polygon.count() < 2) return(true);
 
-/**
-	Gere les changements intervenant sur cette partie
-	@param change Type de changement
-	@param value Valeur numerique relative au changement
-*/
-QVariant PartPolygon::itemChange(GraphicsItemChange change, const QVariant &value) {
-	if (scene()) {
-		if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged) {
-			updateCurrentPartEditor();
-		}
-	}
-	return(QGraphicsPolygonItem::itemChange(change, value));
-}
+	for (int i = 1 ; i < m_polygon.count() ; ++ i)
+		if (m_polygon[i] != m_polygon[i-1]) return(false);
 
-/**
-	@return true si cette partie n'est pas pertinente et ne merite pas d'etre
-	conservee / enregistree.
-	Un polygone est pertinent des lors qu'il possede deux points differents.
-*/
-bool PartPolygon::isUseless() const {
-	QPolygonF poly(polygon());
-	
-	if (polygon().count() < 2) return(true);
-	
-	QPointF previous_point;
-	for (int i = 1 ; i < poly.count() ; ++ i) {
-		if (poly[i] != poly[i-1]) return(false);
-	}
-	
 	return(true);
 }
 
 /**
-	@return the minimum, margin-less rectangle this part can fit into, in scene
-	coordinates. It is different from boundingRect() because it is not supposed
-	to imply any margin, and it is different from shape because it is a regular
-	rectangle, not a complex shape.
-*/
+ * @brief PartPolygon::sceneGeometricRect
+ * @return the minimum, margin-less rectangle this part can fit into, in scene
+ * coordinates. It is different from boundingRect() because it is not supposed
+ * to imply any margin, and it is different from shape because it is a regular
+ * rectangle, not a complex shape.
+ */
 QRectF PartPolygon::sceneGeometricRect() const {
-	return(mapToScene(polygon().boundingRect()).boundingRect());
+	return(mapToScene(m_polygon.boundingRect()).boundingRect());
 }
 
 /**
-	Start the user-induced transformation, provided this primitive is contained
-	within the \a initial_selection_rect bounding rectangle.
-*/
-void PartPolygon::startUserTransformation(const QRectF &initial_selection_rect) {
+ * @brief PartPolygon::startUserTransformation
+ * Start the user-induced transformation, provided this primitive is contained
+ * within the initial_selection_rect bounding rectangle.
+ * @param initial_selection_rect
+ */
+void PartPolygon::startUserTransformation(const QRectF &initial_selection_rect)
+{
 	Q_UNUSED(initial_selection_rect)
-	saved_points_ = mapToScene(polygon()).toList();
+	saved_points_ = mapToScene(m_polygon).toList();
 }
 
 /**
-	Handle the user-induced transformation from \a initial_selection_rect to \a new_selection_rect
-*/
-void PartPolygon::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect) {
+ * @brief PartPolygon::handleUserTransformation
+ * Handle the user-induced transformation from initial_selection_rect to new_selection_rect
+ * @param initial_selection_rect
+ * @param new_selection_rect
+ */
+void PartPolygon::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect)
+{
 	QList<QPointF> mapped_points = mapPoints(initial_selection_rect, new_selection_rect, saved_points_);
-	setPolygon(mapFromScene(QPolygonF(mapped_points.toVector())));
+	m_polygon = (mapFromScene(QPolygonF(mapped_points.toVector())));
 }
 
 /**
-	@reimp CustomElementPart::preferredScalingMethod
-	This method is called by the decorator when it needs to determine the best
-	way to interactively scale a primitive. It is typically called when only a
-	single primitive is being scaled.
-	This reimplementation systematically returns QET::RoundScaleRatios.
-*/
+ * @brief PartPolygon::preferredScalingMethod
+ * This method is called by the decorator when it needs to determine the best
+ * way to interactively scale a primitive. It is typically called when only a
+ * single primitive is being scaled.
+ * @return : This reimplementation systematically returns QET::RoundScaleRatios.
+ */
 QET::ScalingMethod PartPolygon::preferredScalingMethod() const {
 	return(QET::RoundScaleRatios);
 }
 
 /**
+ * @brief PartPolygon::polygon
+ * @return the item's polygon, or an empty polygon if no polygon has been set.
+ */
+QPolygonF PartPolygon::polygon() const {
+	return m_polygon;
+}
+
+/**
+ * @brief PartPolygon::setPolygon
+ * Sets the item's polygon to be the given polygon.
+ * @param polygon
+ */
+void PartPolygon::setPolygon(const QPolygonF &polygon)
+{
+	if (m_polygon == polygon) return;
+	prepareGeometryChange();
+	m_polygon = polygon;
+}
+
+/**
  * @brief PartPolygon::addPoint
  * Add new point to polygon
  * @param point
  */
-void PartPolygon::addPoint(const QPointF &point) {
-	QPolygonF poly = polygon();
-	poly << point;
-	setPolygon(poly);
+void PartPolygon::addPoint(const QPointF &point)
+{
+	prepareGeometryChange();
+	m_polygon << point;
 }
 
 /**
@@ -189,35 +206,59 @@
  * Set the last point of polygon to @point
  * @param point
  */
-void PartPolygon::setLastPoint(const QPointF &point) {
-	QPolygonF poly = polygon();
+void PartPolygon::setLastPoint(const QPointF &point)
+{
+	if (m_polygon.size())
+		m_polygon.pop_back();
 
-	if (poly.size())
-		poly.pop_back();
-
-	poly << point;
-	setPolygon(poly);
+	prepareGeometryChange();
+	m_polygon << point;
 }
 
 /**
  * @brief PartPolygon::removeLastPoint
  * Remove the last point of polygon
  */
-void PartPolygon::removeLastPoint() {
-	QPolygonF poly = polygon();
+void PartPolygon::removeLastPoint()
+{
+	if (m_polygon.size())
+	{
+		prepareGeometryChange();
+		m_polygon.pop_back();
+	}
+}
 
-	if (poly.size())
-		poly.pop_back();
+/**
+ * @brief PartPolygon::shape
+ * @return the shape of this item
+ */
+QPainterPath PartPolygon::shape() const
+{
+	QPainterPath shape;
+	shape.addPolygon(m_polygon);
 
-	setPolygon(poly);
+	if (m_closed)
+		shape.lineTo(m_polygon.first());
+
+	QPainterPathStroker pps;
+	pps.setWidth(penWeight());
+
+	return (pps.createStroke(shape));
 }
 
 /**
-	@return le rectangle delimitant cette partie.
-*/
-QRectF PartPolygon::boundingRect() const {
-	qreal adjust = 1.5;
-	QRectF r(QGraphicsPolygonItem::boundingRect());
+ * @brief PartPolygon::boundingRect
+ * @return the bounding rect of this item
+ */
+QRectF PartPolygon::boundingRect() const
+{
+	QRectF r = m_polygon.boundingRect();
+
+	qreal adjust = (SHADOWS_HEIGHT + penWeight()) / 2;
+		//We add 0.5 because CustomElementGraphicPart::drawShadowShape
+		//draw a shape bigger of 0.5 when pen weight is to 0.
+	if (penWeight() == 0) adjust += 0.5;
+
 	r.adjust(-adjust, -adjust, adjust, adjust);
 	return(r);
 }

Modified: trunk/sources/editor/graphicspart/partpolygon.h
===================================================================
--- trunk/sources/editor/graphicspart/partpolygon.h	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partpolygon.h	2015-02-09 08:57:40 UTC (rev 3694)
@@ -17,63 +17,66 @@
 */
 #ifndef PART_POLYGON_H
 #define PART_POLYGON_H
-#include <QtGui>
+
+#include <QPolygonF>
 #include "customelementgraphicpart.h"
+
 /**
-	This class represents a polygon primitive which may be used to compose the
-	drawing of an electrical element within the element editor.
-*/
-class PartPolygon : public CustomElementGraphicPart, public QGraphicsPolygonItem  {
-	Q_OBJECT
-	// constructors, destructor
+ * @brief The PartPolygon class
+ * This class represents a polygon primitive which may be used to compose the
+ * drawing of an electrical element within the element editor.
+ */
+class PartPolygon : public CustomElementGraphicPart
+{
+		Q_OBJECT
+
+		Q_PROPERTY(bool closed READ isClosed WRITE setClosed)
+
+		// constructors, destructor
 	public:
-	PartPolygon(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
-	virtual ~PartPolygon();
+		PartPolygon(QETElementEditor *editor, QGraphicsItem *parent = 0);
+		virtual ~PartPolygon();
 	
 	private:
-	PartPolygon(const PartPolygon &);
-	
-	// attributes
-	private:
-	bool m_closed;
-	
-	// methods
+		PartPolygon(const PartPolygon &);
+
+		// methods
 	public:
-	enum { Type = UserType + 1105 };
-	/**
-		Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
-		PartPolygon.
-		@return the QGraphicsItem type
-	*/
-	virtual int type() const { return Type; }
-	virtual QString name() const { return(QObject::tr("polygone", "element part name")); }
-	virtual QString xmlName() const { return(QString("polygon")); }
-	void fromXml(const QDomElement &);
-	const QDomElement toXml(QDomDocument &) const;
-	virtual QRectF boundingRect() const;
-	void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
-	virtual bool isUseless() const;
-	virtual QRectF sceneGeometricRect() const;
-	virtual void startUserTransformation(const QRectF &);
-	virtual void handleUserTransformation(const QRectF &, const QRectF &);
-	virtual QET::ScalingMethod preferredScalingMethod() const;
+		enum { Type = UserType + 1105 };
+			/**
+			* Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a PartPolygon.
+			* @return the QGraphicsItem type
+			*/
+		virtual int type() const { return Type; }
+		void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
 
+		virtual QString name() const { return(QObject::tr("polygone", "element part name")); }
+		virtual QString xmlName() const { return(QString("polygon")); }
+		void fromXml(const QDomElement &);
+		const QDomElement toXml(QDomDocument &) const;
+
+		virtual QPainterPath shape () const;
+		virtual QRectF boundingRect() const;
+		virtual bool isUseless() const;
+		virtual QRectF sceneGeometricRect() const;
+
+		virtual void startUserTransformation(const QRectF &);
+		virtual void handleUserTransformation(const QRectF &, const QRectF &);
+		virtual QET::ScalingMethod preferredScalingMethod() const;
+
+		QPolygonF polygon () const;
+		void setPolygon   (const QPolygonF &polygon);
+
 		void addPoint        (const QPointF &point);
 		void setLastPoint    (const QPointF &point);
-		void removeLastPoint ();
+		void removeLastPoint ();	
 
-	///PROPERTY
-	// Closed (join the first and last point by a line)
-	Q_PROPERTY(bool closed READ isClosed WRITE setClosed)
-		bool isClosed() const {return m_closed;}
-		void setClosed(bool c) {m_closed = c;}
-
-
+		bool isClosed  () const {return m_closed;}
+		void setClosed (bool c) {m_closed = c;}
 	
-	protected:
-	QVariant itemChange(GraphicsItemChange, const QVariant &);
-	
 	private:
-	QList<QPointF> saved_points_;
+		bool m_closed;
+		QList<QPointF> saved_points_;
+		QPolygonF m_polygon;
 };
 #endif

Modified: trunk/sources/editor/graphicspart/partrectangle.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partrectangle.cpp	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partrectangle.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -18,201 +18,227 @@
 #include "partrectangle.h"
 
 /**
-	Constructeur
-	@param editor L'editeur d'element concerne
-	@param parent Le QGraphicsItem parent de ce rectangle
-	@param scene La scene sur laquelle figure ce rectangle
-*/
-PartRectangle::PartRectangle(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) : CustomElementGraphicPart(editor), QGraphicsRectItem(parent, scene) {
-	setFlags(QGraphicsItem::ItemIsSelectable);
-#if QT_VERSION >= 0x040600
-	setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
-#endif
-	setAcceptedMouseButtons(Qt::LeftButton);
-}
+ * @brief PartRectangle::PartRectangle
+ * Constructor
+ * @param editor the QETElementEditor of this item
+ * @param parent parent item
+ */
+PartRectangle::PartRectangle(QETElementEditor *editor, QGraphicsItem *parent) :
+	CustomElementGraphicPart(editor, parent)
+{}
 
-/// Destructeur
-PartRectangle::~PartRectangle() {
-}
+/**
+ * @brief PartRectangle::~PartRectangle
+ */
+PartRectangle::~PartRectangle() {}
 
 /**
-	Dessine le rectangle
-	@param painter QPainter a utiliser pour rendre le dessin
-	@param options Options pour affiner le rendu
-	@param widget Widget sur lequel le rendu est effectue
-*/
-void PartRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
+ * @brief PartRectangle::paint
+ * Draw this Rectangle
+ * @param painter
+ * @param options
+ * @param widget
+ */
+void PartRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget)
+{
 	Q_UNUSED(widget);
 	applyStylesToQPainter(*painter);
 	QPen t = painter -> pen();
 	t.setCosmetic(options && options -> levelOfDetail < 1.0);
-	if (isSelected()) {
+
+	if (isSelected())
 		t.setColor(Qt::red);
-	}
-	
-	// force le type de jointures pour les rectangles
+
 	t.setJoinStyle(Qt::MiterJoin);
 	
-	// force le dessin avec un trait fin si l'une des dimensions du rectangle est nulle
-	if (!rect().width() || !rect().height()) {
+		//Force the pen to width 0 if one of dimension is null
+	if (!rect().width() || !rect().height())
 		t.setWidth(0);
-	}
 	
 	painter -> setPen(t);
 	painter -> drawRect(rect());
-	if (isSelected()) {
-		painter -> setRenderHint(QPainter::Antialiasing, false);
-		painter -> setPen((painter -> brush().color() == QColor(Qt::black) && painter -> brush().isOpaque()) ? Qt::yellow : Qt::blue);
-		QPointF center = rect().center();
-		painter -> drawLine(QLineF(center.x() - 2.0, center.y(), center.x() + 2.0, center.y()));
-		painter -> drawLine(QLineF(center.x(), center.y() - 2.0, center.x(), center.y() + 2.0));
-	}
+
+	if (m_hovered)
+		drawShadowShape(painter);
+
+	if (isSelected())
+		drawCross(m_rect.center(), painter);
 }
 
 /**
-	Exporte le rectangle en XML
-	@param xml_document Document XML a utiliser pour creer l'element XML
-	@return un element XML decrivant le rectangle
-*/
-const QDomElement PartRectangle::toXml(QDomDocument &xml_document) const {
+ * @brief PartRectangle::toXml
+ * Export this rectangle in xml
+ * @param xml_document : Xml document to use for create the xml element.
+ * @return an xml element that describe this ellipse
+ */
+const QDomElement PartRectangle::toXml(QDomDocument &xml_document) const
+{
 	QDomElement xml_element = xml_document.createElement("rect");
 	QPointF top_left(sceneTopLeft());
 	xml_element.setAttribute("x", QString("%1").arg(top_left.x()));
 	xml_element.setAttribute("y", QString("%1").arg(top_left.y()));
-	xml_element.setAttribute("width",  QString("%1").arg(rect().width()));
-	xml_element.setAttribute("height", QString("%1").arg(rect().height()));
+	xml_element.setAttribute("width",  QString("%1").arg(m_rect.width()));
+	xml_element.setAttribute("height", QString("%1").arg(m_rect.height()));
 	stylesToXml(xml_element);
 	return(xml_element);
 }
 
 /**
-	Importe les proprietes d'une rectangle depuis un element XML
-	@param qde Element XML a lire
-*/
-void PartRectangle::fromXml(const QDomElement &qde) {
+ * @brief PartRectangle::fromXml
+ * Import the properties of this rectangle from a xml element.
+ * @param qde : Xml document to use.
+ */
+void PartRectangle::fromXml(const QDomElement &qde)
+{
 	stylesFromXml(qde);
-	setRect(
-		QRectF(
-			mapFromScene(
-				qde.attribute("x", "0").toDouble(),
-				qde.attribute("y", "0").toDouble()
-			),
-			QSizeF(
-				qde.attribute("width",  "0").toDouble(),
-				qde.attribute("height", "0").toDouble()
-			)
-		)
-	);
+	setRect(QRectF(mapFromScene(qde.attribute("x", "0").toDouble(),
+								qde.attribute("y", "0").toDouble()),
+				   QSizeF(qde.attribute("width",  "0").toDouble(),
+						  qde.attribute("height", "0").toDouble())));
 }
 
 /**
- * @brief PartRectangle::setX
- * @param x new value
+ * @brief PartRectangle::rect
+ * @return : Returns the item's rectangle.
  */
-void PartRectangle::setX(qreal x) {
-	QRectF current_rect = rect();
-	QPointF current_pos = mapToScene(current_rect.topLeft());
-	setRect(current_rect.translated(x - current_pos.x(), 0.0));
+QRectF PartRectangle::rect() const {
+	return m_rect;
 }
 
 /**
- * @brief PartRectangle::setY
- * @param y new value
+ * @brief PartRectangle::setRect
+ * Sets the item's rectangle to be the given rectangle.
+ * @param rect
  */
-void PartRectangle::setY(qreal y) {
-	QRectF current_rect = rect();
-	QPointF current_pos = mapToScene(current_rect.topLeft());
-	setRect(current_rect.translated(0.0, y - current_pos.y()));
+void PartRectangle::setRect(const QRectF &rect)
+{
+	if (rect == m_rect) return;
+	prepareGeometryChange();
+	m_rect = rect;
 }
 
 /**
+ * @brief PartRectangle::rectTopLeft
+ * @return the rectangle top left in item coordinate
+ */
+QPointF PartRectangle::rectTopLeft() const {
+	return m_rect.topLeft();
+}
+
+/**
+ * @brief PartRectangle::setRectTopLeft
+ * @param point, set the rectangle top left in item coordinate.
+ * The rectangle size is unchanged
+ */
+void PartRectangle::setRectTopLeft(const QPointF &point) {
+	m_rect.moveTopLeft(point);
+}
+
+/**
  * @brief PartRectangle::setWidth
+ * Sets the width of the rectangle to the given width.
+ * The right edge is changed, but not the left one.
  * @param w new value
  */
-void PartRectangle::setWidth(qreal w) {
-	qreal new_width = qAbs(w);
-	QRectF current_rect = rect();
-	current_rect.setWidth(new_width);
-	setRect(current_rect);
+void PartRectangle::setWidth(qreal w)
+{
+	prepareGeometryChange();
+	m_rect.setWidth(qAbs(w));
 }
 
 /**
  * @brief PartRectangle::setHeight
+ * Sets the height of the rectangle to the given height.
+ * The bottom edge is changed, but not the top one.
  * @param h new value
  */
-void PartRectangle::setHeight(qreal h) {
-	qreal new_height = qAbs(h);
-	QRectF current_rect = rect();
-	current_rect.setHeight(new_height);
-	setRect(current_rect);
+void PartRectangle::setHeight(qreal h)
+{
+	prepareGeometryChange();
+	m_rect.setHeight(qAbs(h));
 }
 
 /**
-	Gere les changements intervenant sur cette partie
-	@param change Type de changement
-	@param value Valeur numerique relative au changement
-*/
-QVariant PartRectangle::itemChange(GraphicsItemChange change, const QVariant &value) {
-	if (scene()) {
-		if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged) {
-			updateCurrentPartEditor();
-		}
-	}
-	return(QGraphicsRectItem::itemChange(change, value));
+ * @brief PartRectangle::sceneGeometricRect
+ * @return the minimum, margin-less rectangle this part can fit into, in scene
+ * coordinates. It is different from boundingRect() because it is not supposed
+ * to imply any margin, and it is different from shape because it is a regular
+ * rectangle, not a complex shape.
+ */
+QRectF PartRectangle::sceneGeometricRect() const {
+	return(mapToScene(rect()).boundingRect());
 }
 
 /**
-	@return le coin superieur gauche du rectangle, dans les coordonnees de la
-	scene.
-*/
+ * @brief PartRectangle::sceneTopLeft
+ * @return the top left of rectangle, in scene coordinate
+ */
 QPointF PartRectangle::sceneTopLeft() const {
 	return(mapToScene(rect().topLeft()));
 }
 
 /**
-	@return true si cette partie n'est pas pertinente et ne merite pas d'etre
-	conservee / enregistree.
-	Un rectangle est pertinent des lors que ses dimensions ne sont pas nulles.
-*/
-bool PartRectangle::isUseless() const {
-	return(rect().isNull());
+ * @brief PartRectangle::shape
+ * @return the shape of this item
+ */
+QPainterPath PartRectangle::shape() const
+{
+	QPainterPath shape;
+	shape.addRect(m_rect);
+
+	QPainterPathStroker pps;
+	pps.setWidth(penWeight());
+
+	return (pps.createStroke(shape));
 }
 
 /**
-	@return the minimum, margin-less rectangle this part can fit into, in scene
-	coordinates. It is different from boundingRect() because it is not supposed
-	to imply any margin, and it is different from shape because it is a regular
-	rectangle, not a complex shape.
-*/
-QRectF PartRectangle::sceneGeometricRect() const {
-	return(mapToScene(rect()).boundingRect());
+ * @brief PartRectangle::boundingRect
+ * @return Bounding rectangle this part can fit into
+ */
+QRectF PartRectangle::boundingRect() const
+{
+	qreal adjust = (SHADOWS_HEIGHT + penWeight()) / 2;
+		//We add 0.5 because CustomElementGraphicPart::drawShadowShape
+		//draw a shape bigger of 0.5 when pen weight is to 0.
+	if (penWeight() == 0) adjust += 0.5;
+
+	QRectF r = m_rect.normalized();
+	r.adjust(-adjust, -adjust, adjust, adjust);
+	return(r);
 }
 
 /**
-	Start the user-induced transformation, provided this primitive is contained
-	within the \a initial_selection_rect bounding rectangle.
-*/
-void PartRectangle::startUserTransformation(const QRectF &initial_selection_rect) {
+ * @brief PartRectangle::isUseless
+ * @return true if this part is irrelevant and does not deserve to be Retained / registered.
+ * An rectangle is relevant when he's not null.
+ */
+bool PartRectangle::isUseless() const {
+	return(rect().isNull());
+}
+
+/**
+ * @brief PartRectangle::startUserTransformation
+ * Start the user-induced transformation, provided this primitive is contained
+ * within the initial_selection_rect bounding rectangle.
+ * @param initial_selection_rect
+ */
+void PartRectangle::startUserTransformation(const QRectF &initial_selection_rect)
+{
 	Q_UNUSED(initial_selection_rect)
-	// we keep track of our own rectangle at the moment in scene coordinates too
+		// we keep track of our own rectangle at the moment in scene coordinates too
 	saved_points_.clear();
 	saved_points_ << mapToScene(rect().topLeft()) << mapToScene(rect().bottomRight());
 }
 
 /**
-	Handle the user-induced transformation from \a initial_selection_rect to \a new_selection_rect
-*/
-void PartRectangle::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect) {
+ * @brief PartRectangle::handleUserTransformation
+ * Handle the user-induced transformation from \a initial_selection_rect to \a new_selection_rect
+ * @param initial_selection_rect
+ * @param new_selection_rect
+ */
+void PartRectangle::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect)
+{
 	QList<QPointF> mapped_points = mapPoints(initial_selection_rect, new_selection_rect, saved_points_);
 	setRect(QRectF(mapFromScene(mapped_points.at(0)), mapFromScene(mapped_points.at(1))));
 }
-
-/**
-	@return le rectangle delimitant cette partie.
-*/
-QRectF PartRectangle::boundingRect() const {
-	qreal adjust = 1.5;
-	QRectF r(QGraphicsRectItem::boundingRect().normalized());
-	r.adjust(-adjust, -adjust, adjust, adjust);
-	return(r);
-}

Modified: trunk/sources/editor/graphicspart/partrectangle.h
===================================================================
--- trunk/sources/editor/graphicspart/partrectangle.h	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partrectangle.h	2015-02-09 08:57:40 UTC (rev 3694)
@@ -17,65 +17,69 @@
 */
 #ifndef PART_RECTANGLE_H
 #define PART_RECTANGLE_H
-#include <QtGui>
+
 #include "customelementgraphicpart.h"
+
 /**
-	This class represents a rectangle primitive which may be used to compose the
-	drawing of an electrical element within the element editor.
+ * This class represents a rectangle primitive which may be used to compose the
+ * drawing of an electrical element within the element editor.
+ * All coordinates is in item coordinate, except pos()
 */
-class PartRectangle :  public CustomElementGraphicPart, public QGraphicsRectItem {
-	Q_OBJECT
-	// constructors, destructor
+class PartRectangle :  public CustomElementGraphicPart
+{
+		Q_OBJECT
+
+		Q_PROPERTY(QPointF rectTopLeft READ rectTopLeft WRITE setRectTopLeft)
+		Q_PROPERTY(qreal width         READ width       WRITE setWidth)
+		Q_PROPERTY(qreal height        READ height      WRITE setHeight)
+
+		// constructors, destructor
 	public:
-	PartRectangle(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
-	virtual ~PartRectangle();
+		PartRectangle(QETElementEditor *, QGraphicsItem *parent = 0);
+		virtual ~PartRectangle();
 	
 	private:
-	PartRectangle(const PartRectangle &);
+		PartRectangle(const PartRectangle &);
 	
-	// methods
+		// methods
 	public:
-	enum { Type = UserType + 1109 };
-	/**
-		Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
-		PartRectangle.
-		@return the QGraphicsItem type
-	*/
-	virtual int type() const { return Type; }
-	virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
-	virtual QString name() const { return(QObject::tr("rectangle", "element part name")); }
-	virtual QString xmlName() const { return(QString("rect")); }
-	virtual const QDomElement toXml(QDomDocument &) const;
-	virtual void fromXml(const QDomElement &);
-	virtual QPointF sceneTopLeft() const;
-	virtual QRectF boundingRect() const;
-	virtual bool isUseless() const;
-	virtual QRectF sceneGeometricRect() const;
-	virtual void startUserTransformation(const QRectF &);
-	virtual void handleUserTransformation(const QRectF &, const QRectF &);
+		enum { Type = UserType + 1109 };
+			/**
+			 * Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a PartRectangle.
+			 * @return the QGraphicsItem type
+			 */
+		virtual int     type  () const { return Type; }
+		virtual void    paint (QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
+		virtual QString name  () const { return(QObject::tr("rectangle", "element part name")); }
 
-	///PROPERTY
-	// X value
-	Q_PROPERTY(qreal x READ x WRITE setX)
-		qreal x() const {return mapToScene(rect().topLeft()).x();}
-		void setX(qreal x);
-	// Y value
-	Q_PROPERTY(qreal y READ y WRITE setY)
-		qreal y() const {return mapToScene(rect().topLeft()).y();}
-		void setY(qreal y);
-	// Width value
-	Q_PROPERTY(qreal width READ width WRITE setWidth)
-		qreal width() const {return rect().width();}
-		void setWidth(qreal w);
-	// Height value
-	Q_PROPERTY(qreal height READ height WRITE setHeight)
-		qreal height() const { return rect().height();}
-		void setHeight(qreal h);
+		virtual QString           xmlName () const { return(QString("rect")); }
+		virtual const QDomElement toXml   (QDomDocument &) const;
+		virtual void              fromXml (const QDomElement &);
+
+		QRectF rect() const;
+		void   setRect(const QRectF &rect);
+
+		QPointF rectTopLeft    () const;
+		void    setRectTopLeft (const QPointF &point);
+
+		qreal width    () const {return rect().width();}
+		void  setWidth (qreal w);
+
+		qreal height    () const { return rect().height();}
+		void  setHeight (qreal h);
+
+		virtual QRectF  sceneGeometricRect() const;
+		virtual QPointF sceneTopLeft() const;
+
+		virtual QPainterPath shape () const;
+		virtual QRectF boundingRect() const;
+		virtual bool   isUseless() const;
+
+		virtual void startUserTransformation(const QRectF &);
+		virtual void handleUserTransformation(const QRectF &, const QRectF &);
 	
-	protected:
-	QVariant itemChange(GraphicsItemChange, const QVariant &);
-	
 	private:
-	QList<QPointF> saved_points_;
+		QRectF m_rect;
+		QList<QPointF> saved_points_;
 };
 #endif

Modified: trunk/sources/editor/graphicspart/partterminal.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partterminal.cpp	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partterminal.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -24,16 +24,11 @@
 	@param parent Le QGraphicsItem parent de cette borne
 	@param scene La scene sur laquelle figure cette borne
 */
-PartTerminal::PartTerminal(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) :
-	CustomElementGraphicPart(editor),
-	QGraphicsItem(parent, scene),
+PartTerminal::PartTerminal(QETElementEditor *editor, QGraphicsItem *parent) :
+	CustomElementGraphicPart(editor, parent),
 	m_orientation(Qet::North)
 {
 	updateSecondPoint();
-	setFlags(QGraphicsItem::ItemIsSelectable);
-#if QT_VERSION >= 0x040600
-	setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
-#endif
 	setZValue(100000);
 }
 
@@ -107,23 +102,37 @@
 	p -> setBrush(Terminal::neutralColor);
 	p -> drawPoint(QPointF(0.0, 0.0));
 	p -> restore();
+
+	if (m_hovered)
+		drawShadowShape(p);
 }
 
 /**
-	@return le rectangle delimitant cette partie.
-*/
-QRectF PartTerminal::boundingRect() const {
-	QPointF p1, p2;
-	if (second_point.x() <= 0.0 && second_point.y() <= 0.0) {
-		p1 = second_point;
-		p2 = QPointF(0.0, 0.0);
-	} else {
-		p1 = QPointF(0.0, 0.0);
-		p2 = second_point;
-	}
-	QRectF br;
-	br.setTopLeft    (p1 - QPointF(2.0, 2.0));
-	br.setBottomRight(p2 + QPointF(2.0, 2.0));
+ * @brief PartTerminal::shape
+ * @return the shape of this item
+ */
+QPainterPath PartTerminal::shape() const
+{
+	QPainterPath shape;
+	shape.lineTo(second_point);
+
+	QPainterPathStroker pps;
+	pps.setWidth(1);
+
+	return (pps.createStroke(shape));
+}
+
+/**
+ * @brief PartTerminal::boundingRect
+ * @return the bounding rect of this item
+ */
+QRectF PartTerminal::boundingRect() const
+{
+	QRectF br(QPointF(0, 0), second_point);
+	br = br.normalized();
+
+	qreal adjust = (SHADOWS_HEIGHT + 1) / 2;
+	br.adjust(-adjust, -adjust, adjust, adjust);
 	return(br);
 }
 
@@ -138,20 +147,6 @@
 }
 
 /**
-	Gere les changements intervenant sur cette partie
-	@param change Type de changement
-	@param value Valeur numerique relative au changement
-*/
-QVariant PartTerminal::itemChange(GraphicsItemChange change, const QVariant &value) {
-	if (scene()) {
-		if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged) {
-			updateCurrentPartEditor();
-		}
-	}
-	return(QGraphicsItem::itemChange(change, value));
-}
-
-/**
 	Met a jour la position du second point en fonction de la position et de
 	l'orientation de la borne.
 */

Modified: trunk/sources/editor/graphicspart/partterminal.h
===================================================================
--- trunk/sources/editor/graphicspart/partterminal.h	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/graphicspart/partterminal.h	2015-02-09 08:57:40 UTC (rev 3694)
@@ -17,67 +17,59 @@
 */
 #ifndef PART_TERMINAL_H
 #define PART_TERMINAL_H
+
 #include "customelementgraphicpart.h"
-#include "qet.h"
-#include <QtGui>
+
 /**
 	This class represents a terminal which may be used to compose the drawing of
 	an electrical element within the element editor.
 */
-class PartTerminal : public CustomElementGraphicPart, public QGraphicsItem {
-	Q_OBJECT
+class PartTerminal : public CustomElementGraphicPart
+{
+		Q_OBJECT
+
+		Q_PROPERTY(Qet::Orientation orientation READ orientation WRITE setOrientation)
+
 	public:
-	// constructors, destructor
-	PartTerminal(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0);
-	virtual ~PartTerminal();
+		// constructors, destructor
+		PartTerminal(QETElementEditor *editor, QGraphicsItem *parent = 0);
+		virtual ~PartTerminal();
 	private:
-	PartTerminal(const PartTerminal &);
+		PartTerminal(const PartTerminal &);
 	
-	// attributes
+		// attributes
 	private:
-	Qet::Orientation m_orientation;
-	QPointF second_point;
+		Qet::Orientation m_orientation;
+		QPointF second_point;
 	
-	// methods
+		// methods
 	public:
-	enum { Type = UserType + 1106 };
-	/**
-		Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
-		PartTerminal.
-		@return the QGraphicsItem type
-	*/
-	virtual int type() const { return Type; }
-	virtual QString name() const { return(QObject::tr("borne", "element part name")); }
-	virtual QString xmlName() const { return(QString("terminal")); }
-	virtual void fromXml(const QDomElement &);
-	virtual const QDomElement toXml(QDomDocument &) const;
-	virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
-	virtual QRectF boundingRect() const;
-	
-	/*virtual void setProperty(const QString &, const QVariant &);
-	virtual QVariant property(const QString &);*/
-	virtual bool isUseless() const;
-	virtual QRectF sceneGeometricRect() const;
-	virtual void startUserTransformation(const QRectF &);
-	virtual void handleUserTransformation(const QRectF &, const QRectF &);
+		enum { Type = UserType + 1106 };
+			/**
+			 * Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a PartTerminal.
+			 * @return the QGraphicsItem type
+			 */
+		virtual int type() const { return Type; }
+		virtual QString name() const { return(QObject::tr("borne", "element part name")); }
+		virtual QString xmlName() const { return(QString("terminal")); }
+		virtual void fromXml(const QDomElement &);
+		virtual const QDomElement toXml(QDomDocument &) const;
+		virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
 
-	///PROPERTY
-	// X value
-	Q_PROPERTY(qreal x READ x WRITE setX)
-	// Y value
-	Q_PROPERTY(qreal y READ y WRITE setY)
-	// Horientation value
-	Q_PROPERTY(Qet::Orientation orientation READ orientation WRITE setOrientation)
+		virtual QPainterPath shape() const;
+		virtual QRectF boundingRect() const;
+		virtual bool isUseless() const;
+		virtual QRectF sceneGeometricRect() const;
+		virtual void startUserTransformation(const QRectF &);
+		virtual void handleUserTransformation(const QRectF &, const QRectF &);
+
 		Qet::Orientation orientation() const {return m_orientation;}
 		void setOrientation(Qet::Orientation ori);
 	
-	protected:
-	QVariant itemChange(GraphicsItemChange, const QVariant &);
-	
 	private:
-	void updateSecondPoint();
+		void updateSecondPoint();
 	
 	private:
-	QPointF saved_position_;
+		QPointF saved_position_;
 };
 #endif

Modified: trunk/sources/editor/lineeditor.cpp
===================================================================
--- trunk/sources/editor/lineeditor.cpp	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/lineeditor.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -120,6 +120,22 @@
 }
 
 /**
+ * @brief LineEditor::editedP1
+ * @return The edited P1 in item coordinate
+ */
+QPointF LineEditor::editedP1() const {
+	return part -> mapFromScene(x1->value(), y1->value());
+}
+
+/**
+ * @brief LineEditor::editedP2
+ * @return The edited P2 in item coordinate
+ */
+QPointF LineEditor::editedP2() const {
+	return part -> mapFromScene(x2->value(), y2->value());
+}
+
+/**
 	Met a jour la ligne a partir des donnees du formulaire
 */
 void LineEditor::updateLine() {
@@ -128,28 +144,18 @@
 	part -> setProperty("length1", end1_length -> value());
 	part -> setProperty("end2",	   end2_type   -> itemData(end2_type->currentIndex()));
 	part -> setProperty("length2", end2_length -> value());
-	part -> setLine(
-		QLineF(
-			part -> mapFromScene(
-				x1 -> value(),
-				y1 -> value()
-			),
-			part -> mapFromScene(
-				x2 -> value(),
-				y2 -> value()
-			)
-		)
-	);
+	part -> setProperty("p1", editedP1());
+	part -> setProperty("p2", editedP2());
 }
 
 /// Met a jour l'abscisse du premier point de la ligne et cree un objet d'annulation
-void LineEditor::updateLineX1() { addChangePartCommand(tr("abscisse point 1"),    part, "x1", x1 -> value()); }
+void LineEditor::updateLineX1() { addChangePartCommand(tr("abscisse point 1"),    part, "p1", editedP1()); }
 /// Met a jour l'ordonnee du premier point de la ligne et cree un objet d'annulation
-void LineEditor::updateLineY1() { addChangePartCommand(tr("ordonn\351e point 1"), part, "y1", y1 -> value()); }
+void LineEditor::updateLineY1() { addChangePartCommand(tr("ordonn\351e point 1"), part, "p1", editedP1()); }
 /// Met a jour l'abscisse du second point de la ligne et cree un objet d'annulation
-void LineEditor::updateLineX2() { addChangePartCommand(tr("abscisse point 2"),    part, "x2", x2 -> value()); }
+void LineEditor::updateLineX2() { addChangePartCommand(tr("abscisse point 2"),    part, "p2", editedP2()); }
 /// Met a jour l'ordonnee du second point de la ligne et cree un objet d'annulation
-void LineEditor::updateLineY2() { addChangePartCommand(tr("ordonn\351e point 2"), part, "y2", y2 -> value()); }
+void LineEditor::updateLineY2() { addChangePartCommand(tr("ordonn\351e point 2"), part, "p2", editedP2()); }
 /// Met a jour le type de la premiere extremite
 void LineEditor::updateLineEndType1() {   addChangePartCommand(tr("type fin 1"),     part, "end1",    end1_type -> itemData(end1_type->currentIndex()));   }
 /// Met a jour la longueur de la premiere extremite

Modified: trunk/sources/editor/lineeditor.h
===================================================================
--- trunk/sources/editor/lineeditor.h	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/lineeditor.h	2015-02-09 08:57:40 UTC (rev 3694)
@@ -24,41 +24,44 @@
 /**
 	This class provides a widget to edit lines within the element editor.
 */
-class LineEditor : public ElementItemEditor {
+class LineEditor : public ElementItemEditor
+{
 	Q_OBJECT
 	// constructors, destructor
 	public:
-	LineEditor(QETElementEditor *, PartLine * = 0, QWidget * = 0);
-	virtual ~LineEditor();
+		LineEditor(QETElementEditor *, PartLine * = 0, QWidget * = 0);
+		virtual ~LineEditor();
 	private:
-	LineEditor(const LineEditor &);
+		LineEditor(const LineEditor &);
 	
 	// attributes
 	private:
-	PartLine *part;
-	StyleEditor *style_;
-	QDoubleSpinBox *x1, *y1, *x2, *y2;
-	QComboBox *end1_type, *end2_type;
-	QDoubleSpinBox*end1_length, *end2_length;
+		PartLine *part;
+		StyleEditor *style_;
+		QDoubleSpinBox *x1, *y1, *x2, *y2;
+		QComboBox *end1_type, *end2_type;
+		QDoubleSpinBox*end1_length, *end2_length;
 	
 	// methods
 	public:
-	virtual bool setPart(CustomElementPart *);
-	virtual CustomElementPart *currentPart() const;
+		virtual bool setPart(CustomElementPart *);
+		virtual CustomElementPart *currentPart() const;
+		QPointF editedP1() const;
+		QPointF editedP2() const;
 	
 	public slots:
-	void updateLine();
-	void updateLineX1();
-	void updateLineY1();
-	void updateLineX2();
-	void updateLineY2();
-	void updateLineEndType1();
-	void updateLineEndLength1();
-	void updateLineEndType2();
-	void updateLineEndLength2();
-	void updateForm();
+		void updateLine();
+		void updateLineX1();
+		void updateLineY1();
+		void updateLineX2();
+		void updateLineY2();
+		void updateLineEndType1();
+		void updateLineEndLength1();
+		void updateLineEndType2();
+		void updateLineEndLength2();
+		void updateForm();
 	
 	private:
-	void activeConnections(bool);
+		void activeConnections(bool);
 };
 #endif

Modified: trunk/sources/editor/rectangleeditor.cpp
===================================================================
--- trunk/sources/editor/rectangleeditor.cpp	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/rectangleeditor.cpp	2015-02-09 08:57:40 UTC (rev 3694)
@@ -98,24 +98,31 @@
 }
 
 /**
+ * @brief RectangleEditor::topLeft
+ * @return The edited topLeft already mapped to part coordinate
+ */
+QPointF RectangleEditor::editedTopLeft() const {
+	return part -> mapFromScene(x->value(), y->value());
+}
+
+/**
 	Met a jour le rectangle a partir des donnees du formulaire
 */
 void RectangleEditor::updateRectangle() {
 	if (!part) return;
-	part -> setProperty("x",      x -> value());
-	part -> setProperty("y",      y -> value());
+	part -> setProperty("rectTopLeft", editedTopLeft());
 	part -> setProperty("width",  w -> value());
 	part -> setProperty("height", h -> value());
 }
 
 /// Met a jour l'abscisse du coin superieur gauche du rectangle et cree un objet d'annulation
-void RectangleEditor::updateRectangleX() { addChangePartCommand(tr("abscisse"),               part, "x",           x  -> value());       }
+void RectangleEditor::updateRectangleX() { addChangePartCommand(tr("abscisse"),               part, "rectTopLeft", editedTopLeft());}
 /// Met a jour l'ordonnee du coin superieur gauche du rectangle et cree un objet d'annulation
-void RectangleEditor::updateRectangleY() { addChangePartCommand(tr("ordonn\351e"),            part, "y",           y  -> value());       }
+void RectangleEditor::updateRectangleY() { addChangePartCommand(tr("ordonn\351e"),            part, "rectTopLeft", editedTopLeft());}
 /// Met a jour la largeur du rectangle et cree un objet d'annulation
-void RectangleEditor::updateRectangleW() { addChangePartCommand(tr("largeur"),                part, "width",       w  -> value());       }
+void RectangleEditor::updateRectangleW() { addChangePartCommand(tr("largeur"),                part, "width",       w  -> value());}
 /// Met a jour la hauteur du rectangle et cree un objet d'annulation
-void RectangleEditor::updateRectangleH() { addChangePartCommand(tr("hauteur"),                part, "height",      h  -> value());       }
+void RectangleEditor::updateRectangleH() { addChangePartCommand(tr("hauteur"),                part, "height",      h  -> value());}
 
 /**
 	Met a jour le formulaire d'edition
@@ -123,8 +130,9 @@
 void RectangleEditor::updateForm() {
 	if (!part) return;
 	activeConnections(false);
-	x->setValue(part->property("x").toReal());
-	y->setValue(part->property("y").toReal());
+	QPointF p = part->mapToScene(part->property("rectTopLeft").toPointF());
+	x->setValue(p.x());
+	y->setValue(p.y());
 	w->setValue(part->property("width").toReal());
 	h->setValue(part->property("height").toReal());
 	activeConnections(true);

Modified: trunk/sources/editor/rectangleeditor.h
===================================================================
--- trunk/sources/editor/rectangleeditor.h	2015-02-07 15:38:11 UTC (rev 3693)
+++ trunk/sources/editor/rectangleeditor.h	2015-02-09 08:57:40 UTC (rev 3694)
@@ -43,6 +43,7 @@
 	public:
 	virtual bool setPart(CustomElementPart *);
 	virtual CustomElementPart *currentPart() const;
+	QPointF editedTopLeft () const;
 	
 	public slots:
 	void updateRectangle();


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