QElectroTech  0.70
diagramtextitem.cpp
Go to the documentation of this file.
1 /*
2  Copyright 2006-2019 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 "diagramtextitem.h"
19 #include "diagramcommands.h"
20 #include "qetapp.h"
22 #include "diagram.h"
23 
28 DiagramTextItem::DiagramTextItem(QGraphicsItem *parent) :
29  QGraphicsTextItem(parent)
30 { build(); }
31 
37 DiagramTextItem::DiagramTextItem(const QString &text, QGraphicsItem *parent) :
38  QGraphicsTextItem(text, parent),
39  m_mouse_hover(false),
40  m_previous_html_text(text)
41 { build(); }
42 
48 {
49  //set Zvalue at 10 to be upper than the DiagramImageItem
50  setZValue(10);
51  setAcceptHoverEvents(true);
52  setDefaultTextColor(Qt::black);
54  setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemSendsGeometryChanges);
55  setNoEditable(false);
56  setToolTip(tr("Maintenir ctrl pour un déplacement libre"));
57 }
58 
64  return(qobject_cast<Diagram *>(scene()));
65 }
66 
73 QDomElement DiagramTextItem::toXml(QDomDocument &) const {
74  return QDomElement();
75 }
76 
83 QPointF DiagramTextItem::mapMovementToScene(const QPointF &movement) const {
84  // on definit deux points en coordonnees locales
85  QPointF local_origin(0.0, 0.0);
86  QPointF local_movement_point(movement);
87 
88  // on les mappe sur la scene
89  QPointF scene_origin(mapToScene(local_origin));
90  QPointF scene_movement_point(mapToScene(local_movement_point));
91 
92  // on calcule le vecteur represente par ces deux points
93  return(scene_movement_point - scene_origin);
94 }
95 
102 QPointF DiagramTextItem::mapMovementFromScene(const QPointF &movement) const {
103  // on definit deux points sur la scene
104  QPointF scene_origin(0.0, 0.0);
105  QPointF scene_movement_point(movement);
106 
107  // on les mappe sur ce QGraphicsItem
108  QPointF local_origin(mapFromScene(scene_origin));
109  QPointF local_movement_point(mapFromScene(scene_movement_point));
110 
111  // on calcule le vecteur represente par ces deux points
112  return(local_movement_point - local_origin);
113 }
114 
121 QPointF DiagramTextItem::mapMovementToParent(const QPointF &movement) const {
122  // on definit deux points en coordonnees locales
123  QPointF local_origin(0.0, 0.0);
124  QPointF local_movement_point(movement);
125 
126  // on les mappe sur la scene
127  QPointF parent_origin(mapToParent(local_origin));
128  QPointF parent_movement_point(mapToParent(local_movement_point));
129 
130  // on calcule le vecteur represente par ces deux points
131  return(parent_movement_point - parent_origin);
132 }
133 
140 QPointF DiagramTextItem::mapMovementFromParent(const QPointF &movement) const {
141  // on definit deux points sur le parent
142  QPointF parent_origin(0.0, 0.0);
143  QPointF parent_movement_point(movement);
144 
145  // on les mappe sur ce QGraphicsItem
146  QPointF local_origin(mapFromParent(parent_origin));
147  QPointF local_movement_point(mapFromParent(parent_movement_point));
148 
149  // on calcule le vecteur represente par ces deux points
150  return(local_movement_point - local_origin);
151 }
152 
153 void DiagramTextItem::setFont(const QFont &font)
154 {
155  if (this->font() == font) {
156  return;
157  }
158  else
159  {
161  QGraphicsTextItem::setFont(font);
162  finishAlignment();
163  emit fontChanged(font);
164  }
165 }
166 
167 void DiagramTextItem::setColor(const QColor& color)
168 {
169  setDefaultTextColor(color);
170  emit colorChanged(color);
171 }
172 
173 QColor DiagramTextItem::color() const {
174  return defaultTextColor();
175 }
176 
177 void DiagramTextItem::setAlignment(const Qt::Alignment &alignment)
178 {
181 }
182 
183 Qt::Alignment DiagramTextItem::alignment() const
184 {
185  return m_alignment;
186 }
187 
193 {
194  //Get the bounding rectangle of the text
195  QSizeF size = document()->size();
196  size.setWidth(document()->idealWidth());
197  //Remove the margin. Size is exactly the bounding rect of the text
198  size.rheight() -= document()->documentMargin()*2;
199  size.rwidth() -= document()->documentMargin()*2;
200  //Add a little margin only for a better visual;
201  size.rheight() += 2;
202  size.rwidth() += 2;
203 
204  //The pos of the rect
205  QPointF pos = boundingRect().center();
206  pos.rx() -= size.width()/2;
207  pos.ry() -= size.height()/2;
208 
209  return QRectF(pos, size);
210 }
211 
212 void DiagramTextItem::setHtml(const QString &text)
213 {
214  QGraphicsTextItem::setHtml(text);
215  m_is_html = true;
216 }
217 
218 void DiagramTextItem::setPlainText(const QString &text)
219 {
220  QGraphicsTextItem::setPlainText(text);
221  m_is_html = false;
222 }
223 
225  return m_is_html;
226 }
227 
236 void DiagramTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
237 {
238  painter -> setRenderHint(QPainter::Antialiasing, false);
239  QGraphicsTextItem::paint(painter, option, widget);
240 
241  if (m_mouse_hover && !isSelected())
242  {
243  painter -> save();
244 
245  //Disable renderhints
246  painter -> setRenderHint(QPainter::Antialiasing, false);
247  painter -> setRenderHint(QPainter::TextAntialiasing, false);
248  painter -> setRenderHint(QPainter::SmoothPixmapTransform, false);
249 
250  //Draw the selected rect in grey
251  QPen t;
252  t.setColor(Qt::gray);
253  t.setStyle(Qt::DashDotLine);
254  t.setCosmetic(true);
255  painter -> setPen(t);
256  painter -> drawRoundRect(boundingRect(), 10, 10);
257 
258  painter -> restore();
259  }
260 
261 }
262 
267 void DiagramTextItem::focusInEvent(QFocusEvent *event)
268 {
269  QGraphicsTextItem::focusInEvent(event);
270 
271  setFlag(QGraphicsItem::ItemIsMovable, false);
272 
273  m_previous_html_text = toHtml();
274  m_previous_text = toPlainText();
275 }
276 
281 void DiagramTextItem::focusOutEvent(QFocusEvent *event)
282 {
283  QGraphicsTextItem::focusOutEvent(event);
284 
285  if(toPlainText() != m_previous_text)
286  emit textEdited(m_previous_text, toPlainText());
287 
288  QTextCursor cursor = textCursor();
289  cursor.clearSelection();
290  setTextCursor(cursor);
291 
292  //Bad hack to be re-entrant
293  setTextInteractionFlags(Qt::NoTextInteraction);
294 
295  setFlag(QGraphicsItem::ItemIsMovable, true);
296  setFlag(QGraphicsTextItem::ItemIsFocusable, false);
297 }
298 
303 void DiagramTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) {
304  if (!(textInteractionFlags() & Qt::TextEditable) && !m_no_editable) {
305  // rend le champ de texte editable
306  setTextInteractionFlags(Qt::TextEditorInteraction);
307 
308  // edite le champ de texte
309  setFocus(Qt::MouseFocusReason);
310  } else {
311  QGraphicsTextItem::mouseDoubleClickEvent(event);
312  }
313 }
314 
319 void DiagramTextItem::mousePressEvent (QGraphicsSceneMouseEvent *event)
320 {
321  if (event->button() == Qt::LeftButton)
322  {
323  m_first_move = true;
324  //Save the pos of item at the beggining of the movement
325  m_mouse_to_origin_movement = pos() - event->scenePos();
326  }
327  QGraphicsTextItem::mousePressEvent(event);
328 }
329 
334 void DiagramTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
335  if (textInteractionFlags() & Qt::TextEditable) QGraphicsTextItem::mouseMoveEvent(event);
336 
337  else if ((flags() & QGraphicsItem::ItemIsMovable) && (event -> buttons() & Qt::LeftButton)) {
338  Diagram *diagram_ = diagram();
339 
340  //This is first move, we signal it to parent diagram
341  if(diagram_ && m_first_move)
342  diagram_->elementsMover().beginMovement(diagram_, this);
343 
344  QPointF old_pos = pos();
345 
346  //Set the actual pos
347  QPointF new_pos = event->scenePos() + m_mouse_to_origin_movement;
348  event->modifiers() == Qt::ControlModifier ? setPos(new_pos) : setPos(Diagram::snapToGrid(new_pos));
349 
350 
351  //Update the actual movement for other selected item
352  if (diagram_)
353  diagram_->elementsMover().continueMovement(pos() - old_pos);
354  }
355 
356  else event -> ignore();
357 
358  m_first_move = false;
359 }
360 
365 void DiagramTextItem::mouseReleaseEvent (QGraphicsSceneMouseEvent *event)
366 {
367  //Signal to diagram movement is finish
368  if (diagram() && (event->button() == Qt::LeftButton))
369  {
371  event->accept();
372  if (event->buttonDownScenePos(Qt::LeftButton) != event->scenePos()) {
373  return;
374  }
375  }
376  if (event->modifiers() & Qt::ControlModifier && (event->button() == Qt::LeftButton))
377  {
378  setSelected(!isSelected());
379  event->accept();
380  }
381  else {
382  QGraphicsTextItem::mouseReleaseEvent(event);
383  }
384 }
385 
392 void DiagramTextItem::applyRotation(const qreal &angle) {
393  setRotation(QET::correctAngle(rotation()+angle));
394 }
395 
401 {
402  m_alignment_rect = boundingRect();
403 }
404 
411 {
413  return;
414 
415  QTransform transform;
416  transform.rotate(this->rotation());
417  qreal x,xa, y,ya;
418  x=xa=0;
419  y=ya=0;
420 
421  if(m_alignment &Qt::AlignRight)
422  {
423  x = m_alignment_rect.right();
424  xa = boundingRect().right();
425  }
426  else if(m_alignment &Qt::AlignHCenter)
427  {
428  x = m_alignment_rect.center().x();
429  xa = boundingRect().center().x();
430  }
431 
432  if(m_alignment &Qt::AlignBottom)
433  {
434  y = m_alignment_rect.bottom();
435  ya = boundingRect().bottom();
436  }
437  else if(m_alignment &Qt::AlignVCenter)
438  {
439  y = m_alignment_rect.center().y();
440  ya = boundingRect().center().y();
441  }
442 
443  QPointF p = transform.map(QPointF(x,y));
444  QPointF pa = transform.map(QPointF(xa,ya));
445  QPointF diff = pa-p;
446 
447  setPos(this->pos() - diff);
448 }
449 
454 {
455  QWidget *parent = nullptr;
456  if (scene() && scene()->views().size())
457  parent = scene()->views().first();
458 
460  connect(&editor, &qdesigner_internal::RichTextEditorDialog::applyEditText, [this](QString text) {this->setHtml(text);});
461  editor.setText(toHtml());
462  editor.exec();
463 }
464 
465 
466 
472 void DiagramTextItem::hoverEnterEvent(QGraphicsSceneHoverEvent *e) {
473  Q_UNUSED(e);
474 
475  m_mouse_hover = true;
476  QString str_ToolTip = toPlainText();
477  setToolTip( str_ToolTip );
478  update();
479 }
480 
486 void DiagramTextItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *e) {
487  Q_UNUSED(e);
488  m_mouse_hover = false;
489  update();
490 }
491 
496 void DiagramTextItem::hoverMoveEvent(QGraphicsSceneHoverEvent *e) {
497  Q_UNUSED(e);
498  QGraphicsTextItem::hoverMoveEvent(e);
499 }
void fontChanged(QFont font)
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override
Qt::Alignment alignment() const
void setHtml(const QString &text)
void continueMovement(const QPointF &)
ElementsMover::continueMovement Add a move to the current movement.
void textEdited(const QString &old_str, const QString &new_str)
void setColor(const QColor &color)
void hoverLeaveEvent(QGraphicsSceneHoverEvent *) override
bool isHtml() const
QPointF mapMovementFromScene(const QPointF &) const
void finishAlignment()
DiagramTextItem::finishAlignment Call this function after changing the bouding rect of this text to s...
void colorChanged(QColor color)
void focusInEvent(QFocusEvent *) override
DiagramTextItem::focusInEvent.
void build()
DiagramTextItem::build Build this item with default value.
virtual QDomElement toXml(QDomDocument &) const
DiagramTextItem::toXml This method do nothing and return an empty DomElement This is used to be inher...
void prepareAlignment()
DiagramTextItem::prepareAlignment Call this function before changing the bounding rect of this text...
QPointF mapMovementToParent(const QPointF &) const
void setPlainText(const QString &text)
void edit()
Edit the text with HtmlEditor.
void endMovement()
ElementsMover::endMovement Ended the current movement by creating an undo added to the undostack of t...
void hoverEnterEvent(QGraphicsSceneHoverEvent *) override
QString m_previous_html_text
void setAlignment(const Qt::Alignment &alignment)
ElementsMover & elementsMover()
Definition: diagram.cpp:1499
virtual void applyRotation(const qreal &)
int beginMovement(Diagram *, QGraphicsItem *=nullptr)
ElementsMover::beginMovement Start a new movement.
DiagramTextItem(QGraphicsItem *=nullptr)
DiagramTextItem::DiagramTextItem.
qreal correctAngle(const qreal &)
Definition: qet.cpp:505
QPointF m_mouse_to_origin_movement
void alignmentChanged(Qt::Alignment alignment)
QPointF mapMovementToScene(const QPointF &) const
void mousePressEvent(QGraphicsSceneMouseEvent *event) override
DiagramTextItem::mousePressEvent.
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override
DiagramTextItem::mouseReleaseEvent.
QPointF mapMovementFromParent(const QPointF &) const
Qt::Alignment m_alignment
QIcon tr
Definition: qeticons.cpp:204
void focusOutEvent(QFocusEvent *) override
DiagramTextItem::focusOutEvent.
static QFont diagramTextsItemFont(qreal=-1.0)
QETApp::diagramTextsItemFont the font for to use in independent text item.
Definition: qetapp.cpp:934
static QPointF snapToGrid(const QPointF &p)
Diagram::snapToGrid Return a nearest snap point of p.
Definition: diagram.cpp:1653
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) override
DiagramTextItem::paint Draw this text field. This method draw the text by calling QGraphicsTextItem::...
void setFont(const QFont &font)
void hoverMoveEvent(QGraphicsSceneHoverEvent *) override
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override
DiagramTextItem::mouseMoveEvent.
QRectF frameRect() const
DiagramTextItem::frameRect.
QColor color() const
void setNoEditable(bool e=true)
Diagram * diagram() const
DiagramTextItem::diagram.