[no subject]

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


Modified Paths:
--------------
    branches/devel/sources/conductorautonumerotation.h
    branches/devel/sources/conductorautonumerotationwidget.h
    branches/devel/sources/conductorprofile.cpp
    branches/devel/sources/conductorpropertieswidget.cpp
    branches/devel/sources/diagram.cpp
    branches/devel/sources/diagramcommands.cpp
    branches/devel/sources/diagramcommands.h
    branches/devel/sources/diagramcontent.cpp
    branches/devel/sources/diagramview.cpp
    branches/devel/sources/editor/customelementpart.cpp
    branches/devel/sources/elementscategorieslist.cpp
    branches/devel/sources/elementscollectioncache.cpp
    branches/devel/sources/elementsmover.cpp
    branches/devel/sources/elementspanel.cpp
    branches/devel/sources/elementtextsmover.cpp
    branches/devel/sources/newelementwizard.cpp
    branches/devel/sources/nomenclature.h
    branches/devel/sources/qetdiagrameditor.cpp
    branches/devel/sources/qetgraphicsitem/diagramimageitem.cpp
    branches/devel/sources/qetgraphicsitem/diagramimageitem.h
    branches/devel/sources/qetgraphicsitem/qetgraphicsitem.cpp
    branches/devel/sources/qetgraphicsitem/qetgraphicsitem.h
    branches/devel/sources/terminal.cpp

Added Paths:
-----------
    branches/devel/sources/qetgraphicsitem/conductor.cpp
    branches/devel/sources/qetgraphicsitem/conductor.h
    branches/devel/sources/qetgraphicsitem/conductortextitem.cpp
    branches/devel/sources/qetgraphicsitem/conductortextitem.h
    branches/devel/sources/qetgraphicsitem/customelement.cpp
    branches/devel/sources/qetgraphicsitem/customelement.h
    branches/devel/sources/qetgraphicsitem/diagramtextitem.cpp
    branches/devel/sources/qetgraphicsitem/diagramtextitem.h
    branches/devel/sources/qetgraphicsitem/element.cpp
    branches/devel/sources/qetgraphicsitem/element.h
    branches/devel/sources/qetgraphicsitem/elementtextitem.cpp
    branches/devel/sources/qetgraphicsitem/elementtextitem.h
    branches/devel/sources/qetgraphicsitem/fixedelement.cpp
    branches/devel/sources/qetgraphicsitem/fixedelement.h
    branches/devel/sources/qetgraphicsitem/ghostelement.cpp
    branches/devel/sources/qetgraphicsitem/ghostelement.h
    branches/devel/sources/qetgraphicsitem/independenttextitem.cpp
    branches/devel/sources/qetgraphicsitem/independenttextitem.h

Removed Paths:
-------------
    branches/devel/sources/conductor.cpp
    branches/devel/sources/conductor.h
    branches/devel/sources/conductortextitem.cpp
    branches/devel/sources/conductortextitem.h
    branches/devel/sources/customelement.cpp
    branches/devel/sources/customelement.h
    branches/devel/sources/diagramtextitem.cpp
    branches/devel/sources/diagramtextitem.h
    branches/devel/sources/element.cpp
    branches/devel/sources/element.h
    branches/devel/sources/elementtextitem.cpp
    branches/devel/sources/elementtextitem.h
    branches/devel/sources/fixedelement.cpp
    branches/devel/sources/fixedelement.h
    branches/devel/sources/ghostelement.cpp
    branches/devel/sources/ghostelement.h
    branches/devel/sources/independenttextitem.cpp
    branches/devel/sources/independenttextitem.h


--Ofro6XGXHTz
Content-Disposition: attachment; filename=r2596-blacksun.diff
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Deleted: branches/devel/sources/conductor.cpp
===================================================================
--- branches/devel/sources/conductor.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/conductor.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -1,1631 +0,0 @@
-/*
-	Copyright 2006-2013 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 <QtDebug>
-#include "conductor.h"
-#include "conductorsegment.h"
-#include "conductorsegmentprofile.h"
-#include "conductortextitem.h"
-#include "element.h"
-#include "diagram.h"
-#include "diagramcommands.h"
-#include "conductorautonumerotation.h"
-#define PR(x) qDebug() << #x " = " << x;
-
-bool Conductor::pen_and_brush_initialized = false;
-QPen Conductor::conductor_pen = QPen();
-QBrush Conductor::conductor_brush = QBrush();
-QBrush Conductor::square_brush = QBrush(Qt::darkGreen);
-/**
-	Constructeur
-	@param p1              Premiere Borne a laquelle le conducteur est lie
-	@param p2              Seconde Borne a laquelle le conducteur est lie
-	@param parent_diagram  QGraphicsScene a laquelle appartient le conducteur
-*/
-Conductor::Conductor(Terminal *p1, Terminal* p2, Diagram *parent_diagram) :
-	QObject(),
-	QGraphicsPathItem(0, parent_diagram),
-	terminal1(p1),
-	terminal2(p2),
-	destroyed_(false),
-	text_item(0),
-	segments(NULL),
-	moving_point(false),
-	moving_segment(false),
-	modified_path(false),
-	has_to_save_profile(false),
-	segments_squares_scale_(1.0),
-	must_highlight_(Conductor::None)
-{
-	//set Zvalue at 9 to be upper than the DiagramImageItem and bottom of element(10)
-	setZValue(9);
-	previous_z_value = zValue();
-
-	// ajout du conducteur a la liste de conducteurs de chacune des deux bornes
-	bool ajout_p1 = terminal1 -> addConductor(this);
-	bool ajout_p2 = terminal2 -> addConductor(this);
-	
-	// en cas d'echec de l'ajout (conducteur deja existant notamment)
-	if (!ajout_p1 || !ajout_p2) return;
-	
-	// attributs de dessin par defaut (communs a tous les conducteurs)
-	if (!pen_and_brush_initialized) {
-		conductor_pen.setJoinStyle(Qt::MiterJoin);
-		conductor_pen.setCapStyle(Qt::SquareCap);
-		conductor_pen.setColor(Qt::black);
-		conductor_pen.setStyle(Qt::SolidLine);
-		conductor_pen.setWidthF(1.0);
-		conductor_brush.setColor(Qt::white);
-		conductor_brush.setStyle(Qt::NoBrush);
-		pen_and_brush_initialized = true;
-	}
-	
-	// par defaut, les 4 profils sont des profils nuls = il faut utiliser priv_calculeConductor
-	conductor_profiles.insert(Qt::TopLeftCorner,     ConductorProfile());
-	conductor_profiles.insert(Qt::TopRightCorner,    ConductorProfile());
-	conductor_profiles.insert(Qt::BottomLeftCorner,  ConductorProfile());
-	conductor_profiles.insert(Qt::BottomRightCorner, ConductorProfile());
-
-	// calcul du rendu du conducteur
-	generateConductorPath(terminal1 -> dockConductor(), terminal1 -> orientation(), terminal2 -> dockConductor(), terminal2 -> orientation());
-	setFlags(QGraphicsItem::ItemIsSelectable);
-	setAcceptsHoverEvents(true);
-	
-	// ajout du champ de texte editable
-	text_item = new ConductorTextItem(properties_.text, this);
-	calculateTextItemPosition();
-	connect(
-		text_item,
-		SIGNAL(diagramTextChanged(DiagramTextItem *, const QString &, const QString &)),
-		this,
-		SLOT(displayedTextChanged())
-	);
-}
-
-/**
-	Destructeur
-	Detruit le conducteur ainsi que ses segments. Il ne detruit pas les bornes
-	mais s'en detache
-*/
-Conductor::~Conductor() {
-	// se detache des bornes
-	if (!isDestroyed()) destroy();
-	
-	// supprime les segments
-	deleteSegments();
-}
-
-/**
-	Met a jour la representation graphique du conducteur en recalculant son
-	trace. Cette fonction est typiquement appelee lorsqu'une seule des bornes du
-	conducteur a change de position.
-	@param rect Rectangle a mettre a jour
-	@see QGraphicsPathItem::update()
-*/
-void Conductor::updatePath(const QRectF &rect) {
-	QPointF p1, p2;
-	p1 = terminal1 -> dockConductor();
-	p2 = terminal2 -> dockConductor();
-	if (segmentsCount() && !conductor_profiles[currentPathType()].isNull())
-		updateConductorPath(p1, terminal1 -> orientation(), p2, terminal2 -> orientation());
-	else
-		generateConductorPath(p1, terminal1 -> orientation(), p2, terminal2 -> orientation());
-	calculateTextItemPosition();
-	QGraphicsPathItem::update(rect);
-}
-
-/**
-	Genere le QPainterPath a partir de la liste des points
-*/
-void Conductor::segmentsToPath() {
-	// chemin qui sera dessine
-	QPainterPath path;
-	
-	// s'il n'y a pa des segments, on arrete la
-	if (segments == NULL) setPath(path);
-	
-	// demarre le chemin
-	path.moveTo(segments -> firstPoint());
-	
-	// parcourt les segments pour dessiner le chemin
-	ConductorSegment *segment = segments;
-	while(segment -> hasNextSegment()) {
-		path.lineTo(segment -> secondPoint());
-		segment = segment -> nextSegment();
-	}
-	
-	// termine le chemin
-	path.lineTo(segment -> secondPoint());
-	
-	// affecte le chemin au conducteur
-	setPath(path);
-}
-
-/**
-	Gere les updates
-	@param p1 Coordonnees du point d'amarrage de la borne 1
-	@param o1 Orientation de la borne 1
-	@param p2 Coordonnees du point d'amarrage de la borne 2
-	@param o2 Orientation de la borne 2
-*/
-void Conductor::updateConductorPath(const QPointF &p1, QET::Orientation o1, const QPointF &p2, QET::Orientation o2) {
-	Q_UNUSED(o1);
-	Q_UNUSED(o2);
-	
-	ConductorProfile &conductor_profile = conductor_profiles[currentPathType()];
-	
-	Q_ASSERT_X(conductor_profile.segmentsCount(QET::Both) > 1, "Conductor::priv_modifieConductor", "pas de points a modifier");
-	Q_ASSERT_X(!conductor_profile.isNull(),                 "Conductor::priv_modifieConductor", "pas de profil utilisable");
-	
-	// recupere les coordonnees fournies des bornes
-	QPointF new_p1 = mapFromScene(p1);
-	QPointF new_p2 = mapFromScene(p2);
-	QRectF new_rect = QRectF(new_p1, new_p2);
-	
-	// recupere la largeur et la hauteur du profil
-	qreal profile_width  = conductor_profile.width();
-	qreal profile_height = conductor_profile.height();
-	
-	// calcule les differences verticales et horizontales a appliquer
-	qreal h_diff = (qAbs(new_rect.width())  - qAbs(profile_width) ) * getSign(profile_width);
-	qreal v_diff = (qAbs(new_rect.height()) - qAbs(profile_height)) * getSign(profile_height);
-	
-	// applique les differences aux segments
-	QHash<ConductorSegmentProfile *, qreal> segments_lengths;
-	segments_lengths.unite(shareOffsetBetweenSegments(h_diff, conductor_profile.horizontalSegments()));
-	segments_lengths.unite(shareOffsetBetweenSegments(v_diff, conductor_profile.verticalSegments()));
-	
-	// en deduit egalement les coefficients d'inversion (-1 pour une inversion, +1 pour conserver le meme sens)
-	int horiz_coeff = getCoeff(new_rect.width(),  profile_width);
-	int verti_coeff = getCoeff(new_rect.height(), profile_height);
-	
-	// genere les nouveaux points
-	QList<QPointF> points;
-	points << new_p1;
-	int limit = conductor_profile.segments.count() - 1;
-	for (int i = 0 ; i < limit ; ++ i) {
-		// dernier point
-		QPointF previous_point = points.last();
-		
-		// profil de segment de conducteur en cours
-		ConductorSegmentProfile *csp = conductor_profile.segments.at(i);
-		
-		// coefficient et offset a utiliser pour ce point
-		qreal coeff = csp -> isHorizontal ? horiz_coeff : verti_coeff;
-		qreal offset_applied = segments_lengths[csp];
-		
-		// applique l'offset et le coeff au point
-		if (csp -> isHorizontal) {
-			points << QPointF (
-				previous_point.x() + (coeff * offset_applied),
-				previous_point.y()
-			);
-		} else {
-			points << QPointF (
-				previous_point.x(),
-				previous_point.y() + (coeff * offset_applied)
-			);
-		}
-	}
-	points << new_p2;
-	pointsToSegments(points);
-	segmentsToPath();
-}
-
-/**
-	@param offset Longueur a repartir entre les segments
-	@param segments_list Segments sur lesquels il faut repartir la longueur
-	@param precision seuil en-deca duquel on considere qu'il ne reste rien a repartir
-*/
-QHash<ConductorSegmentProfile *, qreal> Conductor::shareOffsetBetweenSegments(
-	const qreal &offset,
-	const QList<ConductorSegmentProfile *> &segments_list,
-	const qreal &precision
-) const {
-	// construit le QHash qui sera retourne
-	QHash<ConductorSegmentProfile *, qreal> segments_hash;
-	foreach(ConductorSegmentProfile *csp, segments_list) {
-		segments_hash.insert(csp, csp -> length);
-	}
-	
-	// memorise le signe de la longueur de chaque segement
-	QHash<ConductorSegmentProfile *, int> segments_signs;
-	foreach(ConductorSegmentProfile *csp, segments_hash.keys()) {
-		segments_signs.insert(csp, getSign(csp -> length));
-	}
-	
-	//qDebug() << "repartition d'un offset de" << offset << "px sur" << segments_list.count() << "segments";
-	
-	// repartit l'offset sur les segments
-	qreal remaining_offset = offset;
-	while (remaining_offset > precision || remaining_offset < -precision) {
-		// recupere le nombre de segments differents ayant une longueur non nulle
-		uint segments_count = 0;
-		foreach(ConductorSegmentProfile *csp, segments_hash.keys()) if (segments_hash[csp]) ++ segments_count;
-		//qDebug() << "  remaining_offset =" << remaining_offset;
-		qreal local_offset = remaining_offset / segments_count;
-		//qDebug() << "  repartition d'un offset local de" << local_offset << "px sur" << segments_count << "segments";
-		remaining_offset = 0.0;
-		foreach(ConductorSegmentProfile *csp, segments_hash.keys()) {
-			// ignore les segments de longueur nulle
-			if (!segments_hash[csp]) continue;
-			// applique l'offset au segment
-			//qreal segment_old_length = segments_hash[csp];
-			segments_hash[csp] += local_offset;
-			
-			// (la longueur du segment change de signe) <=> (le segment n'a pu absorbe tout l'offset)
-			if (segments_signs[csp] != getSign(segments_hash[csp])) {
-				
-				// on remet le trop-plein dans la reserve d'offset
-				remaining_offset += qAbs(segments_hash[csp]) * getSign(local_offset);
-				//qDebug() << "    trop-plein de" << qAbs(segments_hash[csp]) * getSign(local_offset) << "remaining_offset =" << remaining_offset;
-				segments_hash[csp] = 0.0;
-			} else {
-				//qDebug() << "    offset local de" << local_offset << "accepte";
-			}
-		}
-	}
-	
-	return(segments_hash);
-}
-
-/**
-	Calcule un trajet "par defaut" pour le conducteur
-	@param p1 Coordonnees du point d'amarrage de la borne 1
-	@param o1 Orientation de la borne 1
-	@param p2 Coordonnees du point d'amarrage de la borne 2
-	@param o2 Orientation de la borne 2
-*/
-void Conductor::generateConductorPath(const QPointF &p1, QET::Orientation o1, const QPointF &p2, QET::Orientation o2) {
-	QPointF sp1, sp2, depart, newp1, newp2, arrivee, depart0, arrivee0;
-	QET::Orientation ori_depart, ori_arrivee;
-	
-	// s'assure qu'il n'y a ni points
-	QList<QPointF> points;
-	
-	// mappe les points par rapport a la scene
-	sp1 = mapFromScene(p1);
-	sp2 = mapFromScene(p2);
-	
-	// prolonge les bornes
-	newp1 = extendTerminal(sp1, o1);
-	newp2 = extendTerminal(sp2, o2);
-	
-	// distingue le depart de l'arrivee : le trajet se fait toujours de gauche a droite (apres prolongation)
-	if (newp1.x() <= newp2.x()) {
-		depart      = newp1;
-		arrivee     = newp2;
-		depart0     = sp1;
-		arrivee0    = sp2;
-		ori_depart  = o1;
-		ori_arrivee = o2;
-	} else {
-		depart      = newp2;
-		arrivee     = newp1;
-		depart0     = sp2;
-		arrivee0    = sp1;
-		ori_depart  = o2;
-		ori_arrivee = o1;
-	}
-	
-	// debut du trajet
-	points << depart0;
-	
-	// prolongement de la borne de depart 
-	points << depart;
-	
-	// commence le vrai trajet
-	if (depart.y() < arrivee.y()) {
-		// trajet descendant
-		if ((ori_depart == QET::North && (ori_arrivee == QET::South || ori_arrivee == QET::West)) || (ori_depart == QET::East && ori_arrivee == QET::West)) {
-			// cas "3"
-			int ligne_inter_x = qRound(depart.x() + arrivee.x()) / 2;
-			while (ligne_inter_x % Diagram::xGrid) -- ligne_inter_x;
-			points << QPointF(ligne_inter_x, depart.y());
-			points << QPointF(ligne_inter_x, arrivee.y());
-		} else if ((ori_depart == QET::South && (ori_arrivee == QET::North || ori_arrivee == QET::East)) || (ori_depart == QET::West && ori_arrivee == QET::East)) {
-			// cas "4"
-			int ligne_inter_y = qRound(depart.y() + arrivee.y()) / 2;
-			while (ligne_inter_y % Diagram::yGrid) -- ligne_inter_y;
-			points << QPointF(depart.x(), ligne_inter_y);
-			points << QPointF(arrivee.x(), ligne_inter_y);
-		} else if ((ori_depart == QET::North || ori_depart == QET::East) && (ori_arrivee == QET::North || ori_arrivee == QET::East)) {
-			points << QPointF(arrivee.x(), depart.y()); // cas "2"
-		} else {
-			points << QPointF(depart.x(), arrivee.y()); // cas "1"
-		}
-	} else {
-		// trajet montant
-		if ((ori_depart == QET::West && (ori_arrivee == QET::East || ori_arrivee == QET::South)) || (ori_depart == QET::North && ori_arrivee == QET::South)) {
-			// cas "3"
-			int ligne_inter_y = qRound(depart.y() + arrivee.y()) / 2;
-			while (ligne_inter_y % Diagram::yGrid) -- ligne_inter_y;
-			points << QPointF(depart.x(), ligne_inter_y);
-			points << QPointF(arrivee.x(), ligne_inter_y);
-		} else if ((ori_depart == QET::East && (ori_arrivee == QET::West || ori_arrivee == QET::North)) || (ori_depart == QET::South && ori_arrivee == QET::North)) {
-			// cas "4"
-			int ligne_inter_x = qRound(depart.x() + arrivee.x()) / 2;
-			while (ligne_inter_x % Diagram::xGrid) -- ligne_inter_x;
-			points << QPointF(ligne_inter_x, depart.y());
-			points << QPointF(ligne_inter_x, arrivee.y());
-		} else if ((ori_depart == QET::West || ori_depart == QET::North) && (ori_arrivee == QET::West || ori_arrivee == QET::North)) {
-			points << QPointF(depart.x(), arrivee.y()); // cas "2"
-		} else {
-			points << QPointF(arrivee.x(), depart.y()); // cas "1"
-		}
-	}
-	
-	// fin du vrai trajet
-	points << arrivee;
-	
-	// prolongement de la borne d'arrivee
-	points << arrivee0;
-	
-	// inverse eventuellement l'ordre des points afin que le trajet soit exprime de la borne 1 vers la borne 2
-	if (newp1.x() > newp2.x()) {
-		QList<QPointF> points2;
-		for (int i = points.size() - 1 ; i >= 0 ; -- i) points2 << points.at(i);
-		points = points2;
-	}
-	
-	pointsToSegments(points);
-	segmentsToPath();
-}
-
-/**
-	Prolonge une borne.
-	@param terminal Le point correspondant a la borne
-	@param terminal_orientation L'orientation de la borne
-	@param ext_size la taille de la prolongation
-	@return le point correspondant a la borne apres prolongation
-*/
-QPointF Conductor::extendTerminal(const QPointF &terminal, QET::Orientation terminal_orientation, qreal ext_size) {
-	QPointF extended_terminal;
-	switch(terminal_orientation) {
-		case QET::North:
-			extended_terminal = QPointF(terminal.x(), terminal.y() - ext_size);
-			break;
-		case QET::East:
-			extended_terminal = QPointF(terminal.x() + ext_size, terminal.y());
-			break;
-		case QET::South:
-			extended_terminal = QPointF(terminal.x(), terminal.y() + ext_size);
-			break;
-		case QET::West:
-			extended_terminal = QPointF(terminal.x() - ext_size, terminal.y());
-			break;
-		default: extended_terminal = terminal;
-	}
-	return(extended_terminal);
-}
-
-/**
-	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);
-	qp -> save();
-	qp -> setRenderHint(QPainter::Antialiasing, false);
-	
-	// determine la couleur du conducteur
-	QColor final_conductor_color(properties_.color);
-	if (must_highlight_ == Normal) {
-		final_conductor_color = QColor::fromRgb(69, 137, 255, 255);
-	} else if (must_highlight_ == Alert) {
-		final_conductor_color =QColor::fromRgb(255, 69, 0, 255);
-	} else if (isSelected()) {
-		final_conductor_color = Qt::red;
-	} else {
-		if (Diagram *parent_diagram = diagram()) {
-			if (!parent_diagram -> drawColoredConductors()) {
-				final_conductor_color = Qt::black;
-			}
-		}
-	}
-	
-	// affectation du QPen et de la QBrush modifies au QPainter
-	qp -> setBrush(conductor_brush);
-	QPen final_conductor_pen = conductor_pen;
-	
-	// modification du QPen generique pour lui affecter la couleur et le style adequats
-	final_conductor_pen.setColor(final_conductor_color);
-	final_conductor_pen.setStyle(properties_.style);
-	final_conductor_pen.setJoinStyle(Qt::SvgMiterJoin); // meilleur rendu des pointilles
-	
-	// utilisation d'un trait "cosmetique" en-dessous d'un certain zoom
-	if (options && options -> levelOfDetail < 1.0) {
-		final_conductor_pen.setCosmetic(true);
-	}
-	
-	qp -> setPen(final_conductor_pen);
-	
-	// dessin du conducteur
-	qp -> drawPath(path());
-	if (properties_.type == ConductorProperties::Single) {
-		qp -> setBrush(final_conductor_color);
-		properties_.singleLineProperties.draw(
-			qp,
-			middleSegment() -> isHorizontal() ? QET::Horizontal : QET::Vertical,
-			QRectF(middleSegment() -> middle() - QPointF(12.0, 12.0), QSizeF(24.0, 24.0))
-		);
-		if (isSelected()) qp -> setBrush(Qt::NoBrush);
-	}
-	
-	// decalage ideal pour le rendu centre d'un carre / cercle de 2.0 px de cote / diametre
-	qreal pretty_offset = (options -> levelOfDetail == 1 ? 1.0 : 1.0);
-	
-	// dessin des points d'accroche du conducteur si celui-ci est selectionne
-	if (isSelected()) {
-		QList<QPointF> points = segmentsToPoints();
-		QPointF previous_point;
-		for (int i = 1 ; i < (points.size() -1) ; ++ i) {
-			QPointF point = points.at(i);
-				
-			// dessine le carre de saisie du segment
-			if (i > 1) {
-				qp -> fillRect(
-					QRectF(
-						((previous_point.x() + point.x()) / 2.0 ) - pretty_offset * segments_squares_scale_,
-						((previous_point.y() + point.y()) / 2.0 ) - pretty_offset * segments_squares_scale_,
-						2.0 * segments_squares_scale_,
-						2.0 * segments_squares_scale_
-					),
-					square_brush
-				);
-			}
-			previous_point = point;
-		}
-	}
-	
-	// dessine les eventuelles jonctions
-	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);
-		foreach(QPointF point, junctions_list) {
-			qp -> drawEllipse(QRectF(point.x() - pretty_offset, point.y() - pretty_offset, 2.0, 2.0));
-		}
-	}
-	qp -> restore();
-}
-
-/**
-	Methode de preparation a la destruction du conducteur ; le conducteur se detache de ses deux bornes
-*/
-void Conductor::destroy() {
-	destroyed_ = true;
-	terminal1 -> removeConductor(this);
-	terminal2 -> removeConductor(this);
-}
-
-/// @return le Diagram auquel ce conducteur appartient, ou 0 si ce conducteur est independant
-Diagram *Conductor::diagram() const {
-	return(qobject_cast<Diagram *>(scene()));
-}
-
-/**
-	@return le champ de texte associe a ce conducteur
-*/
-ConductorTextItem *Conductor::textItem() const {
-	return(text_item);
-}
-
-/**
-	Methode de validation d'element XML
-	@param e Un element XML sense represente un Conducteur
-	@return true si l'element XML represente bien un Conducteur ; false sinon
-*/
-bool Conductor::valideXml(QDomElement &e){
-	// verifie le nom du tag
-	if (e.tagName() != "conductor") return(false);
-	
-	// verifie la presence des attributs minimaux
-	if (!e.hasAttribute("terminal1")) return(false);
-	if (!e.hasAttribute("terminal2")) return(false);
-	
-	bool conv_ok;
-	// parse l'abscisse
-	e.attribute("terminal1").toInt(&conv_ok);
-	if (!conv_ok) return(false);
-	
-	// parse l'ordonnee
-	e.attribute("terminal2").toInt(&conv_ok);
-	if (!conv_ok) return(false);
-	return(true);
-}
-
-/**
-	Gere les clics sur le conducteur.
-	@param e L'evenement decrivant le clic.
-*/
-void Conductor::mousePressEvent(QGraphicsSceneMouseEvent *e) {
-	// clic gauche
-	if (e -> buttons() & Qt::LeftButton) {
-		// recupere les coordonnees du clic
-		press_point = e -> pos();
-		
-		/*
-			parcourt les segments pour determiner si le clic a eu lieu
-			- sur l'extremite d'un segment
-			- sur le milieu d'un segment
-			- ailleurs
-		*/
-		ConductorSegment *segment = segments;
-		while (segment -> hasNextSegment()) {
-			if (hasClickedOn(press_point, segment -> secondPoint())) {
-				moving_point = true;
-				moving_segment = false;
-				moved_segment = segment;
-				break;
-			} else if (hasClickedOn(press_point, segment -> middle())) {
-				moving_point = false;
-				moving_segment = true;
-				moved_segment = segment;
-				break;
-			}
-			segment = segment -> nextSegment();
-		}
-		if (moving_segment || moving_point) {
-			// en cas de debut de modification de conducteur, on memorise la position du champ de texte
-			before_mov_text_pos_ = text_item -> pos();
-		}
-	}
-	QGraphicsPathItem::mousePressEvent(e);
-	if (e -> modifiers() & Qt::ControlModifier) {
-		setSelected(!isSelected());
-	}
-}
-
-/**
-	Gere les deplacements de souris sur le conducteur.
-	@param e L'evenement decrivant le deplacement de souris.
-*/
-void Conductor::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
-	// clic gauche
-	if (e -> buttons() & Qt::LeftButton) {
-		// position pointee par la souris
-		qreal mouse_x = e -> pos().x();
-		qreal mouse_y = e -> pos().y();
-		
-		bool snap_conductors_to_grid = e -> modifiers() ^ Qt::ShiftModifier;
-		if (snap_conductors_to_grid) {
-			mouse_x = qRound(mouse_x / (Diagram::xGrid * 1.0)) * Diagram::xGrid;
-			mouse_y = qRound(mouse_y / (Diagram::yGrid * 1.0)) * Diagram::yGrid;
-		}
-		
-		if (moving_point) {
-			// la modification par points revient bientot
-			/*
-			// position precedente du point
-			QPointF p = moved_segment -> secondPoint();
-			qreal p_x = p.x();
-			qreal p_y = p.y();
-			
-			// calcul du deplacement
-			moved_segment -> moveX(mouse_x - p_x());
-			moved_segment -> moveY(mouse_y - p_y());
-			
-			// application du deplacement
-			modified_path = true;
-			updatePoints();
-			segmentsToPath();
-			*/
-		} else if (moving_segment) {
-			// position precedente du point
-			QPointF p = moved_segment -> middle();
-			
-			// calcul du deplacement
-			moved_segment -> moveX(mouse_x - p.x());
-			moved_segment -> moveY(mouse_y - p.y());
-			
-			// application du deplacement
-			modified_path = true;
-			has_to_save_profile = true;
-			segmentsToPath();
-			calculateTextItemPosition();
-		}
-	}
-	QGraphicsPathItem::mouseMoveEvent(e);
-}
-
-/**
-	Gere les relachements de boutons de souris sur le conducteur 
-	@param e L'evenement decrivant le lacher de bouton.
-*/
-void Conductor::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
-	// clic gauche
-	moving_point = false;
-	moving_segment = false;
-	if (has_to_save_profile) {
-		saveProfile();
-		has_to_save_profile = false;
-	}
-	if (!(e -> modifiers() & Qt::ControlModifier)) {
-		QGraphicsPathItem::mouseReleaseEvent(e);
-	}
-	calculateTextItemPosition();
-}
-
-/**
-	Gere l'entree de la souris dans la zone du conducteur
-	@param e Le QGraphicsSceneHoverEvent decrivant l'evenement
-*/
-void Conductor::hoverEnterEvent(QGraphicsSceneHoverEvent *e) {
-	Q_UNUSED(e);
-	segments_squares_scale_ = 2.0;
-	if (isSelected()) {
-		update();
-	}
-}
-
-/**
-	Gere la sortie de la souris de la zone du conducteur
-	@param e Le QGraphicsSceneHoverEvent decrivant l'evenement
-*/
-void Conductor::hoverLeaveEvent(QGraphicsSceneHoverEvent *e) {
-	Q_UNUSED(e);
-	segments_squares_scale_ = 1.0;
-	if (isSelected()) {
-		update();
-	}
-}
-
-/**
-	Gere les mouvements de souris au dessus du conducteur
-	@param e Le QGraphicsSceneHoverEvent decrivant l'evenement
-*/
-void Conductor::hoverMoveEvent(QGraphicsSceneHoverEvent *e) {
-	/*
-	if (isSelected()) {
-		QPointF hover_point = mapFromScene(e -> pos());
-		ConductorSegment *segment = segments;
-		bool cursor_set = false;
-		while (segment -> hasNextSegment()) {
-			if (hasClickedOn(hover_point, segment -> secondPoint())) {
-				setCursor(Qt::CrossCursor);
-				cursor_set = true;
-			} else if (hasClickedOn(hover_point, segment -> middle())) {
-				setCursor(segment -> isVertical() ? Qt::SplitHCursor : Qt::SplitVCursor);
-				cursor_set = true;
-			}
-			segment = segment -> nextSegment();
-		}
-		if (!cursor_set) setCursor(Qt::ArrowCursor);
-	}
-	*/
-	QGraphicsPathItem::hoverMoveEvent(e);
-}
-
-/**
-	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
-		calculateTextItemPosition();
-	} else if (change == QGraphicsItem::ItemVisibleHasChanged) {
-		// permet de positionner correctement le texte du conducteur lors de son ajout a un schema
-		calculateTextItemPosition();
-	}
-	return(QGraphicsPathItem::itemChange(change, value));
-}
-
-/**
-	@return Le rectangle delimitant l'espace de dessin du conducteur
-*/
-QRectF Conductor::boundingRect() const {
-	QRectF retour = QGraphicsPathItem::boundingRect();
-	retour.adjust(-11.0, -11.0, 11.0, 11.0);
-	return(retour);
-}
-
-/**
-	@return La forme / zone "cliquable" du conducteur (epaisseur : 5.0px).
-	@see variableShape()
-*/
-QPainterPath Conductor::shape() const {
-	return(variableShape(5.0));
-}
-
-/**
-	@return la distance en dessous de laquelle on considere qu'un point est a
-	proximite du trajet du conducteur. La valeur est actuellement fixee a
-	60.0px.
-*/
-qreal Conductor::nearDistance() const {
-	return(60.0);
-}
-
-/**
-	@return la zone dans laquelle dont on considere que tous les points sont a
-	proximite du trajet du conducteur.
-	@see nearDistance()
-	@see variableShape()
-*/
-QPainterPath Conductor::nearShape() const {
-	return(variableShape(nearDistance()));
-}
-
-/**
-	@return la forme du conducteur
-	@param thickness la moitie de l'epaisseur voulue pour cette forme
-*/
-QPainterPath Conductor::variableShape(const qreal &thickness) const {
-	qreal my_thickness = qAbs(thickness);
-	
-	QList<QPointF> points = segmentsToPoints();
-	QPainterPath area;
-	QPointF previous_point;
-	QPointF *point1, *point2;
-	foreach(QPointF point, points) {
-		if (!previous_point.isNull()) {
-			if (point.x() == previous_point.x()) {
-				if (point.y() <= previous_point.y()) {
-					point1 = &point;
-					point2 = &previous_point;
-				} else {
-					point1 = &previous_point;
-					point2 = &point;
-				}
-			} else {
-				if (point.x() <= previous_point.x()) {
-					point1 = &point;
-					point2 = &previous_point;
-				} else {
-					point1 = &previous_point;
-					point2 = &point;
-				}
-			}
-			qreal p1_x = point1 -> x();
-			qreal p1_y = point1 -> y();
-			qreal p2_x = point2 -> x();
-			qreal p2_y = point2 -> y();
-			area.setFillRule(Qt::OddEvenFill);
-			area.addRect(p1_x - my_thickness, p1_y - my_thickness, my_thickness * 2.0 + p2_x - p1_x, my_thickness * 2.0  + p2_y - p1_y);
-		}
-		previous_point = point;
-		area.setFillRule(Qt::WindingFill);
-		area.addRect(point.x() - my_thickness, point.y() - my_thickness, my_thickness * 2.0, my_thickness * 2.0 );
-	}
-	return(area);
-}
-
-/**
-	@param point un point, exprime dans les coordonnees du conducteur
-	@return true si le point est a proximite du conducteur, c-a-d a moins de
-	60px du conducteur.
-*/
-bool Conductor::isNearConductor(const QPointF &point) {
-	return(variableShape(60.1).contains(point));
-}
-
-/**
-	Renvoie une valeur donnee apres l'avoir bornee entre deux autres valeurs,
-	en y ajoutant une marge interne.
-	@param tobound valeur a borner
-	@param bound1 borne 1
-	@param bound2 borne 2
-	@param space marge interne ajoutee
-	@return La valeur bornee
-*/
-qreal Conductor::conductor_bound(qreal tobound, qreal bound1, qreal bound2, qreal space) {
-	qDebug() << "will bound" << tobound << "between" << bound1 << "and" << bound2 ;
-	if (bound1 < bound2) {
-		return(qBound(bound1 + space, tobound, bound2 - space));
-	} else {
-		return(qBound(bound2 + space, tobound, bound1 - space));
-	}
-}
-
-/**
-	Renvoie une valeur donnee apres l'avoir bornee avant ou apres une valeur.
-	@param tobound valeur a borner
-	@param bound borne
-	@param positive true pour borner la valeur avant la borne, false sinon
-	@return La valeur bornee
-*/
-qreal Conductor::conductor_bound(qreal tobound, qreal bound, bool positive) {
-	qreal space = 5.0;
-	return(positive ? qMax(tobound, bound + space) : qMin(tobound, bound - space));
-}
-
-/**
-	@param type Type de Segments
-	@return Le nombre de segments composant le conducteur.
-*/
-uint Conductor::segmentsCount(QET::ConductorSegmentType type) const {
-	QList<ConductorSegment *> segments_list = segmentsList();
-	if (type == QET::Both) return(segments_list.count());
-	uint nb_seg = 0;
-	foreach(ConductorSegment *conductor_segment, segments_list) {
-		if (conductor_segment -> type() == type) ++ nb_seg;
-	}
-	return(nb_seg);
-}
-
-/**
-	Genere une liste de points a partir des segments de ce conducteur
-	@return La liste de points representant ce conducteur
-*/
-QList<QPointF> Conductor::segmentsToPoints() const {
-	// liste qui sera retournee
-	QList<QPointF> points_list;
-	
-	// on retourne la liste tout de suite s'il n'y a pas de segments
-	if (segments == NULL) return(points_list);
-	
-	// recupere le premier point
-	points_list << segments -> firstPoint();
-	
-	// parcourt les segments pour recuperer les autres points
-	ConductorSegment *segment = segments;
-	while(segment -> hasNextSegment()) {
-		points_list << segment -> secondPoint();
-		segment = segment -> nextSegment();
-	}
-	
-	// recupere le dernier point
-	points_list << segment -> secondPoint();
-	
-	//retourne la liste
-	return(points_list);
-}
-
-/**
-	Regenere les segments de ce conducteur a partir de la liste de points passee en parametre
-	@param points_list Liste de points a utiliser pour generer les segments
-*/
-void Conductor::pointsToSegments(QList<QPointF> points_list) {
-	// supprime les segments actuels
-	deleteSegments();
-	
-	// cree les segments a partir de la liste de points
-	ConductorSegment *last_segment = NULL;
-	for (int i = 0 ; i < points_list.size() - 1 ; ++ i) {
-		last_segment = new ConductorSegment(points_list.at(i), points_list.at(i + 1), last_segment);
-		if (!i) segments = last_segment;
-	}
-}
-
-/**
-	Permet de savoir si un point est tres proche d'un autre. Cela sert surtout
-	pour determiner si un clic a ete effectue pres d'un point donne.
-	@param press_point Point effectivement clique
-	@param point point cliquable
-	@return true si l'on peut considerer que le point a ete clique, false sinon
-*/
-bool Conductor::hasClickedOn(QPointF press_point, QPointF point) const {
-	return (
-		press_point.x() >= point.x() - 5.0 &&\
-		press_point.x() <  point.x() + 5.0 &&\
-		press_point.y() >= point.y() - 5.0 &&\
-		press_point.y() <  point.y() + 5.0
-	);
-}
-
-/**
-	Charge les caracteristiques du conducteur depuis un element XML.
-	@param e Un element XML
-	@return true si le chargement a reussi, false sinon
-*/
-bool Conductor::fromXml(QDomElement &e) {
-	// recupere la "configuration" du conducteur
-	properties_.fromXml(e);
-	readProperties();
-	qreal user_pos_x, user_pos_y;
-	if (
-		QET::attributeIsAReal(e, "userx", &user_pos_x) &&
-		QET::attributeIsAReal(e, "usery", &user_pos_y)
-	) {
-		text_item -> forceMovedByUser(true);
-		text_item -> setPos(user_pos_x, user_pos_y);
-	}
-	if (e.hasAttribute("rotation")) {
-		text_item -> setRotationAngle(e.attribute("rotation").toDouble());
-		text_item -> forceRotateByUser(true);
-	}
-	
-	// parcourt les elements XML "segment" et en extrait deux listes de longueurs
-	// les segments non valides sont ignores
-	QList<qreal> segments_x, segments_y;
-	for (QDomNode node = e.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
-		// on s'interesse aux elements XML "segment"
-		QDomElement current_segment = node.toElement();
-		if (current_segment.isNull() || current_segment.tagName() != "segment") continue;
-		
-		// le segment doit avoir une longueur
-		if (!current_segment.hasAttribute("length")) continue;
-		
-		// cette longueur doit etre un reel
-		bool ok;
-		qreal segment_length = current_segment.attribute("length").toDouble(&ok);
-		if (!ok) continue;
-		
-		if (current_segment.attribute("orientation") == "horizontal") {
-			segments_x << segment_length;
-			segments_y << 0.0;
-		} else {
-			segments_x << 0.0;
-			segments_y << segment_length;
-		}
-	}
-	
-	// s'il n'y a pas de segments, on renvoie true
-	if (!segments_x.size()) return(true);
-	// les longueurs recueillies doivent etre coherentes avec les positions des bornes
-	qreal width = 0.0, height = 0.0;
-	foreach (qreal t, segments_x) width  += t;
-	foreach (qreal t, segments_y) height += t;
-	QPointF t1 = terminal1 -> dockConductor();
-	QPointF t2 = terminal2 -> dockConductor();
-	qreal expected_width  = t2.x() - t1.x();
-	qreal expected_height = t2.y() - t1.y();
-	
-	// on considere que le trajet est incoherent a partir d'une unite de difference avec l'espacement entre les bornes
-	if (
-		qAbs(expected_width  - width)  > 1.0 ||
-		qAbs(expected_height - height) > 1.0
-	) {
-		qDebug() << "Conductor::fromXml : les segments du conducteur ne semblent pas coherents - utilisation d'un trajet automatique";
-		return(false);
-	}
-	
-	/* on recree les segments a partir des donnes XML */
-	// cree la liste de points
-	QList<QPointF> points_list;
-	points_list << t1;
-	for (int i = 0 ; i < segments_x.size() ; ++ i) {
-		points_list << QPointF(
-			points_list.last().x() + segments_x.at(i),
-			points_list.last().y() + segments_y.at(i)
-		);
-	}
-	
-	pointsToSegments(points_list);
-	
-	// initialise divers parametres lies a la modification des conducteurs
-	modified_path = true;
-	saveProfile(false);
-	
-	segmentsToPath();
-	return(true);
-}
-
-/**
-	Exporte les caracteristiques du conducteur sous forme d'une element XML.
-	@param d Le document XML a utiliser pour creer l'element XML
-	@param table_adr_id Hash stockant les correspondances entre les ids des
-	bornes dans le document XML et leur adresse en memoire
-	@return Un element XML representant le conducteur
-*/
-QDomElement Conductor::toXml(QDomDocument &d, QHash<Terminal *, int> &table_adr_id) const {
-	QDomElement e = d.createElement("conductor");
-	e.setAttribute("terminal1", table_adr_id.value(terminal1));
-	e.setAttribute("terminal2", table_adr_id.value(terminal2));
-	
-	// on n'exporte les segments du conducteur que si ceux-ci ont
-	// ete modifies par l'utilisateur
-	if (modified_path) {
-		// parcours et export des segments
-		QDomElement current_segment;
-		foreach(ConductorSegment *segment, segmentsList()) {
-			current_segment = d.createElement("segment");
-			current_segment.setAttribute("orientation", segment -> isHorizontal() ? "horizontal" : "vertical");
-			current_segment.setAttribute("length", QString("%1").arg(segment -> length()));
-			e.appendChild(current_segment);
-		}
-	}
-	
-	// exporte la "configuration" du conducteur
-	properties_.toXml(e);
-	if (text_item -> wasRotateByUser()) {
-		e.setAttribute("rotation", QString("%1").arg(text_item -> rotationAngle()));
-	}
-	if (text_item -> wasMovedByUser()) {
-		e.setAttribute("userx", QString("%1").arg(text_item -> pos().x()));
-		e.setAttribute("usery", QString("%1").arg(text_item -> pos().y()));
-	}
-	return(e);
-}
-
-/// @return les segments de ce conducteur
-const QList<ConductorSegment *> Conductor::segmentsList() const {
-	if (segments == NULL) return(QList<ConductorSegment *>());
-	
-	QList<ConductorSegment *> segments_vector;
-	ConductorSegment *segment = segments;
-	
-	while (segment -> hasNextSegment()) {
-		segments_vector << segment;
-		segment = segment -> nextSegment();
-	}
-	segments_vector << segment;
-	return(segments_vector);
-}
-
-/**
-	@return La longueur totale du conducteur
-*/
-qreal Conductor::length() {
-	qreal length = 0.0;
-	
-	ConductorSegment *s = segments;
-	while (s -> hasNextSegment()) {
-		length += qAbs(s -> length());
-		s = s -> nextSegment();
-	}
-	
-	return(length);
-}
-
-/**
-	@return Le segment qui contient le point au milieu du conducteur
-*/
-ConductorSegment *Conductor::middleSegment() {
-	if (segments == NULL) return(NULL);
-	
-	qreal half_length = length() / 2.0;
-	
-	ConductorSegment *s = segments;
-	qreal l = 0;
-	
-	while (s -> hasNextSegment()) {
-		l += qAbs(s -> length());
-		if (l >= half_length) break;
-		s = s -> nextSegment();
-	}
-	// s est le segment qui contient le point au milieu du conducteur
-	return(s);
-}
-
-/**
-	Positionne le texte du conducteur au milieu du segment qui contient le
-	point au milieu du conducteur
-	@see middleSegment()
-*/
-void Conductor::calculateTextItemPosition() {
-	if (!text_item) return;
-	
-	//position
-	if (text_item -> wasMovedByUser()) {
-		// le champ de texte a ete deplace par l'utilisateur :
-		// on verifie qu'il est encore a proximite du conducteur
-		QPointF text_item_pos = text_item -> pos();
-		QPainterPath near_shape = nearShape();
-		if (!near_shape.contains(text_item_pos)) {
-			text_item -> setPos(movePointIntoPolygon(text_item_pos, near_shape));
-		}
-	} else {
-		// positionnement automatique basique
-		text_item -> setPos(middleSegment() -> middle());
-		//rotation
-		if (!text_item -> wasRotateByUser()) {
-			middleSegment() -> isVertical()? text_item -> setRotationAngle(properties_.verti_rotate_text):
-											 text_item -> setRotationAngle(properties_.horiz_rotate_text);
-		}
-	}
-}
-
-/**
-	Sauvegarde le profil courant du conducteur pour l'utiliser ulterieurement
-	dans priv_modifieConductor.
-*/
-void Conductor::saveProfile(bool undo) {
-	Qt::Corner current_path_type = currentPathType();
-	ConductorProfile old_profile(conductor_profiles[current_path_type]);
-	conductor_profiles[current_path_type].fromConductor(this);
-	Diagram *dia = diagram();
-	if (undo && dia) {
-		ChangeConductorCommand *undo_object = new ChangeConductorCommand(
-			this,
-			old_profile,
-			conductor_profiles[current_path_type],
-			current_path_type
-		);
-		undo_object -> setConductorTextItemMove(before_mov_text_pos_, text_item -> pos());
-		dia -> undoStack().push(undo_object);
-	}
-}
-
-/**
-	@param value1 Premiere valeur
-	@param value2 Deuxieme valeur
-	@return 1 si les deux valeurs sont de meme signe, -1 sinon
-*/
-int Conductor::getCoeff(const qreal &value1, const qreal &value2) {
-	return(getSign(value1) * getSign(value2));
-}
-
-/**
-	@param value valeur
-	@return 1 si valeur est negatif, 1 s'il est positif ou nul
-*/
-int Conductor::getSign(const qreal &value) {
-	return(value < 0 ? -1 : 1);
-}
-
-/**
-	Applique un nouveau profil a ce conducteur
-	@param cp Profil a appliquer a ce conducteur
-	@param path_type Type de trajet pour lequel ce profil convient
-*/
-void Conductor::setProfile(const ConductorProfile &cp, Qt::Corner path_type) {
-	conductor_profiles[path_type] = cp;
-	// si le type de trajet correspond a l'actuel
-	if (currentPathType() == path_type) {
-		if (conductor_profiles[path_type].isNull()) {
-			generateConductorPath(terminal1 -> dockConductor(), terminal1 -> orientation(), terminal2 -> dockConductor(), terminal2 -> orientation());
-			modified_path = false;
-		} else {
-			updateConductorPath(terminal1 -> dockConductor(), terminal1 -> orientation(), terminal2 -> dockConductor(), terminal2 -> orientation());
-			modified_path = true;
-		}
-		if (type() == ConductorProperties::Multi) {
-			calculateTextItemPosition();
-		}
-	}
-}
-
-/// @return le profil de ce conducteur
-ConductorProfile Conductor::profile(Qt::Corner path_type) const {
-	return(conductor_profiles[path_type]);
-}
-
-/// @return le texte du conducteur
-QString Conductor::text() const {
-	return(text_item -> toPlainText());
-}
-
-/**
-	@param t Nouveau texte du conducteur
-*/
-void Conductor::setText(const QString &t) {
-	text_item -> setPlainText(t);
-}
-
-/// @param p les proprietes de ce conducteur
-void Conductor::setProperties(const ConductorProperties &p) {
-	properties_ = p;
-	readProperties();
-}
-
-/// @return les proprietes de ce conducteur
-ConductorProperties Conductor::properties() const {
-	return(properties_);
-}
-
-/**
-	Relit les proprietes et les applique
-*/
-void Conductor::readProperties() {
-	// la couleur n'est vraiment applicable que lors du rendu du conducteur
-	setText(properties_.text);
-	calculateTextItemPosition();
-	text_item -> setVisible(properties_.type == ConductorProperties::Multi);
-}
-
-/**
-	S'assure que le texte du conducteur est a une position raisonnable
-	Cette methode ne fait rien si ce conducteur n'affiche pas son champ de
-	texte.
-*/
-void Conductor::adjustTextItemPosition() {
-	calculateTextItemPosition();
-}
-
-/**
-	@return true si le conducteur est mis en evidence
-*/
-Conductor::Highlight Conductor::highlight() const {
-	return(must_highlight_);
-}
-
-/**
-	@param hl true pour mettre le conducteur en evidence, false sinon
-*/
-void Conductor::setHighlighted(Conductor::Highlight hl) {
-	must_highlight_ = hl;
-	update();
-}
-
-/**
- * @brief Conductor::autoText
- *lance l'autoNumerotation sur ce conducteur
- */
-void Conductor::autoText() {
-	ConductorAutoNumerotation can(this);
-	can.numerate();
-}
-
-/**
-	Met a jour les proprietes du conducteur apres modification du champ de texte affiche
-*/
-void Conductor::displayedTextChanged() {
-	// verifie que le texte a reellement change
-	if (text_item -> toPlainText() == properties_.text) return;
-	
-	if (Diagram *my_diagram = diagram()) {
-		int qmbreturn=0;
-		//if conductor isn't alone at this potential
-		//ask user to apply text on every conductors of this potential
-		if (relatedPotentialConductors().size() >= 1){
-			qmbreturn = QMessageBox::question(diagramEditor(), tr("Textes de conducteurs"),
-											  tr("Voulez-vous appliquer le nouveau texte \n"
-												 "\340 l'ensemble des conducteurs de ce potentiel ?"),
-											  QMessageBox::No| QMessageBox::Yes, QMessageBox::Yes);
-			if (qmbreturn == QMessageBox::Yes){
-				ConductorAutoNumerotation can(this);
-				can.applyText(text_item -> toPlainText());
-			}
-		}
-		if (qmbreturn == 0 || qmbreturn == QMessageBox::No) {
-			// initialise l'objet UndoCommand correspondant
-			ConductorProperties new_properties(properties_);
-			new_properties.text = text_item -> toPlainText();
-
-			ChangeConductorPropertiesCommand *ccpc = new ChangeConductorPropertiesCommand(this);
-			ccpc -> setOldSettings(properties_);
-			ccpc -> setNewSettings(new_properties);
-			my_diagram -> undoStack().push(ccpc);
-		}
-	}
-}
-
-/**
-	@return les conducteurs avec lesquels ce conducteur partage des bornes
-	communes
-*/
-QSet<Conductor *> Conductor::relatedConductors() const {
-	QList<Conductor *> other_conductors_list = terminal1 -> conductors();
-	other_conductors_list += terminal2 -> conductors();
-	QSet<Conductor *> other_conductors = other_conductors_list.toSet();
-	other_conductors.remove(const_cast<Conductor *>(this));
-	return(other_conductors);
-}
-
-/**
- * @param t_list terminaux a ne pas inclure dans la recherche
- * @return les conducteurs avec lesquels ce conducteur partage
- *  le meme potentiel electrique a l'exception de lui même
- */
-QSet<Conductor *> Conductor::relatedPotentialConductors(QList <Terminal *> *t_list) {
-	bool declar_t_list = false;
-	if (t_list == 0) {
-		declar_t_list = true;
-		t_list = new QList <Terminal *>;
-	}
-
-	QSet <Conductor *> other_conductors;
-	//renvoie tous les conducteurs du terminal 1
-	if (!t_list -> contains(terminal1)) {
-		t_list -> append(terminal1);
-		QList <Conductor *> other_conductors_list_t1 = terminal1 -> conductors();
-		other_conductors_list_t1.removeAll(this);
-		//recherche les conducteurs connecté au conducteur déjà trouvé
-		foreach (Conductor *c, other_conductors_list_t1) {
-			other_conductors += c -> relatedPotentialConductors(t_list);
-		}
-		other_conductors += other_conductors_list_t1.toSet();
-	}
-	//renvoie tous les conducteurs du terminal 2
-	if (!t_list -> contains(terminal2)) {
-		t_list -> append(terminal2);
-		QList <Conductor *> other_conductors_list_t2 = terminal2 -> conductors();
-		other_conductors_list_t2.removeAll(this);
-		//recherche les conducteurs connecté au conducteur déjà trouvé
-		foreach (Conductor *c, other_conductors_list_t2) {
-			other_conductors += c -> relatedPotentialConductors(t_list);
-		}
-		other_conductors += other_conductors_list_t2.toSet();
-	}
-	other_conductors.remove(const_cast<Conductor *>(this));
-
-	if (declar_t_list) delete t_list;
-	return(other_conductors);
-}
-
-/**
- * @return l'editeur de schemas parent ou 0
- */
-QETDiagramEditor* Conductor::diagramEditor() const {
-	QWidget *w = const_cast<QGraphicsView *>(diagram() -> views().at(0));
-	while (w -> parentWidget() && !w -> isWindow()) {
-		w = w -> parentWidget();
-	}
-	return(qobject_cast<QETDiagramEditor *>(w));
-}
-
-/**
-	@param a reel
-	@param b reel
-	@param c reel
-	@return true si a est entre b et c ou est egal a l'un des deux
-*/
-bool isBetween(qreal a, qreal b, qreal c) {
-	if (b <= c) {
-		return(a >= b && a <= c);
-	} else {
-		return(a <= b && a >= c);
-	}
-}
-
-/**
-	@param a point
-	@param b point
-	@param c point
-	@return true si le point a est contenu dans le rectangle delimite par les points b et c
-*/
-bool isContained(const QPointF &a, const QPointF &b, const QPointF &c) {
-	return(
-		isBetween(a.x(), b.x(), c.x()) &&
-		isBetween(a.y(), b.y(), c.y())
-	);
-}
-
-/**
-	@return la liste des positions des jonctions avec d'autres conducteurs
-*/
-QList<QPointF> Conductor::junctions() const {
-	QList<QPointF> junctions_list;
-	
-	// pour qu'il y ait des jonctions, il doit y avoir d'autres conducteurs et des bifurcations
-	QSet<Conductor *> other_conductors = relatedConductors();
-	QList<ConductorBend> bends_list = bends();
-	if (other_conductors.isEmpty() || bends_list.isEmpty()) {
-		return(junctions_list);
-	}
-	
-	QList<QPointF> points = segmentsToPoints();
-	for (int i = 1 ; i < (points.size() -1) ; ++ i) {
-		QPointF point = points.at(i);
-		
-		// determine si le point est une bifurcation ou non
-		bool is_bend = false;
-		Qt::Corner current_bend_type = Qt::TopLeftCorner;
-		foreach(ConductorBend cb, bends_list) {
-			if (cb.first == point) {
-				is_bend = true;
-				current_bend_type = cb.second;
-				break;
-			}
-		}
-		// si le point n'est pas une bifurcation, il ne peut etre une jonction (enfin pas au niveau de ce conducteur)
-		if (!is_bend) continue;
-		
-		bool is_junction = false;
-		QPointF scene_point = mapToScene(point);
-		foreach(Conductor *c, other_conductors) {
-			// exprime le point dans les coordonnees de l'autre conducteur
-			QPointF conductor_point = c -> mapFromScene(scene_point);
-			// recupere les segments de l'autre conducteur
-			QList<ConductorSegment *> c_segments = c -> segmentsList();
-			if (c_segments.isEmpty()) continue;
-			// parcoure les segments a la recherche d'un point commun
-			for (int j = 0 ; j < c_segments.count() ; ++ j) {
-				ConductorSegment *segment = c_segments[j];
-				// un point commun a ete trouve sur ce segment
-				if (isContained(conductor_point, segment -> firstPoint(), segment -> secondPoint())) {
-					is_junction = true;
-					// ce point commun ne doit pas etre une bifurcation identique a celle-ci
-					QList<ConductorBend> other_conductor_bends = c -> bends();
-					foreach(ConductorBend cb, other_conductor_bends) {
-						if (cb.first == conductor_point && cb.second == current_bend_type) {
-							is_junction = false;
-						}
-					}
-				}
-				if (is_junction) junctions_list << point;
-			}
-		}
-	}
-	return(junctions_list);
-}
-
-/**
-	@return la liste des bifurcations de ce conducteur ; ConductorBend est un
-	typedef pour une QPair\<QPointF, Qt::Corner\>. Le point indique la position
-	(en coordonnees locales) de la bifurcation tandis que le Corner indique le
-	type de bifurcation.
-*/
-QList<ConductorBend> Conductor::bends() const {
-	QList<ConductorBend> points;
-	if (!segments) return(points);
-	
-	// recupere la liste des segments de taille non nulle
-	QList<ConductorSegment *> visible_segments;
-	ConductorSegment *segment = segments;
-	while (segment -> hasNextSegment()) {
-		if (!segment -> isPoint()) visible_segments << segment;
-		segment = segment -> nextSegment();
-	}
-	if (!segment  -> isPoint()) visible_segments << segment;
-	
-	ConductorSegment *next_segment;
-	for (int i = 0 ; i < visible_segments.count() -1 ; ++ i) {
-		segment = visible_segments[i];
-		next_segment = visible_segments[i + 1];
-		if (!segment -> isPoint() && !next_segment -> isPoint()) {
-			// si les deux segments ne sont pas dans le meme sens, on a une bifurcation
-			if (next_segment -> type() != segment -> type()) {
-				Qt::Corner bend_type;
-				qreal sl = segment -> length();
-				qreal nsl = next_segment -> length();
-				
-				if (segment -> isHorizontal()) {
-					if (sl < 0 && nsl < 0) {
-						bend_type = Qt::BottomLeftCorner;
-					} else if (sl < 0 && nsl > 0) {
-						bend_type = Qt::TopLeftCorner;
-					} else if (sl > 0 && nsl < 0) {
-						bend_type = Qt::BottomRightCorner;
-					} else {
-						bend_type = Qt::TopRightCorner;
-					}
-				} else {
-					if (sl < 0 && nsl < 0) {
-						bend_type = Qt::TopRightCorner;
-					} else if (sl < 0 && nsl > 0) {
-						bend_type = Qt::TopLeftCorner;
-					} else if (sl > 0 && nsl < 0) {
-						bend_type = Qt::BottomRightCorner;
-					} else {
-						bend_type = Qt::BottomLeftCorner;
-					}
-				}
-				points << qMakePair(segment -> secondPoint(), bend_type);
-			}
-		}
-	}
-	return(points);
-}
-
-/**
-	@param p Point, en coordonnees locales
-	@return true si le point p appartient au trajet du conducteur
-*/
-bool Conductor::containsPoint(const QPointF &p) const {
-	if (!segments) return(false);
-	ConductorSegment *segment = segments;
-	while (segment -> hasNextSegment()) {
-		QRectF rect(segment -> firstPoint(), segment -> secondPoint());
-		if (rect.contains(p)) return(true);
-		segment = segment -> nextSegment();
-	}
-	return(false);
-}
-
-/**
-	@param start Point de depart
-	@param end Point d'arrivee
-	@return le coin vers lequel se dirige le trajet de start vers end
-*/
-Qt::Corner Conductor::movementType(const QPointF &start, const QPointF &end) {
-	Qt::Corner result = Qt::BottomRightCorner;
-	if (start.x() <= end.x()) {
-		result = start.y() <= end.y() ? Qt::BottomRightCorner : Qt::TopRightCorner;
-	} else {
-		result = start.y() <= end.y() ? Qt::BottomLeftCorner : Qt::TopLeftCorner;
-	}
-	return(result);
-}
-
-/// @return le type de trajet actuel de ce conducteur
-Qt::Corner Conductor::currentPathType() const {
-	return(movementType(terminal1 -> dockConductor(), terminal2 -> dockConductor()));
-}
-
-/// @return les profils de ce conducteur
-ConductorProfilesGroup Conductor::profiles() const {
-	return(conductor_profiles);
-}
-
-/**
-	@param cpg Les nouveaux profils de ce conducteur
-*/
-void Conductor::setProfiles(const ConductorProfilesGroup &cpg) {
-	conductor_profiles = cpg;
-	if (conductor_profiles[currentPathType()].isNull()) {
-		generateConductorPath(terminal1 -> dockConductor(), terminal1 -> orientation(), terminal2 -> dockConductor(), terminal2 -> orientation());
-		modified_path = false;
-	} else {
-		updateConductorPath(terminal1 -> dockConductor(), terminal1 -> orientation(), terminal2 -> dockConductor(), terminal2 -> orientation());
-		modified_path = true;
-	}
-	if (type() == ConductorProperties::Multi) {
-		calculateTextItemPosition();
-	}
-}
-
-/// Supprime les segments
-void Conductor::deleteSegments() {
-	if (segments != NULL) {
-		while (segments -> hasNextSegment()) delete segments -> nextSegment();
-		delete segments;
-		segments = NULL;
-	}
-}
-
-/**
-	@param point Un point situe a l'exterieur du polygone
-	@param polygon Le polygone dans lequel on veut rapatrier le point
-	@return la position du point, une fois ramene dans le polygone, ou plus
-	exactement sur le bord du polygone
-*/
-QPointF Conductor::movePointIntoPolygon(const QPointF &point, const QPainterPath &polygon) {
-	// decompose le polygone en lignes et points
-	QList<QPolygonF> polygons = polygon.simplified().toSubpathPolygons();
-	QList<QLineF> lines;
-	QList<QPointF> points;
-	foreach(QPolygonF polygon, polygons) {
-		if (polygon.count() <= 1) continue;
-		
-		// on recense les lignes et les points
-		for (int i = 1 ; i < polygon.count() ; ++ i) {
-			lines << QLineF(polygon.at(i - 1), polygon.at(i));
-			points << polygon.at(i -1);
-		}
-	}
-	
-	// on fait des projetes orthogonaux du point sur les differents segments du
-	// polygone, en les triant par longueur croissante
-	QMap<qreal, QPointF> intersections;
-	foreach (QLineF line, lines) {
-		QPointF intersection_point;
-		if (QET::orthogonalProjection(point, line, &intersection_point)) {
-			intersections.insert(QLineF(intersection_point, point).length(), intersection_point);
-		}
-	}
-	if (intersections.count()) {
-		// on determine la plus courte longueur pour un projete orthogonal
-		QPointF the_point = intersections[intersections.keys().first()];
-		return(the_point);
-	} else {
-			// determine le coin du polygone le plus proche du point exterieur
-			qreal minimum_length = -1;
-			int point_index = -1;
-			for (int i = 0 ; i < points.count() ; ++ i) {
-				qreal length = qAbs(QLineF(points.at(i), point).length());
-				if (minimum_length < 0 || length < minimum_length) {
-					minimum_length = length;
-					point_index    = i;
-				}
-			}
-			// on connait desormais le coin le plus proche du texte
-		
-		// aucun projete orthogonal n'a donne quoi que ce soit, on met le texte sur un des coins du polygone
-		return(points.at(point_index));
-	}
-}

Deleted: branches/devel/sources/conductor.h
===================================================================
--- branches/devel/sources/conductor.h	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/conductor.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -1,170 +0,0 @@
-/*
-	Copyright 2006-2013 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 CONDUCTOR_H
-#define CONDUCTOR_H
-#include <QtGui>
-#include "terminal.h"
-#include "conductorprofile.h"
-#include "conductorproperties.h"
-#include "qetdiagrameditor.h"
-class ConductorSegment;
-class ConductorTextItem;
-class Element;
-typedef QPair<QPointF, Qt::Corner> ConductorBend;
-typedef QHash<Qt::Corner, ConductorProfile> ConductorProfilesGroup;
-/**
-	This class represents a conductor, i.e. a wire between two element
-	terminals.
-*/
-class Conductor : public QObject, public QGraphicsPathItem {
-	
-	Q_OBJECT
-	
-	// constructors, destructor
-	public:
-	Conductor(Terminal *, Terminal *, Diagram * = 0);
-	virtual ~Conductor();
-	
-	private:
-	Conductor(const Conductor &);
-	
-	// attributes
-	public:
-	enum { Type = UserType + 1001 };
-	enum Highlight { None, Normal, Alert };
-	
-	/// First terminal the wire is attached to
-	Terminal *terminal1;
-	/// Second terminal the wire is attached to
-	Terminal *terminal2;
-	
-	// methods
-	public:
-	/**
-		Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
-		Conductor.
-		@return the QGraphicsItem type
-	*/
-	virtual int type() const { return Type; }
-	void destroy();
-	/// @return true if this conductor is destroyed
-	bool isDestroyed() const { return(destroyed_); }
-	Diagram *diagram() const;
-	ConductorTextItem *textItem() const;
-	void updatePath(const QRectF & = QRectF());
-	void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
-	QRectF boundingRect() const;
-	virtual QPainterPath shape() const;
-	virtual qreal nearDistance() const;
-	virtual QPainterPath nearShape() const;
-	virtual QPainterPath variableShape(const qreal &) const;
-	virtual bool isNearConductor(const QPointF &);
-	qreal length();
-	ConductorSegment *middleSegment();
-	bool containsPoint(const QPointF &) const;
-	QString text() const;
-	void setText(const QString &);
-	static bool valideXml(QDomElement &);
-	bool fromXml(QDomElement &);
-	QDomElement toXml(QDomDocument &, QHash<Terminal *, int> &) const;
-	const QList<ConductorSegment *> segmentsList() const;
-	void setProperties(const ConductorProperties &);
-	ConductorProperties properties() const;
-	void setProfile(const ConductorProfile &, Qt::Corner);
-	ConductorProfile profile(Qt::Corner) const;
-	void setProfiles(const ConductorProfilesGroup &);
-	ConductorProfilesGroup profiles() const;
-	void readProperties();
-	void adjustTextItemPosition();
-	virtual Highlight highlight() const;
-	virtual void setHighlighted(Highlight);
-	void autoText();
-	QSet<Conductor *> relatedPotentialConductors(QList <Terminal *> *t_list=0);
-	QETDiagramEditor* diagramEditor() const;
-	
-	public slots:
-	void displayedTextChanged();
-	
-	protected:
-	virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
-	virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
-	virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
-	virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *);
-	virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *);
-	virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *);
-	virtual QVariant itemChange(GraphicsItemChange, const QVariant &);
-	
-	private:
-	/// Functional properties
-	ConductorProperties properties_;
-	/// Whether this conductor is still valid
-	bool destroyed_;
-	/// Text input for non simple, non-singleline conductors
-	ConductorTextItem *text_item;
-	/// Segments composing the conductor
-	ConductorSegment *segments;
-	/// Attributs related to mouse interaction
-	QPointF press_point;
-	bool moving_point;
-	bool moving_segment;
-	int moved_point;
-	qreal previous_z_value;
-	ConductorSegment *moved_segment;
-	QPointF before_mov_text_pos_;
-	/// Whether the conductor was manually modified by users
-	bool modified_path;
-	/// 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
-	ConductorProfilesGroup conductor_profiles;
-	/// QPen et QBrush objects used to draw conductors
-	static QPen conductor_pen;
-	static QBrush conductor_brush;
-	static QBrush square_brush;
-	static bool pen_and_brush_initialized;
-	/// Scale factor to render square used to move segments
-	qreal segments_squares_scale_;
-	/// Define whether and how the conductor should be highlighted
-	Highlight must_highlight_;
-	
-	private:
-	void segmentsToPath();
-	void saveProfile(bool = true);
-	void generateConductorPath(const QPointF &, QET::Orientation, const QPointF &, QET::Orientation);
-	void updateConductorPath(const QPointF &, QET::Orientation, const QPointF &, QET::Orientation);
-	uint segmentsCount(QET::ConductorSegmentType = QET::Both) const;
-	QList<QPointF> segmentsToPoints() const;
-	QSet<Conductor *> relatedConductors() const;
-	QList<ConductorBend> bends() const;
-	QList<QPointF> junctions() const;
-	void pointsToSegments(QList<QPointF>);
-	bool hasClickedOn(QPointF, QPointF) const;
-	void calculateTextItemPosition();
-	Qt::Corner currentPathType() const;
-	void deleteSegments();
-	static int getCoeff(const qreal &, const qreal &);
-	static int getSign(const qreal &);
-	QHash<ConductorSegmentProfile *, qreal> shareOffsetBetweenSegments(const qreal &offset, const QList<ConductorSegmentProfile *> &, const qreal & = 0.01) const;
-	static QPointF extendTerminal(const QPointF &, QET::Orientation, qreal = 9.0);
-	static qreal conductor_bound(qreal, qreal, qreal, qreal = 0.0);
-	static qreal conductor_bound(qreal, qreal, bool);
-	static Qt::Corner movementType(const QPointF &, const QPointF &);
-	static QPointF movePointIntoPolygon(const QPointF &, const QPainterPath &);
-};
-#endif

Modified: branches/devel/sources/conductorautonumerotation.h
===================================================================
--- branches/devel/sources/conductorautonumerotation.h	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/conductorautonumerotation.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -18,7 +18,7 @@
 #ifndef CONDUCTORAUTONUMEROTATION_H
 #define CONDUCTORAUTONUMEROTATION_H
 
-#include "conductor.h"
+#include "qetgraphicsitem/conductor.h"
 #include "numerotationcontext.h"
 #include "autonumerotation.h"
 

Modified: branches/devel/sources/conductorautonumerotationwidget.h
===================================================================
--- branches/devel/sources/conductorautonumerotationwidget.h	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/conductorautonumerotationwidget.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -6,7 +6,7 @@
 #include <QSet>
 #include <QMultiMap>
 #include <QString>
-#include "conductor.h"
+#include "qetgraphicsitem/conductor.h"
 #include "diagram.h"
 
 class ConductorAutoNumerotationWidget : public QDialog

Modified: branches/devel/sources/conductorprofile.cpp
===================================================================
--- branches/devel/sources/conductorprofile.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/conductorprofile.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -16,7 +16,7 @@
 	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "conductorprofile.h"
-#include "conductor.h"
+#include "qetgraphicsitem/conductor.h"
 #include "conductorsegmentprofile.h"
 
 /// Constructeur

Modified: branches/devel/sources/conductorpropertieswidget.cpp
===================================================================
--- branches/devel/sources/conductorpropertieswidget.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/conductorpropertieswidget.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -17,7 +17,7 @@
 */
 #include "conductorpropertieswidget.h"
 #include <QtGui>
-#include "conductor.h"
+#include "qetgraphicsitem/conductor.h"
 #include "qeticons.h"
 #include "qetapp.h"
 

Deleted: branches/devel/sources/conductortextitem.cpp
===================================================================
--- branches/devel/sources/conductortextitem.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/conductortextitem.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -1,223 +0,0 @@
-/*
-	Copyright 2006-2013 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 "conductortextitem.h"
-#include "conductor.h"
-#include "diagramcommands.h"
-
-/**
-	Constructeur
-	@param parent_conductor  Conducteur auquel ce texte est rattache
-	@param parent_diagram    Schema auquel ce texte et son conducteur parent sont rattaches
-*/
-ConductorTextItem::ConductorTextItem(Conductor *parent_conductor, Diagram *parent_diagram) :
-	DiagramTextItem(parent_conductor, parent_diagram),
-	parent_conductor_(parent_conductor),
-	moved_by_user_(false),
-	rotate_by_user_(false),
-	first_move_(true)
-{
-	// par defaut, les DiagramTextItem sont Selectable et Movable
-	// cela nous convient, on ne touche pas a ces flags
-}
-
-/**
-	Constructeur
-	@param text Le texte affiche par le champ de texte
-	@param parent_conductor  Conducteur auquel ce texte est rattache
-	@param parent_diagram    Schema auquel ce texte et son conducteur parent sont rattaches
-*/
-ConductorTextItem::ConductorTextItem(const QString &text, Conductor *parent_conductor, Diagram *parent_diagram) :
-	DiagramTextItem(text, parent_conductor, parent_diagram),
-	parent_conductor_(parent_conductor),
-	moved_by_user_(false),
-	rotate_by_user_(false),
-	first_move_(true)
-{
-	// par defaut, les DiagramTextItem sont Selectable et Movable
-	// cela nous convient, on ne touche pas a ces flags
-}
-
-/**
-	Destructeur
-*/
-ConductorTextItem::~ConductorTextItem() {
-}
-
-/**
-	@return le conducteur parent de ce champ de texte, ou 0 si celui-ci n'en a
-	pas
-*/
-Conductor *ConductorTextItem::parentConductor() const {
-	return(parent_conductor_);
-}
-
-/**
-	Permet de lire le texte a mettre dans le champ a partir d'un element XML.
-	Cette methode se base sur la position du champ pour assigner ou non la
-	valeur a ce champ.
-	@param e L'element XML representant le champ de texte
-*/
-void ConductorTextItem::fromXml(const QDomElement &e) {
-	setPlainText(e.attribute("text"));
-	
-	qreal user_pos_x, user_pos_y;
-	if (
-		QET::attributeIsAReal(e, "userx", &user_pos_x) &&
-		QET::attributeIsAReal(e, "usery", &user_pos_y)
-	) {
-		setPos(user_pos_x, user_pos_y);
-	}
-	
-	setRotationAngle(e.attribute("rotation").toDouble());
-}
-
-/**
-	@param document Le document XML a utiliser
-	@return L'element XML representant ce champ de texte
-*/
-QDomElement ConductorTextItem::toXml(QDomDocument &document) const {
-	QDomElement result = document.createElement("input");
-	result.setAttribute("userx", QString("%1").arg(pos().x()));
-	result.setAttribute("usery", QString("%1").arg(pos().y()));
-	result.setAttribute("text", toPlainText());
-	if (rotationAngle()) {
-		result.setAttribute("rotation", QString("%1").arg(rotationAngle()));
-	}
-	return(result);
-}
-
-/**
-	@return true si ce champ de texte a ete explictement deplace par
-	l'utilisateur, false sinon
-*/
-bool ConductorTextItem::wasMovedByUser() const {
-	return(moved_by_user_);
-}
-
-/**
- * @brief ConductorTextItem::wasRotateByUser
- * @return true if text was explicit moved by user else false
- */
-bool ConductorTextItem::wasRotateByUser() const {
-	return(rotate_by_user_);
-}
-
-/**
-	@param moved_by_user true pour que la position du texte soit consideree
-	comme ayant ete definie par l'utilisateur (et donc soit sauvegardee), false
-	pour remettre le texte a sa position originelle
-*/
-void ConductorTextItem::forceMovedByUser(bool moved_by_user) {
-	if (moved_by_user == moved_by_user_) return;
-	
-	moved_by_user_ = moved_by_user;
-	if (!moved_by_user && parent_conductor_) {
-		parent_conductor_ -> adjustTextItemPosition();
-	}
-	
-}
-
-/**
- * @brief ConductorTextItem::forceRotateByUser
- * @param rotate_by_user true pour que la rotation du texte soit consideree
-	comme ayant ete definie par l'utilisateur (et donc soit sauvegardee), false
-	pour remettre le texte a sont angle originelle
- */
-void ConductorTextItem::forceRotateByUser(bool rotate_by_user) {
-	if (rotate_by_user == rotate_by_user_) return;
-
-	rotate_by_user_ = rotate_by_user;
-	if (!rotate_by_user && parent_conductor_) {
-		parent_conductor_ -> adjustTextItemPosition();
-	}
-}
-
-/**
-	Gere les clics de souris lies au champ de texte
-	@param e Objet decrivant l'evenement souris
-*/
-void ConductorTextItem::mousePressEvent(QGraphicsSceneMouseEvent *e) {
-	if ((flags() & QGraphicsItem::ItemIsMovable) && (e -> buttons() & Qt::LeftButton)) {
-		before_mov_pos_ = pos();
-	}
-	first_move_ = true;
-	DiagramTextItem::mousePressEvent(e);
-}
-
-/**
-	Gere les mouvements de souris lies au champ de texte
-	@param e Objet decrivant l'evenement souris
-*/
-void ConductorTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
-	if (textInteractionFlags() & Qt::TextEditable) {
-		QGraphicsTextItem::mouseMoveEvent(e);
-	} else if ((flags() & QGraphicsItem::ItemIsMovable) && (e -> buttons() & Qt::LeftButton)) {
-		if (first_move_) {
-			mouse_to_origin_movement_ = before_mov_pos_ - mapToParent(e -> buttonDownPos(Qt::LeftButton));
-		}
-		
-		QPointF intended_pos = mapToParent(e -> pos()) + mouse_to_origin_movement_;
-		// si ce texte est attache a un conducteur, alors ses mouvements seront
-		// limites a une certaine distance du trace de ce conducteur
-		if (parent_conductor_) {
-			if (parent_conductor_ -> isNearConductor(intended_pos)) {
-				setPos(intended_pos);
-				parent_conductor_ -> setHighlighted(Conductor::Normal);
-			} else {
-				parent_conductor_ -> setHighlighted(Conductor::Alert);
-			}
-		}
-		
-	} else e -> ignore();
-	
-	if (first_move_) {
-		first_move_ = false;
-	}
-}
-
-/**
-	Gere le relachement de souris
-	Cette methode cree un objet d'annulation pour le deplacement
-	@param e Objet decrivant l'evenement souris
-*/
-void ConductorTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
-	if (flags() & QGraphicsItem::ItemIsMovable) {
-		if (Diagram *diagram_ptr = diagram()) {
-			// on cree un objet d'annulation correspondant au deplacement qui s'acheve
-			QPointF applied_movement = pos() - before_mov_pos_;
-			
-			if (!applied_movement.isNull()) {
-				// on cree un objet d'annulation seulement pour ce champ de texte
-				MoveConductorsTextsCommand *undo_object = new MoveConductorsTextsCommand(diagram_ptr);
-				undo_object -> addTextMovement(this, before_mov_pos_, pos(), moved_by_user_);
-				
-				// on active le flag indiquant que ce champ de texte a ete explicitement repositionne par l'utilisateur
-				moved_by_user_ = true;
-				
-				diagram_ptr -> undoStack().push(undo_object);
-			}
-			
-			if (parent_conductor_) {
-				parent_conductor_ -> setHighlighted(Conductor::None);
-			}
-		}
-	}
-	if (!(e -> modifiers() & Qt::ControlModifier)) {
-		QGraphicsTextItem::mouseReleaseEvent(e);
-	}
-}

Deleted: branches/devel/sources/conductortextitem.h
===================================================================
--- branches/devel/sources/conductortextitem.h	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/conductortextitem.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -1,69 +0,0 @@
-/*
-	Copyright 2006-2013 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 CONDUCTOR_TEXT_ITEM_H
-#define CONDUCTOR_TEXT_ITEM_H
-#include "diagramtextitem.h"
-class Conductor;
-/**
-	This class represents a text item attached to a parent conductor.
-	It may be moved and edited by users.
-	It may also be rotated to any angle.
-	Its movements are however limited to a particular distance around its
-	parent conductor.
-*/
-class ConductorTextItem : public DiagramTextItem {
-	Q_OBJECT
-	
-	// constructors, destructor
-	public:
-	ConductorTextItem(Conductor * = 0, Diagram * = 0);
-	ConductorTextItem(const QString &, Conductor * = 0, Diagram * = 0);
-	virtual ~ConductorTextItem();
-	private:
-	ConductorTextItem(const ConductorTextItem &);
-	
-	// attributes
-	public:
-	enum { Type = UserType + 1006 };
-	Conductor *parentConductor() const;
-	virtual void fromXml(const QDomElement &);
-	virtual QDomElement toXml(QDomDocument &) const;
-	
-	// methods
-	public:
-	virtual int type() const { return Type; }
-	virtual bool wasMovedByUser() const;
-	virtual bool wasRotateByUser() const;
-	virtual void forceMovedByUser(bool);
-	virtual void forceRotateByUser(bool);
-	
-	protected:
-	virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
-	virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
-	virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
-	
-	// attributes
-	private:
-	Conductor *parent_conductor_;
-	bool moved_by_user_;
-	bool rotate_by_user_;
-	QPointF before_mov_pos_;
-	bool first_move_;
-	QPointF mouse_to_origin_movement_;
-};
-#endif

Deleted: branches/devel/sources/customelement.cpp
===================================================================
--- branches/devel/sources/customelement.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/customelement.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -1,806 +0,0 @@
-/*
-	Copyright 2006-2013 The QElectroTech Team
-	This file is part of QElectroTech.
-	
-	QElectroTech is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 2 of the License, or
-	(at your option) any later version.
-	
-	QElectroTech is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-	
-	You should have received a copy of the GNU General Public License
-	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#include "customelement.h"
-#include "elementtextitem.h"
-#include "diagram.h"
-#include "qetapp.h"
-#include "partline.h"
-#include "elementdefinition.h"
-#include <iostream>
-
-/**
-	Constructeur de la classe CustomElement. Permet d'instancier un element
-	utilisable comme un element fixe a la difference que l'element perso est
-	construit a partir d'une description au format XML. Celle-ci est recuperee
-	a l'emplacement indique.
-	@param location Emplacement de la definition d'element a utiliser
-	@param qgi Le QGraphicsItem parent de cet element
-	@param s Le Schema affichant cet element
-	@param state Un pointeur facultatif vers un entier. La valeur de cet entier
-	sera changee de maniere a refleter le deroulement de l'instanciation :
-		- 0 : L'instanciation a reussi
-		- 1 : l'emplacement n'a pas permis d'acceder a une definition d'element
-		- 2 : la definition n'etait pas lisible
-		- 3 : la definition n'etait pas valide / exploitable / utilisable
-		- 4 : Le document XML n'est pas un element "definition"
-		- 5 : Les attributs de la definition ne sont pas presents et / ou valides
-		- 6 : La definition est vide
-		- 7 : L'analyse d'un element XML decrivant une partie du dessin de l'element a echoue
-		- 8 : Aucune partie du dessin n'a pu etre chargee
-*/
-CustomElement::CustomElement(const ElementsLocation &location, QGraphicsItem *qgi, Diagram *s, int *state) :
-	FixedElement(qgi, s),
-	elmt_state(-1),
-	location_(location),
-	forbid_antialiasing(false)
-{
-	// recupere la definition de l'element
-	ElementsCollectionItem *element_item = QETApp::collectionItem(location);
-	ElementDefinition *element_definition;
-	if (
-		!element_item ||\
-		!element_item -> isElement() ||\
-		!(element_definition = qobject_cast<ElementDefinition *>(element_item))
-	) {
-		if (state) *state = 1;
-		elmt_state = 1;
-		return;
-	}
-	
-	if (!element_definition -> isReadable()) {
-		if (state) *state = 2;
-		elmt_state = 2;
-		return;
-	}
-	
-	if (element_definition -> isNull()) {
-		if (state) *state = 3;
-		elmt_state = 3;
-		return;
-	}
-	
-	buildFromXml(element_definition -> xml(), &elmt_state);
-	if (state) *state = elmt_state;
-	if (elmt_state) return;
-	
-	if (state) *state = 0;
-	elmt_state = 0;
-}
-
-CustomElement::CustomElement(const QDomElement &xml_def_elmt, QGraphicsItem *qgi, Diagram *s, int *state) : FixedElement(qgi, s) {
-	int elmt_state = -1;
-	buildFromXml(xml_def_elmt, &elmt_state);
-	if (state) *state = elmt_state;
-}
-
-/**
-	Construit l'element personnalise a partir d'un element XML representant sa
-	definition.
-	@param xml_def_elmt
-	@param state Un pointeur facultatif vers un entier. La valeur de cet entier
-	sera changee de maniere a refleter le deroulement de l'instanciation :
-		- 0 : La construction s'est bien passee
-		- 4 : Le document XML n'est pas un element "definition"
-		- 5 : Les attributs de la definition ne sont pas presents et / ou valides
-		- 6 : La definition est vide
-		- 7 : L'analyse d'un element XML decrivant une partie du dessin de l'element a echoue
-		- 8 : Aucune partie du dessin n'a pu etre chargee
-	@return true si le chargement a reussi, false sinon
-*/
-bool CustomElement::buildFromXml(const QDomElement &xml_def_elmt, int *state) {
-	
-	if (xml_def_elmt.tagName() != "definition" || xml_def_elmt.attribute("type") != "element") {
-		if (state) *state = 4;
-		return(false);
-	}
-	
-	// verifie basiquement que la version actuelle est capable de lire ce fichier
-	if (xml_def_elmt.hasAttribute("version")) {
-		bool conv_ok;
-		qreal element_version = xml_def_elmt.attribute("version").toDouble(&conv_ok);
-		if (conv_ok && QET::version.toDouble() < element_version) {
-			std::cerr << qPrintable(
-				QObject::tr("Avertissement : l'\351l\351ment "
-				" a \351t\351 enregistr\351 avec une version"
-				" ult\351rieure de QElectroTech.")
-			) << std::endl;
-		}
-	}
-	
-	// ces attributs doivent etre presents et valides
-	int w, h, hot_x, hot_y;
-	if (
-		!QET::attributeIsAnInteger(xml_def_elmt, QString("width"), &w) ||\
-		!QET::attributeIsAnInteger(xml_def_elmt, QString("height"), &h) ||\
-		!QET::attributeIsAnInteger(xml_def_elmt, QString("hotspot_x"), &hot_x) ||\
-		!QET::attributeIsAnInteger(xml_def_elmt, QString("hotspot_y"), &hot_y) ||\
-		!validOrientationAttribute(xml_def_elmt)
-	) {
-		if (state) *state = 5;
-		return(false);
-	}
-	
-	// on peut d'ores et deja specifier la taille et le hotspot
-	setSize(w, h);
-	setHotspot(QPoint(hot_x, hot_y));
-	setInternalConnections(xml_def_elmt.attribute("ic") == "true");
-	
-	// la definition est supposee avoir des enfants
-	if (xml_def_elmt.firstChild().isNull()) {
-		if (state) *state = 6;
-		return(false);
-	}
-	
-	// initialisation du QPainter (pour dessiner l'element)
-	QPainter qp;
-	qp.begin(&drawing);
-	
-	QPainter low_zoom_qp;
-	low_zoom_qp.begin(&low_zoom_drawing);
-	QPen tmp;
-	tmp.setWidthF(1.0); // ligne vaudou pour prise en compte du setCosmetic - ne pas enlever
-	tmp.setCosmetic(true);
-	low_zoom_qp.setPen(tmp);
-	
-	// extrait les noms de la definition XML
-	names.fromXml(xml_def_elmt);
-	setToolTip(name());
-	
-	// parcours des enfants de la definition : parties du dessin
-	int parsed_elements_count = 0;
-	for (QDomNode node = xml_def_elmt.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
-		QDomElement elmts = node.toElement();
-		if (elmts.isNull()) continue;
-		if (elmts.tagName() == "description") {
-			// gestion de la description graphique de l'element
-			//  = parcours des differentes parties du dessin
-			for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
-				QDomElement qde = n.toElement();
-				if (qde.isNull()) continue;
-				if (parseElement(qde, qp)) {
-					++ parsed_elements_count;
-					QString current_tag = qde.tagName();
-					if (current_tag != "terminal" && current_tag != "input") {
-						forbid_antialiasing = true;
-						parseElement(qde, low_zoom_qp);
-						forbid_antialiasing = false;
-					}
-				} else {
-					if (state) *state = 7;
-					return(false);
-				}
-			}
-		}
-	}
-	
-	// fin du dessin
-	qp.end();
-	low_zoom_qp.end();
-	
-	// il doit y avoir au moins un element charge
-	if (!parsed_elements_count) {
-		if (state) *state = 8;
-		return(false);
-	} else {
-		if (state) *state = 0;
-		return(true);
-	}
-}
-
-/**
-	Destructeur
-*/
-CustomElement::~CustomElement() {
-}
-
-/// @return la liste des bornes de cet element
-QList<Terminal *> CustomElement::terminals() const {
-	return(list_terminals);
-}
-
-/// @return la liste des conducteurs rattaches a cet element
-QList<Conductor *> CustomElement::conductors() const {
-	QList<Conductor *> conductors;
-	foreach(Terminal *t, list_terminals) conductors << t -> conductors();
-	return(conductors);
-}
-
-/// @return la liste des textes de cet element
-QList<ElementTextItem *> CustomElement::texts() const {
-	return(list_texts_);
-}
-
-/**
-	@return Le nombre de bornes que l'element possede
-*/
-int CustomElement::terminalsCount() const {
-	return(list_terminals.size());
-}
-
-/**
-	Dessine le composant sur le Diagram
-	@param qp Le QPainter a utiliser pour dessiner l'element
-	@param options Les options graphiques
-*/
-void CustomElement::paint(QPainter *qp, const QStyleOptionGraphicsItem *options) {
-	if (options && options -> levelOfDetail < 1.0) {
-		low_zoom_drawing.play(qp);
-	} else {
-		drawing.play(qp);
-	}
-}
-
-/**
-	Analyse et prend en compte un element XML decrivant une partie du dessin
-	de l'element perso. Si l'analyse reussit, la partie est ajoutee au dessin.
-	Cette partie peut etre une borne, une ligne, une ellipse, un cercle, un arc
-	de cercle ou un polygone. Cette methode renvoie false si l'analyse
-	d'une de ces formes echoue. Si l'analyse reussit ou dans le cas d'une forme
-	inconnue, cette methode renvoie true. A l'exception des bornes, toutes les
-	formes peuvent avoir un attribut style. @see setPainterStyle
-	@param e L'element XML a analyser
-	@param qp Le QPainter a utiliser pour dessiner l'element perso
-	@return true si l'analyse reussit, false sinon
-*/
-bool CustomElement::parseElement(QDomElement &e, QPainter &qp) {
-	if (e.tagName() == "terminal") return(parseTerminal(e));
-	else if (e.tagName() == "line") return(parseLine(e, qp));
-	else if (e.tagName() == "rect") return(parseRect(e, qp));
-	else if (e.tagName() == "ellipse") return(parseEllipse(e, qp));
-	else if (e.tagName() == "circle") return(parseCircle(e, qp));
-	else if (e.tagName() == "arc") return(parseArc(e, qp));
-	else if (e.tagName() == "polygon") return(parsePolygon(e, qp));
-	else if (e.tagName() == "text") return(parseText(e, qp));
-	else if (e.tagName() == "input") return(parseInput(e));
-	else return(true);	// on n'est pas chiant, on ignore l'element inconnu
-}
-
-/**
-	Analyse un element XML suppose representer une ligne. Si l'analyse
-	reussit, la ligne est ajoutee au dessin.
-	La ligne est definie par les attributs suivants :
-		- x1, y1 : reels, coordonnees d'une extremite de la ligne
-		- x2, y2 : reels, coordonnees de l'autre extremite de la ligne
-		
-	@param e L'element XML a analyser
-	@param qp Le QPainter a utiliser pour dessiner l'element perso
-	@return true si l'analyse reussit, false sinon
-*/
-bool CustomElement::parseLine(QDomElement &e, QPainter &qp) {
-	// verifie la presence et la validite des attributs obligatoires
-	qreal x1, y1, x2, y2;
-	if (!QET::attributeIsAReal(e, QString("x1"), &x1)) return(false);
-	if (!QET::attributeIsAReal(e, QString("y1"), &y1)) return(false);
-	if (!QET::attributeIsAReal(e, QString("x2"), &x2)) return(false);
-	if (!QET::attributeIsAReal(e, QString("y2"), &y2)) return(false);
-	
-	QET::EndType first_end = QET::endTypeFromString(e.attribute("end1"));
-	QET::EndType second_end = QET::endTypeFromString(e.attribute("end2"));
-	qreal length1, length2;
-	if (!QET::attributeIsAReal(e, QString("length1"), &length1)) length1 = 1.5;
-	if (!QET::attributeIsAReal(e, QString("length2"), &length2)) length2 = 1.5;
-	
-	qp.save();
-	setPainterStyle(e, qp);
-	QPen t = qp.pen();
-	t.setJoinStyle(Qt::MiterJoin);
-	qp.setPen(t);
-	
-	QLineF line(x1, y1, x2, y2);
-	QPointF point1(line.p1());
-	QPointF point2(line.p2());
-	
-	qreal line_length(line.length());
-	qreal pen_width = qp.pen().widthF();
-	
-	// determine s'il faut dessiner les extremites
-	bool draw_1st_end, draw_2nd_end;
-	qreal reduced_line_length = line_length - (length1 * PartLine::requiredLengthForEndType(first_end));
-	draw_1st_end = first_end && reduced_line_length >= 0;
-	if (draw_1st_end) {
-		reduced_line_length -= (length2 * PartLine::requiredLengthForEndType(second_end));
-	} else {
-		reduced_line_length = line_length - (length2 * PartLine::requiredLengthForEndType(second_end));
-	}
-	draw_2nd_end = second_end && reduced_line_length >= 0;
-	
-	// dessine la premiere extremite
-	QPointF start_point, stop_point;
-	if (draw_1st_end) {
-		QList<QPointF> four_points1(PartLine::fourEndPoints(point1, point2, length1));
-		if (first_end == QET::Circle) {
-			qp.drawEllipse(QRectF(four_points1[0] - QPointF(length1, length1), QSizeF(length1 * 2.0, length1 * 2.0)));
-			start_point = four_points1[1];
-		} else if (first_end == QET::Diamond) {
-			qp.drawPolygon(QPolygonF() << four_points1[1] << four_points1[2] << point1 << four_points1[3]);
-			start_point = four_points1[1];
-		} else if (first_end == QET::Simple) {
-			qp.drawPolyline(QPolygonF() << four_points1[3] << point1 << four_points1[2]);
-			start_point = point1;
-			
-		} else if (first_end == QET::Triangle) {
-			qp.drawPolygon(QPolygonF() << four_points1[0] << four_points1[2] << point1 << four_points1[3]);
-			start_point = four_points1[0];
-		}
-		
-		// ajuste le depart selon l'epaisseur du trait
-		if (pen_width && (first_end == QET::Simple || first_end == QET::Circle)) {
-			start_point = QLineF(start_point, point2).pointAt(pen_width / 2.0 / line_length);
-		}
-	} else {
-		start_point = point1;
-	}
-	
-	// dessine la seconde extremite
-	if (draw_2nd_end) {
-		QList<QPointF> four_points2(PartLine::fourEndPoints(point2, point1, length2));
-		if (second_end == QET::Circle) {
-			qp.drawEllipse(QRectF(four_points2[0] - QPointF(length2, length2), QSizeF(length2 * 2.0, length2 * 2.0)));
-			stop_point = four_points2[1];
-		} else if (second_end == QET::Diamond) {
-			qp.drawPolygon(QPolygonF() << four_points2[2] << point2 << four_points2[3] << four_points2[1]);
-			stop_point = four_points2[1];
-		} else if (second_end == QET::Simple) {
-			qp.drawPolyline(QPolygonF() << four_points2[3] << point2 << four_points2[2]);
-			stop_point = point2;
-		} else if (second_end == QET::Triangle) {
-			qp.drawPolygon(QPolygonF() << four_points2[0] << four_points2[2] << point2 << four_points2[3] << four_points2[0]);
-			stop_point = four_points2[0];
-		}
-		
-		// ajuste l'arrivee selon l'epaisseur du trait
-		if (pen_width && (second_end == QET::Simple || second_end == QET::Circle)) {
-			stop_point = QLineF(point1, stop_point).pointAt((line_length - (pen_width / 2.0)) / line_length);
-		}
-	} else {
-		stop_point = point2;
-	}
-	
-	qp.drawLine(start_point, stop_point);
-	
-	qp.restore();
-	return(true);
-}
-
-/**
-	Analyse un element XML suppose representer un rectangle. Si l'analyse
-	reussit, le rectangle est ajoute au dessin.
-	Le rectangle est defini par les attributs suivants :
-		- x : abscisse du coin superieur gauche du rectangle
-		- y : ordonnee du coin superieur gauche du rectangle
-		- width : largeur du rectangle
-		- height : hauteur du rectangle
-		
-	@param e L'element XML a analyser
-	@param qp Le QPainter a utiliser pour dessiner l'element perso
-	@return true si l'analyse reussit, false sinon
-*/
-bool CustomElement::parseRect(QDomElement &e, QPainter &qp) {
-	// verifie la presence des attributs obligatoires
-	qreal rect_x, rect_y, rect_w, rect_h;
-	if (!QET::attributeIsAReal(e, QString("x"),       &rect_x))  return(false);
-	if (!QET::attributeIsAReal(e, QString("y"),       &rect_y))  return(false);
-	if (!QET::attributeIsAReal(e, QString("width"),   &rect_w))  return(false);
-	if (!QET::attributeIsAReal(e, QString("height"),  &rect_h))  return(false);
-	qp.save();
-	setPainterStyle(e, qp);
-	
-	// force le type de jointures pour les rectangles
-	QPen p = qp.pen();
-	p.setJoinStyle(Qt::MiterJoin);
-	qp.setPen(p);
-	
-	qp.drawRect(QRectF(rect_x, rect_y, rect_w, rect_h));
-	qp.restore();
-	return(true);
-}
-
-/**
-	Analyse un element XML suppose representer un cercle. Si l'analyse
-	reussit, le cercle est ajoute au dessin.
-	Le cercle est defini par les attributs suivants :
-		- x : abscisse du coin superieur gauche de la quadrature du cercle
-		- y : ordonnee du coin superieur gauche de la quadrature du cercle
-		- diameter : diametre du cercle
-		
-	@param e L'element XML a analyser
-	@param qp Le QPainter a utiliser pour dessiner l'element perso
-	@return true si l'analyse reussit, false sinon
-*/
-bool CustomElement::parseCircle(QDomElement &e, QPainter &qp) {
-	// verifie la presence des attributs obligatoires
-	qreal cercle_x, cercle_y, cercle_r;
-	if (!QET::attributeIsAReal(e, QString("x"),        &cercle_x)) return(false);
-	if (!QET::attributeIsAReal(e, QString("y"),        &cercle_y)) return(false);
-	if (!QET::attributeIsAReal(e, QString("diameter"), &cercle_r)) return(false);
-	qp.save();
-	setPainterStyle(e, qp);
-	qp.drawEllipse(QRectF(cercle_x, cercle_y, cercle_r, cercle_r));
-	qp.restore();
-	return(true);
-}
-
-/**
-	Analyse un element XML suppose representer une ellipse. Si l'analyse
-	reussit, l'ellipse est ajoutee au dessin.
-	L'ellipse est definie par les attributs suivants :
-		- x : abscisse du coin superieur gauche du rectangle dans lequel s'inscrit l'ellipse
-		- y : ordonnee du coin superieur gauche du rectangle dans lequel s'inscrit l'ellipse
-		- width : dimension de la diagonale horizontale de l'ellipse
-		- height : dimension de la diagonale verticale de l'ellipse
-		
-	@param e L'element XML a analyser
-	@param qp Le QPainter a utiliser pour dessiner l'element perso
-	@return true si l'analyse reussit, false sinon
-*/
-bool CustomElement::parseEllipse(QDomElement &e, QPainter &qp) {
-	// verifie la presence des attributs obligatoires
-	qreal ellipse_x, ellipse_y, ellipse_l, ellipse_h;
-	if (!QET::attributeIsAReal(e, QString("x"),       &ellipse_x))  return(false);
-	if (!QET::attributeIsAReal(e, QString("y"),       &ellipse_y))  return(false);
-	if (!QET::attributeIsAReal(e, QString("width"), &ellipse_l))  return(false);
-	if (!QET::attributeIsAReal(e, QString("height"), &ellipse_h))  return(false);
-	qp.save();
-	setPainterStyle(e, qp);
-	qp.drawEllipse(QRectF(ellipse_x, ellipse_y, ellipse_l, ellipse_h));
-	qp.restore();
-	return(true);
-}
-
-/**
-	Analyse un element XML suppose representer un arc de cercle. Si l'analyse
-	reussit, l'arc de cercle est ajoute au dessin.
-	L'arc de cercle est defini par les quatres parametres d'une ellipse (en fait
-	l'ellipse dans laquelle s'inscrit l'arc de cercle) auxquels s'ajoutent les
-	attributs suivants :
-		- start : angle de depart : l'angle "0 degre" est a trois heures
-		- angle : etendue (en degres) de l'arc de cercle ; une valeur positive
-		va dans le sens contraire des aiguilles d'une montre
-		
-	@param e L'element XML a analyser
-	@param qp Le QPainter a utiliser pour dessiner l'element perso
-	@return true si l'analyse reussit, false sinon
-*/
-bool CustomElement::parseArc(QDomElement &e, QPainter &qp) {
-	// verifie la presence des attributs obligatoires
-	qreal arc_x, arc_y, arc_l, arc_h, arc_s, arc_a;
-	if (!QET::attributeIsAReal(e, QString("x"),       &arc_x))  return(false);
-	if (!QET::attributeIsAReal(e, QString("y"),       &arc_y))  return(false);
-	if (!QET::attributeIsAReal(e, QString("width"),   &arc_l))  return(false);
-	if (!QET::attributeIsAReal(e, QString("height"),  &arc_h))  return(false);
-	if (!QET::attributeIsAReal(e, QString("start"),   &arc_s))  return(false);
-	if (!QET::attributeIsAReal(e, QString("angle"),   &arc_a))  return(false);
-	
-	qp.save();
-	setPainterStyle(e, qp);
-	qp.drawArc(QRectF(arc_x, arc_y, arc_l, arc_h), (int)(arc_s * 16), (int)(arc_a * 16));
-	qp.restore();
-	return(true);
-}
-
-/**
-	Analyse un element XML suppose representer un polygone. Si l'analyse
-	reussit, le polygone est ajoute au dessin.
-	Le polygone est defini par une serie d'attributs x1, x2, ..., xn et autant
-	d'attributs y1, y2, ..., yn representant les coordonnees des differents
-	points du polygone.
-	Il est possible d'obtenir un polygone non ferme en utilisant closed="false"
-	@param e L'element XML a analyser
-	@param qp Le QPainter a utiliser pour dessiner l'element perso
-	@return true si l'analyse reussit, false sinon
-*/
-bool CustomElement::parsePolygon(QDomElement &e, QPainter &qp) {
-	int i = 1;
-	while(true) {
-		if (QET::attributeIsAReal(e, QString("x%1").arg(i)) && QET::attributeIsAReal(e, QString("y%1").arg(i))) ++ i;
-		else break;
-	}
-	if (i < 3) return(false);
-	QVector<QPointF> points(i-1);
-	for (int j = 1 ; j < i ; ++ j) {
-		points.insert(
-			j - 1,
-			QPointF(
-				e.attribute(QString("x%1").arg(j)).toDouble(),
-				e.attribute(QString("y%1").arg(j)).toDouble()
-			)
-		);
-	}
-	qp.save();
-	setPainterStyle(e, qp);
-	if (e.attribute("closed") == "false") qp.drawPolyline(points.data(), i-1);
-	else qp.drawPolygon(points.data(), i-1);
-	qp.restore();
-	return(true);
-}
-
-/**
-	Analyse un element XML suppose representer un texte. Si l'analyse
-	reussit, le texte est ajoute au dessin.
-	Le texte est defini par une position, une chaine de caracteres et une
-	taille.
-	@param e L'element XML a analyser
-	@param qp Le QPainter a utiliser pour dessiner l'element perso
-	@return true si l'analyse reussit, false sinon
-*/
-bool CustomElement::parseText(QDomElement &e, QPainter &qp) {
-	qreal pos_x, pos_y;
-	int size;
-	if (
-		!QET::attributeIsAReal(e, "x", &pos_x) ||\
-		!QET::attributeIsAReal(e, "y", &pos_y) ||\
-		!QET::attributeIsAnInteger(e, "size", &size) ||\
-		!e.hasAttribute("text")
-	) return(false);
-	
-	qp.save();
-	setPainterStyle(e, qp);
-	
-	// determine la police a utiliser et en recupere les metriques associees
-	QFont used_font = QETApp::diagramTextsFont(size);
-	QFontMetrics qfm(used_font);
-	QColor text_color = (e.attribute("color") != "white"? Qt::black : Qt::white);
-	
-	// instancie un QTextDocument (comme la classe QGraphicsTextItem) pour
-	// generer le rendu graphique du texte
-	QTextDocument text_document;
-	text_document.setDefaultFont(used_font);
-	text_document.setPlainText(e.attribute("text"));
-	
-	// Se positionne aux coordonnees indiquees dans la description du texte	
-	qp.setTransform(QTransform(), false);
-	qp.translate(pos_x, pos_y);
-	
-	// Pivote le systeme de coordonnees du QPainter pour effectuer le rendu
-	// dans le bon sens
-	qreal default_rotation_angle = 0.0;
-	if (QET::attributeIsAReal(e, "rotation", &default_rotation_angle)) {
-		qp.rotate(default_rotation_angle);
-	}
-	
-	/*
-		Deplace le systeme de coordonnees du QPainter pour effectuer le rendu au
-		bon endroit ; note : on soustrait l'ascent() de la police pour
-		determiner le coin superieur gauche du texte alors que la position
-		indiquee correspond a la baseline.
-	*/
-	QPointF qpainter_offset(0.0, -qfm.ascent());
-	
-	// ajuste le decalage selon la marge du document texte
-#if QT_VERSION >= 0x040500
-	text_document.setDocumentMargin(0.0);
-#else
-	// il semblerait qu'avant Qt 4.5, le documentMargin vaille 2.0 (et pas 4.0)
-	qpainter_offset.rx() -= 2.0;
-	qpainter_offset.ry() -= 2.0;
-#endif
-	
-	qp.translate(qpainter_offset);
-	
-	// force the palette used to render the QTextDocument
-	QAbstractTextDocumentLayout::PaintContext ctx;
-	ctx.palette.setColor(QPalette::Text, text_color);
-	text_document.documentLayout() -> draw(&qp, ctx);
-	
-	qp.restore();
-	return(true);
-}
-
-/**
-	Analyse un element XML suppose representer un champ de texte editable par
-	l'utilisateur. Si l'analyse reussit, le champ est ajoute au dessin.
-	Le texte est defini par :
-		- une position
-		- une chaine de caracteres facultative utilisee comme valeur par defaut
-		- une taille
-		- le fait de subir les rotations de l'element ou non
-	@param e L'element XML a analyser
-	@return Un pointeur vers l'objet ElementTextItem ainsi cree si l'analyse reussit, 0 sinon
-*/
-ElementTextItem *CustomElement::parseInput(QDomElement &e) {
-	qreal pos_x, pos_y;
-	int size;
-	if (
-		!QET::attributeIsAReal(e, "x", &pos_x) ||\
-		!QET::attributeIsAReal(e, "y", &pos_y) ||\
-		!QET::attributeIsAnInteger(e, "size", &size)
-	) return(0);
-	
-	ElementTextItem *eti = new ElementTextItem(e.attribute("text"), this);
-	eti -> setFont(QETApp::diagramTextsFont(size));
-	
-	// position du champ de texte
-	eti -> setOriginalPos(QPointF(pos_x, pos_y));
-	eti -> setPos(pos_x, pos_y);
-	
-	// rotation du champ de texte
-	qreal original_rotation_angle = 0.0;
-	QET::attributeIsAReal(e, "rotation", &original_rotation_angle);
-	eti -> setOriginalRotationAngle(original_rotation_angle);
-	eti -> setRotationAngle(original_rotation_angle);
-	
-	// comportement du champ lorsque son element parent est pivote
-	eti -> setFollowParentRotations(e.attribute("rotate") == "true");
-	
-	list_texts_ << eti;
-	
-	return(eti);
-}
-
-/**
-	Analyse un element XML suppose representer une borne. Si l'analyse
-	reussit, la borne est ajoutee a l'element.
-	Une borne est definie par les attributs suivants :
-		- x, y : coordonnees de la borne
-		- orientation  : orientation de la borne = Nord (n), Sud (s), Est (e) ou Ouest (w)
-		
-	@param e L'element XML a analyser
-	@return Un pointeur vers l'objet Terminal ainsi cree, 0 sinon
-*/
-Terminal *CustomElement::parseTerminal(QDomElement &e) {
-	// verifie la presence et la validite des attributs obligatoires
-	qreal terminalx, terminaly;
-	QET::Orientation terminalo;
-	if (!QET::attributeIsAReal(e, QString("x"), &terminalx)) return(0);
-	if (!QET::attributeIsAReal(e, QString("y"), &terminaly)) return(0);
-	if (!e.hasAttribute("orientation")) return(0);
-	if (e.attribute("orientation") == "n") terminalo = QET::North;
-	else if (e.attribute("orientation") == "s") terminalo = QET::South;
-	else if (e.attribute("orientation") == "e") terminalo = QET::East;
-	else if (e.attribute("orientation") == "w") terminalo = QET::West;
-	else return(0);
-	Terminal *new_terminal = new Terminal(terminalx, terminaly, terminalo, this, qobject_cast<Diagram *>(scene()));
-	new_terminal -> setZValue(420); // valeur arbitraire pour maintenir les bornes au-dessus des champs de texte
-	list_terminals << new_terminal;
-	return(new_terminal);
-}
-
-/**
-	Active / desactive l'antialiasing sur un QPainter
-	@param qp Le QPainter a modifier
-	@param aa Booleen a true pour activer l'antialiasing, a false pour le desactiver
-*/
-void CustomElement::setQPainterAntiAliasing(QPainter &qp, bool aa) {
-	if (forbid_antialiasing) aa = false;
-	qp.setRenderHint(QPainter::Antialiasing,          aa);
-	qp.setRenderHint(QPainter::TextAntialiasing,      aa);
-	qp.setRenderHint(QPainter::SmoothPixmapTransform, aa);
-}
-
-/**
-	Verifie si l'attribut "orientation" de l'element XML e correspond bien a la
-	syntaxe decrivant les orientations possibles pour un element.
-	Cette syntaxe comprend exactement 4 lettres :
-		- une pour le Nord
-		- une pour l'Est
-		- une pour le Sud
-		- une pour l'Ouest
-	 
-	Pour chaque orientation, on indique si elle est :
-		- l'orientation par defaut : d
-		- une orientation autorisee : y
-		- une orientation interdire : n
-		
-	Exemple : "dnny" represente un element par defaut oriente vers le nord et qui
-	peut etre oriente vers l'ouest mais pas vers le sud ou vers l'est.
-	@param e Element XML
-	@return true si l'attribut "orientation" est valide, false sinon
-*/
-bool CustomElement::validOrientationAttribute(const QDomElement &e) {
-	return(ori.fromString(e.attribute("orientation")));
-}
-
-/**
-	Applique les parametres de style definis dans l'attribut "style" de
-	l'element XML e au QPainter qp
-	Les styles possibles sont :
-		- line-style : style du trait
-			- dashed : trait en pointilles (tirets)
-			- dashdotted : Traits et points
-			- dotted : trait en pointilles (points)
-			- normal : trait plein [par defaut]
-		- line-weight : epaiseur du trait
-			- thin : trait fin
-			- normal : trait d'epaisseur 1 [par defaut]
-		- filling : remplissage de la forme
-			- white : remplissage blanc
-			- black : remplissage noir
-			 - red   : remplissage rouge
-			- blue  : remplissage bleu
-			- green : remplissage vert
-			- none : pas de remplissage [par defaut]
-		- color : couleur du trait et du texte
-			- white : trait noir [par defaut]
-			- black : trait blanc
-			- red   : trait rouge
-			- blue  : trait bleu
-			- green : trait vert
-			
-	Les autres valeurs ne sont pas prises en compte.
-	@param e L'element XML a parser
-	@param qp Le QPainter a modifier en fonction des styles
-*/
-void CustomElement::setPainterStyle(QDomElement &e, QPainter &qp) {
-	// recupere le QPen et la QBrush du QPainter
-	QPen pen = qp.pen();
-	QBrush brush = qp.brush();
-	
-	// attributs par defaut
-	pen.setJoinStyle(Qt::BevelJoin);
-	pen.setCapStyle(Qt::SquareCap);
-	
-	// recupere la liste des couples style / valeur
-	QStringList styles = e.attribute("style").split(";", QString::SkipEmptyParts);
-	
-	// agit sur le QPen et la QBrush en fonction des valeurs rencontrees
-	QRegExp rx("^\\s*([a-z-]+)\\s*:\\s*([a-z-]+)\\s*$");
-	foreach (QString style, styles) {
-		if (rx.exactMatch(style)) {
-			QString style_name = rx.cap(1);
-			QString style_value = rx.cap(2);
-			if (style_name == "line-style") {
-				if (style_value == "dashed") pen.setStyle(Qt::DashLine);
-				else if (style_value == "dotted") pen.setStyle(Qt::DotLine);
-				else if (style_value == "dashdotted") pen.setStyle(Qt::DashDotLine);
-				else if (style_value == "normal") pen.setStyle(Qt::SolidLine);
-			} else if (style_name == "line-weight") {
-				if (style_value == "thin") pen.setWidth(0);
-				else if (style_value == "normal") pen.setWidthF(1.0);
-				else if (style_value == "none") pen.setColor(QColor(0, 0, 0, 0));
-			} else if (style_name == "filling") {
-				if (style_value == "white") {
-					brush.setStyle(Qt::SolidPattern);
-					brush.setColor(Qt::white);
-				} else if (style_value == "black") {
-					brush.setStyle(Qt::SolidPattern);
-					brush.setColor(Qt::black);
-				} else if (style_value == "blue") {
-					brush.setStyle(Qt::SolidPattern);
-					brush.setColor(Qt::blue);
-				} else if (style_value == "red") {
-					brush.setStyle(Qt::SolidPattern);
-					brush.setColor(Qt::red);
-				} else if (style_value == "green") {
-					brush.setStyle(Qt::SolidPattern);
-					brush.setColor(Qt::green);
-				} else if (style_value == "none") {
-					brush.setStyle(Qt::NoBrush);
-				}
-			} else if (style_name == "color") {
-				if (style_value == "black") {
-					pen.setColor(QColor(0, 0, 0, pen.color().alpha()));
-				} else if (style_value == "white") {
-					pen.setColor(QColor(255, 255, 255, pen.color().alpha()));
-				} else if (style_value == "red") {
-					pen.setColor(Qt::red);
-				}else if (style_value == "blue") {
-					pen.setColor(Qt::blue);
-				}else if (style_value == "green") {
-					pen.setColor(Qt::green);
-				}
-			}
-		}
-	}
-	
-	// affectation du QPen et de la QBrush modifies au QPainter 
-	qp.setPen(pen);
-	qp.setBrush(brush);
-	
-	// mise en place (ou non) de l'antialiasing
-	setQPainterAntiAliasing(qp, e.attribute("antialias") == "true");
-}

Deleted: branches/devel/sources/customelement.h
===================================================================
--- branches/devel/sources/customelement.h	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/customelement.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -1,132 +0,0 @@
-/*
-	Copyright 2006-2013 The QElectroTech Team
-	This file is part of QElectroTech.
-	
-	QElectroTech is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 2 of the License, or
-	(at your option) any later version.
-	
-	QElectroTech is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-	
-	You should have received a copy of the GNU General Public License
-	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef CUSTOM_ELEMENT_H
-#define CUSTOM_ELEMENT_H
-#include "fixedelement.h"
-#include <QtGui>
-#include "nameslist.h"
-#include "elementslocation.h"
-class ElementTextItem;
-class Terminal;
-/**
-	This class represents an electrical element; it may be used like a fixed
-	element, the difference being that the CustomElement reads its description
-	(names, drawing, behavior) from an XML document.
-*/
-class CustomElement : public FixedElement {
-	
-	Q_OBJECT
-	
-	// constructors, destructor
-	public:
-	CustomElement(const ElementsLocation &, QGraphicsItem * = 0, Diagram * = 0, int * = 0);
-	CustomElement(const QDomElement &,      QGraphicsItem * = 0, Diagram * = 0, int * = 0);
-	virtual ~CustomElement();
-	
-	private:
-	CustomElement(const CustomElement &);
-	
-	// attributes
-	protected:
-	int elmt_state; // hold the error code in case the instanciation fails, or 0 if everything went well
-	NamesList names;
-	ElementsLocation location_;
-	QPicture drawing;
-	QPicture low_zoom_drawing;
-	QList<Terminal *> list_terminals;
-	QList<ElementTextItem *> list_texts_;
-	bool forbid_antialiasing;
-	
-	// methods
-	public:
-	virtual QList<Terminal *> terminals() const;
-	virtual QList<Conductor *> conductors() const;
-	virtual QList<ElementTextItem *> texts() const;
-	virtual int terminalsCount() const;
-	virtual void paint(QPainter *, const QStyleOptionGraphicsItem *);
-	QString typeId() const;
-	ElementsLocation location() const;
-	bool isNull() const;
-	int state() const;
-	QString name() const;
-	
-	protected:
-	virtual bool buildFromXml(const QDomElement &, int * = 0);
-	virtual bool parseElement(QDomElement &, QPainter &);
-	virtual bool parseLine(QDomElement &, QPainter &);
-	virtual bool parseRect(QDomElement &, QPainter &);
-	virtual bool parseEllipse(QDomElement &, QPainter &);
-	virtual bool parseCircle(QDomElement &, QPainter &);
-	virtual bool parseArc(QDomElement &, QPainter &);
-	virtual bool parsePolygon(QDomElement &, QPainter &);
-	virtual bool parseText(QDomElement &, QPainter &);
-	virtual ElementTextItem *parseInput(QDomElement &);
-	virtual Terminal *parseTerminal(QDomElement &);
-	virtual void setQPainterAntiAliasing(QPainter &, bool);
-	virtual bool validOrientationAttribute(const QDomElement &);
-	virtual void setPainterStyle(QDomElement &, QPainter &);
-};
-
-/**
-	@return The element type ID; considering a CustomElement, this means the
-	@location of its XML description.
-	@see location()
-*/
-inline QString CustomElement::typeId() const {
-	return(location_.path());
-}
-
-/**
-	@return the location of the XML document describing this element.
-*/
-inline ElementsLocation CustomElement::location() const {
-	return(location_);
-}
-
-/**
-	@return true if this element is null, i.e. if its XML description could not
-	be loaded.
-*/
-inline bool CustomElement::isNull() const {
-	return(elmt_state);
-}
-
-/**
-	@return An integer representing the state of this element:
-		- 0: instantiation succeeded
-		- 1: the file does not exist
-		- 2: the file could not be opened
-		- 3: The file is not a valid XML document
-		- 4: The XML document does not have a "definition" root element.
-		- 5: The definition attributes are missing or invalid
-		- 6: The definition is empty
-		- 7: The parsing of an XML element describing an element drawing primitive failed
-		- 8: No primitive could be loadedAucune partie du dessin n'a pu etre chargee
-*/
-inline int CustomElement::state() const {
-	return(elmt_state);
-}
-
-/**
-	@return The name of this element.
-*/
-inline QString CustomElement::name() const {
-	return(names.name(location_.baseName()));
-}
-
-#endif

Modified: branches/devel/sources/diagram.cpp
===================================================================
--- branches/devel/sources/diagram.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/diagram.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -16,19 +16,19 @@
 	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include <math.h>
-#include "conductor.h"
-#include "conductortextitem.h"
-#include "customelement.h"
+#include "qetgraphicsitem/conductor.h"
+#include "qetgraphicsitem/conductortextitem.h"
+#include "qetgraphicsitem/customelement.h"
 #include "diagram.h"
 #include "diagramcommands.h"
 #include "diagramcontent.h"
 #include "diagramposition.h"
-#include "elementtextitem.h"
+#include "qetgraphicsitem/elementtextitem.h"
 #include "elementsmover.h"
 #include "elementtextsmover.h"
 #include "exportdialog.h"
-#include "ghostelement.h"
-#include "independenttextitem.h"
+#include "qetgraphicsitem/ghostelement.h"
+#include "qetgraphicsitem/independenttextitem.h"
 #include "qetapp.h"
 #include "qetgraphicsitem/diagramimageitem.h"
 
@@ -547,7 +547,7 @@
 	// chargement de tous les textes du fichiers XML
 	QList<IndependentTextItem *> added_texts;
 	foreach (QDomElement text_xml, QET::findInDomElement(root, "inputs", "input")) {
-		IndependentTextItem *iti = new IndependentTextItem(this);
+        	IndependentTextItem *iti = new IndependentTextItem(this);
 		iti -> fromXml(text_xml);
 		addIndependentTextItem(iti);
 		added_texts << iti;

Modified: branches/devel/sources/diagramcommands.cpp
===================================================================
--- branches/devel/sources/diagramcommands.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/diagramcommands.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -16,15 +16,15 @@
 	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "diagramcommands.h"
-#include "element.h"
-#include "conductor.h"
-#include "conductortextitem.h"
+#include "qetgraphicsitem/element.h"
+#include "qetgraphicsitem/conductor.h"
+#include "qetgraphicsitem/conductortextitem.h"
 #include "diagram.h"
-#include "elementtextitem.h"
-#include "independenttextitem.h"
+#include "qetgraphicsitem/elementtextitem.h"
+#include "qetgraphicsitem/independenttextitem.h"
 #include "qgimanager.h"
 #include "diagram.h"
-#include "diagramtextitem.h"
+#include "qetgraphicsitem/diagramtextitem.h"
 #include "qetgraphicsitem/diagramimageitem.h"
 
 /**
@@ -635,7 +635,7 @@
 	elements_to_rotate(elements),
 	texts_to_rotate(texts),
 	images_to_rotate(images),
-	applied_rotation_angle_(-90.0)
+	applied_rotation_angle_(90.0)
 {
 	setText(
 		QString(
@@ -706,7 +706,7 @@
 void RotateElementsCommand::rotateElement(Element *element, QET::Orientation orientation) {
 	qreal rotation_value = 90.0 * (orientation - element -> orientation().current());
 	element -> setOrientation(orientation);
-	element -> update();
+	//element -> update();
 	if (rotation_value) {
 		// repositionne les textes de l'element qui ne comportent pas l'option "FollowParentRotations"
 		foreach(ElementTextItem *eti, element -> texts()) {

Modified: branches/devel/sources/diagramcommands.h
===================================================================
--- branches/devel/sources/diagramcommands.h	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/diagramcommands.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -19,7 +19,7 @@
 #define DIAGRAM_COMMANDS_H
 #include <QtGui>
 #include "borderproperties.h"
-#include "conductor.h"
+#include "qetgraphicsitem/conductor.h"
 #include "conductorproperties.h"
 #include "diagramcontent.h"
 #include "titleblockproperties.h"

Modified: branches/devel/sources/diagramcontent.cpp
===================================================================
--- branches/devel/sources/diagramcontent.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/diagramcontent.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -17,9 +17,9 @@
 */
 #include "diagramcontent.h"
 #include <QGraphicsItem>
-#include "element.h"
-#include "independenttextitem.h"
-#include "conductor.h"
+#include "qetgraphicsitem/element.h"
+#include "qetgraphicsitem/independenttextitem.h"
+#include "qetgraphicsitem/conductor.h"
 #include "qetgraphicsitem/diagramimageitem.h"
 
 /**

Deleted: branches/devel/sources/diagramtextitem.cpp
===================================================================
--- branches/devel/sources/diagramtextitem.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/diagramtextitem.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -1,328 +0,0 @@
-/*
-	Copyright 2006-2013 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 "diagramtextitem.h"
-#include "diagramcommands.h"
-#include "qet.h"
-#include "qetapp.h"
-
-#include "richtext/richtexteditor_p.h"
-
-/**
-	Constructeur
-	@param parent Le QGraphicsItem parent du champ de texte
-	@param parent_diagram Le schema auquel appartient le champ de texte
-*/
-DiagramTextItem::DiagramTextItem(QGraphicsItem *parent, Diagram *parent_diagram) :
-	QGraphicsTextItem(parent, parent_diagram),
-	previous_text_(),
-	rotation_angle_(0.0)
-{
-	//set Zvalue at 10 to be upper than the DiagramImageItem
-	setZValue(10);
-	setDefaultTextColor(Qt::black);
-	setFont(QETApp::diagramTextsFont());
-	setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
-#if QT_VERSION >= 0x040600
-	setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
-#endif
-	connect(this, SIGNAL(lostFocus()), this, SLOT(setNonFocusable()));
-}
-
-/**
-	Constructeur
-	@param text Le texte affiche par le champ de texte
-	@param parent Le QGraphicsItem parent du champ de texte
-	@param parent_diagram Le schema auquel appartient le champ de texte
-*/
-DiagramTextItem::DiagramTextItem(const QString &text, QGraphicsItem *parent, Diagram *parent_diagram) :
-	QGraphicsTextItem(text, parent, parent_diagram),
-	previous_text_(text),
-	rotation_angle_(0.0)
-{
-	//set Zvalue at 10 to be upper than the DiagramImageItem
-	setZValue(10);
-	setDefaultTextColor(Qt::black);
-	setFont(QETApp::diagramTextsFont());
-	setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
-#if QT_VERSION >= 0x040600
-	setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
-#endif
-	connect(this, SIGNAL(lostFocus()), this, SLOT(setNonFocusable()));
-}
-
-/// Destructeur
-DiagramTextItem::~DiagramTextItem() {
-}
-
-/**
-	@return le Diagram auquel ce texte appartient, ou 0 si ce texte n'est
-	rattache a aucun schema
-*/
-Diagram *DiagramTextItem::diagram() const {
-	return(qobject_cast<Diagram *>(scene()));
-}
-
-/**
-	@return l'angle de rotation actuel de ce texte
-*/
-qreal DiagramTextItem::rotationAngle() const {
-	return(rotation_angle_);
-}
-
-/**
-	Permet de tourner le texte a un angle donne de maniere absolue.
-	Un angle de 0 degres correspond a un texte horizontal non retourne.
-	@param rotation Nouvel angle de rotation de ce texte
-	@see applyRotation
-*/
-void DiagramTextItem::setRotationAngle(const qreal &rotation) {
-	qreal applied_rotation = QET::correctAngle(rotation);
-	applyRotation(applied_rotation - rotation_angle_);
-	rotation_angle_ = applied_rotation;
-}
-
-/**
-	Permet de tourner le texte de maniere relative.
-	L'angle added_rotation est ajoute a l'orientation actuelle du texte.
-	@param added_rotation Angle a ajouter a la rotation actuelle
-	@see applyRotation
-*/
-void DiagramTextItem::rotateBy(const qreal &added_rotation) {
-	qreal applied_added_rotation = QET::correctAngle(added_rotation);
-	rotation_angle_ = QET::correctAngle(rotation_angle_ + applied_added_rotation);
-	applyRotation(applied_added_rotation);
-}
-
-/**
-	Traduit en coordonnees de la scene un mouvement / vecteur initialement
-	exprime en coordonnees locales.
-	@param movement Vecteur exprime en coordonnees locales
-	@return le meme vecteur, exprime en coordonnees de la scene
-*/
-QPointF DiagramTextItem::mapMovementToScene(const QPointF &movement) const {
-	// on definit deux points en coordonnees locales
-	QPointF local_origin(0.0, 0.0);
-	QPointF local_movement_point(movement);
-	
-	// on les mappe sur la scene
-	QPointF scene_origin(mapToScene(local_origin));
-	QPointF scene_movement_point(mapToScene(local_movement_point));
-	
-	// on calcule le vecteur represente par ces deux points
-	return(scene_movement_point - scene_origin);
-}
-
-/**
-	Traduit en coordonnees locales un mouvement / vecteur initialement
-	exprime en coordonnees de la scene.
-	@param movement Vecteur exprime en coordonnees de la scene
-	@return le meme vecteur, exprime en coordonnees locales
-*/
-QPointF DiagramTextItem::mapMovementFromScene(const QPointF &movement) const {
-	// on definit deux points sur la scene
-	QPointF scene_origin(0.0, 0.0);
-	QPointF scene_movement_point(movement);
-	
-	// on les mappe sur ce QGraphicsItem
-	QPointF local_origin(mapFromScene(scene_origin));
-	QPointF local_movement_point(mapFromScene(scene_movement_point));
-	
-	// on calcule le vecteur represente par ces deux points
-	return(local_movement_point - local_origin);
-}
-
-/**
-	Traduit en coordonnees de l'item parent un mouvement / vecteur initialement
-	exprime en coordonnees locales.
-	@param movement Vecteur exprime en coordonnees locales
-	@return le meme vecteur, exprime en coordonnees du parent
-*/
-QPointF DiagramTextItem::mapMovementToParent(const QPointF &movement) const {
-	// on definit deux points en coordonnees locales
-	QPointF local_origin(0.0, 0.0);
-	QPointF local_movement_point(movement);
-	
-	// on les mappe sur la scene
-	QPointF parent_origin(mapToParent(local_origin));
-	QPointF parent_movement_point(mapToParent(local_movement_point));
-	
-	// on calcule le vecteur represente par ces deux points
-	return(parent_movement_point - parent_origin);
-}
-
-/**
-	Traduit en coordonnees locales un mouvement / vecteur initialement
-	exprime en coordonnees du parent.
-	@param movement Vecteur exprime en coordonnees du parent
-	@return le meme vecteur, exprime en coordonnees locales
-*/
-QPointF DiagramTextItem::mapMovementFromParent(const QPointF &movement) const {
-	// on definit deux points sur le parent
-	QPointF parent_origin(0.0, 0.0);
-	QPointF parent_movement_point(movement);
-	
-	// on les mappe sur ce QGraphicsItem
-	QPointF local_origin(mapFromParent(parent_origin));
-	QPointF local_movement_point(mapFromParent(parent_movement_point));
-	
-	// on calcule le vecteur represente par ces deux points
-	return(local_movement_point - local_origin);
-}
-
-/**
-	Dessine le champ de texte.
-	Cette methode delegue simplement le travail a QGraphicsTextItem::paint apres
-	avoir desactive l'antialiasing.
-	@param painter Le QPainter a utiliser pour dessiner le champ de texte
-	@param option Les options de style pour le champ de texte
-	@param widget Le QWidget sur lequel on dessine 
-*/
-void DiagramTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
-	painter -> setRenderHint(QPainter::Antialiasing, false);
-	QGraphicsTextItem::paint(painter, option, widget);
-}
-
-/**
-	Gere la prise de focus du champ de texte
-	@param e Objet decrivant la prise de focus
-*/
-void DiagramTextItem::focusInEvent(QFocusEvent *e) {
-	QGraphicsTextItem::focusInEvent(e);
-	
-	// empeche le deplacement du texte pendant son edition
-	setFlag(QGraphicsItem::ItemIsMovable, false);
-	
-	// memorise le texte avant que l'utilisateur n'y touche
-	previous_text_ = toHtml();
-	// cela permettra de determiner si l'utilisateur a modifie le texte a la fin de l'edition
-}
-
-/**
-	Gere la perte de focus du champ de texte
-	@param e Objet decrivant la perte de focus
-*/
-void DiagramTextItem::focusOutEvent(QFocusEvent *e) {
-	QGraphicsTextItem::focusOutEvent(e);
-	
-	// signale la modification du texte si besoin
-	if (toPlainText() != previous_text_) {
-		emit(diagramTextChanged(this, previous_text_, toHtml()));
-		previous_text_ = toHtml();
-	}
-	
-	// deselectionne le texte
-	QTextCursor cursor = textCursor();
-	cursor.clearSelection();
-	setTextCursor(cursor);
-	
-	// hack a la con pour etre re-entrant
-	setTextInteractionFlags(Qt::NoTextInteraction);
-	
-	// autorise de nouveau le deplacement du texte
-	setFlag(QGraphicsItem::ItemIsMovable, true);
-	QTimer::singleShot(0, this, SIGNAL(lostFocus()));
-}
-
-/**
-	Gere les double-clics sur ce champ de texte.
-	@param event un QGraphicsSceneMouseEvent decrivant le double-clic
-*/
-void DiagramTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) {
-	if (!(textInteractionFlags() & Qt::TextEditable)) {
-		// rend le champ de texte editable
-		setTextInteractionFlags(Qt::TextEditorInteraction);
-		
-		// edite le champ de texte
-		setFocus(Qt::MouseFocusReason);
-	} else {
-		QGraphicsTextItem::mouseDoubleClickEvent(event);
-	}
-}
-
-/**
-	Effectue la rotation du texte en elle-meme
-	Pour les DiagramTextItem, la rotation s'effectue autour du point (0, 0).
-	Cette methode peut toutefois etre redefinie dans des classes filles
-	@param angle Angle de la rotation a effectuer
-*/
-void DiagramTextItem::applyRotation(const qreal &angle) {
-	setRotation(QET::correctAngle(rotation()+angle));
-}
-
-/**
-	Change la position du champ de texte en veillant a ce qu'il
-	reste sur la grille du schema auquel il appartient.
-	@param p Nouvelles coordonnees de l'element
-*/
-void DiagramTextItem::setPos(const QPointF &p) {
-	if (p == pos()) return;
-	// pas la peine de positionner sur la grille si l'element n'est pas sur un Diagram
-	if (scene()) {
-		// arrondit l'abscisse a 10 px pres
-		int p_x = qRound(p.x() / (Diagram::xGrid * 1.0)) * Diagram::xGrid;
-		// arrondit l'ordonnee a 10 px pres
-		int p_y = qRound(p.y() / (Diagram::yGrid * 1.0)) * Diagram::yGrid;
-		QGraphicsTextItem::setPos(p_x, p_y);
-	} else QGraphicsTextItem::setPos(p);
-}
-
-/**
-	Change la position du champ de texte en veillant a ce que l'il
-	reste sur la grille du schema auquel il appartient.
-	@param x Nouvelle abscisse de l'element
-	@param y Nouvelle ordonnee de l'element
-*/
-void DiagramTextItem::setPos(qreal x, qreal y) {
-	setPos(QPointF(x, y));
-}
-
-/**
-	@return la position du champ de texte
-*/
-QPointF DiagramTextItem::pos() const {
-	return(QGraphicsTextItem::pos());
-}
-
-/// Rend le champ de texte non focusable
-void DiagramTextItem::setNonFocusable() {
-	setFlag(QGraphicsTextItem::ItemIsFocusable, false);
-}
-
-
-/**
- * @brief DiagramTextItem::setHtmlText
- * @param txt
- */
-void DiagramTextItem::setHtmlText(const QString &txt) {
-	setHtml( txt );
-}
-
-/**
- * @brief Edit the text with HtmlEditor
- */
-void DiagramTextItem::edit() {
-	//Open the HtmlEditor
-	qdesigner_internal::RichTextEditorDialog *editor = new qdesigner_internal::RichTextEditorDialog();
-	// connect the in/out
-	connect(editor, SIGNAL(applyEditText(const QString &)), this, SLOT(setHtmlText(const QString &)));
-	// load the Html txt
-	editor->setText( toHtml() );
-	// show
-	editor->show();
-}
-

Deleted: branches/devel/sources/diagramtextitem.h
===================================================================
--- branches/devel/sources/diagramtextitem.h	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/diagramtextitem.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -1,85 +0,0 @@
-/*
-	Copyright 2006-2013 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 DIAGRAM_TEXT_ITEM_H
-#define DIAGRAM_TEXT_ITEM_H
-#include <QtGui>
-#include "diagram.h"
-/**
-	This class represents a selectable, movable and editable text field on a
-	diagram.
-	@see QGraphicsItem::GraphicsItemFlags
-*/
-class DiagramTextItem : public QGraphicsTextItem {
-	Q_OBJECT
-	// constructors, destructor
-	public:
-	DiagramTextItem(QGraphicsItem * = 0, Diagram * = 0);
-	DiagramTextItem(const QString &, QGraphicsItem * = 0, Diagram * = 0);
-	virtual ~DiagramTextItem();
-	
-	// attributes
-	public:
-	enum { Type = UserType + 1004 };
-	
-	// methods
-	public:
-	/**
-		Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
-		DiagramTextItem
-		@return the QGraphicsItem type
-	*/
-	virtual int type() const { return Type; }
-	Diagram *diagram() const;
-	virtual void fromXml(const QDomElement &) = 0;
-	virtual QDomElement toXml(QDomDocument &) const = 0;
-	virtual void setPos(const QPointF &);
-	virtual void setPos(qreal, qreal);
-	virtual QPointF pos() const;
-	qreal rotationAngle() const;
-	void setRotationAngle(const qreal &);
-	void rotateBy(const qreal &);
-	void edit();
-	QPointF mapMovementToScene(const QPointF &) const;
-	QPointF mapMovementFromScene(const QPointF &) const;
-	QPointF mapMovementToParent(const QPointF &) const;
-	QPointF mapMovementFromParent(const QPointF &) const;
-	
-	protected:
-	virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
-	virtual void focusInEvent(QFocusEvent *);
-	virtual void focusOutEvent(QFocusEvent *);
-	virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *);
-	virtual void applyRotation(const qreal &);
-	
-	signals:
-	/// signal emitted when the text field loses focus
-	void lostFocus();
-	/// signal emitted after text was changed
-	void diagramTextChanged(DiagramTextItem *, const QString &, const QString &);
-	
-	public slots:
-	void setNonFocusable();
-	void setHtmlText(const QString &);
-	
-	private:
-	/// Previous text value
-	QString previous_text_;
-	/// angle of rotation of the text field
-	qreal rotation_angle_;
-};
-#endif

Modified: branches/devel/sources/diagramview.cpp
===================================================================
--- branches/devel/sources/diagramview.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/diagramview.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -17,15 +17,15 @@
 */
 #include "diagramview.h"
 #include "diagram.h"
-#include "customelement.h"
-#include "ghostelement.h"
-#include "conductor.h"
+#include "qetgraphicsitem/customelement.h"
+#include "qetgraphicsitem/ghostelement.h"
+#include "qetgraphicsitem/conductor.h"
 #include "diagramcommands.h"
 #include "diagramposition.h"
 #include "conductorpropertieswidget.h"
-#include "conductortextitem.h"
-#include "elementtextitem.h"
-#include "independenttextitem.h"
+#include "qetgraphicsitem/conductortextitem.h"
+#include "qetgraphicsitem/elementtextitem.h"
+#include "qetgraphicsitem/independenttextitem.h"
 #include "qetgraphicsitem/diagramimageitem.h"
 #include "titleblockpropertieswidget.h"
 #include "templatelocation.h"

Modified: branches/devel/sources/editor/customelementpart.cpp
===================================================================
--- branches/devel/sources/editor/customelementpart.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/editor/customelementpart.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -16,7 +16,7 @@
 	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "customelementpart.h"
-#include "customelement.h"
+#include "qetgraphicsitem/customelement.h"
 #include "qetelementeditor.h"
 
 /// @return le QETElementEditor auquel cet editeur appartient

Deleted: branches/devel/sources/element.cpp
===================================================================
--- branches/devel/sources/element.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/element.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -1,529 +0,0 @@
-/*
-	Copyright 2006-2013 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 "element.h"
-#include "qetapp.h"
-#include "diagram.h"
-#include "conductor.h"
-#include "elementtextitem.h"
-#include "diagramcommands.h"
-#include <QtDebug>
-
-/**
-	Constructeur pour un element sans scene ni parent
-*/
-Element::Element(QGraphicsItem *parent, Diagram *scene) :
-	QObject(),
-	QGraphicsItem(parent, scene),
-	internal_connections_(false),
-	must_highlight_(false),
-	first_move_(true)
-{
-	setZValue(10);
-}
-
-/**
-	Destructeur
-*/
-Element::~Element() {
-}
-
-/**
-	@return true si l'element est mis en evidence
-*/
-bool Element::isHighlighted() const {
-	return(must_highlight_);
-}
-
-/**
-	@param hl true pour mettre l'element en evidence, false sinon
-*/
-void Element::setHighlighted(bool hl) {
-	must_highlight_ = hl;
-	update();
-}
-
-/**
-	Methode principale de dessin de l'element
-	@param painter Le QPainter utilise pour dessiner l'elment
-	@param options Les options de style a prendre en compte
-	@param widget  Le widget sur lequel on dessine
-*/
-void Element::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
-	
-#ifndef Q_WS_WIN
-	// corrige un bug de rendu ne se produisant que lors du rendu sur QGraphicsScene sous X11 au zoom par defaut
-	static bool must_correct_rendering_bug = QETApp::settings().value("correct-rendering", false).toBool();
-	if (must_correct_rendering_bug) {
-		Diagram *dia = diagram();
-		if (dia && options -> levelOfDetail == 1.0 && widget) {
-			// calcule la rotation qu'a subi l'element
-			qreal applied_rotation = 90.0 * (ori.current() - ori.defaultOrientation());
-			while (applied_rotation < 360.0) applied_rotation += 360.0;
-			while (applied_rotation > 360.0) applied_rotation -= 360.0;
-			if (applied_rotation == 90.0) painter -> translate(1.0, -1.0);
-			else if (applied_rotation == 180.0) painter -> translate(-1.0, -1.0);
-			else if (applied_rotation == 270.0) painter -> translate(-1.0, 1.0);
-		}
-	}
-#endif
-	if (must_highlight_) drawHighlight(painter, options);
-	
-	// Dessin de l'element lui-meme
-	paint(painter, options);
-	
-	// Dessin du cadre de selection si necessaire
-	if (isSelected()) drawSelection(painter, options);
-}
-
-/**
-	@return Le rectangle delimitant le contour de l'element
-*/
-QRectF Element::boundingRect() const {
-	return(QRectF(QPointF(-hotspot_coord.x(), -hotspot_coord.y()), dimensions));
-}
-
-/**
-	Definit la taille de l'element sur le schema. Les tailles doivent etre
-	des multiples de 10 ; si ce n'est pas le cas, les dimensions indiquees
-	seront arrrondies aux dizaines superieures.
-	@param wid Largeur de l'element
-	@param hei Hauteur de l'element
-	@return La taille finale de l'element
-*/
-QSize Element::setSize(int wid, int hei) {
-	prepareGeometryChange();
-	// chaque dimension indiquee est arrondie a la dizaine superieure
-	while (wid % 10) ++ wid;
-	while (hei % 10) ++ hei;
-	// les dimensions finales sont conservees et retournees
-	return(dimensions = QSize(wid, hei));
-}
-
-/**
-	@return la taille de l'element sur le schema
-*/
-QSize Element::size() const {
-	return(dimensions);
-}
-
-/**
-	Definit le hotspot de l'element par rapport au coin superieur gauche de son rectangle delimitant.
-	Necessite que la taille ait deja ete definie
-	@param hs Coordonnees du hotspot
-*/
-QPoint Element::setHotspot(QPoint hs) {
-	// la taille doit avoir ete definie
-	prepareGeometryChange();
-	if (dimensions.isNull()) hotspot_coord = QPoint(0, 0);
-	else {
-		// les coordonnees indiquees ne doivent pas depasser les dimensions de l'element
-		int hsx = qMin(hs.x(), dimensions.width());
-		int hsy = qMin(hs.y(), dimensions.height());
-		hotspot_coord = QPoint(hsx, hsy);
-	}
-	return(hotspot_coord);
-}
-
-/**
-	@return Le hotspot courant de l'element
-*/
-QPoint Element::hotspot() const {
-	return(hotspot_coord);
-}
-
-/**
-	Selectionne l'element
-*/
-void Element::select() {
-	setSelected(true);
-}
-
-/**
-	Deselectionne l'element
-*/
-void Element::deselect() {
-	setSelected(false);
-}
-
-/**
-	@return La pixmap de l'element
-*/
-QPixmap Element::pixmap() {
-	if (preview.isNull()) updatePixmap(); // on genere la pixmap si ce n'est deja fait
-	return(preview);
-}
-
-/**
-	Permet de specifier l'orientation de l'element
-	@param o la nouvelle orientation de l'objet
-	@return true si l'orientation a pu etre appliquee, false sinon
-*/
-bool Element::setOrientation(QET::Orientation o) {
-	// verifie que l'orientation demandee est acceptee
-	if (!ori.accept(o)) return(false);
-	prepareGeometryChange();
-	// rotation en consequence et rafraichissement de l'element graphique
-	qreal rotation_value = 90.0 * (o - ori.current());
-	rotate(rotation_value);
-	ori.setCurrent(o);
-	update();
-	foreach(QGraphicsItem *qgi, childItems()) {
-		if (Terminal *p = qgraphicsitem_cast<Terminal *>(qgi)) {
-			p -> updateConductor();
-		}
-	}
-	return(true);
-}
-
-/*** Methodes protegees ***/
-
-/**
-	Dessine un petit repere (axes x et y) relatif a l'element
-	@param painter Le QPainter a utiliser pour dessiner les axes
-	@param options Les options de style a prendre en compte
-*/
-void Element::drawAxes(QPainter *painter, const QStyleOptionGraphicsItem *options) {
-	Q_UNUSED(options);
-	painter -> setPen(Qt::blue);
-	painter -> drawLine(0, 0, 10, 0);
-	painter -> drawLine(7,-3, 10, 0);
-	painter -> drawLine(7, 3, 10, 0);
-	painter -> setPen(Qt::red);
-	painter -> drawLine(0,  0, 0, 10);
-	painter -> drawLine(0, 10,-3,  7);
-	painter -> drawLine(0, 10, 3,  7);
-}
-
-/*** Methodes privees ***/
-
-/**
-	Dessine le cadre de selection de l'element de maniere systematiquement non antialiasee.
-	@param painter Le QPainter a utiliser pour dessiner les bornes.
-	@param options Les options de style a prendre en compte
- */
-void Element::drawSelection(QPainter *painter, const QStyleOptionGraphicsItem *options) {
-	Q_UNUSED(options);
-	painter -> save();
-	// Annulation des renderhints
-	painter -> setRenderHint(QPainter::Antialiasing,          false);
-	painter -> setRenderHint(QPainter::TextAntialiasing,      false);
-	painter -> setRenderHint(QPainter::SmoothPixmapTransform, false);
-	// Dessin du cadre de selection en gris
-	QPen t;
-	t.setColor(Qt::gray);
-	t.setStyle(Qt::DashDotLine);
-	painter -> setPen(t);
-	// Le dessin se fait a partir du rectangle delimitant
-	painter -> drawRoundRect(boundingRect().adjusted(1, 1, -1, -1), 10, 10);
-	painter -> restore();
-}
-
-/**
-	Dessine le cadre de selection de l'element de maniere systematiquement non antialiasee.
-	@param painter Le QPainter a utiliser pour dessiner les bornes.
-	@param options Les options de style a prendre en compte
- */
-void Element::drawHighlight(QPainter *painter, const QStyleOptionGraphicsItem *options) {
-	Q_UNUSED(options);
-	painter -> save();
-	
-	qreal gradient_radius = qMin(boundingRect().width(), boundingRect().height()) / 2.0;
-	QRadialGradient gradient(
-		boundingRect().center(),
-		gradient_radius,
-		boundingRect().center()
-	);
-	gradient.setColorAt(0.0, QColor::fromRgb(69, 137, 255, 255));
-	gradient.setColorAt(1.0, QColor::fromRgb(69, 137, 255, 0));
-	QBrush brush(gradient);
-	
-	painter -> setPen(Qt::NoPen);
-	painter -> setBrush(brush);
-	// Le dessin se fait a partir du rectangle delimitant
-	painter -> drawRoundRect(boundingRect().adjusted(1, 1, -1, -1), 10, 10);
-	painter -> restore();
-}
-
-/**
-	Fonction initialisant et dessinant la pixmap de l'element.
-*/
-void Element::updatePixmap() {
-	// Pixmap transparente faisant la taille de base de l'element
-	preview = QPixmap(dimensions);
-	preview.fill(QColor(255, 255, 255, 0));
-	// QPainter sur la pixmap, avec antialiasing
-	QPainter p(&preview);
-	p.setRenderHint(QPainter::Antialiasing, true);
-	p.setRenderHint(QPainter::SmoothPixmapTransform, true);
-	// Translation de l'origine du repere de la pixmap
-	p.translate(hotspot_coord);
-	// L'element se dessine sur la pixmap
-	paint(&p, 0);
-}
-
-/**
-	Change la position de l'element en veillant a ce que l'element
-	reste sur la grille du Diagram auquel il appartient.
-	@param p Nouvelles coordonnees de l'element
-*/
-void Element::setPos(const QPointF &p) {
-	if (p == pos()) return;
-	// pas la peine de positionner sur la grille si l'element n'est pas sur un Diagram
-	if (scene()) {
-		// arrondit l'abscisse a 10 px pres
-		int p_x = qRound(p.x() / (Diagram::xGrid * 1.0)) * Diagram::xGrid;
-		// arrondit l'ordonnee a 10 px pres
-		int p_y = qRound(p.y() / (Diagram::yGrid * 1.0)) * Diagram::yGrid;
-		QGraphicsItem::setPos(p_x, p_y);
-	} else QGraphicsItem::setPos(p);
-}
-
-/**
-	Change la position de l'element en veillant a ce que l'element
-	reste sur la grille du Diagram auquel il appartient.
-	@param x Nouvelle abscisse de l'element
-	@param y Nouvelle ordonnee de l'element
-*/
-void Element::setPos(qreal x, qreal y) {
-	setPos(QPointF(x, y));
-}
-
-/**
-	Gere le clic sur l'element
-	@param e Objet decrivant l'evenement souris
-*/
-void Element::mousePressEvent(QGraphicsSceneMouseEvent *e) {
-	first_move_ = true;
-	if (e -> modifiers() & Qt::ControlModifier) {
-		setSelected(!isSelected());
-	}
-	QGraphicsItem::mousePressEvent(e);
-}
-
-/**
-	Gere les mouvements de souris lies a l'element
-	@param e Objet decrivant l'evenement souris
-*/
-void Element::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
-	if (isSelected() && e -> buttons() & Qt::LeftButton) {
-		// l'element est en train d'etre deplace
-		Diagram *diagram_ptr = diagram();
-		if (diagram_ptr) {
-			if (first_move_) {
-				// il s'agit du premier mouvement du deplacement, on le signale
-				// au schema parent
-				diagram_ptr -> beginMoveElements(this);
-			}
-		}
-		
-		// on applique le mouvement impose par la souris
-		QPointF old_pos = pos();
-		setPos(mapToParent(e -> pos()) - matrix().map(e -> buttonDownPos(Qt::LeftButton)));
-		
-		// on calcule le mouvement reellement applique par setPos()
-		QPointF effective_movement = pos() - old_pos;
-		
-		if (diagram_ptr) {
-			// on signale le mouvement ainsi applique au schema parent, qui
-			// l'appliquera aux autres items selectionnes selon son bon vouloir
-			diagram_ptr -> continueMoveElements(effective_movement);
-		}
-	} else e -> ignore();
-	
-	if (first_move_) {
-		first_move_ = false;
-	}
-}
-
-/**
-	Gere le relachement de souris
-	Cette methode a ete reimplementee pour tenir a jour la liste des elements
-	et conducteurs a deplacer au niveau du schema.
-*/
-void Element::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
-	if (Diagram *diagram_ptr = diagram()) {
-		diagram_ptr -> endMoveElements();
-	}
-	
-	if (!(e -> modifiers() & Qt::ControlModifier)) {
-		QGraphicsItem::mouseReleaseEvent(e);
-	}
-}
-
-/**
-	Permet de savoir si un element XML (QDomElement) represente bien un element
-	@param e Le QDomElement a valide
-	@return true si l'element XML est un Element, false sinon
-*/
-bool Element::valideXml(QDomElement &e) {
-	// verifie le nom du tag
-	if (e.tagName() != "element") return(false);
-	
-	// verifie la presence des attributs minimaux
-	if (!e.hasAttribute("type")) return(false);
-	if (!e.hasAttribute("x"))    return(false);
-	if (!e.hasAttribute("y"))    return(false);
-	
-	bool conv_ok;
-	// parse l'abscisse
-	e.attribute("x").toDouble(&conv_ok);
-	if (!conv_ok) return(false);
-	
-	// parse l'ordonnee
-	e.attribute("y").toDouble(&conv_ok);
-	if (!conv_ok) return(false);
-	return(true);
-}
-
-/**
-	Methode d'import XML. Cette methode est appelee lors de l'import de contenu
-	XML (coller, import, ouverture de fichier...) afin que l'element puisse
-	gerer lui-meme l'importation de ses bornes. Ici, comme cette classe est
-	caracterisee par un nombre fixe de bornes, l'implementation exige de
-	retrouver exactement ses bornes dans le fichier XML.
-	@param e L'element XML a analyser.
-	@param table_id_adr Reference vers la table de correspondance entre les IDs
-	du fichier XML et les adresses en memoire. Si l'import reussit, il faut y
-	ajouter les bons couples (id, adresse).
-	@return true si l'import a reussi, false sinon
-	
-*/
-bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr, bool handle_inputs_rotation) {
-	/*
-		les bornes vont maintenant etre recensees pour associer leurs id a leur adresse reelle
-		ce recensement servira lors de la mise en place des fils
-	*/
-	QList<QDomElement> liste_terminals;
-	foreach(QDomElement qde, QET::findInDomElement(e, "terminals", "terminal")) {
-		if (Terminal::valideXml(qde)) liste_terminals << qde;
-	}
-	
-	QHash<int, Terminal *> priv_id_adr;
-	int terminals_non_trouvees = 0;
-	foreach(QGraphicsItem *qgi, childItems()) {
-		if (Terminal *p = qgraphicsitem_cast<Terminal *>(qgi)) {
-			bool terminal_trouvee = false;
-			foreach(QDomElement qde, liste_terminals) {
-				if (p -> fromXml(qde)) {
-					priv_id_adr.insert(qde.attribute("id").toInt(), p);
-					terminal_trouvee = true;
-					// We used to break here, because we did not expect
-					// several terminals to share the same position.
-					// Of course, it finally happened.
-				}
-			}
-			if (!terminal_trouvee) ++ terminals_non_trouvees;
-		}
-	}
-	
-	if (terminals_non_trouvees > 0) {
-		return(false);
-	} else {
-		// verifie que les associations id / adr n'entrent pas en conflit avec table_id_adr
-		foreach(int id_trouve, priv_id_adr.keys()) {
-			if (table_id_adr.contains(id_trouve)) {
-				// cet element possede un id qui est deja reference (= conflit)
-				return(false);
-			}
-		}
-		// copie des associations id / adr
-		foreach(int id_trouve, priv_id_adr.keys()) {
-			table_id_adr.insert(id_trouve, priv_id_adr.value(id_trouve));
-		}
-	}
-	
-	// importe les valeurs des champs de texte
-	QList<QDomElement> inputs = QET::findInDomElement(e, "inputs", "input");
-	foreach(QGraphicsItem *qgi, childItems()) {
-		if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(qgi)) {
-			foreach(QDomElement input, inputs) eti -> fromXml(input);
-		}
-	}
-	
-	// position, selection
-	setPos(e.attribute("x").toDouble(), e.attribute("y").toDouble());
-	setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
-	
-	// orientation
-	bool conv_ok;
-	int read_ori = e.attribute("orientation").toInt(&conv_ok);
-	if (!conv_ok || read_ori < 0 || read_ori > 3) read_ori = ori.defaultOrientation();
-	if (handle_inputs_rotation) {
-		RotateElementsCommand::rotateElement(this, (QET::Orientation)read_ori);
-	} else {
-		setOrientation((QET::Orientation)read_ori);
-	}
-	return(true);
-}
-
-/**
-	Permet d'exporter l'element en XML
-	@param document Document XML a utiliser
-	@param table_adr_id Table de correspondance entre les adresses des bornes
-	et leur id dans la representation XML ; cette table completee par cette
-	methode
-	@return L'element XML representant cet element electrique
-*/
-QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table_adr_id) const {
-	QDomElement element = document.createElement("element");
-	
-	// type
-	element.setAttribute("type", typeId());
-	
-	// position, selection et orientation
-	element.setAttribute("x", QString("%1").arg(pos().x()));
-	element.setAttribute("y", QString("%1").arg(pos().y()));
-	element.setAttribute("orientation", QString("%1").arg(ori.current()));
-	
-	/* recupere le premier id a utiliser pour les bornes de cet element */
-	int id_terminal = 0;
-	if (!table_adr_id.isEmpty()) {
-		// trouve le plus grand id
-		int max_id_t = -1;
-		foreach (int id_t, table_adr_id.values()) {
-			if (id_t > max_id_t) max_id_t = id_t;
-		}
-		id_terminal = max_id_t + 1;
-	}
-	
-	// enregistrement des bornes de l'appareil
-	QDomElement xml_terminals = document.createElement("terminals");
-	// pour chaque enfant de l'element
-	foreach(Terminal *t, terminals()) {
-		// alors on enregistre la borne
-		QDomElement terminal = t -> toXml(document);
-		terminal.setAttribute("id", id_terminal);
-		table_adr_id.insert(t, id_terminal ++);
-		xml_terminals.appendChild(terminal);
-	}
-	element.appendChild(xml_terminals);
-	
-	// enregistrement des champ de texte de l'appareil
-	QDomElement inputs = document.createElement("inputs");
-	foreach(ElementTextItem *eti, texts()) {
-		inputs.appendChild(eti -> toXml(document));
-	}
-	element.appendChild(inputs);
-	
-	return(element);
-}
-
-/// @return le Diagram auquel cet element appartient, ou 0 si cet element est independant
-Diagram *Element::diagram() const {
-	return(qobject_cast<Diagram *>(scene()));
-}

Deleted: branches/devel/sources/element.h
===================================================================
--- branches/devel/sources/element.h	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/element.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -1,166 +0,0 @@
-/*
-	Copyright 2006-2013 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 ELEMENT_H
-#define ELEMENT_H
-#include <QtGui>
-#include "terminal.h"
-#include "orientationset.h"
-class Diagram;
-class ElementTextItem;
-/**
-	This is the base class for electrical elements.
-*/
-class Element : public QObject, public QGraphicsItem {
-	
-	Q_OBJECT
-	Q_INTERFACES(QGraphicsItem)
-	
-	// constructors, destructor
-	public:
-	Element(QGraphicsItem * = 0, Diagram * = 0);
-	virtual ~Element();
-	
-	private:
-	Element(const Element &);
-	
-	// attributes
-	public:
-	enum { Type = UserType + 1000 };
-	
-	protected:
-	/**
-		Hold orientations for the element :
-			* allowed orientations
-			* current orientation
-			* default orientation
-		@see OrientationSet
-	*/
-	OrientationSet ori;
-	
-	private:
-	QSize   dimensions;
-	QPoint  hotspot_coord;
-	QPixmap preview;
-	
-	// methods
-	public:
-	/**
-		Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into an
-		Element.
-		@return the QGraphicsItem type
-	*/
-	virtual int type() const { return Type; }
-	
-	// pure virtual methods to be defined in derived classes
-	/// @return the list of terminals for this element
-	virtual QList<Terminal *> terminals() const = 0;
-	/// @return the list of conductors attached to this element
-	virtual QList<Conductor *> conductors() const = 0;
-	/// @return the list of text items attached to this element
-	virtual QList<ElementTextItem *> texts() const = 0;
-	/// @return the current number of terminals of this element
-	virtual int terminalsCount() const = 0;
-	/// @return the minimum number of terminals for this element
-	virtual int minTerminalsCount() const = 0;
-	/// @return the maximum number of terminals for this element
-	virtual int maxTerminalsCount() const = 0;
-	/**
-		Draw this element
-	*/
-	virtual void paint(QPainter *, const QStyleOptionGraphicsItem *) = 0;
-	/// @return This element type ID
-	virtual QString typeId() const = 0;
-	/// @return the human name for this element
-	virtual QString name() const = 0;
-	Diagram *diagram() const;
-	
-	virtual bool isHighlighted() const;
-	virtual void setHighlighted(bool);
-	void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
-	QRectF boundingRect() const;
-	QSize setSize(int, int);
-	QSize size() const;
-	QPixmap  pixmap();
-	
-	// methods related to the hotspot
-	QPoint setHotspot(QPoint);
-	QPoint hotspot() const;
-	
-	// selection-related methods
-	void select();
-	void deselect();
-	
-	// position-related methods
-	void setPos(const QPointF &);
-	void setPos(qreal, qreal);
-	
-	// methods related to internal connections
-	bool internalConnections();
-	void setInternalConnections(bool);
-	
-	// methods related to XML import/export
-	static bool valideXml(QDomElement &);
-	virtual bool fromXml(QDomElement &, QHash<int, Terminal *> &, bool = false);
-	virtual QDomElement toXml(QDomDocument &, QHash<Terminal *, int> &) const;
-	
-	// orientation-related methods
-	bool setOrientation(QET::Orientation o);
-	const OrientationSet &orientation() const;
-	
-	protected:
-	void drawAxes(QPainter *, const QStyleOptionGraphicsItem *);
-	void mousePressEvent(QGraphicsSceneMouseEvent *);
-	void mouseMoveEvent(QGraphicsSceneMouseEvent *);
-	void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
-	
-	private:
-	bool internal_connections_;
-	bool must_highlight_;
-	bool first_move_;
-	void drawSelection(QPainter *, const QStyleOptionGraphicsItem *);
-	void drawHighlight(QPainter *, const QStyleOptionGraphicsItem *);
-	void updatePixmap();
-};
-
-/**
-	Indicate whether this element allows internal connections, i.e. whether its
-	terminals can be linked together using a conductor.
-	@return true if internal connections are accepted, false otherwise
-*/
-inline bool Element::internalConnections() {
-	return(internal_connections_);
-}
-
-/**
-	Specify whether this element allows internal connections, i.e. whether its
-	terminals can be linked together using a conductor.
-	@return true for internal connections to be accepted, false otherwise
-*/
-inline void Element::setInternalConnections(bool ic) {
-	internal_connections_ = ic;
-}
-
-/**
-	Indicate the current orientation of this element
-	@return the current orientation of this element
-*/
-inline const OrientationSet & Element::orientation() const {
-	return(ori);
-}
-
-#endif

Modified: branches/devel/sources/elementscategorieslist.cpp
===================================================================
--- branches/devel/sources/elementscategorieslist.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/elementscategorieslist.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -17,7 +17,7 @@
 */
 #include "elementscategorieslist.h"
 #include "qetapp.h"
-#include "customelement.h"
+#include "qetgraphicsitem/customelement.h"
 #include "elementscollection.h"
 #include "elementscategory.h"
 #include "elementdefinition.h"

Modified: branches/devel/sources/elementscollectioncache.cpp
===================================================================
--- branches/devel/sources/elementscollectioncache.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/elementscollectioncache.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -2,7 +2,7 @@
 #include "elementscollection.h"
 #include "elementscategory.h"
 #include "elementdefinition.h"
-#include "customelement.h"
+#include "qetgraphicsitem/customelement.h"
 
 /**
 	Construct a cache for elements collections.

Modified: branches/devel/sources/elementsmover.cpp
===================================================================
--- branches/devel/sources/elementsmover.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/elementsmover.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -16,12 +16,12 @@
 	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "elementsmover.h"
-#include "conductor.h"
-#include "conductortextitem.h"
+#include "qetgraphicsitem/conductor.h"
+#include "qetgraphicsitem/conductortextitem.h"
 #include "diagram.h"
 #include "diagramcommands.h"
-#include "element.h"
-#include "independenttextitem.h"
+#include "qetgraphicsitem/element.h"
+#include "qetgraphicsitem/independenttextitem.h"
 #include "qetgraphicsitem/diagramimageitem.h"
 
 /**

Modified: branches/devel/sources/elementspanel.cpp
===================================================================
--- branches/devel/sources/elementspanel.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/elementspanel.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -21,7 +21,7 @@
 #include "diagram.h"
 #include "elementscategory.h"
 #include "elementscollectioncache.h"
-#include "customelement.h"
+#include "qetgraphicsitem/customelement.h"
 #include "fileelementscollection.h"
 #include "fileelementdefinition.h"
 #include "qeticons.h"

Deleted: branches/devel/sources/elementtextitem.cpp
===================================================================
--- branches/devel/sources/elementtextitem.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/elementtextitem.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -1,310 +0,0 @@
-/*
-	Copyright 2006-2012 Xavier Guerrin
-	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 "elementtextitem.h"
-#include "diagram.h"
-#include "diagramcommands.h"
-#include "element.h"
-
-/**
-	Constructeur
-	@param parent_element Le QGraphicsItem parent du champ de texte
-	@param parent_diagram Le schema auquel appartient le champ de texte
-*/
-ElementTextItem::ElementTextItem(Element *parent_element, Diagram *parent_diagram) :
-	DiagramTextItem(parent_element, parent_diagram),
-	parent_element_(parent_element),
-	follow_parent_rotations(false),
-	original_rotation_angle_(0.0),
-	first_move_(true)
-{
-	// par defaut, les DiagramTextItem sont Selectable et Movable
-	// cela nous convient, on ne touche pas a ces flags
-	
-	adjustItemPosition(1);
-	// ajuste la position du QGraphicsItem lorsque le QTextDocument change
-	connect(document(), SIGNAL(blockCountChanged(int)), this, SLOT(adjustItemPosition(int)));
-	connect(document(), SIGNAL(contentsChanged()),      this, SLOT(adjustItemPosition()));
-}
-
-/**
-	Constructeur
-	@param parent_element L'element parent du champ de texte
-	@param parent_diagram Le schema auquel appartient le champ de texte
-	@param text Le texte affiche par le champ de texte
-*/
-ElementTextItem::ElementTextItem(const QString &text, Element *parent_element, Diagram *parent_diagram) :
-	DiagramTextItem(text, parent_element, parent_diagram),
-	parent_element_(parent_element),
-	follow_parent_rotations(false),
-	original_rotation_angle_(0.0),
-	first_move_(true)
-{
-	// par defaut, les DiagramTextItem sont Selectable et Movable
-	// cela nous convient, on ne touche pas a ces flags
-	
-	adjustItemPosition(1);
-	// ajuste la position du QGraphicsItem lorsque le QTextDocument change
-	connect(document(), SIGNAL(blockCountChanged(int)), this, SLOT(adjustItemPosition(int)));
-	connect(document(), SIGNAL(contentsChanged()),      this, SLOT(adjustItemPosition()));
-}
-
-/// Destructeur
-ElementTextItem::~ElementTextItem() {
-}
-
-/**
-	@return L'element parent de ce champ de texte, ou 0 si celui-ci n'en a pas.
-*/
-Element *ElementTextItem::parentElement() const {
-	return(parent_element_);
-}
-
-/**
-	Modifie la position du champ de texte
-	@param pos La nouvelle position du champ de texte
-*/
-void ElementTextItem::setPos(const QPointF &pos) {
-	QGraphicsTextItem::setPos(pos);
-}
-
-/**
-	Modifie la position du champ de texte
-	@param x La nouvelle abscisse du champ de texte
-	@param y La nouvelle ordonnee du champ de texte
-*/
-void ElementTextItem::setPos(qreal x, qreal y) {
-	setPos(QPointF(x, y));
-}
-
-/**
-	@return La position (bidouillee) du champ de texte
-*/
-QPointF ElementTextItem::pos() const {
-	return(QGraphicsTextItem::pos());
-}
-
-/**
-	Permet de lire le texte a mettre dans le champ a partir d'un element XML.
-	Cette methode se base sur la position du champ pour assigner ou non la
-	valeur a ce champ.
-	@param e L'element XML representant le champ de texte
-*/
-void ElementTextItem::fromXml(const QDomElement &e) {
-	QPointF _pos = pos();
-	if (
-		qFuzzyCompare(qreal(e.attribute("x").toDouble()), _pos.x()) &&
-		qFuzzyCompare(qreal(e.attribute("y").toDouble()), _pos.y())
-	) {
-		setPlainText(e.attribute("text"));
-		
-		qreal user_pos_x, user_pos_y;
-		if (
-			QET::attributeIsAReal(e, "userx", &user_pos_x) &&
-			QET::attributeIsAReal(e, "usery", &user_pos_y)
-		) {
-			setPos(user_pos_x, user_pos_y);
-		}
-		
-		qreal xml_rotation_angle;
-		if (QET::attributeIsAReal(e, "userrotation", &xml_rotation_angle)) {
-			setRotationAngle(xml_rotation_angle);
-		}
-	}
-}
-
-/**
-	@param document Le document XML a utiliser
-	@return L'element XML representant ce champ de texte
-*/
-QDomElement ElementTextItem::toXml(QDomDocument &document) const {
-	QDomElement result = document.createElement("input");
-	
-	result.setAttribute("x", QString("%1").arg(originalPos().x()));
-	result.setAttribute("y", QString("%1").arg(originalPos().y()));
-	
-	if (pos() != originalPos()) {
-		result.setAttribute("userx", QString("%1").arg(pos().x()));
-		result.setAttribute("usery", QString("%1").arg(pos().y()));
-	}
-	
-	result.setAttribute("text", toPlainText());
-	
-	if (rotationAngle() != originalRotationAngle()) {
-		result.setAttribute("userrotation", QString("%1").arg(rotationAngle()));
-	}
-	
-	return(result);
-}
-
-/**
-	@param p Position originale / de reference pour ce champ
-	Cette position est utilisee lors de l'export en XML
-*/
-void ElementTextItem::setOriginalPos(const QPointF &p) {
-	original_position = p;
-}
-
-/**
-	@return la position originale / de reference pour ce champ
-*/
-QPointF ElementTextItem::originalPos() const {
-	return(original_position);
-}
-
-/**
-	Definit l'angle de rotation original de ce champ de texte
-	@param rotation_angle un angle de rotation
-*/
-void ElementTextItem::setOriginalRotationAngle(const qreal &rotation_angle) {
-	original_rotation_angle_ = QET::correctAngle(rotation_angle);
-}
-
-/**
-	@return l'angle de rotation original de ce champ de texte
-*/
-qreal ElementTextItem::originalRotationAngle() const {
-	return(original_rotation_angle_);
-}
-
-/**
-	Set the font used to render the text item to \a font.
-*/
-void ElementTextItem::setFont(const QFont &font) {
-	DiagramTextItem::setFont(font);
-	adjustItemPosition(1);
-}
-
-/**
-	Cette methode s'assure que la position de l'ElementTextItem est coherente
-	en ajustant :
-		* la transformation de base qui permet de considerer que l'origine
-	correspond au milieu du bord gauche du champ de texte
-		* l'origine utilisee lors des appels a setRotation et setScale
-	@param new_block_count Nombre de blocs dans l'ElementTextItem
-*/
-void ElementTextItem::adjustItemPosition(int new_block_count) {
-	Q_UNUSED(new_block_count);
-	qreal origin_offset = boundingRect().bottom() / 2.0;
-	
-	QTransform base_translation;
-	base_translation.translate(0.0, -origin_offset);
-	setTransform(base_translation, false);
-	setTransformOriginPoint(0.0, origin_offset);
-}
-
-/**
-	Effetue la rotation du texte en elle-meme
-	Pour les ElementTextItem, la rotation s'effectue autour du milieu du bord
-	gauche du champ de texte.
-	@param angle Angle de la rotation a effectuer
-*/
-void ElementTextItem::applyRotation(const qreal &angle) {
-	QGraphicsTextItem::setRotation(QGraphicsTextItem::rotation() + angle);
-}
-
-/**
-	Gere le clic sur le champ de texte
-	@param e Objet decrivant l'evenement souris
-*/
-void ElementTextItem::mousePressEvent(QGraphicsSceneMouseEvent *e) {
-	first_move_ = true;
-	if (e -> modifiers() & Qt::ControlModifier) {
-		setSelected(!isSelected());
-	}
-	DiagramTextItem::mousePressEvent(e);
-}
-
-/**
-	Gere les mouvements de souris lies au champ de texte
-	@param e Objet decrivant l'evenement souris
-*/
-void ElementTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
-	if (textInteractionFlags() & Qt::TextEditable) {
-		DiagramTextItem::mouseMoveEvent(e);
-	} else if ((flags() & QGraphicsItem::ItemIsMovable) && (e -> buttons() & Qt::LeftButton)) {
-		QPointF old_pos = pos();
-		/*
-			Utiliser e -> pos() directement aurait pour effet de positionner
-			l'origine du champ de texte a la position indiquee par le curseur,
-			ce qui n'est pas l'effet recherche
-			Au lieu de cela, on applique a la position actuelle le vecteur
-			definissant le mouvement effectue depuis la derniere position
-			cliquee avec le bouton gauche
-		*/
-		QPointF movement = e -> pos() - e -> buttonDownPos(Qt::LeftButton);
-		
-		/*
-			Les methodes pos() et setPos() travaillent toujours avec les
-			coordonnees de l'item parent (ou de la scene s'il n'y a pas d'item
-			parent). On n'oublie donc pas de mapper le mouvement fraichement
-			calcule sur l'item parent avant de l'appliquer.
-		*/
-		QPointF parent_movement = mapMovementToParent(movement);
-		setPos(pos() + parent_movement);
-		
-		Diagram *diagram_ptr = diagram();
-		if (diagram_ptr) {
-			if (first_move_) {
-				// on signale le debut d'un deplacement d'ElementTextItems au schema parent
-				int moved_texts_count = diagram_ptr -> beginMoveElementTexts(this);
-				
-				// s'il n'y a qu'un seul texte deplace, on met en valeur l'element parent
-				if (moved_texts_count == 1 && parent_element_) {
-					parent_element_ -> setHighlighted(true);
-					parent_element_ -> update();
-				}
-			}
-			
-			/*
-				Comme setPos() n'est pas oblige d'appliquer exactement la
-				valeur qu'on lui fournit, on calcule le mouvement reellement
-				applique.
-			*/
-			QPointF effective_movement = pos() - old_pos;
-			QPointF scene_effective_movement = mapMovementToScene(mapMovementFromParent(effective_movement));
-			
-			// on applique le mouvement subi aux autres textes a deplacer
-			diagram_ptr -> continueMoveElementTexts(scene_effective_movement);
-		}
-	} else e -> ignore();
-	
-	if (first_move_) {
-		first_move_ = false;
-	}
-}
-
-/**
-	Gere le relachement de souris
-	Cette methode cree un objet d'annulation pour le deplacement
-	@param e Objet decrivant l'evenement souris
-*/
-void ElementTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
-	if (Diagram *diagram_ptr = diagram()) {
-		// on arrete de mettre en valeur l'element parent
-		if (parent_element_) {
-			if (parent_element_ -> isHighlighted()) {
-				parent_element_ -> setHighlighted(false);
-			}
-		}
-		
-		diagram_ptr -> endMoveElementTexts();
-	}
-	if (!(e -> modifiers() & Qt::ControlModifier)) {
-		QGraphicsTextItem::mouseReleaseEvent(e);
-	}
-}

Deleted: branches/devel/sources/elementtextitem.h
===================================================================
--- branches/devel/sources/elementtextitem.h	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/elementtextitem.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -1,96 +0,0 @@
-/*
-	Copyright 2006-2012 Xavier Guerrin
-	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 ELEMENT_TEXT_ITEM_H
-#define ELEMENT_TEXT_ITEM_H
-#include "diagramtextitem.h"
-#include <QtXml>
-class Diagram;
-class Element;
-/**
-	This class represents a text item attached to an element. Users can change its
-	value, adjust its position (defined relatively to its parent element), and
-	direct it to any angle.
-*/
-class ElementTextItem : public DiagramTextItem {
-	Q_OBJECT
-	// constructors, destructor
-	public:
-	ElementTextItem(Element * = 0, Diagram * = 0);
-	ElementTextItem(const QString &, Element * = 0, Diagram * = 0);
-	virtual ~ElementTextItem();
-	
-	// attributes
-	public:
-	enum { Type = UserType + 1003 };
-	
-	private:
-	Element *parent_element_;
-	bool follow_parent_rotations;
-	QPointF original_position;
-	qreal original_rotation_angle_;
-	bool first_move_;
-	
-	// methods
-	public:
-	virtual int type() const { return Type; }
-	Element *parentElement() const;
-	/// @return the rectangle defining the bounds of this text item
-	virtual QRectF boundingRect() const { return(QGraphicsTextItem::boundingRect().adjusted(0.0, -1.1, 0.0, 0.0)); }
-	bool followParentRotations() const;
-	void setFollowParentRotations(bool);
-	void fromXml(const QDomElement &);
-	QDomElement toXml(QDomDocument &) const;
-	void setPos(const QPointF &);
-	void setPos(qreal, qreal);
-	virtual QPointF pos() const;
-	void setOriginalPos(const QPointF &);
-	QPointF originalPos() const;
-	void setOriginalRotationAngle(const qreal &);
-	qreal originalRotationAngle() const;
-	virtual void setFont(const QFont &);
-	
-	public slots:
-	void adjustItemPosition(int = 0);
-	
-	protected:
-	virtual void applyRotation(const qreal &);
-	virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
-	virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
-	virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
-};
-
-/**
-	Element text items can optionally be applied a counter-rotation when their
-	parent element is rotated, thus preserving their readability.
-	@return whether this text item follows the rotations of its parent element.
-*/
-inline bool ElementTextItem::followParentRotations() const {
-	return(follow_parent_rotations);
-}
-
-/**
-	Element text items can optionally be applied a counter-rotation when their
-	parent element is rotated, thus preserving their readability.
-	@param frp whether this text item should follow the rotations of its parent
-	element.
-*/
-inline void ElementTextItem::setFollowParentRotations(bool frp) {
-	follow_parent_rotations = frp;
-}
-
-#endif

Modified: branches/devel/sources/elementtextsmover.cpp
===================================================================
--- branches/devel/sources/elementtextsmover.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/elementtextsmover.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -16,12 +16,12 @@
 	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "elementtextsmover.h"
-#include "conductor.h"
-#include "elementtextitem.h"
+#include "qetgraphicsitem/conductor.h"
+#include "qetgraphicsitem/elementtextitem.h"
 #include "diagram.h"
 #include "diagramcommands.h"
-#include "element.h"
-#include "independenttextitem.h"
+#include "qetgraphicsitem/element.h"
+#include "qetgraphicsitem/independenttextitem.h"
 
 /**
 	Constructeur

Deleted: branches/devel/sources/fixedelement.cpp
===================================================================
--- branches/devel/sources/fixedelement.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/fixedelement.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -1,43 +0,0 @@
-/*
-	Copyright 2006-2012 Xavier Guerrin
-	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 "fixedelement.h"
-/**
-	Constructeur
-*/
-FixedElement::FixedElement(QGraphicsItem *parent, Diagram *scene) : Element(parent, scene) {
-}
-
-/**
-	Destructeur
-*/
-FixedElement::~FixedElement() {
-}
-
-/**
-	@return Le nombre minimal de bornes que l'element peut avoir
-*/
-int FixedElement::minTerminalsCount() const {
-	return(terminalsCount());
-}
-
-/**
-	@return Le nombre maximal de bornes que l'element peut avoir
-*/
-int FixedElement::maxTerminalsCount() const {
-	return(terminalsCount());
-}

Deleted: branches/devel/sources/fixedelement.h
===================================================================
--- branches/devel/sources/fixedelement.h	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/fixedelement.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -1,42 +0,0 @@
-/*
-	Copyright 2006-2012 Xavier Guerrin
-	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 ELEMENTFIXE_H
-#define ELEMENTFIXE_H
-#include "element.h"
-/**
-	This class represents an element having a fixed number of terminals.
-*/
-class FixedElement : public Element {
-	
-	Q_OBJECT
-	
-	// constructors, destructor
-	public:
-	FixedElement(QGraphicsItem * = 0, Diagram * = 0);
-	virtual ~FixedElement();
-	
-	// methods
-	public:
-	int minTerminalsCount() const;
-	int maxTerminalsCount() const;
-	virtual int terminalsCount() const = 0;
-	virtual void paint(QPainter *, const QStyleOptionGraphicsItem *) = 0;
-	virtual QString typeId() const = 0;
-	virtual QString name() const = 0;
-};
-#endif

Deleted: branches/devel/sources/ghostelement.cpp
===================================================================
--- branches/devel/sources/ghostelement.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/ghostelement.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -1,191 +0,0 @@
-/*
-	Copyright 2006-2012 Xavier Guerrin
-	This file is part of QElectroTech.
-	
-	QElectroTech is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 2 of the License, or
-	(at your option) any later version.
-	
-	QElectroTech is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-	
-	You should have received a copy of the GNU General Public License
-	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#include "ghostelement.h"
-#include "qet.h"
-#include "terminal.h"
-#include "elementtextitem.h"
-#include "diagramcommands.h"
-
-/**
-	Constructeur
-	@param location Emplacement de la definition d'element a utiliser
-	@param qgi Le QGraphicsItem parent de cet element
-	@param d Le schema affichant cet element
-*/
-GhostElement::GhostElement(
-	const ElementsLocation &location,
-	QGraphicsItem *qgi,
-	Diagram *d
-) :
-	CustomElement(location, qgi, d)
-{
-	QString tooltip_string = QString(
-		tr("<u>\311l\351ment manquant\240:</u> %1")
-	).arg(location_.toString());
-	setToolTip(tooltip_string);
-}
-
-/**
-	Destructeur
-*/
-GhostElement::~GhostElement() {
-}
-
-
-/**
-	@param e L'element XML a analyser.
-	@param table_id_adr Reference vers la table de correspondance entre les IDs
-	du fichier XML et les adresses en memoire. Si l'import reussit, il faut y
-	ajouter les bons couples (id, adresse).
-	@return true si l'import a reussi, false sinon
-*/
-bool GhostElement::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr, bool handle_inputs_rotation) {
-	// instancie les bornes decrites dans l'element XML
-	terminalsFromXml(e, table_id_adr);
-	
-	// instancie les champs de texte decrits dans l'element XML
-	foreach(QDomElement qde, QET::findInDomElement(e, "inputs", "input")) {
-		qde.setAttribute("size", 9); // arbitraire
-		if (ElementTextItem *new_input = CustomElement::parseInput(qde)) {
-			new_input -> fromXml(qde);
-		}
-		qde.removeAttribute("size");
-	}
-	
-	/*
-		maintenant que l'element fantome connait toutes les bornes et tous les
-		champs de texte, on peut determiner une taille appropriee
-	*/
-	QRect final_bounding_rect = minimalBoundingRect().united(childrenBoundingRect()).toAlignedRect();
-	setSize(final_bounding_rect.width(), final_bounding_rect.height());
-	setHotspot(QPoint() - final_bounding_rect.topLeft());
-	setInternalConnections(true);
-	
-	// on peut desormais confectionner le rendu de l'element
-	generateDrawings();
-	
-	// position, selection
-	setPos(e.attribute("x").toDouble(), e.attribute("y").toDouble());
-	setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
-	
-	// orientation
-	bool conv_ok;
-	int read_ori = e.attribute("orientation").toInt(&conv_ok);
-	if (!conv_ok || read_ori < 0 || read_ori > 3) read_ori = ori.defaultOrientation();
-	if (handle_inputs_rotation) {
-		RotateElementsCommand::rotateElement(this, (QET::Orientation)read_ori);
-	} else {
-		setOrientation((QET::Orientation)read_ori);
-	}
-	return(true);
-}
-
-/**
-	@return le bounding rect minimum, utilise si l'element fantome n'a ni champ
-	de texte ni borne.
-*/
-QRectF GhostElement::minimalBoundingRect() const {
-	return(
-		QRectF(
-			QPointF(-10.0, -10.0),
-			QSizeF(20.0, 20.0)
-		)
-	);
-}
-
-/**
-	Gere l'import des bornes
-	@param e L'element XML a analyser.
-	@param table_id_adr Reference vers la table de correspondance entre les IDs
-	du fichier XML et les adresses en memoire. Si l'import reussit, il faut y
-	ajouter les bons couples (id, adresse).
-	@return true si l'import a reussi, false sinon
-*/
-bool GhostElement::terminalsFromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr) {
-	// instancie les bornes decrites dans l'element XML
-	foreach(QDomElement qde, QET::findInDomElement(e, "terminals", "terminal")) {
-		if (!Terminal::valideXml(qde)) continue;
-		
-		// modifie certains attributs pour que l'analyse par la classe CustomElement reussisse
-		int previous_x_value   = qde.attribute("x").toInt();
-		int previous_y_value   = qde.attribute("y").toInt();
-		int previous_ori_value = qde.attribute("orientation").toInt();
-		
-		qreal x_add = 0.0, y_add = 0.0;
-		if (previous_ori_value == QET::North)      y_add = -Terminal::terminalSize;
-		else if (previous_ori_value == QET::East)  x_add = Terminal::terminalSize;
-		else if (previous_ori_value == QET::South) y_add = Terminal::terminalSize;
-		else if (previous_ori_value == QET::West)  x_add = -Terminal::terminalSize;
-		qde.setAttribute("x",           previous_x_value + x_add);
-		qde.setAttribute("y",           previous_y_value + y_add);
-		qde.setAttribute("orientation", QET::orientationToString(static_cast<QET::Orientation>(previous_ori_value)));
-		
-		if (Terminal *new_terminal = CustomElement::parseTerminal(qde)) {
-			table_id_adr.insert(qde.attribute("id").toInt(), new_terminal);
-		}
-		
-		// restaure les attributs modifies
-		qde.setAttribute("x",           previous_x_value);
-		qde.setAttribute("y",           previous_y_value);
-		qde.setAttribute("orientation", previous_ori_value);
-	}
-	return(true);
-}
-
-/**
-	Genere les rendus de l'element fantome : il s'agit d'un rectangle
-	representant grosso modo l'espace que devait prendre l'element initial.
-	En son centre est dessine un point d'interrogation. Une petite croix indique
-	le point de saisie de l'element.
-*/
-void GhostElement::generateDrawings() {
-	// style de dessin
-	QPen t(QBrush(Qt::black), 1.0);
-	
-	// rendu normal
-	QPainter qp;
-	qp.begin(&drawing);
-	qp.setPen(t);
-	qp.setRenderHint(QPainter::Antialiasing, false);
-	generateDrawing(&qp);
-	qp.end();
-	
-	// rendu low_zoom
-	QPainter low_zoom_qp;
-	low_zoom_qp.begin(&low_zoom_drawing);
-	t.setCosmetic(true);
-	low_zoom_qp.setRenderHint(QPainter::Antialiasing, false);
-	low_zoom_qp.setPen(t);
-	generateDrawing(&low_zoom_qp);
-	low_zoom_qp.end();
-}
-
-/**
-	Genere un rendu de l'element fantome
-	@see generateDrawings
-*/
-void GhostElement::generateDrawing(QPainter *painter) {
-	// une petite croix indique le point de saisie de l'element
-	painter -> drawLine(QLineF(-1.0, 0.0, 1.0, 0.0));
-	painter -> drawLine(QLineF(0.0, -1.0, 0.0, 1.0));
-	
-	// rectangle avec un point d'interrogation au centre
-	QRectF drawn_rect = boundingRect().adjusted(4.0, 4.0, -4.0, -4.0);
-	painter -> drawRect(drawn_rect);
-	painter -> drawText(drawn_rect, Qt::AlignHCenter | Qt::AlignVCenter, "?");
-}

Deleted: branches/devel/sources/ghostelement.h
===================================================================
--- branches/devel/sources/ghostelement.h	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/ghostelement.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -1,53 +0,0 @@
-/*
-	Copyright 2006-2012 Xavier Guerrin
-	This file is part of QElectroTech.
-	
-	QElectroTech is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 2 of the License, or
-	(at your option) any later version.
-	
-	QElectroTech is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-	
-	You should have received a copy of the GNU General Public License
-	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef GHOST_ELEMENT_H
-#define GHOST_ELEMENT_H
-#include "customelement.h"
-class Diagram;
-class QGraphicsItem;
-class ElementsLocation;
-class Terminal;
-/**
-	The GhostElement class inherits CustomElement. A GhostElement aims at
-	visually replacing a CustomElement whose definition could not be loaded.
-	This way, instead of not loading an element, thus potentially losing its
-	position, its orientation, its child text items and conductors, one can
-	substitute a GhostElement. The GhostElement will extrapolate the position
-	of terminals and text items from the rest of the diagram. It is visually
-	rendered using a simple rectangle.
-*/
-class GhostElement : public CustomElement {
-	
-	Q_OBJECT
-	
-	// constructor, destructor
-	public:
-	GhostElement(const ElementsLocation &, QGraphicsItem * = 0, Diagram * = 0);
-	virtual ~GhostElement();
-	
-	// methods
-	public:
-	virtual bool fromXml(QDomElement &, QHash<int, Terminal *> &, bool = false);
-	
-	protected:
-	QRectF minimalBoundingRect() const;
-	bool terminalsFromXml(QDomElement &, QHash<int, Terminal *> &);
-	void generateDrawings();
-	void generateDrawing(QPainter *);
-};
-#endif

Deleted: branches/devel/sources/independenttextitem.cpp
===================================================================
--- branches/devel/sources/independenttextitem.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/independenttextitem.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -1,140 +0,0 @@
-/*
-	Copyright 2006-2012 Xavier Guerrin
-	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 "independenttextitem.h"
-#include "diagram.h"
-
-/**
-	Constructeur
-	@param parent_diagram Le schema auquel est rattache le champ de texte
-*/
-IndependentTextItem::IndependentTextItem(Diagram *parent_diagram) :
-	DiagramTextItem(0, parent_diagram),
-	first_move_(true)
-{
-}
-
-/**
-	Constructeur
-	@param text Le texte affiche par le champ de texte
-	@param parent_diagram Le schema auquel est rattache le champ de texte
-*/
-IndependentTextItem::IndependentTextItem(const QString &text, Diagram *parent_diagram) :
-	DiagramTextItem(text, 0, parent_diagram),
-	first_move_(true)
-{
-}
-
-/// Destructeur
-IndependentTextItem::~IndependentTextItem() {
-}
-
-/**
-	Permet de lire le texte a mettre dans le champ a partir d'un element XML.
-	Cette methode se base sur la position du champ pour assigner ou non la
-	valeur a ce champ.
-	@param e L'element XML representant le champ de texte
-*/
-void IndependentTextItem::fromXml(const QDomElement &e) {
-	setPos(e.attribute("x").toDouble(), e.attribute("y").toDouble());
-	setHtml(e.attribute("text"));
-	setRotationAngle(e.attribute("rotation").toDouble());
-}
-
-/**
-	@param document Le document XML a utiliser
-	@return L'element XML representant ce champ de texte
-*/
-QDomElement IndependentTextItem::toXml(QDomDocument &document) const {
-	QDomElement result = document.createElement("input");
-	result.setAttribute("x", QString("%1").arg(pos().x()));
-	result.setAttribute("y", QString("%1").arg(pos().y()));
-	result.setAttribute("text", toHtml());
-	if (rotationAngle()) {
-		result.setAttribute("rotation", QString("%1").arg(rotationAngle()));
-	}
-	return(result);
-}
-
-/**
-	Gere le clic sur le champ de texte
-	@param e Objet decrivant l'evenement souris
-*/
-void IndependentTextItem::mousePressEvent(QGraphicsSceneMouseEvent *e) {
-	first_move_ = true;
-	if (e -> modifiers() & Qt::ControlModifier) {
-		setSelected(!isSelected());
-	}
-	DiagramTextItem::mousePressEvent(e);
-}
-
-/**
-	Gere les mouvements de souris lies au champ de texte
-	@param e Objet decrivant l'evenement souris
-*/
-void IndependentTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
-	if (textInteractionFlags() & Qt::TextEditable) {
-		DiagramTextItem::mouseMoveEvent(e);
-	} else if ((flags() & QGraphicsItem::ItemIsMovable) && isSelected() && (e -> buttons() & Qt::LeftButton)) {
-		// le champ de texte est en train d'etre deplace
-		Diagram *diagram_ptr = diagram();
-		if (diagram_ptr) {
-			if (first_move_) {
-				// il s'agit du premier mouvement du deplacement, on le signale
-				// au schema parent
-				diagram_ptr -> beginMoveElements(this);
-			}
-		}
-		
-		// on applique le mouvement impose par la souris
-		QPointF old_pos = pos();
-		if (first_move_) {
-			mouse_to_origin_movement_ = old_pos - e -> buttonDownScenePos(Qt::LeftButton);
-		}
-		QPointF expected_pos = e-> scenePos() + mouse_to_origin_movement_;
-		setPos(expected_pos); // setPos() will snap the expected position to the grid
-		
-		// on calcule le mouvement reellement applique par setPos()
-		QPointF effective_movement = pos() - old_pos;
-		if (diagram_ptr) {
-			// on signale le mouvement ainsi applique au schema parent, qui
-			// l'appliquera aux autres items selectionnes selon son bon vouloir
-			diagram_ptr -> continueMoveElements(effective_movement);
-		}
-	} else e -> ignore();
-	
-	if (first_move_) {
-		first_move_ = false;
-	}
-}
-
-/**
-	Gere le relachement de souris
-	Cette methode a ete reimplementee pour tenir a jour la liste des elements
-	et conducteurs a deplacer au niveau du schema.
-	@param e Objet decrivant l'evenement souris
-*/
-void IndependentTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
-	if (flags() & QGraphicsItem::ItemIsMovable) {
-		if (Diagram *diagram_ptr = diagram()) {
-			diagram_ptr -> endMoveElements();
-		}
-	}
-	if (!(e -> modifiers() & Qt::ControlModifier)) {
-		DiagramTextItem::mouseReleaseEvent(e);
-	}
-}

Deleted: branches/devel/sources/independenttextitem.h
===================================================================
--- branches/devel/sources/independenttextitem.h	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/independenttextitem.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -1,58 +0,0 @@
-/*
-	Copyright 2006-2012 Xavier Guerrin
-	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 INDEPENDENT_TEXT_ITEM_H
-#define INDEPENDENT_TEXT_ITEM_H
-#include <QtGui>
-#include "diagramtextitem.h"
-/**
-	This class represents an independent text field on a particular diagram.
-	It may be moved, edited, and rotated.
-*/
-class IndependentTextItem : public DiagramTextItem {
-	Q_OBJECT
-	// constructors, destructor
-	public:
-	IndependentTextItem(Diagram * = 0);
-	IndependentTextItem(const QString &, Diagram* = 0);
-	virtual ~IndependentTextItem();
-	
-	// attributes
-	public:
-	enum { Type = UserType + 1005 };
-	
-	// methods
-	public:
-	/**
-		Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into an
-		IndependentTextItem.
-		@return le type de QGraphicsItem
-	*/
-	virtual int type() const { return Type; }
-	virtual void fromXml(const QDomElement &);
-	virtual QDomElement toXml(QDomDocument &) const;
-	
-	protected:
-	virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
-	virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
-	virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
-	
-	private:
-	bool first_move_;
-	QPointF mouse_to_origin_movement_;
-};
-#endif

Modified: branches/devel/sources/newelementwizard.cpp
===================================================================
--- branches/devel/sources/newelementwizard.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/newelementwizard.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -21,7 +21,7 @@
 #include "elementscategorieslist.h"
 #include "nameslistwidget.h"
 #include "orientationsetwidget.h"
-#include "element.h"
+#include "qetgraphicsitem/element.h"
 #include "qetelementeditor.h"
 #include "qet.h"
 #include "qetapp.h"

Modified: branches/devel/sources/nomenclature.h
===================================================================
--- branches/devel/sources/nomenclature.h	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/nomenclature.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -22,9 +22,9 @@
 
 #include "qetproject.h"
 #include "diagram.h"
-#include "element.h"
+#include "qetgraphicsitem/element.h"
 #include "diagramcontent.h"
-#include "customelement.h"
+#include "qetgraphicsitem/customelement.h"
 
 class QETProject;
 class Diagram;

Modified: branches/devel/sources/qetdiagrameditor.cpp
===================================================================
--- branches/devel/sources/qetdiagrameditor.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/qetdiagrameditor.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -20,10 +20,10 @@
 #include "diagramcontent.h"
 #include "diagramview.h"
 #include "diagram.h"
-#include "element.h"
+#include "qetgraphicsitem/element.h"
 #include "elementspanelwidget.h"
 #include "conductorpropertieswidget.h"
-#include "customelement.h"
+#include "qetgraphicsitem/customelement.h"
 #include "qetproject.h"
 #include "projectview.h"
 #include "recentfiles.h"

Added: branches/devel/sources/qetgraphicsitem/conductor.cpp
===================================================================
--- branches/devel/sources/qetgraphicsitem/conductor.cpp	                        (rev 0)
+++ branches/devel/sources/qetgraphicsitem/conductor.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -0,0 +1,1631 @@
+/*
+	Copyright 2006-2013 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 <QtDebug>
+#include "conductor.h"
+#include "conductorsegment.h"
+#include "conductorsegmentprofile.h"
+#include "conductortextitem.h"
+#include "element.h"
+#include "diagram.h"
+#include "diagramcommands.h"
+#include "conductorautonumerotation.h"
+#define PR(x) qDebug() << #x " = " << x;
+
+bool Conductor::pen_and_brush_initialized = false;
+QPen Conductor::conductor_pen = QPen();
+QBrush Conductor::conductor_brush = QBrush();
+QBrush Conductor::square_brush = QBrush(Qt::darkGreen);
+/**
+	Constructeur
+	@param p1              Premiere Borne a laquelle le conducteur est lie
+	@param p2              Seconde Borne a laquelle le conducteur est lie
+	@param parent_diagram  QGraphicsScene a laquelle appartient le conducteur
+*/
+Conductor::Conductor(Terminal *p1, Terminal* p2, Diagram *parent_diagram) :
+	QObject(),
+	QGraphicsPathItem(0, parent_diagram),
+	terminal1(p1),
+	terminal2(p2),
+	destroyed_(false),
+	text_item(0),
+	segments(NULL),
+	moving_point(false),
+	moving_segment(false),
+	modified_path(false),
+	has_to_save_profile(false),
+	segments_squares_scale_(1.0),
+	must_highlight_(Conductor::None)
+{
+	//set Zvalue at 9 to be upper than the DiagramImageItem and bottom of element(10)
+	setZValue(9);
+	previous_z_value = zValue();
+
+	// ajout du conducteur a la liste de conducteurs de chacune des deux bornes
+	bool ajout_p1 = terminal1 -> addConductor(this);
+	bool ajout_p2 = terminal2 -> addConductor(this);
+	
+	// en cas d'echec de l'ajout (conducteur deja existant notamment)
+	if (!ajout_p1 || !ajout_p2) return;
+	
+	// attributs de dessin par defaut (communs a tous les conducteurs)
+	if (!pen_and_brush_initialized) {
+		conductor_pen.setJoinStyle(Qt::MiterJoin);
+		conductor_pen.setCapStyle(Qt::SquareCap);
+		conductor_pen.setColor(Qt::black);
+		conductor_pen.setStyle(Qt::SolidLine);
+		conductor_pen.setWidthF(1.0);
+		conductor_brush.setColor(Qt::white);
+		conductor_brush.setStyle(Qt::NoBrush);
+		pen_and_brush_initialized = true;
+	}
+	
+	// par defaut, les 4 profils sont des profils nuls = il faut utiliser priv_calculeConductor
+	conductor_profiles.insert(Qt::TopLeftCorner,     ConductorProfile());
+	conductor_profiles.insert(Qt::TopRightCorner,    ConductorProfile());
+	conductor_profiles.insert(Qt::BottomLeftCorner,  ConductorProfile());
+	conductor_profiles.insert(Qt::BottomRightCorner, ConductorProfile());
+
+	// calcul du rendu du conducteur
+	generateConductorPath(terminal1 -> dockConductor(), terminal1 -> orientation(), terminal2 -> dockConductor(), terminal2 -> orientation());
+	setFlags(QGraphicsItem::ItemIsSelectable);
+	setAcceptsHoverEvents(true);
+	
+	// ajout du champ de texte editable
+	text_item = new ConductorTextItem(properties_.text, this);
+	calculateTextItemPosition();
+	connect(
+		text_item,
+		SIGNAL(diagramTextChanged(DiagramTextItem *, const QString &, const QString &)),
+		this,
+		SLOT(displayedTextChanged())
+	);
+}
+
+/**
+	Destructeur
+	Detruit le conducteur ainsi que ses segments. Il ne detruit pas les bornes
+	mais s'en detache
+*/
+Conductor::~Conductor() {
+	// se detache des bornes
+	if (!isDestroyed()) destroy();
+	
+	// supprime les segments
+	deleteSegments();
+}
+
+/**
+	Met a jour la representation graphique du conducteur en recalculant son
+	trace. Cette fonction est typiquement appelee lorsqu'une seule des bornes du
+	conducteur a change de position.
+	@param rect Rectangle a mettre a jour
+	@see QGraphicsPathItem::update()
+*/
+void Conductor::updatePath(const QRectF &rect) {
+	QPointF p1, p2;
+	p1 = terminal1 -> dockConductor();
+	p2 = terminal2 -> dockConductor();
+	if (segmentsCount() && !conductor_profiles[currentPathType()].isNull())
+		updateConductorPath(p1, terminal1 -> orientation(), p2, terminal2 -> orientation());
+	else
+		generateConductorPath(p1, terminal1 -> orientation(), p2, terminal2 -> orientation());
+	calculateTextItemPosition();
+	QGraphicsPathItem::update(rect);
+}
+
+/**
+	Genere le QPainterPath a partir de la liste des points
+*/
+void Conductor::segmentsToPath() {
+	// chemin qui sera dessine
+	QPainterPath path;
+	
+	// s'il n'y a pa des segments, on arrete la
+	if (segments == NULL) setPath(path);
+	
+	// demarre le chemin
+	path.moveTo(segments -> firstPoint());
+	
+	// parcourt les segments pour dessiner le chemin
+	ConductorSegment *segment = segments;
+	while(segment -> hasNextSegment()) {
+		path.lineTo(segment -> secondPoint());
+		segment = segment -> nextSegment();
+	}
+	
+	// termine le chemin
+	path.lineTo(segment -> secondPoint());
+	
+	// affecte le chemin au conducteur
+	setPath(path);
+}
+
+/**
+	Gere les updates
+	@param p1 Coordonnees du point d'amarrage de la borne 1
+	@param o1 Orientation de la borne 1
+	@param p2 Coordonnees du point d'amarrage de la borne 2
+	@param o2 Orientation de la borne 2
+*/
+void Conductor::updateConductorPath(const QPointF &p1, QET::Orientation o1, const QPointF &p2, QET::Orientation o2) {
+	Q_UNUSED(o1);
+	Q_UNUSED(o2);
+	
+	ConductorProfile &conductor_profile = conductor_profiles[currentPathType()];
+	
+	Q_ASSERT_X(conductor_profile.segmentsCount(QET::Both) > 1, "Conductor::priv_modifieConductor", "pas de points a modifier");
+	Q_ASSERT_X(!conductor_profile.isNull(),                 "Conductor::priv_modifieConductor", "pas de profil utilisable");
+	
+	// recupere les coordonnees fournies des bornes
+	QPointF new_p1 = mapFromScene(p1);
+	QPointF new_p2 = mapFromScene(p2);
+	QRectF new_rect = QRectF(new_p1, new_p2);
+	
+	// recupere la largeur et la hauteur du profil
+	qreal profile_width  = conductor_profile.width();
+	qreal profile_height = conductor_profile.height();
+	
+	// calcule les differences verticales et horizontales a appliquer
+	qreal h_diff = (qAbs(new_rect.width())  - qAbs(profile_width) ) * getSign(profile_width);
+	qreal v_diff = (qAbs(new_rect.height()) - qAbs(profile_height)) * getSign(profile_height);
+	
+	// applique les differences aux segments
+	QHash<ConductorSegmentProfile *, qreal> segments_lengths;
+	segments_lengths.unite(shareOffsetBetweenSegments(h_diff, conductor_profile.horizontalSegments()));
+	segments_lengths.unite(shareOffsetBetweenSegments(v_diff, conductor_profile.verticalSegments()));
+	
+	// en deduit egalement les coefficients d'inversion (-1 pour une inversion, +1 pour conserver le meme sens)
+	int horiz_coeff = getCoeff(new_rect.width(),  profile_width);
+	int verti_coeff = getCoeff(new_rect.height(), profile_height);
+	
+	// genere les nouveaux points
+	QList<QPointF> points;
+	points << new_p1;
+	int limit = conductor_profile.segments.count() - 1;
+	for (int i = 0 ; i < limit ; ++ i) {
+		// dernier point
+		QPointF previous_point = points.last();
+		
+		// profil de segment de conducteur en cours
+		ConductorSegmentProfile *csp = conductor_profile.segments.at(i);
+		
+		// coefficient et offset a utiliser pour ce point
+		qreal coeff = csp -> isHorizontal ? horiz_coeff : verti_coeff;
+		qreal offset_applied = segments_lengths[csp];
+		
+		// applique l'offset et le coeff au point
+		if (csp -> isHorizontal) {
+			points << QPointF (
+				previous_point.x() + (coeff * offset_applied),
+				previous_point.y()
+			);
+		} else {
+			points << QPointF (
+				previous_point.x(),
+				previous_point.y() + (coeff * offset_applied)
+			);
+		}
+	}
+	points << new_p2;
+	pointsToSegments(points);
+	segmentsToPath();
+}
+
+/**
+	@param offset Longueur a repartir entre les segments
+	@param segments_list Segments sur lesquels il faut repartir la longueur
+	@param precision seuil en-deca duquel on considere qu'il ne reste rien a repartir
+*/
+QHash<ConductorSegmentProfile *, qreal> Conductor::shareOffsetBetweenSegments(
+	const qreal &offset,
+	const QList<ConductorSegmentProfile *> &segments_list,
+	const qreal &precision
+) const {
+	// construit le QHash qui sera retourne
+	QHash<ConductorSegmentProfile *, qreal> segments_hash;
+	foreach(ConductorSegmentProfile *csp, segments_list) {
+		segments_hash.insert(csp, csp -> length);
+	}
+	
+	// memorise le signe de la longueur de chaque segement
+	QHash<ConductorSegmentProfile *, int> segments_signs;
+	foreach(ConductorSegmentProfile *csp, segments_hash.keys()) {
+		segments_signs.insert(csp, getSign(csp -> length));
+	}
+	
+	//qDebug() << "repartition d'un offset de" << offset << "px sur" << segments_list.count() << "segments";
+	
+	// repartit l'offset sur les segments
+	qreal remaining_offset = offset;
+	while (remaining_offset > precision || remaining_offset < -precision) {
+		// recupere le nombre de segments differents ayant une longueur non nulle
+		uint segments_count = 0;
+		foreach(ConductorSegmentProfile *csp, segments_hash.keys()) if (segments_hash[csp]) ++ segments_count;
+		//qDebug() << "  remaining_offset =" << remaining_offset;
+		qreal local_offset = remaining_offset / segments_count;
+		//qDebug() << "  repartition d'un offset local de" << local_offset << "px sur" << segments_count << "segments";
+		remaining_offset = 0.0;
+		foreach(ConductorSegmentProfile *csp, segments_hash.keys()) {
+			// ignore les segments de longueur nulle
+			if (!segments_hash[csp]) continue;
+			// applique l'offset au segment
+			//qreal segment_old_length = segments_hash[csp];
+			segments_hash[csp] += local_offset;
+			
+			// (la longueur du segment change de signe) <=> (le segment n'a pu absorbe tout l'offset)
+			if (segments_signs[csp] != getSign(segments_hash[csp])) {
+				
+				// on remet le trop-plein dans la reserve d'offset
+				remaining_offset += qAbs(segments_hash[csp]) * getSign(local_offset);
+				//qDebug() << "    trop-plein de" << qAbs(segments_hash[csp]) * getSign(local_offset) << "remaining_offset =" << remaining_offset;
+				segments_hash[csp] = 0.0;
+			} else {
+				//qDebug() << "    offset local de" << local_offset << "accepte";
+			}
+		}
+	}
+	
+	return(segments_hash);
+}
+
+/**
+	Calcule un trajet "par defaut" pour le conducteur
+	@param p1 Coordonnees du point d'amarrage de la borne 1
+	@param o1 Orientation de la borne 1
+	@param p2 Coordonnees du point d'amarrage de la borne 2
+	@param o2 Orientation de la borne 2
+*/
+void Conductor::generateConductorPath(const QPointF &p1, QET::Orientation o1, const QPointF &p2, QET::Orientation o2) {
+	QPointF sp1, sp2, depart, newp1, newp2, arrivee, depart0, arrivee0;
+	QET::Orientation ori_depart, ori_arrivee;
+	
+	// s'assure qu'il n'y a ni points
+	QList<QPointF> points;
+	
+	// mappe les points par rapport a la scene
+	sp1 = mapFromScene(p1);
+	sp2 = mapFromScene(p2);
+	
+	// prolonge les bornes
+	newp1 = extendTerminal(sp1, o1);
+	newp2 = extendTerminal(sp2, o2);
+	
+	// distingue le depart de l'arrivee : le trajet se fait toujours de gauche a droite (apres prolongation)
+	if (newp1.x() <= newp2.x()) {
+		depart      = newp1;
+		arrivee     = newp2;
+		depart0     = sp1;
+		arrivee0    = sp2;
+		ori_depart  = o1;
+		ori_arrivee = o2;
+	} else {
+		depart      = newp2;
+		arrivee     = newp1;
+		depart0     = sp2;
+		arrivee0    = sp1;
+		ori_depart  = o2;
+		ori_arrivee = o1;
+	}
+	
+	// debut du trajet
+	points << depart0;
+	
+	// prolongement de la borne de depart 
+	points << depart;
+	
+	// commence le vrai trajet
+	if (depart.y() < arrivee.y()) {
+		// trajet descendant
+		if ((ori_depart == QET::North && (ori_arrivee == QET::South || ori_arrivee == QET::West)) || (ori_depart == QET::East && ori_arrivee == QET::West)) {
+			// cas "3"
+			int ligne_inter_x = qRound(depart.x() + arrivee.x()) / 2;
+			while (ligne_inter_x % Diagram::xGrid) -- ligne_inter_x;
+			points << QPointF(ligne_inter_x, depart.y());
+			points << QPointF(ligne_inter_x, arrivee.y());
+		} else if ((ori_depart == QET::South && (ori_arrivee == QET::North || ori_arrivee == QET::East)) || (ori_depart == QET::West && ori_arrivee == QET::East)) {
+			// cas "4"
+			int ligne_inter_y = qRound(depart.y() + arrivee.y()) / 2;
+			while (ligne_inter_y % Diagram::yGrid) -- ligne_inter_y;
+			points << QPointF(depart.x(), ligne_inter_y);
+			points << QPointF(arrivee.x(), ligne_inter_y);
+		} else if ((ori_depart == QET::North || ori_depart == QET::East) && (ori_arrivee == QET::North || ori_arrivee == QET::East)) {
+			points << QPointF(arrivee.x(), depart.y()); // cas "2"
+		} else {
+			points << QPointF(depart.x(), arrivee.y()); // cas "1"
+		}
+	} else {
+		// trajet montant
+		if ((ori_depart == QET::West && (ori_arrivee == QET::East || ori_arrivee == QET::South)) || (ori_depart == QET::North && ori_arrivee == QET::South)) {
+			// cas "3"
+			int ligne_inter_y = qRound(depart.y() + arrivee.y()) / 2;
+			while (ligne_inter_y % Diagram::yGrid) -- ligne_inter_y;
+			points << QPointF(depart.x(), ligne_inter_y);
+			points << QPointF(arrivee.x(), ligne_inter_y);
+		} else if ((ori_depart == QET::East && (ori_arrivee == QET::West || ori_arrivee == QET::North)) || (ori_depart == QET::South && ori_arrivee == QET::North)) {
+			// cas "4"
+			int ligne_inter_x = qRound(depart.x() + arrivee.x()) / 2;
+			while (ligne_inter_x % Diagram::xGrid) -- ligne_inter_x;
+			points << QPointF(ligne_inter_x, depart.y());
+			points << QPointF(ligne_inter_x, arrivee.y());
+		} else if ((ori_depart == QET::West || ori_depart == QET::North) && (ori_arrivee == QET::West || ori_arrivee == QET::North)) {
+			points << QPointF(depart.x(), arrivee.y()); // cas "2"
+		} else {
+			points << QPointF(arrivee.x(), depart.y()); // cas "1"
+		}
+	}
+	
+	// fin du vrai trajet
+	points << arrivee;
+	
+	// prolongement de la borne d'arrivee
+	points << arrivee0;
+	
+	// inverse eventuellement l'ordre des points afin que le trajet soit exprime de la borne 1 vers la borne 2
+	if (newp1.x() > newp2.x()) {
+		QList<QPointF> points2;
+		for (int i = points.size() - 1 ; i >= 0 ; -- i) points2 << points.at(i);
+		points = points2;
+	}
+	
+	pointsToSegments(points);
+	segmentsToPath();
+}
+
+/**
+	Prolonge une borne.
+	@param terminal Le point correspondant a la borne
+	@param terminal_orientation L'orientation de la borne
+	@param ext_size la taille de la prolongation
+	@return le point correspondant a la borne apres prolongation
+*/
+QPointF Conductor::extendTerminal(const QPointF &terminal, QET::Orientation terminal_orientation, qreal ext_size) {
+	QPointF extended_terminal;
+	switch(terminal_orientation) {
+		case QET::North:
+			extended_terminal = QPointF(terminal.x(), terminal.y() - ext_size);
+			break;
+		case QET::East:
+			extended_terminal = QPointF(terminal.x() + ext_size, terminal.y());
+			break;
+		case QET::South:
+			extended_terminal = QPointF(terminal.x(), terminal.y() + ext_size);
+			break;
+		case QET::West:
+			extended_terminal = QPointF(terminal.x() - ext_size, terminal.y());
+			break;
+		default: extended_terminal = terminal;
+	}
+	return(extended_terminal);
+}
+
+/**
+	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);
+	qp -> save();
+	qp -> setRenderHint(QPainter::Antialiasing, false);
+	
+	// determine la couleur du conducteur
+	QColor final_conductor_color(properties_.color);
+	if (must_highlight_ == Normal) {
+		final_conductor_color = QColor::fromRgb(69, 137, 255, 255);
+	} else if (must_highlight_ == Alert) {
+		final_conductor_color =QColor::fromRgb(255, 69, 0, 255);
+	} else if (isSelected()) {
+		final_conductor_color = Qt::red;
+	} else {
+		if (Diagram *parent_diagram = diagram()) {
+			if (!parent_diagram -> drawColoredConductors()) {
+				final_conductor_color = Qt::black;
+			}
+		}
+	}
+	
+	// affectation du QPen et de la QBrush modifies au QPainter
+	qp -> setBrush(conductor_brush);
+	QPen final_conductor_pen = conductor_pen;
+	
+	// modification du QPen generique pour lui affecter la couleur et le style adequats
+	final_conductor_pen.setColor(final_conductor_color);
+	final_conductor_pen.setStyle(properties_.style);
+	final_conductor_pen.setJoinStyle(Qt::SvgMiterJoin); // meilleur rendu des pointilles
+	
+	// utilisation d'un trait "cosmetique" en-dessous d'un certain zoom
+	if (options && options -> levelOfDetail < 1.0) {
+		final_conductor_pen.setCosmetic(true);
+	}
+	
+	qp -> setPen(final_conductor_pen);
+	
+	// dessin du conducteur
+	qp -> drawPath(path());
+	if (properties_.type == ConductorProperties::Single) {
+		qp -> setBrush(final_conductor_color);
+		properties_.singleLineProperties.draw(
+			qp,
+			middleSegment() -> isHorizontal() ? QET::Horizontal : QET::Vertical,
+			QRectF(middleSegment() -> middle() - QPointF(12.0, 12.0), QSizeF(24.0, 24.0))
+		);
+		if (isSelected()) qp -> setBrush(Qt::NoBrush);
+	}
+	
+	// decalage ideal pour le rendu centre d'un carre / cercle de 2.0 px de cote / diametre
+	qreal pretty_offset = (options -> levelOfDetail == 1 ? 1.0 : 1.0);
+	
+	// dessin des points d'accroche du conducteur si celui-ci est selectionne
+	if (isSelected()) {
+		QList<QPointF> points = segmentsToPoints();
+		QPointF previous_point;
+		for (int i = 1 ; i < (points.size() -1) ; ++ i) {
+			QPointF point = points.at(i);
+				
+			// dessine le carre de saisie du segment
+			if (i > 1) {
+				qp -> fillRect(
+					QRectF(
+						((previous_point.x() + point.x()) / 2.0 ) - pretty_offset * segments_squares_scale_,
+						((previous_point.y() + point.y()) / 2.0 ) - pretty_offset * segments_squares_scale_,
+						2.0 * segments_squares_scale_,
+						2.0 * segments_squares_scale_
+					),
+					square_brush
+				);
+			}
+			previous_point = point;
+		}
+	}
+	
+	// dessine les eventuelles jonctions
+	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);
+		foreach(QPointF point, junctions_list) {
+			qp -> drawEllipse(QRectF(point.x() - pretty_offset, point.y() - pretty_offset, 2.0, 2.0));
+		}
+	}
+	qp -> restore();
+}
+
+/**
+	Methode de preparation a la destruction du conducteur ; le conducteur se detache de ses deux bornes
+*/
+void Conductor::destroy() {
+	destroyed_ = true;
+	terminal1 -> removeConductor(this);
+	terminal2 -> removeConductor(this);
+}
+
+/// @return le Diagram auquel ce conducteur appartient, ou 0 si ce conducteur est independant
+Diagram *Conductor::diagram() const {
+	return(qobject_cast<Diagram *>(scene()));
+}
+
+/**
+	@return le champ de texte associe a ce conducteur
+*/
+ConductorTextItem *Conductor::textItem() const {
+	return(text_item);
+}
+
+/**
+	Methode de validation d'element XML
+	@param e Un element XML sense represente un Conducteur
+	@return true si l'element XML represente bien un Conducteur ; false sinon
+*/
+bool Conductor::valideXml(QDomElement &e){
+	// verifie le nom du tag
+	if (e.tagName() != "conductor") return(false);
+	
+	// verifie la presence des attributs minimaux
+	if (!e.hasAttribute("terminal1")) return(false);
+	if (!e.hasAttribute("terminal2")) return(false);
+	
+	bool conv_ok;
+	// parse l'abscisse
+	e.attribute("terminal1").toInt(&conv_ok);
+	if (!conv_ok) return(false);
+	
+	// parse l'ordonnee
+	e.attribute("terminal2").toInt(&conv_ok);
+	if (!conv_ok) return(false);
+	return(true);
+}
+
+/**
+	Gere les clics sur le conducteur.
+	@param e L'evenement decrivant le clic.
+*/
+void Conductor::mousePressEvent(QGraphicsSceneMouseEvent *e) {
+	// clic gauche
+	if (e -> buttons() & Qt::LeftButton) {
+		// recupere les coordonnees du clic
+		press_point = e -> pos();
+		
+		/*
+			parcourt les segments pour determiner si le clic a eu lieu
+			- sur l'extremite d'un segment
+			- sur le milieu d'un segment
+			- ailleurs
+		*/
+		ConductorSegment *segment = segments;
+		while (segment -> hasNextSegment()) {
+			if (hasClickedOn(press_point, segment -> secondPoint())) {
+				moving_point = true;
+				moving_segment = false;
+				moved_segment = segment;
+				break;
+			} else if (hasClickedOn(press_point, segment -> middle())) {
+				moving_point = false;
+				moving_segment = true;
+				moved_segment = segment;
+				break;
+			}
+			segment = segment -> nextSegment();
+		}
+		if (moving_segment || moving_point) {
+			// en cas de debut de modification de conducteur, on memorise la position du champ de texte
+			before_mov_text_pos_ = text_item -> pos();
+		}
+	}
+	QGraphicsPathItem::mousePressEvent(e);
+	if (e -> modifiers() & Qt::ControlModifier) {
+		setSelected(!isSelected());
+	}
+}
+
+/**
+	Gere les deplacements de souris sur le conducteur.
+	@param e L'evenement decrivant le deplacement de souris.
+*/
+void Conductor::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
+	// clic gauche
+	if (e -> buttons() & Qt::LeftButton) {
+		// position pointee par la souris
+		qreal mouse_x = e -> pos().x();
+		qreal mouse_y = e -> pos().y();
+		
+		bool snap_conductors_to_grid = e -> modifiers() ^ Qt::ShiftModifier;
+		if (snap_conductors_to_grid) {
+			mouse_x = qRound(mouse_x / (Diagram::xGrid * 1.0)) * Diagram::xGrid;
+			mouse_y = qRound(mouse_y / (Diagram::yGrid * 1.0)) * Diagram::yGrid;
+		}
+		
+		if (moving_point) {
+			// la modification par points revient bientot
+			/*
+			// position precedente du point
+			QPointF p = moved_segment -> secondPoint();
+			qreal p_x = p.x();
+			qreal p_y = p.y();
+			
+			// calcul du deplacement
+			moved_segment -> moveX(mouse_x - p_x());
+			moved_segment -> moveY(mouse_y - p_y());
+			
+			// application du deplacement
+			modified_path = true;
+			updatePoints();
+			segmentsToPath();
+			*/
+		} else if (moving_segment) {
+			// position precedente du point
+			QPointF p = moved_segment -> middle();
+			
+			// calcul du deplacement
+			moved_segment -> moveX(mouse_x - p.x());
+			moved_segment -> moveY(mouse_y - p.y());
+			
+			// application du deplacement
+			modified_path = true;
+			has_to_save_profile = true;
+			segmentsToPath();
+			calculateTextItemPosition();
+		}
+	}
+	QGraphicsPathItem::mouseMoveEvent(e);
+}
+
+/**
+	Gere les relachements de boutons de souris sur le conducteur 
+	@param e L'evenement decrivant le lacher de bouton.
+*/
+void Conductor::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
+	// clic gauche
+	moving_point = false;
+	moving_segment = false;
+	if (has_to_save_profile) {
+		saveProfile();
+		has_to_save_profile = false;
+	}
+	if (!(e -> modifiers() & Qt::ControlModifier)) {
+		QGraphicsPathItem::mouseReleaseEvent(e);
+	}
+	calculateTextItemPosition();
+}
+
+/**
+	Gere l'entree de la souris dans la zone du conducteur
+	@param e Le QGraphicsSceneHoverEvent decrivant l'evenement
+*/
+void Conductor::hoverEnterEvent(QGraphicsSceneHoverEvent *e) {
+	Q_UNUSED(e);
+	segments_squares_scale_ = 2.0;
+	if (isSelected()) {
+		update();
+	}
+}
+
+/**
+	Gere la sortie de la souris de la zone du conducteur
+	@param e Le QGraphicsSceneHoverEvent decrivant l'evenement
+*/
+void Conductor::hoverLeaveEvent(QGraphicsSceneHoverEvent *e) {
+	Q_UNUSED(e);
+	segments_squares_scale_ = 1.0;
+	if (isSelected()) {
+		update();
+	}
+}
+
+/**
+	Gere les mouvements de souris au dessus du conducteur
+	@param e Le QGraphicsSceneHoverEvent decrivant l'evenement
+*/
+void Conductor::hoverMoveEvent(QGraphicsSceneHoverEvent *e) {
+	/*
+	if (isSelected()) {
+		QPointF hover_point = mapFromScene(e -> pos());
+		ConductorSegment *segment = segments;
+		bool cursor_set = false;
+		while (segment -> hasNextSegment()) {
+			if (hasClickedOn(hover_point, segment -> secondPoint())) {
+				setCursor(Qt::CrossCursor);
+				cursor_set = true;
+			} else if (hasClickedOn(hover_point, segment -> middle())) {
+				setCursor(segment -> isVertical() ? Qt::SplitHCursor : Qt::SplitVCursor);
+				cursor_set = true;
+			}
+			segment = segment -> nextSegment();
+		}
+		if (!cursor_set) setCursor(Qt::ArrowCursor);
+	}
+	*/
+	QGraphicsPathItem::hoverMoveEvent(e);
+}
+
+/**
+	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
+		calculateTextItemPosition();
+	} else if (change == QGraphicsItem::ItemVisibleHasChanged) {
+		// permet de positionner correctement le texte du conducteur lors de son ajout a un schema
+		calculateTextItemPosition();
+	}
+	return(QGraphicsPathItem::itemChange(change, value));
+}
+
+/**
+	@return Le rectangle delimitant l'espace de dessin du conducteur
+*/
+QRectF Conductor::boundingRect() const {
+	QRectF retour = QGraphicsPathItem::boundingRect();
+	retour.adjust(-11.0, -11.0, 11.0, 11.0);
+	return(retour);
+}
+
+/**
+	@return La forme / zone "cliquable" du conducteur (epaisseur : 5.0px).
+	@see variableShape()
+*/
+QPainterPath Conductor::shape() const {
+	return(variableShape(5.0));
+}
+
+/**
+	@return la distance en dessous de laquelle on considere qu'un point est a
+	proximite du trajet du conducteur. La valeur est actuellement fixee a
+	60.0px.
+*/
+qreal Conductor::nearDistance() const {
+	return(60.0);
+}
+
+/**
+	@return la zone dans laquelle dont on considere que tous les points sont a
+	proximite du trajet du conducteur.
+	@see nearDistance()
+	@see variableShape()
+*/
+QPainterPath Conductor::nearShape() const {
+	return(variableShape(nearDistance()));
+}
+
+/**
+	@return la forme du conducteur
+	@param thickness la moitie de l'epaisseur voulue pour cette forme
+*/
+QPainterPath Conductor::variableShape(const qreal &thickness) const {
+	qreal my_thickness = qAbs(thickness);
+	
+	QList<QPointF> points = segmentsToPoints();
+	QPainterPath area;
+	QPointF previous_point;
+	QPointF *point1, *point2;
+	foreach(QPointF point, points) {
+		if (!previous_point.isNull()) {
+			if (point.x() == previous_point.x()) {
+				if (point.y() <= previous_point.y()) {
+					point1 = &point;
+					point2 = &previous_point;
+				} else {
+					point1 = &previous_point;
+					point2 = &point;
+				}
+			} else {
+				if (point.x() <= previous_point.x()) {
+					point1 = &point;
+					point2 = &previous_point;
+				} else {
+					point1 = &previous_point;
+					point2 = &point;
+				}
+			}
+			qreal p1_x = point1 -> x();
+			qreal p1_y = point1 -> y();
+			qreal p2_x = point2 -> x();
+			qreal p2_y = point2 -> y();
+			area.setFillRule(Qt::OddEvenFill);
+			area.addRect(p1_x - my_thickness, p1_y - my_thickness, my_thickness * 2.0 + p2_x - p1_x, my_thickness * 2.0  + p2_y - p1_y);
+		}
+		previous_point = point;
+		area.setFillRule(Qt::WindingFill);
+		area.addRect(point.x() - my_thickness, point.y() - my_thickness, my_thickness * 2.0, my_thickness * 2.0 );
+	}
+	return(area);
+}
+
+/**
+	@param point un point, exprime dans les coordonnees du conducteur
+	@return true si le point est a proximite du conducteur, c-a-d a moins de
+	60px du conducteur.
+*/
+bool Conductor::isNearConductor(const QPointF &point) {
+	return(variableShape(60.1).contains(point));
+}
+
+/**
+	Renvoie une valeur donnee apres l'avoir bornee entre deux autres valeurs,
+	en y ajoutant une marge interne.
+	@param tobound valeur a borner
+	@param bound1 borne 1
+	@param bound2 borne 2
+	@param space marge interne ajoutee
+	@return La valeur bornee
+*/
+qreal Conductor::conductor_bound(qreal tobound, qreal bound1, qreal bound2, qreal space) {
+	qDebug() << "will bound" << tobound << "between" << bound1 << "and" << bound2 ;
+	if (bound1 < bound2) {
+		return(qBound(bound1 + space, tobound, bound2 - space));
+	} else {
+		return(qBound(bound2 + space, tobound, bound1 - space));
+	}
+}
+
+/**
+	Renvoie une valeur donnee apres l'avoir bornee avant ou apres une valeur.
+	@param tobound valeur a borner
+	@param bound borne
+	@param positive true pour borner la valeur avant la borne, false sinon
+	@return La valeur bornee
+*/
+qreal Conductor::conductor_bound(qreal tobound, qreal bound, bool positive) {
+	qreal space = 5.0;
+	return(positive ? qMax(tobound, bound + space) : qMin(tobound, bound - space));
+}
+
+/**
+	@param type Type de Segments
+	@return Le nombre de segments composant le conducteur.
+*/
+uint Conductor::segmentsCount(QET::ConductorSegmentType type) const {
+	QList<ConductorSegment *> segments_list = segmentsList();
+	if (type == QET::Both) return(segments_list.count());
+	uint nb_seg = 0;
+	foreach(ConductorSegment *conductor_segment, segments_list) {
+		if (conductor_segment -> type() == type) ++ nb_seg;
+	}
+	return(nb_seg);
+}
+
+/**
+	Genere une liste de points a partir des segments de ce conducteur
+	@return La liste de points representant ce conducteur
+*/
+QList<QPointF> Conductor::segmentsToPoints() const {
+	// liste qui sera retournee
+	QList<QPointF> points_list;
+	
+	// on retourne la liste tout de suite s'il n'y a pas de segments
+	if (segments == NULL) return(points_list);
+	
+	// recupere le premier point
+	points_list << segments -> firstPoint();
+	
+	// parcourt les segments pour recuperer les autres points
+	ConductorSegment *segment = segments;
+	while(segment -> hasNextSegment()) {
+		points_list << segment -> secondPoint();
+		segment = segment -> nextSegment();
+	}
+	
+	// recupere le dernier point
+	points_list << segment -> secondPoint();
+	
+	//retourne la liste
+	return(points_list);
+}
+
+/**
+	Regenere les segments de ce conducteur a partir de la liste de points passee en parametre
+	@param points_list Liste de points a utiliser pour generer les segments
+*/
+void Conductor::pointsToSegments(QList<QPointF> points_list) {
+	// supprime les segments actuels
+	deleteSegments();
+	
+	// cree les segments a partir de la liste de points
+	ConductorSegment *last_segment = NULL;
+	for (int i = 0 ; i < points_list.size() - 1 ; ++ i) {
+		last_segment = new ConductorSegment(points_list.at(i), points_list.at(i + 1), last_segment);
+		if (!i) segments = last_segment;
+	}
+}
+
+/**
+	Permet de savoir si un point est tres proche d'un autre. Cela sert surtout
+	pour determiner si un clic a ete effectue pres d'un point donne.
+	@param press_point Point effectivement clique
+	@param point point cliquable
+	@return true si l'on peut considerer que le point a ete clique, false sinon
+*/
+bool Conductor::hasClickedOn(QPointF press_point, QPointF point) const {
+	return (
+		press_point.x() >= point.x() - 5.0 &&\
+		press_point.x() <  point.x() + 5.0 &&\
+		press_point.y() >= point.y() - 5.0 &&\
+		press_point.y() <  point.y() + 5.0
+	);
+}
+
+/**
+	Charge les caracteristiques du conducteur depuis un element XML.
+	@param e Un element XML
+	@return true si le chargement a reussi, false sinon
+*/
+bool Conductor::fromXml(QDomElement &e) {
+	// recupere la "configuration" du conducteur
+	properties_.fromXml(e);
+	readProperties();
+	qreal user_pos_x, user_pos_y;
+	if (
+		QET::attributeIsAReal(e, "userx", &user_pos_x) &&
+		QET::attributeIsAReal(e, "usery", &user_pos_y)
+	) {
+		text_item -> forceMovedByUser(true);
+		text_item -> setPos(user_pos_x, user_pos_y);
+	}
+	if (e.hasAttribute("rotation")) {
+		text_item -> setRotationAngle(e.attribute("rotation").toDouble());
+		text_item -> forceRotateByUser(true);
+	}
+	
+	// parcourt les elements XML "segment" et en extrait deux listes de longueurs
+	// les segments non valides sont ignores
+	QList<qreal> segments_x, segments_y;
+	for (QDomNode node = e.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
+		// on s'interesse aux elements XML "segment"
+		QDomElement current_segment = node.toElement();
+		if (current_segment.isNull() || current_segment.tagName() != "segment") continue;
+		
+		// le segment doit avoir une longueur
+		if (!current_segment.hasAttribute("length")) continue;
+		
+		// cette longueur doit etre un reel
+		bool ok;
+		qreal segment_length = current_segment.attribute("length").toDouble(&ok);
+		if (!ok) continue;
+		
+		if (current_segment.attribute("orientation") == "horizontal") {
+			segments_x << segment_length;
+			segments_y << 0.0;
+		} else {
+			segments_x << 0.0;
+			segments_y << segment_length;
+		}
+	}
+	
+	// s'il n'y a pas de segments, on renvoie true
+	if (!segments_x.size()) return(true);
+	// les longueurs recueillies doivent etre coherentes avec les positions des bornes
+	qreal width = 0.0, height = 0.0;
+	foreach (qreal t, segments_x) width  += t;
+	foreach (qreal t, segments_y) height += t;
+	QPointF t1 = terminal1 -> dockConductor();
+	QPointF t2 = terminal2 -> dockConductor();
+	qreal expected_width  = t2.x() - t1.x();
+	qreal expected_height = t2.y() - t1.y();
+	
+	// on considere que le trajet est incoherent a partir d'une unite de difference avec l'espacement entre les bornes
+	if (
+		qAbs(expected_width  - width)  > 1.0 ||
+		qAbs(expected_height - height) > 1.0
+	) {
+		qDebug() << "Conductor::fromXml : les segments du conducteur ne semblent pas coherents - utilisation d'un trajet automatique";
+		return(false);
+	}
+	
+	/* on recree les segments a partir des donnes XML */
+	// cree la liste de points
+	QList<QPointF> points_list;
+	points_list << t1;
+	for (int i = 0 ; i < segments_x.size() ; ++ i) {
+		points_list << QPointF(
+			points_list.last().x() + segments_x.at(i),
+			points_list.last().y() + segments_y.at(i)
+		);
+	}
+	
+	pointsToSegments(points_list);
+	
+	// initialise divers parametres lies a la modification des conducteurs
+	modified_path = true;
+	saveProfile(false);
+	
+	segmentsToPath();
+	return(true);
+}
+
+/**
+	Exporte les caracteristiques du conducteur sous forme d'une element XML.
+	@param d Le document XML a utiliser pour creer l'element XML
+	@param table_adr_id Hash stockant les correspondances entre les ids des
+	bornes dans le document XML et leur adresse en memoire
+	@return Un element XML representant le conducteur
+*/
+QDomElement Conductor::toXml(QDomDocument &d, QHash<Terminal *, int> &table_adr_id) const {
+	QDomElement e = d.createElement("conductor");
+	e.setAttribute("terminal1", table_adr_id.value(terminal1));
+	e.setAttribute("terminal2", table_adr_id.value(terminal2));
+	
+	// on n'exporte les segments du conducteur que si ceux-ci ont
+	// ete modifies par l'utilisateur
+	if (modified_path) {
+		// parcours et export des segments
+		QDomElement current_segment;
+		foreach(ConductorSegment *segment, segmentsList()) {
+			current_segment = d.createElement("segment");
+			current_segment.setAttribute("orientation", segment -> isHorizontal() ? "horizontal" : "vertical");
+			current_segment.setAttribute("length", QString("%1").arg(segment -> length()));
+			e.appendChild(current_segment);
+		}
+	}
+	
+	// exporte la "configuration" du conducteur
+	properties_.toXml(e);
+	if (text_item -> wasRotateByUser()) {
+		e.setAttribute("rotation", QString("%1").arg(text_item -> rotationAngle()));
+	}
+	if (text_item -> wasMovedByUser()) {
+		e.setAttribute("userx", QString("%1").arg(text_item -> pos().x()));
+		e.setAttribute("usery", QString("%1").arg(text_item -> pos().y()));
+	}
+	return(e);
+}
+
+/// @return les segments de ce conducteur
+const QList<ConductorSegment *> Conductor::segmentsList() const {
+	if (segments == NULL) return(QList<ConductorSegment *>());
+	
+	QList<ConductorSegment *> segments_vector;
+	ConductorSegment *segment = segments;
+	
+	while (segment -> hasNextSegment()) {
+		segments_vector << segment;
+		segment = segment -> nextSegment();
+	}
+	segments_vector << segment;
+	return(segments_vector);
+}
+
+/**
+	@return La longueur totale du conducteur
+*/
+qreal Conductor::length() {
+	qreal length = 0.0;
+	
+	ConductorSegment *s = segments;
+	while (s -> hasNextSegment()) {
+		length += qAbs(s -> length());
+		s = s -> nextSegment();
+	}
+	
+	return(length);
+}
+
+/**
+	@return Le segment qui contient le point au milieu du conducteur
+*/
+ConductorSegment *Conductor::middleSegment() {
+	if (segments == NULL) return(NULL);
+	
+	qreal half_length = length() / 2.0;
+	
+	ConductorSegment *s = segments;
+	qreal l = 0;
+	
+	while (s -> hasNextSegment()) {
+		l += qAbs(s -> length());
+		if (l >= half_length) break;
+		s = s -> nextSegment();
+	}
+	// s est le segment qui contient le point au milieu du conducteur
+	return(s);
+}
+
+/**
+	Positionne le texte du conducteur au milieu du segment qui contient le
+	point au milieu du conducteur
+	@see middleSegment()
+*/
+void Conductor::calculateTextItemPosition() {
+	if (!text_item) return;
+	
+	//position
+	if (text_item -> wasMovedByUser()) {
+		// le champ de texte a ete deplace par l'utilisateur :
+		// on verifie qu'il est encore a proximite du conducteur
+		QPointF text_item_pos = text_item -> pos();
+		QPainterPath near_shape = nearShape();
+		if (!near_shape.contains(text_item_pos)) {
+			text_item -> setPos(movePointIntoPolygon(text_item_pos, near_shape));
+		}
+	} else {
+		// positionnement automatique basique
+		text_item -> setPos(middleSegment() -> middle());
+		//rotation
+		if (!text_item -> wasRotateByUser()) {
+			middleSegment() -> isVertical()? text_item -> setRotationAngle(properties_.verti_rotate_text):
+											 text_item -> setRotationAngle(properties_.horiz_rotate_text);
+		}
+	}
+}
+
+/**
+	Sauvegarde le profil courant du conducteur pour l'utiliser ulterieurement
+	dans priv_modifieConductor.
+*/
+void Conductor::saveProfile(bool undo) {
+	Qt::Corner current_path_type = currentPathType();
+	ConductorProfile old_profile(conductor_profiles[current_path_type]);
+	conductor_profiles[current_path_type].fromConductor(this);
+	Diagram *dia = diagram();
+	if (undo && dia) {
+		ChangeConductorCommand *undo_object = new ChangeConductorCommand(
+			this,
+			old_profile,
+			conductor_profiles[current_path_type],
+			current_path_type
+		);
+		undo_object -> setConductorTextItemMove(before_mov_text_pos_, text_item -> pos());
+		dia -> undoStack().push(undo_object);
+	}
+}
+
+/**
+	@param value1 Premiere valeur
+	@param value2 Deuxieme valeur
+	@return 1 si les deux valeurs sont de meme signe, -1 sinon
+*/
+int Conductor::getCoeff(const qreal &value1, const qreal &value2) {
+	return(getSign(value1) * getSign(value2));
+}
+
+/**
+	@param value valeur
+	@return 1 si valeur est negatif, 1 s'il est positif ou nul
+*/
+int Conductor::getSign(const qreal &value) {
+	return(value < 0 ? -1 : 1);
+}
+
+/**
+	Applique un nouveau profil a ce conducteur
+	@param cp Profil a appliquer a ce conducteur
+	@param path_type Type de trajet pour lequel ce profil convient
+*/
+void Conductor::setProfile(const ConductorProfile &cp, Qt::Corner path_type) {
+	conductor_profiles[path_type] = cp;
+	// si le type de trajet correspond a l'actuel
+	if (currentPathType() == path_type) {
+		if (conductor_profiles[path_type].isNull()) {
+			generateConductorPath(terminal1 -> dockConductor(), terminal1 -> orientation(), terminal2 -> dockConductor(), terminal2 -> orientation());
+			modified_path = false;
+		} else {
+			updateConductorPath(terminal1 -> dockConductor(), terminal1 -> orientation(), terminal2 -> dockConductor(), terminal2 -> orientation());
+			modified_path = true;
+		}
+		if (type() == ConductorProperties::Multi) {
+			calculateTextItemPosition();
+		}
+	}
+}
+
+/// @return le profil de ce conducteur
+ConductorProfile Conductor::profile(Qt::Corner path_type) const {
+	return(conductor_profiles[path_type]);
+}
+
+/// @return le texte du conducteur
+QString Conductor::text() const {
+	return(text_item -> toPlainText());
+}
+
+/**
+	@param t Nouveau texte du conducteur
+*/
+void Conductor::setText(const QString &t) {
+	text_item -> setPlainText(t);
+}
+
+/// @param p les proprietes de ce conducteur
+void Conductor::setProperties(const ConductorProperties &p) {
+	properties_ = p;
+	readProperties();
+}
+
+/// @return les proprietes de ce conducteur
+ConductorProperties Conductor::properties() const {
+	return(properties_);
+}
+
+/**
+	Relit les proprietes et les applique
+*/
+void Conductor::readProperties() {
+	// la couleur n'est vraiment applicable que lors du rendu du conducteur
+	setText(properties_.text);
+	calculateTextItemPosition();
+	text_item -> setVisible(properties_.type == ConductorProperties::Multi);
+}
+
+/**
+	S'assure que le texte du conducteur est a une position raisonnable
+	Cette methode ne fait rien si ce conducteur n'affiche pas son champ de
+	texte.
+*/
+void Conductor::adjustTextItemPosition() {
+	calculateTextItemPosition();
+}
+
+/**
+	@return true si le conducteur est mis en evidence
+*/
+Conductor::Highlight Conductor::highlight() const {
+	return(must_highlight_);
+}
+
+/**
+	@param hl true pour mettre le conducteur en evidence, false sinon
+*/
+void Conductor::setHighlighted(Conductor::Highlight hl) {
+	must_highlight_ = hl;
+	update();
+}
+
+/**
+ * @brief Conductor::autoText
+ *lance l'autoNumerotation sur ce conducteur
+ */
+void Conductor::autoText() {
+	ConductorAutoNumerotation can(this);
+	can.numerate();
+}
+
+/**
+	Met a jour les proprietes du conducteur apres modification du champ de texte affiche
+*/
+void Conductor::displayedTextChanged() {
+	// verifie que le texte a reellement change
+	if (text_item -> toPlainText() == properties_.text) return;
+	
+	if (Diagram *my_diagram = diagram()) {
+		int qmbreturn=0;
+		//if conductor isn't alone at this potential
+		//ask user to apply text on every conductors of this potential
+		if (relatedPotentialConductors().size() >= 1){
+			qmbreturn = QMessageBox::question(diagramEditor(), tr("Textes de conducteurs"),
+											  tr("Voulez-vous appliquer le nouveau texte \n"
+												 "\340 l'ensemble des conducteurs de ce potentiel ?"),
+											  QMessageBox::No| QMessageBox::Yes, QMessageBox::Yes);
+			if (qmbreturn == QMessageBox::Yes){
+				ConductorAutoNumerotation can(this);
+				can.applyText(text_item -> toPlainText());
+			}
+		}
+		if (qmbreturn == 0 || qmbreturn == QMessageBox::No) {
+			// initialise l'objet UndoCommand correspondant
+			ConductorProperties new_properties(properties_);
+			new_properties.text = text_item -> toPlainText();
+
+			ChangeConductorPropertiesCommand *ccpc = new ChangeConductorPropertiesCommand(this);
+			ccpc -> setOldSettings(properties_);
+			ccpc -> setNewSettings(new_properties);
+			my_diagram -> undoStack().push(ccpc);
+		}
+	}
+}
+
+/**
+	@return les conducteurs avec lesquels ce conducteur partage des bornes
+	communes
+*/
+QSet<Conductor *> Conductor::relatedConductors() const {
+	QList<Conductor *> other_conductors_list = terminal1 -> conductors();
+	other_conductors_list += terminal2 -> conductors();
+	QSet<Conductor *> other_conductors = other_conductors_list.toSet();
+	other_conductors.remove(const_cast<Conductor *>(this));
+	return(other_conductors);
+}
+
+/**
+ * @param t_list terminaux a ne pas inclure dans la recherche
+ * @return les conducteurs avec lesquels ce conducteur partage
+ *  le meme potentiel electrique a l'exception de lui même
+ */
+QSet<Conductor *> Conductor::relatedPotentialConductors(QList <Terminal *> *t_list) {
+	bool declar_t_list = false;
+	if (t_list == 0) {
+		declar_t_list = true;
+		t_list = new QList <Terminal *>;
+	}
+
+	QSet <Conductor *> other_conductors;
+	//renvoie tous les conducteurs du terminal 1
+	if (!t_list -> contains(terminal1)) {
+		t_list -> append(terminal1);
+		QList <Conductor *> other_conductors_list_t1 = terminal1 -> conductors();
+		other_conductors_list_t1.removeAll(this);
+		//recherche les conducteurs connecté au conducteur déjà trouvé
+		foreach (Conductor *c, other_conductors_list_t1) {
+			other_conductors += c -> relatedPotentialConductors(t_list);
+		}
+		other_conductors += other_conductors_list_t1.toSet();
+	}
+	//renvoie tous les conducteurs du terminal 2
+	if (!t_list -> contains(terminal2)) {
+		t_list -> append(terminal2);
+		QList <Conductor *> other_conductors_list_t2 = terminal2 -> conductors();
+		other_conductors_list_t2.removeAll(this);
+		//recherche les conducteurs connecté au conducteur déjà trouvé
+		foreach (Conductor *c, other_conductors_list_t2) {
+			other_conductors += c -> relatedPotentialConductors(t_list);
+		}
+		other_conductors += other_conductors_list_t2.toSet();
+	}
+	other_conductors.remove(const_cast<Conductor *>(this));
+
+	if (declar_t_list) delete t_list;
+	return(other_conductors);
+}
+
+/**
+ * @return l'editeur de schemas parent ou 0
+ */
+QETDiagramEditor* Conductor::diagramEditor() const {
+	QWidget *w = const_cast<QGraphicsView *>(diagram() -> views().at(0));
+	while (w -> parentWidget() && !w -> isWindow()) {
+		w = w -> parentWidget();
+	}
+	return(qobject_cast<QETDiagramEditor *>(w));
+}
+
+/**
+	@param a reel
+	@param b reel
+	@param c reel
+	@return true si a est entre b et c ou est egal a l'un des deux
+*/
+bool isBetween(qreal a, qreal b, qreal c) {
+	if (b <= c) {
+		return(a >= b && a <= c);
+	} else {
+		return(a <= b && a >= c);
+	}
+}
+
+/**
+	@param a point
+	@param b point
+	@param c point
+	@return true si le point a est contenu dans le rectangle delimite par les points b et c
+*/
+bool isContained(const QPointF &a, const QPointF &b, const QPointF &c) {
+	return(
+		isBetween(a.x(), b.x(), c.x()) &&
+		isBetween(a.y(), b.y(), c.y())
+	);
+}
+
+/**
+	@return la liste des positions des jonctions avec d'autres conducteurs
+*/
+QList<QPointF> Conductor::junctions() const {
+	QList<QPointF> junctions_list;
+	
+	// pour qu'il y ait des jonctions, il doit y avoir d'autres conducteurs et des bifurcations
+	QSet<Conductor *> other_conductors = relatedConductors();
+	QList<ConductorBend> bends_list = bends();
+	if (other_conductors.isEmpty() || bends_list.isEmpty()) {
+		return(junctions_list);
+	}
+	
+	QList<QPointF> points = segmentsToPoints();
+	for (int i = 1 ; i < (points.size() -1) ; ++ i) {
+		QPointF point = points.at(i);
+		
+		// determine si le point est une bifurcation ou non
+		bool is_bend = false;
+		Qt::Corner current_bend_type = Qt::TopLeftCorner;
+		foreach(ConductorBend cb, bends_list) {
+			if (cb.first == point) {
+				is_bend = true;
+				current_bend_type = cb.second;
+				break;
+			}
+		}
+		// si le point n'est pas une bifurcation, il ne peut etre une jonction (enfin pas au niveau de ce conducteur)
+		if (!is_bend) continue;
+		
+		bool is_junction = false;
+		QPointF scene_point = mapToScene(point);
+		foreach(Conductor *c, other_conductors) {
+			// exprime le point dans les coordonnees de l'autre conducteur
+			QPointF conductor_point = c -> mapFromScene(scene_point);
+			// recupere les segments de l'autre conducteur
+			QList<ConductorSegment *> c_segments = c -> segmentsList();
+			if (c_segments.isEmpty()) continue;
+			// parcoure les segments a la recherche d'un point commun
+			for (int j = 0 ; j < c_segments.count() ; ++ j) {
+				ConductorSegment *segment = c_segments[j];
+				// un point commun a ete trouve sur ce segment
+				if (isContained(conductor_point, segment -> firstPoint(), segment -> secondPoint())) {
+					is_junction = true;
+					// ce point commun ne doit pas etre une bifurcation identique a celle-ci
+					QList<ConductorBend> other_conductor_bends = c -> bends();
+					foreach(ConductorBend cb, other_conductor_bends) {
+						if (cb.first == conductor_point && cb.second == current_bend_type) {
+							is_junction = false;
+						}
+					}
+				}
+				if (is_junction) junctions_list << point;
+			}
+		}
+	}
+	return(junctions_list);
+}
+
+/**
+	@return la liste des bifurcations de ce conducteur ; ConductorBend est un
+	typedef pour une QPair\<QPointF, Qt::Corner\>. Le point indique la position
+	(en coordonnees locales) de la bifurcation tandis que le Corner indique le
+	type de bifurcation.
+*/
+QList<ConductorBend> Conductor::bends() const {
+	QList<ConductorBend> points;
+	if (!segments) return(points);
+	
+	// recupere la liste des segments de taille non nulle
+	QList<ConductorSegment *> visible_segments;
+	ConductorSegment *segment = segments;
+	while (segment -> hasNextSegment()) {
+		if (!segment -> isPoint()) visible_segments << segment;
+		segment = segment -> nextSegment();
+	}
+	if (!segment  -> isPoint()) visible_segments << segment;
+	
+	ConductorSegment *next_segment;
+	for (int i = 0 ; i < visible_segments.count() -1 ; ++ i) {
+		segment = visible_segments[i];
+		next_segment = visible_segments[i + 1];
+		if (!segment -> isPoint() && !next_segment -> isPoint()) {
+			// si les deux segments ne sont pas dans le meme sens, on a une bifurcation
+			if (next_segment -> type() != segment -> type()) {
+				Qt::Corner bend_type;
+				qreal sl = segment -> length();
+				qreal nsl = next_segment -> length();
+				
+				if (segment -> isHorizontal()) {
+					if (sl < 0 && nsl < 0) {
+						bend_type = Qt::BottomLeftCorner;
+					} else if (sl < 0 && nsl > 0) {
+						bend_type = Qt::TopLeftCorner;
+					} else if (sl > 0 && nsl < 0) {
+						bend_type = Qt::BottomRightCorner;
+					} else {
+						bend_type = Qt::TopRightCorner;
+					}
+				} else {
+					if (sl < 0 && nsl < 0) {
+						bend_type = Qt::TopRightCorner;
+					} else if (sl < 0 && nsl > 0) {
+						bend_type = Qt::TopLeftCorner;
+					} else if (sl > 0 && nsl < 0) {
+						bend_type = Qt::BottomRightCorner;
+					} else {
+						bend_type = Qt::BottomLeftCorner;
+					}
+				}
+				points << qMakePair(segment -> secondPoint(), bend_type);
+			}
+		}
+	}
+	return(points);
+}
+
+/**
+	@param p Point, en coordonnees locales
+	@return true si le point p appartient au trajet du conducteur
+*/
+bool Conductor::containsPoint(const QPointF &p) const {
+	if (!segments) return(false);
+	ConductorSegment *segment = segments;
+	while (segment -> hasNextSegment()) {
+		QRectF rect(segment -> firstPoint(), segment -> secondPoint());
+		if (rect.contains(p)) return(true);
+		segment = segment -> nextSegment();
+	}
+	return(false);
+}
+
+/**
+	@param start Point de depart
+	@param end Point d'arrivee
+	@return le coin vers lequel se dirige le trajet de start vers end
+*/
+Qt::Corner Conductor::movementType(const QPointF &start, const QPointF &end) {
+	Qt::Corner result = Qt::BottomRightCorner;
+	if (start.x() <= end.x()) {
+		result = start.y() <= end.y() ? Qt::BottomRightCorner : Qt::TopRightCorner;
+	} else {
+		result = start.y() <= end.y() ? Qt::BottomLeftCorner : Qt::TopLeftCorner;
+	}
+	return(result);
+}
+
+/// @return le type de trajet actuel de ce conducteur
+Qt::Corner Conductor::currentPathType() const {
+	return(movementType(terminal1 -> dockConductor(), terminal2 -> dockConductor()));
+}
+
+/// @return les profils de ce conducteur
+ConductorProfilesGroup Conductor::profiles() const {
+	return(conductor_profiles);
+}
+
+/**
+	@param cpg Les nouveaux profils de ce conducteur
+*/
+void Conductor::setProfiles(const ConductorProfilesGroup &cpg) {
+	conductor_profiles = cpg;
+	if (conductor_profiles[currentPathType()].isNull()) {
+		generateConductorPath(terminal1 -> dockConductor(), terminal1 -> orientation(), terminal2 -> dockConductor(), terminal2 -> orientation());
+		modified_path = false;
+	} else {
+		updateConductorPath(terminal1 -> dockConductor(), terminal1 -> orientation(), terminal2 -> dockConductor(), terminal2 -> orientation());
+		modified_path = true;
+	}
+	if (type() == ConductorProperties::Multi) {
+		calculateTextItemPosition();
+	}
+}
+
+/// Supprime les segments
+void Conductor::deleteSegments() {
+	if (segments != NULL) {
+		while (segments -> hasNextSegment()) delete segments -> nextSegment();
+		delete segments;
+		segments = NULL;
+	}
+}
+
+/**
+	@param point Un point situe a l'exterieur du polygone
+	@param polygon Le polygone dans lequel on veut rapatrier le point
+	@return la position du point, une fois ramene dans le polygone, ou plus
+	exactement sur le bord du polygone
+*/
+QPointF Conductor::movePointIntoPolygon(const QPointF &point, const QPainterPath &polygon) {
+	// decompose le polygone en lignes et points
+	QList<QPolygonF> polygons = polygon.simplified().toSubpathPolygons();
+	QList<QLineF> lines;
+	QList<QPointF> points;
+	foreach(QPolygonF polygon, polygons) {
+		if (polygon.count() <= 1) continue;
+		
+		// on recense les lignes et les points
+		for (int i = 1 ; i < polygon.count() ; ++ i) {
+			lines << QLineF(polygon.at(i - 1), polygon.at(i));
+			points << polygon.at(i -1);
+		}
+	}
+	
+	// on fait des projetes orthogonaux du point sur les differents segments du
+	// polygone, en les triant par longueur croissante
+	QMap<qreal, QPointF> intersections;
+	foreach (QLineF line, lines) {
+		QPointF intersection_point;
+		if (QET::orthogonalProjection(point, line, &intersection_point)) {
+			intersections.insert(QLineF(intersection_point, point).length(), intersection_point);
+		}
+	}
+	if (intersections.count()) {
+		// on determine la plus courte longueur pour un projete orthogonal
+		QPointF the_point = intersections[intersections.keys().first()];
+		return(the_point);
+	} else {
+			// determine le coin du polygone le plus proche du point exterieur
+			qreal minimum_length = -1;
+			int point_index = -1;
+			for (int i = 0 ; i < points.count() ; ++ i) {
+				qreal length = qAbs(QLineF(points.at(i), point).length());
+				if (minimum_length < 0 || length < minimum_length) {
+					minimum_length = length;
+					point_index    = i;
+				}
+			}
+			// on connait desormais le coin le plus proche du texte
+		
+		// aucun projete orthogonal n'a donne quoi que ce soit, on met le texte sur un des coins du polygone
+		return(points.at(point_index));
+	}
+}

Added: branches/devel/sources/qetgraphicsitem/conductor.h
===================================================================
--- branches/devel/sources/qetgraphicsitem/conductor.h	                        (rev 0)
+++ branches/devel/sources/qetgraphicsitem/conductor.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -0,0 +1,170 @@
+/*
+	Copyright 2006-2013 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 CONDUCTOR_H
+#define CONDUCTOR_H
+#include <QtGui>
+#include "terminal.h"
+#include "conductorprofile.h"
+#include "conductorproperties.h"
+#include "qetdiagrameditor.h"
+class ConductorSegment;
+class ConductorTextItem;
+class Element;
+typedef QPair<QPointF, Qt::Corner> ConductorBend;
+typedef QHash<Qt::Corner, ConductorProfile> ConductorProfilesGroup;
+/**
+	This class represents a conductor, i.e. a wire between two element
+	terminals.
+*/
+class Conductor : public QObject, public QGraphicsPathItem {
+	
+	Q_OBJECT
+	
+	// constructors, destructor
+	public:
+	Conductor(Terminal *, Terminal *, Diagram * = 0);
+	virtual ~Conductor();
+	
+	private:
+	Conductor(const Conductor &);
+	
+	// attributes
+	public:
+	enum { Type = UserType + 1001 };
+	enum Highlight { None, Normal, Alert };
+	
+	/// First terminal the wire is attached to
+	Terminal *terminal1;
+	/// Second terminal the wire is attached to
+	Terminal *terminal2;
+	
+	// methods
+	public:
+	/**
+		Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
+		Conductor.
+		@return the QGraphicsItem type
+	*/
+	virtual int type() const { return Type; }
+	void destroy();
+	/// @return true if this conductor is destroyed
+	bool isDestroyed() const { return(destroyed_); }
+	Diagram *diagram() const;
+	ConductorTextItem *textItem() const;
+	void updatePath(const QRectF & = QRectF());
+	void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+	QRectF boundingRect() const;
+	virtual QPainterPath shape() const;
+	virtual qreal nearDistance() const;
+	virtual QPainterPath nearShape() const;
+	virtual QPainterPath variableShape(const qreal &) const;
+	virtual bool isNearConductor(const QPointF &);
+	qreal length();
+	ConductorSegment *middleSegment();
+	bool containsPoint(const QPointF &) const;
+	QString text() const;
+	void setText(const QString &);
+	static bool valideXml(QDomElement &);
+	bool fromXml(QDomElement &);
+	QDomElement toXml(QDomDocument &, QHash<Terminal *, int> &) const;
+	const QList<ConductorSegment *> segmentsList() const;
+	void setProperties(const ConductorProperties &);
+	ConductorProperties properties() const;
+	void setProfile(const ConductorProfile &, Qt::Corner);
+	ConductorProfile profile(Qt::Corner) const;
+	void setProfiles(const ConductorProfilesGroup &);
+	ConductorProfilesGroup profiles() const;
+	void readProperties();
+	void adjustTextItemPosition();
+	virtual Highlight highlight() const;
+	virtual void setHighlighted(Highlight);
+	void autoText();
+	QSet<Conductor *> relatedPotentialConductors(QList <Terminal *> *t_list=0);
+	QETDiagramEditor* diagramEditor() const;
+	
+	public slots:
+	void displayedTextChanged();
+	
+	protected:
+	virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
+	virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
+	virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
+	virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *);
+	virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *);
+	virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *);
+	virtual QVariant itemChange(GraphicsItemChange, const QVariant &);
+	
+	private:
+	/// Functional properties
+	ConductorProperties properties_;
+	/// Whether this conductor is still valid
+	bool destroyed_;
+	/// Text input for non simple, non-singleline conductors
+	ConductorTextItem *text_item;
+	/// Segments composing the conductor
+	ConductorSegment *segments;
+	/// Attributs related to mouse interaction
+	QPointF press_point;
+	bool moving_point;
+	bool moving_segment;
+	int moved_point;
+	qreal previous_z_value;
+	ConductorSegment *moved_segment;
+	QPointF before_mov_text_pos_;
+	/// Whether the conductor was manually modified by users
+	bool modified_path;
+	/// 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
+	ConductorProfilesGroup conductor_profiles;
+	/// QPen et QBrush objects used to draw conductors
+	static QPen conductor_pen;
+	static QBrush conductor_brush;
+	static QBrush square_brush;
+	static bool pen_and_brush_initialized;
+	/// Scale factor to render square used to move segments
+	qreal segments_squares_scale_;
+	/// Define whether and how the conductor should be highlighted
+	Highlight must_highlight_;
+	
+	private:
+	void segmentsToPath();
+	void saveProfile(bool = true);
+	void generateConductorPath(const QPointF &, QET::Orientation, const QPointF &, QET::Orientation);
+	void updateConductorPath(const QPointF &, QET::Orientation, const QPointF &, QET::Orientation);
+	uint segmentsCount(QET::ConductorSegmentType = QET::Both) const;
+	QList<QPointF> segmentsToPoints() const;
+	QSet<Conductor *> relatedConductors() const;
+	QList<ConductorBend> bends() const;
+	QList<QPointF> junctions() const;
+	void pointsToSegments(QList<QPointF>);
+	bool hasClickedOn(QPointF, QPointF) const;
+	void calculateTextItemPosition();
+	Qt::Corner currentPathType() const;
+	void deleteSegments();
+	static int getCoeff(const qreal &, const qreal &);
+	static int getSign(const qreal &);
+	QHash<ConductorSegmentProfile *, qreal> shareOffsetBetweenSegments(const qreal &offset, const QList<ConductorSegmentProfile *> &, const qreal & = 0.01) const;
+	static QPointF extendTerminal(const QPointF &, QET::Orientation, qreal = 9.0);
+	static qreal conductor_bound(qreal, qreal, qreal, qreal = 0.0);
+	static qreal conductor_bound(qreal, qreal, bool);
+	static Qt::Corner movementType(const QPointF &, const QPointF &);
+	static QPointF movePointIntoPolygon(const QPointF &, const QPainterPath &);
+};
+#endif

Added: branches/devel/sources/qetgraphicsitem/conductortextitem.cpp
===================================================================
--- branches/devel/sources/qetgraphicsitem/conductortextitem.cpp	                        (rev 0)
+++ branches/devel/sources/qetgraphicsitem/conductortextitem.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -0,0 +1,223 @@
+/*
+	Copyright 2006-2013 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 "conductortextitem.h"
+#include "conductor.h"
+#include "diagramcommands.h"
+
+/**
+	Constructeur
+	@param parent_conductor  Conducteur auquel ce texte est rattache
+	@param parent_diagram    Schema auquel ce texte et son conducteur parent sont rattaches
+*/
+ConductorTextItem::ConductorTextItem(Conductor *parent_conductor, Diagram *parent_diagram) :
+	DiagramTextItem(parent_conductor, parent_diagram),
+	parent_conductor_(parent_conductor),
+	moved_by_user_(false),
+	rotate_by_user_(false),
+	first_move_(true)
+{
+	// par defaut, les DiagramTextItem sont Selectable et Movable
+	// cela nous convient, on ne touche pas a ces flags
+}
+
+/**
+	Constructeur
+	@param text Le texte affiche par le champ de texte
+	@param parent_conductor  Conducteur auquel ce texte est rattache
+	@param parent_diagram    Schema auquel ce texte et son conducteur parent sont rattaches
+*/
+ConductorTextItem::ConductorTextItem(const QString &text, Conductor *parent_conductor, Diagram *parent_diagram) :
+	DiagramTextItem(text, parent_conductor, parent_diagram),
+	parent_conductor_(parent_conductor),
+	moved_by_user_(false),
+	rotate_by_user_(false),
+	first_move_(true)
+{
+	// par defaut, les DiagramTextItem sont Selectable et Movable
+	// cela nous convient, on ne touche pas a ces flags
+}
+
+/**
+	Destructeur
+*/
+ConductorTextItem::~ConductorTextItem() {
+}
+
+/**
+	@return le conducteur parent de ce champ de texte, ou 0 si celui-ci n'en a
+	pas
+*/
+Conductor *ConductorTextItem::parentConductor() const {
+	return(parent_conductor_);
+}
+
+/**
+	Permet de lire le texte a mettre dans le champ a partir d'un element XML.
+	Cette methode se base sur la position du champ pour assigner ou non la
+	valeur a ce champ.
+	@param e L'element XML representant le champ de texte
+*/
+void ConductorTextItem::fromXml(const QDomElement &e) {
+	setPlainText(e.attribute("text"));
+	
+	qreal user_pos_x, user_pos_y;
+	if (
+		QET::attributeIsAReal(e, "userx", &user_pos_x) &&
+		QET::attributeIsAReal(e, "usery", &user_pos_y)
+	) {
+		setPos(user_pos_x, user_pos_y);
+	}
+	
+	setRotationAngle(e.attribute("rotation").toDouble());
+}
+
+/**
+	@param document Le document XML a utiliser
+	@return L'element XML representant ce champ de texte
+*/
+QDomElement ConductorTextItem::toXml(QDomDocument &document) const {
+	QDomElement result = document.createElement("input");
+	result.setAttribute("userx", QString("%1").arg(pos().x()));
+	result.setAttribute("usery", QString("%1").arg(pos().y()));
+	result.setAttribute("text", toPlainText());
+	if (rotationAngle()) {
+		result.setAttribute("rotation", QString("%1").arg(rotationAngle()));
+	}
+	return(result);
+}
+
+/**
+	@return true si ce champ de texte a ete explictement deplace par
+	l'utilisateur, false sinon
+*/
+bool ConductorTextItem::wasMovedByUser() const {
+	return(moved_by_user_);
+}
+
+/**
+ * @brief ConductorTextItem::wasRotateByUser
+ * @return true if text was explicit moved by user else false
+ */
+bool ConductorTextItem::wasRotateByUser() const {
+	return(rotate_by_user_);
+}
+
+/**
+	@param moved_by_user true pour que la position du texte soit consideree
+	comme ayant ete definie par l'utilisateur (et donc soit sauvegardee), false
+	pour remettre le texte a sa position originelle
+*/
+void ConductorTextItem::forceMovedByUser(bool moved_by_user) {
+	if (moved_by_user == moved_by_user_) return;
+	
+	moved_by_user_ = moved_by_user;
+	if (!moved_by_user && parent_conductor_) {
+		parent_conductor_ -> adjustTextItemPosition();
+	}
+	
+}
+
+/**
+ * @brief ConductorTextItem::forceRotateByUser
+ * @param rotate_by_user true pour que la rotation du texte soit consideree
+	comme ayant ete definie par l'utilisateur (et donc soit sauvegardee), false
+	pour remettre le texte a sont angle originelle
+ */
+void ConductorTextItem::forceRotateByUser(bool rotate_by_user) {
+	if (rotate_by_user == rotate_by_user_) return;
+
+	rotate_by_user_ = rotate_by_user;
+	if (!rotate_by_user && parent_conductor_) {
+		parent_conductor_ -> adjustTextItemPosition();
+	}
+}
+
+/**
+	Gere les clics de souris lies au champ de texte
+	@param e Objet decrivant l'evenement souris
+*/
+void ConductorTextItem::mousePressEvent(QGraphicsSceneMouseEvent *e) {
+	if ((flags() & QGraphicsItem::ItemIsMovable) && (e -> buttons() & Qt::LeftButton)) {
+		before_mov_pos_ = pos();
+	}
+	first_move_ = true;
+	DiagramTextItem::mousePressEvent(e);
+}
+
+/**
+	Gere les mouvements de souris lies au champ de texte
+	@param e Objet decrivant l'evenement souris
+*/
+void ConductorTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
+	if (textInteractionFlags() & Qt::TextEditable) {
+		QGraphicsTextItem::mouseMoveEvent(e);
+	} else if ((flags() & QGraphicsItem::ItemIsMovable) && (e -> buttons() & Qt::LeftButton)) {
+		if (first_move_) {
+			mouse_to_origin_movement_ = before_mov_pos_ - mapToParent(e -> buttonDownPos(Qt::LeftButton));
+		}
+		
+		QPointF intended_pos = mapToParent(e -> pos()) + mouse_to_origin_movement_;
+		// si ce texte est attache a un conducteur, alors ses mouvements seront
+		// limites a une certaine distance du trace de ce conducteur
+		if (parent_conductor_) {
+			if (parent_conductor_ -> isNearConductor(intended_pos)) {
+				setPos(intended_pos);
+				parent_conductor_ -> setHighlighted(Conductor::Normal);
+			} else {
+				parent_conductor_ -> setHighlighted(Conductor::Alert);
+			}
+		}
+		
+	} else e -> ignore();
+	
+	if (first_move_) {
+		first_move_ = false;
+	}
+}
+
+/**
+	Gere le relachement de souris
+	Cette methode cree un objet d'annulation pour le deplacement
+	@param e Objet decrivant l'evenement souris
+*/
+void ConductorTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
+	if (flags() & QGraphicsItem::ItemIsMovable) {
+		if (Diagram *diagram_ptr = diagram()) {
+			// on cree un objet d'annulation correspondant au deplacement qui s'acheve
+			QPointF applied_movement = pos() - before_mov_pos_;
+			
+			if (!applied_movement.isNull()) {
+				// on cree un objet d'annulation seulement pour ce champ de texte
+				MoveConductorsTextsCommand *undo_object = new MoveConductorsTextsCommand(diagram_ptr);
+				undo_object -> addTextMovement(this, before_mov_pos_, pos(), moved_by_user_);
+				
+				// on active le flag indiquant que ce champ de texte a ete explicitement repositionne par l'utilisateur
+				moved_by_user_ = true;
+				
+				diagram_ptr -> undoStack().push(undo_object);
+			}
+			
+			if (parent_conductor_) {
+				parent_conductor_ -> setHighlighted(Conductor::None);
+			}
+		}
+	}
+	if (!(e -> modifiers() & Qt::ControlModifier)) {
+		QGraphicsTextItem::mouseReleaseEvent(e);
+	}
+}

Added: branches/devel/sources/qetgraphicsitem/conductortextitem.h
===================================================================
--- branches/devel/sources/qetgraphicsitem/conductortextitem.h	                        (rev 0)
+++ branches/devel/sources/qetgraphicsitem/conductortextitem.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -0,0 +1,69 @@
+/*
+	Copyright 2006-2013 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 CONDUCTOR_TEXT_ITEM_H
+#define CONDUCTOR_TEXT_ITEM_H
+#include "diagramtextitem.h"
+class Conductor;
+/**
+	This class represents a text item attached to a parent conductor.
+	It may be moved and edited by users.
+	It may also be rotated to any angle.
+	Its movements are however limited to a particular distance around its
+	parent conductor.
+*/
+class ConductorTextItem : public DiagramTextItem {
+	Q_OBJECT
+	
+	// constructors, destructor
+	public:
+	ConductorTextItem(Conductor * = 0, Diagram * = 0);
+	ConductorTextItem(const QString &, Conductor * = 0, Diagram * = 0);
+	virtual ~ConductorTextItem();
+	private:
+	ConductorTextItem(const ConductorTextItem &);
+	
+	// attributes
+	public:
+	enum { Type = UserType + 1006 };
+	Conductor *parentConductor() const;
+	virtual void fromXml(const QDomElement &);
+	virtual QDomElement toXml(QDomDocument &) const;
+	
+	// methods
+	public:
+	virtual int type() const { return Type; }
+	virtual bool wasMovedByUser() const;
+	virtual bool wasRotateByUser() const;
+	virtual void forceMovedByUser(bool);
+	virtual void forceRotateByUser(bool);
+	
+	protected:
+	virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
+	virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
+	virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
+	
+	// attributes
+	private:
+	Conductor *parent_conductor_;
+	bool moved_by_user_;
+	bool rotate_by_user_;
+	QPointF before_mov_pos_;
+	bool first_move_;
+	QPointF mouse_to_origin_movement_;
+};
+#endif

Added: branches/devel/sources/qetgraphicsitem/customelement.cpp
===================================================================
--- branches/devel/sources/qetgraphicsitem/customelement.cpp	                        (rev 0)
+++ branches/devel/sources/qetgraphicsitem/customelement.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -0,0 +1,806 @@
+/*
+	Copyright 2006-2013 The QElectroTech Team
+	This file is part of QElectroTech.
+	
+	QElectroTech is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 2 of the License, or
+	(at your option) any later version.
+	
+	QElectroTech is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+	
+	You should have received a copy of the GNU General Public License
+	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "customelement.h"
+#include "elementtextitem.h"
+#include "diagram.h"
+#include "qetapp.h"
+#include "partline.h"
+#include "elementdefinition.h"
+#include <iostream>
+
+/**
+	Constructeur de la classe CustomElement. Permet d'instancier un element
+	utilisable comme un element fixe a la difference que l'element perso est
+	construit a partir d'une description au format XML. Celle-ci est recuperee
+	a l'emplacement indique.
+	@param location Emplacement de la definition d'element a utiliser
+	@param qgi Le QGraphicsItem parent de cet element
+	@param s Le Schema affichant cet element
+	@param state Un pointeur facultatif vers un entier. La valeur de cet entier
+	sera changee de maniere a refleter le deroulement de l'instanciation :
+		- 0 : L'instanciation a reussi
+		- 1 : l'emplacement n'a pas permis d'acceder a une definition d'element
+		- 2 : la definition n'etait pas lisible
+		- 3 : la definition n'etait pas valide / exploitable / utilisable
+		- 4 : Le document XML n'est pas un element "definition"
+		- 5 : Les attributs de la definition ne sont pas presents et / ou valides
+		- 6 : La definition est vide
+		- 7 : L'analyse d'un element XML decrivant une partie du dessin de l'element a echoue
+		- 8 : Aucune partie du dessin n'a pu etre chargee
+*/
+CustomElement::CustomElement(const ElementsLocation &location, QGraphicsItem *qgi, Diagram *s, int *state) :
+	FixedElement(qgi, s),
+	elmt_state(-1),
+	location_(location),
+	forbid_antialiasing(false)
+{
+	// recupere la definition de l'element
+	ElementsCollectionItem *element_item = QETApp::collectionItem(location);
+	ElementDefinition *element_definition;
+	if (
+		!element_item ||\
+		!element_item -> isElement() ||\
+		!(element_definition = qobject_cast<ElementDefinition *>(element_item))
+	) {
+		if (state) *state = 1;
+		elmt_state = 1;
+		return;
+	}
+	
+	if (!element_definition -> isReadable()) {
+		if (state) *state = 2;
+		elmt_state = 2;
+		return;
+	}
+	
+	if (element_definition -> isNull()) {
+		if (state) *state = 3;
+		elmt_state = 3;
+		return;
+	}
+	
+	buildFromXml(element_definition -> xml(), &elmt_state);
+	if (state) *state = elmt_state;
+	if (elmt_state) return;
+	
+	if (state) *state = 0;
+	elmt_state = 0;
+}
+
+CustomElement::CustomElement(const QDomElement &xml_def_elmt, QGraphicsItem *qgi, Diagram *s, int *state) : FixedElement(qgi, s) {
+	int elmt_state = -1;
+	buildFromXml(xml_def_elmt, &elmt_state);
+	if (state) *state = elmt_state;
+}
+
+/**
+	Construit l'element personnalise a partir d'un element XML representant sa
+	definition.
+	@param xml_def_elmt
+	@param state Un pointeur facultatif vers un entier. La valeur de cet entier
+	sera changee de maniere a refleter le deroulement de l'instanciation :
+		- 0 : La construction s'est bien passee
+		- 4 : Le document XML n'est pas un element "definition"
+		- 5 : Les attributs de la definition ne sont pas presents et / ou valides
+		- 6 : La definition est vide
+		- 7 : L'analyse d'un element XML decrivant une partie du dessin de l'element a echoue
+		- 8 : Aucune partie du dessin n'a pu etre chargee
+	@return true si le chargement a reussi, false sinon
+*/
+bool CustomElement::buildFromXml(const QDomElement &xml_def_elmt, int *state) {
+	
+	if (xml_def_elmt.tagName() != "definition" || xml_def_elmt.attribute("type") != "element") {
+		if (state) *state = 4;
+		return(false);
+	}
+	
+	// verifie basiquement que la version actuelle est capable de lire ce fichier
+	if (xml_def_elmt.hasAttribute("version")) {
+		bool conv_ok;
+		qreal element_version = xml_def_elmt.attribute("version").toDouble(&conv_ok);
+		if (conv_ok && QET::version.toDouble() < element_version) {
+			std::cerr << qPrintable(
+				QObject::tr("Avertissement : l'\351l\351ment "
+				" a \351t\351 enregistr\351 avec une version"
+				" ult\351rieure de QElectroTech.")
+			) << std::endl;
+		}
+	}
+	
+	// ces attributs doivent etre presents et valides
+	int w, h, hot_x, hot_y;
+	if (
+		!QET::attributeIsAnInteger(xml_def_elmt, QString("width"), &w) ||\
+		!QET::attributeIsAnInteger(xml_def_elmt, QString("height"), &h) ||\
+		!QET::attributeIsAnInteger(xml_def_elmt, QString("hotspot_x"), &hot_x) ||\
+		!QET::attributeIsAnInteger(xml_def_elmt, QString("hotspot_y"), &hot_y) ||\
+		!validOrientationAttribute(xml_def_elmt)
+	) {
+		if (state) *state = 5;
+		return(false);
+	}
+	
+	// on peut d'ores et deja specifier la taille et le hotspot
+	setSize(w, h);
+	setHotspot(QPoint(hot_x, hot_y));
+	setInternalConnections(xml_def_elmt.attribute("ic") == "true");
+	
+	// la definition est supposee avoir des enfants
+	if (xml_def_elmt.firstChild().isNull()) {
+		if (state) *state = 6;
+		return(false);
+	}
+	
+	// initialisation du QPainter (pour dessiner l'element)
+	QPainter qp;
+	qp.begin(&drawing);
+	
+	QPainter low_zoom_qp;
+	low_zoom_qp.begin(&low_zoom_drawing);
+	QPen tmp;
+	tmp.setWidthF(1.0); // ligne vaudou pour prise en compte du setCosmetic - ne pas enlever
+	tmp.setCosmetic(true);
+	low_zoom_qp.setPen(tmp);
+	
+	// extrait les noms de la definition XML
+	names.fromXml(xml_def_elmt);
+	setToolTip(name());
+	
+	// parcours des enfants de la definition : parties du dessin
+	int parsed_elements_count = 0;
+	for (QDomNode node = xml_def_elmt.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
+		QDomElement elmts = node.toElement();
+		if (elmts.isNull()) continue;
+		if (elmts.tagName() == "description") {
+			// gestion de la description graphique de l'element
+			//  = parcours des differentes parties du dessin
+			for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
+				QDomElement qde = n.toElement();
+				if (qde.isNull()) continue;
+				if (parseElement(qde, qp)) {
+					++ parsed_elements_count;
+					QString current_tag = qde.tagName();
+					if (current_tag != "terminal" && current_tag != "input") {
+						forbid_antialiasing = true;
+						parseElement(qde, low_zoom_qp);
+						forbid_antialiasing = false;
+					}
+				} else {
+					if (state) *state = 7;
+					return(false);
+				}
+			}
+		}
+	}
+	
+	// fin du dessin
+	qp.end();
+	low_zoom_qp.end();
+	
+	// il doit y avoir au moins un element charge
+	if (!parsed_elements_count) {
+		if (state) *state = 8;
+		return(false);
+	} else {
+		if (state) *state = 0;
+		return(true);
+	}
+}
+
+/**
+	Destructeur
+*/
+CustomElement::~CustomElement() {
+}
+
+/// @return la liste des bornes de cet element
+QList<Terminal *> CustomElement::terminals() const {
+	return(list_terminals);
+}
+
+/// @return la liste des conducteurs rattaches a cet element
+QList<Conductor *> CustomElement::conductors() const {
+	QList<Conductor *> conductors;
+	foreach(Terminal *t, list_terminals) conductors << t -> conductors();
+	return(conductors);
+}
+
+/// @return la liste des textes de cet element
+QList<ElementTextItem *> CustomElement::texts() const {
+	return(list_texts_);
+}
+
+/**
+	@return Le nombre de bornes que l'element possede
+*/
+int CustomElement::terminalsCount() const {
+	return(list_terminals.size());
+}
+
+/**
+	Dessine le composant sur le Diagram
+	@param qp Le QPainter a utiliser pour dessiner l'element
+	@param options Les options graphiques
+*/
+void CustomElement::paint(QPainter *qp, const QStyleOptionGraphicsItem *options) {
+	if (options && options -> levelOfDetail < 1.0) {
+		low_zoom_drawing.play(qp);
+	} else {
+		drawing.play(qp);
+	}
+}
+
+/**
+	Analyse et prend en compte un element XML decrivant une partie du dessin
+	de l'element perso. Si l'analyse reussit, la partie est ajoutee au dessin.
+	Cette partie peut etre une borne, une ligne, une ellipse, un cercle, un arc
+	de cercle ou un polygone. Cette methode renvoie false si l'analyse
+	d'une de ces formes echoue. Si l'analyse reussit ou dans le cas d'une forme
+	inconnue, cette methode renvoie true. A l'exception des bornes, toutes les
+	formes peuvent avoir un attribut style. @see setPainterStyle
+	@param e L'element XML a analyser
+	@param qp Le QPainter a utiliser pour dessiner l'element perso
+	@return true si l'analyse reussit, false sinon
+*/
+bool CustomElement::parseElement(QDomElement &e, QPainter &qp) {
+	if (e.tagName() == "terminal") return(parseTerminal(e));
+	else if (e.tagName() == "line") return(parseLine(e, qp));
+	else if (e.tagName() == "rect") return(parseRect(e, qp));
+	else if (e.tagName() == "ellipse") return(parseEllipse(e, qp));
+	else if (e.tagName() == "circle") return(parseCircle(e, qp));
+	else if (e.tagName() == "arc") return(parseArc(e, qp));
+	else if (e.tagName() == "polygon") return(parsePolygon(e, qp));
+	else if (e.tagName() == "text") return(parseText(e, qp));
+	else if (e.tagName() == "input") return(parseInput(e));
+	else return(true);	// on n'est pas chiant, on ignore l'element inconnu
+}
+
+/**
+	Analyse un element XML suppose representer une ligne. Si l'analyse
+	reussit, la ligne est ajoutee au dessin.
+	La ligne est definie par les attributs suivants :
+		- x1, y1 : reels, coordonnees d'une extremite de la ligne
+		- x2, y2 : reels, coordonnees de l'autre extremite de la ligne
+		
+	@param e L'element XML a analyser
+	@param qp Le QPainter a utiliser pour dessiner l'element perso
+	@return true si l'analyse reussit, false sinon
+*/
+bool CustomElement::parseLine(QDomElement &e, QPainter &qp) {
+	// verifie la presence et la validite des attributs obligatoires
+	qreal x1, y1, x2, y2;
+	if (!QET::attributeIsAReal(e, QString("x1"), &x1)) return(false);
+	if (!QET::attributeIsAReal(e, QString("y1"), &y1)) return(false);
+	if (!QET::attributeIsAReal(e, QString("x2"), &x2)) return(false);
+	if (!QET::attributeIsAReal(e, QString("y2"), &y2)) return(false);
+	
+	QET::EndType first_end = QET::endTypeFromString(e.attribute("end1"));
+	QET::EndType second_end = QET::endTypeFromString(e.attribute("end2"));
+	qreal length1, length2;
+	if (!QET::attributeIsAReal(e, QString("length1"), &length1)) length1 = 1.5;
+	if (!QET::attributeIsAReal(e, QString("length2"), &length2)) length2 = 1.5;
+	
+	qp.save();
+	setPainterStyle(e, qp);
+	QPen t = qp.pen();
+	t.setJoinStyle(Qt::MiterJoin);
+	qp.setPen(t);
+	
+	QLineF line(x1, y1, x2, y2);
+	QPointF point1(line.p1());
+	QPointF point2(line.p2());
+	
+	qreal line_length(line.length());
+	qreal pen_width = qp.pen().widthF();
+	
+	// determine s'il faut dessiner les extremites
+	bool draw_1st_end, draw_2nd_end;
+	qreal reduced_line_length = line_length - (length1 * PartLine::requiredLengthForEndType(first_end));
+	draw_1st_end = first_end && reduced_line_length >= 0;
+	if (draw_1st_end) {
+		reduced_line_length -= (length2 * PartLine::requiredLengthForEndType(second_end));
+	} else {
+		reduced_line_length = line_length - (length2 * PartLine::requiredLengthForEndType(second_end));
+	}
+	draw_2nd_end = second_end && reduced_line_length >= 0;
+	
+	// dessine la premiere extremite
+	QPointF start_point, stop_point;
+	if (draw_1st_end) {
+		QList<QPointF> four_points1(PartLine::fourEndPoints(point1, point2, length1));
+		if (first_end == QET::Circle) {
+			qp.drawEllipse(QRectF(four_points1[0] - QPointF(length1, length1), QSizeF(length1 * 2.0, length1 * 2.0)));
+			start_point = four_points1[1];
+		} else if (first_end == QET::Diamond) {
+			qp.drawPolygon(QPolygonF() << four_points1[1] << four_points1[2] << point1 << four_points1[3]);
+			start_point = four_points1[1];
+		} else if (first_end == QET::Simple) {
+			qp.drawPolyline(QPolygonF() << four_points1[3] << point1 << four_points1[2]);
+			start_point = point1;
+			
+		} else if (first_end == QET::Triangle) {
+			qp.drawPolygon(QPolygonF() << four_points1[0] << four_points1[2] << point1 << four_points1[3]);
+			start_point = four_points1[0];
+		}
+		
+		// ajuste le depart selon l'epaisseur du trait
+		if (pen_width && (first_end == QET::Simple || first_end == QET::Circle)) {
+			start_point = QLineF(start_point, point2).pointAt(pen_width / 2.0 / line_length);
+		}
+	} else {
+		start_point = point1;
+	}
+	
+	// dessine la seconde extremite
+	if (draw_2nd_end) {
+		QList<QPointF> four_points2(PartLine::fourEndPoints(point2, point1, length2));
+		if (second_end == QET::Circle) {
+			qp.drawEllipse(QRectF(four_points2[0] - QPointF(length2, length2), QSizeF(length2 * 2.0, length2 * 2.0)));
+			stop_point = four_points2[1];
+		} else if (second_end == QET::Diamond) {
+			qp.drawPolygon(QPolygonF() << four_points2[2] << point2 << four_points2[3] << four_points2[1]);
+			stop_point = four_points2[1];
+		} else if (second_end == QET::Simple) {
+			qp.drawPolyline(QPolygonF() << four_points2[3] << point2 << four_points2[2]);
+			stop_point = point2;
+		} else if (second_end == QET::Triangle) {
+			qp.drawPolygon(QPolygonF() << four_points2[0] << four_points2[2] << point2 << four_points2[3] << four_points2[0]);
+			stop_point = four_points2[0];
+		}
+		
+		// ajuste l'arrivee selon l'epaisseur du trait
+		if (pen_width && (second_end == QET::Simple || second_end == QET::Circle)) {
+			stop_point = QLineF(point1, stop_point).pointAt((line_length - (pen_width / 2.0)) / line_length);
+		}
+	} else {
+		stop_point = point2;
+	}
+	
+	qp.drawLine(start_point, stop_point);
+	
+	qp.restore();
+	return(true);
+}
+
+/**
+	Analyse un element XML suppose representer un rectangle. Si l'analyse
+	reussit, le rectangle est ajoute au dessin.
+	Le rectangle est defini par les attributs suivants :
+		- x : abscisse du coin superieur gauche du rectangle
+		- y : ordonnee du coin superieur gauche du rectangle
+		- width : largeur du rectangle
+		- height : hauteur du rectangle
+		
+	@param e L'element XML a analyser
+	@param qp Le QPainter a utiliser pour dessiner l'element perso
+	@return true si l'analyse reussit, false sinon
+*/
+bool CustomElement::parseRect(QDomElement &e, QPainter &qp) {
+	// verifie la presence des attributs obligatoires
+	qreal rect_x, rect_y, rect_w, rect_h;
+	if (!QET::attributeIsAReal(e, QString("x"),       &rect_x))  return(false);
+	if (!QET::attributeIsAReal(e, QString("y"),       &rect_y))  return(false);
+	if (!QET::attributeIsAReal(e, QString("width"),   &rect_w))  return(false);
+	if (!QET::attributeIsAReal(e, QString("height"),  &rect_h))  return(false);
+	qp.save();
+	setPainterStyle(e, qp);
+	
+	// force le type de jointures pour les rectangles
+	QPen p = qp.pen();
+	p.setJoinStyle(Qt::MiterJoin);
+	qp.setPen(p);
+	
+	qp.drawRect(QRectF(rect_x, rect_y, rect_w, rect_h));
+	qp.restore();
+	return(true);
+}
+
+/**
+	Analyse un element XML suppose representer un cercle. Si l'analyse
+	reussit, le cercle est ajoute au dessin.
+	Le cercle est defini par les attributs suivants :
+		- x : abscisse du coin superieur gauche de la quadrature du cercle
+		- y : ordonnee du coin superieur gauche de la quadrature du cercle
+		- diameter : diametre du cercle
+		
+	@param e L'element XML a analyser
+	@param qp Le QPainter a utiliser pour dessiner l'element perso
+	@return true si l'analyse reussit, false sinon
+*/
+bool CustomElement::parseCircle(QDomElement &e, QPainter &qp) {
+	// verifie la presence des attributs obligatoires
+	qreal cercle_x, cercle_y, cercle_r;
+	if (!QET::attributeIsAReal(e, QString("x"),        &cercle_x)) return(false);
+	if (!QET::attributeIsAReal(e, QString("y"),        &cercle_y)) return(false);
+	if (!QET::attributeIsAReal(e, QString("diameter"), &cercle_r)) return(false);
+	qp.save();
+	setPainterStyle(e, qp);
+	qp.drawEllipse(QRectF(cercle_x, cercle_y, cercle_r, cercle_r));
+	qp.restore();
+	return(true);
+}
+
+/**
+	Analyse un element XML suppose representer une ellipse. Si l'analyse
+	reussit, l'ellipse est ajoutee au dessin.
+	L'ellipse est definie par les attributs suivants :
+		- x : abscisse du coin superieur gauche du rectangle dans lequel s'inscrit l'ellipse
+		- y : ordonnee du coin superieur gauche du rectangle dans lequel s'inscrit l'ellipse
+		- width : dimension de la diagonale horizontale de l'ellipse
+		- height : dimension de la diagonale verticale de l'ellipse
+		
+	@param e L'element XML a analyser
+	@param qp Le QPainter a utiliser pour dessiner l'element perso
+	@return true si l'analyse reussit, false sinon
+*/
+bool CustomElement::parseEllipse(QDomElement &e, QPainter &qp) {
+	// verifie la presence des attributs obligatoires
+	qreal ellipse_x, ellipse_y, ellipse_l, ellipse_h;
+	if (!QET::attributeIsAReal(e, QString("x"),       &ellipse_x))  return(false);
+	if (!QET::attributeIsAReal(e, QString("y"),       &ellipse_y))  return(false);
+	if (!QET::attributeIsAReal(e, QString("width"), &ellipse_l))  return(false);
+	if (!QET::attributeIsAReal(e, QString("height"), &ellipse_h))  return(false);
+	qp.save();
+	setPainterStyle(e, qp);
+	qp.drawEllipse(QRectF(ellipse_x, ellipse_y, ellipse_l, ellipse_h));
+	qp.restore();
+	return(true);
+}
+
+/**
+	Analyse un element XML suppose representer un arc de cercle. Si l'analyse
+	reussit, l'arc de cercle est ajoute au dessin.
+	L'arc de cercle est defini par les quatres parametres d'une ellipse (en fait
+	l'ellipse dans laquelle s'inscrit l'arc de cercle) auxquels s'ajoutent les
+	attributs suivants :
+		- start : angle de depart : l'angle "0 degre" est a trois heures
+		- angle : etendue (en degres) de l'arc de cercle ; une valeur positive
+		va dans le sens contraire des aiguilles d'une montre
+		
+	@param e L'element XML a analyser
+	@param qp Le QPainter a utiliser pour dessiner l'element perso
+	@return true si l'analyse reussit, false sinon
+*/
+bool CustomElement::parseArc(QDomElement &e, QPainter &qp) {
+	// verifie la presence des attributs obligatoires
+	qreal arc_x, arc_y, arc_l, arc_h, arc_s, arc_a;
+	if (!QET::attributeIsAReal(e, QString("x"),       &arc_x))  return(false);
+	if (!QET::attributeIsAReal(e, QString("y"),       &arc_y))  return(false);
+	if (!QET::attributeIsAReal(e, QString("width"),   &arc_l))  return(false);
+	if (!QET::attributeIsAReal(e, QString("height"),  &arc_h))  return(false);
+	if (!QET::attributeIsAReal(e, QString("start"),   &arc_s))  return(false);
+	if (!QET::attributeIsAReal(e, QString("angle"),   &arc_a))  return(false);
+	
+	qp.save();
+	setPainterStyle(e, qp);
+	qp.drawArc(QRectF(arc_x, arc_y, arc_l, arc_h), (int)(arc_s * 16), (int)(arc_a * 16));
+	qp.restore();
+	return(true);
+}
+
+/**
+	Analyse un element XML suppose representer un polygone. Si l'analyse
+	reussit, le polygone est ajoute au dessin.
+	Le polygone est defini par une serie d'attributs x1, x2, ..., xn et autant
+	d'attributs y1, y2, ..., yn representant les coordonnees des differents
+	points du polygone.
+	Il est possible d'obtenir un polygone non ferme en utilisant closed="false"
+	@param e L'element XML a analyser
+	@param qp Le QPainter a utiliser pour dessiner l'element perso
+	@return true si l'analyse reussit, false sinon
+*/
+bool CustomElement::parsePolygon(QDomElement &e, QPainter &qp) {
+	int i = 1;
+	while(true) {
+		if (QET::attributeIsAReal(e, QString("x%1").arg(i)) && QET::attributeIsAReal(e, QString("y%1").arg(i))) ++ i;
+		else break;
+	}
+	if (i < 3) return(false);
+	QVector<QPointF> points(i-1);
+	for (int j = 1 ; j < i ; ++ j) {
+		points.insert(
+			j - 1,
+			QPointF(
+				e.attribute(QString("x%1").arg(j)).toDouble(),
+				e.attribute(QString("y%1").arg(j)).toDouble()
+			)
+		);
+	}
+	qp.save();
+	setPainterStyle(e, qp);
+	if (e.attribute("closed") == "false") qp.drawPolyline(points.data(), i-1);
+	else qp.drawPolygon(points.data(), i-1);
+	qp.restore();
+	return(true);
+}
+
+/**
+	Analyse un element XML suppose representer un texte. Si l'analyse
+	reussit, le texte est ajoute au dessin.
+	Le texte est defini par une position, une chaine de caracteres et une
+	taille.
+	@param e L'element XML a analyser
+	@param qp Le QPainter a utiliser pour dessiner l'element perso
+	@return true si l'analyse reussit, false sinon
+*/
+bool CustomElement::parseText(QDomElement &e, QPainter &qp) {
+	qreal pos_x, pos_y;
+	int size;
+	if (
+		!QET::attributeIsAReal(e, "x", &pos_x) ||\
+		!QET::attributeIsAReal(e, "y", &pos_y) ||\
+		!QET::attributeIsAnInteger(e, "size", &size) ||\
+		!e.hasAttribute("text")
+	) return(false);
+	
+	qp.save();
+	setPainterStyle(e, qp);
+	
+	// determine la police a utiliser et en recupere les metriques associees
+	QFont used_font = QETApp::diagramTextsFont(size);
+	QFontMetrics qfm(used_font);
+	QColor text_color = (e.attribute("color") != "white"? Qt::black : Qt::white);
+	
+	// instancie un QTextDocument (comme la classe QGraphicsTextItem) pour
+	// generer le rendu graphique du texte
+	QTextDocument text_document;
+	text_document.setDefaultFont(used_font);
+	text_document.setPlainText(e.attribute("text"));
+	
+	// Se positionne aux coordonnees indiquees dans la description du texte	
+	qp.setTransform(QTransform(), false);
+	qp.translate(pos_x, pos_y);
+	
+	// Pivote le systeme de coordonnees du QPainter pour effectuer le rendu
+	// dans le bon sens
+	qreal default_rotation_angle = 0.0;
+	if (QET::attributeIsAReal(e, "rotation", &default_rotation_angle)) {
+		qp.rotate(default_rotation_angle);
+	}
+	
+	/*
+		Deplace le systeme de coordonnees du QPainter pour effectuer le rendu au
+		bon endroit ; note : on soustrait l'ascent() de la police pour
+		determiner le coin superieur gauche du texte alors que la position
+		indiquee correspond a la baseline.
+	*/
+	QPointF qpainter_offset(0.0, -qfm.ascent());
+	
+	// ajuste le decalage selon la marge du document texte
+#if QT_VERSION >= 0x040500
+	text_document.setDocumentMargin(0.0);
+#else
+	// il semblerait qu'avant Qt 4.5, le documentMargin vaille 2.0 (et pas 4.0)
+	qpainter_offset.rx() -= 2.0;
+	qpainter_offset.ry() -= 2.0;
+#endif
+	
+	qp.translate(qpainter_offset);
+	
+	// force the palette used to render the QTextDocument
+	QAbstractTextDocumentLayout::PaintContext ctx;
+	ctx.palette.setColor(QPalette::Text, text_color);
+	text_document.documentLayout() -> draw(&qp, ctx);
+	
+	qp.restore();
+	return(true);
+}
+
+/**
+	Analyse un element XML suppose representer un champ de texte editable par
+	l'utilisateur. Si l'analyse reussit, le champ est ajoute au dessin.
+	Le texte est defini par :
+		- une position
+		- une chaine de caracteres facultative utilisee comme valeur par defaut
+		- une taille
+		- le fait de subir les rotations de l'element ou non
+	@param e L'element XML a analyser
+	@return Un pointeur vers l'objet ElementTextItem ainsi cree si l'analyse reussit, 0 sinon
+*/
+ElementTextItem *CustomElement::parseInput(QDomElement &e) {
+	qreal pos_x, pos_y;
+	int size;
+	if (
+		!QET::attributeIsAReal(e, "x", &pos_x) ||\
+		!QET::attributeIsAReal(e, "y", &pos_y) ||\
+		!QET::attributeIsAnInteger(e, "size", &size)
+	) return(0);
+	
+	ElementTextItem *eti = new ElementTextItem(e.attribute("text"), this);
+	eti -> setFont(QETApp::diagramTextsFont(size));
+	
+	// position du champ de texte
+	eti -> setOriginalPos(QPointF(pos_x, pos_y));
+	eti -> setPos(pos_x, pos_y);
+	
+	// rotation du champ de texte
+	qreal original_rotation_angle = 0.0;
+	QET::attributeIsAReal(e, "rotation", &original_rotation_angle);
+	eti -> setOriginalRotationAngle(original_rotation_angle);
+	eti -> setRotationAngle(original_rotation_angle);
+	
+	// comportement du champ lorsque son element parent est pivote
+	eti -> setFollowParentRotations(e.attribute("rotate") == "true");
+	
+	list_texts_ << eti;
+	
+	return(eti);
+}
+
+/**
+	Analyse un element XML suppose representer une borne. Si l'analyse
+	reussit, la borne est ajoutee a l'element.
+	Une borne est definie par les attributs suivants :
+		- x, y : coordonnees de la borne
+		- orientation  : orientation de la borne = Nord (n), Sud (s), Est (e) ou Ouest (w)
+		
+	@param e L'element XML a analyser
+	@return Un pointeur vers l'objet Terminal ainsi cree, 0 sinon
+*/
+Terminal *CustomElement::parseTerminal(QDomElement &e) {
+	// verifie la presence et la validite des attributs obligatoires
+	qreal terminalx, terminaly;
+	QET::Orientation terminalo;
+	if (!QET::attributeIsAReal(e, QString("x"), &terminalx)) return(0);
+	if (!QET::attributeIsAReal(e, QString("y"), &terminaly)) return(0);
+	if (!e.hasAttribute("orientation")) return(0);
+	if (e.attribute("orientation") == "n") terminalo = QET::North;
+	else if (e.attribute("orientation") == "s") terminalo = QET::South;
+	else if (e.attribute("orientation") == "e") terminalo = QET::East;
+	else if (e.attribute("orientation") == "w") terminalo = QET::West;
+	else return(0);
+	Terminal *new_terminal = new Terminal(terminalx, terminaly, terminalo, this, qobject_cast<Diagram *>(scene()));
+	new_terminal -> setZValue(420); // valeur arbitraire pour maintenir les bornes au-dessus des champs de texte
+	list_terminals << new_terminal;
+	return(new_terminal);
+}
+
+/**
+	Active / desactive l'antialiasing sur un QPainter
+	@param qp Le QPainter a modifier
+	@param aa Booleen a true pour activer l'antialiasing, a false pour le desactiver
+*/
+void CustomElement::setQPainterAntiAliasing(QPainter &qp, bool aa) {
+	if (forbid_antialiasing) aa = false;
+	qp.setRenderHint(QPainter::Antialiasing,          aa);
+	qp.setRenderHint(QPainter::TextAntialiasing,      aa);
+	qp.setRenderHint(QPainter::SmoothPixmapTransform, aa);
+}
+
+/**
+	Verifie si l'attribut "orientation" de l'element XML e correspond bien a la
+	syntaxe decrivant les orientations possibles pour un element.
+	Cette syntaxe comprend exactement 4 lettres :
+		- une pour le Nord
+		- une pour l'Est
+		- une pour le Sud
+		- une pour l'Ouest
+	 
+	Pour chaque orientation, on indique si elle est :
+		- l'orientation par defaut : d
+		- une orientation autorisee : y
+		- une orientation interdire : n
+		
+	Exemple : "dnny" represente un element par defaut oriente vers le nord et qui
+	peut etre oriente vers l'ouest mais pas vers le sud ou vers l'est.
+	@param e Element XML
+	@return true si l'attribut "orientation" est valide, false sinon
+*/
+bool CustomElement::validOrientationAttribute(const QDomElement &e) {
+	return(ori.fromString(e.attribute("orientation")));
+}
+
+/**
+	Applique les parametres de style definis dans l'attribut "style" de
+	l'element XML e au QPainter qp
+	Les styles possibles sont :
+		- line-style : style du trait
+			- dashed : trait en pointilles (tirets)
+			- dashdotted : Traits et points
+			- dotted : trait en pointilles (points)
+			- normal : trait plein [par defaut]
+		- line-weight : epaiseur du trait
+			- thin : trait fin
+			- normal : trait d'epaisseur 1 [par defaut]
+		- filling : remplissage de la forme
+			- white : remplissage blanc
+			- black : remplissage noir
+			 - red   : remplissage rouge
+			- blue  : remplissage bleu
+			- green : remplissage vert
+			- none : pas de remplissage [par defaut]
+		- color : couleur du trait et du texte
+			- white : trait noir [par defaut]
+			- black : trait blanc
+			- red   : trait rouge
+			- blue  : trait bleu
+			- green : trait vert
+			
+	Les autres valeurs ne sont pas prises en compte.
+	@param e L'element XML a parser
+	@param qp Le QPainter a modifier en fonction des styles
+*/
+void CustomElement::setPainterStyle(QDomElement &e, QPainter &qp) {
+	// recupere le QPen et la QBrush du QPainter
+	QPen pen = qp.pen();
+	QBrush brush = qp.brush();
+	
+	// attributs par defaut
+	pen.setJoinStyle(Qt::BevelJoin);
+	pen.setCapStyle(Qt::SquareCap);
+	
+	// recupere la liste des couples style / valeur
+	QStringList styles = e.attribute("style").split(";", QString::SkipEmptyParts);
+	
+	// agit sur le QPen et la QBrush en fonction des valeurs rencontrees
+	QRegExp rx("^\\s*([a-z-]+)\\s*:\\s*([a-z-]+)\\s*$");
+	foreach (QString style, styles) {
+		if (rx.exactMatch(style)) {
+			QString style_name = rx.cap(1);
+			QString style_value = rx.cap(2);
+			if (style_name == "line-style") {
+				if (style_value == "dashed") pen.setStyle(Qt::DashLine);
+				else if (style_value == "dotted") pen.setStyle(Qt::DotLine);
+				else if (style_value == "dashdotted") pen.setStyle(Qt::DashDotLine);
+				else if (style_value == "normal") pen.setStyle(Qt::SolidLine);
+			} else if (style_name == "line-weight") {
+				if (style_value == "thin") pen.setWidth(0);
+				else if (style_value == "normal") pen.setWidthF(1.0);
+				else if (style_value == "none") pen.setColor(QColor(0, 0, 0, 0));
+			} else if (style_name == "filling") {
+				if (style_value == "white") {
+					brush.setStyle(Qt::SolidPattern);
+					brush.setColor(Qt::white);
+				} else if (style_value == "black") {
+					brush.setStyle(Qt::SolidPattern);
+					brush.setColor(Qt::black);
+				} else if (style_value == "blue") {
+					brush.setStyle(Qt::SolidPattern);
+					brush.setColor(Qt::blue);
+				} else if (style_value == "red") {
+					brush.setStyle(Qt::SolidPattern);
+					brush.setColor(Qt::red);
+				} else if (style_value == "green") {
+					brush.setStyle(Qt::SolidPattern);
+					brush.setColor(Qt::green);
+				} else if (style_value == "none") {
+					brush.setStyle(Qt::NoBrush);
+				}
+			} else if (style_name == "color") {
+				if (style_value == "black") {
+					pen.setColor(QColor(0, 0, 0, pen.color().alpha()));
+				} else if (style_value == "white") {
+					pen.setColor(QColor(255, 255, 255, pen.color().alpha()));
+				} else if (style_value == "red") {
+					pen.setColor(Qt::red);
+				}else if (style_value == "blue") {
+					pen.setColor(Qt::blue);
+				}else if (style_value == "green") {
+					pen.setColor(Qt::green);
+				}
+			}
+		}
+	}
+	
+	// affectation du QPen et de la QBrush modifies au QPainter 
+	qp.setPen(pen);
+	qp.setBrush(brush);
+	
+	// mise en place (ou non) de l'antialiasing
+	setQPainterAntiAliasing(qp, e.attribute("antialias") == "true");
+}

Added: branches/devel/sources/qetgraphicsitem/customelement.h
===================================================================
--- branches/devel/sources/qetgraphicsitem/customelement.h	                        (rev 0)
+++ branches/devel/sources/qetgraphicsitem/customelement.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -0,0 +1,132 @@
+/*
+	Copyright 2006-2013 The QElectroTech Team
+	This file is part of QElectroTech.
+	
+	QElectroTech is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 2 of the License, or
+	(at your option) any later version.
+	
+	QElectroTech is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+	
+	You should have received a copy of the GNU General Public License
+	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef CUSTOM_ELEMENT_H
+#define CUSTOM_ELEMENT_H
+#include "fixedelement.h"
+#include <QtGui>
+#include "nameslist.h"
+#include "elementslocation.h"
+class ElementTextItem;
+class Terminal;
+/**
+	This class represents an electrical element; it may be used like a fixed
+	element, the difference being that the CustomElement reads its description
+	(names, drawing, behavior) from an XML document.
+*/
+class CustomElement : public FixedElement {
+	
+	Q_OBJECT
+	
+	// constructors, destructor
+	public:
+	CustomElement(const ElementsLocation &, QGraphicsItem * = 0, Diagram * = 0, int * = 0);
+	CustomElement(const QDomElement &,      QGraphicsItem * = 0, Diagram * = 0, int * = 0);
+	virtual ~CustomElement();
+	
+	private:
+	CustomElement(const CustomElement &);
+	
+	// attributes
+	protected:
+	int elmt_state; // hold the error code in case the instanciation fails, or 0 if everything went well
+	NamesList names;
+	ElementsLocation location_;
+	QPicture drawing;
+	QPicture low_zoom_drawing;
+	QList<Terminal *> list_terminals;
+	QList<ElementTextItem *> list_texts_;
+	bool forbid_antialiasing;
+	
+	// methods
+	public:
+	virtual QList<Terminal *> terminals() const;
+	virtual QList<Conductor *> conductors() const;
+	virtual QList<ElementTextItem *> texts() const;
+	virtual int terminalsCount() const;
+	virtual void paint(QPainter *, const QStyleOptionGraphicsItem *);
+	QString typeId() const;
+	ElementsLocation location() const;
+	bool isNull() const;
+	int state() const;
+	QString name() const;
+	
+	protected:
+	virtual bool buildFromXml(const QDomElement &, int * = 0);
+	virtual bool parseElement(QDomElement &, QPainter &);
+	virtual bool parseLine(QDomElement &, QPainter &);
+	virtual bool parseRect(QDomElement &, QPainter &);
+	virtual bool parseEllipse(QDomElement &, QPainter &);
+	virtual bool parseCircle(QDomElement &, QPainter &);
+	virtual bool parseArc(QDomElement &, QPainter &);
+	virtual bool parsePolygon(QDomElement &, QPainter &);
+	virtual bool parseText(QDomElement &, QPainter &);
+	virtual ElementTextItem *parseInput(QDomElement &);
+	virtual Terminal *parseTerminal(QDomElement &);
+	virtual void setQPainterAntiAliasing(QPainter &, bool);
+	virtual bool validOrientationAttribute(const QDomElement &);
+	virtual void setPainterStyle(QDomElement &, QPainter &);
+};
+
+/**
+	@return The element type ID; considering a CustomElement, this means the
+	@location of its XML description.
+	@see location()
+*/
+inline QString CustomElement::typeId() const {
+	return(location_.path());
+}
+
+/**
+	@return the location of the XML document describing this element.
+*/
+inline ElementsLocation CustomElement::location() const {
+	return(location_);
+}
+
+/**
+	@return true if this element is null, i.e. if its XML description could not
+	be loaded.
+*/
+inline bool CustomElement::isNull() const {
+	return(elmt_state);
+}
+
+/**
+	@return An integer representing the state of this element:
+		- 0: instantiation succeeded
+		- 1: the file does not exist
+		- 2: the file could not be opened
+		- 3: The file is not a valid XML document
+		- 4: The XML document does not have a "definition" root element.
+		- 5: The definition attributes are missing or invalid
+		- 6: The definition is empty
+		- 7: The parsing of an XML element describing an element drawing primitive failed
+		- 8: No primitive could be loadedAucune partie du dessin n'a pu etre chargee
+*/
+inline int CustomElement::state() const {
+	return(elmt_state);
+}
+
+/**
+	@return The name of this element.
+*/
+inline QString CustomElement::name() const {
+	return(names.name(location_.baseName()));
+}
+
+#endif

Modified: branches/devel/sources/qetgraphicsitem/diagramimageitem.cpp
===================================================================
--- branches/devel/sources/qetgraphicsitem/diagramimageitem.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/qetgraphicsitem/diagramimageitem.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -57,28 +57,6 @@
 }
 
 /**
-	Permet de tourner le image a un angle donne de maniere absolue.
-	Un angle de 0 degres correspond a un image horizontal non retourne.
-	@param rotation Nouvel angle de rotation de ce image
-	@see applyRotation
-*/
-void DiagramImageItem::setRotationAngle(const qreal &rotation_angle) {
-	qreal applied_rotation = QET::correctAngle(rotation_angle);
-	applyRotation(applied_rotation - rotation());
-}
-
-/**
-	Permet de tourner le image de maniere relative.
-	L'angle added_rotation est ajoute a l'orientation actuelle du image.
-	@param added_rotation Angle a ajouter a la rotation actuelle
-	@see applyRotation
-*/
-void DiagramImageItem::rotateBy(const qreal &added_rotation) {
-	qreal applied_added_rotation = QET::correctAngle(added_rotation);
-	applyRotation(applied_added_rotation);
-}
-
-/**
  * @brief DiagramImageItem::paint
  * Draw the pixmap.
  * @param painter the Qpainter to use for draw the pixmap
@@ -104,16 +82,6 @@
 }
 
 /**
-	Effectue la rotation du image en elle-meme
-	Pour les DiagramImageItem, la rotation s'effectue autour du point (0, 0).
-	Cette methode peut toutefois etre redefinie dans des classes filles
-	@param angle Angle de la rotation a effectuer
-*/
-void DiagramImageItem::applyRotation(const qreal &angle) {
-	setRotation(QET::correctAngle(rotation()+angle));
-}
-
-/**
  * @brief DiagramImageItem::setScale
  * @param scale the value of @scale must be betwen 1 and 200
  */

Modified: branches/devel/sources/qetgraphicsitem/diagramimageitem.h
===================================================================
--- branches/devel/sources/qetgraphicsitem/diagramimageitem.h	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/qetgraphicsitem/diagramimageitem.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -49,15 +49,12 @@
 	
 	virtual bool fromXml(const QDomElement &);
 	virtual QDomElement toXml(QDomDocument &) const;
-	void setRotationAngle(const qreal &);
-	void rotateBy(const qreal &);
 	virtual void editProperty();
 	void setPixmap(const QPixmap &pixmap);
 	virtual QRectF boundingRect() const;
 	
 	protected:
 	virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
-	void applyRotation(const qreal &);
 	
 	signals:
 

Added: branches/devel/sources/qetgraphicsitem/diagramtextitem.cpp
===================================================================
--- branches/devel/sources/qetgraphicsitem/diagramtextitem.cpp	                        (rev 0)
+++ branches/devel/sources/qetgraphicsitem/diagramtextitem.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -0,0 +1,328 @@
+/*
+	Copyright 2006-2013 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 "diagramtextitem.h"
+#include "diagramcommands.h"
+#include "qet.h"
+#include "qetapp.h"
+
+#include "richtext/richtexteditor_p.h"
+
+/**
+	Constructeur
+	@param parent Le QGraphicsItem parent du champ de texte
+	@param parent_diagram Le schema auquel appartient le champ de texte
+*/
+DiagramTextItem::DiagramTextItem(QGraphicsItem *parent, Diagram *parent_diagram) :
+	QGraphicsTextItem(parent, parent_diagram),
+	previous_text_(),
+	rotation_angle_(0.0)
+{
+	//set Zvalue at 10 to be upper than the DiagramImageItem
+	setZValue(10);
+	setDefaultTextColor(Qt::black);
+	setFont(QETApp::diagramTextsFont());
+	setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
+#if QT_VERSION >= 0x040600
+	setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
+#endif
+	connect(this, SIGNAL(lostFocus()), this, SLOT(setNonFocusable()));
+}
+
+/**
+	Constructeur
+	@param text Le texte affiche par le champ de texte
+	@param parent Le QGraphicsItem parent du champ de texte
+	@param parent_diagram Le schema auquel appartient le champ de texte
+*/
+DiagramTextItem::DiagramTextItem(const QString &text, QGraphicsItem *parent, Diagram *parent_diagram) :
+	QGraphicsTextItem(text, parent, parent_diagram),
+	previous_text_(text),
+	rotation_angle_(0.0)
+{
+	//set Zvalue at 10 to be upper than the DiagramImageItem
+	setZValue(10);
+	setDefaultTextColor(Qt::black);
+	setFont(QETApp::diagramTextsFont());
+	setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
+#if QT_VERSION >= 0x040600
+	setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
+#endif
+	connect(this, SIGNAL(lostFocus()), this, SLOT(setNonFocusable()));
+}
+
+/// Destructeur
+DiagramTextItem::~DiagramTextItem() {
+}
+
+/**
+	@return le Diagram auquel ce texte appartient, ou 0 si ce texte n'est
+	rattache a aucun schema
+*/
+Diagram *DiagramTextItem::diagram() const {
+	return(qobject_cast<Diagram *>(scene()));
+}
+
+/**
+	@return l'angle de rotation actuel de ce texte
+*/
+qreal DiagramTextItem::rotationAngle() const {
+	return(rotation_angle_);
+}
+
+/**
+	Permet de tourner le texte a un angle donne de maniere absolue.
+	Un angle de 0 degres correspond a un texte horizontal non retourne.
+	@param rotation Nouvel angle de rotation de ce texte
+	@see applyRotation
+*/
+void DiagramTextItem::setRotationAngle(const qreal &rotation) {
+	qreal applied_rotation = QET::correctAngle(rotation);
+	applyRotation(applied_rotation - rotation_angle_);
+	rotation_angle_ = applied_rotation;
+}
+
+/**
+	Permet de tourner le texte de maniere relative.
+	L'angle added_rotation est ajoute a l'orientation actuelle du texte.
+	@param added_rotation Angle a ajouter a la rotation actuelle
+	@see applyRotation
+*/
+void DiagramTextItem::rotateBy(const qreal &added_rotation) {
+	qreal applied_added_rotation = QET::correctAngle(added_rotation);
+	rotation_angle_ = QET::correctAngle(rotation_angle_ + applied_added_rotation);
+	applyRotation(applied_added_rotation);
+}
+
+/**
+	Traduit en coordonnees de la scene un mouvement / vecteur initialement
+	exprime en coordonnees locales.
+	@param movement Vecteur exprime en coordonnees locales
+	@return le meme vecteur, exprime en coordonnees de la scene
+*/
+QPointF DiagramTextItem::mapMovementToScene(const QPointF &movement) const {
+	// on definit deux points en coordonnees locales
+	QPointF local_origin(0.0, 0.0);
+	QPointF local_movement_point(movement);
+	
+	// on les mappe sur la scene
+	QPointF scene_origin(mapToScene(local_origin));
+	QPointF scene_movement_point(mapToScene(local_movement_point));
+	
+	// on calcule le vecteur represente par ces deux points
+	return(scene_movement_point - scene_origin);
+}
+
+/**
+	Traduit en coordonnees locales un mouvement / vecteur initialement
+	exprime en coordonnees de la scene.
+	@param movement Vecteur exprime en coordonnees de la scene
+	@return le meme vecteur, exprime en coordonnees locales
+*/
+QPointF DiagramTextItem::mapMovementFromScene(const QPointF &movement) const {
+	// on definit deux points sur la scene
+	QPointF scene_origin(0.0, 0.0);
+	QPointF scene_movement_point(movement);
+	
+	// on les mappe sur ce QGraphicsItem
+	QPointF local_origin(mapFromScene(scene_origin));
+	QPointF local_movement_point(mapFromScene(scene_movement_point));
+	
+	// on calcule le vecteur represente par ces deux points
+	return(local_movement_point - local_origin);
+}
+
+/**
+	Traduit en coordonnees de l'item parent un mouvement / vecteur initialement
+	exprime en coordonnees locales.
+	@param movement Vecteur exprime en coordonnees locales
+	@return le meme vecteur, exprime en coordonnees du parent
+*/
+QPointF DiagramTextItem::mapMovementToParent(const QPointF &movement) const {
+	// on definit deux points en coordonnees locales
+	QPointF local_origin(0.0, 0.0);
+	QPointF local_movement_point(movement);
+	
+	// on les mappe sur la scene
+	QPointF parent_origin(mapToParent(local_origin));
+	QPointF parent_movement_point(mapToParent(local_movement_point));
+	
+	// on calcule le vecteur represente par ces deux points
+	return(parent_movement_point - parent_origin);
+}
+
+/**
+	Traduit en coordonnees locales un mouvement / vecteur initialement
+	exprime en coordonnees du parent.
+	@param movement Vecteur exprime en coordonnees du parent
+	@return le meme vecteur, exprime en coordonnees locales
+*/
+QPointF DiagramTextItem::mapMovementFromParent(const QPointF &movement) const {
+	// on definit deux points sur le parent
+	QPointF parent_origin(0.0, 0.0);
+	QPointF parent_movement_point(movement);
+	
+	// on les mappe sur ce QGraphicsItem
+	QPointF local_origin(mapFromParent(parent_origin));
+	QPointF local_movement_point(mapFromParent(parent_movement_point));
+	
+	// on calcule le vecteur represente par ces deux points
+	return(local_movement_point - local_origin);
+}
+
+/**
+	Dessine le champ de texte.
+	Cette methode delegue simplement le travail a QGraphicsTextItem::paint apres
+	avoir desactive l'antialiasing.
+	@param painter Le QPainter a utiliser pour dessiner le champ de texte
+	@param option Les options de style pour le champ de texte
+	@param widget Le QWidget sur lequel on dessine 
+*/
+void DiagramTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
+	painter -> setRenderHint(QPainter::Antialiasing, false);
+	QGraphicsTextItem::paint(painter, option, widget);
+}
+
+/**
+	Gere la prise de focus du champ de texte
+	@param e Objet decrivant la prise de focus
+*/
+void DiagramTextItem::focusInEvent(QFocusEvent *e) {
+	QGraphicsTextItem::focusInEvent(e);
+	
+	// empeche le deplacement du texte pendant son edition
+	setFlag(QGraphicsItem::ItemIsMovable, false);
+	
+	// memorise le texte avant que l'utilisateur n'y touche
+	previous_text_ = toHtml();
+	// cela permettra de determiner si l'utilisateur a modifie le texte a la fin de l'edition
+}
+
+/**
+	Gere la perte de focus du champ de texte
+	@param e Objet decrivant la perte de focus
+*/
+void DiagramTextItem::focusOutEvent(QFocusEvent *e) {
+	QGraphicsTextItem::focusOutEvent(e);
+	
+	// signale la modification du texte si besoin
+	if (toPlainText() != previous_text_) {
+		emit(diagramTextChanged(this, previous_text_, toHtml()));
+		previous_text_ = toHtml();
+	}
+	
+	// deselectionne le texte
+	QTextCursor cursor = textCursor();
+	cursor.clearSelection();
+	setTextCursor(cursor);
+	
+	// hack a la con pour etre re-entrant
+	setTextInteractionFlags(Qt::NoTextInteraction);
+	
+	// autorise de nouveau le deplacement du texte
+	setFlag(QGraphicsItem::ItemIsMovable, true);
+	QTimer::singleShot(0, this, SIGNAL(lostFocus()));
+}
+
+/**
+	Gere les double-clics sur ce champ de texte.
+	@param event un QGraphicsSceneMouseEvent decrivant le double-clic
+*/
+void DiagramTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) {
+	if (!(textInteractionFlags() & Qt::TextEditable)) {
+		// rend le champ de texte editable
+		setTextInteractionFlags(Qt::TextEditorInteraction);
+		
+		// edite le champ de texte
+		setFocus(Qt::MouseFocusReason);
+	} else {
+		QGraphicsTextItem::mouseDoubleClickEvent(event);
+	}
+}
+
+/**
+	Effectue la rotation du texte en elle-meme
+	Pour les DiagramTextItem, la rotation s'effectue autour du point (0, 0).
+	Cette methode peut toutefois etre redefinie dans des classes filles
+	@param angle Angle de la rotation a effectuer
+*/
+void DiagramTextItem::applyRotation(const qreal &angle) {
+	setRotation(QET::correctAngle(rotation()+angle));
+}
+
+/**
+	Change la position du champ de texte en veillant a ce qu'il
+	reste sur la grille du schema auquel il appartient.
+	@param p Nouvelles coordonnees de l'element
+*/
+void DiagramTextItem::setPos(const QPointF &p) {
+	if (p == pos()) return;
+	// pas la peine de positionner sur la grille si l'element n'est pas sur un Diagram
+	if (scene()) {
+		// arrondit l'abscisse a 10 px pres
+		int p_x = qRound(p.x() / (Diagram::xGrid * 1.0)) * Diagram::xGrid;
+		// arrondit l'ordonnee a 10 px pres
+		int p_y = qRound(p.y() / (Diagram::yGrid * 1.0)) * Diagram::yGrid;
+		QGraphicsTextItem::setPos(p_x, p_y);
+	} else QGraphicsTextItem::setPos(p);
+}
+
+/**
+	Change la position du champ de texte en veillant a ce que l'il
+	reste sur la grille du schema auquel il appartient.
+	@param x Nouvelle abscisse de l'element
+	@param y Nouvelle ordonnee de l'element
+*/
+void DiagramTextItem::setPos(qreal x, qreal y) {
+	setPos(QPointF(x, y));
+}
+
+/**
+	@return la position du champ de texte
+*/
+QPointF DiagramTextItem::pos() const {
+	return(QGraphicsTextItem::pos());
+}
+
+/// Rend le champ de texte non focusable
+void DiagramTextItem::setNonFocusable() {
+	setFlag(QGraphicsTextItem::ItemIsFocusable, false);
+}
+
+
+/**
+ * @brief DiagramTextItem::setHtmlText
+ * @param txt
+ */
+void DiagramTextItem::setHtmlText(const QString &txt) {
+	setHtml( txt );
+}
+
+/**
+ * @brief Edit the text with HtmlEditor
+ */
+void DiagramTextItem::edit() {
+	//Open the HtmlEditor
+	qdesigner_internal::RichTextEditorDialog *editor = new qdesigner_internal::RichTextEditorDialog();
+	// connect the in/out
+	connect(editor, SIGNAL(applyEditText(const QString &)), this, SLOT(setHtmlText(const QString &)));
+	// load the Html txt
+	editor->setText( toHtml() );
+	// show
+	editor->show();
+}
+

Added: branches/devel/sources/qetgraphicsitem/diagramtextitem.h
===================================================================
--- branches/devel/sources/qetgraphicsitem/diagramtextitem.h	                        (rev 0)
+++ branches/devel/sources/qetgraphicsitem/diagramtextitem.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -0,0 +1,85 @@
+/*
+	Copyright 2006-2013 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 DIAGRAM_TEXT_ITEM_H
+#define DIAGRAM_TEXT_ITEM_H
+#include <QtGui>
+#include "diagram.h"
+/**
+	This class represents a selectable, movable and editable text field on a
+	diagram.
+	@see QGraphicsItem::GraphicsItemFlags
+*/
+class DiagramTextItem : public QGraphicsTextItem {
+	Q_OBJECT
+	// constructors, destructor
+	public:
+	DiagramTextItem(QGraphicsItem * = 0, Diagram * = 0);
+	DiagramTextItem(const QString &, QGraphicsItem * = 0, Diagram * = 0);
+	virtual ~DiagramTextItem();
+	
+	// attributes
+	public:
+	enum { Type = UserType + 1004 };
+	
+	// methods
+	public:
+	/**
+		Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
+		DiagramTextItem
+		@return the QGraphicsItem type
+	*/
+	virtual int type() const { return Type; }
+	Diagram *diagram() const;
+	virtual void fromXml(const QDomElement &) = 0;
+	virtual QDomElement toXml(QDomDocument &) const = 0;
+	virtual void setPos(const QPointF &);
+	virtual void setPos(qreal, qreal);
+	virtual QPointF pos() const;
+	qreal rotationAngle() const;
+	void setRotationAngle(const qreal &);
+	void rotateBy(const qreal &);
+	void edit();
+	QPointF mapMovementToScene(const QPointF &) const;
+	QPointF mapMovementFromScene(const QPointF &) const;
+	QPointF mapMovementToParent(const QPointF &) const;
+	QPointF mapMovementFromParent(const QPointF &) const;
+	
+	protected:
+	virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+	virtual void focusInEvent(QFocusEvent *);
+	virtual void focusOutEvent(QFocusEvent *);
+	virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *);
+	virtual void applyRotation(const qreal &);
+	
+	signals:
+	/// signal emitted when the text field loses focus
+	void lostFocus();
+	/// signal emitted after text was changed
+	void diagramTextChanged(DiagramTextItem *, const QString &, const QString &);
+	
+	public slots:
+	void setNonFocusable();
+	void setHtmlText(const QString &);
+	
+	private:
+	/// Previous text value
+	QString previous_text_;
+	/// angle of rotation of the text field
+	qreal rotation_angle_;
+};
+#endif

Added: branches/devel/sources/qetgraphicsitem/element.cpp
===================================================================
--- branches/devel/sources/qetgraphicsitem/element.cpp	                        (rev 0)
+++ branches/devel/sources/qetgraphicsitem/element.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -0,0 +1,433 @@
+/*
+	Copyright 2006-2013 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 "element.h"
+#include "qetapp.h"
+#include "diagram.h"
+#include "conductor.h"
+#include "elementtextitem.h"
+#include "diagramcommands.h"
+#include <QtDebug>
+
+/**
+	Constructeur pour un element sans scene ni parent
+*/
+Element::Element(QGraphicsItem *parent, Diagram *scene) :
+	QetGraphicsItem(parent),
+	internal_connections_(false),
+	must_highlight_(false)
+{
+	setZValue(10);
+}
+
+/**
+	Destructeur
+*/
+Element::~Element() {
+}
+
+/**
+	@return true si l'element est mis en evidence
+*/
+bool Element::isHighlighted() const {
+	return(must_highlight_);
+}
+
+/**
+	@param hl true pour mettre l'element en evidence, false sinon
+*/
+void Element::setHighlighted(bool hl) {
+	must_highlight_ = hl;
+	update();
+}
+
+/**
+	Methode principale de dessin de l'element
+	@param painter Le QPainter utilise pour dessiner l'elment
+	@param options Les options de style a prendre en compte
+	@param widget  Le widget sur lequel on dessine
+*/
+void Element::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
+	
+#ifndef Q_WS_WIN
+	// corrige un bug de rendu ne se produisant que lors du rendu sur QGraphicsScene sous X11 au zoom par defaut
+	static bool must_correct_rendering_bug = QETApp::settings().value("correct-rendering", false).toBool();
+	if (must_correct_rendering_bug) {
+		Diagram *dia = diagram();
+		if (dia && options -> levelOfDetail == 1.0 && widget) {
+			// calcule la rotation qu'a subi l'element
+			qreal applied_rotation = 90.0 * (ori.current() - ori.defaultOrientation());
+			while (applied_rotation < 360.0) applied_rotation += 360.0;
+			while (applied_rotation > 360.0) applied_rotation -= 360.0;
+			if (applied_rotation == 90.0) painter -> translate(1.0, -1.0);
+			else if (applied_rotation == 180.0) painter -> translate(-1.0, -1.0);
+			else if (applied_rotation == 270.0) painter -> translate(-1.0, 1.0);
+		}
+	}
+#endif
+	if (must_highlight_) drawHighlight(painter, options);
+	
+	// Dessin de l'element lui-meme
+	paint(painter, options);
+	
+	// Dessin du cadre de selection si necessaire
+	if (isSelected()) drawSelection(painter, options);
+}
+
+/**
+	@return Le rectangle delimitant le contour de l'element
+*/
+QRectF Element::boundingRect() const {
+	return(QRectF(QPointF(-hotspot_coord.x(), -hotspot_coord.y()), dimensions));
+}
+
+/**
+	Definit la taille de l'element sur le schema. Les tailles doivent etre
+	des multiples de 10 ; si ce n'est pas le cas, les dimensions indiquees
+	seront arrrondies aux dizaines superieures.
+	@param wid Largeur de l'element
+	@param hei Hauteur de l'element
+	@return La taille finale de l'element
+*/
+QSize Element::setSize(int wid, int hei) {
+	prepareGeometryChange();
+	// chaque dimension indiquee est arrondie a la dizaine superieure
+	while (wid % 10) ++ wid;
+	while (hei % 10) ++ hei;
+	// les dimensions finales sont conservees et retournees
+	return(dimensions = QSize(wid, hei));
+}
+
+/**
+	@return la taille de l'element sur le schema
+*/
+QSize Element::size() const {
+	return(dimensions);
+}
+
+/**
+	Definit le hotspot de l'element par rapport au coin superieur gauche de son rectangle delimitant.
+	Necessite que la taille ait deja ete definie
+	@param hs Coordonnees du hotspot
+*/
+QPoint Element::setHotspot(QPoint hs) {
+	// la taille doit avoir ete definie
+	prepareGeometryChange();
+	if (dimensions.isNull()) hotspot_coord = QPoint(0, 0);
+	else {
+		// les coordonnees indiquees ne doivent pas depasser les dimensions de l'element
+		int hsx = qMin(hs.x(), dimensions.width());
+		int hsy = qMin(hs.y(), dimensions.height());
+		hotspot_coord = QPoint(hsx, hsy);
+	}
+	return(hotspot_coord);
+}
+
+/**
+	@return Le hotspot courant de l'element
+*/
+QPoint Element::hotspot() const {
+	return(hotspot_coord);
+}
+
+/**
+	Selectionne l'element
+*/
+void Element::select() {
+	setSelected(true);
+}
+
+/**
+	Deselectionne l'element
+*/
+void Element::deselect() {
+	setSelected(false);
+}
+
+/**
+	@return La pixmap de l'element
+*/
+QPixmap Element::pixmap() {
+	if (preview.isNull()) updatePixmap(); // on genere la pixmap si ce n'est deja fait
+	return(preview);
+}
+
+/**
+	Permet de specifier l'orientation de l'element
+	@param o la nouvelle orientation de l'objet
+	@return true si l'orientation a pu etre appliquee, false sinon
+*/
+bool Element::setOrientation(QET::Orientation o) {
+	// verifie que l'orientation demandee est acceptee
+	if (!ori.accept(o)) return(false);
+	prepareGeometryChange();
+	// rotation en consequence et rafraichissement de l'element graphique
+	qreal rotation_value = 90.0 * (o - ori.current());
+	applyRotation(rotation_value);
+	ori.setCurrent(o);
+	update();
+	foreach(QGraphicsItem *qgi, childItems()) {
+		if (Terminal *p = qgraphicsitem_cast<Terminal *>(qgi)) {
+			p -> updateConductor();
+		}
+	}
+	return(true);
+}
+
+/*** Methodes protegees ***/
+
+/**
+	Dessine un petit repere (axes x et y) relatif a l'element
+	@param painter Le QPainter a utiliser pour dessiner les axes
+	@param options Les options de style a prendre en compte
+*/
+void Element::drawAxes(QPainter *painter, const QStyleOptionGraphicsItem *options) {
+	Q_UNUSED(options);
+	painter -> setPen(Qt::blue);
+	painter -> drawLine(0, 0, 10, 0);
+	painter -> drawLine(7,-3, 10, 0);
+	painter -> drawLine(7, 3, 10, 0);
+	painter -> setPen(Qt::red);
+	painter -> drawLine(0,  0, 0, 10);
+	painter -> drawLine(0, 10,-3,  7);
+	painter -> drawLine(0, 10, 3,  7);
+}
+
+/*** Methodes privees ***/
+
+/**
+	Dessine le cadre de selection de l'element de maniere systematiquement non antialiasee.
+	@param painter Le QPainter a utiliser pour dessiner les bornes.
+	@param options Les options de style a prendre en compte
+ */
+void Element::drawSelection(QPainter *painter, const QStyleOptionGraphicsItem *options) {
+	Q_UNUSED(options);
+	painter -> save();
+	// Annulation des renderhints
+	painter -> setRenderHint(QPainter::Antialiasing,          false);
+	painter -> setRenderHint(QPainter::TextAntialiasing,      false);
+	painter -> setRenderHint(QPainter::SmoothPixmapTransform, false);
+	// Dessin du cadre de selection en gris
+	QPen t;
+	t.setColor(Qt::gray);
+	t.setStyle(Qt::DashDotLine);
+	painter -> setPen(t);
+	// Le dessin se fait a partir du rectangle delimitant
+	painter -> drawRoundRect(boundingRect().adjusted(1, 1, -1, -1), 10, 10);
+	painter -> restore();
+}
+
+/**
+	Dessine le cadre de selection de l'element de maniere systematiquement non antialiasee.
+	@param painter Le QPainter a utiliser pour dessiner les bornes.
+	@param options Les options de style a prendre en compte
+ */
+void Element::drawHighlight(QPainter *painter, const QStyleOptionGraphicsItem *options) {
+	Q_UNUSED(options);
+	painter -> save();
+	
+	qreal gradient_radius = qMin(boundingRect().width(), boundingRect().height()) / 2.0;
+	QRadialGradient gradient(
+		boundingRect().center(),
+		gradient_radius,
+		boundingRect().center()
+	);
+	gradient.setColorAt(0.0, QColor::fromRgb(69, 137, 255, 255));
+	gradient.setColorAt(1.0, QColor::fromRgb(69, 137, 255, 0));
+	QBrush brush(gradient);
+	
+	painter -> setPen(Qt::NoPen);
+	painter -> setBrush(brush);
+	// Le dessin se fait a partir du rectangle delimitant
+	painter -> drawRoundRect(boundingRect().adjusted(1, 1, -1, -1), 10, 10);
+	painter -> restore();
+}
+
+/**
+	Fonction initialisant et dessinant la pixmap de l'element.
+*/
+void Element::updatePixmap() {
+	// Pixmap transparente faisant la taille de base de l'element
+	preview = QPixmap(dimensions);
+	preview.fill(QColor(255, 255, 255, 0));
+	// QPainter sur la pixmap, avec antialiasing
+	QPainter p(&preview);
+	p.setRenderHint(QPainter::Antialiasing, true);
+	p.setRenderHint(QPainter::SmoothPixmapTransform, true);
+	// Translation de l'origine du repere de la pixmap
+	p.translate(hotspot_coord);
+	// L'element se dessine sur la pixmap
+	paint(&p, 0);
+}
+
+/**
+	Permet de savoir si un element XML (QDomElement) represente bien un element
+	@param e Le QDomElement a valide
+	@return true si l'element XML est un Element, false sinon
+*/
+bool Element::valideXml(QDomElement &e) {
+	// verifie le nom du tag
+	if (e.tagName() != "element") return(false);
+	
+	// verifie la presence des attributs minimaux
+	if (!e.hasAttribute("type")) return(false);
+	if (!e.hasAttribute("x"))    return(false);
+	if (!e.hasAttribute("y"))    return(false);
+	
+	bool conv_ok;
+	// parse l'abscisse
+	e.attribute("x").toDouble(&conv_ok);
+	if (!conv_ok) return(false);
+	
+	// parse l'ordonnee
+	e.attribute("y").toDouble(&conv_ok);
+	if (!conv_ok) return(false);
+	return(true);
+}
+
+/**
+	Methode d'import XML. Cette methode est appelee lors de l'import de contenu
+	XML (coller, import, ouverture de fichier...) afin que l'element puisse
+	gerer lui-meme l'importation de ses bornes. Ici, comme cette classe est
+	caracterisee par un nombre fixe de bornes, l'implementation exige de
+	retrouver exactement ses bornes dans le fichier XML.
+	@param e L'element XML a analyser.
+	@param table_id_adr Reference vers la table de correspondance entre les IDs
+	du fichier XML et les adresses en memoire. Si l'import reussit, il faut y
+	ajouter les bons couples (id, adresse).
+	@return true si l'import a reussi, false sinon
+	
+*/
+bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr, bool handle_inputs_rotation) {
+	/*
+		les bornes vont maintenant etre recensees pour associer leurs id a leur adresse reelle
+		ce recensement servira lors de la mise en place des fils
+	*/
+	QList<QDomElement> liste_terminals;
+	foreach(QDomElement qde, QET::findInDomElement(e, "terminals", "terminal")) {
+		if (Terminal::valideXml(qde)) liste_terminals << qde;
+	}
+	
+	QHash<int, Terminal *> priv_id_adr;
+	int terminals_non_trouvees = 0;
+	foreach(QGraphicsItem *qgi, childItems()) {
+		if (Terminal *p = qgraphicsitem_cast<Terminal *>(qgi)) {
+			bool terminal_trouvee = false;
+			foreach(QDomElement qde, liste_terminals) {
+				if (p -> fromXml(qde)) {
+					priv_id_adr.insert(qde.attribute("id").toInt(), p);
+					terminal_trouvee = true;
+					// We used to break here, because we did not expect
+					// several terminals to share the same position.
+					// Of course, it finally happened.
+				}
+			}
+			if (!terminal_trouvee) ++ terminals_non_trouvees;
+		}
+	}
+	
+	if (terminals_non_trouvees > 0) {
+		return(false);
+	} else {
+		// verifie que les associations id / adr n'entrent pas en conflit avec table_id_adr
+		foreach(int id_trouve, priv_id_adr.keys()) {
+			if (table_id_adr.contains(id_trouve)) {
+				// cet element possede un id qui est deja reference (= conflit)
+				return(false);
+			}
+		}
+		// copie des associations id / adr
+		foreach(int id_trouve, priv_id_adr.keys()) {
+			table_id_adr.insert(id_trouve, priv_id_adr.value(id_trouve));
+		}
+	}
+	
+	// importe les valeurs des champs de texte
+	QList<QDomElement> inputs = QET::findInDomElement(e, "inputs", "input");
+	foreach(QGraphicsItem *qgi, childItems()) {
+		if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(qgi)) {
+			foreach(QDomElement input, inputs) eti -> fromXml(input);
+		}
+	}
+	
+	// position, selection
+	setPos(e.attribute("x").toDouble(), e.attribute("y").toDouble());
+	setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
+	
+	// orientation
+	bool conv_ok;
+	int read_ori = e.attribute("orientation").toInt(&conv_ok);
+	if (!conv_ok || read_ori < 0 || read_ori > 3) read_ori = ori.defaultOrientation();
+	if (handle_inputs_rotation) {
+		RotateElementsCommand::rotateElement(this, (QET::Orientation)read_ori);
+	} else {
+		setOrientation((QET::Orientation)read_ori);
+	}
+	return(true);
+}
+
+/**
+	Permet d'exporter l'element en XML
+	@param document Document XML a utiliser
+	@param table_adr_id Table de correspondance entre les adresses des bornes
+	et leur id dans la representation XML ; cette table completee par cette
+	methode
+	@return L'element XML representant cet element electrique
+*/
+QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table_adr_id) const {
+	QDomElement element = document.createElement("element");
+	
+	// type
+	element.setAttribute("type", typeId());
+	
+	// position, selection et orientation
+	element.setAttribute("x", QString("%1").arg(pos().x()));
+	element.setAttribute("y", QString("%1").arg(pos().y()));
+	element.setAttribute("orientation", QString("%1").arg(ori.current()));
+	
+	/* recupere le premier id a utiliser pour les bornes de cet element */
+	int id_terminal = 0;
+	if (!table_adr_id.isEmpty()) {
+		// trouve le plus grand id
+		int max_id_t = -1;
+		foreach (int id_t, table_adr_id.values()) {
+			if (id_t > max_id_t) max_id_t = id_t;
+		}
+		id_terminal = max_id_t + 1;
+	}
+	
+	// enregistrement des bornes de l'appareil
+	QDomElement xml_terminals = document.createElement("terminals");
+	// pour chaque enfant de l'element
+	foreach(Terminal *t, terminals()) {
+		// alors on enregistre la borne
+		QDomElement terminal = t -> toXml(document);
+		terminal.setAttribute("id", id_terminal);
+		table_adr_id.insert(t, id_terminal ++);
+		xml_terminals.appendChild(terminal);
+	}
+	element.appendChild(xml_terminals);
+	
+	// enregistrement des champ de texte de l'appareil
+	QDomElement inputs = document.createElement("inputs");
+	foreach(ElementTextItem *eti, texts()) {
+		inputs.appendChild(eti -> toXml(document));
+	}
+	element.appendChild(inputs);
+	
+	return(element);
+}

Added: branches/devel/sources/qetgraphicsitem/element.h
===================================================================
--- branches/devel/sources/qetgraphicsitem/element.h	                        (rev 0)
+++ branches/devel/sources/qetgraphicsitem/element.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -0,0 +1,157 @@
+/*
+	Copyright 2006-2013 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 ELEMENT_H
+#define ELEMENT_H
+#include <QtGui>
+#include "terminal.h"
+#include "orientationset.h"
+#include "qetgraphicsitem.h"
+class Diagram;
+class ElementTextItem;
+/**
+	This is the base class for electrical elements.
+*/
+class Element : public QetGraphicsItem {
+	
+	Q_OBJECT
+	
+	// constructors, destructor
+	public:
+	Element(QGraphicsItem * = 0, Diagram * = 0);
+	virtual ~Element();
+	
+	private:
+	Element(const Element &);
+	
+	// attributes
+	public:
+	enum { Type = UserType + 1000 };
+	
+	protected:
+	/**
+		Hold orientations for the element :
+			* allowed orientations
+			* current orientation
+			* default orientation
+		@see OrientationSet
+	*/
+	OrientationSet ori;
+	
+	private:
+	QSize   dimensions;
+	QPoint  hotspot_coord;
+	QPixmap preview;
+	
+	// methods
+	public:
+	/**
+		Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into an
+		Element.
+		@return the QGraphicsItem type
+	*/
+	virtual int type() const { return Type; }
+	
+	// pure virtual methods to be defined in derived classes
+	/// @return the list of terminals for this element
+	virtual QList<Terminal *> terminals() const = 0;
+	/// @return the list of conductors attached to this element
+	virtual QList<Conductor *> conductors() const = 0;
+	/// @return the list of text items attached to this element
+	virtual QList<ElementTextItem *> texts() const = 0;
+	/// @return the current number of terminals of this element
+	virtual int terminalsCount() const = 0;
+	/// @return the minimum number of terminals for this element
+	virtual int minTerminalsCount() const = 0;
+	/// @return the maximum number of terminals for this element
+	virtual int maxTerminalsCount() const = 0;
+	/**
+		Draw this element
+	*/
+	virtual void paint(QPainter *, const QStyleOptionGraphicsItem *) = 0;
+	/// @return This element type ID
+	virtual QString typeId() const = 0;
+	/// @return the human name for this element
+	virtual QString name() const = 0;
+	
+	virtual bool isHighlighted() const;
+	virtual void setHighlighted(bool);
+	void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+	QRectF boundingRect() const;
+	QSize setSize(int, int);
+	QSize size() const;
+	QPixmap  pixmap();
+	
+	// methods related to the hotspot
+	QPoint setHotspot(QPoint);
+	QPoint hotspot() const;
+	
+	// selection-related methods
+	void select();
+	void deselect();	
+	
+	// methods related to internal connections
+	bool internalConnections();
+	void setInternalConnections(bool);
+	
+	// methods related to XML import/export
+	static bool valideXml(QDomElement &);
+	virtual bool fromXml(QDomElement &, QHash<int, Terminal *> &, bool = false);
+	virtual QDomElement toXml(QDomDocument &, QHash<Terminal *, int> &) const;
+	
+	// orientation-related methods
+	bool setOrientation(QET::Orientation o);
+	const OrientationSet &orientation() const;
+	
+	protected:
+	void drawAxes(QPainter *, const QStyleOptionGraphicsItem *);
+	
+	private:
+	bool internal_connections_;
+	bool must_highlight_;
+	void drawSelection(QPainter *, const QStyleOptionGraphicsItem *);
+	void drawHighlight(QPainter *, const QStyleOptionGraphicsItem *);
+	void updatePixmap();
+};
+
+/**
+	Indicate whether this element allows internal connections, i.e. whether its
+	terminals can be linked together using a conductor.
+	@return true if internal connections are accepted, false otherwise
+*/
+inline bool Element::internalConnections() {
+	return(internal_connections_);
+}
+
+/**
+	Specify whether this element allows internal connections, i.e. whether its
+	terminals can be linked together using a conductor.
+	@return true for internal connections to be accepted, false otherwise
+*/
+inline void Element::setInternalConnections(bool ic) {
+	internal_connections_ = ic;
+}
+
+/**
+	Indicate the current orientation of this element
+	@return the current orientation of this element
+*/
+inline const OrientationSet & Element::orientation() const {
+	return(ori);
+}
+
+#endif

Added: branches/devel/sources/qetgraphicsitem/elementtextitem.cpp
===================================================================
--- branches/devel/sources/qetgraphicsitem/elementtextitem.cpp	                        (rev 0)
+++ branches/devel/sources/qetgraphicsitem/elementtextitem.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -0,0 +1,310 @@
+/*
+	Copyright 2006-2012 Xavier Guerrin
+	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 "elementtextitem.h"
+#include "diagram.h"
+#include "diagramcommands.h"
+#include "element.h"
+
+/**
+	Constructeur
+	@param parent_element Le QGraphicsItem parent du champ de texte
+	@param parent_diagram Le schema auquel appartient le champ de texte
+*/
+ElementTextItem::ElementTextItem(Element *parent_element, Diagram *parent_diagram) :
+	DiagramTextItem(parent_element, parent_diagram),
+	parent_element_(parent_element),
+	follow_parent_rotations(false),
+	original_rotation_angle_(0.0),
+	first_move_(true)
+{
+	// par defaut, les DiagramTextItem sont Selectable et Movable
+	// cela nous convient, on ne touche pas a ces flags
+	
+	adjustItemPosition(1);
+	// ajuste la position du QGraphicsItem lorsque le QTextDocument change
+	connect(document(), SIGNAL(blockCountChanged(int)), this, SLOT(adjustItemPosition(int)));
+	connect(document(), SIGNAL(contentsChanged()),      this, SLOT(adjustItemPosition()));
+}
+
+/**
+	Constructeur
+	@param parent_element L'element parent du champ de texte
+	@param parent_diagram Le schema auquel appartient le champ de texte
+	@param text Le texte affiche par le champ de texte
+*/
+ElementTextItem::ElementTextItem(const QString &text, Element *parent_element, Diagram *parent_diagram) :
+	DiagramTextItem(text, parent_element, parent_diagram),
+	parent_element_(parent_element),
+	follow_parent_rotations(false),
+	original_rotation_angle_(0.0),
+	first_move_(true)
+{
+	// par defaut, les DiagramTextItem sont Selectable et Movable
+	// cela nous convient, on ne touche pas a ces flags
+	
+	adjustItemPosition(1);
+	// ajuste la position du QGraphicsItem lorsque le QTextDocument change
+	connect(document(), SIGNAL(blockCountChanged(int)), this, SLOT(adjustItemPosition(int)));
+	connect(document(), SIGNAL(contentsChanged()),      this, SLOT(adjustItemPosition()));
+}
+
+/// Destructeur
+ElementTextItem::~ElementTextItem() {
+}
+
+/**
+	@return L'element parent de ce champ de texte, ou 0 si celui-ci n'en a pas.
+*/
+Element *ElementTextItem::parentElement() const {
+	return(parent_element_);
+}
+
+/**
+	Modifie la position du champ de texte
+	@param pos La nouvelle position du champ de texte
+*/
+void ElementTextItem::setPos(const QPointF &pos) {
+	QGraphicsTextItem::setPos(pos);
+}
+
+/**
+	Modifie la position du champ de texte
+	@param x La nouvelle abscisse du champ de texte
+	@param y La nouvelle ordonnee du champ de texte
+*/
+void ElementTextItem::setPos(qreal x, qreal y) {
+	setPos(QPointF(x, y));
+}
+
+/**
+	@return La position (bidouillee) du champ de texte
+*/
+QPointF ElementTextItem::pos() const {
+	return(QGraphicsTextItem::pos());
+}
+
+/**
+	Permet de lire le texte a mettre dans le champ a partir d'un element XML.
+	Cette methode se base sur la position du champ pour assigner ou non la
+	valeur a ce champ.
+	@param e L'element XML representant le champ de texte
+*/
+void ElementTextItem::fromXml(const QDomElement &e) {
+	QPointF _pos = pos();
+	if (
+		qFuzzyCompare(qreal(e.attribute("x").toDouble()), _pos.x()) &&
+		qFuzzyCompare(qreal(e.attribute("y").toDouble()), _pos.y())
+	) {
+		setPlainText(e.attribute("text"));
+		
+		qreal user_pos_x, user_pos_y;
+		if (
+			QET::attributeIsAReal(e, "userx", &user_pos_x) &&
+			QET::attributeIsAReal(e, "usery", &user_pos_y)
+		) {
+			setPos(user_pos_x, user_pos_y);
+		}
+		
+		qreal xml_rotation_angle;
+		if (QET::attributeIsAReal(e, "userrotation", &xml_rotation_angle)) {
+			setRotationAngle(xml_rotation_angle);
+		}
+	}
+}
+
+/**
+	@param document Le document XML a utiliser
+	@return L'element XML representant ce champ de texte
+*/
+QDomElement ElementTextItem::toXml(QDomDocument &document) const {
+	QDomElement result = document.createElement("input");
+	
+	result.setAttribute("x", QString("%1").arg(originalPos().x()));
+	result.setAttribute("y", QString("%1").arg(originalPos().y()));
+	
+	if (pos() != originalPos()) {
+		result.setAttribute("userx", QString("%1").arg(pos().x()));
+		result.setAttribute("usery", QString("%1").arg(pos().y()));
+	}
+	
+	result.setAttribute("text", toPlainText());
+	
+	if (rotationAngle() != originalRotationAngle()) {
+		result.setAttribute("userrotation", QString("%1").arg(rotationAngle()));
+	}
+	
+	return(result);
+}
+
+/**
+	@param p Position originale / de reference pour ce champ
+	Cette position est utilisee lors de l'export en XML
+*/
+void ElementTextItem::setOriginalPos(const QPointF &p) {
+	original_position = p;
+}
+
+/**
+	@return la position originale / de reference pour ce champ
+*/
+QPointF ElementTextItem::originalPos() const {
+	return(original_position);
+}
+
+/**
+	Definit l'angle de rotation original de ce champ de texte
+	@param rotation_angle un angle de rotation
+*/
+void ElementTextItem::setOriginalRotationAngle(const qreal &rotation_angle) {
+	original_rotation_angle_ = QET::correctAngle(rotation_angle);
+}
+
+/**
+	@return l'angle de rotation original de ce champ de texte
+*/
+qreal ElementTextItem::originalRotationAngle() const {
+	return(original_rotation_angle_);
+}
+
+/**
+	Set the font used to render the text item to \a font.
+*/
+void ElementTextItem::setFont(const QFont &font) {
+	DiagramTextItem::setFont(font);
+	adjustItemPosition(1);
+}
+
+/**
+	Cette methode s'assure que la position de l'ElementTextItem est coherente
+	en ajustant :
+		* la transformation de base qui permet de considerer que l'origine
+	correspond au milieu du bord gauche du champ de texte
+		* l'origine utilisee lors des appels a setRotation et setScale
+	@param new_block_count Nombre de blocs dans l'ElementTextItem
+*/
+void ElementTextItem::adjustItemPosition(int new_block_count) {
+	Q_UNUSED(new_block_count);
+	qreal origin_offset = boundingRect().bottom() / 2.0;
+	
+	QTransform base_translation;
+	base_translation.translate(0.0, -origin_offset);
+	setTransform(base_translation, false);
+	setTransformOriginPoint(0.0, origin_offset);
+}
+
+/**
+	Effetue la rotation du texte en elle-meme
+	Pour les ElementTextItem, la rotation s'effectue autour du milieu du bord
+	gauche du champ de texte.
+	@param angle Angle de la rotation a effectuer
+*/
+void ElementTextItem::applyRotation(const qreal &angle) {
+	QGraphicsTextItem::setRotation(QGraphicsTextItem::rotation() + angle);
+}
+
+/**
+	Gere le clic sur le champ de texte
+	@param e Objet decrivant l'evenement souris
+*/
+void ElementTextItem::mousePressEvent(QGraphicsSceneMouseEvent *e) {
+	first_move_ = true;
+	if (e -> modifiers() & Qt::ControlModifier) {
+		setSelected(!isSelected());
+	}
+	DiagramTextItem::mousePressEvent(e);
+}
+
+/**
+	Gere les mouvements de souris lies au champ de texte
+	@param e Objet decrivant l'evenement souris
+*/
+void ElementTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
+	if (textInteractionFlags() & Qt::TextEditable) {
+		DiagramTextItem::mouseMoveEvent(e);
+	} else if ((flags() & QGraphicsItem::ItemIsMovable) && (e -> buttons() & Qt::LeftButton)) {
+		QPointF old_pos = pos();
+		/*
+			Utiliser e -> pos() directement aurait pour effet de positionner
+			l'origine du champ de texte a la position indiquee par le curseur,
+			ce qui n'est pas l'effet recherche
+			Au lieu de cela, on applique a la position actuelle le vecteur
+			definissant le mouvement effectue depuis la derniere position
+			cliquee avec le bouton gauche
+		*/
+		QPointF movement = e -> pos() - e -> buttonDownPos(Qt::LeftButton);
+		
+		/*
+			Les methodes pos() et setPos() travaillent toujours avec les
+			coordonnees de l'item parent (ou de la scene s'il n'y a pas d'item
+			parent). On n'oublie donc pas de mapper le mouvement fraichement
+			calcule sur l'item parent avant de l'appliquer.
+		*/
+		QPointF parent_movement = mapMovementToParent(movement);
+		setPos(pos() + parent_movement);
+		
+		Diagram *diagram_ptr = diagram();
+		if (diagram_ptr) {
+			if (first_move_) {
+				// on signale le debut d'un deplacement d'ElementTextItems au schema parent
+				int moved_texts_count = diagram_ptr -> beginMoveElementTexts(this);
+				
+				// s'il n'y a qu'un seul texte deplace, on met en valeur l'element parent
+				if (moved_texts_count == 1 && parent_element_) {
+					parent_element_ -> setHighlighted(true);
+					parent_element_ -> update();
+				}
+			}
+			
+			/*
+				Comme setPos() n'est pas oblige d'appliquer exactement la
+				valeur qu'on lui fournit, on calcule le mouvement reellement
+				applique.
+			*/
+			QPointF effective_movement = pos() - old_pos;
+			QPointF scene_effective_movement = mapMovementToScene(mapMovementFromParent(effective_movement));
+			
+			// on applique le mouvement subi aux autres textes a deplacer
+			diagram_ptr -> continueMoveElementTexts(scene_effective_movement);
+		}
+	} else e -> ignore();
+	
+	if (first_move_) {
+		first_move_ = false;
+	}
+}
+
+/**
+	Gere le relachement de souris
+	Cette methode cree un objet d'annulation pour le deplacement
+	@param e Objet decrivant l'evenement souris
+*/
+void ElementTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
+	if (Diagram *diagram_ptr = diagram()) {
+		// on arrete de mettre en valeur l'element parent
+		if (parent_element_) {
+			if (parent_element_ -> isHighlighted()) {
+				parent_element_ -> setHighlighted(false);
+			}
+		}
+		
+		diagram_ptr -> endMoveElementTexts();
+	}
+	if (!(e -> modifiers() & Qt::ControlModifier)) {
+		QGraphicsTextItem::mouseReleaseEvent(e);
+	}
+}

Added: branches/devel/sources/qetgraphicsitem/elementtextitem.h
===================================================================
--- branches/devel/sources/qetgraphicsitem/elementtextitem.h	                        (rev 0)
+++ branches/devel/sources/qetgraphicsitem/elementtextitem.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -0,0 +1,96 @@
+/*
+	Copyright 2006-2012 Xavier Guerrin
+	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 ELEMENT_TEXT_ITEM_H
+#define ELEMENT_TEXT_ITEM_H
+#include "diagramtextitem.h"
+#include <QtXml>
+class Diagram;
+class Element;
+/**
+	This class represents a text item attached to an element. Users can change its
+	value, adjust its position (defined relatively to its parent element), and
+	direct it to any angle.
+*/
+class ElementTextItem : public DiagramTextItem {
+	Q_OBJECT
+	// constructors, destructor
+	public:
+	ElementTextItem(Element * = 0, Diagram * = 0);
+	ElementTextItem(const QString &, Element * = 0, Diagram * = 0);
+	virtual ~ElementTextItem();
+	
+	// attributes
+	public:
+	enum { Type = UserType + 1003 };
+	
+	private:
+	Element *parent_element_;
+	bool follow_parent_rotations;
+	QPointF original_position;
+	qreal original_rotation_angle_;
+	bool first_move_;
+	
+	// methods
+	public:
+	virtual int type() const { return Type; }
+	Element *parentElement() const;
+	/// @return the rectangle defining the bounds of this text item
+	virtual QRectF boundingRect() const { return(QGraphicsTextItem::boundingRect().adjusted(0.0, -1.1, 0.0, 0.0)); }
+	bool followParentRotations() const;
+	void setFollowParentRotations(bool);
+	void fromXml(const QDomElement &);
+	QDomElement toXml(QDomDocument &) const;
+	void setPos(const QPointF &);
+	void setPos(qreal, qreal);
+	virtual QPointF pos() const;
+	void setOriginalPos(const QPointF &);
+	QPointF originalPos() const;
+	void setOriginalRotationAngle(const qreal &);
+	qreal originalRotationAngle() const;
+	virtual void setFont(const QFont &);
+	
+	public slots:
+	void adjustItemPosition(int = 0);
+	
+	protected:
+	virtual void applyRotation(const qreal &);
+	virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
+	virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
+	virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
+};
+
+/**
+	Element text items can optionally be applied a counter-rotation when their
+	parent element is rotated, thus preserving their readability.
+	@return whether this text item follows the rotations of its parent element.
+*/
+inline bool ElementTextItem::followParentRotations() const {
+	return(follow_parent_rotations);
+}
+
+/**
+	Element text items can optionally be applied a counter-rotation when their
+	parent element is rotated, thus preserving their readability.
+	@param frp whether this text item should follow the rotations of its parent
+	element.
+*/
+inline void ElementTextItem::setFollowParentRotations(bool frp) {
+	follow_parent_rotations = frp;
+}
+
+#endif

Added: branches/devel/sources/qetgraphicsitem/fixedelement.cpp
===================================================================
--- branches/devel/sources/qetgraphicsitem/fixedelement.cpp	                        (rev 0)
+++ branches/devel/sources/qetgraphicsitem/fixedelement.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -0,0 +1,43 @@
+/*
+	Copyright 2006-2012 Xavier Guerrin
+	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 "fixedelement.h"
+/**
+	Constructeur
+*/
+FixedElement::FixedElement(QGraphicsItem *parent, Diagram *scene) : Element(parent, scene) {
+}
+
+/**
+	Destructeur
+*/
+FixedElement::~FixedElement() {
+}
+
+/**
+	@return Le nombre minimal de bornes que l'element peut avoir
+*/
+int FixedElement::minTerminalsCount() const {
+	return(terminalsCount());
+}
+
+/**
+	@return Le nombre maximal de bornes que l'element peut avoir
+*/
+int FixedElement::maxTerminalsCount() const {
+	return(terminalsCount());
+}

Added: branches/devel/sources/qetgraphicsitem/fixedelement.h
===================================================================
--- branches/devel/sources/qetgraphicsitem/fixedelement.h	                        (rev 0)
+++ branches/devel/sources/qetgraphicsitem/fixedelement.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -0,0 +1,42 @@
+/*
+	Copyright 2006-2012 Xavier Guerrin
+	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 ELEMENTFIXE_H
+#define ELEMENTFIXE_H
+#include "element.h"
+/**
+	This class represents an element having a fixed number of terminals.
+*/
+class FixedElement : public Element {
+	
+	Q_OBJECT
+	
+	// constructors, destructor
+	public:
+	FixedElement(QGraphicsItem * = 0, Diagram * = 0);
+	virtual ~FixedElement();
+	
+	// methods
+	public:
+	int minTerminalsCount() const;
+	int maxTerminalsCount() const;
+	virtual int terminalsCount() const = 0;
+	virtual void paint(QPainter *, const QStyleOptionGraphicsItem *) = 0;
+	virtual QString typeId() const = 0;
+	virtual QString name() const = 0;
+};
+#endif

Added: branches/devel/sources/qetgraphicsitem/ghostelement.cpp
===================================================================
--- branches/devel/sources/qetgraphicsitem/ghostelement.cpp	                        (rev 0)
+++ branches/devel/sources/qetgraphicsitem/ghostelement.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -0,0 +1,191 @@
+/*
+	Copyright 2006-2012 Xavier Guerrin
+	This file is part of QElectroTech.
+	
+	QElectroTech is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 2 of the License, or
+	(at your option) any later version.
+	
+	QElectroTech is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+	
+	You should have received a copy of the GNU General Public License
+	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "ghostelement.h"
+#include "qet.h"
+#include "terminal.h"
+#include "elementtextitem.h"
+#include "diagramcommands.h"
+
+/**
+	Constructeur
+	@param location Emplacement de la definition d'element a utiliser
+	@param qgi Le QGraphicsItem parent de cet element
+	@param d Le schema affichant cet element
+*/
+GhostElement::GhostElement(
+	const ElementsLocation &location,
+	QGraphicsItem *qgi,
+	Diagram *d
+) :
+	CustomElement(location, qgi, d)
+{
+	QString tooltip_string = QString(
+		tr("<u>\311l\351ment manquant\240:</u> %1")
+	).arg(location_.toString());
+	setToolTip(tooltip_string);
+}
+
+/**
+	Destructeur
+*/
+GhostElement::~GhostElement() {
+}
+
+
+/**
+	@param e L'element XML a analyser.
+	@param table_id_adr Reference vers la table de correspondance entre les IDs
+	du fichier XML et les adresses en memoire. Si l'import reussit, il faut y
+	ajouter les bons couples (id, adresse).
+	@return true si l'import a reussi, false sinon
+*/
+bool GhostElement::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr, bool handle_inputs_rotation) {
+	// instancie les bornes decrites dans l'element XML
+	terminalsFromXml(e, table_id_adr);
+	
+	// instancie les champs de texte decrits dans l'element XML
+	foreach(QDomElement qde, QET::findInDomElement(e, "inputs", "input")) {
+		qde.setAttribute("size", 9); // arbitraire
+		if (ElementTextItem *new_input = CustomElement::parseInput(qde)) {
+			new_input -> fromXml(qde);
+		}
+		qde.removeAttribute("size");
+	}
+	
+	/*
+		maintenant que l'element fantome connait toutes les bornes et tous les
+		champs de texte, on peut determiner une taille appropriee
+	*/
+	QRect final_bounding_rect = minimalBoundingRect().united(childrenBoundingRect()).toAlignedRect();
+	setSize(final_bounding_rect.width(), final_bounding_rect.height());
+	setHotspot(QPoint() - final_bounding_rect.topLeft());
+	setInternalConnections(true);
+	
+	// on peut desormais confectionner le rendu de l'element
+	generateDrawings();
+	
+	// position, selection
+	setPos(e.attribute("x").toDouble(), e.attribute("y").toDouble());
+	setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
+	
+	// orientation
+	bool conv_ok;
+	int read_ori = e.attribute("orientation").toInt(&conv_ok);
+	if (!conv_ok || read_ori < 0 || read_ori > 3) read_ori = ori.defaultOrientation();
+	if (handle_inputs_rotation) {
+		RotateElementsCommand::rotateElement(this, (QET::Orientation)read_ori);
+	} else {
+		setOrientation((QET::Orientation)read_ori);
+	}
+	return(true);
+}
+
+/**
+	@return le bounding rect minimum, utilise si l'element fantome n'a ni champ
+	de texte ni borne.
+*/
+QRectF GhostElement::minimalBoundingRect() const {
+	return(
+		QRectF(
+			QPointF(-10.0, -10.0),
+			QSizeF(20.0, 20.0)
+		)
+	);
+}
+
+/**
+	Gere l'import des bornes
+	@param e L'element XML a analyser.
+	@param table_id_adr Reference vers la table de correspondance entre les IDs
+	du fichier XML et les adresses en memoire. Si l'import reussit, il faut y
+	ajouter les bons couples (id, adresse).
+	@return true si l'import a reussi, false sinon
+*/
+bool GhostElement::terminalsFromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr) {
+	// instancie les bornes decrites dans l'element XML
+	foreach(QDomElement qde, QET::findInDomElement(e, "terminals", "terminal")) {
+		if (!Terminal::valideXml(qde)) continue;
+		
+		// modifie certains attributs pour que l'analyse par la classe CustomElement reussisse
+		int previous_x_value   = qde.attribute("x").toInt();
+		int previous_y_value   = qde.attribute("y").toInt();
+		int previous_ori_value = qde.attribute("orientation").toInt();
+		
+		qreal x_add = 0.0, y_add = 0.0;
+		if (previous_ori_value == QET::North)      y_add = -Terminal::terminalSize;
+		else if (previous_ori_value == QET::East)  x_add = Terminal::terminalSize;
+		else if (previous_ori_value == QET::South) y_add = Terminal::terminalSize;
+		else if (previous_ori_value == QET::West)  x_add = -Terminal::terminalSize;
+		qde.setAttribute("x",           previous_x_value + x_add);
+		qde.setAttribute("y",           previous_y_value + y_add);
+		qde.setAttribute("orientation", QET::orientationToString(static_cast<QET::Orientation>(previous_ori_value)));
+		
+		if (Terminal *new_terminal = CustomElement::parseTerminal(qde)) {
+			table_id_adr.insert(qde.attribute("id").toInt(), new_terminal);
+		}
+		
+		// restaure les attributs modifies
+		qde.setAttribute("x",           previous_x_value);
+		qde.setAttribute("y",           previous_y_value);
+		qde.setAttribute("orientation", previous_ori_value);
+	}
+	return(true);
+}
+
+/**
+	Genere les rendus de l'element fantome : il s'agit d'un rectangle
+	representant grosso modo l'espace que devait prendre l'element initial.
+	En son centre est dessine un point d'interrogation. Une petite croix indique
+	le point de saisie de l'element.
+*/
+void GhostElement::generateDrawings() {
+	// style de dessin
+	QPen t(QBrush(Qt::black), 1.0);
+	
+	// rendu normal
+	QPainter qp;
+	qp.begin(&drawing);
+	qp.setPen(t);
+	qp.setRenderHint(QPainter::Antialiasing, false);
+	generateDrawing(&qp);
+	qp.end();
+	
+	// rendu low_zoom
+	QPainter low_zoom_qp;
+	low_zoom_qp.begin(&low_zoom_drawing);
+	t.setCosmetic(true);
+	low_zoom_qp.setRenderHint(QPainter::Antialiasing, false);
+	low_zoom_qp.setPen(t);
+	generateDrawing(&low_zoom_qp);
+	low_zoom_qp.end();
+}
+
+/**
+	Genere un rendu de l'element fantome
+	@see generateDrawings
+*/
+void GhostElement::generateDrawing(QPainter *painter) {
+	// une petite croix indique le point de saisie de l'element
+	painter -> drawLine(QLineF(-1.0, 0.0, 1.0, 0.0));
+	painter -> drawLine(QLineF(0.0, -1.0, 0.0, 1.0));
+	
+	// rectangle avec un point d'interrogation au centre
+	QRectF drawn_rect = boundingRect().adjusted(4.0, 4.0, -4.0, -4.0);
+	painter -> drawRect(drawn_rect);
+	painter -> drawText(drawn_rect, Qt::AlignHCenter | Qt::AlignVCenter, "?");
+}

Added: branches/devel/sources/qetgraphicsitem/ghostelement.h
===================================================================
--- branches/devel/sources/qetgraphicsitem/ghostelement.h	                        (rev 0)
+++ branches/devel/sources/qetgraphicsitem/ghostelement.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -0,0 +1,53 @@
+/*
+	Copyright 2006-2012 Xavier Guerrin
+	This file is part of QElectroTech.
+	
+	QElectroTech is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 2 of the License, or
+	(at your option) any later version.
+	
+	QElectroTech is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+	
+	You should have received a copy of the GNU General Public License
+	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef GHOST_ELEMENT_H
+#define GHOST_ELEMENT_H
+#include "customelement.h"
+class Diagram;
+class QGraphicsItem;
+class ElementsLocation;
+class Terminal;
+/**
+	The GhostElement class inherits CustomElement. A GhostElement aims at
+	visually replacing a CustomElement whose definition could not be loaded.
+	This way, instead of not loading an element, thus potentially losing its
+	position, its orientation, its child text items and conductors, one can
+	substitute a GhostElement. The GhostElement will extrapolate the position
+	of terminals and text items from the rest of the diagram. It is visually
+	rendered using a simple rectangle.
+*/
+class GhostElement : public CustomElement {
+	
+	Q_OBJECT
+	
+	// constructor, destructor
+	public:
+	GhostElement(const ElementsLocation &, QGraphicsItem * = 0, Diagram * = 0);
+	virtual ~GhostElement();
+	
+	// methods
+	public:
+	virtual bool fromXml(QDomElement &, QHash<int, Terminal *> &, bool = false);
+	
+	protected:
+	QRectF minimalBoundingRect() const;
+	bool terminalsFromXml(QDomElement &, QHash<int, Terminal *> &);
+	void generateDrawings();
+	void generateDrawing(QPainter *);
+};
+#endif

Added: branches/devel/sources/qetgraphicsitem/independenttextitem.cpp
===================================================================
--- branches/devel/sources/qetgraphicsitem/independenttextitem.cpp	                        (rev 0)
+++ branches/devel/sources/qetgraphicsitem/independenttextitem.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -0,0 +1,140 @@
+/*
+	Copyright 2006-2012 Xavier Guerrin
+	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 "independenttextitem.h"
+#include "diagram.h"
+
+/**
+	Constructeur
+	@param parent_diagram Le schema auquel est rattache le champ de texte
+*/
+IndependentTextItem::IndependentTextItem(Diagram *parent_diagram) :
+	DiagramTextItem(0, parent_diagram),
+	first_move_(true)
+{
+}
+
+/**
+	Constructeur
+	@param text Le texte affiche par le champ de texte
+	@param parent_diagram Le schema auquel est rattache le champ de texte
+*/
+IndependentTextItem::IndependentTextItem(const QString &text, Diagram *parent_diagram) :
+	DiagramTextItem(text, 0, parent_diagram),
+	first_move_(true)
+{
+}
+
+/// Destructeur
+IndependentTextItem::~IndependentTextItem() {
+}
+
+/**
+	Permet de lire le texte a mettre dans le champ a partir d'un element XML.
+	Cette methode se base sur la position du champ pour assigner ou non la
+	valeur a ce champ.
+	@param e L'element XML representant le champ de texte
+*/
+void IndependentTextItem::fromXml(const QDomElement &e) {
+	setPos(e.attribute("x").toDouble(), e.attribute("y").toDouble());
+	setHtml(e.attribute("text"));
+	setRotationAngle(e.attribute("rotation").toDouble());
+}
+
+/**
+	@param document Le document XML a utiliser
+	@return L'element XML representant ce champ de texte
+*/
+QDomElement IndependentTextItem::toXml(QDomDocument &document) const {
+	QDomElement result = document.createElement("input");
+	result.setAttribute("x", QString("%1").arg(pos().x()));
+	result.setAttribute("y", QString("%1").arg(pos().y()));
+	result.setAttribute("text", toHtml());
+	if (rotationAngle()) {
+		result.setAttribute("rotation", QString("%1").arg(rotationAngle()));
+	}
+	return(result);
+}
+
+/**
+	Gere le clic sur le champ de texte
+	@param e Objet decrivant l'evenement souris
+*/
+void IndependentTextItem::mousePressEvent(QGraphicsSceneMouseEvent *e) {
+	first_move_ = true;
+	if (e -> modifiers() & Qt::ControlModifier) {
+		setSelected(!isSelected());
+	}
+	DiagramTextItem::mousePressEvent(e);
+}
+
+/**
+	Gere les mouvements de souris lies au champ de texte
+	@param e Objet decrivant l'evenement souris
+*/
+void IndependentTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
+	if (textInteractionFlags() & Qt::TextEditable) {
+		DiagramTextItem::mouseMoveEvent(e);
+	} else if ((flags() & QGraphicsItem::ItemIsMovable) && isSelected() && (e -> buttons() & Qt::LeftButton)) {
+		// le champ de texte est en train d'etre deplace
+		Diagram *diagram_ptr = diagram();
+		if (diagram_ptr) {
+			if (first_move_) {
+				// il s'agit du premier mouvement du deplacement, on le signale
+				// au schema parent
+				diagram_ptr -> beginMoveElements(this);
+			}
+		}
+		
+		// on applique le mouvement impose par la souris
+		QPointF old_pos = pos();
+		if (first_move_) {
+			mouse_to_origin_movement_ = old_pos - e -> buttonDownScenePos(Qt::LeftButton);
+		}
+		QPointF expected_pos = e-> scenePos() + mouse_to_origin_movement_;
+		setPos(expected_pos); // setPos() will snap the expected position to the grid
+		
+		// on calcule le mouvement reellement applique par setPos()
+		QPointF effective_movement = pos() - old_pos;
+		if (diagram_ptr) {
+			// on signale le mouvement ainsi applique au schema parent, qui
+			// l'appliquera aux autres items selectionnes selon son bon vouloir
+			diagram_ptr -> continueMoveElements(effective_movement);
+		}
+	} else e -> ignore();
+	
+	if (first_move_) {
+		first_move_ = false;
+	}
+}
+
+/**
+	Gere le relachement de souris
+	Cette methode a ete reimplementee pour tenir a jour la liste des elements
+	et conducteurs a deplacer au niveau du schema.
+	@param e Objet decrivant l'evenement souris
+*/
+void IndependentTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
+	if (flags() & QGraphicsItem::ItemIsMovable) {
+		if (Diagram *diagram_ptr = diagram()) {
+			diagram_ptr -> endMoveElements();
+		}
+	}
+	if (!(e -> modifiers() & Qt::ControlModifier)) {
+		DiagramTextItem::mouseReleaseEvent(e);
+	}
+}

Added: branches/devel/sources/qetgraphicsitem/independenttextitem.h
===================================================================
--- branches/devel/sources/qetgraphicsitem/independenttextitem.h	                        (rev 0)
+++ branches/devel/sources/qetgraphicsitem/independenttextitem.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -0,0 +1,58 @@
+/*
+	Copyright 2006-2012 Xavier Guerrin
+	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 INDEPENDENT_TEXT_ITEM_H
+#define INDEPENDENT_TEXT_ITEM_H
+#include <QtGui>
+#include "diagramtextitem.h"
+/**
+	This class represents an independent text field on a particular diagram.
+	It may be moved, edited, and rotated.
+*/
+class IndependentTextItem : public DiagramTextItem {
+	Q_OBJECT
+	// constructors, destructor
+	public:
+	IndependentTextItem(Diagram * = 0);
+	IndependentTextItem(const QString &, Diagram* = 0);
+	virtual ~IndependentTextItem();
+	
+	// attributes
+	public:
+	enum { Type = UserType + 1005 };
+	
+	// methods
+	public:
+	/**
+		Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into an
+		IndependentTextItem.
+		@return le type de QGraphicsItem
+	*/
+	virtual int type() const { return Type; }
+	virtual void fromXml(const QDomElement &);
+	virtual QDomElement toXml(QDomDocument &) const;
+	
+	protected:
+	virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
+	virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
+	virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
+	
+	private:
+	bool first_move_;
+	QPointF mouse_to_origin_movement_;
+};
+#endif

Modified: branches/devel/sources/qetgraphicsitem/qetgraphicsitem.cpp
===================================================================
--- branches/devel/sources/qetgraphicsitem/qetgraphicsitem.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/qetgraphicsitem/qetgraphicsitem.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -23,15 +23,17 @@
  * @param diagram, diagram aka QGraphicsScene of the item
  * @param parent, Parent Item
  */
-QetGraphicsItem::QetGraphicsItem(QetGraphicsItem *parent):
+QetGraphicsItem::QetGraphicsItem(QGraphicsItem *parent):
 	QGraphicsObject(parent),
-	first_move_(false)
+	first_move_(true)
 {
 }
 
 QetGraphicsItem::~QetGraphicsItem()
 {}
 
+void QetGraphicsItem::editProperty(){}
+
 /**
  * @brief QetGraphicsItem::diagram
  *return the diagram of this item
@@ -67,6 +69,37 @@
 }
 
 /**
+	Permet de tourner l'item a un angle donne de maniere absolue.
+	Un angle de 0 degres correspond a un image horizontal non retourne.
+	@param rotation Nouvel angle de rotation de ce image
+	@see applyRotation
+*/
+void QetGraphicsItem::setRotationAngle(const qreal &rotation_angle) {
+	qreal applied_rotation = QET::correctAngle(rotation_angle);
+	applyRotation(applied_rotation - rotation());
+}
+
+/**
+	Permet de tourner l'item de maniere relative.
+	L'angle added_rotation est ajoute a l'orientation actuelle du image.
+	@param added_rotation Angle a ajouter a la rotation actuelle
+	@see applyRotation
+*/
+void QetGraphicsItem::rotateBy(const qreal &added_rotation) {
+	qreal applied_added_rotation = QET::correctAngle(added_rotation);
+	applyRotation(applied_added_rotation);
+}
+
+/**
+	Effectue la rotation de l'item en lui même
+	Cette methode peut toutefois etre redefinie dans des classes filles
+	@param angle Angle de la rotation a effectuer
+*/
+void QetGraphicsItem::applyRotation(const qreal &angle) {
+	setRotation(QET::correctAngle(rotation() + angle));
+}
+
+/**
  * @brief QetGraphicsItem::mousePressEvent
  *handle the mouse click
  * @param e

Modified: branches/devel/sources/qetgraphicsitem/qetgraphicsitem.h
===================================================================
--- branches/devel/sources/qetgraphicsitem/qetgraphicsitem.h	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/qetgraphicsitem/qetgraphicsitem.h	2013-11-07 09:18:03 UTC (rev 2596)
@@ -25,18 +25,18 @@
 
 	public:
 	//constructor destructor
-	QetGraphicsItem(QetGraphicsItem *parent = 0);
-	virtual ~QetGraphicsItem();
+	QetGraphicsItem(QGraphicsItem *parent = 0);
+	virtual ~QetGraphicsItem() = 0;
 
 	//abstarct methode	
-	virtual bool fromXml(const QDomElement &document) = 0;
-	virtual QDomElement toXml(QDomDocument &document) const = 0;
-	virtual void editProperty () = 0;
+	virtual void editProperty ();
 
 	//public methode
 	Diagram* diagram() const;
 	virtual void setPos(const QPointF &p);
 	virtual void setPos(qreal x, qreal y);
+	void setRotationAngle(const qreal &);
+	void rotateBy(const qreal &);
 
 	signals:
 
@@ -44,6 +44,7 @@
 
 	//protected method
 	protected:
+	void applyRotation(const qreal &);
 	virtual void mousePressEvent(QGraphicsSceneMouseEvent *e);
 	virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *e);
 	virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *e);

Modified: branches/devel/sources/terminal.cpp
===================================================================
--- branches/devel/sources/terminal.cpp	2013-11-06 18:44:39 UTC (rev 2595)
+++ branches/devel/sources/terminal.cpp	2013-11-07 09:18:03 UTC (rev 2596)
@@ -17,8 +17,8 @@
 */
 #include "terminal.h"
 #include "diagram.h"
-#include "element.h"
-#include "conductor.h"
+#include "qetgraphicsitem/element.h"
+#include "qetgraphicsitem/conductor.h"
 #include "diagramcommands.h"
 #include "qetapp.h"
 

--Ofro6XGXHTz--



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