diff --git a/customelement.cpp b/customelement.cpp index db0f99717..14ea347b7 100644 --- a/customelement.cpp +++ b/customelement.cpp @@ -384,7 +384,7 @@ bool CustomElement::parseInput(QDomElement &e, Diagram *s) { ElementTextItem *eti = new ElementTextItem(e.attribute("text"), this, s); eti -> setFont(QFont("Sans Serif", size)); eti -> setPos(pos_x, pos_y); - if (e.attribute("rotate") == "true") eti -> setFollowParentRotations(true); + if (e.attribute("rotate") == "false") eti -> setFollowParentRotations(true); return(true); } diff --git a/editor/editorscene.cpp b/editor/editorscene.cpp index 258ee8091..54053c91c 100644 --- a/editor/editorscene.cpp +++ b/editor/editorscene.cpp @@ -6,6 +6,7 @@ #include "partpolygon.h" #include "partterminal.h" #include "parttext.h" +#include "parttextfield.h" #include "partarc.h" #define GRILLE_X 10 #define GRILLE_Y 10 @@ -155,6 +156,7 @@ void EditorScene::mousePressEvent(QGraphicsSceneMouseEvent *e) { void EditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) { PartTerminal *terminal; PartText *text; + PartTextField *textfield; if (behavior != Polygon && current_polygon != NULL) current_polygon = NULL; if (e -> button() & Qt::LeftButton) { switch(behavior) { @@ -180,6 +182,10 @@ void EditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) { text = new PartText(0, this); text -> setPos(e -> scenePos()); break; + case TextField: + textfield = new PartTextField(0, this); + textfield -> setPos(e -> scenePos()); + break; default: QGraphicsScene::mouseReleaseEvent(e); } @@ -343,13 +349,14 @@ void EditorScene::fromXml(const QDomDocument &xml_document) { QDomElement qde = n.toElement(); if (qde.isNull()) continue; CustomElementPart *cep; - if (qde.tagName() == "line") cep = new PartLine (0, this); - else if (qde.tagName() == "ellipse") cep = new PartEllipse (0, this); - else if (qde.tagName() == "circle") cep = new PartCircle (0, this); - else if (qde.tagName() == "polygon") cep = new PartPolygon (0, this); - else if (qde.tagName() == "terminal") cep = new PartTerminal(0, this); - else if (qde.tagName() == "text") cep = new PartText (0, this); - else if (qde.tagName() == "arc") cep = new PartArc (0, this); + if (qde.tagName() == "line") cep = new PartLine (0, this); + else if (qde.tagName() == "ellipse") cep = new PartEllipse (0, this); + else if (qde.tagName() == "circle") cep = new PartCircle (0, this); + else if (qde.tagName() == "polygon") cep = new PartPolygon (0, this); + else if (qde.tagName() == "terminal") cep = new PartTerminal (0, this); + else if (qde.tagName() == "text") cep = new PartText (0, this); + else if (qde.tagName() == "input") cep = new PartTextField(0, this); + else if (qde.tagName() == "arc") cep = new PartArc (0, this); else continue; if (QGraphicsItem *qgi = dynamic_cast(cep)) qgi -> setZValue(z++); cep -> fromXml(qde); diff --git a/editor/parttext.h b/editor/parttext.h index 323d72355..82b58e6b9 100644 --- a/editor/parttext.h +++ b/editor/parttext.h @@ -1,7 +1,7 @@ #ifndef PART_TEXT #define PART_TEXT #include -#include "customelementgraphicpart.h" +#include "customelementpart.h" class TextEditor; class PartText : public QGraphicsTextItem, public CustomElementPart { // constructeurs, destructeur diff --git a/editor/parttextfield.cpp b/editor/parttextfield.cpp new file mode 100644 index 000000000..8e9a88842 --- /dev/null +++ b/editor/parttextfield.cpp @@ -0,0 +1,116 @@ +#include "parttextfield.h" +#include "textfieldeditor.h" + + +PartTextField::PartTextField(QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsTextItem(parent, scene), CustomElementPart(), follow_parent_rotations(true), can_check_changes(true) { + setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); + setPlainText(tr("_")); + infos = new TextFieldEditor(this); +} + +PartTextField::~PartTextField() { + qDebug() << "~PartTextField()"; + delete infos; +} + +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(QFont(QString("Sans Serif"), font_size)); + setPlainText(xml_element.attribute("text")); + setPos( + xml_element.attribute("x").toDouble(), + xml_element.attribute("y").toDouble() + ); + + follow_parent_rotations = (xml_element.attribute("rotate") == "false"); +} + +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()); + if (follow_parent_rotations) xml_element.setAttribute("rotate", "false"); + return(xml_element); +} + +QWidget *PartTextField::elementInformations() { + return(infos); +} + +/** + Retourne la position du texte, l'origine etant le point en bas a gauche du + texte (et pas du cadre) + @return la position du texte +*/ +QPointF PartTextField::pos() const { + return(QGraphicsTextItem::pos() + margin()); +} + +void PartTextField::setPos(const QPointF &left_corner_pos) { + QGraphicsTextItem::setPos(left_corner_pos - margin()); +} + +void PartTextField::setPos(qreal x, qreal y) { + QGraphicsTextItem::setPos(QPointF(x, y) - margin()); +} + +bool PartTextField::followParentRotations() { + return(follow_parent_rotations); +} + +void PartTextField::setFollowParentRotations(bool fpr) { + follow_parent_rotations = fpr; +} + +/** + @return Les coordonnees du point situe en bas a gauche du texte. +*/ +QPointF PartTextField::margin() const { + QFont used_font = font(); + QFontMetrics qfm(used_font); + QPointF margin( + (boundingRect().width () - qfm.width(toPlainText())) / 2.0, + ((boundingRect().height() - used_font.pointSizeF()) / 3.0) + used_font.pointSizeF() + ); + return(margin); +} + +/** + 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); + setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); +} + +/** + 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) { + setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable); + setTextInteractionFlags(Qt::TextEditorInteraction); + QGraphicsTextItem::mouseDoubleClickEvent(e); + setFocus(Qt::MouseFocusReason); +} + +QVariant PartTextField::itemChange(GraphicsItemChange change, const QVariant &value) { + if (scene() && can_check_changes) { + if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) { + infos -> updateForm(); + } + } + return(QGraphicsTextItem::itemChange(change, value)); +} + +QRectF PartTextField::boundingRect() const { + QRectF r = QGraphicsTextItem::boundingRect(); + r.adjust(0.0, -2.0, 0.0, 0.0); + return(r); +} diff --git a/editor/parttextfield.h b/editor/parttextfield.h new file mode 100644 index 000000000..bed61e892 --- /dev/null +++ b/editor/parttextfield.h @@ -0,0 +1,42 @@ +#ifndef PART_TEXTFIELD +#define PART_TEXTFIELD +#include +#include "customelementpart.h" +class TextFieldEditor; +class PartTextField : public QGraphicsTextItem, public CustomElementPart { + // constructeurs, destructeur + public: + PartTextField(QGraphicsItem * = 0, QGraphicsScene * = 0); + virtual ~PartTextField(); + + private: + PartTextField(const PartTextField &); + + // attributs + TextFieldEditor *infos; + bool follow_parent_rotations; + + // methodes + public: + void fromXml(const QDomElement &); + const QDomElement toXml(QDomDocument &) const; + QWidget *elementInformations(); + QPointF pos() const; + void setPos(const QPointF &); + void setPos(qreal, qreal); + bool followParentRotations(); + void setFollowParentRotations(bool); + + protected: + virtual void focusOutEvent(QFocusEvent *); + virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *); + virtual QVariant itemChange(GraphicsItemChange, const QVariant &); + QRectF boundingRect() const; + + public: + bool can_check_changes; + + private: + QPointF margin() const; +}; +#endif diff --git a/editor/terminaleditor.h b/editor/terminaleditor.h index 12316d2d7..ffc323da1 100644 --- a/editor/terminaleditor.h +++ b/editor/terminaleditor.h @@ -5,7 +5,7 @@ class PartTerminal; /** Cette classe represente un editeur de borne. Elle permet d'editer a travers une interface graphique les - proprietes d'une borne d'element. + proprietes d'une borne d'element. */ class TerminalEditor : public QWidget { Q_OBJECT diff --git a/editor/textfieldeditor.cpp b/editor/textfieldeditor.cpp new file mode 100644 index 000000000..42bfe8921 --- /dev/null +++ b/editor/textfieldeditor.cpp @@ -0,0 +1,82 @@ +#include "textfieldeditor.h" +#include "parttextfield.h" + +/** + Constructeur + @param part Champ de texte a editer + @param parent QWidget parent +*/ +TextFieldEditor::TextFieldEditor(PartTextField *textfield, QWidget *parent) : QWidget(parent) { + part = textfield; + + qle_x = new QLineEdit(); + qle_y = new QLineEdit(); + qle_text = new QLineEdit(); + font_size = new QSpinBox(); + font_size -> setRange(0, 144); + rotate = new QCheckBox(tr("Maintenir horizontal malgr\351\n les rotations de l'\351l\351ment")); + rotate -> setChecked(true); + + QVBoxLayout *main_layout = new QVBoxLayout(); + main_layout -> addWidget(new QLabel(tr("Postion : "))); + + QHBoxLayout *position = new QHBoxLayout(); + position -> addWidget(new QLabel(tr("x : "))); + position -> addWidget(qle_x ); + position -> addWidget(new QLabel(tr("y : "))); + position -> addWidget(qle_y ); + main_layout -> addLayout(position); + + QHBoxLayout *fs = new QHBoxLayout(); + fs -> addWidget(new QLabel(tr("Taille : "))); + fs -> addWidget(font_size); + main_layout -> addLayout(fs); + + QHBoxLayout *t = new QHBoxLayout(); + t -> addWidget(new QLabel(tr("Texte par d\351faut : "))); + t -> addWidget(qle_text); + main_layout -> addLayout(t); + + QHBoxLayout *r = new QHBoxLayout(); + r -> addWidget(rotate); + main_layout -> addLayout(r); + + main_layout -> addStretch(); + setLayout(main_layout); + + connect(qle_x, SIGNAL(textEdited(const QString &)), this, SLOT(updateTextField())); + connect(qle_y, SIGNAL(textEdited(const QString &)), this, SLOT(updateTextField())); + connect(qle_text, SIGNAL(textEdited(const QString &)), this, SLOT(updateTextField())); + connect(font_size, SIGNAL(valueChanged(int)), this, SLOT(updateTextField())); + connect(rotate, SIGNAL(stateChanged(int)), this, SLOT(updateTextField())); +} + +/** + Destructeur +*/ +TextFieldEditor::~TextFieldEditor() { + qDebug() << "~TextFieldEditor()"; +} + +/** + Met a jour le champ de texte a partir des donnees du formulaire +*/ +void TextFieldEditor::updateTextField() { + part -> can_check_changes = false; + part -> setFont(QFont(part -> font().family(), font_size -> value())); + part -> setPlainText(qle_text -> text()); + part -> setPos(qle_x -> text().toDouble(), qle_y -> text().toDouble()); + part -> setFollowParentRotations(!rotate -> isChecked()); + part -> can_check_changes = true; +} + +/** + Met a jour le formulaire a partir du champ de texte +*/ +void TextFieldEditor::updateForm() { + qle_x -> setText(QString("%1").arg(part -> pos().x())); + qle_y -> setText(QString("%1").arg(part -> pos().y())); + qle_text -> setText(part -> toPlainText()); + font_size -> setValue(part -> font().pointSize()); + rotate -> setChecked(!part -> followParentRotations()); +} diff --git a/editor/textfieldeditor.h b/editor/textfieldeditor.h new file mode 100644 index 000000000..c29b4ec75 --- /dev/null +++ b/editor/textfieldeditor.h @@ -0,0 +1,32 @@ +#ifndef TEXTFIELD_EDITOR_H +#define TEXTFIELD_EDITOR_H +#include +class PartTextField; +/** + Cette classe represente un editeur de champ de texte + Elle permet d'editer a travers une interface graphique les + proprietes d'un champ de texte : taille de la police, texte par + defaut et position. +*/ +class TextFieldEditor : public QWidget { + Q_OBJECT + // Constructeurs, destructeur + public: + TextFieldEditor(PartTextField *, QWidget * = 0); + virtual ~TextFieldEditor(); + private: + TextFieldEditor(const TextFieldEditor &); + + // attributs + private: + PartTextField *part; + QLineEdit *qle_x, *qle_y, *qle_text; + QSpinBox *font_size; + QCheckBox *rotate; + + // methodes + public slots: + void updateTextField(); + void updateForm(); +}; +#endif diff --git a/qelectrotech.pro b/qelectrotech.pro index 3f5e45992..4957048e8 100644 --- a/qelectrotech.pro +++ b/qelectrotech.pro @@ -51,7 +51,9 @@ HEADERS += aboutqet.h \ editor/parttext.h \ editor/texteditor.h \ editor/partarc.h \ - editor/arceditor.h + editor/arceditor.h \ + editor/parttextfield.h \ + editor/textfieldeditor.h SOURCES += aboutqet.cpp \ borderinset.cpp \ conducer.cpp \ @@ -96,7 +98,9 @@ SOURCES += aboutqet.cpp \ editor/parttext.cpp \ editor/texteditor.cpp \ editor/partarc.cpp \ - editor/arceditor.cpp + editor/arceditor.cpp \ + editor/parttextfield.cpp \ + editor/textfieldeditor.cpp RESOURCES += qelectrotech.qrc TRANSLATIONS += lang/qet_en.ts lang/qt_fr.ts QT += xml