[qet] qet/qet: [5001] Toatly revamp of the handlers use to modify primitves, shapes and conductors.

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


Revision: 5001
Author:   blacksun
Date:     2017-08-02 17:26:14 +0200 (Wed, 02 Aug 2017)
Log Message:
-----------
Toatly revamp of the handlers use to modify primitves, shapes and conductors.

Modified Paths:
--------------
    trunk/dev_doc/enum_type_of_QGraphicsItem
    trunk/sources/QetGraphicsItemModeler/QetGraphicsItemModeler.pri
    trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp
    trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h
    trunk/sources/diagram.cpp
    trunk/sources/editor/elementprimitivedecorator.cpp
    trunk/sources/editor/elementprimitivedecorator.h
    trunk/sources/editor/elementscene.cpp
    trunk/sources/editor/elementscene.h
    trunk/sources/editor/graphicspart/abstractpartellipse.cpp
    trunk/sources/editor/graphicspart/abstractpartellipse.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/qetgraphicsitem/conductor.cpp
    trunk/sources/qetgraphicsitem/conductor.h
    trunk/sources/qetgraphicsitem/qetshapeitem.cpp
    trunk/sources/qetgraphicsitem/qetshapeitem.h

Added Paths:
-----------
    trunk/sources/QetGraphicsItemModeler/qetgraphicshandleritem.cpp
    trunk/sources/QetGraphicsItemModeler/qetgraphicshandleritem.h

Modified: trunk/dev_doc/enum_type_of_QGraphicsItem
===================================================================
--- trunk/dev_doc/enum_type_of_QGraphicsItem	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/dev_doc/enum_type_of_QGraphicsItem	2017-08-02 15:26:14 UTC (rev 5001)
@@ -21,6 +21,3 @@
 part text       + 1107
 part text field + 1108
 part rectangle  + 1109
-
-###QetGraphicsHandlerItem###
-QetGraphicsHandlerItem = 1200

Modified: trunk/sources/QetGraphicsItemModeler/QetGraphicsItemModeler.pri
===================================================================
--- trunk/sources/QetGraphicsItemModeler/QetGraphicsItemModeler.pri	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/QetGraphicsItemModeler/QetGraphicsItemModeler.pri	2017-08-02 15:26:14 UTC (rev 5001)
@@ -1,5 +1,7 @@
 HEADERS += \
-    $$PWD/qetgraphicshandlerutility.h
+    $$PWD/qetgraphicshandlerutility.h \
+    $$PWD/qetgraphicshandleritem.h
 
 SOURCES += \
-    $$PWD/qetgraphicshandlerutility.cpp
+    $$PWD/qetgraphicshandlerutility.cpp \
+    $$PWD/qetgraphicshandleritem.cpp

Added: trunk/sources/QetGraphicsItemModeler/qetgraphicshandleritem.cpp
===================================================================
--- trunk/sources/QetGraphicsItemModeler/qetgraphicshandleritem.cpp	                        (rev 0)
+++ trunk/sources/QetGraphicsItemModeler/qetgraphicshandleritem.cpp	2017-08-02 15:26:14 UTC (rev 5001)
@@ -0,0 +1,99 @@
+/*
+    Copyright 2006-2017 The QElectroTech Team
+    This file is part of QElectroTech.
+
+    QElectroTech is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 2 of the License, or
+    (at your option) any later version.
+
+    QElectroTech is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "qetgraphicshandleritem.h"
+#include <QPainter>
+#include <QDebug>
+
+/**
+ * @brief QetGraphicsHandlerItem::QetGraphicsHandlerItem
+ * @param size, the size of the handler
+ */
+QetGraphicsHandlerItem::QetGraphicsHandlerItem(qreal size) :
+    m_size(size)
+{}
+
+/**
+ * @brief QetGraphicsHandlerItem::boundingRect
+ * @return 
+ */
+QRectF QetGraphicsHandlerItem::boundingRect() const
+{
+    qreal rect_size = m_size * m_previous_zoom_factor;
+    QRectF rect(0-rect_size/2, 0-rect_size/2, rect_size, rect_size);
+    rect.adjust(-2, -2, 2, 2);
+	return rect;
+}
+
+/**
+ * @brief QetGraphicsHandlerItem::setColor
+ * @param color, set the color of the handler
+ */
+void QetGraphicsHandlerItem::setColor(QColor color)
+{
+	m_color = color;
+	update();
+}
+
+/**
+ * @brief QetGraphicsHandlerItem::paint
+ * @param painter
+ * @param option
+ * @param widget
+ */
+void QetGraphicsHandlerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    qreal zoom_factor = 1.0/painter->transform().m11();
+    if(zoom_factor != m_previous_zoom_factor)
+    {
+        prepareGeometryChange();
+        m_previous_zoom_factor = zoom_factor;
+    }
+
+    qreal rect_size = m_size * m_previous_zoom_factor;
+    QRectF rect(0-rect_size/2, 0-rect_size/2, rect_size, rect_size);
+
+    painter->save();
+    painter->setBrush(QBrush(m_color));
+    QPen pen(QBrush(m_color), 2, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin);
+	pen.setCosmetic(true);
+    painter->setPen(pen);
+	painter->setRenderHint(QPainter::Antialiasing, true);
+    painter->drawEllipse(rect);
+	painter->restore();
+}
+
+/**
+ * @brief QetGraphicsHandlerItem::handlerForPoint
+ * @param points
+ * @return A list of handler with pos at point
+ */
+QVector<QetGraphicsHandlerItem *> QetGraphicsHandlerItem::handlerForPoint(const QVector<QPointF> &points, int size)
+{
+    QVector <QetGraphicsHandlerItem *> list_;
+    for (QPointF point : points)
+    {
+        QetGraphicsHandlerItem *qghi = new QetGraphicsHandlerItem(size);
+        qghi->setPos(point);
+        list_ << qghi;
+    }
+
+	return list_;
+}

Added: trunk/sources/QetGraphicsItemModeler/qetgraphicshandleritem.h
===================================================================
--- trunk/sources/QetGraphicsItemModeler/qetgraphicshandleritem.h	                        (rev 0)
+++ trunk/sources/QetGraphicsItemModeler/qetgraphicshandleritem.h	2017-08-02 15:26:14 UTC (rev 5001)
@@ -0,0 +1,53 @@
+/*
+    Copyright 2006-2017 The QElectroTech Team
+    This file is part of QElectroTech.
+
+    QElectroTech is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 2 of the License, or
+    (at your option) any later version.
+
+    QElectroTech is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef QETGRAPHICSHANDLERITEM_H
+#define QETGRAPHICSHANDLERITEM_H
+
+#include <QGraphicsItem>
+
+/**
+ * @brief The QetGraphicsHandlerItem class
+ * This graphics item represents a point, destined to be used as an handler,
+ * for modifie the geometrie of a another graphics item (like shapes).
+ * The graphics item to be modified, must call "installSceneEventFilter" of this item with itself for argument,.
+ * The ghraphics item to be modified, need to reimplement "sceneEventFilter" for create the modification behavior.
+ */
+class QetGraphicsHandlerItem : public QGraphicsItem
+{
+    public:
+        QetGraphicsHandlerItem(qreal size = 15);
+        virtual QRectF boundingRect() const;
+		
+		enum { Type = UserType + 1200};
+		virtual int type() const {return Type;}
+		
+		void setColor(QColor color);
+
+    protected:
+        virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+    private:
+        qreal m_size,
+              m_previous_zoom_factor = 1;
+		QColor m_color;
+		
+	public:
+		static QVector<QetGraphicsHandlerItem *> handlerForPoint(const QVector<QPointF> &points, int size = 15);
+};
+
+#endif // QETGRAPHICSHANDLERITEM_H

Modified: trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp
===================================================================
--- trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp	2017-08-02 15:26:14 UTC (rev 5001)
@@ -16,113 +16,12 @@
 	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "qetgraphicshandlerutility.h"
-#include <QPainter>
+//#include <QVector>
+//#include <QPointF>
+#include <QPainterPath>
 
-/**
- * @brief QetGraphicsHandlerUtility::QetGraphicsHandlerUtility
- * Constructor
- * @param size : the size of the handler
- */
-QetGraphicsHandlerUtility::QetGraphicsHandlerUtility(qreal size) :
-	m_size (size)
-{}
 
 /**
- * @brief QetGraphicsHandlerUtility::drawHandler
- * Draw the handler at pos @point, using the QPainter @painter.
- * @param painter : painter to use for drawing the handler
- * @param point : point to draw the handler
- */
-void QetGraphicsHandlerUtility::drawHandler(QPainter *painter, const QPointF &point)
-{
-		//Setup the zoom factor to draw the handler in the same size at screen,
-		//no matter the zoom of the QPainter
-	m_zoom_factor = 1.0/painter->transform().m11();
-
-	painter->save();
-	painter->setBrush(QBrush(m_inner_color));
-	QPen square_pen(QBrush(m_outer_color), 2, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin);
-	square_pen.setCosmetic(true);
-	painter->setPen(square_pen);
-	painter->drawRect(getRect(point));
-	painter->restore();
-}
-
-/**
- * @brief QetGraphicsHandlerUtility::drawHandler
- * Conveniance method for void QetGraphicsHandlerUtility::drawHandler(QPainter *painter, const QPointF &point)
- * @param painter
- * @param points
- * @param color2
- */
-void QetGraphicsHandlerUtility::drawHandler(QPainter *painter, const QVector<QPointF> &points) {
-	foreach(QPointF point, points)
-		drawHandler(painter, point);
-}
-
-/**
- * @brief QetGraphicsHandlerUtility::pointIsInHandler
- * @param point : point to compare
- * @param key_point : point at the center of handler (the point to modify, for exemple the corner of a rectangle)
- * @return true if point is in a handler. else false
- */
-bool QetGraphicsHandlerUtility::pointIsInHandler(const QPointF &point, const QPointF &key_point) const {
-	return (getRect(key_point).contains(point));
-}
-
-/**
- * @brief QetGraphicsHandlerUtility::pointIsHoverHandler
- * @param point : point to compare
- * @param vector : vector of key_point (the point to modify, for exemple the corners of a rectangle)
- * @return if point is hover an handler, return the index of the hovered key_point in the vector, else return -1
- */
-int QetGraphicsHandlerUtility::pointIsHoverHandler(const QPointF &point, const QVector<QPointF> &vector) const
-{
-	foreach (QPointF key_point, vector)
-		if (pointIsInHandler(point, key_point))
-			return vector.indexOf(key_point);
-
-	return -1;
-}
-
-/**
- * @brief QetGraphicsHandlerUtility::handlerRect
- * Return the rect of the handler for all key_point in vector (the point to modify, for exemple the corners of a rectangle)
- * The order of rect in the returned vector is the same as the given vector.
- * @param vector
- * @return
- */
-QVector<QRectF> QetGraphicsHandlerUtility::handlerRect(const QVector<QPointF> &vector) const
-{
-	QVector <QRectF> rect_vector;
-
-	foreach(QPointF point, vector)
-		rect_vector << getRect(point);
-
-	return rect_vector;
-}
-
-void QetGraphicsHandlerUtility::setInnerColor(QColor color) {
-	m_inner_color = color;
-}
-
-void QetGraphicsHandlerUtility::setOuterColor(QColor color) {
-	m_outer_color = color;
-}
-
-/**
- * @brief QetGraphicsHandlerUtility::getRect
- * @param point
- * @return
- */
-QRectF QetGraphicsHandlerUtility::getRect(const QPointF &point) const
-{
-	qreal rect_size = m_size * m_zoom_factor;
-	QRectF rect(point.x() - rect_size/2, point.y() - rect_size/2, rect_size, rect_size);
-	return rect;
-}
-
-/**
  * @brief QetGraphicsHandlerUtility::pointsForRect
  * Return the keys points of the rectangle, stored in a vector.
  * The points in the vector are stored like this :
@@ -169,7 +68,6 @@
 	return (QVector<QPointF> {line.p1(), line.p2()});
 }
 
-#include <QDebug>
 /**
  * @brief QetGraphicsHandlerUtility::pointsForArc
  * Return the points for the given arc.

Modified: trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h
===================================================================
--- trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h	2017-08-02 15:26:14 UTC (rev 5001)
@@ -33,25 +33,6 @@
 class QetGraphicsHandlerUtility
 {
 	public:
-		QetGraphicsHandlerUtility (qreal size = 1);
-		void setSize(qreal size) {m_size = size;}
-		void drawHandler (QPainter *painter, const QPointF & point);
-		void drawHandler(QPainter *painter, const QVector<QPointF> &points);
-		QPointF posForHandler(const QPointF &point) const;
-		bool pointIsInHandler (const QPointF &point, const QPointF &key_point) const;
-		int pointIsHoverHandler (const QPointF &point, const QVector<QPointF> &vector) const;
-		QVector<QRectF> handlerRect (const QVector<QPointF> &vector) const;
-		void setInnerColor (QColor color);
-		void setOuterColor (QColor color);
-
-	private:
-		QRectF getRect (const QPointF &point) const;
-		qreal m_size;
-		qreal m_zoom_factor = 1;
-		QColor m_inner_color = Qt::white,
-			   m_outer_color = Qt::blue;
-
-	public:
 		static QVector <QPointF> pointsForRect (const QRectF &rect);
 		static QVector <QPointF> pointsForLine (const QLineF &line);
 		static QVector <QPointF> pointsForArc  (const QRectF &rect, qreal start_angle, qreal span_angle);

Modified: trunk/sources/diagram.cpp
===================================================================
--- trunk/sources/diagram.cpp	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/diagram.cpp	2017-08-02 15:26:14 UTC (rev 5001)
@@ -91,30 +91,31 @@
  * @brief Diagram::~Diagram
  * Destructor
  */
-Diagram::~Diagram()
-{
-        //First clear every selection to close an hypothetical editor
-    clearSelection();
-        // clear undo stack to prevent errors, because contains pointers to this diagram and is elements.
+Diagram::~Diagram() {
+	// clear undo stack to prevent errors, because contains pointers to this diagram and is elements.
 	undoStack().clear();
-        //delete of QGIManager, every elements he knows are removed
+	//delete of QGIManager, every elements he knows are removed
 	delete qgi_manager_;
-        // remove of conductor setter
+	// remove of conductor setter
 	delete conductor_setter_;
 	
-        // delete of object for manage movement
+	// delete of object for manage movement
 	delete elements_mover_;
 	delete element_texts_mover_;
 
-	if (m_event_interface)
-        delete m_event_interface;
+	if (m_event_interface) delete m_event_interface;
 	
-        // list removable items
+	// list removable items
 	QList<QGraphicsItem *> deletable_items;
 	for(QGraphicsItem *qgi : items())
-    {
-		if (qgi -> parentItem()) continue;
-		if (qgraphicsitem_cast<Conductor *>(qgi)) continue;
+	{
+		if (qgi->parentItem())
+			continue;
+		if (qgi->type() == Conductor::Type)
+			continue;
+		if (qgi->type() == QetGraphicsHandlerItem::Type)
+			continue;
+		
 		deletable_items << qgi;
 	}
 
@@ -377,6 +378,8 @@
  * Diagram become the ownership of event_interface
  * If there is a previous interface, they will be delete before
  * and call init() to the new interface.
+ * The derivated class of DiagramEventInterface need to emit the signal "finish" when the job is done,
+ * diagram use this signal to delete the interface. If the signal isn't send, the interface will never be deleted.
  * @param event_interface
  */
 void Diagram::setEventInterface(DiagramEventInterface *event_interface)

Modified: trunk/sources/editor/elementprimitivedecorator.cpp
===================================================================
--- trunk/sources/editor/elementprimitivedecorator.cpp	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/elementprimitivedecorator.cpp	2017-08-02 15:26:14 UTC (rev 5001)
@@ -24,6 +24,7 @@
 #include <QGraphicsSceneHoverEvent>
 #include <QStyleOptionGraphicsItem>
 #include <QGraphicsScene>
+#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
 
 /**
 	Constructor
@@ -30,17 +31,17 @@
 	@param parent Parent QGraphicsItem
 */
 ElementPrimitiveDecorator::ElementPrimitiveDecorator(QGraphicsItem *parent):
-	QGraphicsObject(parent),
-	m_handler(10)
+	QGraphicsObject(parent)
 {
 	init();
-	m_handler.setOuterColor(Qt::darkGreen);
 }
 
 /**
 	Destructor
 */
-ElementPrimitiveDecorator::~ElementPrimitiveDecorator() {
+ElementPrimitiveDecorator::~ElementPrimitiveDecorator()
+{
+	removeHandler();
 }
 
 /**
@@ -68,12 +69,7 @@
 */
 QRectF ElementPrimitiveDecorator::boundingRect() const
 {
-	QVector<QRectF> rect_vector = m_handler.handlerRect(getResizingsPoints());
-	
-	QRectF rect = effective_bounding_rect_;
-	rect |= rect_vector.first();
-	rect |= rect_vector.last();
-	return(rect);
+	return effective_bounding_rect_;
 }
 
 /**
@@ -96,9 +92,6 @@
 	pen.setCosmetic(true);
 	painter -> setPen(pen);
 	painter -> drawRect(modified_bounding_rect_);
-
-		//Draw the handlers
-	m_handler.drawHandler(painter, getResizingsPoints());
 	
 	// uncomment to draw the real bouding rect (=adjusted internal bounding rect)
 	// painter -> setBrush(QBrush(QColor(240, 0, 0, 127)));
@@ -118,15 +111,19 @@
 	if (focusItem() != this) {
 		setFocus();
 	}
+	adjusteHandlerPos();
 }
 
 /**
 	@param items the new list of items this decorator is suposed to manipulate.
 */
-void ElementPrimitiveDecorator::setItems(const QList<QGraphicsItem *> &items) {
+void ElementPrimitiveDecorator::setItems(const QList<QGraphicsItem *> &items)
+{
 	QList<CustomElementPart *> primitives;
-	foreach (QGraphicsItem *item, items) {
-		if (CustomElementPart *part_item = dynamic_cast<CustomElementPart *>(item)) {
+	for(QGraphicsItem *item : items)
+	{
+		if (CustomElementPart *part_item = dynamic_cast<CustomElementPart *>(item))
+		{
 			primitives << part_item;
 		}
 	}
@@ -157,7 +154,8 @@
 	Adjust the visual decorator according to the currently assigned items.
 	It is notably called by setItems().
 */
-void ElementPrimitiveDecorator::adjust() {
+void ElementPrimitiveDecorator::adjust()
+{
 	saveOriginalBoundingRect();
 	modified_bounding_rect_ = original_bounding_rect_;
 	adjustEffectiveBoundingRect();
@@ -164,65 +162,23 @@
 }
 
 /**
-	Handle events generated when the mouse hovers over the decorator.
-	@param event Object describing the hover event.
-*/
-void ElementPrimitiveDecorator::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
-{
-	int p = m_handler.pointIsHoverHandler(event->pos(), getResizingsPoints());
-
-	if (p == 0 || p == 7)
-		setCursor(Qt::SizeFDiagCursor);
-	else if (p == 2 || p == 5)
-		setCursor(Qt::SizeBDiagCursor);
-	else if (p == 1 || p ==6)
-		setCursor(Qt::SizeVerCursor);
-	else if (p == 3 || p == 4)
-		setCursor(Qt::SizeHorCursor);
-	else if (p == -1 && modified_bounding_rect_.normalized().contains(event->pos()))
-		setCursor(Qt::SizeAllCursor);
-	else
-		setCursor(Qt::ArrowCursor);
-}
-
-/**
 	Handle event generated when mouse buttons are pressed.
 	@param event Object describing the mouse event
 */
 void ElementPrimitiveDecorator::mousePressEvent(QGraphicsSceneMouseEvent *event)
-{
-	QPointF pos = event -> pos();
-	QVector <QPointF> points = getResizingsPoints();
-	
-	current_operation_square_ = m_handler.pointIsHoverHandler(pos, points);
-	bool accept = false;
-
-	if (current_operation_square_ != QET::NoOperation)
-		accept = true;
-	else
+{	
+	if (internalBoundingRect().contains(event->pos()))
 	{
-		if (internalBoundingRect().contains(pos))
-		{
-			current_operation_square_ = QET::MoveArea;
-			accept = true;
-		}
-	}
-	
-	if (accept)
-	{
-		if (current_operation_square_ > QET::NoOperation)
-			first_pos_ = latest_pos_ = mapToScene(points.at(current_operation_square_));
-		else
-		{
-			first_pos_ = decorated_items_.at(0) -> toItem() -> scenePos();
-			latest_pos_ = event -> scenePos();
-			mouse_offset_ = event -> scenePos() - first_pos_;
-		}
+		current_operation_square_ = QET::MoveArea;
+		
+		first_pos_ = decorated_items_.at(0) -> toItem() -> scenePos();
+		latest_pos_ = event -> scenePos();
+		mouse_offset_ = event -> scenePos() - first_pos_;
 		startMovement();
-		event -> accept();
+		event->accept();
 	}
 	else
-		event -> ignore();
+		event->ignore();
 }
 
 /**
@@ -235,59 +191,25 @@
 	QPointF scene_pos = event -> scenePos();
 	QPointF movement = scene_pos - latest_pos_;
 	
-	if (current_operation_square_ > QET::NoOperation) {
-		// This is a scaling operation.
-		
-		// For convenience purposes, we may need to adjust mouse movements.
-		QET::ScalingMethod scaling_method = scalingMethod(event);
-		if (scaling_method > QET::FreeScaling) {
-			// real, non-rounded movement from the mouse press event
-			QPointF global_movement = scene_pos - first_pos_;
-			
-			QPointF rounded_global_movement;
-			if (scaling_method == QET::SnapScalingPointToGrid) {
-				// real, rounded movement from the mouse press event
-				rounded_global_movement = snapConstPointToGrid(global_movement);
-			}
-			else {
-				QRectF new_bounding_rect = original_bounding_rect_;
-				applyMovementToRect(current_operation_square_, global_movement, new_bounding_rect);
-				
-				const qreal scale_epsilon = 20.0; // rounds to 0.05
-				QPointF delta = deltaForRoundScaling(original_bounding_rect_, new_bounding_rect, scale_epsilon);
-				
-				// real, rounded movement from the mouse press event
-				rounded_global_movement = global_movement + delta;
-			}
-			
-			// rounded position of the current mouse move event
-			QPointF rounded_scene_pos = first_pos_ + rounded_global_movement;
-			
-			// when scaling the selection, consider the center of the currently dragged resizing rectangle
-			QPointF current_position = mapToScene(getResizingsPoints().at(current_operation_square_));
-			// determine the final, effective movement
-			movement = rounded_scene_pos - current_position;
-		}
-	}
-	else if (current_operation_square_ == QET::MoveArea) {
+	if (current_operation_square_ == QET::MoveArea)
+	{
 		// When moving the selection, consider the position of the first selected item
 		QPointF current_position = scene_pos - mouse_offset_;
 		QPointF rounded_current_position = snapConstPointToGrid(current_position);
 		movement = rounded_current_position - decorated_items_.at(0) -> toItem() -> scenePos();
+		
+		QRectF bounding_rect = modified_bounding_rect_;
+		applyMovementToRect(current_operation_square_, movement, modified_bounding_rect_);
+		if (modified_bounding_rect_ != bounding_rect) {
+			adjustEffectiveBoundingRect();
+		}
+		latest_pos_ = event -> scenePos();
+		translateItems(movement);
 	}
 	
-	QRectF bounding_rect = modified_bounding_rect_;
-	applyMovementToRect(current_operation_square_, movement, modified_bounding_rect_);
-	if (modified_bounding_rect_ != bounding_rect) {
-		adjustEffectiveBoundingRect();
-	}
-	latest_pos_ = event -> scenePos();
+
 	
-	if (current_operation_square_ == QET::MoveArea) {
-		translateItems(movement);
-	} else {
-		scaleItems(original_bounding_rect_, modified_bounding_rect_);
-	}
+
 }
 
 /**
@@ -296,31 +218,25 @@
 	@param event Object describing the mouse event
 	@see QGraphicsScene::mouseGrabberItem()
 */
-void ElementPrimitiveDecorator::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
+void ElementPrimitiveDecorator::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
 	Q_UNUSED(event)
 	
 	ElementEditionCommand *command = 0;
-	if (current_operation_square_ > QET::NoOperation) {
-		ScalePartsCommand *scale_command = new ScalePartsCommand();
-		scale_command -> setScaledPrimitives(items());
-		scale_command -> setTransformation(
-			mapToScene(original_bounding_rect_).boundingRect(),
-			mapToScene(modified_bounding_rect_).boundingRect()
-		);
-		command = scale_command;
-	} else if (current_operation_square_ == QET::MoveArea) {
+
+	if (current_operation_square_ == QET::MoveArea)
+	{
 		QPointF movement = mapToScene(modified_bounding_rect_.topLeft()) - mapToScene(original_bounding_rect_.topLeft());
-		if (!movement.isNull()) {
+		if (!movement.isNull())
+		{
 			MovePartsCommand *move_command = new MovePartsCommand(movement, 0, graphicsItems());
 			command = move_command;
 		}
-    }
-	
-	if (command) {
-		emit(actionFinished(command));
-	}
-	
-	if (current_operation_square_ != QET::NoOperation) {
+		
+		if (command) {
+			emit(actionFinished(command));
+		}
+		
 		adjust();
 	}
 	
@@ -376,7 +292,8 @@
 /**
 	Initialize an ElementPrimitiveDecorator
 */
-void ElementPrimitiveDecorator::init() {
+void ElementPrimitiveDecorator::init()
+{
 	setFlag(QGraphicsItem::ItemIsFocusable, true);
 	grid_step_x_ = grid_step_y_ = 1;
 	setAcceptHoverEvents(true);
@@ -397,6 +314,7 @@
 	prepareGeometryChange();
 	effective_bounding_rect_ = modified_bounding_rect_ | effective_bounding_rect_;
 	update();
+	adjusteHandlerPos();
 }
 
 /**
@@ -529,6 +447,152 @@
 }
 
 /**
+ * @brief ElementPrimitiveDecorator::adjusteHandlerPos
+ */
+void ElementPrimitiveDecorator::adjusteHandlerPos()
+{
+	QVector <QPointF> points_vector = mapToScene(getResizingsPoints());
+	for (int i = 0 ; i < points_vector.size() ; ++i)
+		m_handler_vector.at(i)->setPos(points_vector.at(i));
+}
+
+/**
+ * @brief ElementPrimitiveDecorator::handlerMousePressEvent
+ * @param qghi
+ * @param event
+ */
+void ElementPrimitiveDecorator::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+	Q_UNUSED(event);
+	
+	QVector <QPointF> points = getResizingsPoints();
+	
+	current_operation_square_ = m_handler_vector.indexOf(qghi);
+	
+	first_pos_ = latest_pos_ = mapToScene(points.at(current_operation_square_));
+	startMovement();
+}
+
+/**
+ * @brief ElementPrimitiveDecorator::handlerMouseMoveEvent
+ * @param qghi
+ * @param event
+ */
+void ElementPrimitiveDecorator::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+	Q_UNUSED(qghi);
+	
+	QPointF scene_pos = event -> scenePos();
+	QPointF movement = scene_pos - latest_pos_;
+	
+		// For convenience purposes, we may need to adjust mouse movements.
+	QET::ScalingMethod scaling_method = scalingMethod(event);
+	if (scaling_method > QET::FreeScaling)
+	{
+			// real, non-rounded movement from the mouse press event
+		QPointF global_movement = scene_pos - first_pos_;
+		
+		QPointF rounded_global_movement;
+		if (scaling_method == QET::SnapScalingPointToGrid)
+		{
+				// real, rounded movement from the mouse press event
+			rounded_global_movement = snapConstPointToGrid(global_movement);
+		}
+		else
+		{
+			QRectF new_bounding_rect = original_bounding_rect_;
+			applyMovementToRect(current_operation_square_, global_movement, new_bounding_rect);
+			
+			const qreal scale_epsilon = 20.0; // rounds to 0.05
+			QPointF delta = deltaForRoundScaling(original_bounding_rect_, new_bounding_rect, scale_epsilon);
+			
+				// real, rounded movement from the mouse press event
+			rounded_global_movement = global_movement + delta;
+		}
+		
+			// rounded position of the current mouse move event
+		QPointF rounded_scene_pos = first_pos_ + rounded_global_movement;
+		
+			// when scaling the selection, consider the center of the currently dragged resizing rectangle
+		QPointF current_position = mapToScene(getResizingsPoints().at(current_operation_square_));
+			// determine the final, effective movement
+		movement = rounded_scene_pos - current_position;
+	}
+	
+	QRectF bounding_rect = modified_bounding_rect_;
+	applyMovementToRect(current_operation_square_, movement, modified_bounding_rect_);
+	if (modified_bounding_rect_ != bounding_rect) {
+		adjustEffectiveBoundingRect();
+	}
+	latest_pos_ = event -> scenePos();
+	scaleItems(original_bounding_rect_, modified_bounding_rect_);
+}
+
+/**
+ * @brief ElementPrimitiveDecorator::handlerMouseReleaseEvent
+ * @param qghi
+ * @param event
+ */
+void ElementPrimitiveDecorator::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+	Q_UNUSED(qghi);
+	Q_UNUSED(event);
+	
+	ElementEditionCommand *command = 0;
+	if (current_operation_square_ > QET::NoOperation)
+	{
+		ScalePartsCommand *scale_command = new ScalePartsCommand();
+		scale_command -> setScaledPrimitives(items());
+		scale_command -> setTransformation(
+					mapToScene(original_bounding_rect_).boundingRect(),
+					mapToScene(modified_bounding_rect_).boundingRect()
+					);
+		command = scale_command;
+	}
+	
+	if (command) {
+		emit(actionFinished(command));
+	}
+	
+	adjust();
+	
+	current_operation_square_ = QET::NoOperation;
+}
+
+/**
+ * @brief ElementPrimitiveDecorator::addHandler
+ * Add handlers for this item
+ */
+void ElementPrimitiveDecorator::addHandler()
+{
+	if (m_handler_vector.isEmpty() && scene())
+	 {
+		m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapFromScene(getResizingsPoints()));
+		 
+		 for(QetGraphicsHandlerItem *handler : m_handler_vector)
+		 { 
+			 scene()->addItem(handler);
+			 handler->setColor(Qt::darkGreen);
+			 handler->installSceneEventFilter(this);
+			 handler->setZValue(this->zValue()+1);
+		 }
+	 }
+}
+
+/**
+ * @brief ElementPrimitiveDecorator::removeHandler
+ * Remove the handlers of this item
+ */
+void ElementPrimitiveDecorator::removeHandler()
+{
+	if (!m_handler_vector.isEmpty())
+	{
+		qDeleteAll(m_handler_vector);
+		m_handler_vector.clear();
+	}
+}
+
+/**
 	Receive two rects, assuming they share a common corner and current is a \a
 	scaled version of \a original.
 	Calculate the scale ratios implied by this assumption, round them to the
@@ -597,3 +661,73 @@
 	}
 	return QET::RoundScaleRatios;
 }
+
+/**
+ * @brief ElementPrimitiveDecorator::itemChange
+ * @param change
+ * @param value
+ * @return 
+ */
+QVariant ElementPrimitiveDecorator::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+{
+	if (change == ItemSceneHasChanged)
+	{
+		if(scene()) //Item is added to scene, we also add handlers
+			addHandler();
+		else //Item is removed from scene, we also remove the handlers
+			removeHandler();
+	}
+	else if (change == ItemVisibleHasChanged)
+	{
+		bool visible = value.toBool();
+		for(QetGraphicsHandlerItem *qghi : m_handler_vector)
+			qghi->setVisible(visible);
+	}
+	else if (change == ItemZValueHasChanged && !m_handler_vector.isEmpty())
+	{
+		for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+			qghi->setZValue(this->zValue()+1);
+	}
+	
+	return QGraphicsObject::itemChange(change, value);
+}
+
+/**
+ * @brief ElementPrimitiveDecorator::sceneEventFilter
+ * @param watched
+ * @param event
+ * @return 
+ */
+bool ElementPrimitiveDecorator::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
+{
+	//Watched must be an handler
+	if(watched->type() == QetGraphicsHandlerItem::Type)
+	{
+		QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
+		
+		if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
+		{
+			m_vector_index = m_handler_vector.indexOf(qghi);
+			if (m_vector_index != -1)
+			{
+				if(event->type() == QEvent::GraphicsSceneMousePress) //Click
+				{
+					handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
+				}
+				else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
+				{
+					handlerMouseMoveEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
+				}
+				else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
+				{
+					handlerMouseReleaseEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
+				}
+			}
+		}
+	}
+	
+	return false;
+}

Modified: trunk/sources/editor/elementprimitivedecorator.h
===================================================================
--- trunk/sources/editor/elementprimitivedecorator.h	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/elementprimitivedecorator.h	2017-08-02 15:26:14 UTC (rev 5001)
@@ -20,11 +20,11 @@
 
 #include <QGraphicsObject>
 #include "qet.h"
-#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
 
 class ElementEditionCommand;
 class ElementScene;
 class CustomElementPart;
+class QetGraphicsHandlerItem;
 
 /**
 	This class represents a decorator rendered above selected items so users
@@ -42,72 +42,85 @@
 	Q_OBJECT
 	
 	public:
-	ElementPrimitiveDecorator(QGraphicsItem * = 0);
-	virtual ~ElementPrimitiveDecorator();
+		ElementPrimitiveDecorator(QGraphicsItem * = 0);
+		virtual ~ElementPrimitiveDecorator();
+		
+		enum { Type = UserType + 2200 };
+		
+			// methods
+		QRectF internalBoundingRect() const;
+		virtual QRectF boundingRect () const;
+		virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
+		virtual int type() const { return Type; }
+		void setItems(const QList<QGraphicsItem *> &);
+		void setItems(const QList<CustomElementPart *> &);
+		QList<CustomElementPart *> items() const;
+		QList<QGraphicsItem *> graphicsItems() const;
 	
-	enum { Type = UserType + 2200 };
-	
-	// methods
-	QRectF internalBoundingRect() const;
-	virtual QRectF boundingRect () const;
-	virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
-	virtual int type() const { return Type; }
-	void setItems(const QList<QGraphicsItem *> &);
-	void setItems(const QList<CustomElementPart *> &);
-	QList<CustomElementPart *> items() const;
-	QList<QGraphicsItem *> graphicsItems() const;
-	
 	public slots:
-	void adjust();
+		void adjust();
 	
 	signals:
-	void actionFinished(ElementEditionCommand *);
+		void actionFinished(ElementEditionCommand *);
 	
 	protected:
-	void hoverMoveEvent(QGraphicsSceneHoverEvent *);
-	void mousePressEvent(QGraphicsSceneMouseEvent *);
-	void mouseMoveEvent(QGraphicsSceneMouseEvent *);
-	void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
-	void keyPressEvent(QKeyEvent *);
-	void keyReleaseEvent(QKeyEvent *);
-	QPointF deltaForRoundScaling(const QRectF &, const QRectF &, qreal);
-	QPointF snapConstPointToGrid(const QPointF &) const;
-	void snapPointToGrid(QPointF &) const;
-	bool mustSnapToGrid(QGraphicsSceneMouseEvent *);
-	QET::ScalingMethod scalingMethod(QGraphicsSceneMouseEvent *);
+		void mousePressEvent(QGraphicsSceneMouseEvent *);
+		void mouseMoveEvent(QGraphicsSceneMouseEvent *);
+		void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
+		void keyPressEvent(QKeyEvent *);
+		void keyReleaseEvent(QKeyEvent *);
+		QPointF deltaForRoundScaling(const QRectF &, const QRectF &, qreal);
+		QPointF snapConstPointToGrid(const QPointF &) const;
+		void snapPointToGrid(QPointF &) const;
+		bool mustSnapToGrid(QGraphicsSceneMouseEvent *);
+		QET::ScalingMethod scalingMethod(QGraphicsSceneMouseEvent *);
+		virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+		virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
 	
 	private:
-	void init();
-	void saveOriginalBoundingRect();
-	void adjustEffectiveBoundingRect();
-	void startMovement();
-	void applyMovementToRect(int, const QPointF &, QRectF &);
-	CustomElementPart *singleItem() const;
-	void translateItems(const QPointF &);
-	void scaleItems(const QRectF &, const QRectF &);
-	QRectF getSceneBoundingRect(QGraphicsItem *) const;
-	QVector <QPointF> getResizingsPoints() const;
+		void init();
+		void saveOriginalBoundingRect();
+		void adjustEffectiveBoundingRect();
+		void startMovement();
+		void applyMovementToRect(int, const QPointF &, QRectF &);
+		CustomElementPart *singleItem() const;
+		void translateItems(const QPointF &);
+		void scaleItems(const QRectF &, const QRectF &);
+		QRectF getSceneBoundingRect(QGraphicsItem *) const;
+		QVector <QPointF> getResizingsPoints() const;
 	
-	// attributes
+		
 	private:
-	QList<CustomElementPart *> decorated_items_;
-	QRectF effective_bounding_rect_; ///< actual, effective bounding rect -- never shrinks
-	QRectF original_bounding_rect_; ///< original bounding rect
-	QRectF modified_bounding_rect_; ///< new bounding rect, after the user moved or resized items
+		void adjusteHandlerPos();
+		void handlerMousePressEvent   (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void handlerMouseMoveEvent    (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		
+		void addHandler();
+		void removeHandler();
+		
+		
+		
+		
+		QList<CustomElementPart *> decorated_items_;
+		QRectF effective_bounding_rect_; ///< actual, effective bounding rect -- never shrinks
+		QRectF original_bounding_rect_; ///< original bounding rect
+		QRectF modified_bounding_rect_; ///< new bounding rect, after the user moved or resized items
 	
-	/**
-		Index of the square leading the current operation (resizing, etc.) or -1 if no
-		operation is occurring, -2 for a move operation.
-	*/
-	int current_operation_square_;
-	int grid_step_x_;              ///< Grid horizontal step
-	int grid_step_y_;              ///< Grid horizontal step
-	QPointF first_pos_;            ///< First point involved within the current resizing operation
-	QPointF latest_pos_;           ///< Latest point involved within the current resizing operation
-	QPointF mouse_offset_;         ///< Offset between the mouse position and the point to be snapped to grid when moving selection
-	bool moving_by_keys_;          ///< Whether we are currently moving our decorated items using the arrow keys
-	QPointF keys_movement_;           ///< Movement applied to our decorated items using the arrow keys
-	QetGraphicsHandlerUtility m_handler;
+			/**
+				Index of the square leading the current operation (resizing, etc.) or -1 if no
+				operation is occurring, -2 for a move operation.
+			*/
+		int current_operation_square_;
+		int grid_step_x_;              ///< Grid horizontal step
+		int grid_step_y_;              ///< Grid horizontal step
+		QPointF first_pos_;            ///< First point involved within the current resizing operation
+		QPointF latest_pos_;           ///< Latest point involved within the current resizing operation
+		QPointF mouse_offset_;         ///< Offset between the mouse position and the point to be snapped to grid when moving selection
+		bool moving_by_keys_;          ///< Whether we are currently moving our decorated items using the arrow keys
+		QPointF keys_movement_;           ///< Movement applied to our decorated items using the arrow keys
+		QVector<QetGraphicsHandlerItem *> m_handler_vector;
+		int m_vector_index = -1;
 };
 
 #endif

Modified: trunk/sources/editor/elementscene.cpp
===================================================================
--- trunk/sources/editor/elementscene.cpp	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/elementscene.cpp	2017-08-02 15:26:14 UTC (rev 5001)
@@ -32,8 +32,9 @@
 #include "nameslist.h"
 #include "ui/elementpropertieseditorwidget.h"
 #include "eseventinterface.h"
+#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
+
 #include <algorithm>
-
 #include <QKeyEvent>
 
 /**
@@ -524,27 +525,45 @@
 }
 
 /**
-	Selectionne une liste de parties
-	@param content liste des parties a selectionner
-*/
-void ElementScene::slot_select(const ElementContent &content) {
+ * @brief ElementScene::slot_select
+ * Select the item in content, every others items in the scene are deselected
+ * @param content
+ */
+void ElementScene::slot_select(const ElementContent &content)
+{
 	blockSignals(true);
+	
+	//Befor clear selection, we must to remove the handlers items in @content,
+	//because if in @content there are a selected item, but also its handlers items,
+	//When item is deselected, the item delete its handlers items,
+	//then handlers in content doesn't exist anymore and cause segfault
+	QList<QGraphicsItem*> items_list;
+	for (QGraphicsItem *qgi : content)
+	{
+		if(qgi->type() != QetGraphicsHandlerItem::Type)
+			items_list << qgi;
+	}
 	clearSelection();
-	foreach(QGraphicsItem *qgi, content) qgi -> setSelected(true);
+
+	foreach(QGraphicsItem *qgi, items_list)
+		qgi -> setSelected(true);
+	
 	blockSignals(false);
 	emit(selectionChanged());
 }
 
 /**
-	Selectionne tout
-*/
+ * @brief ElementScene::slot_selectAll
+ * Select all items
+ */
 void ElementScene::slot_selectAll() {
 	slot_select(items());
 }
 
 /**
-	Deselectionne tout
-*/
+ * @brief ElementScene::slot_deselectAll
+ * deselect all item
+ */
 void ElementScene::slot_deselectAll() {
 	slot_select(ElementContent());
 }
@@ -811,8 +830,16 @@
 	clearSelection();
 	undoStack().clear();
 
-	foreach (QGraphicsItem *qgi, items())
+		//We don't add handlers, because it's the role of the primitive or decorator to remove it.
+	QList<QGraphicsItem*> items_list;
+	for (QGraphicsItem *qgi : items())
 	{
+		if(qgi->type() != QetGraphicsHandlerItem::Type)
+			items_list << qgi;
+	}
+	
+	for (QGraphicsItem *qgi : items_list)
+	{
 		removeItem(qgi);
 		qgiManager().release(qgi);
 	}
@@ -1065,9 +1092,16 @@
 		// should we hide the decorator?
 	QList<QGraphicsItem *> selected_items = zItems(ElementScene::Selected | ElementScene::IncludeTerminals);
     if (selected_items.size() <= 1)
+	{
 		m_decorator -> hide();
+	}
 	else
 	{
+		for(QGraphicsItem *qgi : selected_items)
+		{
+				//We recall set selected, then every primitive will remove there handler because there are several item selected
+			qgi->setSelected(true);
+		}
 		m_decorator -> setZValue(1000000);
 		m_decorator -> setPos(0, 0);
 		m_decorator -> setItems(selected_items);

Modified: trunk/sources/editor/elementscene.h
===================================================================
--- trunk/sources/editor/elementscene.h	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/elementscene.h	2017-08-02 15:26:14 UTC (rev 5001)
@@ -44,13 +44,13 @@
 	public:
 		enum Behavior { Normal, PasteArea, AddPart };
 		enum ItemOption {
-				SortByZValue = 1,
-				IncludeTerminals = 2,
-				IncludeHelperItems = 4,
-				Selected = 8,
-				NonSelected = 16,
-				SelectedOrNot = 24
-			};
+			SortByZValue = 1,
+			IncludeTerminals = 2,
+			IncludeHelperItems = 4,
+			Selected = 8,
+			NonSelected = 16,
+			SelectedOrNot = 24
+		};
 		Q_DECLARE_FLAGS(ItemOptions, ItemOption)
 	
 		// constructors, destructor
@@ -82,7 +82,7 @@
 		QETElementEditor *m_element_editor = nullptr;
 	
 			/// Variables to manage the paste area on the scene
-		QGraphicsRectItem *m_paste_area = nullptr;
+		QGraphicsRectItem *m_paste_area;
 		QRectF m_defined_paste_area;
 	
 			/// Variables to handle copy/paste with offset

Modified: trunk/sources/editor/graphicspart/abstractpartellipse.cpp
===================================================================
--- trunk/sources/editor/graphicspart/abstractpartellipse.cpp	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/abstractpartellipse.cpp	2017-08-02 15:26:14 UTC (rev 5001)
@@ -118,6 +118,7 @@
 	if (rect == m_rect) return;
 	prepareGeometryChange();
 	m_rect = rect;
+	
 	emit rectChanged();
 }
 

Modified: trunk/sources/editor/graphicspart/abstractpartellipse.h
===================================================================
--- trunk/sources/editor/graphicspart/abstractpartellipse.h	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/abstractpartellipse.h	2017-08-02 15:26:14 UTC (rev 5001)
@@ -20,6 +20,8 @@
 
 #include "customelementgraphicpart.h"
 
+class QetGraphicsHandlerItem;
+
 /**
  * @brief The AbstractPartEllipse class
  * This is the base class for all ellipse based item like ellipse, circle, arc.
@@ -61,14 +63,14 @@
 		virtual QPointF sceneTopLeft()       const;
 
 		QRectF rect() const;
-		void   setRect (const QRectF &rect);
+		virtual void   setRect (const QRectF &rect);
 		virtual bool isUseless() const;
 
 		int  startAngle() const {return m_start_angle;}
-		void setStartAngle (const int &start_angle);
+		virtual void setStartAngle (const int &start_angle);
 
 		int  spanAngle () const {return m_span_angle;}
-		void setSpanAngle (const int &span_angle);
+		virtual void setSpanAngle (const int &span_angle);
 
 	protected:
 		QList<QPointF> saved_points_;
@@ -75,6 +77,7 @@
 		QRectF m_rect;
 		qreal m_start_angle;
 		qreal m_span_angle;
+		QVector<QetGraphicsHandlerItem *> m_handler_vector;
 };
 
 #endif // ABSTRACTPARTELLIPSE_H

Modified: trunk/sources/editor/graphicspart/partarc.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partarc.cpp	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partarc.cpp	2017-08-02 15:26:14 UTC (rev 5001)
@@ -18,6 +18,8 @@
 #include "partarc.h"
 #include "QPropertyUndoCommand/qpropertyundocommand.h"
 #include "elementscene.h"
+#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
+#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
 
 
 /**
@@ -37,8 +39,10 @@
  * @brief PartArc::~PartArc
  * Destructor
  */
-PartArc::~PartArc() {
+PartArc::~PartArc()
+{
 	if(m_undo_command) delete m_undo_command;
+	removeHandler();
 }
 
 /**
@@ -82,15 +86,7 @@
 		drawShadowShape(painter);
 
 	if (isSelected())
-	{
 		drawCross(m_rect.center(), painter);
-		if (scene()->selectedItems().size() == 1) {
-			if (m_resize_mode == 3)
-				m_handler.drawHandler(painter, m_handler.pointsForArc(m_rect, m_start_angle /16, m_span_angle /16));
-			else
-				m_handler.drawHandler(painter, m_handler.pointsForRect(m_rect));
-		}
-	}
 }
 
 /**
@@ -129,16 +125,6 @@
 	m_span_angle  = qde.attribute("angle", "-1440").toDouble() * 16;
 }
 
-QRectF PartArc::boundingRect() const
-{
-	QRectF r = AbstractPartEllipse::boundingRect();
-
-	foreach(QRectF rect, m_handler.handlerRect(m_handler.pointsForRect(m_rect)))
-		r |= rect;
-
-	return r;
-}
-
 /**
  * @brief PartArc::shape
  * @return the shape of this item
@@ -153,10 +139,6 @@
 	pps.setWidth(m_hovered? penWeight()+SHADOWS_HEIGHT : penWeight());
 	shape = pps.createStroke(shape);
 
-	if (isSelected())
-		foreach(QRectF rect, m_handler.handlerRect(m_handler.pointsForRect(m_rect)))
-			shape.addRect(rect);
-
 	return shape;
 }
 
@@ -172,195 +154,324 @@
 	return (pps.createStroke(shape));
 }
 
-void PartArc::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+/**
+ * @brief PartArc::mouseReleaseEvent
+ * Handle mouse release event
+ * @param event
+ */
+void PartArc::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
 {
-	if (!isSelected())
-	{
-		CustomElementGraphicPart::hoverMoveEvent(event);
-		return;
-	}
+	if (event->button() == Qt::LeftButton && event->buttonDownPos(Qt::LeftButton) == event->pos())
+		switchResizeMode();
 
-	if (m_resize_mode == 1 || m_resize_mode == 2) {
-		int handler = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForRect(m_rect));
+	CustomElementGraphicPart::mouseReleaseEvent(event);
+}
 
-		if (handler >= 0)
+/**
+ * @brief PartArc::itemChange
+ * @param change
+ * @param value
+ * @return 
+ */
+QVariant PartArc::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+{
+	if (change == ItemSelectedHasChanged && scene())
+	{
+		if (value.toBool() == true)
 		{
-			if (handler == 0 || handler == 2 || handler == 5 || handler == 7)
-				setCursor(Qt::SizeAllCursor);
-			else if (handler == 1 || handler == 6)
-				setCursor(Qt::SizeVerCursor);
-			else if (handler == 3 || handler == 4)
-				setCursor(Qt::SizeHorCursor);
-
-			return;
+				//When item is selected, he must to be up to date whene the selection in the scene change, for display or not the handler,
+				//according to the number of selected items.
+			connect(scene(), &QGraphicsScene::selectionChanged, this, &PartArc::sceneSelectionChanged); 
+			
+			if (scene()->selectedItems().size() == 1)
+				addHandler();
 		}
-	}
-	else if (m_resize_mode == 3) {
-		if (m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForArc(m_rect, m_start_angle /16, m_span_angle /16)) >= 0) {
-			setCursor(Qt::SizeAllCursor);
-			return;
+		else
+		{
+			disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartArc::sceneSelectionChanged);
+			removeHandler();
 		}
 	}
-
-	CustomElementGraphicPart::hoverMoveEvent(event);
+	else if (change == ItemPositionHasChanged)
+	{
+		adjusteHandlerPos();
+	}
+	else if (change == ItemSceneChange)
+	{
+		if(scene())
+			disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartArc::sceneSelectionChanged);
+		
+		setSelected(false); //This is item removed from scene, then we deselect this, and so, the handlers is also removed.
+	}
+	
+	return QGraphicsItem::itemChange(change, value);
 }
 
 /**
- * @brief PartArc::mousePressEvent
- * Handle mouse press event
+ * @brief PartArc::sceneEventFilter
+ * @param watched
  * @param event
+ * @return 
  */
-void PartArc::mousePressEvent(QGraphicsSceneMouseEvent *event)
+bool PartArc::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
 {
-	if (event->button() == Qt::LeftButton)
+		//Watched must be an handler
+	if(watched->type() == QetGraphicsHandlerItem::Type)
 	{
-		setCursor(Qt::ClosedHandCursor);
-		if (isSelected())
+		QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
+		
+		if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
 		{
-				//resize rect
-			if (m_resize_mode == 1 || m_resize_mode == 2) {
-				m_handler_index = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForRect(m_rect));
-
-				if(m_handler_index >= 0 && m_handler_index <= 7) //User click on an handler
+			m_vector_index = m_handler_vector.indexOf(qghi);
+			if (m_vector_index != -1)
+			{
+				if(event->type() == QEvent::GraphicsSceneMousePress) //Click
 				{
-					m_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect));
-					m_undo_command->setText(tr("Modifier un arc"));
-					m_undo_command->enableAnimation();
-					return;
+					handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
 				}
-			}
-				//resize angle
-			if (m_resize_mode == 3) {
-				m_handler_index = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForArc(m_rect, m_start_angle /16, m_span_angle /16));
-				if (m_handler_index == 0) {
-					m_span_point = m_handler.pointsForArc(m_rect, m_start_angle /16, m_span_angle /16).at(1);
-
-					m_undo_command = new QPropertyUndoCommand(this, "startAngle", QVariant(m_start_angle));
-					m_undo_command->setText(tr("Modifier un arc"));
-					m_undo_command->enableAnimation();
-
-					m_undo_command2 = new QPropertyUndoCommand(this, "spanAngle", QVariant(m_span_angle), m_undo_command);
-					m_undo_command2->setText(tr("Modifier un arc"));
-					m_undo_command2->enableAnimation();
-
-					return;
+				else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
+				{
+					handlerMouseMoveEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
 				}
-				else if (m_handler_index == 1) {
-					m_undo_command = new QPropertyUndoCommand(this, "spanAngle", QVariant(m_span_angle));
-					m_undo_command->setText(tr("Modifier un arc"));
-					m_undo_command->enableAnimation();
-
-					return;
+				else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
+				{
+					handlerMouseReleaseEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
 				}
 			}
-
 		}
 	}
+	
+	return false;
+}
 
-	CustomElementGraphicPart::mousePressEvent(event);
+/**
+ * @brief PartArc::switchResizeMode
+ */
+void PartArc::switchResizeMode()
+{	
+	if (m_resize_mode == 1)
+	{
+		m_resize_mode = 2;
+		for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+			qghi->setColor(Qt::darkGreen);
+	}
+	else if (m_resize_mode == 2)
+	{		
+		m_resize_mode = 3;
+			
+			//From rect mode to angle mode, then numbers of handlers change
+		removeHandler();
+		addHandler();
+		
+		for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+			qghi->setColor(Qt::magenta);
+	}
+	else
+	{		
+		m_resize_mode = 1;
+		
+			//From angle mode to rect mode, then numbers of handlers change
+		removeHandler();
+		addHandler();
+		
+		for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+			qghi->setColor(Qt::blue);
+	}
 }
 
 /**
- * @brief PartArc::mouseMoveEvent
- * Handle mouse move event
+ * @brief PartArc::adjusteHandlerPos
+ */
+void PartArc::adjusteHandlerPos()
+{
+	if (m_handler_vector.isEmpty())
+		return;
+	
+	QVector <QPointF> points_vector;
+	
+	if(m_resize_mode == 3)
+		points_vector = QetGraphicsHandlerUtility::pointsForArc(m_rect, m_start_angle/16, m_span_angle/16);
+	else
+		points_vector = QetGraphicsHandlerUtility::pointsForRect(m_rect);
+		
+	
+	if (m_handler_vector.size() == points_vector.size())
+	{
+		points_vector = mapToScene(points_vector);
+		for (int i = 0 ; i < points_vector.size() ; ++i)
+			m_handler_vector.at(i)->setPos(points_vector.at(i));
+	}	
+}
+
+/**
+ * @brief PartArc::handlerMousePressEvent
+ * @param qghi
  * @param event
  */
-void PartArc::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+void PartArc::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
 {
-	if (m_resize_mode == 1 || m_resize_mode == 2) {
-		if (m_handler_index >= 0 && m_handler_index <= 7) {
-			QPointF pos_ = event->modifiers() == Qt::ControlModifier ? event->pos() : mapFromScene(elementScene()->snapToGrid(event->scenePos()));
-			prepareGeometryChange();
+	Q_UNUSED(qghi);
+	Q_UNUSED(event);
+	
+	if (m_resize_mode == 3) //Resize angle
+	{
+		if (m_vector_index == 0)
+		{
+			m_span_point = QetGraphicsHandlerUtility::pointsForArc(m_rect, m_start_angle /16, m_span_angle /16).at(1);
 
-			if (m_resize_mode == 1)
-				setRect(m_handler.rectForPosAtIndex(m_rect, pos_, m_handler_index));
-			else
-				setRect(m_handler.mirrorRectForPosAtIndex(m_rect, pos_, m_handler_index));
+			m_undo_command = new QPropertyUndoCommand(this, "startAngle", QVariant(m_start_angle));
+			m_undo_command->setText(tr("Modifier un arc"));
+			m_undo_command->enableAnimation();
 
-			return;
+			m_undo_command2 = new QPropertyUndoCommand(this, "spanAngle", QVariant(m_span_angle), m_undo_command);
+			m_undo_command2->setText(tr("Modifier un arc"));
+			m_undo_command2->enableAnimation();
 		}
+		else if (m_vector_index == 1)
+		{
+			m_undo_command = new QPropertyUndoCommand(this, "spanAngle", QVariant(m_span_angle));
+			m_undo_command->setText(tr("Modifier un arc"));
+			m_undo_command->enableAnimation();
+		}
 	}
-	else if (m_resize_mode == 3) {
-		if (m_handler_index == 0 || m_handler_index == 1) {
-			QLineF line(m_rect.center(), event->pos());
-			prepareGeometryChange();
+	else //resize rect
+	{
+		m_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect));
+		m_undo_command->setText(tr("Modifier un arc"));
+		m_undo_command->enableAnimation();
+	}
+}
 
-			if (m_handler_index == 0) {
-				setStartAngle(line.angle()*16);
-				setSpanAngle(line.angleTo(QLineF(m_rect.center(), m_span_point))*16);
-			}
-			else if (m_handler_index == 1) {
-				QLineF line2(m_rect.center(), m_handler.pointsForArc(m_rect, m_start_angle/16, m_span_angle/16).at(0));
-				setSpanAngle (line2.angleTo(line)*16);
-			}
+/**
+ * @brief PartArc::handlerMouseMoveEvent
+ * @param qghi
+ * @param event
+ */
+void PartArc::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+	Q_UNUSED(qghi);
+	
+	QPointF new_pos = event->scenePos();
+	if (event->modifiers() != Qt::ControlModifier)
+		new_pos = elementScene()->snapToGrid(event->scenePos());
+	new_pos = mapFromScene(new_pos);
+	
+	if (m_resize_mode == 1)
+		setRect(QetGraphicsHandlerUtility::rectForPosAtIndex(m_rect, new_pos, m_vector_index));
+	else if (m_resize_mode == 2)
+		setRect(QetGraphicsHandlerUtility::mirrorRectForPosAtIndex(m_rect, new_pos, m_vector_index));
+	else
+	{
+		QLineF line(m_rect.center(), mapFromItem(qghi, event->pos()));
+		prepareGeometryChange();
 
-			return;
+		if (m_vector_index == 0) {
+			setStartAngle(line.angle()*16);
+			setSpanAngle(line.angleTo(QLineF(m_rect.center(), m_span_point))*16);
 		}
+		else if (m_vector_index == 1) {
+			QLineF line2(m_rect.center(), QetGraphicsHandlerUtility::pointsForArc(m_rect, m_start_angle/16, m_span_angle/16).at(0));
+			setSpanAngle (line2.angleTo(line)*16);
+		}
 	}
-
-	CustomElementGraphicPart::mouseMoveEvent(event);
 }
 
 /**
- * @brief PartArc::mouseReleaseEvent
- * Handle mouse release event
+ * @brief PartArc::handlerMouseReleaseEvent
+ * @param qghi
  * @param event
  */
-void PartArc::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+void PartArc::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
 {
-	if (event->button() == Qt::LeftButton) {
-		setCursor(Qt::OpenHandCursor);
-		if (event->buttonDownPos(Qt::LeftButton) == event->pos())
-			switchResizeMode();
-	}
-
-	if (m_resize_mode == 1 || m_resize_mode == 2) {
-		if (m_handler_index >= 0 && m_handler_index <= 7) {
-			if (!m_rect.isValid())
-				m_rect = m_rect.normalized();
-
-			m_undo_command->setNewValue(QVariant(m_rect));
-			elementScene()->undoStack().push(m_undo_command);
-			m_undo_command = nullptr;
-			m_handler_index = -1;
-			return;
-		}
-	}
-	else if (m_resize_mode == 3) {
-		if (m_handler_index == 0) {
+	Q_UNUSED(qghi);
+	Q_UNUSED(event);
+	
+	if (m_resize_mode == 3)
+	{
+		if (m_vector_index == 0)
+		{
 			m_undo_command->setNewValue(QVariant(m_start_angle));
 			m_undo_command2->setNewValue(QVariant(m_span_angle));
 			elementScene()->undoStack().push(m_undo_command);
 			m_undo_command = nullptr;
 			m_undo_command2 = nullptr;
-			m_handler_index = -1;
-			return;
+			m_vector_index = -1;
 		}
-		else if (m_handler_index == 1) {
+		else if (m_vector_index == 1)
+		{
 			m_undo_command->setNewValue(QVariant(m_span_angle));
 			elementScene()->undoStack().push(m_undo_command);
 			m_undo_command = nullptr;
-			m_handler_index = -1;
-			return;
+			m_vector_index = -1;
 		}
 	}
+	else
+	{
+		if (!m_rect.isValid())
+			m_rect = m_rect.normalized();
 
-	CustomElementGraphicPart::mouseReleaseEvent(event);
+		m_undo_command->setNewValue(QVariant(m_rect));
+		elementScene()->undoStack().push(m_undo_command);
+		m_undo_command = nullptr;
+		m_vector_index = -1;
+	}
 }
 
-void PartArc::switchResizeMode()
+/**
+ * @brief PartArc::sceneSelectionChanged
+ * When the scene selection change, if there are several primitive selected, we remove the handler of this item
+ */
+void PartArc::sceneSelectionChanged()
 {
-	if (m_resize_mode == 1) {
-		m_resize_mode = 2;
-		m_handler.setOuterColor(Qt::darkGreen);
+	if (this->isSelected() && scene()->selectedItems().size() == 1)
+		addHandler();
+	else
+		removeHandler();
+}
+
+/**
+ * @brief PartArc::addHandler
+ * Add handlers for this item
+ */
+void PartArc::addHandler()
+{
+	if (m_handler_vector.isEmpty() && scene())
+	{
+		if(m_resize_mode == 3)
+		{
+			m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(QetGraphicsHandlerUtility::pointsForArc(m_rect, m_start_angle/16, m_span_angle/16)));
+		}
+		else
+			m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(QetGraphicsHandlerUtility::pointsForRect(m_rect)));
+		
+		for(QetGraphicsHandlerItem *handler : m_handler_vector)
+		{
+			QColor color = Qt::blue;
+			if (m_resize_mode == 2)
+				color = Qt::darkGreen;
+			else if (m_resize_mode == 3)
+				color = Qt::magenta;
+			
+			handler->setColor(color);
+			scene()->addItem(handler);
+			handler->installSceneEventFilter(this);
+			handler->setZValue(this->zValue()+1);
+		}
 	}
-	else if (m_resize_mode == 2 ) {
-		m_resize_mode = 3;
-		m_handler.setOuterColor(Qt::magenta);
+}
+
+/**
+ * @brief PartArc::removeHandler
+ * Remove the handlers of this item
+ */
+void PartArc::removeHandler()
+{
+	if (!m_handler_vector.isEmpty())
+	{
+		qDeleteAll(m_handler_vector);
+		m_handler_vector.clear();
 	}
-	else {
-		m_resize_mode = 1;
-		m_handler.setOuterColor(Qt::blue);
-	}
-	update();
 }

Modified: trunk/sources/editor/graphicspart/partarc.h
===================================================================
--- trunk/sources/editor/graphicspart/partarc.h	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partarc.h	2017-08-02 15:26:14 UTC (rev 5001)
@@ -19,9 +19,9 @@
 #define PART_ARC_H
 
 #include "abstractpartellipse.h"
-#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
 
 class QPropertyUndoCommand;
+class QetGraphicsHandlerItem;
 
 /**
  * @brief The PartArc class
@@ -54,25 +54,34 @@
 		virtual const QDomElement toXml   (QDomDocument &) const;
 		virtual void              fromXml (const QDomElement &);
 
-		virtual QRectF boundingRect()  const;
 		virtual QPainterPath shape() const;
 		virtual QPainterPath shadowShape() const;
+		virtual void setRect(const QRectF &rect) {AbstractPartEllipse::setRect(rect); adjusteHandlerPos();}
+		virtual void setStartAngle(const int &start_angle) {AbstractPartEllipse::setStartAngle(start_angle); adjusteHandlerPos();}
+		virtual void setSpanAngle(const int &span_angle) {AbstractPartEllipse::setSpanAngle(span_angle); adjusteHandlerPos();}
 
 	protected:
-		virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
-		virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
-		virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
 		virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+		virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+		virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
 
 	private:
 		void switchResizeMode();
+		void adjusteHandlerPos();
+		void handlerMousePressEvent   (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void handlerMouseMoveEvent    (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void sceneSelectionChanged ();
+		
+		void addHandler();
+		void removeHandler();
 
 	private:
-		QetGraphicsHandlerUtility m_handler = 10;
-		int m_handler_index = -1;
 		QPropertyUndoCommand *m_undo_command = nullptr;
 		QPropertyUndoCommand *m_undo_command2 = nullptr;
-		int m_resize_mode = 1;
+		int m_resize_mode = 1,
+			m_vector_index = -1;
 		QPointF m_span_point;
+		QVector<QetGraphicsHandlerItem *> m_handler_vector;
 };
 #endif

Modified: trunk/sources/editor/graphicspart/partellipse.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partellipse.cpp	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partellipse.cpp	2017-08-02 15:26:14 UTC (rev 5001)
@@ -18,6 +18,8 @@
 #include "partellipse.h"
 #include "QPropertyUndoCommand/qpropertyundocommand.h"
 #include "elementscene.h"
+#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
+#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
 
 /**
  * @brief PartEllipse::PartEllipse
@@ -27,8 +29,6 @@
  */
 PartEllipse::PartEllipse(QETElementEditor *editor, QGraphicsItem *parent) :
 	AbstractPartEllipse(editor, parent),
-	m_handler(10),
-	m_handler_index(-1),
 	m_undo_command(nullptr)
 {}
 
@@ -36,8 +36,10 @@
  * @brief PartEllipse::~PartEllipse
  * Destructor
  */
-PartEllipse::~PartEllipse() {
+PartEllipse::~PartEllipse()
+{
 	if(m_undo_command) delete m_undo_command;
+	removeHandler();
 }
 
 /**
@@ -65,11 +67,7 @@
 		drawShadowShape(painter);
 
 	if (isSelected())
-	{
 		drawCross(m_rect.center(), painter);
-		if (scene()->selectedItems().size() == 1)
-			m_handler.drawHandler(painter, m_handler.pointsForRect(m_rect));
-	}
 }
 
 /**
@@ -125,16 +123,6 @@
 					QSizeF(width, height));
 }
 
-QRectF PartEllipse::boundingRect() const
-{
-	QRectF r = AbstractPartEllipse::boundingRect();
-
-	foreach(QRectF rect, m_handler.handlerRect(m_handler.pointsForRect(m_rect)))
-		r |= rect;
-
-	return r;
-}
-
 /**
  * @brief PartEllipse::shape
  * @return the shape of this item
@@ -148,10 +136,6 @@
 	pps.setWidth(m_hovered? penWeight()+SHADOWS_HEIGHT : penWeight());
 	shape = pps.createStroke(shape);
 
-	if (isSelected())
-		foreach(QRectF rect, m_handler.handlerRect(m_handler.pointsForRect(m_rect)))
-			shape.addRect(rect);
-
 	return shape;
 }
 
@@ -166,113 +150,232 @@
 	return (pps.createStroke(shape));
 }
 
-void PartEllipse::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+/**
+ * @brief PartEllipse::mouseReleaseEvent
+ * Handle mouse release event
+ * @param event
+ */
+void PartEllipse::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
 {
-	if (!isSelected())
+	if (event->button() == Qt::LeftButton && event->buttonDownPos(Qt::LeftButton) == event->pos())
+		switchResizeMode();
+	
+	CustomElementGraphicPart::mouseReleaseEvent(event);
+}
+
+/**
+ * @brief PartEllipse::itemChange
+ * @param change
+ * @param value
+ * @return 
+ */
+QVariant PartEllipse::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+{
+	if (change == ItemSelectedHasChanged && scene())
 	{
-		CustomElementGraphicPart::hoverMoveEvent(event);
-		return;
+		if (value.toBool() == true)
+		{
+				//When item is selected, he must to be up to date whene the selection in the scene change, for display or not the handler,
+				//according to the number of selected items.
+			connect(scene(), &QGraphicsScene::selectionChanged, this, &PartEllipse::sceneSelectionChanged); 
+			
+			if (scene()->selectedItems().size() == 1)
+				addHandler();
+		}
+		else
+		{
+			disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartEllipse::sceneSelectionChanged);
+			removeHandler();
+		}
 	}
-
-	int handler = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForRect(m_rect));
-
-	if (handler >= 0)
+	else if (change == ItemPositionHasChanged)
 	{
-		if (handler == 0 || handler == 2 || handler == 5 || handler == 7)
-			setCursor(Qt::SizeAllCursor);
-		else if (handler == 1 || handler == 6)
-			setCursor(Qt::SizeVerCursor);
-		else if (handler == 3 || handler == 4)
-			setCursor(Qt::SizeHorCursor);
+		adjusteHandlerPos();
 	}
-	else
-		CustomElementGraphicPart::hoverMoveEvent(event);
+	else if (change == ItemSceneChange)
+	{
+		if(scene())
+			disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartEllipse::sceneSelectionChanged);
+		
+		setSelected(false); //This item is removed from scene, then we deselect this, and so, the handlers is also removed.
+	}
+	
+	return QGraphicsItem::itemChange(change, value);
 }
 
 /**
- * @brief PartEllipse::mousePressEvent
- * Handle mouse press event
+ * @brief PartEllipse::sceneEventFilter
+ * @param watched
  * @param event
+ * @return 
  */
-void PartEllipse::mousePressEvent(QGraphicsSceneMouseEvent *event)
+bool PartEllipse::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
 {
-	if (event->button() == Qt::LeftButton)
+		//Watched must be an handler
+	if(watched->type() == QetGraphicsHandlerItem::Type)
 	{
-		setCursor(Qt::ClosedHandCursor);
-		if (isSelected())
+		QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
+		
+		if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
 		{
-			m_handler_index = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForRect(m_rect));
-
-			if(m_handler_index >= 0 && m_handler_index <= 7) //User click on an handler
+			m_vector_index = m_handler_vector.indexOf(qghi);
+			if (m_vector_index != -1)
 			{
-				m_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect));
-				m_undo_command->setText(tr("Modifier une ellipse"));
-				m_undo_command->enableAnimation();
-				return;
+				if(event->type() == QEvent::GraphicsSceneMousePress) //Click
+				{
+					handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
+				}
+				else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
+				{
+					handlerMouseMoveEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
+				}
+				else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
+				{
+					handlerMouseReleaseEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
+				}
 			}
 		}
 	}
+	
+	return false;
+}
 
-	CustomElementGraphicPart::mousePressEvent(event);
+void PartEllipse::switchResizeMode()
+{
+	if (m_resize_mode == 1)
+	{
+		m_resize_mode = 2;
+		for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+			qghi->setColor(Qt::darkGreen);
+	}
+	else
+	{
+		m_resize_mode = 1;
+		for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+			qghi->setColor(Qt::blue);
+	}
 }
 
 /**
- * @brief PartEllipse::mouseMoveEvent
- * Handle mouse move event
- * @param event
+ * @brief PartEllipse::adjusteHandlerPos
  */
-void PartEllipse::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
-{		
-	if(m_handler_index >= 0 && m_handler_index <= 7)
+void PartEllipse::adjusteHandlerPos()
+{
+	if (m_handler_vector.isEmpty())
+		return;
+	
+	QVector <QPointF> points_vector = QetGraphicsHandlerUtility::pointsForRect(m_rect);
+	
+	if (m_handler_vector.size() == points_vector.size())
 	{
-		QPointF pos_ = event->modifiers() == Qt::ControlModifier ? event->pos() : mapFromScene(elementScene()->snapToGrid(event->scenePos()));
-		prepareGeometryChange();
+		points_vector = mapToScene(points_vector);
+		for (int i = 0 ; i < points_vector.size() ; ++i)
+			m_handler_vector.at(i)->setPos(points_vector.at(i));
+	}
+}
 
-		if (m_resize_mode == 1)
-			setRect(m_handler.rectForPosAtIndex(m_rect, pos_, m_handler_index));
-		else
-			setRect(m_handler.mirrorRectForPosAtIndex(m_rect, pos_, m_handler_index));
-	}
+/**
+ * @brief PartEllipse::handlerMousePressEvent
+ * @param qghi
+ * @param event
+ */
+void PartEllipse::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+	Q_UNUSED(qghi);
+	Q_UNUSED(event);
+
+	m_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect));
+	m_undo_command->setText(tr("Modifier un rectangle"));
+	m_undo_command->enableAnimation();
+	return;	
+}
+
+/**
+ * @brief PartEllipse::handlerMouseMoveEvent
+ * @param qghi
+ * @param event
+ */
+void PartEllipse::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+	Q_UNUSED(qghi);
+	
+	QPointF new_pos = event->scenePos();
+	if (event->modifiers() != Qt::ControlModifier)
+		new_pos = elementScene()->snapToGrid(event->scenePos());
+	new_pos = mapFromScene(new_pos);
+	
+	if (m_resize_mode == 1)
+		setRect(QetGraphicsHandlerUtility::rectForPosAtIndex(m_rect, new_pos, m_vector_index));
 	else
-		CustomElementGraphicPart::mouseMoveEvent(event);
+		setRect(QetGraphicsHandlerUtility::mirrorRectForPosAtIndex(m_rect, new_pos, m_vector_index));
+	
+	adjusteHandlerPos();
 }
 
 /**
- * @brief PartEllipse::mouseReleaseEvent
- * Handle mouse release event
+ * @brief PartEllipse::handlerMouseReleaseEvent
+ * @param qghi
  * @param event
  */
-void PartEllipse::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+void PartEllipse::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
 {
-	if (event->button() == Qt::LeftButton) {
-		setCursor(Qt::OpenHandCursor);
-		if (event->buttonDownPos(Qt::LeftButton) == event->pos())
-			switchResizeMode();
-	}
+	Q_UNUSED(qghi);
+	Q_UNUSED(event);
+	
+	m_undo_command->setNewValue(QVariant(m_rect));
+	elementScene()->undoStack().push(m_undo_command);
+	m_undo_command = nullptr;
+	m_vector_index = -1;
+}
 
-	if (m_handler_index >= 0 && m_handler_index <= 7)
-	{
-		if (!m_rect.isValid())
-			m_rect = m_rect.normalized();
+/**
+ * @brief PartEllipse::sceneSelectionChanged
+ * When the scene selection change, if there are several primitive selected, we remove the handler of this item
+ */
+void PartEllipse::sceneSelectionChanged()
+{
+	if (this->isSelected() && scene()->selectedItems().size() == 1)
+		addHandler();
+	else
+		removeHandler();
+}
 
-		m_undo_command->setNewValue(QVariant(m_rect));
-		elementScene()->undoStack().push(m_undo_command);
-		m_undo_command = nullptr;
-		m_handler_index = -1;
+/**
+ * @brief PartEllipse::addHandler
+ * Add handlers for this item
+ */
+void PartEllipse::addHandler()
+{
+	if (m_handler_vector.isEmpty() && scene())
+	{		
+		m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(QetGraphicsHandlerUtility::pointsForRect(m_rect)));
+		
+		for(QetGraphicsHandlerItem *handler : m_handler_vector)
+		{
+			QColor color = Qt::blue;
+			if (m_resize_mode == 2)
+				color = Qt::darkGreen;
+			
+			handler->setColor(color);
+			scene()->addItem(handler);
+			handler->installSceneEventFilter(this);
+			handler->setZValue(this->zValue()+1);
+		}
 	}
-	else
-		CustomElementGraphicPart::mouseReleaseEvent(event);
 }
 
-void PartEllipse::switchResizeMode()
+/**
+ * @brief PartEllipse::removeHandler
+ * Remove the handlers of this item
+ */
+void PartEllipse::removeHandler()
 {
-	if (m_resize_mode == 1) {
-		m_resize_mode = 2;
-		m_handler.setOuterColor(Qt::darkGreen);
+	if (!m_handler_vector.isEmpty())
+	{
+		qDeleteAll(m_handler_vector);
+		m_handler_vector.clear();
 	}
-	else {
-		m_resize_mode = 1;
-		m_handler.setOuterColor(Qt::blue);
-	}
-	update();
 }

Modified: trunk/sources/editor/graphicspart/partellipse.h
===================================================================
--- trunk/sources/editor/graphicspart/partellipse.h	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partellipse.h	2017-08-02 15:26:14 UTC (rev 5001)
@@ -19,7 +19,6 @@
 #define PART_ELLIPSE_H
 
 #include "abstractpartellipse.h"
-#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
 
 class QPropertyUndoCommand;
 
@@ -55,24 +54,29 @@
 		virtual QString xmlName() const { return(QString("ellipse")); }
 		virtual const QDomElement toXml   (QDomDocument &) const;
 		virtual void              fromXml (const QDomElement &);
-
-		virtual QRectF boundingRect()  const;
 		virtual QPainterPath shape() const;
 		virtual QPainterPath shadowShape() const;
+		virtual void setRect(const QRectF &rect) {AbstractPartEllipse::setRect(rect); adjusteHandlerPos();}
 
 	protected:
-		virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
-		virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
-		virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
 		virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+		virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+		virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
 
 	private:
 		void switchResizeMode();
+		void adjusteHandlerPos();
+		void handlerMousePressEvent   (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void handlerMouseMoveEvent    (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void sceneSelectionChanged ();
+		
+		void addHandler();
+		void removeHandler();
 
 	private:
-		QetGraphicsHandlerUtility m_handler;
-		int m_handler_index;
 		QPropertyUndoCommand *m_undo_command;
-		int m_resize_mode = 1;
+		int m_resize_mode = 1,
+			m_vector_index = -1;
 };
 #endif

Modified: trunk/sources/editor/graphicspart/partline.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partline.cpp	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partline.cpp	2017-08-02 15:26:14 UTC (rev 5001)
@@ -19,6 +19,7 @@
 #include <cmath>
 #include "elementscene.h"
 #include "QPropertyUndoCommand/qpropertyundocommand.h"
+#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
 
 
 /**
@@ -33,14 +34,16 @@
 	first_length(1.5),
 	second_end(Qet::None),
 	second_length(1.5),
-	m_handler(10),
-	m_handler_index(-1),
 	m_undo_command(nullptr)
 {}
 
 /// Destructeur
-PartLine::~PartLine() {
-	if(m_undo_command) delete m_undo_command;
+PartLine::~PartLine()
+{
+	if(m_undo_command)
+		delete m_undo_command;
+	
+	removeHandler();
 }
 
 /**
@@ -90,9 +93,6 @@
 	if (m_hovered)
 		drawShadowShape(painter);
 
-	if (isSelected() && scene()->selectedItems().size() == 1)
-		m_handler.drawHandler(painter, m_handler.pointsForLine(m_line));
-
 	painter->restore();
 }
 
@@ -140,72 +140,209 @@
 }
 
 /**
- * @brief PartLine::mousePressEvent
- * Handle mouse press event
+ * @brief PartLine::itemChange
+ * @param change
+ * @param value
+ * @return 
+ */
+QVariant PartLine::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+{
+	if (change == ItemSelectedHasChanged && scene())
+	{
+		if (value.toBool() == true)
+		{
+				//When item is selected, he must to be up to date whene the selection in the scene change, for display or not the handler,
+				//according to the number of selected items.
+			connect(scene(), &QGraphicsScene::selectionChanged, this, &PartLine::sceneSelectionChanged); 
+			
+			if (scene()->selectedItems().size() == 1)
+				addHandler();
+		}
+		else
+		{
+			disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartLine::sceneSelectionChanged);
+			removeHandler();
+		}
+	}
+	else if (change == ItemPositionHasChanged)
+	{
+		adjusteHandlerPos();
+	}
+	else if (change == ItemSceneChange)
+	{
+		if(scene())
+			disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartLine::sceneSelectionChanged);
+		
+		setSelected(false); //This is item removed from scene, then we deselect this, and so, the handlers is also removed.
+	}
+	
+	return QGraphicsItem::itemChange(change, value);
+}
+
+/**
+ * @brief PartLine::sceneEventFilter
+ * @param watched
  * @param event
+ * @return 
  */
-void PartLine::mousePressEvent(QGraphicsSceneMouseEvent *event)
+bool PartLine::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
 {
-	if(event->button() == Qt::LeftButton)
+	//Watched must be an handler
+	if(watched->type() == QetGraphicsHandlerItem::Type)
 	{
-		setCursor(Qt::ClosedHandCursor);
-
-		if (isSelected())
+		QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
+		
+		if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
 		{
-			m_handler_index = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForLine(m_line));
-
-			if(m_handler_index >= 0 && m_handler_index <= 1) //User click on an handler
+			m_vector_index = m_handler_vector.indexOf(qghi);
+			if (m_vector_index != -1)
 			{
-				m_undo_command = new QPropertyUndoCommand(this, "line", QVariant(m_line));
-				m_undo_command->setText(tr("Modifier une ligne"));
-				m_undo_command->enableAnimation();
-				return;
+				if(event->type() == QEvent::GraphicsSceneMousePress) //Click
+				{
+					handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
+				}
+				else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
+				{
+					handlerMouseMoveEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
+				}
+				else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
+				{
+					handlerMouseReleaseEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
+				}
 			}
 		}
 	}
+	
+	return false;
+}
 
-	CustomElementGraphicPart::mousePressEvent(event);
+/**
+ * @brief PartLine::adjusteHandlerPos
+ * Adjust the position of the handler item
+ */
+void PartLine::adjusteHandlerPos()
+{
+	if(m_handler_vector.isEmpty())
+		return;
+	
+	QVector<QPointF> points_vector;
+	points_vector << m_line.p1() << m_line.p2();
+	
+	if (m_handler_vector.size() == points_vector.size())
+	{
+		points_vector = mapToScene(points_vector);
+		for (int i = 0 ; i < points_vector.size() ; ++i)
+			m_handler_vector.at(i)->setPos(points_vector.at(i));
+	}
 }
 
 /**
- * @brief PartLine::mouseMoveEvent
- * Handle pouse move event
+ * @brief PartLine::handlerMousePressEvent
+ * @param qghi
  * @param event
  */
-void PartLine::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+void PartLine::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
 {
-	if(m_handler_index >= 0 && m_handler_index <= 1)
-	{
-		QPointF pos_ = event->modifiers() == Qt::ControlModifier ? event->pos() : mapFromScene(elementScene()->snapToGrid(event->scenePos()));
-		prepareGeometryChange();
-		setLine(m_handler.lineForPosAtIndex(m_line, pos_, m_handler_index));
-	}
+	Q_UNUSED(qghi);
+	Q_UNUSED(event);
+	
+	m_undo_command = new QPropertyUndoCommand(this, "line", QVariant(m_line));
+	m_undo_command->setText(tr("Modifier une ligne"));
+	m_undo_command->enableAnimation();
+	return;
+}
+
+/**
+ * @brief PartLine::handlerMouseMoveEvent
+ * @param qghi
+ * @param event
+ */
+void PartLine::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+	Q_UNUSED(qghi);
+	
+	QPointF new_pos = event->scenePos();
+	if (event->modifiers() != Qt::ControlModifier)
+		new_pos = elementScene()->snapToGrid(event->scenePos());
+	new_pos = mapFromScene(new_pos);
+	
+	prepareGeometryChange();
+	if (m_vector_index == 0)
+		m_line.setP1(new_pos);
 	else
-		CustomElementGraphicPart::mouseMoveEvent(event);
+		m_line.setP2(new_pos);
+	
+	adjusteHandlerPos();
 }
 
 /**
- * @brief PartLine::mouseReleaseEvent
- * Handle mouse release event
+ * @brief PartLine::handlerMouseReleaseEvent
+ * @param qghi
  * @param event
  */
-void PartLine::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+void PartLine::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
 {
-	if (event->button() == Qt::LeftButton)
-		setCursor(Qt::OpenHandCursor);
+	Q_UNUSED(qghi);
+	Q_UNUSED(event);
+	
+	m_undo_command->setNewValue(QVariant(m_line));
+	elementScene()->undoStack().push(m_undo_command);
+	m_undo_command = nullptr;
+	m_vector_index = -1;
+}
 
-	if (m_handler_index >= 0 && m_handler_index <= 1)
+/**
+ * @brief PartLine::sceneSelectionChanged
+ * When the scene selection change, if there are several primitive selected, we remove the handler of this item
+ */
+void PartLine::sceneSelectionChanged()
+{
+	if (this->isSelected() && scene()->selectedItems().size() == 1)
+		addHandler();
+	else
+		removeHandler();
+}
+
+/**
+ * @brief PartLine::addHandler
+ * Add handlers for this item
+ */
+void PartLine::addHandler()
+{
+	if (m_handler_vector.isEmpty() && scene())
 	{
-		m_undo_command->setNewValue(QVariant(m_line));
-		elementScene()->undoStack().push(m_undo_command);
-		m_undo_command = nullptr;
-		m_handler_index = -1;
+		QVector<QPointF> points_vector;
+		points_vector << m_line.p1() << m_line.p2();
+		
+		m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(points_vector));
+		
+		for(QetGraphicsHandlerItem *handler : m_handler_vector)
+		{
+			handler->setColor(Qt::blue);
+			scene()->addItem(handler);
+			handler->installSceneEventFilter(this);
+			handler->setZValue(this->zValue()+1);
+		}
 	}
-	else
-		CustomElementGraphicPart::mouseReleaseEvent(event);
 }
 
 /**
+ * @brief PartLine::removeHandler
+ * Remove the handlers of this item
+ */
+void PartLine::removeHandler()
+{
+	if (!m_handler_vector.isEmpty())
+	{
+		qDeleteAll(m_handler_vector);
+		m_handler_vector.clear();
+	}
+}
+
+/**
  * @brief PartLine::sceneP1
  * @return the point p1 in scene coordinate
  */
@@ -243,10 +380,6 @@
 	pps.setWidth(m_hovered? penWeight()+SHADOWS_HEIGHT : penWeight());
 	shape = pps.createStroke(shape);
 
-	if (isSelected())
-		foreach(QRectF rect, m_handler.handlerRect(m_handler.pointsForLine(m_line)))
-			shape.addRect(rect);
-
 	return shape;
 }
 
@@ -402,9 +535,6 @@
 	bound = bound.normalized();
 	bound.adjust(-adjust, -adjust, adjust, adjust);
 
-	foreach(QRectF rect, m_handler.handlerRect(m_handler.pointsForLine(m_line)))
-		bound |= rect;
-
 	return bound;
 }
 
@@ -496,6 +626,7 @@
 	if (m_line == line) return;
 	prepareGeometryChange();
 	m_line = line;
+	adjusteHandlerPos();
 	emit lineChanged();
 }
 
@@ -533,20 +664,6 @@
 	emit secondEndLengthChanged();
 }
 
-void PartLine::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
-{
-	if (!isSelected())
-	{
-		CustomElementGraphicPart::hoverMoveEvent(event);
-		return;
-	}
-
-	if (m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForLine(m_line)) >= 0)
-		setCursor(Qt::SizeAllCursor);
-	else
-		CustomElementGraphicPart::hoverMoveEvent(event);
-}
-
 /**
  * @brief PartLine::path
  * @return this line has a QPainterPath.

Modified: trunk/sources/editor/graphicspart/partline.h
===================================================================
--- trunk/sources/editor/graphicspart/partline.h	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partline.h	2017-08-02 15:26:14 UTC (rev 5001)
@@ -20,9 +20,9 @@
 
 #include "customelementgraphicpart.h"
 #include "qet.h"
-#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
 
 class QPropertyUndoCommand;
+class QetGraphicsHandlerItem;
 
 /**
 	This class represents a line primitive which may be used to compose the
@@ -96,19 +96,26 @@
 		void setSecondEndLength(const qreal &l);
 
 	protected:
-		virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
-		virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
-		virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
-		virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
-	
+		virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+		virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
+		
 	private:
+		void adjusteHandlerPos();
+		void handlerMousePressEvent   (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void handlerMouseMoveEvent    (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void sceneSelectionChanged ();
+		
+		void addHandler();
+		void removeHandler();
+		
 		QPainterPath path() const;
-
 		QList<QPointF> fourShapePoints() const;
 		QRectF firstEndCircleRect() const;
 		QRectF secondEndCircleRect() const;
 		void debugPaint(QPainter *);
 
+		/*****************/
 		Qet::EndType first_end;
 		qreal        first_length;
 
@@ -116,8 +123,8 @@
 		qreal        second_length;
 		QList<QPointF> saved_points_;
 		QLineF m_line;
-		QetGraphicsHandlerUtility m_handler;
-		int m_handler_index;
+		int m_vector_index = -1;
 		QPropertyUndoCommand *m_undo_command;
+		QVector<QetGraphicsHandlerItem *> m_handler_vector;
 };
 #endif

Modified: trunk/sources/editor/graphicspart/partpolygon.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partpolygon.cpp	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partpolygon.cpp	2017-08-02 15:26:14 UTC (rev 5001)
@@ -18,6 +18,7 @@
 #include "partpolygon.h"
 #include "QPropertyUndoCommand/qpropertyundocommand.h"
 #include "elementscene.h"
+#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
 
 
 /**
@@ -29,8 +30,6 @@
 PartPolygon::PartPolygon(QETElementEditor *editor, QGraphicsItem *parent) :
 	CustomElementGraphicPart(editor, parent),
 	m_closed(false),
-	m_handler(10),
-	m_handler_index(-1),
 	m_undo_command(nullptr)
 {}
 
@@ -37,8 +36,10 @@
 /**
  * @brief PartPolygon::~PartPolygon
  */
-PartPolygon::~PartPolygon() {
+PartPolygon::~PartPolygon()
+{
 	if(m_undo_command) delete m_undo_command;
+	removeHandler();
 }
 
 /**
@@ -64,9 +65,6 @@
 
 	if (m_hovered)
 		drawShadowShape(painter);
-
-	if (isSelected() && scene()->selectedItems().size() == 1)
-		m_handler.drawHandler(painter, m_polygon);
 }
 
 /**
@@ -199,6 +197,7 @@
 	if (m_polygon == polygon) return;
 	prepareGeometryChange();
 	m_polygon = polygon;
+	adjusteHandlerPos();
 	emit polygonChanged();
 }
 
@@ -248,83 +247,195 @@
 	emit closedChange();
 }
 
-void PartPolygon::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+/**
+ * @brief PartPolygon::itemChange
+ * @param change
+ * @param value
+ * @return 
+ */
+QVariant PartPolygon::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
 {
-	if (!isSelected())
+	if (change == ItemSelectedHasChanged && scene())
 	{
-		CustomElementGraphicPart::hoverMoveEvent(event);
-		return;
+		if (value.toBool() == true)
+		{
+				//When item is selected, he must to be up to date whene the selection in the scene change, for display or not the handler,
+				//according to the number of selected items.
+			connect(scene(), &QGraphicsScene::selectionChanged, this, &PartPolygon::sceneSelectionChanged); 
+			
+			if (scene()->selectedItems().size() == 1)
+				addHandler();
+		}
+		else
+		{
+			disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartPolygon::sceneSelectionChanged);
+			removeHandler();
+		}
 	}
-
-	if (m_handler.pointIsHoverHandler(event->pos(), m_polygon) >= 0)
-		setCursor(Qt::SizeAllCursor);
-	else
-		CustomElementGraphicPart::hoverMoveEvent(event);
+	else if (change == ItemPositionHasChanged)
+	{
+		adjusteHandlerPos();
+	}
+	else if (change == ItemSceneChange)
+	{
+		if(scene())
+			disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartPolygon::sceneSelectionChanged);
+		
+		setSelected(false); //This is item removed from scene, then we deselect this, and so, the handlers is also removed.
+	}
+	
+	return QGraphicsItem::itemChange(change, value);
 }
 
 /**
- * @brief PartPolygon::mousePressEvent
- * Handle mouse press event
+ * @brief PartPolygon::sceneEventFilter
+ * @param watched
  * @param event
+ * @return 
  */
-void PartPolygon::mousePressEvent(QGraphicsSceneMouseEvent *event)
+bool PartPolygon::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
 {
-	if (event->button() == Qt::LeftButton)
+		//Watched must be an handler
+	if(watched->type() == QetGraphicsHandlerItem::Type)
 	{
-		setCursor(Qt::ClosedHandCursor);
-		if(isSelected())
+		QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
+		
+		if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
 		{
-			m_handler_index = m_handler.pointIsHoverHandler(event->pos(), m_polygon);
-
-			if(m_handler_index >= 0) //User click on an handler
+			m_vector_index = m_handler_vector.indexOf(qghi);
+			if (m_vector_index != -1)
 			{
-				m_undo_command = new QPropertyUndoCommand(this, "polygon", QVariant(m_polygon));
-				m_undo_command->setText(tr("Modifier un polygone"));
-				return;
+				if(event->type() == QEvent::GraphicsSceneMousePress) //Click
+				{
+					handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
+				}
+				else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
+				{
+					handlerMouseMoveEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
+				}
+				else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
+				{
+					handlerMouseReleaseEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
+				}
 			}
 		}
 	}
-
-	CustomElementGraphicPart::mousePressEvent(event);
+	
+	return false;
 }
 
 /**
- * @brief PartPolygon::mouseMoveEvent
- * Handle mouse move event
- * @param event
+ * @brief PartPolygon::adjusteHandlerPos
  */
-void PartPolygon::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+void PartPolygon::adjusteHandlerPos()
 {
-	if(m_handler_index >= 0)
+	if(m_handler_vector.isEmpty())
+		return;
+	
+	if (m_handler_vector.size() == m_polygon.size())
 	{
-		QPointF pos_ = event->modifiers() == Qt::ControlModifier ? event->pos() : mapFromScene(elementScene()->snapToGrid(event->scenePos()));
-		prepareGeometryChange();
-		m_polygon.replace(m_handler_index, pos_);
-		emit polygonChanged();
+		QVector <QPointF> points_vector = mapToScene(m_polygon);
+		for (int i = 0 ; i < points_vector.size() ; ++i)
+			m_handler_vector.at(i)->setPos(points_vector.at(i));
 	}
-	else
-		CustomElementGraphicPart::mouseMoveEvent(event);
 }
 
 /**
- * @brief PartPolygon::mouseReleaseEvent
- * Handle mouse release event
+ * @brief PartPolygon::handlerMousePressEvent
+ * @param qghi
  * @param event
  */
-void PartPolygon::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+void PartPolygon::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
 {
-	if (event->button() == Qt::LeftButton)
-		setCursor(Qt::OpenHandCursor);
+	Q_UNUSED(qghi);
+	Q_UNUSED(event);
+	
+	m_undo_command = new QPropertyUndoCommand(this, "polygon", QVariant(m_polygon));
+	m_undo_command->setText(tr("Modifier un polygone"));
+}
 
-	if (m_handler_index >= 0)
+/**
+ * @brief PartPolygon::handlerMouseMoveEvent
+ * @param qghi
+ * @param event
+ */
+void PartPolygon::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+	Q_UNUSED(qghi);
+	
+	QPointF new_pos = event->scenePos();
+	if (event->modifiers() != Qt::ControlModifier)
+		new_pos = elementScene()->snapToGrid(event->scenePos());
+	new_pos = mapFromScene(new_pos);
+	
+	prepareGeometryChange();
+	m_polygon.replace(m_vector_index, new_pos);
+	adjusteHandlerPos();
+	emit polygonChanged();
+}
+
+/**
+ * @brief PartPolygon::handlerMouseReleaseEvent
+ * @param qghi
+ * @param event
+ */
+void PartPolygon::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+	Q_UNUSED(qghi);
+	Q_UNUSED(event);
+	
+	m_undo_command->setNewValue(QVariant(m_polygon));
+	elementScene()->undoStack().push(m_undo_command);
+	m_undo_command = nullptr;
+	m_vector_index = -1;
+}
+
+/**
+ * @brief PartPolygon::sceneSelectionChanged
+ * When the scene selection change, if there are several primitive selected, we remove the handler of this item
+ */
+void PartPolygon::sceneSelectionChanged()
+{
+	if (this->isSelected() && scene()->selectedItems().size() == 1)
+		addHandler();
+	else
+		removeHandler();
+}
+
+/**
+ * @brief PartPolygon::addHandler
+ * Add handlers for this item
+ */
+void PartPolygon::addHandler()
+{
+	if (m_handler_vector.isEmpty() && scene())
+	{		
+		m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(m_polygon));
+		
+		for(QetGraphicsHandlerItem *handler : m_handler_vector)
+		{
+			handler->setColor(Qt::blue);
+			scene()->addItem(handler);
+			handler->installSceneEventFilter(this);
+			handler->setZValue(this->zValue()+1);
+		}
+	}
+}
+
+/**
+ * @brief PartPolygon::removeHandler
+ * Remove the handlers of this item
+ */
+void PartPolygon::removeHandler()
+{
+	if (!m_handler_vector.isEmpty())
 	{
-		m_undo_command->setNewValue(QVariant(m_polygon));
-		elementScene()->undoStack().push(m_undo_command);
-		m_undo_command = nullptr;
-		m_handler_index = -1;
+		qDeleteAll(m_handler_vector);
+		m_handler_vector.clear();
 	}
-	else
-		CustomElementGraphicPart::mouseReleaseEvent(event);
 }
 
 /**
@@ -343,10 +454,6 @@
 	pps.setWidth(m_hovered? penWeight()+SHADOWS_HEIGHT : penWeight());
 	shape = pps.createStroke(shape);
 
-	if (isSelected())
-		foreach(QRectF rect, m_handler.handlerRect(m_polygon))
-			shape.addRect(rect);
-
 	return shape;
 }
 
@@ -379,8 +486,5 @@
 
 	r.adjust(-adjust, -adjust, adjust, adjust);
 
-	foreach(QRectF rect, m_handler.handlerRect(m_polygon))
-		r |=rect;
-
 	return(r);
 }

Modified: trunk/sources/editor/graphicspart/partpolygon.h
===================================================================
--- trunk/sources/editor/graphicspart/partpolygon.h	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partpolygon.h	2017-08-02 15:26:14 UTC (rev 5001)
@@ -20,10 +20,9 @@
 
 #include <QPolygonF>
 #include "customelementgraphicpart.h"
-#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
 
-
 class QPropertyUndoCommand;
+class QetGraphicsHandlerItem;
 
 /**
  * @brief The PartPolygon class
@@ -85,17 +84,25 @@
 		void setClosed (bool close);
 
 	protected:
-		virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
-		virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
-		virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
-		virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+		virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+		virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
 	
 	private:
+		void adjusteHandlerPos();
+		void handlerMousePressEvent   (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void handlerMouseMoveEvent    (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void sceneSelectionChanged ();
+		
+		void addHandler();
+		void removeHandler();
+		
+		
 		bool m_closed;
 		QList<QPointF> saved_points_;
 		QPolygonF m_polygon;
-		QetGraphicsHandlerUtility m_handler;
-		int m_handler_index;
 		QPropertyUndoCommand *m_undo_command;
+		int m_vector_index = -1;
+		QVector<QetGraphicsHandlerItem *> m_handler_vector;
 };
 #endif

Modified: trunk/sources/editor/graphicspart/partrectangle.cpp
===================================================================
--- trunk/sources/editor/graphicspart/partrectangle.cpp	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partrectangle.cpp	2017-08-02 15:26:14 UTC (rev 5001)
@@ -18,6 +18,8 @@
 #include "partrectangle.h"
 #include "elementscene.h"
 #include "QPropertyUndoCommand/qpropertyundocommand.h"
+#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
+#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
 
 /**
  * @brief PartRectangle::PartRectangle
@@ -27,8 +29,6 @@
  */
 PartRectangle::PartRectangle(QETElementEditor *editor, QGraphicsItem *parent) :
 	CustomElementGraphicPart(editor, parent),
-	m_handler(10),
-	m_handler_index(-1),
 	m_undo_command(nullptr)
 {}
 
@@ -35,8 +35,10 @@
 /**
  * @brief PartRectangle::~PartRectangle
  */
-PartRectangle::~PartRectangle() {
+PartRectangle::~PartRectangle()
+{
 	if(m_undo_command) delete m_undo_command;
+	removeHandler();
 }
 
 /**
@@ -69,11 +71,7 @@
 		drawShadowShape(painter);
 
 	if (isSelected())
-	{
 		drawCross(m_rect.center(), painter);
-		if (scene()->selectedItems().size() == 1)
-			m_handler.drawHandler(painter, m_handler.pointsForRect(m_rect));
-	}
 }
 
 /**
@@ -129,6 +127,7 @@
 	if (rect == m_rect) return;
 	prepareGeometryChange();
 	m_rect = rect;
+	adjusteHandlerPos();
 	emit rectChanged();
 }
 
@@ -164,10 +163,6 @@
 	pps.setWidth(m_hovered? penWeight()+SHADOWS_HEIGHT : penWeight());
 	shape = pps.createStroke(shape);
 
-	if (isSelected())
-		foreach(QRectF rect, m_handler.handlerRect(m_handler.pointsForRect(m_rect)))
-			shape.addRect(rect);
-
 	return shape;
 }
 
@@ -196,9 +191,6 @@
 	QRectF r = m_rect.normalized();
 	r.adjust(-adjust, -adjust, adjust, adjust);
 
-	foreach(QRectF rect, m_handler.handlerRect(m_handler.pointsForRect(m_rect)))
-		r |= rect;
-
 	return(r);
 }
 
@@ -237,113 +229,230 @@
 	setRect(QRectF(mapFromScene(mapped_points.at(0)), mapFromScene(mapped_points.at(1))));
 }
 
-void PartRectangle::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+/**
+ * @brief PartRectangle::mouseReleaseEvent
+ * Handle mouse release event
+ * @param event
+ */
+void PartRectangle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
 {
-	if (!isSelected())
+	if (event->button() == Qt::LeftButton && event->buttonDownPos(Qt::LeftButton) == event->pos())
+		switchResizeMode();
+	
+	CustomElementGraphicPart::mouseReleaseEvent(event);
+}
+
+/**
+ * @brief PartRectangle::itemChange
+ * @param change
+ * @param value
+ * @return 
+ */
+QVariant PartRectangle::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+{
+	if (change == ItemSelectedHasChanged && scene())
 	{
-		CustomElementGraphicPart::hoverMoveEvent(event);
-		return;
+		if (value.toBool() == true)
+		{
+				//When item is selected, he must to be up to date whene the selection in the scene change, for display or not the handler,
+				//according to the number of selected items.
+			connect(scene(), &QGraphicsScene::selectionChanged, this, &PartRectangle::sceneSelectionChanged); 
+			
+			if (scene()->selectedItems().size() == 1)
+				addHandler();
+		}
+		else
+		{
+			disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartRectangle::sceneSelectionChanged);
+			removeHandler();
+		}
 	}
-
-	int handler = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForRect(m_rect));
-
-	if (handler >= 0)
+	else if (change == ItemPositionHasChanged)
 	{
-		if (handler == 0 || handler == 2 || handler == 5 || handler == 7)
-			setCursor(Qt::SizeAllCursor);
-		else if (handler == 1 || handler == 6)
-			setCursor(Qt::SizeVerCursor);
-		else if (handler == 3 || handler == 4)
-			setCursor(Qt::SizeHorCursor);
+		adjusteHandlerPos();
 	}
-	else
-		CustomElementGraphicPart::hoverMoveEvent(event);
+	else if (change == ItemSceneChange)
+	{
+		if(scene())
+			disconnect(scene(), &QGraphicsScene::selectionChanged, this, &PartRectangle::sceneSelectionChanged);
+		
+		setSelected(false); //This item is removed from scene, then we deselect this, and so, the handlers is also removed.
+	}
+	
+	return QGraphicsItem::itemChange(change, value);
 }
 
 /**
- * @brief PartRectangle::mousePressEvent
- * Handle mouse press event
+ * @brief PartRectangle::sceneEventFilter
+ * @param watched
  * @param event
+ * @return 
  */
-void PartRectangle::mousePressEvent(QGraphicsSceneMouseEvent *event)
+bool PartRectangle::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
 {
-	if (event->button() == Qt::LeftButton)
+		//Watched must be an handler
+	if(watched->type() == QetGraphicsHandlerItem::Type)
 	{
-		setCursor(Qt::ClosedHandCursor);
-		if(isSelected())
+		QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
+		
+		if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
 		{
-			m_handler_index = m_handler.pointIsHoverHandler(event->pos(), m_handler.pointsForRect(m_rect));
-
-			if(m_handler_index >= 0 && m_handler_index <= 7) //User click on an handler
+			m_vector_index = m_handler_vector.indexOf(qghi);
+			if (m_vector_index != -1)
 			{
-				m_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect));
-				m_undo_command->setText(tr("Modifier un rectangle"));
-				m_undo_command->enableAnimation();
-				return;
+				if(event->type() == QEvent::GraphicsSceneMousePress) //Click
+				{
+					handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
+				}
+				else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
+				{
+					handlerMouseMoveEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
+				}
+				else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
+				{
+					handlerMouseReleaseEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
+				}
 			}
 		}
 	}
-
-	CustomElementGraphicPart::mousePressEvent(event);
+	
+	return false;
 }
 
 /**
- * @brief PartRectangle::mouseMoveEvent
- * Handle mouse press event
- * @param event
+ * @brief PartRectangle::switchResizeMode
  */
-void PartRectangle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+void PartRectangle::switchResizeMode()
 {
-	if(m_handler_index >= 0 && m_handler_index <= 7)
+	if (m_resize_mode == 1)
 	{
-		QPointF pos_ = event->modifiers() == Qt::ControlModifier ? event->pos() : mapFromScene(elementScene()->snapToGrid(event->scenePos()));
-		prepareGeometryChange();
-
-		if (m_resize_mode == 1)
-			setRect(m_handler.rectForPosAtIndex(m_rect, pos_, m_handler_index));
-		else
-			setRect(m_handler.mirrorRectForPosAtIndex(m_rect, pos_, m_handler_index));
+		m_resize_mode = 2;
+		for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+			qghi->setColor(Qt::darkGreen);
 	}
 	else
-		CustomElementGraphicPart::mouseMoveEvent(event);
+	{
+		m_resize_mode = 1;
+		for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+			qghi->setColor(Qt::blue);
+	}
 }
 
 /**
- * @brief PartRectangle::mouseReleaseEvent
- * Handle mouse release event
- * @param event
+ * @brief PartRectangle::adjusteHandlerPos
  */
-void PartRectangle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+void PartRectangle::adjusteHandlerPos()
 {
-	if (event->button() == Qt::LeftButton) {
-		setCursor(Qt::OpenHandCursor);
-		if (event->buttonDownPos(Qt::LeftButton) == event->pos())
-			switchResizeMode();
+	if (m_handler_vector.isEmpty())
+		return;
+	
+	QVector <QPointF> points_vector = QetGraphicsHandlerUtility::pointsForRect(m_rect);
+	
+	if (m_handler_vector.size() == points_vector.size())
+	{
+		points_vector = mapToScene(points_vector);
+		for (int i = 0 ; i < points_vector.size() ; ++i)
+			m_handler_vector.at(i)->setPos(points_vector.at(i));
 	}
+}
 
-	if (m_handler_index >= 0 && m_handler_index <= 7)
-	{
-		if (!m_rect.isValid())
-			m_rect = m_rect.normalized();
+/**
+ * @brief PartRectangle::handlerMousePressEvent
+ * @param qghi
+ * @param event
+ */
+void PartRectangle::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+	Q_UNUSED(qghi);
+	Q_UNUSED(event);
 
-		m_undo_command->setNewValue(QVariant(m_rect));
-		elementScene()->undoStack().push(m_undo_command);
-		m_undo_command = nullptr;
-		m_handler_index = -1;
-	}
+	m_undo_command = new QPropertyUndoCommand(this, "rect", QVariant(m_rect));
+	m_undo_command->setText(tr("Modifier un rectangle"));
+	m_undo_command->enableAnimation();
+	return;	
+}
+
+/**
+ * @brief PartRectangle::handlerMouseMoveEvent
+ * @param qghi
+ * @param event
+ */
+void PartRectangle::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+	Q_UNUSED(qghi);
+	
+	QPointF new_pos = event->scenePos();
+	if (event->modifiers() != Qt::ControlModifier)
+		new_pos = elementScene()->snapToGrid(event->scenePos());
+	new_pos = mapFromScene(new_pos);
+	
+	if (m_resize_mode == 1)
+		setRect(QetGraphicsHandlerUtility::rectForPosAtIndex(m_rect, new_pos, m_vector_index));
 	else
-		CustomElementGraphicPart::mouseReleaseEvent(event);
+		setRect(QetGraphicsHandlerUtility::mirrorRectForPosAtIndex(m_rect, new_pos, m_vector_index));
+	
+	adjusteHandlerPos();
 }
 
-void PartRectangle::switchResizeMode()
+void PartRectangle::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
 {
-	if (m_resize_mode == 1) {
-		m_resize_mode = 2;
-		m_handler.setOuterColor(Qt::darkGreen);
+	Q_UNUSED(qghi);
+	Q_UNUSED(event);
+	
+	m_undo_command->setNewValue(QVariant(m_rect));
+	elementScene()->undoStack().push(m_undo_command);
+	m_undo_command = nullptr;
+	m_vector_index = -1;
+}
+
+/**
+ * @brief PartRectangle::sceneSelectionChanged
+ * When the scene selection change, if there are several primitive selected, we remove the handler of this item
+ */
+void PartRectangle::sceneSelectionChanged()
+{
+	if (this->isSelected() && scene()->selectedItems().size() == 1)
+		addHandler();
+	else
+		removeHandler();
+}
+
+/**
+ * @brief PartRectangle::addHandler
+ * Add handlers for this item
+ */
+void PartRectangle::addHandler()
+{
+	if (m_handler_vector.isEmpty() && scene())
+	{		
+		m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(QetGraphicsHandlerUtility::pointsForRect(m_rect)));
+		
+		for(QetGraphicsHandlerItem *handler : m_handler_vector)
+		{
+			QColor color = Qt::blue;
+			if (m_resize_mode == 2)
+				color = Qt::darkGreen;
+			
+			handler->setColor(color);
+			scene()->addItem(handler);
+			handler->installSceneEventFilter(this);
+			handler->setZValue(this->zValue()+1);
+		}
 	}
-	else {
-		m_resize_mode = 1;
-		m_handler.setOuterColor(Qt::blue);
+}
+
+/**
+ * @brief PartRectangle::removeHandler
+ * Remove the handlers of this item
+ */
+void PartRectangle::removeHandler()
+{
+	if (!m_handler_vector.isEmpty())
+	{
+		qDeleteAll(m_handler_vector);
+		m_handler_vector.clear();
 	}
-	update();
 }

Modified: trunk/sources/editor/graphicspart/partrectangle.h
===================================================================
--- trunk/sources/editor/graphicspart/partrectangle.h	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/editor/graphicspart/partrectangle.h	2017-08-02 15:26:14 UTC (rev 5001)
@@ -19,9 +19,9 @@
 #define PART_RECTANGLE_H
 
 #include "customelementgraphicpart.h"
-#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
 
 class QPropertyUndoCommand;
+class QetGraphicsHandlerItem;
 
 /**
  * This class represents a rectangle primitive which may be used to compose the
@@ -75,20 +75,27 @@
 		virtual void handleUserTransformation(const QRectF &, const QRectF &);
 
 	protected:
-		virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
-		virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
-		virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
 		virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+		virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+		virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
 
 	private:
 		void switchResizeMode();
+		void adjusteHandlerPos();
+		void handlerMousePressEvent   (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void handlerMouseMoveEvent    (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void sceneSelectionChanged ();
+		
+		void addHandler();
+		void removeHandler();
 	
 	private:
 		QRectF m_rect;
 		QList<QPointF> saved_points_;
-		QetGraphicsHandlerUtility m_handler;
-		int m_handler_index;
 		QPropertyUndoCommand *m_undo_command;
-		int m_resize_mode = 1;
+		int m_resize_mode = 1,
+			m_vector_index = -1;
+		QVector<QetGraphicsHandlerItem *> m_handler_vector;
 };
 #endif

Modified: trunk/sources/qetgraphicsitem/conductor.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/conductor.cpp	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/qetgraphicsitem/conductor.cpp	2017-08-02 15:26:14 UTC (rev 5001)
@@ -78,10 +78,9 @@
 	terminal1(p1),
 	terminal2(p2),
 	m_mouse_over(false),
-	m_handler(10),
 	m_text_item(0),
 	segments(NULL),
-	moving_segment(false),
+	m_moving_segment(false),
 	modified_path(false),
 	has_to_save_profile(false),
 	must_highlight_(Conductor::None)
@@ -88,7 +87,7 @@
 {
 		//set Zvalue at 11 to be upper than the DiagramImageItem and element
 	setZValue(11);
-	previous_z_value = zValue();
+	m_previous_z_value = zValue();
 
 		//Add this conductor to the list of conductor of each of the two terminal
 	bool ajout_p1 = terminal1 -> addConductor(this);
@@ -117,7 +116,7 @@
 
 		//Generate the path of this conductor.
 	generateConductorPath(terminal1 -> dockConductor(), terminal1 -> orientation(), terminal2 -> dockConductor(), terminal2 -> orientation());
-	setFlags(QGraphicsItem::ItemIsSelectable);
+	setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsScenePositionChanges);
 	setAcceptHoverEvents(true);
 	
 		// Add the text field
@@ -137,6 +136,7 @@
  */
 Conductor::~Conductor()
 {
+	removeHandler();
 	terminal1->removeConductor(this);
 	terminal2->removeConductor(this);
 	deleteSegments();
@@ -171,30 +171,39 @@
 }
 
 /**
-	Genere le QPainterPath a partir de la liste des points
-*/
-void Conductor::segmentsToPath() {
-	// chemin qui sera dessine
+ * @brief Conductor::segmentsToPath
+ * Generate the QPainterPath from the list of points
+ */
+void Conductor::segmentsToPath()
+{
 	QPainterPath path;
 	
-	// s'il n'y a pa des segments, on arrete la
-	if (segments == NULL) setPath(path);
+	if (segments == NULL)
+		setPath(path);
 	
-	// demarre le chemin
+		//Start the path
 	path.moveTo(segments -> firstPoint());
-	
-	// parcourt les segments pour dessiner le chemin
+		//Each segments
 	ConductorSegment *segment = segments;
 	while(segment -> hasNextSegment()) {
 		path.lineTo(segment -> secondPoint());
 		segment = segment -> nextSegment();
 	}
-	
-	// termine le chemin
+		//Finish the path
 	path.lineTo(segment -> secondPoint());
 	
-	// affecte le chemin au conducteur
 	setPath(path);
+	
+		//If conductor is selected and he's not being modified
+		//we update the position of the handlers
+	if (isSelected() && !m_moving_segment)
+	{
+		if(handlerPoints().size() == m_handler_vector.size())
+			adjusteHandlerPos();
+		else
+			removeHandler();
+			addHandler();
+	}
 }
 
 /**
@@ -456,12 +465,11 @@
 }
 
 /**
- * @brief Conductor::paint
- * Draw the conductor
- * @param qp
- * @param options
- * @param qw
- */
+	Dessine le conducteur sans antialiasing.
+	@param qp Le QPainter a utiliser pour dessiner le conducteur
+	@param options Les options de style pour le conducteur
+	@param qw Le QWidget sur lequel on dessine 
+*/
 void Conductor::paint(QPainter *qp, const QStyleOptionGraphicsItem *options, QWidget *qw)
 {
 	Q_UNUSED(qw);
@@ -501,7 +509,7 @@
 		final_conductor_pen.setCosmetic(true);
 	}
 	
-	qp->setPen(final_conductor_pen);
+	qp -> setPen(final_conductor_pen);
 	
 		//Draw the conductor
 	qp -> drawPath(path());
@@ -529,22 +537,17 @@
 		if (isSelected()) qp -> setBrush(Qt::NoBrush);
 	}
 	
-		//Draw the squares used to modify the path of conductor when he is selected
-	if (isSelected())
-		m_handler.drawHandler(qp, handlerPoints());
-	
 		//Draw the junctions
-	const QList<QPointF> junctions_list = junctions();
-	if (!junctions_list.isEmpty())
-	{
+	QList<QPointF> junctions_list = junctions();
+	if (!junctions_list.isEmpty()) {
 		final_conductor_pen.setStyle(Qt::SolidLine);
 		QBrush junction_brush(final_conductor_color, Qt::SolidPattern);
 		qp -> setPen(final_conductor_pen);
 		qp -> setBrush(junction_brush);
 		qp -> setRenderHint(QPainter::Antialiasing, true);
-		
-		for(QPointF point : junctions_list)
+		foreach(QPointF point, junctions_list) {
 			qp -> drawEllipse(QRectF(point.x() - 1.5, point.y() - 1.5, 3.0, 3.0));
+		}
 	}
 
 	qp -> restore();
@@ -603,70 +606,18 @@
  */
 void Conductor::mousePressEvent(QGraphicsSceneMouseEvent *event)
 {
-		//Left clic
-	if (event->buttons() & Qt::LeftButton)
-	{
-			//If user click on a handler (square used to modify the path of conductor),
-			//we get the segment corresponding to the handler
-		int index = m_handler.pointIsHoverHandler(event->pos(), handlerPoints());
-		if (index > -1)
-		{
-			moving_segment = true;
-			moved_segment = segmentsList().at(index+1);
-			before_mov_text_pos_ = m_text_item -> pos();
-		}
-	}
-
 	QGraphicsPathItem::mousePressEvent(event);
-
-	if (event -> modifiers() & Qt::ControlModifier)
+	
+	if (event->modifiers() & Qt::ControlModifier)
 		setSelected(!isSelected());
 }
 
 /**
- * @brief Conductor::mouseMoveEvent
- * Manage the mouse move event
- * @param event
- */
-void Conductor::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
-{
-		//Left clic
-	if ((event->buttons() & Qt::LeftButton) && moving_segment)
-	{
-			//Snap the mouse pos to grid
-		QPointF pos_ = Diagram::snapToGrid(event->pos());
-
-			//Position of the last point
-		QPointF p = moved_segment -> middle();
-
-			//Calcul the movement
-		moved_segment -> moveX(pos_.x() - p.x());
-		moved_segment -> moveY(pos_.y() - p.y());
-			
-			//Apply the movement
-		modified_path = true;
-		has_to_save_profile = true;
-		segmentsToPath();
-		calculateTextItemPosition();
-	}
-
-	QGraphicsPathItem::mouseMoveEvent(event);
-}
-
-/**
  * @brief Conductor::mouseReleaseEvent
- * Manage the mouse release event
  * @param event
  */
 void Conductor::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
 {
-	moving_segment = false;
-	if (has_to_save_profile)
-	{
-		saveProfile();
-		has_to_save_profile = false;
-	}
-
 	if (!(event -> modifiers() & Qt::ControlModifier))
 		QGraphicsPathItem::mouseReleaseEvent(event);
 }
@@ -694,59 +645,212 @@
 }
 
 /**
- * @brief Conductor::hoverMoveEvent conductor
- * @param e QGraphicsSceneHoverEvent describing the event
+ * @brief Conductor::itemChange
+ * @param change
+ * @param value
+ * @return 
  */
-void Conductor::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+QVariant Conductor::itemChange(GraphicsItemChange change, const QVariant &value)
 {
-	if (isSelected())
+	if (change == QGraphicsItem::ItemSelectedChange)
 	{
-			//If user hover an handler (square used to modify the path of conductor),
-			//we get the segment corresponding to the handler
-		int index = m_handler.pointIsHoverHandler(event->pos(), handlerPoints());
-		if (index > -1)
+		if (value.toBool())
 		{
-			ConductorSegment *segment_ = segmentsList().at(index+1);
-			if (m_handler.pointIsInHandler(event->pos(), segment_->secondPoint()))
-				setCursor(Qt::ForbiddenCursor);
-			else if (m_handler.pointIsInHandler(event->pos(), segment_->middle()))
-				setCursor(segmentsList().at(index+1)->isVertical() ? Qt::SplitHCursor : Qt::SplitVCursor);
+			m_previous_z_value = zValue();
+			setZValue(qAbs(m_previous_z_value) + 10000);
+			addHandler();
 		}
 		else
-			setCursor(Qt::ArrowCursor);
+		{
+			setZValue(m_previous_z_value);
+			removeHandler();
+		}
 	}
+	else if (change == QGraphicsItem::ItemSceneHasChanged)
+	{
+		calculateTextItemPosition();
+		
+		if(!scene())
+			removeHandler();
+		else if (scene() && isSelected())
+			addHandler();
+	}
+	else if (change == QGraphicsItem::ItemVisibleHasChanged) {
+		calculateTextItemPosition();
+	}
+	else if (change == QGraphicsItem::ItemPositionHasChanged && isSelected()) {
+		adjusteHandlerPos();
+	}
+	
+	return(QGraphicsPathItem::itemChange(change, value));
+}
 
-	QGraphicsPathItem::hoverMoveEvent(event);
+/**
+ * @brief Conductor::sceneEventFilter
+ * @param watched
+ * @param event
+ * @return 
+ */
+bool Conductor::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
+{
+		//Watched must be an handler
+	if(watched->type() == QetGraphicsHandlerItem::Type)
+	{
+		QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
+		
+		if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
+		{
+			m_vector_index = m_handler_vector.indexOf(qghi);
+			if (m_vector_index != -1)
+			{
+				if(event->type() == QEvent::GraphicsSceneMousePress) //Click
+				{
+					handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
+				}
+				else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
+				{
+					handlerMouseMoveEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
+				}
+				else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
+				{
+					handlerMouseReleaseEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
+				}
+			}
+		}
+	}
+	
+	return false;
 }
 
 /**
-	Gere les changements relatifs au conducteur
-	Reimplemente ici pour :
-	  * positionner le conducteur en avant-plan lorsqu'il est selectionne
-	@param change Type de changement
-	@param value  Valeur relative au changement
-*/
-QVariant Conductor::itemChange(GraphicsItemChange change, const QVariant &value) {
-	if (change == QGraphicsItem::ItemSelectedChange) {
-		if (value.toBool()) {
-			// le conducteur vient de se faire selectionner
-			previous_z_value = zValue();
-			setZValue(qAbs(previous_z_value) + 10000);
-		} else {
-			// le conducteur vient de se faire deselectionner
-			setZValue(previous_z_value);
-		}
-	} else if (change == QGraphicsItem::ItemSceneHasChanged) {
-		// permet de positionner correctement le texte du conducteur lors de son ajout a un schema
+ * @brief Conductor::adjusteHandlerPos
+ * Adjust the position of the handler item
+ */
+void Conductor::adjusteHandlerPos()
+{
+	if (m_handler_vector.isEmpty())
+		return;
+	
+	if (m_handler_vector.size() == handlerPoints().size())
+	{
+		QVector <QPointF> points_vector = mapToScene(handlerPoints());
+		for (int i = 0 ; i < points_vector.size() ; ++i)
+			m_handler_vector.at(i)->setPos(points_vector.at(i));
+	}
+}
+
+/**
+ * @brief Conductor::handlerMousePressEvent
+ * @param qghi
+ * @param event
+ */
+void Conductor::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+	Q_UNUSED(event);
+	
+		//we get the segment corresponding to the handler
+	if (m_vector_index > -1)
+	{
+		qghi->setColor(Qt::cyan);
+		m_moving_segment = true;
+		m_moved_segment = segmentsList().at(m_vector_index+1);
+		before_mov_text_pos_ = m_text_item -> pos();
+		
+		for(QetGraphicsHandlerItem *handler : m_handler_vector)
+			if(handler != qghi)
+				handler->hide();
+	}
+}
+
+/**
+ * @brief Conductor::handlerMouseMoveEvent
+ * @param qghi
+ * @param event
+ */
+void Conductor::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+	if (m_moving_segment)
+	{
+			//Snap the mouse pos to grid
+		QPointF pos_ = Diagram::snapToGrid(mapFromItem(qghi, event->pos()));
+		
+			//Position of the last point
+		QPointF p = m_moved_segment -> middle();
+		
+			//Calcul the movement
+		m_moved_segment -> moveX(pos_.x() - p.x());
+		m_moved_segment -> moveY(pos_.y() - p.y());
+		
+			//Apply the movement
+		modified_path = true;
+		has_to_save_profile = true;
+		segmentsToPath();
 		calculateTextItemPosition();
-	} else if (change == QGraphicsItem::ItemVisibleHasChanged) {
-		// permet de positionner correctement le texte du conducteur lors de son ajout a un schema
-		calculateTextItemPosition();
+		qghi->setPos(mapToScene(m_moved_segment->middle()));
 	}
-	return(QGraphicsPathItem::itemChange(change, value));
 }
 
 /**
+ * @brief Conductor::handlerMouseReleaseEvent
+ * @param qghi
+ * @param event
+ */
+void Conductor::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+	Q_UNUSED(event);
+	Q_UNUSED(qghi);
+	
+	m_vector_index = -1;
+	
+	m_moving_segment = false;
+	if (has_to_save_profile)
+	{
+		saveProfile();
+		has_to_save_profile = false;
+	}
+		//When handler is released, the conductor can have more segment than befor the handler was moved
+		//then we remove all handles and new ones are added
+	removeHandler();
+	addHandler();
+}
+
+/**
+ * @brief Conductor::addHandler
+ * Add handlers for this item
+ */
+void Conductor::addHandler()
+{
+	if (m_handler_vector.isEmpty() && scene())
+	{		
+		m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(handlerPoints()));
+		
+		for(QetGraphicsHandlerItem *handler : m_handler_vector)
+		{
+			handler->setColor(Qt::blue);
+			scene()->addItem(handler);
+			handler->installSceneEventFilter(this);
+			handler->setZValue(this->zValue()+1);
+		}
+	}
+}
+
+/**
+ * @brief Conductor::removeHandler
+ * Remove the handlers of this item
+ */
+void Conductor::removeHandler()
+{
+	if (!m_handler_vector.isEmpty())
+	{
+		qDeleteAll(m_handler_vector);
+		m_handler_vector.clear();
+	}
+}
+
+/**
  * @brief Conductor::boundingRect
  * @return
  */
@@ -768,23 +872,7 @@
 	pps.setJoinStyle(conductor_pen.joinStyle());
 
 	QPainterPath shape_(pps.createStroke(path()));
-
-	/**
-		Add handle rect to path, occur a weird bug.
-		when the conductor is removed from the scene he continue to be painted in the scene and make artefact.
-		If we save (exactly when we clear the undo stack of project when saving), Qet crash,
-		Don't add the handle rect to the path seem to work well.
-		More information here :
-		https://qelectrotech.org/bugtracker/view.php?id=107
-		https://qelectrotech.org/forum/viewtopic.php?pid=5619#p5619
-		https://qelectrotech.org/forum/viewtopic.php?pid=5067#p5067
-	**/
-//	if (isSelected()) {
-//		foreach (QRectF rect, m_handler.handlerRect(handlerPoints())) {
-//			shape_.addRect(rect);
-//		}
-//	}
-
+	
 	return shape_;
 }
 

Modified: trunk/sources/qetgraphicsitem/conductor.h
===================================================================
--- trunk/sources/qetgraphicsitem/conductor.h	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/qetgraphicsitem/conductor.h	2017-08-02 15:26:14 UTC (rev 5001)
@@ -20,7 +20,6 @@
 
 #include "conductorproperties.h"
 #include <QGraphicsPathItem>
-#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
 #include "assignvariables.h"
 
 class ConductorProfile;
@@ -32,6 +31,8 @@
 class Element;
 class QETDiagramEditor;
 class NumerotationContext;
+class QetGraphicsHandlerItem;
+
 typedef QPair<QPointF, Qt::Corner> ConductorBend;
 typedef QHash<Qt::Corner, ConductorProfile> ConductorProfilesGroup;
 /**
@@ -133,36 +134,45 @@
 	protected:
 		virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
 		virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
-		virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
 		virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
 		virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
 		virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
-		virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
 		virtual QVariant itemChange(GraphicsItemChange, const QVariant &);
+        virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
 
 	private:
+		void adjusteHandlerPos();
+		
+		void handlerMousePressEvent   (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void handlerMouseMoveEvent    (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void addHandler();
+		void removeHandler();
+		
+		
+		QVector<QetGraphicsHandlerItem *> m_handler_vector;
+		int m_vector_index = -1;
 		bool m_mouse_over;
-		QetGraphicsHandlerUtility m_handler;
-		/// Functional properties
+			/// Functional properties
 		ConductorProperties m_properties;
-		/// Text input for non simple, non-singleline conductors
+			/// Text input for non simple, non-singleline conductors
 		ConductorTextItem *m_text_item;
-		/// Segments composing the conductor
+			/// Segments composing the conductor
 		ConductorSegment *segments;
-		/// Attributs related to mouse interaction
-		bool moving_segment;
+			/// Attributs related to mouse interaction
+		bool m_moving_segment;
 		int moved_point;
-		qreal previous_z_value;
-		ConductorSegment *moved_segment;
+		qreal m_previous_z_value;
+		ConductorSegment *m_moved_segment;
 		QPointF before_mov_text_pos_;
-		/// Whether the conductor was manually modified by users
+			/// Whether the conductor was manually modified by users
 		bool modified_path;
-		/// Whether the current profile should be saved as soon as possible
+			/// Whether the current profile should be saved as soon as possible
 		bool has_to_save_profile;
-		/// conductor profile: "photography" of what the conductor is supposed to look
-		/// like - there is one profile per kind of traject
+			/// conductor profile: "photography" of what the conductor is supposed to look
+			/// like - there is one profile per kind of traject
 		ConductorProfilesGroup conductor_profiles;
-		/// Define whether and how the conductor should be highlighted
+			/// Define whether and how the conductor should be highlighted
 		Highlight must_highlight_;
 		bool m_valid;
 		bool m_freeze_label = false;

Modified: trunk/sources/qetgraphicsitem/qetshapeitem.cpp
===================================================================
--- trunk/sources/qetgraphicsitem/qetshapeitem.cpp	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/qetgraphicsitem/qetshapeitem.cpp	2017-08-02 15:26:14 UTC (rev 5001)
@@ -22,6 +22,7 @@
 #include "shapegraphicsitempropertieswidget.h"
 #include "PropertiesEditor/propertieseditordialog.h"
 #include "QPropertyUndoCommand/qpropertyundocommand.h"
+#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
 #include "qetxml.h"
 
 /**
@@ -37,18 +38,20 @@
 	m_shapeType(type),
 	m_P1 (p1),
 	m_P2 (p2),
-	m_hovered(false),
-	m_mouse_grab_handler(false),
-	m_handler(10)
+	m_hovered(false)
 {
 	if (type == Polygon) m_polygon << m_P1 << m_P2;
-	setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
+    setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
 	setAcceptHoverEvents(true);
 	m_pen.setStyle(Qt::DashLine);
 
 }
 
-QetShapeItem::~QetShapeItem() {}
+QetShapeItem::~QetShapeItem()
+{
+    if(!m_handler_vector.isEmpty())
+        qDeleteAll(m_handler_vector);
+}
 
 /**
  * @brief QetShapeItem::setPen
@@ -109,6 +112,7 @@
 	prepareGeometryChange();
 	m_P1 = line.p1();
 	m_P2 = line.p2();
+	adjusteHandlerPos();
 	return true;
 }
 
@@ -125,6 +129,7 @@
 		prepareGeometryChange();
 		m_P1 = rect.topLeft();
 		m_P2 = rect.bottomRight();
+		adjusteHandlerPos();
 		return true;
 	}
 
@@ -142,6 +147,7 @@
 	if (Q_UNLIKELY(m_shapeType != Polygon)) return false;
 	prepareGeometryChange();
 	m_polygon = polygon;
+	adjusteHandlerPos();
 	return true;
 }
 
@@ -246,23 +252,6 @@
 	pps.setJoinStyle(Qt::RoundJoin);
 	path = pps.createStroke(path);
 
-	if (isSelected())
-	{
-		QVector <QPointF> vector;
-
-		if (m_shapeType == Line)
-			vector << m_P1 << m_P2;
-		else if (m_shapeType == Rectangle || m_shapeType == Ellipse) {
-			QRectF rect (m_P1, m_P2);
-			vector << rect.topLeft() << rect.topRight() << rect.bottomRight() << rect.bottomLeft();
-		}
-		else
-			vector = m_polygon;
-
-		foreach(QRectF r, m_handler.handlerRect(vector))
-			path.addRect(r);
-	}
-
 	return (path);
 }
 
@@ -293,35 +282,16 @@
 		painter -> drawPath (shape());
 		painter -> restore  ();
 	}
-
-		//Draw the shape and handlers if is selected
-	switch (m_shapeType)
-	{
-		case Line:
-			painter->drawLine(QLineF(m_P1, m_P2));
-			if (isSelected())
-				m_handler.drawHandler(painter, QVector<QPointF>{m_P1, m_P2});
-			break;
-
-		case Rectangle:
-			painter->drawRect(QRectF(m_P1, m_P2));
-			if (isSelected())
-				m_handler.drawHandler(painter, m_handler.pointsForRect(QRectF(m_P1, m_P2)));
-			break;
-
-		case Ellipse:
-			painter->drawEllipse(QRectF(m_P1, m_P2));
-			if (isSelected())
-				m_handler.drawHandler(painter, m_handler.pointsForRect(QRectF(m_P1, m_P2)));
-			break;
-
-		case Polygon:
-			m_close ? painter->drawPolygon(m_polygon) : painter->drawPolyline(m_polygon);
-			if (isSelected())
-				m_handler.drawHandler(painter, m_polygon);
-			break;
-	}
-	painter->restore();
+	
+    switch (m_shapeType)
+    {
+        case Line:      painter->drawLine(QLineF(m_P1, m_P2)); break;
+        case Rectangle: painter->drawRect(QRectF(m_P1, m_P2)); break;
+        case Ellipse:   painter->drawEllipse(QRectF(m_P1, m_P2)); break;
+        case Polygon:   m_close ? painter->drawPolygon(m_polygon) : painter->drawPolyline(m_polygon); break;
+    }
+    
+    painter->restore();
 }
 
 /**
@@ -329,195 +299,275 @@
  * Handle hover enter event
  * @param event
  */
-void QetShapeItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) {
+void QetShapeItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
+{
 	m_hovered = true;
 	QetGraphicsItem::hoverEnterEvent(event);
 }
 
-void QetShapeItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
-{
-	if (!isSelected()) return;
-
-	QVector <QPointF> vector;
-	switch (m_shapeType)
-	{
-		case Line:      vector << m_P1 << m_P2;                               break;
-		case Rectangle: vector = m_handler.pointsForRect(QRectF(m_P1, m_P2)); break;
-		case Ellipse:   vector = m_handler.pointsForRect(QRectF(m_P1, m_P2)); break;
-		case Polygon:   vector = m_polygon;                                   break;
-	}
-
-	int handler = m_handler.pointIsHoverHandler(event->pos(), vector);
-	if (handler >= 0)
-	{
-		if (m_shapeType & (Line | Polygon)) {
-			setCursor(Qt::SizeAllCursor);
-			return;
-		}
-
-		if (handler == 0 || handler == 2 || handler == 5 || handler == 7)
-			setCursor(Qt::SizeAllCursor);
-		else if (handler == 1 || handler == 6)
-			setCursor(Qt::SizeVerCursor);
-		else if (handler == 3 || handler == 4)
-			setCursor(Qt::SizeHorCursor);
-	}
-	else
-		setCursor(Qt::OpenHandCursor);
-}
-
 /**
  * @brief QetShapeItem::hoverLeaveEvent
  * Handle hover leave event
  * @param event
  */
-void QetShapeItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) {
+void QetShapeItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
+{
 	m_hovered = false;
-	unsetCursor();
 	QetGraphicsItem::hoverLeaveEvent(event);
 }
 
 /**
- * @brief QetShapeItem::mousePressEvent
- * Handle mouse press event
+ * @brief QetShapeItem::mouseReleaseEvent
+ * Handle mouse release event
  * @param event
  */
-void QetShapeItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
+void QetShapeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
 {
-	if (event->button() == Qt::LeftButton)
+	if (event->buttonDownPos(Qt::LeftButton) == event->pos())
+		switchResizeMode();
+
+    QetGraphicsItem::mouseReleaseEvent(event);
+}
+
+/**
+ * @brief QetShapeItem::itemChange
+ * @param change
+ * @param value
+ * @return 
+ */
+QVariant QetShapeItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+{
+    if (change == ItemSelectedHasChanged)
+    {
+        if (value.toBool() == true) //If this is selected, wa add handlers.
+        {
+            QVector <QPointF> points_vector;
+            switch (m_shapeType)
+            {
+                case Line:      points_vector << m_P1 << m_P2; break;
+                case Rectangle: points_vector = QetGraphicsHandlerUtility::pointsForRect(QRectF(m_P1, m_P2)); break;
+                case Ellipse:   points_vector = QetGraphicsHandlerUtility::pointsForRect(QRectF(m_P1, m_P2)); break;
+                case Polygon:   points_vector = m_polygon; break;
+            }
+
+            if(!points_vector.isEmpty() && scene())
+            {
+                m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(points_vector));
+
+                for(QetGraphicsHandlerItem *handler : m_handler_vector)
+				{
+					handler->setColor(Qt::blue);
+                    scene()->addItem(handler);
+					handler->installSceneEventFilter(this);
+				}
+            }
+        }
+        else //Else this is deselected, we remove handlers
+        {
+            if(!m_handler_vector.isEmpty())
+            {
+                qDeleteAll(m_handler_vector);
+                m_handler_vector.clear();
+            }
+        }
+    }
+    else if (change == ItemPositionHasChanged)
+    {
+		adjusteHandlerPos();
+    }
+	else if (change == ItemSceneHasChanged)
 	{
-		setCursor(Qt::ClosedHandCursor);
-			//Shape is selected, we see if user click in a handler
-		if (isSelected())
+		if (!scene()) //This is removed from scene, then we deselect this, and so, the handlers is also removed.
 		{
-			QVector <QPointF> vector;
-			switch (m_shapeType)
-			{
-				case Line:      vector << m_P1 << m_P2;                               break;
-				case Rectangle: vector = m_handler.pointsForRect(QRectF(m_P1, m_P2)); break;
-				case Ellipse:   vector = m_handler.pointsForRect(QRectF(m_P1, m_P2)); break;
-				case Polygon:  vector = m_polygon;                                   break;
-			}
-
-			m_vector_index = m_handler.pointIsHoverHandler(event->pos(), vector);
-			if (m_vector_index != -1)
-			{
-					//User click on an handler
-				m_mouse_grab_handler = true;
-				m_old_P1 = m_P1;
-				m_old_P2 = m_P2;
-				m_old_polygon = m_polygon;
-				return;
-			}
+			setSelected(false);
 		}
 	}
 
-	QetGraphicsItem::mousePressEvent(event);
+    return QGraphicsItem::itemChange(change, value);
 }
 
 /**
- * @brief QetShapeItem::mouseMoveEvent
- * Handle move event
+ * @brief QetShapeItem::sceneEventFilter
+ * @param watched
  * @param event
+ * @return 
  */
-void QetShapeItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+bool QetShapeItem::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
 {
-	if (m_mouse_grab_handler)
+		//Watched must be an handler
+	if(watched->type() == QetGraphicsHandlerItem::Type)
 	{
-		QPointF new_pos = event->pos();
-		if (event->modifiers() != Qt::ControlModifier)
-			new_pos = mapFromScene(Diagram::snapToGrid(event->scenePos()));
-
-		switch (m_shapeType)
+		QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
+		
+		if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
 		{
-			case Line:
-				prepareGeometryChange();
-				m_vector_index == 0 ? m_P1 = new_pos : m_P2 = new_pos;
-				break;
-
-			case Rectangle:
-				if (m_resize_mode == 1) {
-					setRect(m_handler.rectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
-					break;
+			m_vector_index = m_handler_vector.indexOf(qghi);
+			if (m_vector_index != -1)
+			{
+				if(event->type() == QEvent::GraphicsSceneMousePress) //Click
+				{
+					handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
 				}
-				else {
-					setRect(m_handler.mirrorRectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
-					break;
+				else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
+				{
+					handlerMouseMoveEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
 				}
-			case Ellipse:
-				if (m_resize_mode == 1) {
-					setRect(m_handler.rectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
-					break;
+				else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
+				{
+					handlerMouseReleaseEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
+					return true;
 				}
-				else {
-					setRect(m_handler.mirrorRectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
-					break;
-				}
+			}
+		}
+	}
+	
+	return false;
+}
 
-			case Polygon:
-				prepareGeometryChange();
-				m_polygon.replace(m_vector_index, new_pos);
-				break;
-		}	//End switch
-		return;
+/**
+ * @brief QetShapeItem::switchResizeMode
+ */
+void QetShapeItem::switchResizeMode()
+{
+	if (m_shapeType & (Rectangle | Ellipse))
+	{
+		if (m_resize_mode == 1)
+		{
+			m_resize_mode = 2;
+			for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+				qghi->setColor(Qt::darkGreen);
+		}
+		else
+		{
+			m_resize_mode = 1;
+			for (QetGraphicsHandlerItem *qghi : m_handler_vector)
+				qghi->setColor(Qt::blue);
+		}
 	}
+}
 
-	QetGraphicsItem::mouseMoveEvent(event);
+/**
+ * @brief QetShapeItem::adjusteHandlerPos
+ * Adjust the position of the handler item
+ */
+void QetShapeItem::adjusteHandlerPos()
+{
+	QVector <QPointF> points_vector;
+	switch (m_shapeType)
+	{
+		case Line:      points_vector << m_P1 << m_P2; break;
+		case Rectangle: points_vector = QetGraphicsHandlerUtility::pointsForRect(QRectF(m_P1, m_P2)); break;
+		case Ellipse:   points_vector = QetGraphicsHandlerUtility::pointsForRect(QRectF(m_P1, m_P2)); break;
+		case Polygon:   points_vector = m_polygon; break;
+	}
+	
+	if (m_handler_vector.size() == points_vector.size())
+	{
+		points_vector = mapToScene(points_vector);
+		for (int i = 0 ; i < points_vector.size() ; ++i)
+			m_handler_vector.at(i)->setPos(points_vector.at(i));
+	}
 }
 
 /**
- * @brief QetShapeItem::mouseReleaseEvent
- * Handle mouse release event
+ * @brief QetShapeItem::handlerMousePressEvent
+ * @param qghi
  * @param event
  */
-void QetShapeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+void QetShapeItem::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
 {
-	if ((m_shapeType & (Rectangle | Ellipse)) && event->buttonDownPos(Qt::LeftButton) == event->pos())
-		switchResizeMode();
+	Q_UNUSED(qghi);
+	Q_UNUSED(event);
+	
+	m_old_P1 = m_P1;
+	m_old_P2 = m_P2;
+	m_old_polygon = m_polygon;
+}
 
-	if (m_mouse_grab_handler)
+/**
+ * @brief QetShapeItem::handlerMouseMoveEvent
+ * @param qghi
+ * @param event
+ */
+void QetShapeItem::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
+{
+	Q_UNUSED(qghi);
+	
+	QPointF new_pos = event->scenePos();
+	if (event->modifiers() != Qt::ControlModifier)
+		new_pos = Diagram::snapToGrid(event->scenePos());
+	new_pos = mapFromScene(new_pos);
+
+	switch (m_shapeType)
 	{
-		m_mouse_grab_handler = false;
-		if (diagram())
-		{
-			QPropertyUndoCommand *undo = nullptr;
-			if ((m_shapeType & (Line | Rectangle | Ellipse)) && (m_P1 != m_old_P1 || m_P2 != m_old_P2))
-			{
-				switch(m_shapeType)
-				{
-					case Line:      undo = new QPropertyUndoCommand(this, "line",QLineF(m_old_P1, m_old_P2), QLineF(m_P1, m_P2)); break;
-					case Rectangle: undo = new QPropertyUndoCommand(this, "rect",QRectF(m_old_P1, m_old_P2), QRectF(m_P1, m_P2)); break;
-					case Ellipse:   undo = new QPropertyUndoCommand(this, "rect",QRectF(m_old_P1, m_old_P2), QRectF(m_P1, m_P2)); break;
-					case Polygon: break;
-				}
-				if (undo) undo->enableAnimation();
-			}
-			else if (m_shapeType == Polygon && (m_polygon != m_old_polygon))
-				undo = new QPropertyUndoCommand(this, "polygon", m_old_polygon, m_polygon);
+		case Line:
+			prepareGeometryChange();
+			m_vector_index == 0 ? m_P1 = new_pos : m_P2 = new_pos;
+			adjusteHandlerPos();
+			break;
 
-			if(undo)
-			{
-				undo->setText(tr("Modifier %1").arg(name()));
-				diagram()->undoStack().push(undo);
+		case Rectangle:
+			if (m_resize_mode == 1) {
+				setRect(QetGraphicsHandlerUtility::rectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
+				break;
 			}
-		}
-		setCursor(Qt::OpenHandCursor);
-	}
+			else {
+				setRect(QetGraphicsHandlerUtility::mirrorRectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
+				break;
+			}
+		case Ellipse:
+			if (m_resize_mode == 1) {
+				setRect(QetGraphicsHandlerUtility::rectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
+				break;
+			}
+			else {
+				setRect(QetGraphicsHandlerUtility::mirrorRectForPosAtIndex(QRectF(m_P1, m_P2), new_pos, m_vector_index));
+				break;
+			}
 
-	QetGraphicsItem::mouseReleaseEvent(event);
+		case Polygon:
+			prepareGeometryChange();
+			m_polygon.replace(m_vector_index, new_pos);
+			adjusteHandlerPos();
+			break;
+	}	//End switch
 }
 
-void QetShapeItem::switchResizeMode()
+/**
+ * @brief QetShapeItem::handlerMouseReleaseEvent
+ * @param qghi
+ * @param event
+ */
+void QetShapeItem::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
 {
-	if (m_resize_mode == 1) {
-		m_resize_mode = 2;
-		m_handler.setOuterColor(Qt::darkGreen);
+	Q_UNUSED(qghi);
+	Q_UNUSED(event);
+	
+	if (diagram())
+	{
+		QPropertyUndoCommand *undo = nullptr;
+		if ((m_shapeType & (Line | Rectangle | Ellipse)) && (m_P1 != m_old_P1 || m_P2 != m_old_P2))
+		{
+			switch(m_shapeType)
+			{
+				case Line:      undo = new QPropertyUndoCommand(this, "line",QLineF(m_old_P1, m_old_P2), QLineF(m_P1, m_P2)); break;
+				case Rectangle: undo = new QPropertyUndoCommand(this, "rect",QRectF(m_old_P1, m_old_P2), QRectF(m_P1, m_P2)); break;
+				case Ellipse:   undo = new QPropertyUndoCommand(this, "rect",QRectF(m_old_P1, m_old_P2), QRectF(m_P1, m_P2)); break;
+				case Polygon: break;
+			}
+			if (undo) undo->enableAnimation();
+		}
+		else if (m_shapeType == Polygon && (m_polygon != m_old_polygon))
+			undo = new QPropertyUndoCommand(this, "polygon", m_old_polygon, m_polygon);
+		
+		if(undo)
+		{
+			undo->setText(tr("Modifier %1").arg(name()));
+			diagram()->undoStack().push(undo);
+		}
 	}
-	else {
-		m_resize_mode = 1;
-		m_handler.setOuterColor(Qt::blue);
-	}
-	update();
 }
 
 /**

Modified: trunk/sources/qetgraphicsitem/qetshapeitem.h
===================================================================
--- trunk/sources/qetgraphicsitem/qetshapeitem.h	2017-08-01 19:37:04 UTC (rev 5000)
+++ trunk/sources/qetgraphicsitem/qetshapeitem.h	2017-08-02 15:26:14 UTC (rev 5001)
@@ -20,10 +20,11 @@
 
 #include <QPen>
 #include "qetgraphicsitem.h"
-#include "QetGraphicsItemModeler/qetgraphicshandlerutility.h"
+#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
 
 class QDomElement;
 class QDomDocument;
+class QetGraphicsHandlerItem;
 
 /**
  * @brief The QetShapeItem class
@@ -96,14 +97,18 @@
 	protected:
 		virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
 		virtual void hoverEnterEvent   (QGraphicsSceneHoverEvent *event);
-		virtual void hoverMoveEvent    (QGraphicsSceneHoverEvent *event);
 		virtual void hoverLeaveEvent   (QGraphicsSceneHoverEvent *event);
-		virtual void mousePressEvent   (QGraphicsSceneMouseEvent *event);
-		virtual void mouseMoveEvent    (QGraphicsSceneMouseEvent *event);
 		virtual void mouseReleaseEvent (QGraphicsSceneMouseEvent *event);
+        virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+        virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
 
 	private:
 		void switchResizeMode();
+		void adjusteHandlerPos();
+		
+		void handlerMousePressEvent   (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void handlerMouseMoveEvent    (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
+		void handlerMouseReleaseEvent (QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event);
 
 		///ATTRIBUTES
 	private:
@@ -112,11 +117,10 @@
 		QBrush       m_brush;
 		QPointF		 m_P1, m_P2, m_old_P1, m_old_P2;
 		QPolygonF	 m_polygon, m_old_polygon;
-		bool		 m_hovered,
-					 m_mouse_grab_handler;
+		bool		 m_hovered;
 		int			 m_vector_index;
-		QetGraphicsHandlerUtility m_handler;
 		bool m_close = false;
 		int m_resize_mode = 1;
+        QVector<QetGraphicsHandlerItem *> m_handler_vector;
 };
 #endif // QETSHAPEITEM_H


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