diff --git a/sources/customelement.cpp b/sources/customelement.cpp index cc4393305..c53986158 100644 --- a/sources/customelement.cpp +++ b/sources/customelement.cpp @@ -611,9 +611,19 @@ ElementTextItem *CustomElement::parseInput(QDomElement &e) { ElementTextItem *eti = new ElementTextItem(e.attribute("text"), this); eti -> setFont(QETApp::diagramTextsFont(size)); - eti -> setPos(pos_x, pos_y); + + // position du champ de texte eti -> setOriginalPos(QPointF(pos_x, pos_y)); - if (e.attribute("rotate") == "true") eti -> setFollowParentRotations(true); + eti -> setPos(pos_x, pos_y); + + // rotation du champ de texte + qreal original_rotation_angle = 0.0; + QET::attributeIsAReal(e, "rotation", &original_rotation_angle); + eti -> setOriginalRotationAngle(original_rotation_angle); + eti -> setRotationAngle(original_rotation_angle); + + // comportement du champ lorsque son element parent est pivote + eti -> setFollowParentRotations(e.attribute("rotate") == "true"); list_texts_ << eti; diff --git a/sources/diagram.cpp b/sources/diagram.cpp index 1c8a758e5..d57b1c42e 100644 --- a/sources/diagram.cpp +++ b/sources/diagram.cpp @@ -1072,6 +1072,8 @@ bool Diagram::canRotateSelection() const { foreach(QGraphicsItem * qgi, selectedItems()) { if (/*DiagramTextItem *dti = */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/diagramtextitem.cpp b/sources/diagramtextitem.cpp index 64f75078d..76bf869d4 100644 --- a/sources/diagramtextitem.cpp +++ b/sources/diagramtextitem.cpp @@ -17,6 +17,7 @@ */ #include "diagramtextitem.h" #include "diagramcommands.h" +#include "qet.h" #include "qetapp.h" /** @@ -68,32 +69,27 @@ qreal DiagramTextItem::rotationAngle() const { } /** - Permet de tourner le texte a un angle donne. La rotation s'effectue par - rapport au point (0, 0) du texte. + Permet de tourner le texte a un angle donne de maniere absolue. + Un angle de 0 degres correspond a un texte horizontal non retourne. @param rotation Nouvel angle de rotation de ce texte + @see applyRotation */ void DiagramTextItem::setRotationAngle(const qreal &rotation) { - // ramene l'angle demande entre -360.0 et +360.0 degres - qreal applied_rotation = rotation; - while (applied_rotation < -360.0) applied_rotation += 360.0; - while (applied_rotation > 360.0) applied_rotation -= 360.0; - - rotate(applied_rotation - rotation_angle_); + qreal applied_rotation = QET::correctAngle(rotation); + applyRotation(applied_rotation - rotation_angle_); rotation_angle_ = applied_rotation; } /** - Ajoute + Permet de tourner le texte de maniere relative. + L'angle added_rotation est ajoute a l'orientation actuelle du texte. @param added_rotation Angle a ajouter a la rotation actuelle + @see applyRotation */ void DiagramTextItem::rotateBy(const qreal &added_rotation) { - // ramene l'angle demande entre -360.0 et +360.0 degres - qreal applied_added_rotation = added_rotation; - while (applied_added_rotation < 360.0) applied_added_rotation += 360.0; - while (applied_added_rotation > 360.0) applied_added_rotation -= 360.0; - - rotation_angle_ += applied_added_rotation; - rotate(applied_added_rotation); + qreal applied_added_rotation = QET::correctAngle(added_rotation); + rotation_angle_ = QET::correctAngle(rotation_angle_ + applied_added_rotation); + applyRotation(applied_added_rotation); } /** @@ -210,6 +206,17 @@ void DiagramTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) { } } +/** + Effetue la rotation du texte en elle-meme + Pour les DiagramTextItem, la rotation s'effectue autour du point (0, 0). + Cette methode peut toutefois etre redefinie dans des classes + @param angle Angle de la rotation a effectuer +*/ +void DiagramTextItem::applyRotation(const qreal &angle) { + // un simple appel a QGraphicsTextItem::rotate suffit + QGraphicsTextItem::rotate(angle); +} + /** Change la position du champ de texte en veillant a ce qu'il reste sur la grille du schema auquel il appartient. diff --git a/sources/diagramtextitem.h b/sources/diagramtextitem.h index 64b94d35b..0015c4b86 100644 --- a/sources/diagramtextitem.h +++ b/sources/diagramtextitem.h @@ -60,6 +60,7 @@ class DiagramTextItem : public QGraphicsTextItem { virtual void mousePressEvent(QGraphicsSceneMouseEvent *); virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *); virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *); + virtual void applyRotation(const qreal &); // signaux signals: diff --git a/sources/diagramview.cpp b/sources/diagramview.cpp index 588214810..6daca3968 100644 --- a/sources/diagramview.cpp +++ b/sources/diagramview.cpp @@ -124,8 +124,12 @@ void DiagramView::rotateSelection() { elements_to_rotate.insert(e, e -> orientation().current()); } else if (DiagramTextItem *dti = qgraphicsitem_cast(item)) { texts_to_rotate << dti; - } /*else if (ElementTextItem *eti = qgraphicsitem_cast(item)) { - }*/ + } 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()) { + texts_to_rotate << eti; + } + } } // effectue les rotations s'il y a quelque chose a pivoter diff --git a/sources/elementtextitem.cpp b/sources/elementtextitem.cpp index abecd7719..55badf287 100644 --- a/sources/elementtextitem.cpp +++ b/sources/elementtextitem.cpp @@ -26,11 +26,15 @@ */ ElementTextItem::ElementTextItem(QGraphicsItem *parent, QGraphicsScene *scene) : DiagramTextItem(parent, scene), - follow_parent_rotations(false) + follow_parent_rotations(false), + original_rotation_angle_(0.0) { // par defaut, les DiagramTextItem sont Selectable et Movable // on desactive Movable pour les textes des elements setFlag(QGraphicsItem::ItemIsMovable, false); + + // ajuste la position du QGraphicsItem lorsque le QTextDocument change + connect(document(), SIGNAL(blockCountChanged(int)), this, SLOT(adjustItemPosition(int))); } /** @@ -41,11 +45,15 @@ ElementTextItem::ElementTextItem(QGraphicsItem *parent, QGraphicsScene *scene) : */ ElementTextItem::ElementTextItem(const QString &text, QGraphicsItem *parent, QGraphicsScene *scene) : DiagramTextItem(text, parent, scene), - follow_parent_rotations(false) + follow_parent_rotations(false), + original_rotation_angle_(0.0) { // par defaut, les DiagramTextItem sont Selectable et Movable // on desactive Movable pour les textes des elements setFlag(QGraphicsItem::ItemIsMovable, false); + + // ajuste la position du QGraphicsItem lorsque le QTextDocument change + connect(document(), SIGNAL(blockCountChanged(int)), this, SLOT(adjustItemPosition(int))); } /// Destructeur @@ -59,7 +67,7 @@ ElementTextItem::~ElementTextItem() { void ElementTextItem::setPos(const QPointF &pos) { QPointF actual_pos = pos; actual_pos -= QPointF(0.0, boundingRect().height() / 2.0); - DiagramTextItem::setPos(actual_pos); + QGraphicsTextItem::setPos(actual_pos); } /** @@ -88,9 +96,16 @@ QPointF ElementTextItem::pos() const { */ void ElementTextItem::fromXml(const QDomElement &e) { QPointF _pos = pos(); - if (qFuzzyCompare(qreal(e.attribute("x").toDouble()), _pos.x()) && qFuzzyCompare(qreal(e.attribute("y").toDouble()), _pos.y())) { + if ( + qFuzzyCompare(qreal(e.attribute("x").toDouble()), _pos.x()) && + qFuzzyCompare(qreal(e.attribute("y").toDouble()), _pos.y()) + ) { setPlainText(e.attribute("text")); previous_text = e.attribute("text"); + qreal xml_rotation_angle; + if (QET::attributeIsAReal(e, "userrotation", &xml_rotation_angle)) { + setRotationAngle(xml_rotation_angle); + } } } @@ -103,6 +118,9 @@ QDomElement ElementTextItem::toXml(QDomDocument &document) const { result.setAttribute("x", QString("%1").arg(originalPos().x())); result.setAttribute("y", QString("%1").arg(originalPos().y())); result.setAttribute("text", toPlainText()); + if (rotationAngle() != originalRotationAngle()) { + result.setAttribute("userrotation", QString("%1").arg(rotationAngle())); + } return(result); } @@ -120,3 +138,48 @@ void ElementTextItem::setOriginalPos(const QPointF &p) { QPointF ElementTextItem::originalPos() const { return(original_position); } + +/** + Definit l'angle de rotation original de ce champ de texte + @param rotation_angle un angle de rotation +*/ +void ElementTextItem::setOriginalRotationAngle(const qreal &rotation_angle) { + original_rotation_angle_ = QET::correctAngle(rotation_angle); +} + +/** + @return l'angle de rotation original de ce champ de texte +*/ +qreal ElementTextItem::originalRotationAngle() const { + return(original_rotation_angle_); +} + +/** + Cette methode s'assure que la position de l'ElementTextItem est coherente + en repositionnant son origine (c-a-d le milieu du bord gauche du champ de + texte) a la position originale. Cela est notamment utile lorsque le champ + de texte est agrandi ou retreci verticalement (ajout ou retrait de lignes). + @param new_bloc_count Nombre de blocs dans l'ElementTextItem + @see originalPos() +*/ +void ElementTextItem::adjustItemPosition(int new_block_count) { + Q_UNUSED(new_block_count); + setPos(originalPos()); +} + +/** + Effetue la rotation du texte en elle-meme + Pour les ElementTextItem, la rotation s'effectue autour du milieu du bord + gauche du champ de texte. + @param angle Angle de la rotation a effectuer +*/ +void ElementTextItem::applyRotation(const qreal &angle) { + qreal origin_offset = boundingRect().height() / 2.0; + + QTransform rotation; + rotation.translate(0.0, origin_offset); + rotation.rotate(angle); + rotation.translate(0.0, -origin_offset); + + QGraphicsTextItem::setTransform(rotation, true); +} diff --git a/sources/elementtextitem.h b/sources/elementtextitem.h index 9383b2252..35db09282 100644 --- a/sources/elementtextitem.h +++ b/sources/elementtextitem.h @@ -40,6 +40,7 @@ class ElementTextItem : public DiagramTextItem { private: bool follow_parent_rotations; QPointF original_position; + qreal original_rotation_angle_; // methodes public: @@ -55,6 +56,14 @@ class ElementTextItem : public DiagramTextItem { QPointF pos() const; void setOriginalPos(const QPointF &); QPointF originalPos() const; + void setOriginalRotationAngle(const qreal &); + qreal originalRotationAngle() const; + + public slots: + void adjustItemPosition(int); + + protected: + virtual void applyRotation(const qreal &); }; /**