From 4a15be237033f85debe3de36e51074401abe977c Mon Sep 17 00:00:00 2001 From: xavier Date: Sun, 18 Apr 2010 17:59:54 +0000 Subject: [PATCH] Ajout de deux classes (ConductorTextItem et IndependentTextItem) pour faciliter la distinction du comportement de chaque type de texte. git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/branches/0.3@956 bfdf4180-ca20-0410-9c96-a3a8aa849046 --- sources/conductor.cpp | 34 +++++++------ sources/conductor.h | 4 +- sources/conductortextitem.cpp | 73 +++++++++++++++++++++++++++ sources/conductortextitem.h | 55 ++++++++++++++++++++ sources/diagram.cpp | 89 +++++++++++++++++---------------- sources/diagram.h | 27 +++++----- sources/diagramcommands.cpp | 24 +++++---- sources/diagramcommands.h | 27 +++++----- sources/diagramcontent.cpp | 2 +- sources/diagramcontent.h | 6 +-- sources/diagramtextitem.cpp | 72 +++++++++++++------------- sources/diagramtextitem.h | 12 +++-- sources/diagramview.cpp | 30 ++++++----- sources/diagramview.h | 4 +- sources/element.cpp | 1 + sources/elementtextitem.cpp | 26 +++++++--- sources/elementtextitem.h | 14 ++++-- sources/independenttextitem.cpp | 71 ++++++++++++++++++++++++++ sources/independenttextitem.h | 48 ++++++++++++++++++ 19 files changed, 452 insertions(+), 167 deletions(-) create mode 100644 sources/conductortextitem.cpp create mode 100644 sources/conductortextitem.h create mode 100644 sources/independenttextitem.cpp create mode 100644 sources/independenttextitem.h diff --git a/sources/conductor.cpp b/sources/conductor.cpp index 645e8ebd9..b228af191 100644 --- a/sources/conductor.cpp +++ b/sources/conductor.cpp @@ -19,7 +19,7 @@ #include "conductor.h" #include "conductorsegment.h" #include "conductorsegmentprofile.h" -#include "diagramtextitem.h" +#include "conductortextitem.h" #include "element.h" #include "diagram.h" #include "diagramcommands.h" @@ -31,16 +31,16 @@ 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 Element parent du conducteur (0 par defaut) - @param scene QGraphicsScene a laquelle appartient le conducteur + @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, Element *parent, QGraphicsScene *scene) : +Conductor::Conductor(Terminal *p1, Terminal* p2, Diagram *parent_diagram) : QObject(), - QGraphicsPathItem(parent, scene), + QGraphicsPathItem(0, parent_diagram), terminal1(p1), terminal2(p2), + parent_diagram_(parent_diagram), destroyed(false), text_item(0), segments(NULL), @@ -82,14 +82,8 @@ Conductor::Conductor(Terminal *p1, Terminal* p2, Element *parent, QGraphicsScene setAcceptsHoverEvents(true); // ajout du champ de texte editable - text_item = new DiagramTextItem(); - // par defaut, les DiagramTextItem sont Selectable et Movable - // on desactive Movable pour les textes des conducteurs - text_item -> setFlag(QGraphicsItem::ItemIsMovable, false); - text_item -> setPlainText(properties_.text); - text_item -> previous_text = properties_.text; + text_item = new ConductorTextItem(properties_.text, this); calculateTextItemPosition(); - text_item -> setParentItem(this); connect( text_item, SIGNAL(diagramTextChanged(DiagramTextItem *, const QString &, const QString &)), @@ -549,7 +543,7 @@ void Conductor::destroy() { /// @return le Diagram auquel ce conducteur appartient, ou 0 si ce conducteur est independant Diagram *Conductor::diagram() const { - return(qobject_cast(scene())); + return(parent_diagram_); } /** @@ -751,7 +745,14 @@ QVariant Conductor::itemChange(GraphicsItemChange change, const QVariant &value) // le conducteur vient de se faire deselectionner setZValue(previous_z_value); } - } else if (change == QGraphicsItem::ItemSceneHasChanged || change == QGraphicsItem::ItemVisibleHasChanged) { + } else if (change == QGraphicsItem::ItemSceneHasChanged) { + // prend en compte le changement de schema + QGraphicsScene *qgscene = value.value(); + parent_diagram_ = static_cast(qgscene); + + // 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(); } @@ -1092,6 +1093,7 @@ void Conductor::saveProfile(bool undo) { ConductorProfile old_profile(conductor_profiles[current_path_type]); conductor_profiles[current_path_type].fromConductor(this); Diagram *dia = diagram(); + qDebug () << Q_FUNC_INFO << dia; if (undo && dia) { dia -> undoStack().push(new ChangeConductorCommand(this, old_profile, conductor_profiles[current_path_type], current_path_type)); } diff --git a/sources/conductor.h b/sources/conductor.h index d404b0bb2..d7def414d 100644 --- a/sources/conductor.h +++ b/sources/conductor.h @@ -35,7 +35,7 @@ class Conductor : public QObject, public QGraphicsPathItem { // constructeurs, destructeur public: - Conductor(Terminal *, Terminal *, Element * = 0, QGraphicsScene * = 0); + Conductor(Terminal *, Terminal *, Diagram * = 0); virtual ~Conductor(); private: @@ -96,6 +96,8 @@ class Conductor : public QObject, public QGraphicsPathItem { virtual QVariant itemChange(GraphicsItemChange, const QVariant &); private: + /// Schema auquel ce conducteur est rattache + Diagram *parent_diagram_; /// caracteristiques du conducteur ConductorProperties properties_; /// booleen indiquant si le fil est encore valide diff --git a/sources/conductortextitem.cpp b/sources/conductortextitem.cpp new file mode 100644 index 000000000..141beac9d --- /dev/null +++ b/sources/conductortextitem.cpp @@ -0,0 +1,73 @@ +#include "conductortextitem.h" +#include "conductor.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) +{ + // par defaut, les DiagramTextItem sont Selectable et Movable + // on desactive Movable pour les textes des conducteurs + setFlag(QGraphicsItem::ItemIsMovable, false); +} + +/** + 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) +{ + // par defaut, les DiagramTextItem sont Selectable et Movable + // on desactive Movable pour les textes des conducteurs + setFlag(QGraphicsItem::ItemIsMovable, false); +} + +/** + 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) { + setPos(e.attribute("x").toDouble(), e.attribute("y").toDouble()); + setPlainText(e.attribute("text")); + previous_text = 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 ConductorTextItem::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", toPlainText()); + if (rotationAngle()) { + result.setAttribute("rotation", QString("%1").arg(rotationAngle())); + } + return(result); +} diff --git a/sources/conductortextitem.h b/sources/conductortextitem.h new file mode 100644 index 000000000..b6cf44d3e --- /dev/null +++ b/sources/conductortextitem.h @@ -0,0 +1,55 @@ +/* + Copyright 2006-2010 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 . +*/ +#ifndef CONDUCTOR_TEXT_ITEM_H +#define CONDUCTOR_TEXT_ITEM_H +#include "diagramtextitem.h" +class Conductor; +/** + Cette classe represente un champ de texte rattache a un conducteur. + Il est editable et deplacable par l'utilisateur. + Il peut egalement etre oriente a un angle quelconque. + Ses deplacements sont toutefois limites a une certaine distance autour de + son conducteur parent. +*/ +class ConductorTextItem : public DiagramTextItem { + Q_OBJECT + + // constructeurs, destructeur + public: + ConductorTextItem(Conductor * = 0, Diagram * = 0); + ConductorTextItem(const QString &, Conductor * = 0, Diagram * = 0); + virtual ~ConductorTextItem(); + private: + ConductorTextItem(const ConductorTextItem &); + + // attributs + public: + enum { Type = UserType + 1006 }; + Conductor *parentConductor() const; + virtual void fromXml(const QDomElement &); + virtual QDomElement toXml(QDomDocument &) const; + + // methodes + public: + virtual int type() const { return Type; } + + // attributs + private: + Conductor *parent_conductor_; +}; +#endif diff --git a/sources/diagram.cpp b/sources/diagram.cpp index 9215988c8..2ce610299 100644 --- a/sources/diagram.cpp +++ b/sources/diagram.cpp @@ -16,16 +16,18 @@ along with QElectroTech. If not, see . */ #include -#include "qetapp.h" #include "conductor.h" +#include "conductortextitem.h" #include "customelement.h" #include "diagram.h" -#include "elementtextitem.h" -#include "exportdialog.h" -#include "ghostelement.h" #include "diagramcommands.h" #include "diagramcontent.h" #include "diagramposition.h" +#include "elementtextitem.h" +#include "exportdialog.h" +#include "ghostelement.h" +#include "independenttextitem.h" +#include "qetapp.h" const int Diagram::xGrid = 10; const int Diagram::yGrid = 10; @@ -295,13 +297,13 @@ QDomDocument Diagram::toXml(bool diagram) { } else if (Conductor *f = qgraphicsitem_cast(qgi)) { if (diagram) list_conductors << f; // lorsqu'on n'exporte pas tout le diagram, il faut retirer les conducteurs non selectionnes - // et pour l'instant, les conducteurs non selectionnes sont les conducteurs dont un des elements n'est pas relie - else if (f -> terminal1 -> parentItem() -> isSelected() && f -> terminal2 -> parentItem() -> isSelected()) list_conductors << f; - } else if (DiagramTextItem *dti = qgraphicsitem_cast(qgi)) { - if (!dti -> parentItem()) { - if (diagram) list_texts << dti; - else if (dti -> isSelected()) list_texts << dti; + // et pour l'instant, les conducteurs non selectionnes sont les conducteurs dont un des elements n'est pas selectionne + else if (f -> terminal1 -> parentItem() -> isSelected() && f -> terminal2 -> parentItem() -> isSelected()) { + list_conductors << f; } + } else if (IndependentTextItem *iti = qgraphicsitem_cast(qgi)) { + if (diagram) list_texts << iti; + else if (iti -> isSelected()) list_texts << iti; } } @@ -460,11 +462,11 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf // chargement de tous les elements du fichier XML QList added_elements; QHash table_adr_id; - foreach (QDomElement e, QET::findInDomElement(root, "elements", "element")) { - if (!Element::valideXml(e)) continue; + foreach (QDomElement element_xml, QET::findInDomElement(root, "elements", "element")) { + if (!Element::valideXml(element_xml)) continue; // cree un element dont le type correspond a l'id type - QString type_id = e.attribute("type"); + QString type_id = element_xml.attribute("type"); ElementsLocation element_location = ElementsLocation(type_id); if (type_id.startsWith("embed://")) element_location.setProject(project_); @@ -479,7 +481,7 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf } // charge les caracteristiques de l'element - if (nvel_elmt -> fromXml(e, table_adr_id)) { + if (nvel_elmt -> fromXml(element_xml, table_adr_id)) { // ajout de l'element au schema et a la liste des elements ajoutes addElement(nvel_elmt); added_elements << nvel_elmt; @@ -490,12 +492,12 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf } // chargement de tous les textes du fichiers XML - QList added_texts; - foreach (QDomElement f, QET::findInDomElement(root, "inputs", "input")) { - DiagramTextItem *dti = new DiagramTextItem(0, this); - dti -> fromXml(f); - addDiagramTextItem(dti); - added_texts << dti; + QList added_texts; + foreach (QDomElement text_xml, QET::findInDomElement(root, "inputs", "input")) { + IndependentTextItem *iti = new IndependentTextItem(this); + iti -> fromXml(text_xml); + addIndependentTextItem(iti); + added_texts << iti; } // gere la translation des nouveaux elements et texte si celle-ci est demandee @@ -549,7 +551,7 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf } } if (can_add_conductor) { - Conductor *c = new Conductor(table_adr_id.value(id_p1), table_adr_id.value(id_p2), 0, this); + Conductor *c = new Conductor(table_adr_id.value(id_p1), table_adr_id.value(id_p2), this); c -> fromXml(f); added_conductors << c; } @@ -649,19 +651,19 @@ void Diagram::addConductor(Conductor *conductor) { /** Aoute un champ de texte independant sur le schema - @param dti Champ de texte a ajouter + @param iti Champ de texte a ajouter */ -void Diagram::addDiagramTextItem(DiagramTextItem *dti) { - if (!dti || isReadOnly()) return; +void Diagram::addIndependentTextItem(IndependentTextItem *iti) { + if (!iti || isReadOnly()) return; // ajoute le champ de texte au schema - if (dti -> scene() != this) { - addItem(dti); + if (iti -> scene() != this) { + addItem(iti); } // surveille les modifications apportees au champ de texte connect( - dti, + iti, SIGNAL(diagramTextChanged(DiagramTextItem *, const QString &, const QString &)), this, SLOT(diagramTextChanged(DiagramTextItem *, const QString &, const QString &)) @@ -706,17 +708,17 @@ void Diagram::removeConductor(Conductor *conductor) { /** Enleve un champ de texte independant du schema - @param dti Champ de texte a enlever + @param iti Champ de texte a enlever */ -void Diagram::removeDiagramTextItem(DiagramTextItem *dti) { - if (!dti || isReadOnly()) return; +void Diagram::removeIndependentTextItem(IndependentTextItem *iti) { + if (!iti || isReadOnly()) return; // enleve le champ de texte au schema - removeItem(dti); + removeItem(iti); // arrete la surveillance des modifications apportees au champ de texte disconnect( - dti, + iti, SIGNAL(diagramTextChanged(DiagramTextItem *, const QString &, const QString &)), this, SLOT(diagramTextChanged(DiagramTextItem *, const QString &, const QString &)) @@ -821,8 +823,8 @@ void Diagram::fetchMovedElements() { foreach (QGraphicsItem *item, selectedItems()) { if (Element *elmt = qgraphicsitem_cast(item)) { elements_to_move << elmt; - } else if (DiagramTextItem *t = qgraphicsitem_cast(item)) { - if (!t -> parentItem()) texts_to_move << t; + } else if (IndependentTextItem *iti = qgraphicsitem_cast(item)) { + texts_to_move << iti; } } @@ -859,7 +861,6 @@ void Diagram::fetchMovedElements() { void Diagram::moveElements(const QPointF &diff, QGraphicsItem *dontmove) { // inutile de deplacer les autres elements s'il n'y a pas eu de mouvement concret if (diff.isNull()) return; - current_movement += diff; // deplace les elements selectionnes @@ -880,7 +881,7 @@ void Diagram::moveElements(const QPointF &diff, QGraphicsItem *dontmove) { } // deplace les champs de texte - foreach(DiagramTextItem *dti, textsToMove()) { + foreach(DiagramTextItem *dti, independentTextsToMove()) { if (dontmove && dti == dontmove) continue; dti -> setPos(dti -> pos() + diff); } @@ -987,10 +988,12 @@ QSet Diagram::selectedConductors() const { QSet Diagram::selectedTexts() const { QSet selected_texts; foreach(QGraphicsItem *item, selectedItems()) { - if (DiagramTextItem *dti = qgraphicsitem_cast(item)) { - selected_texts << dti; + if (ConductorTextItem *cti = qgraphicsitem_cast(item)) { + selected_texts << cti; } else if (ElementTextItem *eti = qgraphicsitem_cast(item)) { selected_texts << eti; + } else if (IndependentTextItem *iti = qgraphicsitem_cast(item)) { + selected_texts << iti; } } return(selected_texts); @@ -1045,8 +1048,8 @@ DiagramContent Diagram::content() const { foreach(QGraphicsItem *qgi, items()) { if (Element *e = qgraphicsitem_cast(qgi)) { dc.elements << e; - } else if (DiagramTextItem *dti = qgraphicsitem_cast(qgi)) { - dc.textFields << dti; + } else if (IndependentTextItem *iti = qgraphicsitem_cast(qgi)) { + dc.textFields << iti; } else if (Conductor *c = qgraphicsitem_cast(qgi)) { dc.conductorsToMove << c; } @@ -1061,7 +1064,7 @@ DiagramContent Diagram::selectedContent() { invalidateMovedElements(); DiagramContent dc; dc.elements = elementsToMove().toList(); - dc.textFields = textsToMove().toList(); + dc.textFields = independentTextsToMove().toList(); dc.conductorsToMove = conductorsToMove().toList(); dc.conductorsToUpdate = conductorsToUpdate(); @@ -1088,10 +1091,12 @@ DiagramContent Diagram::selectedContent() { */ bool Diagram::canRotateSelection() const { foreach(QGraphicsItem * qgi, selectedItems()) { - if (/*DiagramTextItem *dti = */qgraphicsitem_cast(qgi)) { + if (qgraphicsitem_cast(qgi)) { return(true); } else if (qgraphicsitem_cast(qgi)) { return(true); + } else if (qgraphicsitem_cast(qgi)) { + return(true); } else if (Element *e = qgraphicsitem_cast(qgi)) { // l'element est-il pivotable ? if (e -> orientation().current() != e -> orientation().next()) { diff --git a/sources/diagram.h b/sources/diagram.h index b987d51f3..fdf3997b9 100644 --- a/sources/diagram.h +++ b/sources/diagram.h @@ -15,23 +15,24 @@ You should have received a copy of the GNU General Public License along with QElectroTech. If not, see . */ -#ifndef SCHEMA_H -#define SCHEMA_H +#ifndef DIAGRAM_H +#define DIAGRAM_H #include #include #include "borderinset.h" -#include "qgimanager.h" #include "conductorproperties.h" #include "exportproperties.h" -class Element; -class CustomElement; -class Terminal; +#include "qgimanager.h" class Conductor; -class DiagramTextItem; +class CustomElement; class DiagramContent; class DiagramPosition; -class QETProject; +class DiagramTextItem; +class Element; class ElementsLocation; +class IndependentTextItem; +class QETProject; +class Terminal; /** Cette classe represente un schema electrique. Elle gere les differents elements et conducteurs qui le composent @@ -78,7 +79,7 @@ class Diagram : public QGraphicsScene { QSet elements_to_move; QSet conductors_to_move; QHash conductors_to_update; - QSet texts_to_move; + QSet texts_to_move; QGIManager *qgi_manager; QUndoStack *undo_stack; bool draw_terminals; @@ -122,11 +123,11 @@ class Diagram : public QGraphicsScene { // fonctions relative a l'ajout et a l'enlevement d'elements graphiques sur le schema void addElement(Element *); void addConductor(Conductor *); - void addDiagramTextItem(DiagramTextItem *); + void addIndependentTextItem(IndependentTextItem *); void removeElement(Element *); void removeConductor(Conductor *); - void removeDiagramTextItem(DiagramTextItem *); + void removeIndependentTextItem(IndependentTextItem *); // fonctions relatives aux options graphiques ExportProperties applyProperties(const ExportProperties &); @@ -156,7 +157,7 @@ class Diagram : public QGraphicsScene { const QSet &elementsToMove(); const QSet &conductorsToMove(); const QHash &conductorsToUpdate(); - const QSet &textsToMove(); + const QSet &independentTextsToMove(); QSet selectedTexts() const; QSet selectedConductors() const; DiagramContent content() const; @@ -286,7 +287,7 @@ inline const QHash &Diagram::conductorsToUpdate() { } /// @return la liste des textes a deplacer -inline const QSet &Diagram::textsToMove() { +inline const QSet &Diagram::independentTextsToMove() { if (!moved_elements_fetched) fetchMovedElements(); return(texts_to_move); } diff --git a/sources/diagramcommands.cpp b/sources/diagramcommands.cpp index 0b721541d..e81b1e8c6 100644 --- a/sources/diagramcommands.cpp +++ b/sources/diagramcommands.cpp @@ -19,7 +19,11 @@ #include "element.h" #include "conductor.h" #include "diagram.h" +#include "independenttextitem.h" #include "qgimanager.h" +#include "diagram.h" +#include "diagramtextitem.h" + /** Constructeur @param d Schema auquel on ajoute un element @@ -65,7 +69,7 @@ void AddElementCommand::redo() { @param pos Position a laquelle le texte est ajoute @param parent QUndoCommand parent */ -AddTextCommand::AddTextCommand(Diagram *dia, DiagramTextItem *text, const QPointF &pos, QUndoCommand *parent) : +AddTextCommand::AddTextCommand(Diagram *dia, IndependentTextItem *text, const QPointF &pos, QUndoCommand *parent) : QUndoCommand(QObject::tr("Ajouter un champ de texte", "undo caption"), parent), textitem(text), diagram(dia), @@ -81,12 +85,12 @@ AddTextCommand::~AddTextCommand() { /// Annule l'ajout void AddTextCommand::undo() { - diagram -> removeDiagramTextItem(textitem); + diagram -> removeIndependentTextItem(textitem); } /// Refait l'ajout void AddTextCommand::redo() { - diagram -> addDiagramTextItem(textitem); + diagram -> addIndependentTextItem(textitem); textitem -> setPos(position); } @@ -167,8 +171,8 @@ void DeleteElementsCommand::undo() { } // remet les textes - foreach(DiagramTextItem *t, removed_content.textFields) { - diagram -> addDiagramTextItem(t); + foreach(IndependentTextItem *t, removed_content.textFields) { + diagram -> addIndependentTextItem(t); } } @@ -185,8 +189,8 @@ void DeleteElementsCommand::redo() { } // enleve les textes - foreach(DiagramTextItem *t, removed_content.textFields) { - diagram -> removeDiagramTextItem(t); + foreach(IndependentTextItem *t, removed_content.textFields) { + diagram -> removeIndependentTextItem(t); } } @@ -233,7 +237,7 @@ void PasteDiagramCommand::undo() { foreach(Element *e, content.elements) diagram -> removeElement(e); // enleve les textes - foreach(DiagramTextItem *t, content.textFields) diagram -> removeDiagramTextItem(t); + foreach(IndependentTextItem *t, content.textFields) diagram -> removeIndependentTextItem(t); } /// refait le coller @@ -247,11 +251,11 @@ void PasteDiagramCommand::redo() { foreach(Conductor *c, content.conductorsToMove) diagram -> addConductor(c); // pose les textes - foreach(DiagramTextItem *t, content.textFields) diagram -> addDiagramTextItem(t); + foreach(IndependentTextItem *t, content.textFields) diagram -> addIndependentTextItem(t); } foreach(Element *e, content.elements) e -> setSelected(true); foreach(Conductor *c, content.conductorsToMove) c -> setSelected(true); - foreach(DiagramTextItem *t, content.textFields) t -> setSelected(true); + foreach(IndependentTextItem *t, content.textFields) t -> setSelected(true); } /** diff --git a/sources/diagramcommands.h b/sources/diagramcommands.h index 727869b24..bec30cef8 100644 --- a/sources/diagramcommands.h +++ b/sources/diagramcommands.h @@ -17,15 +17,18 @@ */ #ifndef DIAGRAM_COMMANDS_H #define DIAGRAM_COMMANDS_H -#include "qet.h" -#include "diagram.h" -#include "diagramcontent.h" -#include "diagramtextitem.h" -#include "conductor.h" -#include "borderproperties.h" -#include "conductorproperties.h" -#include "insetproperties.h" #include +#include "borderproperties.h" +#include "conductor.h" +#include "conductorproperties.h" +#include "diagramcontent.h" +#include "insetproperties.h" +#include "qet.h" +class Diagram; +class DiagramTextItem; +class Element; +class IndependentTextItem; + /** Cette classe represente l'action d'ajouter un element au schema */ @@ -58,7 +61,7 @@ class AddElementCommand : public QUndoCommand { class AddTextCommand : public QUndoCommand { // constructeurs, destructeur public: - AddTextCommand(Diagram *, DiagramTextItem *, const QPointF &, QUndoCommand * = 0); + AddTextCommand(Diagram *, IndependentTextItem *, const QPointF &, QUndoCommand * = 0); virtual ~AddTextCommand(); private: AddTextCommand(const AddTextCommand &); @@ -71,7 +74,7 @@ class AddTextCommand : public QUndoCommand { // attributs private: /// texte ajoute - DiagramTextItem *textitem; + IndependentTextItem *textitem; /// schema sur lequel on ajoute le texte Diagram *diagram; /// position du texte sur le schema @@ -103,8 +106,8 @@ class AddConductorCommand : public QUndoCommand { }; /** - Cette classe represente l'action de supprimer des elements et / ou - conducteurs d'un schema + Cette classe represente l'action de supprimer des elements, conducteurs + et / ou textes independants d'un schema */ class DeleteElementsCommand : public QUndoCommand { // constructeurs, destructeur diff --git a/sources/diagramcontent.cpp b/sources/diagramcontent.cpp index e46c4ee47..bbd4e17a4 100644 --- a/sources/diagramcontent.cpp +++ b/sources/diagramcontent.cpp @@ -18,7 +18,7 @@ #include "diagramcontent.h" #include #include "element.h" -#include "diagramtextitem.h" +#include "independenttextitem.h" #include "conductor.h" /** diff --git a/sources/diagramcontent.h b/sources/diagramcontent.h index deeafb000..627e379d8 100644 --- a/sources/diagramcontent.h +++ b/sources/diagramcontent.h @@ -21,7 +21,7 @@ class Conductor; class Element; class Terminal; -class DiagramTextItem; +class IndependentTextItem; /** Cette classe est un conteneur pour passer facilement le contenu d'un schema a une fonction. Il permet d'acceder rapidement aux differents types de @@ -52,8 +52,8 @@ class DiagramContent { /// Elements de texte du schema QList elements; - /// Champs de texte du schema - QList textFields; + /// Champs de texte independants du schema + QList textFields; /// Conducteurs a mettre a jour du schema QHash conductorsToUpdate; /// Conducteurs a deplacer du schema diff --git a/sources/diagramtextitem.cpp b/sources/diagramtextitem.cpp index 93db89074..b6cac420f 100644 --- a/sources/diagramtextitem.cpp +++ b/sources/diagramtextitem.cpp @@ -23,10 +23,12 @@ /** Constructeur @param parent Le QGraphicsItem parent du champ de texte - @param scene La scene a laquelle appartient le champ de texte + @param parent_diagram Le schema auquel appartient le champ de texte */ -DiagramTextItem::DiagramTextItem(QGraphicsItem *parent, QGraphicsScene *scene) : - QGraphicsTextItem(parent, scene), +DiagramTextItem::DiagramTextItem(QGraphicsItem *parent, Diagram *parent_diagram) : + QGraphicsTextItem(parent, parent_diagram), + previous_text(), + parent_diagram_(parent_diagram), rotation_angle_(0.0) { setDefaultTextColor(Qt::black); @@ -37,13 +39,14 @@ DiagramTextItem::DiagramTextItem(QGraphicsItem *parent, QGraphicsScene *scene) : /** Constructeur - @param parent Le QGraphicsItem parent du champ de texte - @param scene La scene a laquelle appartient le champ de texte @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, QGraphicsScene *scene) : - QGraphicsTextItem(text, parent, scene), +DiagramTextItem::DiagramTextItem(const QString &text, QGraphicsItem *parent, Diagram *parent_diagram) : + QGraphicsTextItem(text, parent, parent_diagram), previous_text(text), + parent_diagram_(parent_diagram), rotation_angle_(0.0) { setDefaultTextColor(Qt::black); @@ -56,9 +59,12 @@ DiagramTextItem::DiagramTextItem(const QString &text, QGraphicsItem *parent, QGr DiagramTextItem::~DiagramTextItem() { } -/// @return le Diagram auquel ce texte appartient, ou 0 si ce texte est independant +/** + @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(scene())); + return(parent_diagram_); } /** @@ -93,7 +99,18 @@ void DiagramTextItem::rotateBy(const qreal &added_rotation) { } /** - gere la perte de focus du champ de texte + Gere les changements dont ce champ de texte est informe +*/ +QVariant DiagramTextItem::itemChange(GraphicsItemChange change, const QVariant &value) { + if (change == QGraphicsItem::ItemSceneHasChanged) { + QGraphicsScene *qgscene = value.value(); + parent_diagram_ = static_cast(qgscene); + } + return(QGraphicsTextItem::itemChange(change, value)); +} + +/** + Gere la perte de focus du champ de texte */ void DiagramTextItem::focusOutEvent(QFocusEvent *e) { QGraphicsTextItem::focusOutEvent(e); @@ -113,34 +130,6 @@ void DiagramTextItem::focusOutEvent(QFocusEvent *e) { QTimer::singleShot(0, this, SIGNAL(lostFocus())); } -/** - 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 DiagramTextItem::fromXml(const QDomElement &e) { - setPos(e.attribute("x").toDouble(), e.attribute("y").toDouble()); - setPlainText(e.attribute("text")); - previous_text = 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 DiagramTextItem::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", toPlainText()); - if (rotation_angle_) { - result.setAttribute("rotation", QString("%1").arg(rotation_angle_)); - } - return(result); -} - /** Gere les double-clics sur ce champ de texte. @param event un QGraphicsSceneMouseEvent decrivant le double-clic @@ -244,6 +233,13 @@ 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); diff --git a/sources/diagramtextitem.h b/sources/diagramtextitem.h index 8edf1b58e..12f6d4580 100644 --- a/sources/diagramtextitem.h +++ b/sources/diagramtextitem.h @@ -28,8 +28,8 @@ class DiagramTextItem : public QGraphicsTextItem { Q_OBJECT // constructeurs, destructeur public: - DiagramTextItem(QGraphicsItem * = 0, QGraphicsScene * = 0); - DiagramTextItem(const QString &, QGraphicsItem * = 0, QGraphicsScene * = 0); + DiagramTextItem(QGraphicsItem * = 0, Diagram * = 0); + DiagramTextItem(const QString &, QGraphicsItem * = 0, Diagram * = 0); virtual ~DiagramTextItem(); // attributs @@ -46,15 +46,17 @@ class DiagramTextItem : public QGraphicsTextItem { */ virtual int type() const { return Type; } Diagram *diagram() const; - virtual void fromXml(const QDomElement &); - virtual QDomElement toXml(QDomDocument &) 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 &); protected: + virtual QVariant itemChange(GraphicsItemChange, const QVariant &); virtual void focusOutEvent(QFocusEvent *); virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *); virtual void mousePressEvent(QGraphicsSceneMouseEvent *); @@ -75,6 +77,8 @@ class DiagramTextItem : public QGraphicsTextItem { // attributs prives private: + /// Schema auquel ce texte est rattache + Diagram *parent_diagram_; /// angle de rotation du champ de texte qreal rotation_angle_; }; diff --git a/sources/diagramview.cpp b/sources/diagramview.cpp index e301c6801..9cd7c8a34 100644 --- a/sources/diagramview.cpp +++ b/sources/diagramview.cpp @@ -23,7 +23,9 @@ #include "diagramcommands.h" #include "diagramposition.h" #include "conductorpropertieswidget.h" +#include "conductortextitem.h" #include "elementtextitem.h" +#include "independenttextitem.h" #include "insetpropertieswidget.h" #include "qetapp.h" #include "qetproject.h" @@ -123,8 +125,10 @@ void DiagramView::rotateSelection() { foreach (QGraphicsItem *item, scene -> selectedItems()) { if (Element *e = qgraphicsitem_cast(item)) { elements_to_rotate.insert(e, e -> orientation().current()); - } else if (DiagramTextItem *dti = qgraphicsitem_cast(item)) { - texts_to_rotate << dti; + } else if (ConductorTextItem *cti = qgraphicsitem_cast(item)) { + texts_to_rotate << cti; + } else if (IndependentTextItem *iti = qgraphicsitem_cast(item)) { + texts_to_rotate << iti; } else if (ElementTextItem *eti = qgraphicsitem_cast(item)) { // on ne pivote un texte d'element que si son parent n'est pas selectionne if (eti -> parentItem() && !eti -> parentItem() -> isSelected()) { @@ -144,8 +148,10 @@ void DiagramView::rotateTexts() { // recupere les champs de texte a orienter QList texts_to_rotate; foreach (QGraphicsItem *item, scene -> selectedItems()) { - if (DiagramTextItem *dti = qgraphicsitem_cast(item)) { - texts_to_rotate << dti; + if (ConductorTextItem *cti = qgraphicsitem_cast(item)) { + texts_to_rotate << cti; + } else if (IndependentTextItem *iti = qgraphicsitem_cast(item)) { + texts_to_rotate << iti; } else if (ElementTextItem *eti = qgraphicsitem_cast(item)) { // ici, on pivote un texte d'element meme si son parent est selectionne texts_to_rotate << eti; @@ -878,20 +884,18 @@ void DiagramView::addText() { @param pos Position du champ de texte ajoute @return le champ de texte ajoute */ -DiagramTextItem *DiagramView::addDiagramTextAtPos(const QPointF &pos) { +IndependentTextItem *DiagramView::addDiagramTextAtPos(const QPointF &pos) { // cree un nouveau champ de texte - DiagramTextItem *dti = new DiagramTextItem(); - dti -> setPlainText("_"); - dti -> previous_text = "_"; - + IndependentTextItem *iti = new IndependentTextItem("_"); + // le place a la position pos en gerant l'annulation - scene -> undoStack().push(new AddTextCommand(scene, dti, pos)); + scene -> undoStack().push(new AddTextCommand(scene, iti, pos)); adjustSceneRect(); - + // emet le signal textAdded emit(textAdded(false)); - - return(dti); + + return(iti); } /** diff --git a/sources/diagramview.h b/sources/diagramview.h index 5029f5fc8..3dabec08f 100644 --- a/sources/diagramview.h +++ b/sources/diagramview.h @@ -21,8 +21,8 @@ #include "elementslocation.h" class Conductor; class Diagram; -class DiagramTextItem; class Element; +class IndependentTextItem; class QETDiagramEditor; /** Classe representant graphiquement un schema electrique @@ -62,7 +62,7 @@ class DiagramView : public QGraphicsView { QETDiagramEditor *diagramEditor() const; bool hasSelectedItems(); void addText(); - DiagramTextItem *addDiagramTextAtPos(const QPointF &); + IndependentTextItem *addDiagramTextAtPos(const QPointF &); protected: virtual void mouseDoubleClickEvent(QMouseEvent *); diff --git a/sources/element.cpp b/sources/element.cpp index 84f570fa6..30502ad84 100644 --- a/sources/element.cpp +++ b/sources/element.cpp @@ -282,6 +282,7 @@ void Element::mousePressEvent(QGraphicsSceneMouseEvent *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) { diff --git a/sources/elementtextitem.cpp b/sources/elementtextitem.cpp index be43f71b9..71a4da013 100644 --- a/sources/elementtextitem.cpp +++ b/sources/elementtextitem.cpp @@ -18,14 +18,16 @@ #include "elementtextitem.h" #include "diagram.h" #include "diagramcommands.h" +#include "element.h" /** Constructeur - @param parent Le QGraphicsItem parent du champ de texte - @param scene La scene a laquelle appartient le champ de texte + @param parent_element Le QGraphicsItem parent du champ de texte + @param parent_diagram Le schema auquel appartient le champ de texte */ -ElementTextItem::ElementTextItem(QGraphicsItem *parent, QGraphicsScene *scene) : - DiagramTextItem(parent, scene), +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) { @@ -39,12 +41,13 @@ ElementTextItem::ElementTextItem(QGraphicsItem *parent, QGraphicsScene *scene) : /** Constructeur - @param parent Le QGraphicsItem parent du champ de texte - @param scene La scene a laquelle appartient le champ de texte + @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, QGraphicsItem *parent, QGraphicsScene *scene) : - DiagramTextItem(text, parent, scene), +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) { @@ -60,6 +63,13 @@ ElementTextItem::ElementTextItem(const QString &text, QGraphicsItem *parent, QGr 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 diff --git a/sources/elementtextitem.h b/sources/elementtextitem.h index cfbf47d78..52059d1b7 100644 --- a/sources/elementtextitem.h +++ b/sources/elementtextitem.h @@ -20,8 +20,12 @@ #include "diagramtextitem.h" #include class Diagram; +class Element; /** - Cette classe represente un element de texte editable. + Cette classe represente un champ de texte rattache a un element. + Il est editable et deplacable (relativement a son element parent) par + l'utilisateur. + Il peut egalement etre oriente a un angle quelconque. Il est possible pour ce champ de texte de rester dans le sens de la lecture malgre les rotations de son element parent. */ @@ -29,8 +33,8 @@ class ElementTextItem : public DiagramTextItem { Q_OBJECT // constructeurs, destructeur public: - ElementTextItem(QGraphicsItem * = 0, QGraphicsScene * = 0); - ElementTextItem(const QString &, QGraphicsItem * = 0, QGraphicsScene * = 0); + ElementTextItem(Element * = 0, Diagram * = 0); + ElementTextItem(const QString &, Element * = 0, Diagram * = 0); virtual ~ElementTextItem(); // attributs @@ -38,6 +42,7 @@ class ElementTextItem : public DiagramTextItem { enum { Type = UserType + 1003 }; private: + Element *parent_element_; bool follow_parent_rotations; QPointF original_position; qreal original_rotation_angle_; @@ -45,6 +50,7 @@ class ElementTextItem : public DiagramTextItem { // methodes public: virtual int type() const { return Type; } + Element *parentElement() const; /// @return le rectangle delimitant le champ de texte virtual QRectF boundingRect() const { return(QGraphicsTextItem::boundingRect().adjusted(0.0, -1.1, 0.0, 0.0)); } bool followParentRotations() const; @@ -53,7 +59,7 @@ class ElementTextItem : public DiagramTextItem { QDomElement toXml(QDomDocument &) const; void setPos(const QPointF &); void setPos(qreal, qreal); - QPointF pos() const; + virtual QPointF pos() const; void setOriginalPos(const QPointF &); QPointF originalPos() const; void setOriginalRotationAngle(const qreal &); diff --git a/sources/independenttextitem.cpp b/sources/independenttextitem.cpp new file mode 100644 index 000000000..1f77a63cd --- /dev/null +++ b/sources/independenttextitem.cpp @@ -0,0 +1,71 @@ +/* + Copyright 2006-2010 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 . +*/ +#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) +{ +} + +/** + 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) +{ +} + +/// 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()); + setPlainText(e.attribute("text")); + previous_text = 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", toPlainText()); + if (rotationAngle()) { + result.setAttribute("rotation", QString("%1").arg(rotationAngle())); + } + return(result); +} + diff --git a/sources/independenttextitem.h b/sources/independenttextitem.h new file mode 100644 index 000000000..a65453e2c --- /dev/null +++ b/sources/independenttextitem.h @@ -0,0 +1,48 @@ +/* + Copyright 2006-2010 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 . +*/ +#ifndef INDEPENDENT_TEXT_ITEM_H +#define INDEPENDENT_TEXT_ITEM_H +#include +#include "diagramtextitem.h" +/** + Cette classe represente un champ de texte editable independant sur le schema. + Il peut etre pivote et deplace. +*/ +class IndependentTextItem : public DiagramTextItem { + Q_OBJECT + // constructeurs, destructeur + public: + IndependentTextItem(Diagram * = 0); + IndependentTextItem(const QString &, Diagram* = 0); + virtual ~IndependentTextItem(); + + // attributs + public: + enum { Type = UserType + 1005 }; + + // methodes + public: + /** + Cette methode permet d'utiliser qgraphicsitem_cast sur cet objet + @return le type de QGraphicsItem + */ + virtual int type() const { return Type; } + virtual void fromXml(const QDomElement &); + virtual QDomElement toXml(QDomDocument &) const; +}; +#endif