QElectroTech  0.70
parttext.cpp
Go to the documentation of this file.
1 /*
2  Copyright 2006-2019 The QElectroTech Team
3  This file is part of QElectroTech.
4 
5  QElectroTech is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 2 of the License, or
8  (at your option) any later version.
9 
10  QElectroTech is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include "parttext.h"
19 #include "texteditor.h"
21 #include "elementscene.h"
22 #include "qetapp.h"
24 
30 PartText::PartText(QETElementEditor *editor, QGraphicsItem *parent) :
31  QGraphicsTextItem(parent),
32  CustomElementPart(editor),
33  previous_text()
34 {
35  document() -> setDocumentMargin(1.0);
36  setDefaultTextColor(Qt::black);
38  real_font_size_ = font().pointSize();
39  setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges | QGraphicsItem::ItemIsMovable);
40  setAcceptHoverEvents(true);
41  setDefaultTextColor(Qt::black);
42  setPlainText(QObject::tr("T", "default text when adding a text in the element editor"));
43 
45  // adjust textfield position after line additions/deletions
46  connect(document(), SIGNAL(blockCountChanged(int)), this, SLOT(adjustItemPosition(int)));
47  connect(document(), SIGNAL(contentsChanged()), this, SLOT(adjustItemPosition()));
48 }
49 
52 }
53 
58 void PartText::fromXml(const QDomElement &xml_element)
59 {
60  bool ok;
61 
62  if (xml_element.hasAttribute("size"))
63  {
64  int font_size = xml_element.attribute("size").toInt(&ok);
65  if (!ok || font_size < 1) {
66  font_size = 20;
67  }
68  QFont font_ = this->font();
69  font_.setPointSize(font_size);
70  setFont(font_);
71  }
72  else if (xml_element.hasAttribute("font"))
73  {
74  QFont font_;
75  font_.fromString(xml_element.attribute("font"));
76  setFont(font_);
77  }
78 
79  setDefaultTextColor(QColor(xml_element.attribute("color", "#000000")));
80  setPlainText(xml_element.attribute("text"));
81  setPos(xml_element.attribute("x").toDouble(),
82  xml_element.attribute("y").toDouble());
83  setRotation(xml_element.attribute("rotation", QString::number(0)).toDouble());
84 }
85 
91 const QDomElement PartText::toXml(QDomDocument &xml_document) const
92 {
93  QDomElement xml_element = xml_document.createElement(xmlName());
94 
95  xml_element.setAttribute("x", QString::number(pos().x()));
96  xml_element.setAttribute("y", QString::number(pos().y()));
97  xml_element.setAttribute("text", toPlainText());
98  xml_element.setAttribute("font", font().toString());
99  xml_element.setAttribute("rotation", QString::number(rotation()));
100  xml_element.setAttribute("color", defaultTextColor().name());
101 
102  return(xml_element);
103 }
104 
108 QPointF PartText::margin() const
109 {
110  QFont used_font = font();
111  QFontMetrics qfm(used_font);
112  qreal document_margin = document() -> documentMargin();
113 
114  QPointF margin(
115  // marge autour du texte
116  document_margin,
117  // marge au-dessus du texte + distance entre le plafond du texte et la baseline
118  document_margin + qfm.ascent()
119  );
120  return(margin);
121 }
122 
128 void PartText::focusInEvent(QFocusEvent *e) {
129  startEdition();
130  QGraphicsTextItem::focusInEvent(e);
131 }
132 
133 
139 void PartText::focusOutEvent(QFocusEvent *e) {
140  QGraphicsTextItem::focusOutEvent(e);
141  endEdition();
142 }
143 
149 void PartText::keyPressEvent(QKeyEvent *event) {
150  if (event -> key() == Qt::Key_Escape) {
151  endEdition();
152  }
153  else {
154  QGraphicsTextItem::keyPressEvent(event);
155  }
156 }
157 
162 void PartText::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *e) {
163  QGraphicsTextItem::mouseDoubleClickEvent(e);
164  if (e -> button() == Qt::LeftButton) {
165  setEditable(true);
166  }
167 }
168 
174 QVariant PartText::itemChange(GraphicsItemChange change, const QVariant &value) {
175  if (change == QGraphicsItem::ItemPositionHasChanged || change == QGraphicsItem::ItemSceneHasChanged) {
177  } else if (change == QGraphicsItem::ItemSelectedHasChanged) {
178  if (value.toBool() == true) {
180  }
181  }
182  return(QGraphicsTextItem::itemChange(change, value));
183 }
184 
188 QRectF PartText::boundingRect() const {
189  QRectF r = QGraphicsTextItem::boundingRect();
190  r.adjust(0.0, -1.1, 0.0, 0.0);
191  return(r);
192 }
193 
199 bool PartText::isUseless() const {
200  return(toPlainText().isEmpty());
201 }
202 
210  return(sceneBoundingRect());
211 }
212 
217 void PartText::startUserTransformation(const QRectF &rect) {
218  Q_UNUSED(rect)
219  saved_point_ = pos(); // scene coordinates, no need to mapFromScene()
221 }
222 
226 void PartText::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect) {
227  // let's try the naive approach
228  QPointF new_pos = mapPoints(initial_selection_rect, new_selection_rect, QList<QPointF>() << saved_point_).first();
229  setPos(new_pos);
230 
231  // adjust the font size following the vertical scale factor
232  qreal sy = new_selection_rect.height() / initial_selection_rect.height();
233  qreal new_font_size = saved_font_size_ * sy;
234  setProperty("real_size", qMax(1, qRound(new_font_size)));
235 }
236 
237 void PartText::setDefaultTextColor(const QColor &color)
238 {
239  if (color != this->defaultTextColor())
240  {
241  QGraphicsTextItem::setDefaultTextColor(color);
242  emit colorChanged(color);
243  }
244 }
245 
246 void PartText::setPlainText(const QString &text)
247 {
248  if (text != this->toPlainText())
249  {
250  QGraphicsTextItem::setPlainText(text);
251  emit plainTextChanged(text);
252  }
253 }
254 
255 void PartText::setFont(const QFont &font)
256 {
257  if (font != this->font())
258  {
259  QGraphicsTextItem::setFont(font);
260  emit fontChanged(font);
261  }
262 }
263 
264 
265 void PartText::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
266 {
267  if((event->buttons() & Qt::LeftButton) && (flags() & QGraphicsItem::ItemIsMovable))
268  {
269  QPointF pos = event->scenePos() + (m_origine_pos - event->buttonDownScenePos(Qt::LeftButton));
270  event->modifiers() == Qt::ControlModifier ? setPos(pos) : setPos(elementScene()->snapToGrid(pos));
271  }
272  else
273  QGraphicsObject::mouseMoveEvent(event);
274 }
275 
276 void PartText::mousePressEvent(QGraphicsSceneMouseEvent *event)
277 {
278  if(event->button() == Qt::LeftButton)
279  m_origine_pos = this->pos();
280 
281  QGraphicsObject::mousePressEvent(event);
282 }
283 
284 void PartText::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
285 {
286  if((event->button() & Qt::LeftButton) && (flags() & QGraphicsItem::ItemIsMovable) && m_origine_pos != pos())
287  {
288  QPropertyUndoCommand *undo = new QPropertyUndoCommand(this, "pos", QVariant(m_origine_pos), QVariant(pos()));
289  undo->setText(tr("Déplacer un texte"));
290  undo->enableAnimation();
291  elementScene()->undoStack().push(undo);
292  }
293 
294  QGraphicsObject::mouseReleaseEvent(event);
295 }
296 
304 void PartText::adjustItemPosition(int new_block_count) {
305  Q_UNUSED(new_block_count);
306  QPointF origin_offset = margin();
307 
308  QTransform base_translation;
309  base_translation.translate(-origin_offset.x(), -origin_offset.y());
310  setTransform(base_translation, false);
311  setTransformOriginPoint(origin_offset);
312 }
313 
317 void PartText::setEditable(bool editable) {
318  if (editable) {
319  setFlag(QGraphicsItem::ItemIsFocusable, true);
320  setTextInteractionFlags(Qt::TextEditorInteraction);
321  setFocus(Qt::MouseFocusReason);
322  }
323  else {
324  setTextInteractionFlags(Qt::NoTextInteraction);
325  setFlag(QGraphicsItem::ItemIsFocusable, false);
326  }
327 }
328 
333  // !previous_text.isNull() means the text is being edited
334  previous_text = toPlainText();
335 }
336 
342 {
343  if (!previous_text.isNull())
344  {
345  // the text was being edited
346  QString new_text = toPlainText();
347  if (previous_text != new_text)
348  {
349  QPropertyUndoCommand *undo = new QPropertyUndoCommand(this, "text", previous_text, new_text);
350  undo->setText(tr("Modifier un champ texte"));
351  undoStack().push(undo);
352  previous_text = QString();
353  }
354  }
355 
356  // deselectionne le texte
357  QTextCursor qtc = textCursor();
358  qtc.clearSelection();
359  setTextCursor(qtc);
360 
361  setEditable(false);
362 }
QString previous_text
Definition: parttext.h:98
The QPropertyUndoCommand class This undo command manage QProperty of a QObject. This undo command can...
void startEdition()
Definition: parttext.cpp:332
virtual QUndoStack & undoStack() const
void setFont(const QFont &font)
Definition: parttext.cpp:255
qreal real_font_size_
Definition: parttext.h:99
void plainTextChanged(const QString &text)
QRectF boundingRect() const override
Definition: parttext.cpp:188
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *) override
Definition: parttext.cpp:162
QPointF saved_point_
Definition: parttext.h:100
void setPlainText(const QString &text)
Definition: parttext.cpp:246
qreal saved_font_size_
Definition: parttext.h:101
~PartText() override
Destructeur.
Definition: parttext.cpp:51
void adjustItemPosition(int=0)
Definition: parttext.cpp:304
QString text
Definition: parttext.h:35
void colorChanged(const QColor &color)
void enableAnimation(bool animate=true)
QPropertyUndoCommand::enableAnimation True to enable animation.
QPointF m_origine_pos
Definition: parttext.h:103
void focusOutEvent(QFocusEvent *) override
Definition: parttext.cpp:139
void endEdition()
Definition: parttext.cpp:341
QList< QPointF > mapPoints(const QRectF &, const QRectF &, const QList< QPointF > &)
QFont font
Definition: parttext.h:36
QColor color
Definition: parttext.h:34
QUndoStack & undoStack()
void setEditable(bool)
Definition: parttext.cpp:317
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override
Definition: parttext.cpp:265
QString name() const override
Definition: parttext.h:60
void setRotation(qreal angle)
Definition: parttext.h:64
void fromXml(const QDomElement &) override
Definition: parttext.cpp:58
QRectF sceneGeometricRect() const override
Definition: parttext.cpp:209
QIcon tr
Definition: qeticons.cpp:204
void startUserTransformation(const QRectF &) override
Definition: parttext.cpp:217
void setDefaultTextColor(const QColor &color)
Definition: parttext.cpp:237
void fontChanged(const QFont &font)
virtual void updateCurrentPartEditor() const
void keyPressEvent(QKeyEvent *) override
Definition: parttext.cpp:149
void focusInEvent(QFocusEvent *) override
Definition: parttext.cpp:128
const QDomElement toXml(QDomDocument &) const override
Definition: parttext.cpp:91
PartText(QETElementEditor *, QGraphicsItem *=nullptr)
Definition: parttext.cpp:30
void handleUserTransformation(const QRectF &, const QRectF &) override
Definition: parttext.cpp:226
static QFont diagramTextsFont(qreal=-1.0)
QETApp::diagramTextsFont The font to use By default the font is "sans Serif" and size 9...
Definition: qetapp.cpp:910
void mousePressEvent(QGraphicsSceneMouseEvent *event) override
Definition: parttext.cpp:276
virtual ElementScene * elementScene() const
QString xmlName() const override
Definition: parttext.h:61
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override
Definition: parttext.cpp:284
bool isUseless() const override
Definition: parttext.cpp:199
void setProperty(const char *name, const QVariant &value) override
Definition: parttext.h:70
QVariant itemChange(GraphicsItemChange, const QVariant &) override
Definition: parttext.cpp:174
QPointF margin() const
Definition: parttext.cpp:108