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