mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2025-09-14 20:33:05 +02:00
Optimisation de l'editeur d'element. L'organisation interne de l'editeur d'element a ete completement revue. Auparavant, chaque primitive instanciait son propre widget d'edition et le gardait durant toute sa duree de vie, entrainant ainsi une consommation memoire et un temps de chargement importants. Desormais, l'editeur instancie des son demarrage 9 widgets d'edition qu'il conserve durant toute sa duree de vie. Il choisit alors lequel afficher en fonction des primitives selectionnees. git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/branches/0.3@856 bfdf4180-ca20-0410-9c96-a3a8aa849046
365 lines
11 KiB
C++
365 lines
11 KiB
C++
/*
|
|
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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#include "parttextfield.h"
|
|
#include "textfieldeditor.h"
|
|
#include "editorcommands.h"
|
|
#include "qetapp.h"
|
|
|
|
/**
|
|
Constructeur
|
|
@param editor L'editeur d'element concerne
|
|
@param parent Le QGraphicsItem parent de ce champ de texte
|
|
@param scene La scene sur laquelle figure ce champ de texte
|
|
*/
|
|
PartTextField::PartTextField(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) :
|
|
QGraphicsTextItem(parent, scene),
|
|
CustomElementPart(editor),
|
|
follow_parent_rotations(true),
|
|
rotation_angle_(0.0)
|
|
{
|
|
setDefaultTextColor(Qt::black);
|
|
setFont(QETApp::diagramTextsFont());
|
|
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
|
#if QT_VERSION >= 0x040600
|
|
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
|
|
#endif
|
|
setPlainText(QObject::tr("_", "default text when adding a textfield in the element editor"));
|
|
|
|
// ajuste la position du champ de texte lorsqu'on lui ajoute/retire des lignes
|
|
connect(document(), SIGNAL(blockCountChanged(int)), this, SLOT(adjustItemPosition(int)));
|
|
}
|
|
|
|
/// Destructeur
|
|
PartTextField::~PartTextField() {
|
|
}
|
|
|
|
/**
|
|
Importe les proprietes d'un champ de texte depuis un element XML
|
|
@param xml_element Element XML a lire
|
|
*/
|
|
void PartTextField::fromXml(const QDomElement &xml_element) {
|
|
bool ok;
|
|
int font_size = xml_element.attribute("size").toInt(&ok);
|
|
if (!ok || font_size < 1) font_size = 20;
|
|
|
|
setFont(QETApp::diagramTextsFont(font_size));
|
|
setPlainText(xml_element.attribute("text"));
|
|
|
|
qreal default_rotation_angle = 0.0;
|
|
if (QET::attributeIsAReal(xml_element, "rotation", &default_rotation_angle)) {
|
|
setRotationAngle(default_rotation_angle);
|
|
}
|
|
|
|
setPos(
|
|
xml_element.attribute("x").toDouble(),
|
|
xml_element.attribute("y").toDouble()
|
|
);
|
|
known_position_ = pos();
|
|
|
|
follow_parent_rotations = (xml_element.attribute("rotate") == "true");
|
|
}
|
|
|
|
/**
|
|
Exporte le champ de texte en XML
|
|
@param xml_document Document XML a utiliser pour creer l'element XML
|
|
@return un element XML decrivant le champ de texte
|
|
*/
|
|
const QDomElement PartTextField::toXml(QDomDocument &xml_document) const {
|
|
QDomElement xml_element = xml_document.createElement("input");
|
|
xml_element.setAttribute("x", QString("%1").arg(pos().x()));
|
|
xml_element.setAttribute("y", QString("%1").arg(pos().y()));
|
|
xml_element.setAttribute("text", toPlainText());
|
|
xml_element.setAttribute("size", font().pointSize());
|
|
// angle de rotation du champ de texte
|
|
if (rotationAngle()) {
|
|
xml_element.setAttribute("rotation", QString("%1").arg(rotationAngle()));
|
|
}
|
|
// suivi (ou non) des rotations de l'element parent par le champ de texte
|
|
if (follow_parent_rotations) {
|
|
xml_element.setAttribute("rotate", "true");
|
|
}
|
|
return(xml_element);
|
|
}
|
|
|
|
/**
|
|
Retourne la position du texte, l'origine etant le milieu du bord gauche du
|
|
champ
|
|
@return la position du texte
|
|
*/
|
|
QPointF PartTextField::pos() const {
|
|
return(mapToScene(margin()));
|
|
}
|
|
|
|
/**
|
|
Specifie la position du champ de texte
|
|
@param new_pos Nouvelle position
|
|
*/
|
|
void PartTextField::setPos(const QPointF &new_pos) {
|
|
// annule toute transformation (rotation notamment)
|
|
resetTransform();
|
|
|
|
// effectue le positionnement en lui-meme
|
|
QPointF m = margin();
|
|
QGraphicsTextItem::setPos(new_pos - m);
|
|
|
|
// applique a nouveau la rotation du champ de texte
|
|
setTransform(QTransform().translate(m.x(), m.y()).rotate(rotation_angle_).translate(-m.x(), -m.y()));
|
|
}
|
|
|
|
/**
|
|
Specifie la position du champ de texte
|
|
@param x abscisse de la nouvelle position
|
|
@param y ordonnee de la nouvelle position
|
|
*/
|
|
void PartTextField::setPos(qreal x, qreal y) {
|
|
PartTextField::setPos(QPointF(x, y));
|
|
}
|
|
|
|
/**
|
|
@return l'angle de rotation de ce champ de texte
|
|
*/
|
|
qreal PartTextField::rotationAngle() const {
|
|
return(rotation_angle_);
|
|
}
|
|
|
|
/**
|
|
@param angle Le nouvel angle de rotation de ce champ de texte
|
|
*/
|
|
void PartTextField::setRotationAngle(const qreal &angle) {
|
|
qreal applied_rotation = QET::correctAngle(angle);
|
|
|
|
QPointF t = margin();
|
|
translate(t.x(), t.y());
|
|
rotate(applied_rotation - rotation_angle_);
|
|
rotation_angle_ = applied_rotation;
|
|
translate(-t.x(), -t.y());
|
|
}
|
|
|
|
/**
|
|
@return true si le champ de texte suit les rotation de l'element, false
|
|
sinon
|
|
*/
|
|
bool PartTextField::followParentRotations() {
|
|
return(follow_parent_rotations);
|
|
}
|
|
|
|
/**
|
|
@param fpr true pour que le champ de texte suive les rotation de
|
|
l'element, false sinon
|
|
*/
|
|
void PartTextField::setFollowParentRotations(bool fpr) {
|
|
follow_parent_rotations = fpr;
|
|
}
|
|
|
|
/**
|
|
@return le decalage entre l'origine du QGraphicsItem et l'origine du champ de
|
|
texte.
|
|
*/
|
|
QPointF PartTextField::margin() const {
|
|
return(QPointF(0.0, boundingRect().bottom() / 2.0));
|
|
}
|
|
|
|
/**
|
|
Permet a l'element texte de redevenir deplacable a la fin de l'edition de texte
|
|
@param e Le QFocusEvent decrivant la perte de focus
|
|
*/
|
|
void PartTextField::focusOutEvent(QFocusEvent *e) {
|
|
QGraphicsTextItem::focusOutEvent(e);
|
|
if (previous_text != toPlainText()) {
|
|
undoStack().push(
|
|
new ChangePartCommand(
|
|
TextFieldEditor::tr("contenu") + " " + name(),
|
|
this,
|
|
"text",
|
|
previous_text,
|
|
toPlainText()
|
|
)
|
|
);
|
|
previous_text = toPlainText();
|
|
}
|
|
|
|
// deselectionne le texte
|
|
QTextCursor qtc = textCursor();
|
|
qtc.clearSelection();
|
|
setTextCursor(qtc);
|
|
|
|
setTextInteractionFlags(Qt::NoTextInteraction);
|
|
setFlag(QGraphicsItem::ItemIsFocusable, false);
|
|
}
|
|
|
|
/**
|
|
Permet a l'element texte de devenir editable lorsqu'on double-clique dessus
|
|
@param e Le QGraphicsSceneMouseEvent qui decrit le double-clic
|
|
*/
|
|
void PartTextField::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *e) {
|
|
setFlag(QGraphicsItem::ItemIsFocusable, true);
|
|
setTextInteractionFlags(Qt::TextEditorInteraction);
|
|
previous_text = toPlainText();
|
|
QGraphicsTextItem::mouseDoubleClickEvent(e);
|
|
setFocus(Qt::MouseFocusReason);
|
|
}
|
|
|
|
/**
|
|
Specifie la valeur d'une propriete donnee du champ de texte
|
|
@param property propriete a modifier. Valeurs acceptees :
|
|
* x : abscisse de la position
|
|
* y : ordonnee de la position
|
|
* size : taille du texte
|
|
* text : texte
|
|
* rotate : suivi de la rotation de l'element parent
|
|
@param value Valeur a attribuer a la propriete
|
|
*/
|
|
void PartTextField::setProperty(const QString &property, const QVariant &value) {
|
|
if (property == "x") {
|
|
if (!value.canConvert(QVariant::Double)) return;
|
|
setPos(value.toDouble(), pos().y());
|
|
} else if (property == "y") {
|
|
if (!value.canConvert(QVariant::Double)) return;
|
|
setPos(pos().x(), value.toDouble());
|
|
} else if (property == "size") {
|
|
if (!value.canConvert(QVariant::Int)) return;
|
|
setFont(QETApp::diagramTextsFont(value.toInt()));
|
|
adjustItemPosition(0);
|
|
} else if (property == "text") {
|
|
setPlainText(value.toString());
|
|
} else if (property == "rotation angle") {
|
|
setRotationAngle(value.toDouble());
|
|
} else if (property == "rotate") {
|
|
follow_parent_rotations = value.toBool();
|
|
}
|
|
update();
|
|
}
|
|
|
|
/**
|
|
Permet d'acceder a la valeur d'une propriete donnee du champ de texte
|
|
@param property propriete lue. Valeurs acceptees :
|
|
* x : abscisse de la position
|
|
* y : ordonnee de la position
|
|
* size : taille du texte
|
|
* text : texte
|
|
* rotate : suivi de la rotation de l'element parent
|
|
@return La valeur de la propriete property
|
|
*/
|
|
QVariant PartTextField::property(const QString &property) {
|
|
if (property == "x") {
|
|
return(pos().x());
|
|
} else if (property == "y") {
|
|
return(pos().y());
|
|
} else if (property == "size") {
|
|
return(font().pointSize());
|
|
} else if (property == "text") {
|
|
return(toPlainText());
|
|
} else if (property == "rotation angle") {
|
|
return(rotation_angle_);
|
|
} else if (property == "rotate") {
|
|
return(follow_parent_rotations);
|
|
}
|
|
return(QVariant());
|
|
}
|
|
|
|
/**
|
|
Gere les changements intervenant sur cette partie
|
|
@param change Type de changement
|
|
@param value Valeur numerique relative au changement
|
|
*/
|
|
QVariant PartTextField::itemChange(GraphicsItemChange change, const QVariant &value) {
|
|
if (change == QGraphicsItem::ItemPositionHasChanged || change == QGraphicsItem::ItemSceneHasChanged) {
|
|
// memorise la nouvelle position "officielle" du champ de texte
|
|
// cette information servira a le recentrer en cas d'ajout / retrait de lignes
|
|
known_position_ = pos();
|
|
updateCurrentPartEditor();
|
|
} else if (change == QGraphicsItem::ItemSelectedHasChanged) {
|
|
if (value.toBool() == true) {
|
|
updateCurrentPartEditor();
|
|
}
|
|
}
|
|
return(QGraphicsTextItem::itemChange(change, value));
|
|
}
|
|
|
|
/**
|
|
@return le rectangle delimitant cette partie.
|
|
*/
|
|
QRectF PartTextField::boundingRect() const {
|
|
QRectF r = QGraphicsTextItem::boundingRect();
|
|
r.adjust(0.0, -1.1, 0.0, 0.0);
|
|
return(r);
|
|
}
|
|
|
|
/**
|
|
@return true si cette partie n'est pas pertinente et ne merite pas d'etre
|
|
conservee / enregistree.
|
|
Un champ de texte est toujours pertinent ; cette fonction renvoie donc
|
|
toujours false
|
|
*/
|
|
bool PartTextField::isUseless() const {
|
|
return(false);
|
|
}
|
|
|
|
/**
|
|
Dessine le texte statique.
|
|
@param painter QPainter a utiliser pour effectuer le rendu
|
|
@param qsogi Pptions de dessin
|
|
@param widget Widget sur lequel on dessine (facultatif)
|
|
*/
|
|
void PartTextField::paint(QPainter *painter, const QStyleOptionGraphicsItem *qsogi, QWidget *qw) {
|
|
QGraphicsTextItem::paint(painter, qsogi, qw);
|
|
|
|
#ifdef QET_DEBUG_EDITOR_TEXTS
|
|
painter -> setPen(Qt::blue);
|
|
painter -> drawRect(boundingRect());
|
|
|
|
painter -> setPen(Qt::red);
|
|
drawPoint(painter, QPointF(0, 0));
|
|
|
|
painter -> setPen(QColor("#800000"));
|
|
drawPoint(painter, mapFromScene(pos()));
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
Cette methode s'assure que la position du champ de texte 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_block_count Nombre de blocs dans le PartTextField
|
|
*/
|
|
void PartTextField::adjustItemPosition(int new_block_count) {
|
|
Q_UNUSED(new_block_count);
|
|
setPos(known_position_);
|
|
}
|
|
|
|
#ifdef QET_DEBUG_EDITOR_TEXTS
|
|
/**
|
|
Dessine deux petites fleches pour mettre un point en valeur
|
|
@param painter QPainter a utiliser pour effectuer le rendu
|
|
@param point Point a dessiner
|
|
*/
|
|
void PartTextField::drawPoint(QPainter *painter, const QPointF &point) {
|
|
qreal px = point.x();
|
|
qreal py = point.y();
|
|
qreal size_1 = 5.0;
|
|
qreal size_2 = 1.0;
|
|
painter -> drawLine(px, py, px + size_1, py);
|
|
painter -> drawLine(px + size_1 - size_2, py - size_2, px + size_1, py);
|
|
painter -> drawLine(px + size_1 - size_2, py + size_2, px + size_1, py);
|
|
painter -> drawLine(px, py, px, py + size_1);
|
|
painter -> drawLine(px, py + size_1, px - size_2, py + size_1 - size_2);
|
|
painter -> drawLine(px, py + size_1, px + size_2, py + size_1 - size_2);
|
|
}
|
|
#endif
|