Developer Documentation
sceneElement.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 
43 
44 //== INCLUDES =================================================================
45 #include <QWidget>
46 #include <QVBoxLayout>
47 #include <QLabel>
48 #include <QMessageBox>
49 #include <QPainter>
50 #include <QGraphicsSceneMouseEvent>
51 #include <QGraphicsLinearLayout>
52 #include <QGraphicsProxyWidget>
53 #include <QGraphicsGridLayout>
54 #include <QGraphicsView>
55 
56 #include <QDomText>
57 #include <QXmlResultItems>
58 
59 #include "sceneElement.hh"
60 #include "graphicsScene.hh"
61 
62 #include "text.hh"
63 #include "button.hh"
64 #include "connectionPoint.hh"
65 #include "connection.hh"
66 
67 #include "elementInput.hh"
68 #include "elementOutput.hh"
69 #include "elementFunction.hh"
70 
71 #include "config/configDialog.hh"
72 
73 #include "../parser/element.hh"
74 #include "../parser/context.hh"
75 #include "../parser/function.hh"
76 
77 #define BACKGROUND_RED 0x00
78 #define BACKGROUND_GREEN 0x00
79 #define BACKGROUND_BLUE 0x00
80 #define BACKGROUND_ALPHA 0xff
81 
82 #define SELECTED_BACKGROUND_RED 0x00
83 #define SELECTED_BACKGROUND_GREEN 0x00
84 #define SELECTED_BACKGROUND_BLUE 0x6f
85 #define SELECTED_BACKGROUND_ALPHA 0xff
86 
87 
88 //== NAMESPACES ===============================================================
89 namespace VSI {
90 
91 //=============================================================================
92 //
93 // CLASS VSI::SceneElement - IMPLEMENTATION
94 //
95 //=============================================================================
96 
97 
99  scene_ (_scene),
100  element_ (_element),
101  dataIn_ (0),
102  dataOut_ (0),
103  id_ (_element->getNewId ())
104 {
105  int index = 1;
106  bool hasConfig = false;
107 
108  QGraphicsLinearLayout *layout = new QGraphicsLinearLayout (Qt::Vertical);
109  layout->setSpacing (0);
110 
111  nameLayout_ = new QGraphicsLinearLayout (Qt::Vertical);
112  nameLayout_->setSpacing(0);
113  nameLayout_->setContentsMargins(15, 0, 15, 0);
114  // add name text
115  name_ = new Text (element_->shortDescription (), this);
116 
117  name_->setAlignment (Qt::AlignHCenter);
118 
119  QFont font = name_->font ();
120  if (font.pointSize () != -1)
121  font.setPointSize (font.pointSize () + 1);
122  else
123  font.setPixelSize (font.pixelSize () + 1);
124  font.setBold (true);
125  name_->setFont (font);
126 
127  nameLayout_->addItem(name_);
128  nameLayout_->setAlignment (name_, Qt::AlignCenter);
129 
130  elementName_ = new Text (element_->shortDescription (), this);
131  font = elementName_->font ();
132  if (font.pointSize () != -1)
133  font.setPointSize (font.pointSize () - 2);
134  else
135  font.setPixelSize (font.pixelSize () - 2);
136  elementName_->setFont (font);
137 
138  nameLayout_->addItem(elementName_);
139  nameLayout_->setAlignment (elementName_, Qt::AlignCenter);
140 
141  elementName_->hide ();
142 
143  layout->addItem(nameLayout_);
144  layout->setAlignment (nameLayout_, Qt::AlignCenter);
145 
146  // add inputs
147  QGraphicsGridLayout *inGrid = new QGraphicsGridLayout;
148  inGrid->setContentsMargins (0,0,5,0);
149  int row = 0;
150  qreal typeWidth = 0;
151  qreal height = 1000;
152 
153  foreach (Input *in, element_->inputs ())
154  {
155  ElementInput *i = new ElementInput (in, this);
156  inputs_.append (i);
157 
158  if (!(in->state () & Input::NoUserInput))
159  {
160  hasConfig = true;
161  configInputs_.append (i);
162  }
163 
164  if (in->state () & Input::NoExternalInput)
165  {
166  i->connectionPointItem ()->hide ();
167  i->typeTextItem ()->hide ();
168  i->descriptionTextItem ()->hide ();
169  continue;
170  }
171 
172  inGrid->addItem (i->connectionPointItem (), row, 0, Qt::AlignLeft | Qt::AlignVCenter);
173  inGrid->addItem (i->typeTextItem (), row, 1, Qt::AlignLeft | Qt::AlignVCenter);
174  inGrid->addItem (i->descriptionTextItem (), row, 2, Qt::AlignLeft | Qt::AlignVCenter);
175 
176  height = qMin (height, i->typeTextItem ()->preferredHeight () / 2);
177  typeWidth = qMax (i->typeTextItem ()->preferredWidth (), typeWidth);
178  row ++;
179  }
180 
181  if (!element_->inputs ().isEmpty ())
182  {
183  inGrid->setColumnMinimumWidth (1, qMin (typeWidth, 100.0));
184  inGrid->setHorizontalSpacing (1);
185  layout->insertItem (index, inGrid);
186  layout->setAlignment (inGrid, Qt::AlignLeft);
187  layout->setItemSpacing (index - 1, 10);
188  index++;
189  }
190 
191  // add outputs
192  QGraphicsGridLayout *outGrid = new QGraphicsGridLayout;
193  outGrid->setContentsMargins (5,0,0,0);
194  row = 0;
195  typeWidth = 0;
196  height = 1000;
197 
198  foreach (Output *out, element_->outputs ())
199  {
200  ElementOutput *o = new ElementOutput (out, this);
201 
202  outGrid->addItem (o->connectionPointItem (), row, 2, Qt::AlignRight | Qt::AlignVCenter);
203  outGrid->addItem (o->typeTextItem (), row, 1, Qt::AlignRight | Qt::AlignVCenter);
204  outGrid->addItem (o->descriptionTextItem (), row, 0, Qt::AlignRight | Qt::AlignVCenter);
205 
206  height = qMin (height, o->typeTextItem ()->preferredHeight () / 2);
207  typeWidth = qMax (o->typeTextItem ()->preferredWidth (), typeWidth);
208  row ++;
209 
210  outputs_.append (o);
211  }
212 
213  if (!element_->outputs ().isEmpty ())
214  {
215  outGrid->setColumnMinimumWidth (1, qMin (typeWidth, 100.0));
216  outGrid->setHorizontalSpacing (1);
217  layout->insertItem(index, outGrid);
218  layout->setAlignment (outGrid, Qt::AlignRight);
219  layout->setItemSpacing (index - 1, 10);
220  index++;
221  }
222 
223  if (hasConfig || !element_->functions ().isEmpty ())
224  {
225  QGraphicsLinearLayout *hl = new QGraphicsLinearLayout (Qt::Horizontal);
226  QGraphicsLinearLayout *vl = new QGraphicsLinearLayout (Qt::Vertical);
227  hl->setContentsMargins(15, 0, 15, 0);
228 
229  // add input config button
230  if (hasConfig)
231  {
232  Button *configButton = new Button ("Configure", this);
233  configButton->setBrush (Qt::black);
234  configButton->setBackgroundBrush (Qt::lightGray);
235  configButton->setBackground (true, true);
236  configButton->setHorizontalStretch (true);
237  configButton->setAlignment (Qt::AlignHCenter);
238 
239  vl->addItem (configButton);
240 
241  connect (configButton, SIGNAL (pressed()), this, SLOT (showInputConfig()));
242  }
243 
244  // add function edit buttons
245  foreach (Function *f, element_->functions ())
246  {
247  ElementFunction *ef = new ElementFunction (f, this);
248 
249  Button *config = new Button ("Edit:" + f->shortDescription (), this);
250  config->setBrush (Qt::black);
251  config->setBackgroundBrush (Qt::lightGray);
252  config->setBackground (true, true);
253  config->setAlignment (Qt::AlignHCenter);
254 
255  vl->addItem (config);
256 
257  connect (config, SIGNAL (pressed()), ef, SLOT (editFunction ()));
258 
259  functions_.append (ef);
260  }
261 
262  hl->addStretch ();
263  hl->addItem (vl);
264  hl->addStretch ();
265 
266  layout->insertItem (index, hl);
267  layout->setAlignment (hl, Qt::AlignCenter);
268  layout->setItemSpacing (index - 1, 10);
269  index++;
270  }
271 
272  // add scenegraph input / output
273  if (element_->dataOut () || element_->dataIn ())
274  {
275  QGraphicsGridLayout *sIO = new QGraphicsGridLayout ();
276  int col = 0;
277  int lo = 0, ro = 0;
278 
279  // Start node has no scene graph input
280  if (element_->dataIn ())
281  {
282  dataIn_ = new ElementInput (element_->dataIn (), this);
283  dataIn_->typeTextItem ()->hide ();
284  sIO->addItem (dataIn_->connectionPointItem (), 0, col++, Qt::AlignLeft | Qt::AlignVCenter);
285  sIO->addItem (dataIn_->descriptionTextItem (), 0, col++, Qt::AlignCenter);
286  } else
287  lo = 5;
288 
289  if (element_->dataOut ())
290  {
291  dataOut_ = new ElementOutput (element_->dataOut (), this);
292  dataOut_->typeTextItem ()->hide ();
293  if (dataIn_)
294  {
295  dataOut_->descriptionTextItem ()->hide ();
296  dataIn_->descriptionTextItem ()->setBackground (false, false);
297  dataIn_->descriptionTextItem ()->setAlignment (Qt::AlignHCenter);
298  }
299  else
300  {
301  sIO->addItem (dataOut_->descriptionTextItem (), 0, col++, Qt::AlignCenter);
302  }
303  sIO->addItem (dataOut_->connectionPointItem (), 0, col, Qt::AlignRight | Qt::AlignVCenter);
304  } else
305  ro = 5;
306 
307  sIO->setContentsMargins (lo, 0, ro, 0);
308  sIO->setHorizontalSpacing (1);
309 
310  layout->insertItem (index, sIO);
311  layout->setAlignment (sIO, Qt::AlignCenter);
312  layout->setItemSpacing (index - 1, 10);
313  index++;
314  }
315 
316  layout->setItemSpacing (0, 1);
317 
318  layout->setContentsMargins (0, 2, 0, 6);
319 
320  setLayout (layout);
321 
322  if (layout->preferredWidth() < 200)
323  setMinimumWidth (layout->preferredWidth());
324  else
325  setMinimumWidth (200);
326 
327  setZValue (scene_->getNewZ ());
328 
329  setFlag (QGraphicsItem::ItemIsSelectable, true);
330  setFlag (QGraphicsItem::ItemIsMovable, true);
331 
332  setMaximumWidth (200);
333 
334  setToolTip (element_->longDescription ());
335 }
336 
337 //------------------------------------------------------------------------------
338 
341 {
342  foreach (ElementInOut *e, inputs_)
343  delete e;
344  foreach (ElementInOut *e, outputs_)
345  delete e;
346 
347  if (dataIn_)
348  delete dataIn_;
349  if (dataOut_)
350  delete dataOut_;
351 }
352 
353 //------------------------------------------------------------------------------
354 
356 void SceneElement::paint (QPainter *_painter, const QStyleOptionGraphicsItem *_option, QWidget *_widget)
357 {
358  int w = geometry().width() - 20;
359  int h = geometry().height();
360 
361  _painter->setRenderHint(QPainter::Antialiasing, true);
362  if (isSelected ())
363  _painter->setBrush(QBrush(QColor(SELECTED_BACKGROUND_RED,
364  SELECTED_BACKGROUND_GREEN,
365  SELECTED_BACKGROUND_BLUE,
366  SELECTED_BACKGROUND_ALPHA)));
367  else
368  _painter->setBrush(QBrush(QColor(BACKGROUND_RED,
369  BACKGROUND_GREEN,
370  BACKGROUND_BLUE,
371  BACKGROUND_ALPHA)));
372 
373  _painter->setPen (Qt::NoPen);
374  _painter->drawRoundedRect(10, 0, w, h, 5, 5);
375 
376  float wH = w / 2.0;
377  float wT = w / 3.0;
378 
379  QPainterPath path;
380  QRadialGradient rG;
381  QLinearGradient lG;
382 
383  path.moveTo (10, 20);
384  path.lineTo (10, 5);
385  path.arcTo (10, 0, 10, 10, 180, -90);
386  path.lineTo (w + 6, 0);
387  path.arcTo (w, 0, 10, 10, 90, -90);
388  path.lineTo (w + 10, 10);
389 
390  path.cubicTo (QPointF (10 + wH, 10), QPointF (10 + wH, 20), QPointF (10, 20));
391 
392  rG.setCenter (10 + wT, 0);
393  rG.setFocalPoint(10 + wT, 0);
394  rG.setRadius (w);
395  rG.setColorAt(0, QColor (255, 255, 255, 128));
396  rG.setColorAt(1, Qt::transparent);
397  _painter->setBrush (rG);
398  _painter->setPen (Qt::NoPen);
399  _painter->drawPath(path);
400 
401  path = QPainterPath ();
402  path.moveTo (w + 5, 0);
403  path.arcTo (w, 0, 10, 10, 90, -90);
404  path.lineTo (w + 10, h - 5);
405  path.lineTo (w + 5, h - 5);
406  path.lineTo (w + 5, 0);
407 
408  lG.setStart (w + 5, 0);
409  lG.setFinalStop(w + 10, 0);
410  lG.setColorAt(0, Qt::transparent);
411  lG.setColorAt(1, QColor (255, 255, 255, 128));
412  _painter->setBrush (lG);
413  _painter->drawPath(path);
414 
415  path = QPainterPath ();
416  path.moveTo (10, h - 5);
417  path.arcTo (10, h - 10, 10, 10, 180, 90);
418  path.lineTo (w + 5, h);
419  path.lineTo (w + 5, h - 5);
420  path.lineTo (10, h - 5);
421  lG.setStart (0, h - 5);
422  lG.setFinalStop (0, h);
423  _painter->setBrush (lG);
424  _painter->drawPath (path);
425 
426  path = QPainterPath ();
427  path.moveTo (w + 5, h);
428  path.arcTo (w, h - 10, 10, 10, -90, 90);
429  path.lineTo (w + 5, h - 5);
430  path.lineTo (w + 5, h);
431  rG.setCenter (w + 5, h - 5);
432  rG.setFocalPoint(w + 5, h - 5);
433  rG.setRadius (5);
434  rG.setColorAt (0, Qt::transparent);
435  rG.setColorAt (1, QColor (255, 255, 255, 128));
436  _painter->setBrush (rG);
437  _painter->drawPath(path);
438 
439  QGraphicsWidget::paint (_painter, _option, _widget);
440 }
441 
442 //------------------------------------------------------------------------------
443 
444 // Start draging on mouse press
445 void SceneElement::mousePressEvent (QGraphicsSceneMouseEvent *_event)
446 {
447  QGraphicsWidget::mousePressEvent (_event);
448  setZValue (scene_->getNewZ ());
449 }
450 
451 //------------------------------------------------------------------------------
452 
453 // move all selected elements
454 void SceneElement::mouseMoveEvent (QGraphicsSceneMouseEvent *_event)
455 {
456  QGraphicsWidget::mouseMoveEvent (_event);
457 }
458 
459 //------------------------------------------------------------------------------
460 
461 // stop moving
462 void SceneElement::mouseReleaseEvent (QGraphicsSceneMouseEvent *_event)
463 {
464  QGraphicsWidget::mouseReleaseEvent (_event);
465  scene_->mouseRelease (_event->scenePos (), this);
466 }
467 
468 //------------------------------------------------------------------------------
469 
471 void SceneElement::mouseDoubleClickEvent (QGraphicsSceneMouseEvent *_event)
472 {
473  QPointF _scenePos = _event->scenePos ();
474  if (name_->boundingRect ().contains (name_->mapFromScene (_scenePos)) ||
475  elementName_->boundingRect ().contains (elementName_->mapFromScene (_scenePos)))
476  {
477  ConfigDialog d (QVector<ElementInput *> (), name_->text (), scene ()->views ()[0]);
478  d.setWindowTitle ("Element Name Configuration");
479  if (d.exec () == QDialog::Accepted)
480  {
481  if (d.name ().isEmpty())
482  name_->setText (element_->shortDescription ());
483  else
484  name_->setText (d.name ());
485 
486  if (name_->text () == element_->shortDescription ())
487  elementName_->hide ();
488  else
489  elementName_->show ();
490 
491  nameLayout_->invalidate ();
492  }
493  return;
494  }
495 
496  foreach (ElementInput *i, inputs_)
497  {
498  bool click = false;
499  if (i->connectionPointItem ()->isVisible () &&
500  i->connectionPointItem ()->shape ().contains (i->connectionPointItem ()->mapFromScene (_scenePos)))
501  click = true;
502  if (i->typeTextItem ()->isVisible () &&
503  i->typeTextItem ()->shape ().contains (i->typeTextItem ()->mapFromScene (_scenePos)))
504  click = true;
505  if (i->descriptionTextItem ()->isVisible () &&
506  i->descriptionTextItem ()->shape ().contains (i->descriptionTextItem ()->mapFromScene (_scenePos)))
507  click = true;
508 
509  if (!click)
510  continue;
511 
512  if (configInputs_.contains (i))
513  {
514  QVector<ElementInput *> inputs;
515  inputs.append (i);
516 
517  ConfigDialog d (inputs, QString (), scene ()->views ()[0]);
518  d.setWindowTitle (i->inOut ()->shortDescription () + " Configuration");
519  d.exec ();
520  } else
521  {
522  QMessageBox msgBox (scene ()->views ()[0]);
523  msgBox.setText("No configuration available.");
524  msgBox.exec();
525  }
526  }
527 
528 }
529 
530 //------------------------------------------------------------------------------
531 
532 // update connection on move
533 void SceneElement::moveEvent (QGraphicsSceneMoveEvent *_event)
534 {
535  QGraphicsWidget::moveEvent (_event);
536 
537  foreach (ElementInput *e, inputs_)
538  foreach (Connection *c, e->connections ())
539  c->updatePositions ();
540 
541  foreach (ElementOutput *e, outputs_)
542  foreach (Connection *c, e->connections ())
543  c->updatePositions ();
544 
545  if (dataIn_)
546  foreach (Connection *c, dataIn_->connections ())
547  c->updatePositions ();
548 
549  if (dataOut_)
550  foreach (Connection *c, dataOut_->connections ())
551  c->updatePositions ();
552 
553  scene_->contentChange ();
554 }
555 
556 //------------------------------------------------------------------------------
557 
560 {
561  foreach (ElementInput *i, inputs ())
562  i->setValid (false);
563  if (dataIn ())
564  dataIn ()->setValid (false);
565 
566  code_ = element_->code ();
567 }
568 
569 //------------------------------------------------------------------------------
570 
572 void SceneElement::replaceCodeBlock(QString _name, QString _id, QString _value)
573 {
574  QString regex = "\\[\\s*" + _name + "\\s*=\\s*\"" + _id + "\"\\s*\\]";
575  code_ = code_.replace (QRegExp (regex), _value);
576 }
577 
578 //------------------------------------------------------------------------------
579 
582 {
583  return element_->name () + "_" + QString::number (id_);
584 }
585 
586 //------------------------------------------------------------------------------
587 
588 // show input configuration dialog
589 void SceneElement::showInputConfig()
590 {
591  ConfigDialog d (configInputs_, name_->text (), scene ()->views ()[0]);
592  d.setWindowTitle (name_->text () + " Input Configuration");
593  if (d.exec () == QDialog::Accepted)
594  {
595  if (d.name ().isEmpty())
596  name_->setText (element_->shortDescription ());
597  else
598  name_->setText (d.name ());
599 
600  if (name_->text () == element_->shortDescription ())
601  elementName_->hide ();
602  else
603  elementName_->show ();
604 
605  nameLayout_->invalidate ();
606  }
607 }
608 
609 //------------------------------------------------------------------------------
610 
613 {
614  foreach (ElementOutput *o, outputs_)
615  {
616  foreach (Connection *c, o->connections ())
617  {
618  if (c->input ()->element () == _e)
619  return true;
620  bool rv = c->input ()->element ()->isBefore (_e);
621  if (rv)
622  return true;
623  }
624  }
625 
626  if (dataOut ())
627  foreach (Connection *c, dataOut ()->connections ())
628  {
629  if (c->input ()->element () == _e)
630  return true;
631  bool rv = c->input ()->element ()->isBefore (_e);
632  if (rv)
633  return true;
634  }
635  return false;
636 }
637 
638 //------------------------------------------------------------------------------
639 
642 {
643  foreach (ElementInput *i, inputs_)
644  {
645  foreach (Connection *c, i->connections ())
646  {
647  if (c->output ()->element () == _e)
648  return true;
649  bool rv = c->output ()->element ()->isAfter (_e);
650  if (rv)
651  return true;
652  }
653  }
654 
655  if (dataIn ())
656  foreach (Connection *c, dataIn ()->connections ())
657  {
658  if (c->output ()->element () == _e)
659  return true;
660  bool rv = c->output ()->element ()->isAfter (_e);
661  if (rv)
662  return true;
663  }
664  return false;
665 }
666 
667 //------------------------------------------------------------------------------
668 
669 // invalidate (reset) all connections of this element
670 void VSI::SceneElement::invalidateConnections()
671 {
672 
673  foreach (ElementInput *e, inputs_)
674  foreach (Connection *c, e->connections ())
675  c->invalidate ();
676 
677  foreach (ElementOutput *e, outputs_)
678  foreach (Connection *c, e->connections ())
679  c->invalidate ();
680 
681  if (dataIn_)
682  foreach (Connection *c, dataIn_->connections ())
683  c->invalidate ();
684 
685  if (dataOut_)
686  foreach (Connection *c, dataOut_->connections ())
687  c->invalidate ();
688 }
689 
690 //------------------------------------------------------------------------------
691 
693 void SceneElement::saveToXml(QDomDocument & _doc, QDomElement & _root)
694 {
695  QDomText t;
696 
697  QDomElement main = _doc.createElement("element");
698  _root.appendChild(main);
699  main.setAttribute ("name",element_->name ());
700 
701  if (name_->text () != element_->shortDescription ())
702  {
703  QDomElement name = _doc.createElement("visible_name");
704  main.appendChild(name);
705  t = _doc.createTextNode(name_->text ());
706  name.appendChild(t);
707  }
708 
709  QDomElement id = _doc.createElement("id");
710  main.appendChild(id);
711  t = _doc.createTextNode(QString::number (id_));
712  id.appendChild(t);
713 
714  QDomElement px = _doc.createElement("x");
715  main.appendChild(px);
716  t = _doc.createTextNode(QString::number (pos ().x ()));
717  px.appendChild(t);
718 
719  QDomElement py = _doc.createElement("y");
720  main.appendChild(py);
721  t = _doc.createTextNode(QString::number (pos ().y ()));
722  py.appendChild(t);
723 
724  if (!inputs_.isEmpty() || dataIn_)
725  {
726  QDomElement inputs = _doc.createElement("inputs");
727  main.appendChild(inputs);
728  foreach (ElementInput *i, inputs_)
729  i->saveToXml (_doc, inputs);
730  if (dataIn_)
731  dataIn_->saveToXml (_doc, inputs);
732  }
733  if (!functions_.isEmpty ())
734  {
735  QDomElement functions = _doc.createElement("functions");
736  main.appendChild(functions);
737  foreach (ElementFunction *ef, functions_)
738  ef->saveToXml (_doc, functions);
739  }
740 }
741 
742 //------------------------------------------------------------------------------
743 
745 void SceneElement::loadFromXml(QXmlQuery & _xml)
746 {
747  bool ok1, ok2;
748  int id;
749  double x, y;
750  QString val;
751 
752  val = Context::getXmlString (_xml, "visible_name/string(text())");
753 
754  if (!val.isEmpty ())
755  name_->setText (val);
756 
757  if (name_->text () == element_->shortDescription ())
758  elementName_->hide ();
759  else
760  elementName_->show ();
761 
762  nameLayout_->invalidate ();
763 
764  val = Context::getXmlString (_xml, "id/string(text())");
765 
766  id = val.toUInt (&ok1);
767 
768  if (ok1)
769  {
770  id_ = id;
771  element_->setMinId(id + 1);
772  }
773 
774  val = Context::getXmlString (_xml, "x/string(text())");
775  x = val.toDouble (&ok1);
776 
777  val = Context::getXmlString (_xml, "y/string(text())");
778  y = val.toDouble (&ok2);
779 
780  if (ok1 && ok2)
781  setPos (x, y);
782 
783  val = Context::getXmlString (_xml, "is_set/string(text())");
784 
785  _xml.setQuery ("inputs/input");
786 
787  QXmlResultItems i;
788 
789  if (_xml.isValid ())
790  {
791  _xml.evaluateTo (&i);
792  QXmlItem item (i.next ());
793  while (!item.isNull ())
794  {
795  QXmlQuery q (_xml);
796  q.setFocus (item);
797 
798  val = Context::getXmlString (q, "string(@name)");
799 
800  if (!val.isEmpty())
801  {
802  if (val == "data" && dataIn_)
803  dataIn_->loadFromXml (q);
804  else
805  {
806  foreach (ElementInput *i, inputs_)
807  if (i->inOut()->name () == val)
808  {
809  i->loadFromXml (q);
810  break;
811  }
812  }
813  }
814 
815  item = i.next ();
816  }
817 
818  }
819 
820  _xml.setQuery ("functions/function");
821 
822  if (_xml.isValid ())
823  {
824  _xml.evaluateTo (&i);
825  QXmlItem item (i.next ());
826  while (!item.isNull ())
827  {
828  QXmlQuery q (_xml);
829  q.setFocus (item);
830 
831  val = Context::getXmlString (q, "string(@name)");
832 
833  if (!val.isEmpty())
834  {
835  foreach (ElementFunction *ef, functions_)
836  if (ef->function ()->name () == val)
837  {
838  ef->loadFromXml (q);
839  break;
840  }
841  }
842 
843  item = i.next ();
844  }
845 
846  }
847 }
848 
849 //------------------------------------------------------------------------------
850 }
851 
852 
853 
InOut * inOut() const
InOut context object.
void setAlignment(Qt::Alignment _alignment)
Placement of the text in a stretched widget.
Definition: text.cc:311
QPainterPath shape() const
Returns the shape for proper repainting/event handling.
Definition: text.cc:397
void contentChange()
handle content changes
void loadFromXml(QXmlQuery &_xml)
Load from xml.
const QString & longDescription() const
Long description.
Definition: element.hh:91
const QVector< Output * > & outputs() const
Outputs.
Definition: element.hh:97
void paint(QPainter *_painter, const QStyleOptionGraphicsItem *_option, QWidget *_widget=0)
Background painting.
const QString & name() const
Name.
Definition: inout.hh:70
QString variableId()
Unique variable name for code generation.
Input * dataIn()
Scenegraph input.
Definition: element.hh:103
ElementInput * dataIn()
Scene input.
static QString getXmlString(QXmlQuery &_xml, QString _expr, QString _default="")
Gets the string of a xml query.
Definition: context.cc:534
void updatePositions()
called to update position on element movement
Definition: connection.cc:232
int id()
Unique id for identification.
Output * dataOut()
Scenegraph output.
Definition: element.hh:106
ConnectionPoint * connectionPointItem() const
Connection point widget.
Definition: elementInOut.hh:89
QString name() const
Name.
Definition: function.hh:81
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *_event)
Double click occured. We can&#39;t use mouseDoubleClickEvent because we won&#39;t get one for the ConecctionP...
const QVector< Function * > & functions() const
Functions.
Definition: element.hh:100
Text * descriptionTextItem() const
Short description widget.
Definition: elementInOut.hh:95
const QVector< Input * > & inputs() const
Inputs.
Definition: element.hh:94
void loadFromXml(QXmlQuery &_xml)
Load from xml.
void setMinId(unsigned int _id)
sets the minimum for an unused id
Definition: element.cc:100
SceneElement * element()
Scene element.
ElementOutput * dataOut()
Scene output.
Text * typeTextItem() const
Type text widget.
Definition: elementInOut.hh:92
SceneElement(GraphicsScene *_scene, Element *_element)
Constructor.
Definition: sceneElement.cc:98
QString text()
Get displayed text.
Definition: text.hh:121
void mouseRelease(QPointF _pos, QGraphicsItem *_item)
Redirect mouse release to tools area.
const QString & shortDescription() const
Short description.
Definition: element.hh:88
void loadFromXml(QXmlQuery &_xml)
Load from xml.
void setValid(bool _value)
Sets the valid flag (needed during code generation)
Definition: elementInput.hh:81
virtual QRectF boundingRect() const
Bounding rectangle.
Definition: text.cc:342
void invalidate()
invalidate way
Definition: connection.cc:263
const QString & shortDescription() const
Short description.
Definition: function.hh:84
QString name() const
Element name.
Definition: element.hh:82
QString code() const
Code segment.
Definition: element.hh:115
ElementOutput * output()
Output of this connection.
Definition: connection.cc:248
qreal getNewZ()
Returns a new Z value that is above all elements.
~SceneElement()
Destructor.
void saveToXml(QDomDocument &_doc, QDomElement &_root)
Save to xml.
ElementInput * input()
Input of this connection.
Definition: connection.cc:239
void setBackgroundBrush(QBrush _brush) override
Sets the background brush.
Definition: button.cc:143
bool isBefore(SceneElement *_e)
Will this element be executed before _e bacause of its connections?
void setText(QString _text)
Set displayed text.
Definition: text.hh:118
QVector< ElementFunction * > functions()
Functions.
Definition: sceneElement.hh:97
void resetCodeGeneration()
Reset code block for code generation.
Function * function()
Function class.
bool isAfter(SceneElement *_e)
Will this element be executed after _e bacause of its connections?
void setBackground(bool _leftOut, bool _rightOut)
Enables background painting.
Definition: text.cc:300
void setHorizontalStretch(bool _stretch)
Should this widget be stretchable in horizontal direction.
Definition: text.cc:324
void replaceCodeBlock(QString _name, QString _id, QString _value)
Replace block with name _name and id _id with _value.
QVector< ElementInput * > inputs()
Inputs.
Definition: sceneElement.hh:91
void saveToXml(QDomDocument &_doc, QDomElement &_root)
Save to xml.
void saveToXml(QDomDocument &_doc, QDomElement &_root)
Save to xml.
QList< Connection * > connections() const
Connections.
Definition: elementInOut.hh:98
const QString & shortDescription() const
Short description.
Definition: inout.hh:73