[qet] [2449] Merge branch 0.4 import image to trunk

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


Revision: 2449
Author:   scorpio810
Date:     2013-08-24 17:18:45 +0200 (Sat, 24 Aug 2013)
Log Message:
-----------
Merge branch 0.4 import image to trunk

Modified Paths:
--------------
    trunk/sources/conductor.cpp
    trunk/sources/diagram.cpp
    trunk/sources/diagram.h
    trunk/sources/diagramcommands.cpp
    trunk/sources/diagramcommands.h
    trunk/sources/diagramcontent.cpp
    trunk/sources/diagramcontent.h
    trunk/sources/diagramtextitem.cpp
    trunk/sources/diagramview.cpp
    trunk/sources/diagramview.h
    trunk/sources/elementsmover.cpp
    trunk/sources/qet.cpp
    trunk/sources/qet.h
    trunk/sources/qetdiagrameditor.cpp
    trunk/sources/qetdiagrameditor.h
    trunk/sources/qeticons.cpp
    trunk/sources/qeticons.h
    trunk/sources/qgimanager.cpp

Added Paths:
-----------
    trunk/sources/diagramimageitem.cpp
    trunk/sources/diagramimageitem.h

Modified: trunk/sources/conductor.cpp
===================================================================
--- trunk/sources/conductor.cpp	2013-08-24 12:45:21 UTC (rev 2448)
+++ trunk/sources/conductor.cpp	2013-08-24 15:18:45 UTC (rev 2449)
@@ -46,12 +46,15 @@
 	segments(NULL),
 	moving_point(false),
 	moving_segment(false),
-	previous_z_value(zValue()),
 	modified_path(false),
 	has_to_save_profile(false),
 	segments_squares_scale_(1.0),
 	must_highlight_(Conductor::None)
 {
+	//set Zvalue at 10 to be upper than the DiagramImageItem
+	setZValue(10);
+	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);

Modified: trunk/sources/diagram.cpp
===================================================================
--- trunk/sources/diagram.cpp	2013-08-24 12:45:21 UTC (rev 2448)
+++ trunk/sources/diagram.cpp	2013-08-24 15:18:45 UTC (rev 2449)
@@ -30,6 +30,7 @@
 #include "ghostelement.h"
 #include "independenttextitem.h"
 #include "qetapp.h"
+#include "diagramimageitem.h"
 
 const int   Diagram::xGrid  = 10;
 const int   Diagram::yGrid  = 10;
@@ -334,6 +335,7 @@
 	QList<Element *> list_elements;
 	QList<Conductor *> list_conductors;
 	QList<DiagramTextItem *> list_texts;
+	QList<DiagramImageItem *> list_images;
 	
 	// Determine les elements a "XMLiser"
 	foreach(QGraphicsItem *qgi, items()) {
@@ -350,6 +352,9 @@
 		} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(qgi)) {
 			if (whole_content) list_texts << iti;
 			else if (iti -> isSelected()) list_texts << iti;
+		} else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(qgi)) {
+			if (whole_content) list_images << dii;
+			else if (dii -> isSelected()) list_images << dii;
 		}
 	}
 	
@@ -382,6 +387,15 @@
 		}
 		racine.appendChild(inputs);
 	}
+
+	// save of images
+	if (!list_images.isEmpty()) {
+		QDomElement images = document.createElement("images");
+		foreach (DiagramImageItem *dii, list_images) {
+			images.appendChild(dii -> toXml(document));
+		}
+		racine.appendChild(images);
+	}
 	
 	// on retourne le document XML ainsi genere
 	return(document);
@@ -536,6 +550,14 @@
 		addIndependentTextItem(iti);
 		added_texts << iti;
 	}
+
+	QList<DiagramImageItem *> added_images;
+	foreach (QDomElement image_xml, QET::findInDomElement(root, "images", "image")) {
+		DiagramImageItem *dii = new DiagramImageItem (this);
+		dii -> fromXml(image_xml);
+		addItem(dii);
+		added_images << dii;
+	}
 	
 	// gere la translation des nouveaux elements et texte si celle-ci est demandee
 	if (position != QPointF()) {
@@ -545,6 +567,7 @@
 		QList<QGraphicsItem *> added_items;
 		foreach (Element *added_element, added_elements) added_items << added_element;
 		foreach (DiagramTextItem *added_text, added_texts) added_items << added_text;
+		foreach (DiagramImageItem *added_image, added_images) added_items << added_image;
 		foreach (QGraphicsItem *item, added_items) {
 			QPointF csg = item -> mapToScene(item -> boundingRect()).boundingRect().topLeft();
 			qreal px = csg.x();
@@ -566,6 +589,9 @@
 		foreach (DiagramTextItem *added_text, added_texts) {
 			added_text -> setPos(added_text -> pos().x() + diff_x, added_text -> pos().y() + diff_y);
 		}
+		foreach (DiagramImageItem *added_image, added_images) {
+			added_image -> setPos(added_image -> pos().x() + diff_x, added_image -> pos().y() + diff_y);
+		}
 	}
 	
 	// chargement de tous les Conducteurs du fichier XML
@@ -601,6 +627,7 @@
 		content_ptr -> elements         = added_elements.toSet();
 		content_ptr -> conductorsToMove = added_conductors.toSet();
 		content_ptr -> textFields       = added_texts.toSet();
+		content_ptr -> images			= added_images.toSet();
 	}
 	
 	return(true);
@@ -707,6 +734,15 @@
 	);
 }
 
+void Diagram::addDiagramImageItem(DiagramImageItem *dii) {
+	if (!dii || isReadOnly()) return;
+
+	//add image at diagram
+	if (dii -> scene() != this) {
+		addItem(dii);
+	}
+}
+
 /**
 	Enleve un element du schema
 	@param element Element a enlever
@@ -1183,6 +1219,8 @@
 			) {
 				dc.otherConductors << c;
 			}
+		} else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(item)) {
+			dc.images << dii;
 		}
 	}
 	
@@ -1227,6 +1265,8 @@
 			if (e -> orientation().current() != e -> orientation().next()) {
 				return(true);
 			}
+		} else if (qgraphicsitem_cast<DiagramImageItem *>(qgi)) {
+			return (true);
 		}
 	}
 	return(false);

Modified: trunk/sources/diagram.h
===================================================================
--- trunk/sources/diagram.h	2013-08-24 12:45:21 UTC (rev 2448)
+++ trunk/sources/diagram.h	2013-08-24 15:18:45 UTC (rev 2449)
@@ -40,6 +40,7 @@
 class QETProject;
 class Terminal;
 class ConductorTextItem;
+class DiagramImageItem;
 /**
 	This class represents an electric diagram. It manages its various child
 	elements, conductors and texts and handles their graphic rendering.
@@ -134,6 +135,7 @@
 	void addElement(Element *);
 	void addConductor(Conductor *);
 	void addIndependentTextItem(IndependentTextItem *);
+	void addDiagramImageItem(DiagramImageItem *);
 	
 	void removeElement(Element *);
 	void removeConductor(Conductor *);

Modified: trunk/sources/diagramcommands.cpp
===================================================================
--- trunk/sources/diagramcommands.cpp	2013-08-24 12:45:21 UTC (rev 2448)
+++ trunk/sources/diagramcommands.cpp	2013-08-24 15:18:45 UTC (rev 2449)
@@ -25,6 +25,7 @@
 #include "qgimanager.h"
 #include "diagram.h"
 #include "diagramtextitem.h"
+#include "diagramimageitem.h"
 
 /**
 	Constructeur
@@ -98,6 +99,38 @@
 
 /**
 	Constructeur
+	@param dia Schema auquel on ajoute une image
+	@param image Image ajoute
+	@param pos Position a laquelle l'image est ajoute
+	@param parent QUndoCommand parent
+ */
+AddImageCommand::AddImageCommand(Diagram *dia, DiagramImageItem *image, const QPointF &pos, QUndoCommand *parent):
+	QUndoCommand(QObject::tr("Ajouter une image", "undo caption"), parent),
+	imageitem(image),
+	diagram(dia),
+	position(pos)
+{
+	diagram -> qgiManager().manage(imageitem);
+}
+
+///Destructor
+AddImageCommand::~AddImageCommand() {
+	diagram -> qgiManager().release(imageitem);
+}
+
+///Annule l'ajout
+void AddImageCommand::undo() {
+	diagram -> removeItem(imageitem);
+}
+
+///Refait l'ajout
+void AddImageCommand::redo() {
+	diagram -> addDiagramImageItem(imageitem);
+	imageitem -> setPos(position - imageitem -> boundingRect().center());
+}
+
+/**
+	Constructeur
 	@param d Schema auquel on ajoute un conducteur
 	@param c Conducteur ajoute
 	@param parent QUndoCommand parent
@@ -176,6 +209,10 @@
 	foreach(IndependentTextItem *t, removed_content.textFields) {
 		diagram -> addIndependentTextItem(t);
 	}
+
+	foreach(DiagramImageItem *dii, removed_content.images) {
+		diagram -> addItem(dii);
+	}
 }
 
 /// refait les suppressions
@@ -194,6 +231,11 @@
 	foreach(IndependentTextItem *t, removed_content.textFields) {
 		diagram -> removeIndependentTextItem(t);
 	}
+
+	//enleve les images
+	foreach(DiagramImageItem *dii, removed_content.images) {
+		diagram -> removeItem(dii);
+	}
 }
 
 /**
@@ -310,7 +352,8 @@
 		DiagramContent::Elements |
 		DiagramContent::TextFields |
 		DiagramContent::ConductorsToUpdate |
-		DiagramContent::ConductorsToMove
+		DiagramContent::ConductorsToMove |
+		DiagramContent::Images
 	);
 	
 	setText(
@@ -371,6 +414,11 @@
 	foreach(DiagramTextItem *text, content_to_move.textFields) {
 		text -> setPos(text -> pos() + actual_movement);
 	}
+
+	// deplace les images
+	foreach (DiagramImageItem *dii, content_to_move.images) {
+		dii -> setPos(dii -> pos() + actual_movement);
+	}
 }
 
 /**
@@ -575,10 +623,11 @@
 	@param texts Textes a pivoter
 	@param parent QUndoCommand parent
 */
-RotateElementsCommand::RotateElementsCommand(const QHash<Element *, QET::Orientation> &elements, const QList<DiagramTextItem *> &texts, QUndoCommand *parent) :
+RotateElementsCommand::RotateElementsCommand(const QHash<Element *, QET::Orientation> &elements, const QList<DiagramTextItem *> &texts, const QList<DiagramImageItem *> &images, QUndoCommand *parent) :
 	QUndoCommand(parent),
 	elements_to_rotate(elements),
 	texts_to_rotate(texts),
+	images_to_rotate(images),
 	applied_rotation_angle_(-90.0)
 {
 	setText(
@@ -587,7 +636,7 @@
 				"pivoter %1",
 				"undo caption - %1 is a sentence listing the rotated content"
 			)
-		).arg(QET::ElementsAndConductorsSentence(elements.count(), 0, texts.count()))
+		).arg(QET::ElementsAndConductorsSentence(elements.count(), 0, texts.count(), images.count()))
 	);
 }
 
@@ -609,6 +658,7 @@
 		}
 		else {dti -> rotateBy(-applied_rotation_angle_);}
 	}
+	foreach(DiagramImageItem *dii, images_to_rotate) dii -> rotateBy(-applied_rotation_angle_);
 }
 
 /// refait le pivotement
@@ -624,6 +674,7 @@
 		}
 		dti -> rotateBy(applied_rotation_angle_);
 	}
+	foreach(DiagramImageItem *dii, images_to_rotate) dii -> rotateBy(applied_rotation_angle_);
 }
 
 /**

Modified: trunk/sources/diagramcommands.h
===================================================================
--- trunk/sources/diagramcommands.h	2013-08-24 12:45:21 UTC (rev 2448)
+++ trunk/sources/diagramcommands.h	2013-08-24 15:18:45 UTC (rev 2449)
@@ -29,6 +29,7 @@
 class Element;
 class ElementTextItem;
 class IndependentTextItem;
+class DiagramImageItem;
 
 /**
 	This command adds an element to a particular diagram.
@@ -84,6 +85,33 @@
 };
 
 /**
+  This command adds an image item to a particular diagram
+*/
+class AddImageCommand : public QUndoCommand {
+	//constructors, destructor
+	public:
+	AddImageCommand (Diagram *, DiagramImageItem *, const QPointF &, QUndoCommand * = 0);
+	virtual ~AddImageCommand();
+	private:
+	AddImageCommand(const AddImageCommand &);
+
+	//methods
+	public:
+	virtual void undo();
+	virtual void redo();
+
+	// attributes
+	private:
+	/// added image item
+	DiagramImageItem *imageitem;
+	/// diagram the image item is added to
+	Diagram *diagram;
+	/// position of the image item on the diagram
+	QPointF position;
+
+};
+
+/**
 	This command adds a conductor to a particular diagram.
 */
 class AddConductorCommand : public QUndoCommand {
@@ -302,7 +330,7 @@
 class RotateElementsCommand : public QUndoCommand {
 	// constructors, destructor
 	public:
-	RotateElementsCommand(const QHash<Element *, QET::Orientation> &elements, const QList<DiagramTextItem *> &, QUndoCommand * = 0);
+	RotateElementsCommand(const QHash<Element *, QET::Orientation> &elements, const QList<DiagramTextItem *> &, const QList<DiagramImageItem *> &, QUndoCommand * = 0);
 	virtual ~RotateElementsCommand();
 	private:
 	RotateElementsCommand(const RotateElementsCommand &);
@@ -321,6 +349,8 @@
 	QHash<Element *, QET::Orientation> elements_to_rotate;
 	/// text items to be rotated
 	QList<DiagramTextItem *> texts_to_rotate;
+	/// images item to be rotated
+	QList<DiagramImageItem *> images_to_rotate;
 	/// angle of rotation to be applied to text items
 	qreal applied_rotation_angle_;
 	/// previous state of each conductor text item

Modified: trunk/sources/diagramcontent.cpp
===================================================================
--- trunk/sources/diagramcontent.cpp	2013-08-24 12:45:21 UTC (rev 2448)
+++ trunk/sources/diagramcontent.cpp	2013-08-24 15:18:45 UTC (rev 2449)
@@ -20,6 +20,7 @@
 #include "element.h"
 #include "independenttextitem.h"
 #include "conductor.h"
+#include "diagramimageitem.h"
 
 /**
 	Constructeur par defaut. Ne contient rien.
@@ -33,6 +34,7 @@
 DiagramContent::DiagramContent(const DiagramContent &other) :
 	elements(other.elements),
 	textFields(other.textFields),
+	images(other.images),
 	conductorsToUpdate(other.conductorsToUpdate),
 	conductorsToMove(other.conductorsToMove),
 	otherConductors(other.otherConductors)
@@ -68,6 +70,7 @@
 void DiagramContent::clear() {
 	elements.clear();
 	textFields.clear();
+	images.clear();
 	conductorsToUpdate.clear();
 	conductorsToMove.clear();
 	otherConductors.clear();
@@ -82,6 +85,7 @@
 	foreach(QGraphicsItem *qgi, conductors(filter)) items_list << qgi;
 	if (filter & Elements)   foreach(QGraphicsItem *qgi, elements)   items_list << qgi;
 	if (filter & TextFields) foreach(QGraphicsItem *qgi, textFields)  items_list << qgi;
+	if (filter & Images) foreach(QGraphicsItem *qgi, images) items_list << qgi;
 	if (filter & SelectedOnly) {
 		foreach(QGraphicsItem *qgi, items_list) {
 			if (!qgi -> isSelected()) items_list.removeOne(qgi);
@@ -99,12 +103,14 @@
 	if (filter & SelectedOnly) {
 		if (filter & Elements)           foreach(Element *element,     elements)                  { if (element   -> isSelected()) ++ count; }
 		if (filter & TextFields)         foreach(DiagramTextItem *dti, textFields)                { if (dti       -> isSelected()) ++ count; }
+		if (filter & Images)			 foreach(DiagramImageItem *dii, images)					  { if (dii		  -> isSelected()) ++ count; }
 		if (filter & ConductorsToMove)   foreach(Conductor *conductor, conductorsToMove)          { if (conductor -> isSelected()) ++ count; }
 		if (filter & ConductorsToUpdate) foreach(Conductor *conductor, conductorsToUpdate)        { if (conductor -> isSelected()) ++ count; }
 		if (filter & OtherConductors)    foreach(Conductor *conductor, otherConductors)           { if (conductor -> isSelected()) ++ count; }
 	} else {
 		if (filter & Elements)           count += elements.count();
 		if (filter & TextFields)         count += textFields.count();
+		if (filter & Images)			 count += images.count();
 		if (filter & ConductorsToMove)   count += conductorsToMove.count();
 		if (filter & ConductorsToUpdate) count += conductorsToUpdate.count();
 		if (filter & OtherConductors)    count += otherConductors.count();
@@ -122,12 +128,14 @@
 	int elements_count   = (filter & Elements) ? elements.count() : 0;
 	int conductors_count = conductors(filter).count();
 	int textfields_count = (filter & TextFields) ? textFields.count() : 0;
+	int images_count	 = (filter & Images) ? images.count() : 0;
 	
 	return(
 		QET::ElementsAndConductorsSentence(
 			elements_count,
 			conductors_count,
-			textfields_count
+			textfields_count,
+			images_count
 		)
 	);
 }

Modified: trunk/sources/diagramcontent.h
===================================================================
--- trunk/sources/diagramcontent.h	2013-08-24 12:45:21 UTC (rev 2448)
+++ trunk/sources/diagramcontent.h	2013-08-24 15:18:45 UTC (rev 2449)
@@ -21,6 +21,7 @@
 class Conductor;
 class Element;
 class IndependentTextItem;
+class DiagramImageItem;
 /**
 	This class provides a container that makes the transmission of diagram content
 	to other functions/methods easier. The different kind of items are made
@@ -40,6 +41,7 @@
 	enum Filter {
 		Elements = 1,
 		TextFields = 2,
+		Images = 3,
 		ConductorsToMove = 4,
 		ConductorsToUpdate = 8,
 		OtherConductors = 16,
@@ -52,6 +54,8 @@
 	QSet<Element *> elements;
 	/// Hold independent text items
 	QSet<IndependentTextItem *> textFields;
+	/// Hold image
+	QSet<DiagramImageItem *> images;
 	/// Hold conductors that would get updated considering electrical elements are moved
 	QSet<Conductor *> conductorsToUpdate;
 	/// Hold conductors that would be moved as is considering electrical elements are moved

Added: trunk/sources/diagramimageitem.cpp
===================================================================
--- trunk/sources/diagramimageitem.cpp	                        (rev 0)
+++ trunk/sources/diagramimageitem.cpp	2013-08-24 15:18:45 UTC (rev 2449)
@@ -0,0 +1,381 @@
+/*
+	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 "diagramimageitem.h"
+#include "diagramcommands.h"
+#include "qet.h"
+#include "qetapp.h"
+
+DiagramImageItem::DiagramImageItem(Diagram *parent_diagram) :
+	QGraphicsPixmapItem(0, parent_diagram)
+{
+	setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
+#if QT_VERSION >= 0x040600
+	setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
+#endif
+	//connect(this, SIGNAL(lostFocus()), this, SLOT(setNonFocusable()));
+}
+
+/**
+ * @brief DiagramImageItem::DiagramImageItem
+ * @param parent
+ * @param parent_diagram
+ */
+DiagramImageItem::DiagramImageItem(const QPixmap &pixmap, Diagram *parent_diagram) :
+	QGraphicsPixmapItem(pixmap, 0, parent_diagram),
+	first_move_(false)
+{
+	setCursor(Qt::PointingHandCursor);
+	setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
+#if QT_VERSION >= 0x040600
+	setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
+#endif
+	//connect(this, SIGNAL(lostFocus()), this, SLOT(setNonFocusable()));
+}
+
+/// Destructeur
+DiagramImageItem::~DiagramImageItem() {
+}
+
+/**
+	@return le Diagram auquel ce image appartient, ou 0 si ce image n'est
+	rattache a aucun schema
+*/
+Diagram *DiagramImageItem::diagram() const {
+	return(qobject_cast<Diagram *>(scene()));
+}
+
+/**
+	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);
+}
+
+/**
+	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 DiagramImageItem::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 DiagramImageItem::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 DiagramImageItem::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 DiagramImageItem::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 image.
+	Cette methode delegue simplement le travail a QGraphicsPixmapItem::paint apres
+	avoir desactive l'antialiasing.
+	@param painter Le QPainter a utiliser pour dessiner le champ de image
+	@param option Les options de style pour le champ de image
+	@param widget Le QWidget sur lequel on dessine 
+*/
+void DiagramImageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
+	painter -> setRenderHint(QPainter::Antialiasing, false);
+	QGraphicsPixmapItem::paint(painter, option, widget);
+}
+
+/**
+	Gere la prise de focus du champ de image
+	@param e Objet decrivant la prise de focus
+*/
+void DiagramImageItem::focusInEvent(QFocusEvent *e) {
+	QGraphicsPixmapItem::focusInEvent(e);
+	
+	// empeche le deplacement du image pendant son edition
+	setFlag(QGraphicsItem::ItemIsMovable, false);
+}
+
+/**
+	Gere la perte de focus du champ de image
+	@param e Objet decrivant la perte de focus
+*/
+void DiagramImageItem::focusOutEvent(QFocusEvent *e) {
+	QGraphicsPixmapItem::focusOutEvent(e);
+	
+	/*// deselectionne le image
+	QTextCursor cursor = textCursor();
+	cursor.clearSelection();
+	setTextCursor(cursor);
+	
+	// hack a la con pour etre re-entrant
+	setTextInteractionFlags(Qt::NoTextInteraction);
+	
+	// autorise de nouveau le deplacement du image
+	setFlag(QGraphicsItem::ItemIsMovable, true);
+	QTimer::singleShot(0, this, SIGNAL(lostFocus()));*/
+}
+
+/**
+	Gere le clic sur le champ de texte
+	@param e Objet decrivant l'evenement souris
+*/
+void DiagramImageItem::mousePressEvent(QGraphicsSceneMouseEvent *e) {
+	first_move_ = true;
+	if (e -> modifiers() & Qt::ControlModifier) {
+		setSelected(!isSelected());
+	}
+	QGraphicsItem::mousePressEvent(e);
+}
+
+/**
+	Gere les double-clics sur ce champ de image.
+	@param event un QGraphicsSceneMouseEvent decrivant le double-clic
+*/
+void DiagramImageItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) {
+	/*if (!(textInteractionFlags() & Qt::imageditable)) {
+		// rend le champ de image editable
+		setTextInteractionFlags(Qt::imageditorInteraction);
+		
+		// edite le champ de image
+		setFocus(Qt::MouseFocusReason);
+	} else {
+		QGraphicsPixmapItem::mouseDoubleClickEvent(event);
+	}*/
+}
+
+/**
+ * @brief DiagramImageItem::mouseMoveEvent
+ * Gere les mouvements de souris lies a l'image
+ * @param e Objet decrivant l'evenement souris
+ */
+void DiagramImageItem::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
+	if (isSelected() && e -> buttons() & Qt::LeftButton) {
+		//Image is moving
+		if(diagram()) {
+			if (first_move_) {
+				//It's the first movement, we signal it to parent diagram
+				diagram() -> beginMoveElements(this);
+			}
+		}
+
+		//we apply the mouse movement
+		QPointF old_pos = pos();
+		setPos(mapToParent(e -> pos()) - matrix().map(e -> buttonDownPos(Qt::LeftButton)));
+		//we calcul the real movement apply by setPos()
+		QPointF effective_movement = pos() - old_pos;
+
+		if (diagram()) {
+			//we signal the real movement apply to diagram,
+			//who he apply to other selected item
+			diagram() -> continueMoveElements(effective_movement);
+		}
+	} else e -> ignore();
+
+	if (first_move_) first_move_ = false;
+}
+
+/**
+ * @brief DiagramImageItem::mouseReleaseEvent
+ * 	Gere le relachement de souris
+ *  Cette methode a ete reimplementee pour tenir a jour la liste
+ *  des images à deplacer au niveau du schema.
+ * @param e Objet decrivant l'evenement souris
+ */
+void DiagramImageItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
+	if (diagram()) {
+		diagram() -> endMoveElements();
+	}
+	if (!(e -> modifiers() & Qt::ControlModifier)) {
+		QGraphicsItem::mouseReleaseEvent(e);
+	}
+}
+
+/**
+	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) {
+	// un simple appel a QGraphicsPixmapItem::setRotation suffit
+	setTransformOriginPoint(boundingRect().center());
+	QGraphicsPixmapItem::setRotation(QGraphicsPixmapItem::rotation() + angle);
+}
+
+/**
+	Change la position du champ de image en veillant a ce qu'il
+	reste sur la grille du schema auquel il appartient.
+	@param p Nouvelles coordonnees de l'element
+*/
+void DiagramImageItem::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;
+		QGraphicsPixmapItem::setPos(p_x, p_y);
+	} else QGraphicsPixmapItem::setPos(p);
+}
+
+/**
+	Change la position du champ de image 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 DiagramImageItem::setPos(qreal x, qreal y) {
+	setPos(QPointF(x, y));
+}
+
+/**
+	@return la position du champ de image
+*/
+QPointF DiagramImageItem::pos() const {
+	return(QGraphicsPixmapItem::pos());
+}
+
+/// Rend le champ de image non focusable
+void DiagramImageItem::setNonFocusable() {
+	setFlag(QGraphicsPixmapItem::ItemIsFocusable, false);
+}
+
+/**
+ * @brief Edit the image with ....
+ */
+void DiagramImageItem::edit() {
+	// waiting
+}
+
+/**
+	Load the image from this xml element
+	@param e xml element that define an image
+*/
+bool DiagramImageItem::fromXml(const QDomElement &e) {
+	if (e.tagName() != "image") return (false);
+	QDomNode image_node = e.firstChild();
+	if (!image_node.isText()) return (false);
+
+	//load xml text image to QByteArray
+	QByteArray array;
+	array = QByteArray::fromBase64(e.text().toAscii());
+
+	//Set QPixmap from the @array
+	QPixmap pixmap;
+	pixmap.loadFromData(array);
+	setPixmap(pixmap);
+
+	setPos(e.attribute("x").toDouble(), e.attribute("y").toDouble());
+	if (e.hasAttribute("rotation")) setRotationAngle(e.attribute("rotation").toDouble());
+
+	return (true);
+}
+
+/**
+	@param document Le document XML a utiliser
+	@return L'element XML representant ce champ de texte
+*/
+QDomElement DiagramImageItem::toXml(QDomDocument &document) const {
+	QDomElement result = document.createElement("image");
+	//write some attribute
+	result.setAttribute("x", QString("%1").arg(pos().x()));
+	result.setAttribute("y", QString("%1").arg(pos().y()));
+	if (rotation()) result.setAttribute("rotation", QString("%1").arg(rotation()));
+
+	//write the pixmap in the xml element after he was been transformed to base64
+	QByteArray array;
+	QBuffer buffer(&array);
+	buffer.open(QIODevice::ReadWrite);
+	pixmap().save(&buffer, "PNG");
+	QDomText base64 = document.createTextNode(array.toBase64());
+	result.appendChild(base64);
+
+	return(result);
+}

Added: trunk/sources/diagramimageitem.h
===================================================================
--- trunk/sources/diagramimageitem.h	                        (rev 0)
+++ trunk/sources/diagramimageitem.h	2013-08-24 15:18:45 UTC (rev 2449)
@@ -0,0 +1,85 @@
+/*
+	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/>.
+*/
+#ifndef DIAGRAM_IMAGE_ITEM_H
+#define DIAGRAM_IMAGE_ITEM_H
+#include <QtGui>
+#include "diagram.h"
+/**
+	This class represents a selectable, movable and editable image on a
+	diagram.
+	@see QGraphicsItem::GraphicsItemFlags
+*/
+class DiagramImageItem : public QObject, public QGraphicsPixmapItem {
+	Q_OBJECT
+	// constructors, destructor
+	public:
+	DiagramImageItem(Diagram * = 0);
+	DiagramImageItem(const QPixmap &, Diagram * = 0);
+	virtual ~DiagramImageItem();
+	
+	// attributes
+	public:
+	enum { Type = UserType + 1007 };
+	
+	// methods
+	public:
+	/**
+		Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into a
+		DiagramImageItem
+		@return the QGraphicsItem type
+	*/
+	virtual int type() const { return Type; }
+	Diagram *diagram() const;
+	
+	virtual bool fromXml(const QDomElement &);
+	virtual QDomElement toXml(QDomDocument &) const;
+	
+	virtual void setPos(const QPointF &);
+	virtual void setPos(qreal, qreal);
+	virtual QPointF pos() 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:
+	void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+	void focusInEvent(QFocusEvent *);
+	void focusOutEvent(QFocusEvent *);
+	void mousePressEvent(QGraphicsSceneMouseEvent *e);
+	void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *);
+	void mouseMoveEvent(QGraphicsSceneMouseEvent *);
+	void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
+	void applyRotation(const qreal &);
+	
+	signals:
+	/// signal emitted when the image field loses focus
+	void lostFocus();
+	/// signal emitted after image was changed
+	void diagramImageChanged(DiagramImageItem *, const QString &, const QString &);
+	
+	public slots:
+	void setNonFocusable();
+	
+	private:
+	bool first_move_;
+};
+#endif

Modified: trunk/sources/diagramtextitem.cpp
===================================================================
--- trunk/sources/diagramtextitem.cpp	2013-08-24 12:45:21 UTC (rev 2448)
+++ trunk/sources/diagramtextitem.cpp	2013-08-24 15:18:45 UTC (rev 2449)
@@ -32,6 +32,8 @@
 	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);
@@ -52,6 +54,8 @@
 	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);

Modified: trunk/sources/diagramview.cpp
===================================================================
--- trunk/sources/diagramview.cpp	2013-08-24 12:45:21 UTC (rev 2448)
+++ trunk/sources/diagramview.cpp	2013-08-24 15:18:45 UTC (rev 2449)
@@ -26,6 +26,7 @@
 #include "conductortextitem.h"
 #include "elementtextitem.h"
 #include "independenttextitem.h"
+#include "diagramimageitem.h"
 #include "titleblockpropertieswidget.h"
 #include "templatelocation.h"
 #include "qetapp.h"
@@ -37,17 +38,22 @@
 #include "qeticons.h"
 #include "qetmessagebox.h"
 #include "qtextorientationspinboxwidget.h"
+#include <QGraphicsObject>
 
+#include <QGraphicsPixmapItem>
+#include <QGraphicsSceneMouseEvent>
 
+
 /**
 	Constructeur
 	@param diagram Schema a afficher ; si diagram vaut 0, un nouveau Diagram est utilise
 	@param parent Le QWidget parent de cette vue de schema
 */
-DiagramView::DiagramView(Diagram *diagram, QWidget *parent) : QGraphicsView(parent), is_adding_text(false), is_moving_view_(false) {
+DiagramView::DiagramView(Diagram *diagram, QWidget *parent) : QGraphicsView(parent) {
 	setAttribute(Qt::WA_DeleteOnClose, true);
 	setInteractive(true);
-	
+	current_behavior = noAction;
+
 	QString whatsthis = tr(
 		"Ceci est la zone dans laquelle vous concevez vos sch\351mas en y ajoutant"
 		" des \351l\351ments et en posant des conducteurs entre leurs bornes. Il est"
@@ -140,6 +146,7 @@
 	// recupere les elements et les champs de texte a pivoter
 	QHash<Element *, QET::Orientation> elements_to_rotate;
 	QList<DiagramTextItem *> texts_to_rotate;
+	QList<DiagramImageItem *> images_to_rotate;
 	foreach (QGraphicsItem *item, scene -> selectedItems()) {
 		if (Element *e = qgraphicsitem_cast<Element *>(item)) {
 			elements_to_rotate.insert(e, e -> orientation().current());
@@ -152,12 +159,14 @@
 			if (eti -> parentItem() && !eti -> parentItem() -> isSelected()) {
 				texts_to_rotate << eti;
 			}
+		} else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(item)) {
+			images_to_rotate << dii;
 		}
 	}
 	
 	// effectue les rotations s'il y a quelque chose a pivoter
-	if (elements_to_rotate.isEmpty() && texts_to_rotate.isEmpty()) return;
-	scene -> undoStack().push(new RotateElementsCommand(elements_to_rotate, texts_to_rotate));
+	if (elements_to_rotate.isEmpty() && texts_to_rotate.isEmpty() && images_to_rotate.isEmpty()) return;
+	scene -> undoStack().push(new RotateElementsCommand(elements_to_rotate, texts_to_rotate, images_to_rotate));
 }
 
 void DiagramView::rotateTexts() {
@@ -417,11 +426,16 @@
 		switchToVisualisationModeIfNeeded(e);
 		fresh_focus_in_ = false;
 	}
-	if (isInteractive() && !scene -> isReadOnly()) {
-		if (is_adding_text && e -> buttons() == Qt::LeftButton) {
-			addDiagramTextAtPos(mapToScene(e -> pos()));
-			is_adding_text = false;
+	if (isInteractive() && !scene -> isReadOnly() && current_behavior > noAction && e -> buttons() == Qt::LeftButton) {
+		switch (current_behavior) {
+			case addingText:
+				addDiagramTextAtPos(mapToScene(e -> pos()));
+				break;
+			case addingImage:
+				addDiagramImageAtPos(mapToScene(e -> pos()));
+				break;
 		}
+		current_behavior = noAction;
 	}
 	// workaround for drag view with hold wheel click and drag mouse
 	// see also mouseMoveEvent() and mouseReleaseEvent()
@@ -632,7 +646,8 @@
 	foreach(QGraphicsItem *qgi, scene -> selectedItems()) {
 		if (
 			qgraphicsitem_cast<Element *>(qgi) ||
-			qgraphicsitem_cast<IndependentTextItem *>(qgi)
+			qgraphicsitem_cast<IndependentTextItem *>(qgi) ||
+			qgraphicsitem_cast<DiagramImageItem *>(qgi)
 		) {
 			return(true);
 		}
@@ -649,7 +664,8 @@
 		if (
 			qgraphicsitem_cast<Element *>(qgi) ||
 			qgraphicsitem_cast<Conductor *>(qgi) ||
-			qgraphicsitem_cast<IndependentTextItem *>(qgi)
+			qgraphicsitem_cast<IndependentTextItem *>(qgi) ||
+			qgraphicsitem_cast<DiagramImageItem *>(qgi)
 		) {
 			return(true);
 		}
@@ -1143,7 +1159,7 @@
 bool DiagramView::switchToVisualisationModeIfNeeded(QInputEvent *e) {
 	if (isCtrlShifting(e) && !selectedItemHasFocus()) {
 		if (dragMode() != QGraphicsView::ScrollHandDrag) {
-			is_moving_view_ = true;
+			current_behavior = dragView;
 			setVisualisationMode();
 			return(true);
 		}
@@ -1157,9 +1173,9 @@
 	otherwise.
 */
 bool DiagramView::switchToSelectionModeIfNeeded(QInputEvent *e) {
-	if (is_moving_view_ && !selectedItemHasFocus() && !isCtrlShifting(e)) {
+	if (current_behavior == dragView && !selectedItemHasFocus() && !isCtrlShifting(e)) {
 		setSelectionMode();
-		is_moving_view_ = false;
+		current_behavior = noAction;
 		return(true);
 	}
 	return(false);
@@ -1201,12 +1217,11 @@
 */
 void DiagramView::addText() {
 	if (scene -> isReadOnly()) return;
-	is_adding_text = true;
+	current_behavior = addingText;
 }
 
 
-/**
-	To edit the text through the htmlEditor
+/**	To edit the text through the htmlEditor
 */
 void DiagramView::editText() {
 	if (scene -> isReadOnly()) return;
@@ -1225,7 +1240,51 @@
 	else texts_to_edit.at(0)->edit();	
 }
 
+
 /**
+* @brief DiagramView::addImage
+*/
+void DiagramView::addImage() {
+	if (scene -> isReadOnly()) return;
+
+	QString pathPictures = QDesktopServices::storageLocation ( QDesktopServices::PicturesLocation );
+	QString fileName = QFileDialog::getOpenFileName(this, tr("Selectionner une image..."), pathPictures.toStdString().c_str(), tr("Image Files (*.png *.jpg *.bmp *.svg)"));
+	if(fileName.isEmpty()) {
+		emit ImageAddedCanceled(false);
+		return;
+	}
+
+	int ret = image_to_add_.load(fileName);
+	if(!ret){
+		QMessageBox::critical(this, tr("Erreur"), tr("Impossible de charger l'image...D\351soler :("));
+		return;
+	}
+	current_behavior = addingImage;
+}
+/**
+* @brief DiagramView::addDiagramImageAtPos
+* @param pos
+* @return
+*/
+DiagramImageItem *DiagramView::addDiagramImageAtPos(const QPointF &pos) {
+
+	if (!isInteractive() || scene -> isReadOnly()) return(0);
+
+	// cree un nouveau champ image
+	DiagramImageItem *Imageitem = new DiagramImageItem( QPixmap::fromImage(image_to_add_) );
+
+	// le place a la position pos en gerant l'annulation
+	scene -> undoStack().push(new AddImageCommand(scene, Imageitem, pos));
+	adjustSceneRect();
+	
+	// emet le signal ImageAdded
+	emit(ImageAdded(false));
+
+	return(Imageitem);
+
+}
+
+/**
 	Cree un nouveau champ de texte et le place a la position pos
 	en gerant l'annulation ; enfin, le signal textAdded est emis.
 	@param pos Position du champ de texte ajoute
@@ -1243,7 +1302,7 @@
 	
 	// emet le signal textAdded
 	emit(textAdded(false));
-	
+
 	return(iti);
 }
 

Modified: trunk/sources/diagramview.h
===================================================================
--- trunk/sources/diagramview.h	2013-08-24 12:45:21 UTC (rev 2448)
+++ trunk/sources/diagramview.h	2013-08-24 15:18:45 UTC (rev 2449)
@@ -24,6 +24,7 @@
 class Diagram;
 class Element;
 class IndependentTextItem;
+class DiagramImageItem;
 class QETDiagramEditor;
 /**
 	This class provides a widget to render an electric diagram in an editable,
@@ -37,6 +38,8 @@
 	DiagramView(Diagram * = 0, QWidget * = 0);
 	virtual ~DiagramView();
 	
+	enum behavior {noAction, addingText, addingImage, dragView};
+
 	private:
 	DiagramView(const DiagramView &);
 	
@@ -47,13 +50,13 @@
 	QAction *paste_here;
 	QAction *find_element_;
 	QPoint paste_here_pos;
-	bool is_adding_text;
-	bool is_moving_view_;               ///< Indicate whether the visualisation mode has been enabled due to mouse/keyboard interactions
+	behavior current_behavior;
 	bool fresh_focus_in_;               ///< Indicate the focus was freshly gained
 	ElementsLocation next_location_;
 	QPoint next_position_;
 	QPointF reference_view_;
 	QPointF center_view_;
+	QImage image_to_add_;
 	
 	// methods
 	public:
@@ -71,7 +74,9 @@
 	bool hasDeletableItems();
 	void addText();
 	void editText();
+	void addImage();
 	IndependentTextItem *addDiagramTextAtPos(const QPointF &);
+	DiagramImageItem *addDiagramImageAtPos(const QPointF &);
 	
 	protected:
 	virtual void mouseDoubleClickEvent(QMouseEvent *);
@@ -120,6 +125,10 @@
 	void editElementRequired(const ElementsLocation &);
 	/// Signal emitted when users want to edit and/or duplicate an existing title block template
 	void editTitleBlockTemplate(const QString &, bool);
+	/// Signal emitted after a image was added
+	void ImageAdded(bool);
+	/// Signal emmitted fater windows selection image have been canceled
+	void ImageAddedCanceled(bool);
 	
 	public slots:
 	void selectNothing();

Modified: trunk/sources/elementsmover.cpp
===================================================================
--- trunk/sources/elementsmover.cpp	2013-08-24 12:45:21 UTC (rev 2448)
+++ trunk/sources/elementsmover.cpp	2013-08-24 15:18:45 UTC (rev 2449)
@@ -22,6 +22,7 @@
 #include "diagramcommands.h"
 #include "element.h"
 #include "independenttextitem.h"
+#include "diagramimageitem.h"
 
 /**
 	Constructeur
@@ -138,6 +139,13 @@
 		if (movement_driver_ && text_field == movement_driver_) continue;
 		text_field -> setPos(text_field -> pos() + movement);
 	}
+
+	//deplace les images
+	foreach(DiagramImageItem *dii, moved_content_.images) {
+		if (movement_driver_ && dii == movement_driver_) continue;
+		dii -> setPos(dii -> pos() + movement);
+	}
+
 }
 
 /**

Modified: trunk/sources/qet.cpp
===================================================================
--- trunk/sources/qet.cpp	2013-08-24 12:45:21 UTC (rev 2448)
+++ trunk/sources/qet.cpp	2013-08-24 15:18:45 UTC (rev 2449)
@@ -196,10 +196,11 @@
 	@param elements_count nombre d'elements
 	@param conductors_count nombre de conducteurs
 	@param texts_count nombre de champs de texte
+	@param images_count nombre d'images
 	@return la proposition decrivant le nombre d'elements, de conducteurs et de
 	textes
 */
-QString QET::ElementsAndConductorsSentence(int elements_count, int conductors_count, int texts_count) {
+QString QET::ElementsAndConductorsSentence(int elements_count, int conductors_count, int texts_count, int images_count) {
 	QString text;
 	if (elements_count) {
 		text += QObject::tr(
@@ -207,13 +208,15 @@
 			"part of a sentence listing the content of a diagram",
 			elements_count
 		);
-		if (conductors_count && texts_count) {
+		if ((conductors_count && texts_count) ||
+			(conductors_count && images_count) ||
+			(texts_count && images_count)) {
 			text += QObject::tr(
 				", ",
 				"separator between elements and conductors in a sentence "
 				"listing the content of a diagram"
 			);
-		} else if (conductors_count || texts_count) {
+		} else if (conductors_count || texts_count || images_count) {
 			text += QObject::tr(
 				" et ",
 				"separator between elements and conductors (or texts) in a "
@@ -228,8 +231,15 @@
 			"part of a sentence listing the content of a diagram",
 			conductors_count
 		);
-		if (texts_count) {
+		if (texts_count && images_count) {
 			text += QObject::tr(
+				", ",
+				"separator between elements and conductors in a sentence "
+				"listing the content of a diagram"
+			);
+		}
+		else if (texts_count || images_count) {
+			text += QObject::tr(
 				" et ",
 				"separator between conductors and texts in a sentence listing "
 				"the content of a diagram"
@@ -243,7 +253,22 @@
 			"part of a sentence listing the content of a diagram",
 			texts_count
 		);
+		if (images_count) {
+			text += QObject::tr(
+				" et ",
+				"separator between conductors and texts in a sentence listing "
+				"the content of a diagram"
+			);
+		}
 	}
+
+	if (images_count) {
+		text += QObject::tr(
+			"%n image(s)",
+			"part of a sentence listing the content of a diagram",
+			images_count
+		);
+	}
 	return(text);
 }
 

Modified: trunk/sources/qet.h
===================================================================
--- trunk/sources/qet.h	2013-08-24 12:45:21 UTC (rev 2448)
+++ trunk/sources/qet.h	2013-08-24 15:18:45 UTC (rev 2449)
@@ -152,7 +152,7 @@
 	bool orthogonalProjection(const QPointF &, const QLineF &, QPointF * = 0);
 	bool attributeIsAnInteger(const QDomElement &, QString , int * = NULL);
 	bool attributeIsAReal(const QDomElement &, QString , qreal * = NULL);
-	QString ElementsAndConductorsSentence(int, int, int = 0);
+	QString ElementsAndConductorsSentence(int, int, int = 0, int = 0);
 	QList<QDomElement> findInDomElement(const QDomElement &, const QString &);
 	QList<QDomElement> findInDomElement(const QDomElement &, const QString &, const QString &);
 	QList<QChar> forbiddenCharacters();

Modified: trunk/sources/qetdiagrameditor.cpp
===================================================================
--- trunk/sources/qetdiagrameditor.cpp	2013-08-24 12:45:21 UTC (rev 2448)
+++ trunk/sources/qetdiagrameditor.cpp	2013-08-24 15:18:45 UTC (rev 2449)
@@ -216,6 +216,7 @@
 	add_text          = new QAction(QET::Icons::PartTextField,         tr("Ajouter un champ de texte"),            this);
 	add_edittext      = new QAction(QET::Icons::EditText,              tr("\311diter le champ de texte"),          this);
 	add_column        = new QAction(QET::Icons::EditTableInsertColumnRight, tr("Ajouter une colonne"),             this);
+	add_image      = new QAction(QET::Icons::adding_image,          tr("Ajouter une image"),             this);
 	remove_column     = new QAction(QET::Icons::EditTableDeleteColumn,      tr("Enlever une colonne"),             this);
 	add_row           = new QAction(QET::Icons::EditTableInsertRowUnder,    tr("Ajouter une ligne"),               this);
 	remove_row        = new QAction(QET::Icons::EditTableDeleteRow,         tr("Enlever une ligne"),               this);
@@ -337,6 +338,7 @@
 	
 	// traitements speciaux
 	add_text           -> setCheckable(true);
+	add_image       -> setCheckable(true);
 	windowed_view_mode -> setCheckable(true);
 	tabbed_view_mode   -> setCheckable(true);
 	mode_selection     -> setCheckable(true);
@@ -399,6 +401,7 @@
 	connect(infos_diagram,      SIGNAL(triggered()), this,       SLOT(editCurrentDiagramProperties()));
 	connect(add_text,           SIGNAL(triggered()), this,       SLOT(slot_addText())              );
 	connect(add_edittext,       SIGNAL(triggered()), this,       SLOT(slot_editText())              );
+	connect(add_image,			SIGNAL(triggered()), this,       SLOT(slot_addImage())              );
 	connect(add_column,         SIGNAL(triggered()), this,       SLOT(slot_addColumn())            );
 	connect(remove_column,      SIGNAL(triggered()), this,       SLOT(slot_removeColumn())         );
 	connect(add_row,            SIGNAL(triggered()), this,       SLOT(slot_addRow())               );
@@ -514,7 +517,7 @@
 	menu_affichage -> addAction(zoom_content);
 	menu_affichage -> addAction(zoom_fit);
 	menu_affichage -> addAction(zoom_reset);
-	
+
 	// menu Fenetres
 	slot_updateWindowsMenu();
 }
@@ -562,6 +565,7 @@
 	diagram_bar -> addAction(infos_diagram);
 	diagram_bar -> addAction(conductor_reset);
 	diagram_bar -> addAction(add_text);
+	diagram_bar -> addAction(add_image);
 
 	// ajout de la barre d'outils a la fenetre principale
 	addToolBar(Qt::TopToolBarArea, main_bar);
@@ -1150,6 +1154,7 @@
 	remove_column     -> setEnabled(editable_diagram);
 	add_row           -> setEnabled(editable_diagram);
 	remove_row        -> setEnabled(editable_diagram);
+	add_image		  ->setEnabled(editable_diagram);
 	
 	//display the beta feature only in debug mode
 #ifdef QT_NO_DEBUG
@@ -1193,8 +1198,8 @@
 	// actions ayant aussi besoin d'items (elements, conducteurs, textes, ...) selectionnes
 	bool copiable_items  = dv ? (dv -> hasCopiableItems()) : false;
 	bool deletable_items = dv ? (dv -> hasDeletableItems()) : false;
-	cut              -> setEnabled(editable_diagram && copiable_items);
-	copy             -> setEnabled(copiable_items);
+	cut              -> setEnabled(editable_diagram);
+	copy             -> setEnabled(editable_diagram);
 	delete_selection -> setEnabled(editable_diagram && deletable_items);
 	rotate_selection -> setEnabled(editable_diagram && dv -> diagram() -> canRotateSelection());
 	selection_prop   -> setEnabled(deletable_items);
@@ -1482,12 +1487,21 @@
 	Ajoute un texte au schema courant
 */
 void QETDiagramEditor::slot_addText() {
+	add_image -> setChecked(false);
 	if (DiagramView *dv = currentDiagram()) {
 		dv -> addText();
 	}
 }
-
 /**
+	Ajoute une image au schema courant
+*/
+void QETDiagramEditor::slot_addImage() {
+	add_text -> setChecked(false);
+	if (DiagramView *dv = currentDiagram()) {
+		dv -> addImage();
+	}
+}
+/**
 	to Edit en text through the html editor
 */
 void QETDiagramEditor::slot_editText() {
@@ -1754,6 +1768,8 @@
 	connect(dv,              SIGNAL(modeChanged()),              this,     SLOT(slot_updateModeActions()));
 	connect(dv,              SIGNAL(textAdded(bool)),            add_text, SLOT(setChecked(bool)));
 	connect(dv,              SIGNAL(textAdded(bool)),            add_edittext, SLOT(setChecked(bool)));
+	connect(dv,              SIGNAL(ImageAdded(bool)),           add_image, SLOT(setChecked(bool)));
+	connect(dv,				 SIGNAL(ImageAddedCanceled(bool)),   add_image, SLOT(setChecked(bool)));
 }
 
 /**

Modified: trunk/sources/qetdiagrameditor.h
===================================================================
--- trunk/sources/qetdiagrameditor.h	2013-08-24 12:45:21 UTC (rev 2448)
+++ trunk/sources/qetdiagrameditor.h	2013-08-24 15:18:45 UTC (rev 2449)
@@ -124,6 +124,7 @@
 	void slot_resetConductors();
 	void slot_addText();
 	void slot_editText();
+	void slot_addImage();
 	void setWindowedMode();
 	void setTabbedMode();
 	void readSettings();
@@ -215,7 +216,7 @@
 	QAction *cascade_window;     ///< Show MDI subwindows as cascade
 	QAction *prev_window;        ///< Switch to the previous document
 	QAction *next_window;        ///< Switch to the next document
-	
+	QAction *add_image;       ///< Tool to add an independent image item on diagrams
 	private:
 	QMdiArea workspace;
 	QSignalMapper windowMapper;

Modified: trunk/sources/qeticons.cpp
===================================================================
--- trunk/sources/qeticons.cpp	2013-08-24 12:45:21 UTC (rev 2448)
+++ trunk/sources/qeticons.cpp	2013-08-24 15:18:45 UTC (rev 2449)
@@ -152,6 +152,7 @@
 		QIcon ZoomIn;
 		QIcon ZoomOriginal;
 		QIcon ZoomOut;
+		QIcon adding_image;
 	}
 }
 
@@ -221,6 +222,7 @@
 	EditClear           .addFile(":/ico/16x16/edit-clear.png");
 	EditClear           .addFile(":/ico/22x22/edit-clear.png");
     EditText            .addFile(":/ico/22x22/names.png");
+	adding_image        .addFile(":/ico/22x22/insert-image.png");
 	
 	if (rtl) {
 		EditClearLocationBar.addPixmap(QPixmap(":/ico/16x16/edit-clear-locationbar-ltr.png").transformed(reverse));

Modified: trunk/sources/qeticons.h
===================================================================
--- trunk/sources/qeticons.h	2013-08-24 12:45:21 UTC (rev 2448)
+++ trunk/sources/qeticons.h	2013-08-24 15:18:45 UTC (rev 2449)
@@ -161,6 +161,7 @@
 		extern QIcon ZoomIn;
 		extern QIcon ZoomOriginal;
 		extern QIcon ZoomOut;
+		extern QIcon adding_image;
 	}
 }
 #endif

Modified: trunk/sources/qgimanager.cpp
===================================================================
--- trunk/sources/qgimanager.cpp	2013-08-24 12:45:21 UTC (rev 2448)
+++ trunk/sources/qgimanager.cpp	2013-08-24 15:18:45 UTC (rev 2449)
@@ -60,8 +60,8 @@
 	if (!qgi_manager.contains(qgi)) return;
 	-- qgi_manager[qgi];
 	if (qgi_manager[qgi] <= 0 && !(scene -> items().contains(qgi))) {
+		delete qgi;
 		qgi_manager.remove(qgi);
-		delete qgi;
 	}
 }
 


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