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
98 SceneElement::SceneElement (GraphicsScene *_scene, Element *_element) :
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
340 SceneElement::~SceneElement ()
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
559 void SceneElement::resetCodeGeneration()
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
581 QString SceneElement::variableId()
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
612 bool SceneElement::isBefore(SceneElement * _e)
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
641 bool SceneElement::isAfter(SceneElement * _e)
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
VSI::ElementInOut::inOut
InOut * inOut() const
InOut context object.
Definition: elementInOut.hh:110
VSI::Button
Definition: button.hh:67
VSI::Text::setAlignment
void setAlignment(Qt::Alignment _alignment)
Placement of the text in a stretched widget.
Definition: text.cc:311
VSI::GraphicsScene
Definition: graphicsScene.hh:80
VSI::Text::shape
QPainterPath shape() const
Returns the shape for proper repainting/event handling.
Definition: text.cc:397
VSI::GraphicsScene::contentChange
void contentChange()
handle content changes
Definition: graphicsScene.cc:1107
VSI::ElementFunction::loadFromXml
void loadFromXml(QXmlQuery &_xml)
Load from xml.
Definition: elementFunction.cc:95
VSI::Element::longDescription
const QString & longDescription() const
Long description.
Definition: element.hh:91
VSI::ElementInOut
Definition: elementInOut.hh:69
VSI::Element::outputs
const QVector< Output * > & outputs() const
Outputs.
Definition: element.hh:97
VSI::SceneElement::paint
void paint(QPainter *_painter, const QStyleOptionGraphicsItem *_option, QWidget *_widget=0)
Background painting.
Definition: sceneElement.cc:356
VSI::ElementInput
Definition: elementInput.hh:67
pybind11
Definition: PythonTypeConversions.hh:49
VSI::InOut::name
const QString & name() const
Name.
Definition: inout.hh:70
VSI::SceneElement::variableId
QString variableId()
Unique variable name for code generation.
Definition: sceneElement.cc:581
VSI::Element::dataIn
Input * dataIn()
Scenegraph input.
Definition: element.hh:103
VSI::SceneElement::dataIn
ElementInput * dataIn()
Scene input.
Definition: sceneElement.hh:100
VSI::Context::getXmlString
static QString getXmlString(QXmlQuery &_xml, QString _expr, QString _default="")
Gets the string of a xml query.
Definition: context.cc:534
VSI::Connection::updatePositions
void updatePositions()
called to update position on element movement
Definition: connection.cc:232
VSI::SceneElement::id
int id()
Unique id for identification.
Definition: sceneElement.hh:115
VSI::Element::dataOut
Output * dataOut()
Scenegraph output.
Definition: element.hh:106
VSI::Connection
Definition: connection.hh:66
VSI::ElementInOut::connectionPointItem
ConnectionPoint * connectionPointItem() const
Connection point widget.
Definition: elementInOut.hh:89
VSI::Function::name
QString name() const
Name.
Definition: function.hh:81
VSI::SceneElement::mouseDoubleClickEvent
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *_event)
Double click occured. We can&#39;t use mouseDoubleClickEvent because we won&#39;t get one for the ConecctionP...
Definition: sceneElement.cc:471
VSI::Element::functions
const QVector< Function * > & functions() const
Functions.
Definition: element.hh:100
VSI::ElementOutput
Definition: elementOutput.hh:60
VSI::ElementInOut::descriptionTextItem
Text * descriptionTextItem() const
Short description widget.
Definition: elementInOut.hh:95
VSI::Element::inputs
const QVector< Input * > & inputs() const
Inputs.
Definition: element.hh:94
VSI::SceneElement::loadFromXml
void loadFromXml(QXmlQuery &_xml)
Load from xml.
Definition: sceneElement.cc:745
VSI::Element::setMinId
void setMinId(unsigned int _id)
sets the minimum for an unused id
Definition: element.cc:100
VSI::ElementInOut::element
SceneElement * element()
Scene element.
Definition: elementInOut.hh:113
VSI::SceneElement::dataOut
ElementOutput * dataOut()
Scene output.
Definition: sceneElement.hh:103
VSI::ElementInOut::typeTextItem
Text * typeTextItem() const
Type text widget.
Definition: elementInOut.hh:92
VSI::SceneElement::SceneElement
SceneElement(GraphicsScene *_scene, Element *_element)
Constructor.
Definition: sceneElement.cc:98
VSI::Text::text
QString text()
Get displayed text.
Definition: text.hh:121
VSI::GraphicsScene::mouseRelease
void mouseRelease(QPointF _pos, QGraphicsItem *_item)
Redirect mouse release to tools area.
Definition: graphicsScene.cc:330
VSI::Element::shortDescription
const QString & shortDescription() const
Short description.
Definition: element.hh:88
VSI::ElementInput::loadFromXml
void loadFromXml(QXmlQuery &_xml)
Load from xml.
Definition: elementInput.cc:255
VSI::ElementInput::setValid
void setValid(bool _value)
Sets the valid flag (needed during code generation)
Definition: elementInput.hh:81
VSI::ElementFunction
Definition: elementFunction.hh:66
VSI::Text::boundingRect
virtual QRectF boundingRect() const
Bounding rectangle.
Definition: text.cc:342
VSI::Connection::invalidate
void invalidate()
invalidate way
Definition: connection.cc:263
VSI::Function::shortDescription
const QString & shortDescription() const
Short description.
Definition: function.hh:84
VSI::Element::name
QString name() const
Element name.
Definition: element.hh:82
VSI::Element::code
QString code() const
Code segment.
Definition: element.hh:115
VSI::Connection::output
ElementOutput * output()
Output of this connection.
Definition: connection.cc:248
VSI::GraphicsScene::getNewZ
qreal getNewZ()
Returns a new Z value that is above all elements.
Definition: graphicsScene.cc:252
VSI::ConfigDialog
Definition: configDialog.hh:67
VSI::SceneElement::~SceneElement
~SceneElement()
Destructor.
Definition: sceneElement.cc:340
VSI::SceneElement::saveToXml
void saveToXml(QDomDocument &_doc, QDomElement &_root)
Save to xml.
Definition: sceneElement.cc:693
VSI::Connection::input
ElementInput * input()
Input of this connection.
Definition: connection.cc:239
VSI::Button::setBackgroundBrush
void setBackgroundBrush(QBrush _brush) override
Sets the background brush.
Definition: button.cc:143
VSI
Definition: baseWidget.cc:72
VSI::Output
Definition: output.hh:60
VSI::SceneElement::isBefore
bool isBefore(SceneElement *_e)
Will this element be executed before _e bacause of its connections?
Definition: sceneElement.cc:612
VSI::Function
Definition: function.hh:67
VSI::Element
Definition: element.hh:68
VSI::Input
Definition: input.hh:60
VSI::Text::setText
void setText(QString _text)
Set displayed text.
Definition: text.hh:118
VSI::SceneElement::functions
QVector< ElementFunction * > functions()
Functions.
Definition: sceneElement.hh:97
VSI::SceneElement::resetCodeGeneration
void resetCodeGeneration()
Reset code block for code generation.
Definition: sceneElement.cc:559
VSI::ElementFunction::function
Function * function()
Function class.
Definition: elementFunction.hh:82
VSI::SceneElement::isAfter
bool isAfter(SceneElement *_e)
Will this element be executed after _e bacause of its connections?
Definition: sceneElement.cc:641
VSI::SceneElement
Definition: sceneElement.hh:73
VSI::Text
Definition: text.hh:67
VSI::Text::setBackground
void setBackground(bool _leftOut, bool _rightOut)
Enables background painting.
Definition: text.cc:300
VSI::Text::setHorizontalStretch
void setHorizontalStretch(bool _stretch)
Should this widget be stretchable in horizontal direction.
Definition: text.cc:324
VSI::SceneElement::replaceCodeBlock
void replaceCodeBlock(QString _name, QString _id, QString _value)
Replace block with name _name and id _id with _value.
Definition: sceneElement.cc:572
VSI::SceneElement::inputs
QVector< ElementInput * > inputs()
Inputs.
Definition: sceneElement.hh:91
VSI::ElementFunction::saveToXml
void saveToXml(QDomDocument &_doc, QDomElement &_root)
Save to xml.
Definition: elementFunction.cc:84
VSI::ElementInput::saveToXml
void saveToXml(QDomDocument &_doc, QDomElement &_root)
Save to xml.
Definition: elementInput.cc:210
VSI::ElementInOut::connections
QList< Connection * > connections() const
Connections.
Definition: elementInOut.hh:98
VSI::InOut::shortDescription
const QString & shortDescription() const
Short description.
Definition: inout.hh:73