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
This commit is contained in:
blacksun
2014-10-25 21:21:52 +00:00
parent bd76d66b31
commit 3cf0f0f929
13 changed files with 429 additions and 40 deletions

View File

@@ -33,6 +33,7 @@
#include "qetgraphicsitem/diagramimageitem.h" #include "qetgraphicsitem/diagramimageitem.h"
#include "qetgraphicsitem/qetshapeitem.h" #include "qetgraphicsitem/qetshapeitem.h"
#include "terminal.h" #include "terminal.h"
#include "elementtextsmover.h"
const int Diagram::xGrid = 10; const int Diagram::xGrid = 10;
const int Diagram::yGrid = 10; const int Diagram::yGrid = 10;
@@ -67,7 +68,8 @@ Diagram::Diagram(QObject *parent) :
// initialise les objets gerant les deplacements // initialise les objets gerant les deplacements
elements_mover_ = new ElementsMover(); // deplacements d'elements/conducteurs/textes elements_mover_ = new ElementsMover(); // deplacements d'elements/conducteurs/textes
element_texts_mover_ = new ElementTextsMover(); // deplacements d'ElementTextItem
connect( connect(
&border_and_titleblock, SIGNAL(needTitleBlockTemplate(const QString &)), &border_and_titleblock, SIGNAL(needTitleBlockTemplate(const QString &)),
this, SLOT(setTitleBlockTemplate(const QString &)) this, SLOT(setTitleBlockTemplate(const QString &))
@@ -92,6 +94,7 @@ Diagram::~Diagram() {
// delete of object for manage movement // delete of object for manage movement
delete elements_mover_; delete elements_mover_;
delete element_texts_mover_;
// list removable items // list removable items
QList<QGraphicsItem *> deletable_items; QList<QGraphicsItem *> deletable_items;
@@ -1017,6 +1020,33 @@ void Diagram::endMoveElements() {
elements_mover_ -> endMovement(); 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 Permet de savoir si un element est utilise sur un schema
@param location Emplacement d'un element @param location Emplacement d'un element
@@ -1269,8 +1299,6 @@ DiagramContent Diagram::selectedContent() {
dc.elements << elmt; dc.elements << elmt;
} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item)) { } else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item)) {
dc.textFields << iti; dc.textFields << iti;
} else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item)) {
dc.elementTextFields << eti;
} else if (Conductor *c = qgraphicsitem_cast<Conductor *>(item)) { } else if (Conductor *c = qgraphicsitem_cast<Conductor *>(item)) {
// recupere les conducteurs selectionnes isoles (= non deplacables mais supprimables) // recupere les conducteurs selectionnes isoles (= non deplacables mais supprimables)
if ( if (

View File

@@ -42,6 +42,7 @@ class QETProject;
class Terminal; class Terminal;
class ConductorTextItem; class ConductorTextItem;
class DiagramImageItem; class DiagramImageItem;
class ElementTextsMover;
/** /**
This class represents an electric diagram. It manages its various child This class represents an electric diagram. It manages its various child
elements, conductors and texts and handles their graphic rendering. elements, conductors and texts and handles their graphic rendering.
@@ -84,6 +85,7 @@ class Diagram : public QGraphicsScene {
private: private:
QGraphicsLineItem *conductor_setter_; QGraphicsLineItem *conductor_setter_;
ElementsMover *elements_mover_; ElementsMover *elements_mover_;
ElementTextsMover *element_texts_mover_;
QGIManager *qgi_manager_; QGIManager *qgi_manager_;
QETProject *project_; QETProject *project_;
@@ -189,6 +191,9 @@ class Diagram : public QGraphicsScene {
int beginMoveElements(QGraphicsItem * = 0); int beginMoveElements(QGraphicsItem * = 0);
void continueMoveElements(const QPointF &); void continueMoveElements(const QPointF &);
void endMoveElements(); void endMoveElements();
int beginMoveElementTexts(QGraphicsItem * = 0);
void continueMoveElementTexts(const QPointF &);
void endMoveElementTexts();
bool usesElement(const ElementsLocation &); bool usesElement(const ElementsLocation &);
bool usesTitleBlockTemplate(const QString &); bool usesTitleBlockTemplate(const QString &);

View File

@@ -349,7 +349,7 @@ void MoveElementsCommand::move(const QPointF &actual_movement) {
typedef DiagramContent dc; typedef DiagramContent dc;
//Move every movable item, except conductor //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 //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. //we don't apply movement to this item, because this item will be moved by is parent.
if (qgi->parentItem()) { if (qgi->parentItem()) {
@@ -392,6 +392,65 @@ void MoveElementsCommand::setupAnimation(QObject *target, const QByteArray &prop
m_anim_group->addAnimation(animation); 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<ElementTextItem *> &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 Constructeur
@param diagram Schema sur lequel on deplace des champs de texte @param diagram Schema sur lequel on deplace des champs de texte

View File

@@ -177,6 +177,33 @@ class MoveElementsCommand : public QUndoCommand {
bool first_redo; bool first_redo;
}; };
class MoveElementsTextsCommand : public QUndoCommand {
// constructors, destructor
public:
MoveElementsTextsCommand(Diagram *, const QSet<ElementTextItem *> &, 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<ElementTextItem *> 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 This command moves text items related to conductors on a particular
diagram. diagram.

View File

@@ -36,7 +36,6 @@ DiagramContent::DiagramContent() {
DiagramContent::DiagramContent(const DiagramContent &other) : DiagramContent::DiagramContent(const DiagramContent &other) :
elements(other.elements), elements(other.elements),
textFields(other.textFields), textFields(other.textFields),
elementTextFields(other.elementTextFields),
images(other.images), images(other.images),
shapes(other.shapes), shapes(other.shapes),
conductorsToUpdate(other.conductorsToUpdate), conductorsToUpdate(other.conductorsToUpdate),
@@ -74,7 +73,6 @@ QList<Conductor *> DiagramContent::conductors(int filter) const {
void DiagramContent::clear() { void DiagramContent::clear() {
elements.clear(); elements.clear();
textFields.clear(); textFields.clear();
elementTextFields.clear();
images.clear(); images.clear();
shapes.clear(); shapes.clear();
conductorsToUpdate.clear(); conductorsToUpdate.clear();
@@ -92,7 +90,6 @@ QList<QGraphicsItem *> DiagramContent::items(int filter) const {
if (filter & Elements) foreach(QGraphicsItem *qgi, elements) 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 & 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 & Images) foreach(QGraphicsItem *qgi, images) items_list << qgi;
if (filter & Shapes) foreach(QGraphicsItem *qgi, shapes) 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 & SelectedOnly) {
if (filter & Elements) foreach(Element *element, elements) { if (element -> isSelected()) ++ count; } if (filter & Elements) foreach(Element *element, elements) { if (element -> isSelected()) ++ count; }
if (filter & TextFields) foreach(DiagramTextItem *dti, textFields) { if (dti -> 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 & Images) foreach(DiagramImageItem *dii, images) { if (dii -> isSelected()) ++ count; }
if (filter & Shapes) foreach(QetShapeItem *dsi, shapes) { if (dsi -> isSelected()) ++ count; } if (filter & Shapes) foreach(QetShapeItem *dsi, shapes) { if (dsi -> isSelected()) ++ count; }
if (filter & ConductorsToMove) foreach(Conductor *conductor, conductorsToMove) { if (conductor -> isSelected()) ++ count; } if (filter & ConductorsToMove) foreach(Conductor *conductor, conductorsToMove) { if (conductor -> isSelected()) ++ count; }
@@ -123,7 +119,6 @@ int DiagramContent::count(int filter) const {
else { else {
if (filter & Elements) count += elements.count(); if (filter & Elements) count += elements.count();
if (filter & TextFields) count += textFields.count(); if (filter & TextFields) count += textFields.count();
if (filter & ElementTextFields) count += elementTextFields.count();
if (filter & Images) count += images.count(); if (filter & Images) count += images.count();
if (filter & Shapes) count += shapes.count(); if (filter & Shapes) count += shapes.count();
if (filter & ConductorsToMove) count += conductorsToMove.count(); if (filter & ConductorsToMove) count += conductorsToMove.count();
@@ -142,7 +137,7 @@ int DiagramContent::count(int filter) const {
QString DiagramContent::sentence(int filter) const { QString DiagramContent::sentence(int filter) const {
int elements_count = (filter & Elements) ? elements.count() : 0; int elements_count = (filter & Elements) ? elements.count() : 0;
int conductors_count = conductors(filter).count(); 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 images_count = (filter & Images) ? images.count() : 0;
int shapes_count = (filter & Shapes) ? shapes.count() : 0; int shapes_count = (filter & Shapes) ? shapes.count() : 0;

View File

@@ -62,8 +62,6 @@ class DiagramContent {
QSet<Element *> elements; QSet<Element *> elements;
/// Hold independent text items /// Hold independent text items
QSet<IndependentTextItem *> textFields; QSet<IndependentTextItem *> textFields;
/// Hold element text item
QSet <ElementTextItem *> elementTextFields;
/// Hold image /// Hold image
QSet<DiagramImageItem *> images; QSet<DiagramImageItem *> images;
/// Hold shape /// Hold shape

View File

@@ -76,13 +76,6 @@ int ElementsMover::beginMovement(Diagram *diagram, QGraphicsItem *driver_item) {
moved_content_ = diagram -> selectedContent(); 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); if (!moved_content_.count()) return(-1);
/* At this point, we've got all info to manage movement. /* 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 //Move every movable item, except conductor
typedef DiagramContent dc; 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 == movement_driver_) continue;
if (qgi->parentItem()) {
if (moved_content_.items().contains(qgi->parentItem()))
continue;
}
qgi -> setPos(qgi->pos() + movement); qgi -> setPos(qgi->pos() + movement);
} }

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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<ElementTextItem *>(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;
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef ELEMENT_TEXTS_MOVER_H
#define ELEMENT_TEXTS_MOVER_H
#include <QtGui>
#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<ElementTextItem *> moved_texts_;
};
#endif

View File

@@ -110,6 +110,25 @@ void DiagramTextItem::rotateBy(const qreal &added_rotation) {
applyRotation(applied_added_rotation); applyRotation(applied_added_rotation);
} }
/**
Traduit en coordonnees de la scene un mouvement / vecteur initialement
exprime en coordonnees locales.
@param movement Vecteur exprime en coordonnees locales
@return le meme vecteur, exprime en coordonnees de la scene
*/
QPointF DiagramTextItem::mapMovementToScene(const QPointF &movement) const {
// on definit deux points en coordonnees locales
QPointF local_origin(0.0, 0.0);
QPointF local_movement_point(movement);
// on les mappe sur la scene
QPointF scene_origin(mapToScene(local_origin));
QPointF scene_movement_point(mapToScene(local_movement_point));
// on calcule le vecteur represente par ces deux points
return(scene_movement_point - scene_origin);
}
/** /**
Traduit en coordonnees locales un mouvement / vecteur initialement Traduit en coordonnees locales un mouvement / vecteur initialement
exprime en coordonnees de la scene. exprime en coordonnees de la scene.
@@ -120,11 +139,11 @@ QPointF DiagramTextItem::mapMovementFromScene(const QPointF &movement) const {
// on definit deux points sur la scene // on definit deux points sur la scene
QPointF scene_origin(0.0, 0.0); QPointF scene_origin(0.0, 0.0);
QPointF scene_movement_point(movement); QPointF scene_movement_point(movement);
// on les mappe sur ce QGraphicsItem // on les mappe sur ce QGraphicsItem
QPointF local_origin(mapFromScene(scene_origin)); QPointF local_origin(mapFromScene(scene_origin));
QPointF local_movement_point(mapFromScene(scene_movement_point)); QPointF local_movement_point(mapFromScene(scene_movement_point));
// on calcule le vecteur represente par ces deux points // on calcule le vecteur represente par ces deux points
return(local_movement_point - local_origin); return(local_movement_point - local_origin);
} }
@@ -139,15 +158,34 @@ QPointF DiagramTextItem::mapMovementToParent(const QPointF &movement) const {
// on definit deux points en coordonnees locales // on definit deux points en coordonnees locales
QPointF local_origin(0.0, 0.0); QPointF local_origin(0.0, 0.0);
QPointF local_movement_point(movement); QPointF local_movement_point(movement);
// on les mappe sur la scene // on les mappe sur la scene
QPointF parent_origin(mapToParent(local_origin)); QPointF parent_origin(mapToParent(local_origin));
QPointF parent_movement_point(mapToParent(local_movement_point)); QPointF parent_movement_point(mapToParent(local_movement_point));
// on calcule le vecteur represente par ces deux points // on calcule le vecteur represente par ces deux points
return(parent_movement_point - parent_origin); 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) { void DiagramTextItem::setFontSize(int &s) {
setFont(QETApp::diagramTextsFont(s)); setFont(QETApp::diagramTextsFont(s));
} }

View File

@@ -59,8 +59,10 @@ class DiagramTextItem : public QGraphicsTextItem {
void setRotationAngle(const qreal &); void setRotationAngle(const qreal &);
void rotateBy(const qreal &); void rotateBy(const qreal &);
void edit(); void edit();
QPointF mapMovementToScene(const QPointF &) const;
QPointF mapMovementFromScene(const QPointF &) const; QPointF mapMovementFromScene(const QPointF &) const;
QPointF mapMovementToParent(const QPointF &) const; QPointF mapMovementToParent(const QPointF &) const;
QPointF mapMovementFromParent(const QPointF &) const;
void setFontSize(int &s); void setFontSize(int &s);
void setNoEditable(bool e = true) {no_editable = e;} void setNoEditable(bool e = true) {no_editable = e;}

View File

@@ -18,6 +18,8 @@
#include "elementtextitem.h" #include "elementtextitem.h"
#include "element.h" #include "element.h"
#include <QTextDocument> #include <QTextDocument>
#include "diagram.h"
#include "diagramcommands.h"
/** /**
Constructeur Constructeur
@@ -183,22 +185,76 @@ void ElementTextItem::applyRotation(const qreal &angle) {
/** /**
* @brief ElementTextItem::mouseMoveEvent * @brief ElementTextItem::mouseMoveEvent
* @param event * @param e
*/ */
void ElementTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { void ElementTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
if (parent_element_) if (textInteractionFlags() & Qt::TextEditable) {
parent_element_->setHighlighted(true); 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 * @brief ElementTextItem::mouseReleaseEvent
* @param event * @param e
*/ */
void ElementTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { void ElementTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
if (parent_element_) if (Diagram *diagram_ptr = diagram()) {
parent_element_->setHighlighted(false); 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);
}
} }

View File

@@ -71,8 +71,8 @@ class ElementTextItem : public DiagramTextItem {
protected: protected:
virtual void applyRotation(const qreal &); virtual void applyRotation(const qreal &);
virtual void mouseMoveEvent (QGraphicsSceneMouseEvent *event); virtual void mouseMoveEvent (QGraphicsSceneMouseEvent *e);
virtual void mouseReleaseEvent (QGraphicsSceneMouseEvent *event); virtual void mouseReleaseEvent (QGraphicsSceneMouseEvent *e);
private: private:
void build(); void build();