From 3cf0f0f9292b2a394b80376141a3481d2821fcfb Mon Sep 17 00:00:00 2001 From: blacksun Date: Sat, 25 Oct 2014 21:21:52 +0000 Subject: [PATCH] Bug fix: element text item move strange when element is rotated. (my apologies for this weird bug) git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@3399 bfdf4180-ca20-0410-9c96-a3a8aa849046 --- sources/diagram.cpp | 34 ++++- sources/diagram.h | 5 + sources/diagramcommands.cpp | 61 ++++++++- sources/diagramcommands.h | 27 ++++ sources/diagramcontent.cpp | 7 +- sources/diagramcontent.h | 2 - sources/elementsmover.cpp | 13 +- sources/elementtextsmover.cpp | 141 ++++++++++++++++++++ sources/elementtextsmover.h | 51 +++++++ sources/qetgraphicsitem/diagramtextitem.cpp | 46 ++++++- sources/qetgraphicsitem/diagramtextitem.h | 2 + sources/qetgraphicsitem/elementtextitem.cpp | 76 +++++++++-- sources/qetgraphicsitem/elementtextitem.h | 4 +- 13 files changed, 429 insertions(+), 40 deletions(-) create mode 100644 sources/elementtextsmover.cpp create mode 100644 sources/elementtextsmover.h diff --git a/sources/diagram.cpp b/sources/diagram.cpp index 56eb8fd6c..f109e0617 100644 --- a/sources/diagram.cpp +++ b/sources/diagram.cpp @@ -33,6 +33,7 @@ #include "qetgraphicsitem/diagramimageitem.h" #include "qetgraphicsitem/qetshapeitem.h" #include "terminal.h" +#include "elementtextsmover.h" const int Diagram::xGrid = 10; const int Diagram::yGrid = 10; @@ -67,7 +68,8 @@ Diagram::Diagram(QObject *parent) : // initialise les objets gerant les deplacements elements_mover_ = new ElementsMover(); // deplacements d'elements/conducteurs/textes - + element_texts_mover_ = new ElementTextsMover(); // deplacements d'ElementTextItem + connect( &border_and_titleblock, SIGNAL(needTitleBlockTemplate(const QString &)), this, SLOT(setTitleBlockTemplate(const QString &)) @@ -92,6 +94,7 @@ Diagram::~Diagram() { // delete of object for manage movement delete elements_mover_; + delete element_texts_mover_; // list removable items QList deletable_items; @@ -1017,6 +1020,33 @@ void Diagram::endMoveElements() { elements_mover_ -> endMovement(); } +/** + Initialise un deplacement d'ElementTextItems + @param driver_item Item deplace par la souris et ne necessitant donc pas + d'etre deplace lors des appels a continueMovement. + @see ElementTextsMover +*/ +int Diagram::beginMoveElementTexts(QGraphicsItem *driver_item) { + return(element_texts_mover_ -> beginMovement(this, driver_item)); +} + +/** + Prend en compte un mouvement composant un deplacement d'ElementTextItems + @param movement mouvement a ajouter au deplacement en cours + @see ElementTextsMover +*/ +void Diagram::continueMoveElementTexts(const QPointF &movement) { + element_texts_mover_ -> continueMovement(movement); +} + +/** + Finalise un deplacement d'ElementTextItems + @see ElementTextsMover +*/ +void Diagram::endMoveElementTexts() { + element_texts_mover_ -> endMovement(); +} + /** Permet de savoir si un element est utilise sur un schema @param location Emplacement d'un element @@ -1269,8 +1299,6 @@ DiagramContent Diagram::selectedContent() { dc.elements << elmt; } else if (IndependentTextItem *iti = qgraphicsitem_cast(item)) { dc.textFields << iti; - } else if (ElementTextItem *eti = qgraphicsitem_cast(item)) { - dc.elementTextFields << eti; } else if (Conductor *c = qgraphicsitem_cast(item)) { // recupere les conducteurs selectionnes isoles (= non deplacables mais supprimables) if ( diff --git a/sources/diagram.h b/sources/diagram.h index 374491b8e..1cb25f02b 100644 --- a/sources/diagram.h +++ b/sources/diagram.h @@ -42,6 +42,7 @@ class QETProject; class Terminal; class ConductorTextItem; class DiagramImageItem; +class ElementTextsMover; /** This class represents an electric diagram. It manages its various child elements, conductors and texts and handles their graphic rendering. @@ -84,6 +85,7 @@ class Diagram : public QGraphicsScene { private: QGraphicsLineItem *conductor_setter_; ElementsMover *elements_mover_; + ElementTextsMover *element_texts_mover_; QGIManager *qgi_manager_; QETProject *project_; @@ -189,6 +191,9 @@ class Diagram : public QGraphicsScene { int beginMoveElements(QGraphicsItem * = 0); void continueMoveElements(const QPointF &); void endMoveElements(); + int beginMoveElementTexts(QGraphicsItem * = 0); + void continueMoveElementTexts(const QPointF &); + void endMoveElementTexts(); bool usesElement(const ElementsLocation &); bool usesTitleBlockTemplate(const QString &); diff --git a/sources/diagramcommands.cpp b/sources/diagramcommands.cpp index a4d39fd4a..b9c6d3483 100644 --- a/sources/diagramcommands.cpp +++ b/sources/diagramcommands.cpp @@ -349,7 +349,7 @@ void MoveElementsCommand::move(const QPointF &actual_movement) { typedef DiagramContent dc; //Move every movable item, except conductor - foreach (QGraphicsItem *qgi, content_to_move.items(dc::Elements | dc::TextFields | dc::ElementTextFields | dc::Images | dc::Shapes)) { + foreach (QGraphicsItem *qgi, content_to_move.items(dc::Elements | dc::TextFields | dc::Images | dc::Shapes)) { //If curent item have parent, and parent item is in content_to_move //we don't apply movement to this item, because this item will be moved by is parent. if (qgi->parentItem()) { @@ -392,6 +392,65 @@ void MoveElementsCommand::setupAnimation(QObject *target, const QByteArray &prop m_anim_group->addAnimation(animation); } +/** + Constructeur + @param diagram Schema sur lequel on deplace des champs de texte + @param texts Liste des textes deplaces + @param m translation subie par les elements + @param parent QUndoCommand parent +*/ +MoveElementsTextsCommand::MoveElementsTextsCommand( + Diagram *diagram, + const QSet &texts, + const QPointF &m, + QUndoCommand *parent +) : + QUndoCommand(parent), + diagram(diagram), + texts_to_move(texts), + movement(m), + first_redo(true) +{ + QString moved_content_sentence = QET::ElementsAndConductorsSentence(0, 0, texts_to_move.count()); + setText( + QString( + QObject::tr( + "d\351placer %1", + "undo caption - %1 is a sentence listing the moved content" + ).arg(moved_content_sentence) + ) + ); +} + +/// Destructeur +MoveElementsTextsCommand::~MoveElementsTextsCommand() { +} + +/// annule le deplacement +void MoveElementsTextsCommand::undo() { + diagram -> showMe(); + move(-movement); +} + +/// refait le deplacement +void MoveElementsTextsCommand::redo() { + diagram -> showMe(); + if (first_redo) first_redo = false; + else move(movement); +} + +/** + deplace les elements et conducteurs + @param actual_movement translation a effectuer sur les elements et conducteurs +*/ +void MoveElementsTextsCommand::move(const QPointF &actual_movement) { + // deplace les textes + foreach(ElementTextItem *text, texts_to_move) { + QPointF applied_movement = text -> mapMovementToParent(text -> mapMovementFromScene(actual_movement)); + text -> setPos(text -> pos() + applied_movement); + } +} + /** Constructeur @param diagram Schema sur lequel on deplace des champs de texte diff --git a/sources/diagramcommands.h b/sources/diagramcommands.h index 383cb45f5..b8a7542ab 100644 --- a/sources/diagramcommands.h +++ b/sources/diagramcommands.h @@ -177,6 +177,33 @@ class MoveElementsCommand : public QUndoCommand { bool first_redo; }; +class MoveElementsTextsCommand : public QUndoCommand { + // constructors, destructor + public: + MoveElementsTextsCommand(Diagram *, const QSet &, const QPointF &m, QUndoCommand * = 0); + virtual ~MoveElementsTextsCommand(); + + private: + MoveElementsTextsCommand(const MoveElementsTextsCommand &); + + // methods + public: + virtual void undo(); + virtual void redo(); + virtual void move(const QPointF &); + + // attributes + private: + /// diagram the movement takes place on. + Diagram *diagram; + /// text items to be moved + QSet texts_to_move; + /// applied movement + QPointF movement; + /// prevent the first call to redo() + bool first_redo; +}; + /** This command moves text items related to conductors on a particular diagram. diff --git a/sources/diagramcontent.cpp b/sources/diagramcontent.cpp index 937910fdc..0dd6fafd4 100644 --- a/sources/diagramcontent.cpp +++ b/sources/diagramcontent.cpp @@ -36,7 +36,6 @@ DiagramContent::DiagramContent() { DiagramContent::DiagramContent(const DiagramContent &other) : elements(other.elements), textFields(other.textFields), - elementTextFields(other.elementTextFields), images(other.images), shapes(other.shapes), conductorsToUpdate(other.conductorsToUpdate), @@ -74,7 +73,6 @@ QList DiagramContent::conductors(int filter) const { void DiagramContent::clear() { elements.clear(); textFields.clear(); - elementTextFields.clear(); images.clear(); shapes.clear(); conductorsToUpdate.clear(); @@ -92,7 +90,6 @@ QList DiagramContent::items(int filter) const { if (filter & Elements) foreach(QGraphicsItem *qgi, elements) items_list << qgi; if (filter & TextFields) foreach(QGraphicsItem *qgi, textFields) items_list << qgi; - if (filter & ElementTextFields) foreach(QGraphicsItem *qgi, elementTextFields) items_list << qgi; if (filter & Images) foreach(QGraphicsItem *qgi, images) items_list << qgi; if (filter & Shapes) foreach(QGraphicsItem *qgi, shapes) items_list << qgi; @@ -113,7 +110,6 @@ int DiagramContent::count(int filter) const { 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 & ElementTextFields) foreach(DiagramTextItem *dti, elementTextFields) { if (dti -> isSelected()) ++ count; } if (filter & Images) foreach(DiagramImageItem *dii, images) { if (dii -> isSelected()) ++ count; } if (filter & Shapes) foreach(QetShapeItem *dsi, shapes) { if (dsi -> isSelected()) ++ count; } if (filter & ConductorsToMove) foreach(Conductor *conductor, conductorsToMove) { if (conductor -> isSelected()) ++ count; } @@ -123,7 +119,6 @@ int DiagramContent::count(int filter) const { else { if (filter & Elements) count += elements.count(); if (filter & TextFields) count += textFields.count(); - if (filter & ElementTextFields) count += elementTextFields.count(); if (filter & Images) count += images.count(); if (filter & Shapes) count += shapes.count(); if (filter & ConductorsToMove) count += conductorsToMove.count(); @@ -142,7 +137,7 @@ int DiagramContent::count(int filter) const { QString DiagramContent::sentence(int filter) const { int elements_count = (filter & Elements) ? elements.count() : 0; int conductors_count = conductors(filter).count(); - int textfields_count = (filter & TextFields) ? (textFields.count() + elementTextFields.count()) : 0; + int textfields_count = (filter & TextFields) ? (textFields.count()) : 0; int images_count = (filter & Images) ? images.count() : 0; int shapes_count = (filter & Shapes) ? shapes.count() : 0; diff --git a/sources/diagramcontent.h b/sources/diagramcontent.h index a8ae30d11..3458e4ef3 100644 --- a/sources/diagramcontent.h +++ b/sources/diagramcontent.h @@ -62,8 +62,6 @@ class DiagramContent { QSet elements; /// Hold independent text items QSet textFields; - /// Hold element text item - QSet elementTextFields; /// Hold image QSet images; /// Hold shape diff --git a/sources/elementsmover.cpp b/sources/elementsmover.cpp index 2825cde97..e3a7f5ebf 100644 --- a/sources/elementsmover.cpp +++ b/sources/elementsmover.cpp @@ -76,13 +76,6 @@ int ElementsMover::beginMovement(Diagram *diagram, QGraphicsItem *driver_item) { moved_content_ = diagram -> selectedContent(); - if (driver_item) { - if (driver_item -> parentItem()) { - if (moved_content_.items().contains(driver_item -> parentItem())) - moved_content_.clear(); - } - } - if (!moved_content_.count()) return(-1); /* At this point, we've got all info to manage movement. @@ -104,12 +97,8 @@ void ElementsMover::continueMovement(const QPointF &movement) { //Move every movable item, except conductor typedef DiagramContent dc; - foreach (QGraphicsItem *qgi, moved_content_.items(dc::Elements | dc::TextFields | dc::ElementTextFields | dc::Images | dc::Shapes)) { + foreach (QGraphicsItem *qgi, moved_content_.items(dc::Elements | dc::TextFields | dc::Images | dc::Shapes)) { if (qgi == movement_driver_) continue; - if (qgi->parentItem()) { - if (moved_content_.items().contains(qgi->parentItem())) - continue; - } qgi -> setPos(qgi->pos() + movement); } diff --git a/sources/elementtextsmover.cpp b/sources/elementtextsmover.cpp new file mode 100644 index 000000000..bed7f4a4c --- /dev/null +++ b/sources/elementtextsmover.cpp @@ -0,0 +1,141 @@ +/* + Copyright 2006-2012 Xavier Guerrin + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#include "elementtextsmover.h" +#include "conductor.h" +#include "elementtextitem.h" +#include "diagram.h" +#include "diagramcommands.h" +#include "element.h" +#include "independenttextitem.h" + +/** + Constructeur +*/ +ElementTextsMover::ElementTextsMover() : + movement_running_(false), + current_movement_(), + diagram_(0), + movement_driver_(0), + moved_texts_() +{ + +} + +/** + Destructeur +*/ +ElementTextsMover::~ElementTextsMover() { +} + +/** + @return true si ce gestionnaire de deplacement est pret a etre utilise, + false sinon. Un gestionnaire de deplacement est pret a etre utilise a partir + du moment ou le mouvement precedemment gere n'est plus en cours. +*/ +bool ElementTextsMover::isReady() const { + return(!movement_running_); +} + +/** + Demarre un nouveau mouvement d'ElementTextItems + @param diagram Schema sur lequel se deroule le deplacement + @param driver_item Item deplace par la souris et ne necessitant donc pas + d'etre deplace lors des appels a continueMovement. + @return le nombre d'items concernes par le deplacement, ou -1 si le + mouvement n'a pas ete initie +*/ +int ElementTextsMover::beginMovement(Diagram *diagram, QGraphicsItem *driver_item) { + // il ne doit pas y avoir de mouvement en cours + if (movement_running_) return(-1); + + // on s'assure que l'on dispose d'un schema pour travailler + if (!diagram) return(-1); + diagram_ = diagram; + + // on prend en compte le driver_item + movement_driver_ = driver_item; + + // au debut du mouvement, le deplacement est nul + current_movement_ = QPointF(0.0, 0.0); + + // on stocke dans cet objet les items concernes par le deplacement + moved_texts_.clear(); + foreach(QGraphicsItem *item, diagram -> selectedItems()) { + if (ElementTextItem *text_item = qgraphicsitem_cast(item)) { + moved_texts_ << text_item; + } + } + + // on s'assure qu'il y a quelque chose a deplacer + if (!moved_texts_.count()) return(-1); + + // a ce stade, on dispose de toutes les informations necessaires pour + // prendre en compte les mouvements + + // il y a desormais un mouvement en cours + movement_running_ = true; + + return(moved_texts_.count()); +} + +/** + Ajoute un mouvement au deplacement en cours. Cette methode + @param movement mouvement a ajouter au deplacement en cours +*/ +void ElementTextsMover::continueMovement(const QPointF &movement) { + // un mouvement doit avoir ete initie + if (!movement_running_) return; + + // inutile de faire quoi que ce soit s'il n'y a pas eu de mouvement concret + if (movement.isNull()) return; + + // prise en compte du mouvement + current_movement_ += movement; + + // deplace les elements selectionnes + foreach(ElementTextItem *text_item, moved_texts_) { + if (movement_driver_ && text_item == movement_driver_) continue; + QPointF applied_movement = text_item -> mapMovementToParent(text_item-> mapMovementFromScene(movement)); + text_item -> setPos(text_item -> pos() + applied_movement); + } +} + +/** + Termine le deplacement en creant un objet d'annulation et en l'ajoutant a + la QUndoStack du schema concerne. + @see Diagram::undoStack() +*/ +void ElementTextsMover::endMovement() { + // un mouvement doit avoir ete initie + if (!movement_running_) return; + + // inutile de faire quoi que ce soit s'il n'y a pas eu de mouvement concret + if (!current_movement_.isNull()) { + // cree un objet d'annulation pour le mouvement ainsi realise + MoveElementsTextsCommand*undo_object = new MoveElementsTextsCommand( + diagram_, + moved_texts_, + current_movement_ + ); + + diagram_ -> undoStack().push(undo_object); + } + + // il n'y a plus de mouvement en cours + movement_running_ = false; +} diff --git a/sources/elementtextsmover.h b/sources/elementtextsmover.h new file mode 100644 index 000000000..3b4951e9e --- /dev/null +++ b/sources/elementtextsmover.h @@ -0,0 +1,51 @@ +/* + Copyright 2006-2012 Xavier Guerrin + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#ifndef ELEMENT_TEXTS_MOVER_H +#define ELEMENT_TEXTS_MOVER_H +#include +#include "diagramcontent.h" +class ElementTextItem; +class Diagram; +/** + This class manages the interactive movement of element text items on a + particular diagram. +*/ +class ElementTextsMover { + // constructors, destructor + public: + ElementTextsMover(); + virtual ~ElementTextsMover(); + private: + ElementTextsMover(const ElementTextsMover &); + + // methods + public: + bool isReady() const; + int beginMovement(Diagram *, QGraphicsItem * = 0); + void continueMovement(const QPointF &); + void endMovement(); + + // attributes + private: + bool movement_running_; + QPointF current_movement_; + Diagram *diagram_; + QGraphicsItem *movement_driver_; + QSet moved_texts_; +}; +#endif diff --git a/sources/qetgraphicsitem/diagramtextitem.cpp b/sources/qetgraphicsitem/diagramtextitem.cpp index c3b761d19..0ba2d8f60 100644 --- a/sources/qetgraphicsitem/diagramtextitem.cpp +++ b/sources/qetgraphicsitem/diagramtextitem.cpp @@ -110,6 +110,25 @@ void DiagramTextItem::rotateBy(const qreal &added_rotation) { applyRotation(applied_added_rotation); } +/** + Traduit en coordonnees de la scene un mouvement / vecteur initialement + exprime en coordonnees locales. + @param movement Vecteur exprime en coordonnees locales + @return le meme vecteur, exprime en coordonnees de la scene +*/ +QPointF DiagramTextItem::mapMovementToScene(const QPointF &movement) const { + // on definit deux points en coordonnees locales + QPointF local_origin(0.0, 0.0); + QPointF local_movement_point(movement); + + // on les mappe sur la scene + QPointF scene_origin(mapToScene(local_origin)); + QPointF scene_movement_point(mapToScene(local_movement_point)); + + // on calcule le vecteur represente par ces deux points + return(scene_movement_point - scene_origin); +} + /** Traduit en coordonnees locales un mouvement / vecteur initialement exprime en coordonnees de la scene. @@ -120,11 +139,11 @@ QPointF DiagramTextItem::mapMovementFromScene(const QPointF &movement) const { // on definit deux points sur la scene QPointF scene_origin(0.0, 0.0); QPointF scene_movement_point(movement); - + // on les mappe sur ce QGraphicsItem QPointF local_origin(mapFromScene(scene_origin)); QPointF local_movement_point(mapFromScene(scene_movement_point)); - + // on calcule le vecteur represente par ces deux points return(local_movement_point - local_origin); } @@ -139,15 +158,34 @@ QPointF DiagramTextItem::mapMovementToParent(const QPointF &movement) const { // on definit deux points en coordonnees locales QPointF local_origin(0.0, 0.0); QPointF local_movement_point(movement); - + // on les mappe sur la scene QPointF parent_origin(mapToParent(local_origin)); QPointF parent_movement_point(mapToParent(local_movement_point)); - + // on calcule le vecteur represente par ces deux points return(parent_movement_point - parent_origin); } +/** + Traduit en coordonnees locales un mouvement / vecteur initialement + exprime en coordonnees du parent. + @param movement Vecteur exprime en coordonnees du parent + @return le meme vecteur, exprime en coordonnees locales +*/ +QPointF DiagramTextItem::mapMovementFromParent(const QPointF &movement) const { + // on definit deux points sur le parent + QPointF parent_origin(0.0, 0.0); + QPointF parent_movement_point(movement); + + // on les mappe sur ce QGraphicsItem + QPointF local_origin(mapFromParent(parent_origin)); + QPointF local_movement_point(mapFromParent(parent_movement_point)); + + // on calcule le vecteur represente par ces deux points + return(local_movement_point - local_origin); +} + void DiagramTextItem::setFontSize(int &s) { setFont(QETApp::diagramTextsFont(s)); } diff --git a/sources/qetgraphicsitem/diagramtextitem.h b/sources/qetgraphicsitem/diagramtextitem.h index ce128d3fc..0496d3f02 100644 --- a/sources/qetgraphicsitem/diagramtextitem.h +++ b/sources/qetgraphicsitem/diagramtextitem.h @@ -59,8 +59,10 @@ class DiagramTextItem : public QGraphicsTextItem { 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; void setFontSize(int &s); void setNoEditable(bool e = true) {no_editable = e;} diff --git a/sources/qetgraphicsitem/elementtextitem.cpp b/sources/qetgraphicsitem/elementtextitem.cpp index 93afcd026..df18666e1 100644 --- a/sources/qetgraphicsitem/elementtextitem.cpp +++ b/sources/qetgraphicsitem/elementtextitem.cpp @@ -18,6 +18,8 @@ #include "elementtextitem.h" #include "element.h" #include +#include "diagram.h" +#include "diagramcommands.h" /** Constructeur @@ -183,22 +185,76 @@ void ElementTextItem::applyRotation(const qreal &angle) { /** * @brief ElementTextItem::mouseMoveEvent - * @param event + * @param e */ -void ElementTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { - if (parent_element_) - parent_element_->setHighlighted(true); +void ElementTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *e) { + if (textInteractionFlags() & Qt::TextEditable) { + DiagramTextItem::mouseMoveEvent(e); + } else if ((flags() & QGraphicsItem::ItemIsMovable) && (e -> buttons() & Qt::LeftButton)) { + QPointF old_pos = pos(); - DiagramTextItem::mouseMoveEvent(event); + /* + * Use e -> pos() directly will be have for behavior to pos the origin + * of the text field to the position pointed by the cursor, that isn't the wanted effect. + * Instead of this, we apply to the actual pos, + * the vector defined by the movement of cursor since the last pos clicked by left button + */ + QPointF movement = e -> pos() - e -> buttonDownPos(Qt::LeftButton); + + /* + * the method pos() and setPos() always work with coordinate of parent item + * (or scene if there isn't parent) we don't forget to map the movemement to parent + * before applyRotation + */ + QPointF new_pos = pos() + mapMovementToParent(movement); + e -> modifiers() == Qt::ControlModifier ? setPos(new_pos) : setPos(Diagram::snapToGrid(new_pos)); + + Diagram *diagram_ptr = diagram(); + if (diagram_ptr) { + if (m_first_move) { + //We signal the beginning of movement to the parent diagram + int moved_texts_count = diagram_ptr -> beginMoveElementTexts(this); + + //If there is one texte to move, we highlight the parent element. + if (moved_texts_count == 1 && parent_element_) { + parent_element_ -> setHighlighted(true); + parent_element_ -> update(); + } + } + + /* + Comme setPos() n'est pas oblige d'appliquer exactement la + valeur qu'on lui fournit, on calcule le mouvement reellement + applique. + */ + QPointF effective_movement = pos() - old_pos; + QPointF scene_effective_movement = mapMovementToScene(mapMovementFromParent(effective_movement)); + + // on applique le mouvement subi aux autres textes a deplacer + diagram_ptr -> continueMoveElementTexts(scene_effective_movement); + } + } else e -> ignore(); + + if (m_first_move) { + m_first_move = false; + } } /** * @brief ElementTextItem::mouseReleaseEvent - * @param event + * @param e */ -void ElementTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { - if (parent_element_) - parent_element_->setHighlighted(false); +void ElementTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) { + if (Diagram *diagram_ptr = diagram()) { + if (parent_element_) { + if (parent_element_ -> isHighlighted()) { + parent_element_ -> setHighlighted(false); + } + } - DiagramTextItem::mouseReleaseEvent(event); + diagram_ptr -> endMoveElementTexts(); + } + if (!(e -> modifiers() & Qt::ControlModifier)) { + QGraphicsTextItem::mouseReleaseEvent(e); + } } diff --git a/sources/qetgraphicsitem/elementtextitem.h b/sources/qetgraphicsitem/elementtextitem.h index a05956c6b..881c52a37 100644 --- a/sources/qetgraphicsitem/elementtextitem.h +++ b/sources/qetgraphicsitem/elementtextitem.h @@ -71,8 +71,8 @@ class ElementTextItem : public DiagramTextItem { protected: virtual void applyRotation(const qreal &); - virtual void mouseMoveEvent (QGraphicsSceneMouseEvent *event); - virtual void mouseReleaseEvent (QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent (QGraphicsSceneMouseEvent *e); + virtual void mouseReleaseEvent (QGraphicsSceneMouseEvent *e); private: void build();