QElectroTech  0.70
dynamicelementtextitem.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 "dynamicelementtextitem.h"
19 #include "qet.h"
20 #include "element.h"
21 #include "qetapp.h"
22 #include "diagram.h"
24 #include "terminal.h"
25 #include "conductor.h"
26 #include "elementtextitemgroup.h"
27 #include "crossrefitem.h"
28 
29 #include <QDomDocument>
30 #include <QDomElement>
31 #include <QGraphicsSceneMouseEvent>
32 
39  m_parent_element(parent_element),
40  m_uuid(QUuid::createUuid())
41 {
43  setText(tr("Texte"));
44  setParentItem(parent_element);
45  QSettings settings;
46  setRotation(settings.value("dynamic_text_rotation", 0).toInt());
47  setTextWidth(settings.value("dynamic_text_widht", -1).toInt());
48  connect(this, &DynamicElementTextItem::textEdited, [this](const QString &old_str, const QString &new_str)
49  {
50  if(this->m_parent_element && this->m_parent_element->diagram())
51  {
52  QUndoCommand *undo = new QPropertyUndoCommand(this, "text", old_str, new_str);
53  undo->setText(tr("Éditer un texte d'élément"));
54  this->m_parent_element->diagram()->undoStack().push(undo);
55  }
56  });
57 
58  //Option when text is displayed in multiple line
59  QTextOption option = document()->defaultTextOption();
60  option.setAlignment(Qt::AlignHCenter);
61  option.setWrapMode(QTextOption::WordWrap);
62  document()->setDefaultTextOption(option);
63 }
64 
66 {}
67 
73 {
75  return deti.metaObject()->enumerator(deti.metaObject()->indexOfEnumerator("TextFrom"));
76 }
77 
79 {}
80 
87 QDomElement DynamicElementTextItem::toXml(QDomDocument &dom_doc) const
88 {
89  QDomElement root_element = dom_doc.createElement(xmlTaggName());
90 
91  root_element.setAttribute("x", QString::number(pos().x()));
92  root_element.setAttribute("y", QString::number(pos().y()));
93  root_element.setAttribute("rotation", QString::number(QET::correctAngle(rotation())));
94  root_element.setAttribute("uuid", m_uuid.toString());
95  root_element.setAttribute("frame", m_frame? "true" : "false");
96  root_element.setAttribute("text_width", QString::number(m_text_width));
97  root_element.setAttribute("font", font().toString());
98 
99  QMetaEnum me = textFromMetaEnum();
100  root_element.setAttribute("text_from", me.valueToKey(m_text_from));
101 
102  me = QMetaEnum::fromType<Qt::Alignment>();
103  if(this->alignment() &Qt::AlignRight)
104  root_element.setAttribute("Halignment", me.valueToKey(Qt::AlignRight));
105  else if(this->alignment() &Qt::AlignLeft)
106  root_element.setAttribute("Halignment", me.valueToKey(Qt::AlignLeft));
107  else if(this->alignment() &Qt::AlignHCenter)
108  root_element.setAttribute("Halignment", me.valueToKey(Qt::AlignHCenter));
109 
110  if(this->alignment() &Qt::AlignBottom)
111  root_element.setAttribute("Valignment", me.valueToKey(Qt::AlignBottom));
112  else if(this->alignment() & Qt::AlignTop)
113  root_element.setAttribute("Valignment", me.valueToKey(Qt::AlignTop));
114  else if(this->alignment() &Qt::AlignVCenter)
115  root_element.setAttribute("Valignment", me.valueToKey(Qt::AlignVCenter));
116 
117 
118  QDomElement dom_text = dom_doc.createElement("text");
119  dom_text.appendChild(dom_doc.createTextNode(toPlainText()));
120  root_element.appendChild(dom_text);
121 
122  //Info name
123  if(!m_info_name.isEmpty())
124  {
125  QDomElement dom_info_name = dom_doc.createElement("info_name");
126  dom_info_name.appendChild(dom_doc.createTextNode(m_info_name));
127  root_element.appendChild(dom_info_name);
128  }
129 
130  //Composite text
131  if(!m_composite_text.isEmpty())
132  {
133  QDomElement dom_comp_text = dom_doc.createElement("composite_text");
134  dom_comp_text.appendChild(dom_doc.createTextNode(m_composite_text));
135  root_element.appendChild(dom_comp_text);
136  }
137 
138  //Color
139  if(color() != QColor(Qt::black))
140  {
141  QDomElement dom_color = dom_doc.createElement("color");
142  dom_color.appendChild(dom_doc.createTextNode(color().name()));
143  root_element.appendChild(dom_color);
144  }
145 
146  return root_element;
147 }
148 
154 void DynamicElementTextItem::fromXml(const QDomElement &dom_elmt)
155 {
156  if (dom_elmt.tagName() != xmlTaggName()) {
157  qDebug() << "DynamicElementTextItem::fromXml : Wrong tagg name";
158  return;
159  }
160 
161  QGraphicsTextItem::setRotation(dom_elmt.attribute("rotation", QString::number(0)).toDouble());
162 
163  if (dom_elmt.hasAttribute("font"))
164  {
165  QFont font;
166  font.fromString(dom_elmt.attribute("font"));
167  setFont(font);
168  }
169  else //Retrocompatibility during the 0.7 dev because the font property was added lately. TODO remove this part in futur
170  {
171  QFont font_(dom_elmt.attribute("font_family", font().family()),
172  dom_elmt.attribute("font_size", QString::number(9)).toInt());
173  font_.setStyleName(dom_elmt.attribute("dynamicitemstyle", font().styleName()));
174  setFont(font_);
175  }
176 
177  m_uuid = QUuid(dom_elmt.attribute("uuid", QUuid::createUuid().toString()));
178  setFrame(dom_elmt.attribute("frame", "false") == "true"? true : false);
179  setTextWidth(dom_elmt.attribute("text_width", QString::number(-1)).toDouble());
180 
181  //Text from
182  QMetaEnum me = textFromMetaEnum();
183  setTextFrom(DynamicElementTextItem::TextFrom(me.keyToValue(dom_elmt.attribute("text_from").toStdString().data())));
184 
185  me = QMetaEnum::fromType<Qt::Alignment>();
186  if(dom_elmt.hasAttribute("Halignment"))
187  setAlignment(Qt::Alignment(me.keyToValue(dom_elmt.attribute("Halignment").toStdString().data())));
188  if(dom_elmt.hasAttribute(("Valignment")))
189  setAlignment(Qt::Alignment(me.keyToValue(dom_elmt.attribute("Valignment").toStdString().data())) | this->alignment());
190 
191  //Text
192  QDomElement dom_text = dom_elmt.firstChildElement("text");
193  if (!dom_text.isNull())
194  setText(dom_text.text());
195 
196  //Info name
197  QDomElement dom_info_name = dom_elmt.firstChildElement("info_name");
198  if(!dom_info_name.isNull())
199  setInfoName(dom_info_name.text());
200 
201  //Composite text
202  QDomElement dom_comp_text = dom_elmt.firstChildElement("composite_text");
203  if(!dom_comp_text.isNull())
204  setCompositeText(dom_comp_text.text());
205 
206  //Color
207  QDomElement dom_color = dom_elmt.firstChildElement("color");
208  if(!dom_color.isNull())
209  setColor(QColor(dom_color.text()));
210 
211  //Force the update of the displayed text
213 
214  QGraphicsTextItem::setPos(dom_elmt.attribute("x", QString::number(0)).toDouble(),
215  dom_elmt.attribute("y", QString::number(0)).toDouble());
216 }
217 
225  return m_parent_element;
226 }
227 
234 {
235  if(parentItem())
236  {
237  if(ElementTextItemGroup *grp = dynamic_cast<ElementTextItemGroup *>(parentItem()))
238  return grp;
239  }
240 
241  return nullptr;
242 }
243 
256 {
257  Element *elmt = parentElement();
258  if(!elmt)
259  return nullptr;
260 
261  switch (elmt->linkType())
262  {
263  case Element::Simple:
264  return elmt;
265  case Element::NextReport:
266  return elmt;
268  return elmt;
269  case Element::Master:
270  return elmt;
271  case Element::Slave:
272  {
273  if(elmt->linkedElements().isEmpty())
274  return nullptr;
275  else
276  return elmt->linkedElements().first();
277  }
278  case Element::Terminale:
279  return elmt;
280  default:
281  return elmt;
282  }
283 }
284 
291 {
292  if ((m_text_from == ElementInfo && m_info_name == "label") ||
293  (m_text_from == CompositeText && m_composite_text.contains("%{label}")))
294  {
295  if(m_parent_element.data()->linkType() & Element::AllReport)
296  {
299  }
300  else
301  {
303  updateLabel();
304  }
305  }
306 }
307 
313  return m_text_from;
314 }
315 
322 {
323  if(m_text_from == text_from)
324  return;
325 
326  setNoEditable(text_from == UserText? false : true);
328 
329  TextFrom old_text_from = m_text_from;
330  m_text_from = text_from;
331 
332  if(m_text_from == UserText)
333  {
336  }
337  else if (m_text_from == ElementInfo && elementUseForInfo())
338  {
339  if(m_info_name == "label")
340  {
342  updateLabel();
343  }
344  else
345  setPlainText(elementUseForInfo()->elementInformations().value(m_info_name).toString());
346 
347  if(old_text_from == UserText)
349  }
351  {
352  if(m_composite_text.contains("%{label}"))
353  {
355  updateLabel();
356  }
357  else
359 
360  if(old_text_from == UserText)
362  }
363 
364  if(m_parent_element.data()->linkType() == Element::Master ||
365  m_parent_element.data()->linkType() == Element::Slave)
366  updateXref();
367 
369 }
370 
375 QString DynamicElementTextItem::text() const {
376  return m_text;
377 }
378 
384 void DynamicElementTextItem::setText(const QString &text)
385 {
386  m_text = text;
389  emit textChanged(m_text);
390 }
391 
397 void DynamicElementTextItem::setInfoName(const QString &info_name)
398 {
399  QString old_info_name = m_info_name;
400  m_info_name = info_name;
401 
402 
403  if(old_info_name == "label")
404  {
406  updateXref();
407  }
408 
409  if (m_parent_element && (m_parent_element.data()->linkType() & Element::AllReport)) //special treatment for report
410  {
411  if(old_info_name != info_name)
412  {
413  if(old_info_name == "label") {
415  }
416  if(info_name == "label")
417  {
420  }
421  else
423  }
424  }
425  else if (m_info_name == "label" && elementUseForInfo())
426  {
428  updateLabel();
429  updateXref();
430  }
432  setPlainText(elementUseForInfo()->elementInformations().value(info_name).toString());
433  }
434 
435  emit infoNameChanged(info_name);
436 }
437 
442 QString DynamicElementTextItem::infoName() const {
443  return m_info_name;
444 }
445 
452 {
453  QString old_composite_text = m_composite_text;
455 
456  if(old_composite_text.contains("%{label}"))
457  {
459  updateXref();
460  }
461 
462  if (m_parent_element && (m_parent_element.data()->linkType() & Element::AllReport)) //special treatment for report
463  {
464  /*
465  * May be in some case the old and new composite text have both the var %{label},
466  * and so we don't have to remove connection and after set conection,
467  * but for that we must to do several check and because I'm lazy,
468  * in every case I remove connection and set it after ;)
469  */
470  if(old_composite_text.contains("%{label}"))
472  if(m_composite_text.contains("%{label}"))
474 
476  }
477  else if (m_composite_text.contains("%{label}") && elementUseForInfo())
478  {
480  updateLabel();
481  updateXref();
482  }
484  {
485  DiagramContext dc;
486  if(elementUseForInfo())
489  }
490 
492 }
493 
499 {
500  return m_composite_text;
501 }
502 
503 void DynamicElementTextItem::setFrame(const bool frame)
504 {
505  m_frame = frame;
506  update();
507  emit frameChanged(m_frame);
508 }
509 
511 {
512  return m_frame;
513 }
514 
516 {
517  return m_uuid;
518 }
519 
524 void DynamicElementTextItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
525 {
526  //The text become selected, we set the real color, otherwise the editor will display the color of text as blue,
527  //but this is not the color set by the user.
528  if(m_user_color.isValid())
529  {
530  setDefaultTextColor(m_user_color);
531  m_user_color = QColor(); //m_user_color is now invalid
533  m_slave_Xref_item->setDefaultTextColor(Qt::black);
534  }
535 
537 }
538 
543 void DynamicElementTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
544 {
545  if((event->buttons() & Qt::LeftButton) && (flags() & ItemIsMovable))
546  {
547  if(diagram() && m_first_move)
549 
550  if(m_first_move)
551  {
552  m_initial_position = pos();
553  if(parentElement())
554  parentElement()->setHighlighted(true);
555  }
556 
557  QPointF current_parent_pos;
558  QPointF button_down_parent_pos;
559  current_parent_pos = mapToParent(mapFromScene(event->scenePos()));
560  button_down_parent_pos = mapToParent(mapFromScene(event->buttonDownScenePos(Qt::LeftButton)));
561 
562  QPointF new_pos = m_initial_position + current_parent_pos - button_down_parent_pos;
563  event->modifiers() == Qt::ControlModifier ? setPos(new_pos) : setPos(Diagram::snapToGrid(new_pos));
564 
565  if(diagram())
567  } else {
568  event->ignore();
569  }
570 
571  if(m_first_move)
572  m_first_move = false;
573 }
574 
579 void DynamicElementTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
580 {
581  if (m_parent_element)
582  m_parent_element->setHighlighted(false);
583 
584  if(m_parent_element && m_parent_element->diagram())
585  m_parent_element.data()->diagram()->elementTextsMover().endMovement();
586 
587  if(!(event->modifiers() & Qt::ControlModifier))
588  QGraphicsTextItem::mouseReleaseEvent(event);
589 }
590 
598 void DynamicElementTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
599 {
602 }
603 
611 void DynamicElementTextItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
612 {
614 
615  //If the text is selected we set the real color, otherwise the editor will display the color of text as blue,
616  //but this is not the color set by the user.
617  if(isSelected())
618  return;
619 
620  if ((parentElement()->linkType() & Element::AllReport) && m_other_report)
621  {
622  if( (m_text_from == ElementInfo && m_info_name == "label") ||
623  (m_text_from == CompositeText && m_composite_text.contains("%{label}")) )
624  {
625  m_user_color = color();
626  setDefaultTextColor(Qt::blue);
627  }
628  }
629 }
630 
635 void DynamicElementTextItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
636 {
638 
639  if(m_user_color.isValid())
640  {
641  setDefaultTextColor(m_user_color);
642  m_user_color = QColor(); //m_user_color is now invalid
643  }
644 
645 }
646 
647 void DynamicElementTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
648 {
649  DiagramTextItem::paint(painter, option, widget);
650 
651  if (m_frame)
652  {
653  painter->save();
654  painter->setFont(QETApp::dynamicTextsItemFont(font().pointSize()));
655 
656  //Adjust the thickness according to the font size,
657  qreal w=0.3;
658  if(font().pointSize() >= 5)
659  {
660  w = font().pointSizeF()*0.1;
661  if(w > 2.5)
662  w = 2.5;
663  }
664 
665  QPen pen;
666  pen.setColor(color());
667  pen.setWidthF(w);
668  painter->setPen(pen);
669  painter->setRenderHint(QPainter::Antialiasing);
670 
671  //Adjust the rounding of the rectangle according to the size of the font
672  qreal ro = font().pointSizeF()/3;
673  painter->drawRoundedRect(frameRect(), ro, ro);
674 
675  painter->restore();
676  }
677 }
678 
679 QVariant DynamicElementTextItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
680 {
681  //The first time this text is added to a scene, we make several cheking and connection
682  //according to the link type of the parent element
683  if(change == QGraphicsItem::ItemSceneHasChanged && m_first_scene_change)
684  {
685  if(m_parent_element.isNull())
686  return QGraphicsObject::itemChange(change, value);
687 
688  //If the parent is slave, we keep aware about the changement of master.
689  if(m_parent_element.data()->linkType() == Element::Slave)
690  {
692  //The parent is already linked, wa call master changed for init the connection
693  if(!m_parent_element.data()->linkedElements().isEmpty())
694  masterChanged();
695  }
696  else if(m_parent_element.data()->linkType() & Element::AllReport)
697  {
698  //Get the report formula, and add connection to keep up to date the formula.
699  if (m_parent_element.data()->diagram() && m_parent_element.data()->diagram()->project())
700  {
701  m_report_formula = m_parent_element.data()->diagram()->project()->defaultReportProperties();
703  }
704 
705  //Add connection to keep up to date the status of the element linked to the parent folio report of this text.
707  //The parent is already linked, we call reportChanged for init the connection
708  if(!m_parent_element.data()->linkedElements().isEmpty())
709  reportChanged();
710 
711  if(m_parent_element.data()->terminals().size())
712  {
713  //Add connection to keep up date the conductors added or removed to the parent folio report element
714  connect(m_parent_element.data()->terminals().first(), &Terminal::conductorWasAdded, this, &DynamicElementTextItem::conductorWasAdded);
716  }
717  //Get a conductor in the potential
719  }
720  else if(m_parent_element.data()->linkType() == Element::Master)
721  {
723  if(m_parent_element.data()->diagram())
724  connect(m_parent_element.data()->diagram()->project(), &QETProject::XRefPropertiesChanged, this, &DynamicElementTextItem::updateXref);
725  if(!m_parent_element.data()->linkedElements().isEmpty())
726  updateXref();
727  }
728 
729  m_first_scene_change = false;
730  return QGraphicsObject::itemChange(change, value);
731  }
732  else if (change == QGraphicsItem::ItemParentHasChanged)
733  {
734  updateXref();
735  updateXref();
736  }
737 
738  return QGraphicsObject::itemChange(change, value);
739 }
740 
741 bool DynamicElementTextItem::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
742 {
743  if(watched != m_slave_Xref_item)
744  return false;
745 
746  if(event->type() == QEvent::GraphicsSceneHoverEnter) {
747  m_slave_Xref_item->setDefaultTextColor(Qt::blue);
748  return true;
749  }
750  else if(event->type() == QEvent::GraphicsSceneHoverLeave) {
751  m_slave_Xref_item->setDefaultTextColor(Qt::black);
752  return true;
753  }
754  else if(event->type() == QEvent::GraphicsSceneMouseDoubleClick) {
756  return true;
757  }
758 
759  return false;
760 }
761 
763 {
764  DiagramContext dc;
765  if(elementUseForInfo())
767 
768  QString final_text;
769  Element *element = elementUseForInfo();
770 
771  if (m_text_from == ElementInfo)
772  {
773  //If the info is the label, then we must to make some connection
774  //if the label is created from a formula
775  if(m_info_name == "label")
776  {
778 
779  if (dc.value("formula").toString().isEmpty())
780  final_text = dc.value(m_info_name).toString();
781  else
782  final_text = autonum::AssignVariables::formulaToLabel(dc.value("formula").toString(), element->rSequenceStruct(), element->diagram(), element);
783  }
784  else
785  final_text = dc.value(m_info_name).toString();
786  }
787  else if (m_text_from == CompositeText)
788  {
789  //If the composite have the label variable, we must to make some
790  //connection if the label is created from a formula
791  if (m_composite_text.contains("%{label}"))
793 
795  }
796  else if (m_text_from == UserText)
797  final_text = m_text;
798 
799  setPlainText(final_text);
800  emit plainTextChanged();
801 }
802 
809 {
810  //First we remove the old connection
812  {
814  m_master_element.clear();
815  updateXref();
816  }
817 
818  if(elementUseForInfo())
819  {
823 
824  updateXref();
825  }
826 
827  //Because master changed we update this text
829 }
830 
837 {
838  /*
839  * When the dynamic text are added by a drag & drop from the element panel,
840  * the connection below are made in the constructor.
841  * If the text are added at load of a .qet file, the text is not yet added to a diagram then the connection is not made.
842  * We make it now, because when the linked report changed, that mean this text is in a diagram
843  */
845  {
846  //Get the report formula, and add connection to keep up to date the formula.
847  if (parentElement()->diagram() && parentElement()->diagram()->project())
848  {
851  }
852  }
853 
854  bool text_have_label = false;
855 
856  if((textFrom() == ElementInfo && m_info_name == "label") ||
857  (textFrom() == CompositeText && m_composite_text.contains("%{label}")))
858  text_have_label = true;
859 
860  if(text_have_label)
862 
863  m_other_report.clear();
864  if(!m_parent_element.data()->linkedElements().isEmpty())
865  m_other_report = m_parent_element.data()->linkedElements().first();
866 
867  //Because linked report was changed, we ensure there is a conductor watched
869 
870  if(text_have_label)
871  {
874  }
875 }
876 
882 {
884 
885  if(m_text_from == ElementInfo && m_info_name == "label")
887 }
888 
890 {
891  if(m_other_report.isNull() || formula.isEmpty())
892  return;
893 
894  Element *other_elmt = m_other_report.data();
895  QString string = formula;
896  Diagram *other_diagram = m_other_report.data()->diagram();
897 
898  //Because the variable %F is a reference to another text which can contain variables,
899  //we must to replace %F by the real text, to check if the real text contain the variable %id
900  if (other_diagram && string.contains("%F"))
901  {
902  m_F_str = other_diagram->border_and_titleblock.folio();
903  string.replace("%F", other_diagram->border_and_titleblock.folio());
905  }
906 
907  if (other_diagram && (string.contains("%f") || string.contains("%id")))
908  {
911  }
912  if (string.contains("%l"))
913  connect(other_elmt, &Element::yChanged, this, &DynamicElementTextItem::updateReportText);
914  if (string.contains("%c"))
915  connect(other_elmt, &Element::xChanged, this, &DynamicElementTextItem::updateReportText);
916 }
917 
919 {
920  if(m_other_report.isNull() || formula.isEmpty())
921  return;
922 
923  Element *other_element = m_other_report.data();
924  QString string = formula;
925  Diagram *other_diagram = m_other_report.data()->diagram();
926 
927  //Because the variable %F is a reference to another text which can contain variables,
928  //we must to replace %F by the real text, to check if the real text contain the variable %id
929  if (other_diagram && string.contains("%F"))
930  {
931  string.replace("%F", m_F_str);
933  }
934 
935  if (other_diagram && (string.contains("%f") || string.contains("%id")))
937  if (string.contains("%l"))
938  disconnect(other_element, &Element::yChanged, this, &DynamicElementTextItem::updateReportText);
939  if (string.contains("%c"))
940  disconnect(other_element, &Element::xChanged, this, &DynamicElementTextItem::updateReportText);
941 
942 }
943 
949 {
950  if ((m_text_from == ElementInfo && m_info_name == "label") ||
951  (m_text_from == CompositeText && m_composite_text.contains("%{label}")))
952  {
954 
955  Element *element = elementUseForInfo();
956  if (!element)
957  return;
958 
959  Diagram *diagram = element->diagram();
960  QString formula = element->elementInformations().value("formula").toString();
961 
962  //Label is frozen, so we don't update it.
963  if (element->isFreezeLabel())
964  return;
965 
966  if (diagram && formula.contains("%F"))
967  {
969  formula.replace("%F", m_F_str);
971  }
972 
973  if (diagram && (formula.contains("%f") || formula.contains("%id")))
974  {
977  }
978  if (formula.contains("%l"))
979  m_formula_connection << connect(element, &Element::yChanged, this, &DynamicElementTextItem::updateLabel);
980  if (formula.contains("%c"))
981  m_formula_connection << connect(element, &Element::xChanged, this, &DynamicElementTextItem::updateLabel);
982 
983  }
984 }
985 
987 {
988  for (const QMetaObject::Connection& con : m_formula_connection)
989  disconnect(con);
990  m_formula_connection.clear();
991 }
992 
994 {
995  if(!(m_parent_element.data()->linkType() & Element::AllReport))
996  return;
997 
1000  updateReportText();
1001 }
1002 
1008 {
1009  if(!(m_parent_element.data()->linkType() & Element::AllReport))
1010  return;
1011 
1012  if (m_text_from == ElementInfo && m_info_name == "label")
1013  {
1014  if(m_other_report)
1015  {
1016  Element *elmt = m_other_report.data();
1017  QString label = m_report_formula;
1018  label = autonum::AssignVariables::formulaToLabel(label, elmt->rSequenceStruct(), elmt->diagram(), elmt);
1019  setPlainText(label);
1020  }
1021  else
1022  {
1023  setPlainText("");
1024  }
1025  }
1026  else if (m_text_from == CompositeText) {
1028  }
1029 }
1030 
1038 {
1039  if ((m_text_from == ElementInfo && m_info_name == "label") ||
1040  (m_text_from == CompositeText && m_composite_text.contains("%{label}")))
1041  {
1042  DiagramContext dc;
1043  if(elementUseForInfo())
1045 
1046  Element *element = elementUseForInfo();
1047 
1048  if(m_text_from == ElementInfo)
1049  {
1050  if(dc.value("formula").toString().isEmpty())
1051  setPlainText(dc.value("label").toString());
1052  else
1053  setPlainText(autonum::AssignVariables::formulaToLabel(dc.value("formula").toString(), element->rSequenceStruct(), element->diagram(), element));
1054  }
1055  else if (m_text_from == CompositeText)
1057  }
1058 }
1059 
1066 {
1067  Q_UNUSED(conductor)
1069 }
1070 
1077 {
1078  if(m_watched_conductor.data() == conductor)
1079  {
1081  m_watched_conductor.clear();
1083  }
1084 }
1085 
1092 {
1093  if(parentElement() && (parentElement()->linkType() & Element::AllReport))
1094  {
1095  if(parentElement()->terminals().isEmpty())
1096  return;
1097 
1098  /*
1099  * #First case, if m_watched_conductor is a conductor of the parent report, everything is ok
1100  * #Second case, if the conductors list of parent report element is not empty,
1101  * we set one of these conductor as m_watched_conductor, even if m_watched_conductor is already set,
1102  * because that mean the conductor is a conductor of the linked report, and we prefer to set a conductor
1103  * owned by the parent report element of this text.
1104  * #third case, if m_watched_conductor is null, we set a conductor of the linked report, if any.
1105  */
1106  QList<Conductor *> c_list = parentElement()->terminals().first()->conductors();
1107 
1108  if(!c_list.isEmpty() && c_list.contains(m_watched_conductor.data()))
1109  return;
1110  else if(!c_list.isEmpty())
1111  {
1112  if(!m_watched_conductor.isNull())
1114 
1115  m_watched_conductor = c_list.first();
1117  }
1118  else if(m_watched_conductor.isNull() && m_other_report)
1119  {
1120  if (!m_other_report.data()->terminals().first()->conductors().isEmpty())
1121  {
1122  m_watched_conductor = m_other_report.data()->terminals().first()->conductors().first();
1124  }
1125  }
1126  }
1127  else //This text haven't got a parent element, then ther isn't a conductor in the potential
1128  {
1129  if(!m_watched_conductor.isNull())
1131 
1132  m_watched_conductor.clear();
1133  }
1134 }
1135 
1141 {
1142  if(m_parent_element && (m_parent_element.data()->linkType() & Element::AllReport))
1143  {
1144  if(m_text_from == ElementInfo)
1145  {
1146  if(m_info_name == "function")
1147  setPlainText(m_watched_conductor? m_watched_conductor.data()->properties().m_function : "");
1148  else if (m_info_name == "tension-protocol")
1149  setPlainText(m_watched_conductor? m_watched_conductor.data()->properties().m_tension_protocol : "");
1150  }
1151  else if (m_text_from == CompositeText) {
1153  }
1154  }
1155 }
1156 
1164 {
1165  QString string;
1166 
1167  if(m_parent_element.data()->linkType() & Element::AllReport)
1168  {
1169  string = m_composite_text;
1170 
1171  if (string.contains("%{label}") && m_other_report)
1172  {
1173  Element *elmt = m_other_report.data();
1174  QString label = m_report_formula;
1175  label = autonum::AssignVariables::formulaToLabel(label, elmt->rSequenceStruct(), elmt->diagram(), elmt);
1176  string.replace("%{label}", label);
1177  }
1178  if (m_watched_conductor)
1179  {
1180  if(string.contains("%{function}"))
1181  string.replace("%{function}", m_watched_conductor.data()->properties().m_function);
1182  if(string.contains("%{tension-protocol}"))
1183  string.replace("%{tension-protocol}", m_watched_conductor.data()->properties().m_tension_protocol);
1184  }
1185  }
1186 
1187  return string;
1188 }
1189 
1196 {
1197  if(!parentElement())
1198  return;
1199 
1200  Element *zoomed_element = nullptr;
1201 
1202  if(parentElement()->linkType() == Element::Slave && m_master_element)
1203  {
1204  if ((m_text_from == ElementInfo && m_info_name == "label") ||
1205  (m_text_from == CompositeText && m_composite_text.contains("%{label}")))
1206  zoomed_element = m_master_element.data();
1207  }
1208  if((parentElement()->linkType() & Element::AllReport) && m_other_report)
1209  {
1210  if((m_text_from == ElementInfo && m_info_name == "label") ||
1211  (m_text_from == CompositeText && m_composite_text.contains("%{label}")))
1212  zoomed_element = m_other_report.data();
1213  }
1214 
1215  if(zoomed_element)
1216  {
1217  //Unselect and ungrab mouse to prevent unwanted
1218  //move when linked element is in the same scene of this.
1219  setSelected(false);
1220  ungrabMouse();
1221 
1222  if(scene() != zoomed_element->scene())
1223  zoomed_element->diagram()->showMe();
1224  zoomed_element->setSelected(true);
1225 
1226  //Zoom to the element
1227  for(QGraphicsView *view : zoomed_element->scene()->views())
1228  {
1229  QRectF fit = zoomed_element->sceneBoundingRect();
1230  fit.adjust(-200, -200, 200, 200);
1231  view->fitInView(fit, Qt::KeepAspectRatioByExpanding);
1232  }
1233  }
1234 }
1235 
1241 {
1242  if(diagram())
1243  {
1244  if(m_parent_element.data()->linkType() == Element::Master)
1245  {
1246  XRefProperties xrp = diagram()->project()->defaultXRefProperties(m_parent_element.data()->kindInformations()["type"].toString());
1247 
1249  m_info_name == "label" &&
1250  !m_parent_element.data()->linkedElements().isEmpty() &&
1251  xrp.snapTo() == XRefProperties::Label)
1252  {
1253  //For add a Xref, this text must not be in a group
1254  if(!parentGroup())
1255  {
1256  if(!m_Xref_item)
1257  m_Xref_item = new CrossRefItem(m_parent_element.data(), this);
1258  return;
1259  }
1260  }
1261  }
1262  else if (m_parent_element.data()->linkType() == Element::Slave)
1263  {
1264  if(m_master_element && !parentGroup() &&
1265  (
1268  )
1269  )
1270  {
1271  XRefProperties xrp = diagram()->project()->defaultXRefProperties(m_master_element.data()->kindInformations()["type"].toString());
1272  QString xref_label = xrp.slaveLabel();
1273  xref_label = autonum::AssignVariables::formulaToLabel(xref_label, m_master_element.data()->rSequenceStruct(), m_master_element.data()->diagram(), m_master_element.data());
1274 
1275  if(!m_slave_Xref_item)
1276  {
1277  m_slave_Xref_item = new QGraphicsTextItem(xref_label, this);
1279  m_slave_Xref_item->installSceneEventFilter(this);
1280 
1281  m_update_slave_Xref_connection << connect(m_master_element.data(), &Element::xChanged, this, &DynamicElementTextItem::updateXref);
1282  m_update_slave_Xref_connection << connect(m_master_element.data(), &Element::yChanged, this, &DynamicElementTextItem::updateXref);
1287  }
1288  else
1289  m_slave_Xref_item->setPlainText(xref_label);
1290 
1291  QRectF r = boundingRect();
1292  QPointF pos(r.center().x() - m_slave_Xref_item->boundingRect().width()/2,
1293  r.bottom());
1294  m_slave_Xref_item->setPos(pos);
1295  return;
1296  }
1297  }
1298  }
1299 
1300  //There is no reason to have a xref, we delete it if exist
1301  if(m_Xref_item)
1302  {
1303  delete m_Xref_item;
1304  m_Xref_item = nullptr;
1305  }
1306 
1307  if(m_slave_Xref_item)
1308  {
1309  delete m_slave_Xref_item;
1310  m_slave_Xref_item = nullptr;
1312  }
1313 }
1314 
1315 void DynamicElementTextItem::setPlainText(const QString &text)
1316 {
1317  if (toPlainText() == text)
1318  return;
1319 
1320  bool update_alignment = true;
1321  if (diagram() && (diagram()->project()->state() == QETProject::ProjectParsingRunning))
1322  update_alignment = false;
1323  if (m_parent_element.data()->state() == QET::GIBuildingFromXml ||
1324  m_parent_element.data()->state() == QET::GILoadingFromXml)
1325  update_alignment = false;
1326 
1327  if (update_alignment) {
1328  prepareAlignment();
1329  }
1330 
1332 
1333  //User define a text width
1334  if (m_text_width > 0)
1335  {
1336  if (document()->size().width() > m_text_width)
1337  {
1338  document()->setTextWidth(m_text_width);
1339  if (document()->size().width() > m_text_width)
1340  {
1341  document()->setTextWidth(document()->idealWidth());
1342  }
1343  }
1344  }
1345 
1346  if (update_alignment) {
1347  finishAlignment();
1348  }
1349 
1350  if (m_Xref_item) {
1351  m_Xref_item->autoPos();
1352  }
1353  else if (m_slave_Xref_item)
1354  {
1355  QRectF r = boundingRect();
1356  QPointF pos(r.center().x() - m_slave_Xref_item->boundingRect().width()/2,
1357  r.bottom());
1358  m_slave_Xref_item->setPos(pos);
1359  }
1360 }
1361 
1363 {
1364  this->document()->setTextWidth(width);
1365  m_text_width = width;
1366  emit textWidthChanged(width);
1367 }
The CrossRefItem class This clas provide an item, for show the cross reference, like the contacts lin...
Definition: crossrefitem.h:40
The QPropertyUndoCommand class This undo command manage QProperty of a QObject. This undo command can...
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override
Qt::Alignment alignment() const
void refreshLabelConnection()
DynamicElementTextItem::refreshLabelConnection Refresh the connection of this text when the source of...
bool sceneEventFilter(QGraphicsItem *watched, QEvent *event) override
Item is currently building from a xml description (element)
Definition: qet.h:38
ElementTextItemGroup * parentGroup() const
DynamicElementTextItem::parentGroup.
virtual kind linkType() const
Definition: element.h:138
void textEdited(const QString &old_str, const QString &new_str)
QList< Element * > linkedElements()
Element::linkedElements.
Definition: element.h:229
QPointer< Conductor > m_watched_conductor
static QString formulaToLabel(QString formula, sequentialNumbers &seqStruct, Diagram *diagram, const Element *elmt=nullptr)
AssignVariables::formulaToLabel Return the with variable assigned (ready to be displayed) ...
QString infoName() const
void setColor(const QColor &color)
The DynamicElementTextItem class This class provide a simple text field of element who can be added o...
QMetaObject::Connection m_report_formula_con
QList< QMetaObject::Connection > m_formula_connection
void textFromChanged(DynamicElementTextItem::TextFrom text_from)
void setPotentialConductor()
DynamicElementTextItem::setPotentialConductor This function is only used when the parent element of t...
void conductorWasAdded(Conductor *conductor)
DynamicElementTextItem::conductorWasAdded Function only use when parent element is a folio report...
void hoverLeaveEvent(QGraphicsSceneHoverEvent *) override
The XRefProperties class this class store properties used by XrefItem.
DiagramContext elementInformations() const
Definition: element.h:89
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override
DynamicElementTextItem::hoverLeaveEvent.
void setCompositeText(const QString &text)
DynamicElementTextItem::setCompositeText Set the composite text of this text item to ...
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override
DynamicElementTextItem::mouseMoveEvent.
void finishAlignment()
DiagramTextItem::finishAlignment Call this function after changing the bouding rect of this text to s...
Diagram * diagram() const
QetGraphicsItem::diagram return the diagram of this item.
autonum::sequentialNumbers & rSequenceStruct()
Definition: element.h:96
QGraphicsTextItem * m_slave_Xref_item
void setPlainText(const QString &text)
QString slaveLabel() const
virtual void setHighlighted(bool)
Definition: element.cpp:162
void prepareAlignment()
DiagramTextItem::prepareAlignment Call this function before changing the bounding rect of this text...
void linkedElementChanged()
QVariant value(const QString &key) const
void reportFormulaChanged()
DynamicElementTextItem::reportFormulaChanged The report formula use in the project was changed...
int beginMovement(Diagram *diagram, QGraphicsItem *driver_item=nullptr)
ElementTextsMover::beginMovement Begin a movement.
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override
void setPlainText(const QString &text)
void conductorWasAdded(Conductor *conductor)
Element * elementUseForInfo() const
DynamicElementTextItem::elementUseForInfo.
QDomElement toXml(QDomDocument &dom_doc) const override
DynamicElementTextItem::toXml Export this text to xml.
void reportPropertiesChanged(const QString &old_str, const QString &new_str)
void titleBlockFolioChanged(const QString &)
titleBlockFolioChanged Signal emitted after Folio has changed
void hoverEnterEvent(QGraphicsSceneHoverEvent *) override
void frameChanged(bool frame)
void setAlignment(const Qt::Alignment &alignment)
void setFrame(const bool frame)
void reportChanged()
DynamicElementTextItem::reportChanged This function is only use when parent element of this text is a...
QList< Terminal * > terminals() const
Element::terminals.
Definition: element.cpp:124
void masterChanged()
DynamicElementTextItem::masterChanged This function is only use when the parent element is a slave...
ElementTextsMover & elementTextsMover()
Definition: diagram.cpp:1503
void updateXref()
DynamicElementTextItem::updateXref Create or delete the Xref according to the current properties of t...
void updateReportText()
DynamicElementTextItem::updateReportText This function is only use when this text is owned by a repor...
void conductorWasRemoved(Conductor *conductor)
DynamicElementTextItem::conductorWasRemoved Function only use when parent element is a folio report...
qreal correctAngle(const qreal &)
Definition: qet.cpp:505
QPointer< Element > m_parent_element
QPointer< Element > m_other_report
QString defaultReportProperties() const
Definition: qetproject.cpp:467
void conductorPropertiesChanged()
DynamicElementTextItem::conductorPropertiesChanged This function is only used when the parent element...
void setInfoName(const QString &info_name)
DynamicElementTextItem::setInfoName Set the information name of the parent element.
void zoomToLinkedElement()
DynamicElementTextItem::zoomToLinkedElement If the parent element is a folio report or a slave elemen...
QString compositeText() const
static QMetaEnum textFromMetaEnum()
DynamicElementTextItem::textFromMetaEnum.
void mousePressEvent(QGraphicsSceneMouseEvent *event) override
DiagramTextItem::mousePressEvent.
bool isFreezeLabel() const
Definition: element.h:101
QPointer< Element > m_master_element
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override
DynamicElementTextItem::mouseDoubleClickEvent Reimplemented functions, for add extra feature when thi...
QIcon tr
Definition: qeticons.cpp:204
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override
DynamicElementTextItem::mouseReleaseEvent.
static QFont dynamicTextsItemFont(qreal=-1.0)
QETApp::dynamicTextsFont the defaukt font of dynamic element text item.
Definition: qetapp.cpp:962
QString folio() const
void removeConnectionForReportFormula(const QString &formula)
void continueMovement(QGraphicsSceneMouseEvent *event)
Element * parentElement() const
DynamicElementTextItem::ParentElement.
The ElementTextItemGroup class This class represent a group of element text Texts in the group can be...
void mousePressEvent(QGraphicsSceneMouseEvent *event) override
DynamicElementTextItem::mousePressEvent.
void setConnectionForReportFormula(const QString &formula)
void textWidthChanged(qreal width)
DynamicElementTextItem::TextFrom textFrom() const
void projectDiagramsOrderChanged(QETProject *, int, int)
void elementInfoChange(DiagramContext old_info, DiagramContext new_info)
void textChanged(QString text)
void setTextFrom(DynamicElementTextItem::TextFrom text_from)
DynamicElementTextItem::setTextFrom Set the final text is created from.
void infoNameChanged(QString info)
QString reportReplacedCompositeText() const
DynamicElementTextItem::reportReplacedCompositeText This function is only used when the parent elemen...
SnapTo snapTo() const
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 propertiesChange()
QIcon ro
Definition: qeticons.cpp:199
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override
DynamicElementTextItem::hoverEnterEvent If the parent element of this text is a folio report or a sla...
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 compositeTextChanged(QString text)
QString text() const
QList< QMetaObject::Connection > m_update_slave_Xref_connection
void conductorWasRemoved(Conductor *conductor)
XRefProperties defaultXRefProperties(const QString &type) const
Definition: qetproject.h:102
void fromXml(const QDomElement &dom_elmt) override
DynamicElementTextItem::fromXml Import this text from xml.
QRectF frameRect() const
DiagramTextItem::frameRect.
Item is loading her properties from a xml description.
Definition: qet.h:39
DynamicElementTextItem::TextFrom m_text_from
void setupFormulaConnection()
DynamicElementTextItem::setupFormulaConnection Setup the required connection for the formula of the l...
QColor color() const
void XRefPropertiesChanged()
void setNoEditable(bool e=true)
BorderTitleBlock border_and_titleblock
Diagram dimensions and title block.
Definition: diagram.h:74
QETProject * project() const
Definition: diagram.cpp:1716
void autoPos()
CrossRefItem::autoPos Calculate and set position automaticaly.
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
XML parsing failed.
Definition: qetproject.h:55
void setText(const QString &text)
DynamicElementTextItem::setText Set the text of this text.
void updateLabel()
DynamicElementTextItem::updateLabel Update the displayed text, when this dynamic text is based on the...
void diagramRemoved(QETProject *, Diagram *)
void showMe()
Definition: diagram.h:150
static QString replaceVariable(const QString &formula, const DiagramContext &dc)
AssignVariables::replaceVariable Replace the variables in in form %{my-var} to the corresponding val...
Diagram * diagram() const
DiagramTextItem::diagram.