mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2025-12-17 12:40:35 +01:00
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:
@@ -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,6 +68,7 @@ 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 &)),
|
||||
@@ -92,6 +94,7 @@ Diagram::~Diagram() {
|
||||
|
||||
// delete of object for manage movement
|
||||
delete elements_mover_;
|
||||
delete element_texts_mover_;
|
||||
|
||||
// list removable items
|
||||
QList<QGraphicsItem *> 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<IndependentTextItem *>(item)) {
|
||||
dc.textFields << iti;
|
||||
} else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item)) {
|
||||
dc.elementTextFields << eti;
|
||||
} else if (Conductor *c = qgraphicsitem_cast<Conductor *>(item)) {
|
||||
// recupere les conducteurs selectionnes isoles (= non deplacables mais supprimables)
|
||||
if (
|
||||
|
||||
@@ -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 &);
|
||||
|
||||
|
||||
@@ -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<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
|
||||
@param diagram Schema sur lequel on deplace des champs de texte
|
||||
|
||||
@@ -177,6 +177,33 @@ class MoveElementsCommand : public QUndoCommand {
|
||||
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
|
||||
diagram.
|
||||
|
||||
@@ -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<Conductor *> 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<QGraphicsItem *> 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;
|
||||
|
||||
|
||||
@@ -62,8 +62,6 @@ class DiagramContent {
|
||||
QSet<Element *> elements;
|
||||
/// Hold independent text items
|
||||
QSet<IndependentTextItem *> textFields;
|
||||
/// Hold element text item
|
||||
QSet <ElementTextItem *> elementTextFields;
|
||||
/// Hold image
|
||||
QSet<DiagramImageItem *> images;
|
||||
/// Hold shape
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
141
sources/elementtextsmover.cpp
Normal file
141
sources/elementtextsmover.cpp
Normal 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;
|
||||
}
|
||||
51
sources/elementtextsmover.h
Normal file
51
sources/elementtextsmover.h
Normal 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
|
||||
@@ -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.
|
||||
@@ -148,6 +167,25 @@ QPointF DiagramTextItem::mapMovementToParent(const QPointF &movement) const {
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -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;}
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include "elementtextitem.h"
|
||||
#include "element.h"
|
||||
#include <QTextDocument>
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user