Version: 8.3.0
SceneComposedNodeItem.cxx
Go to the documentation of this file.
1 // Copyright (C) 2006-2016 CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 
20 #define CHRONODEF
21 #include "chrono.hxx"
22 
23 #include "SceneBlocItem.hxx"
26 #include "SceneHeaderItem.hxx"
27 #include "SceneHeaderNodeItem.hxx"
28 #include "SceneInPortItem.hxx"
29 #include "SceneOutPortItem.hxx"
30 #include "SceneLinkItem.hxx"
31 #include "SceneDSLinkItem.hxx"
32 #include "SceneCtrlLinkItem.hxx"
33 #include "SceneProgressItem.hxx"
34 #include "LinkMatrix.hxx"
35 #include "LinkAStar.hxx"
36 #include "ItemMimeData.hxx"
37 #include "QtGuiContext.hxx"
38 #include "Menus.hxx"
39 #include "Message.hxx"
40 #include "guiObservers.hxx"
41 #include "GuiEditor.hxx"
42 #include "Scene.hxx"
43 #include "Switch.hxx"
44 
45 #include <QPointF>
46 #include <QGraphicsSceneDragDropEvent>
47 
48 #include <cassert>
49 
50 #include "Resource.hxx"
51 
52 //#define _DEVDEBUG_
53 #include "YacsTrace.hxx"
54 
55 using namespace std;
56 using namespace YACS::ENGINE;
57 using namespace YACS::HMI;
58 
59 SceneComposedNodeItem::SceneComposedNodeItem(QGraphicsScene *scene, SceneItem *parent,
60  QString label, Subject *subject)
61  : SceneNodeItem(scene, parent, label, subject)
62 {
63  DEBTRACE("SceneComposedNodeItem::SceneComposedNodeItem " <<label.toStdString());
64 
67 
71  adjustColors();
72  _dragOver = false;
73  setAcceptDrops(true);
74 }
75 
77 {
78 }
79 
81 {
83  for (list<AbstractSceneItem*>::const_iterator it=_children.begin(); it!=_children.end(); ++it)
84  {
85  if (SceneComposedNodeItem *scnode = dynamic_cast<SceneComposedNodeItem*>(*it))
86  scnode->adjustColors();
87  }
88  }
89 
91 {
92  QRectF ChildrenBRect =QRectF(x(), y(), 5, 5);
93  if (_header) ChildrenBRect = _header->getMinimalBoundingRect();
94  for (list<AbstractSceneItem*>::const_iterator it=_children.begin(); it!=_children.end(); ++it)
95  ChildrenBRect = ChildrenBRect.united(childBoundingRect(*it));
96  ChildrenBRect.setWidth (ChildrenBRect.width() + Resource::Border_Margin);
97  ChildrenBRect.setHeight(ChildrenBRect.height() + Resource::Border_Margin);
98  return ChildrenBRect;
99 }
100 
101 void SceneComposedNodeItem::paint(QPainter *painter,
102  const QStyleOptionGraphicsItem *option,
103  QWidget *widget)
104 {
105  //DEBTRACE("SceneComposedNodeItem::paint " << _label.toStdString());
106  // IMN (14/11/2013) below block commented
107  // prevent bad resizing of scene in shrink mode
108  /* if (!isExpanded()) {
109  _width = 2*Resource::Corner_Margin + 2*Resource::DataPort_Width + Resource::Space_Margin;
110  _height = getHeaderBottom() + Resource::Corner_Margin;
111  };*/
112 
113  painter->save();
114  painter->setPen(getPenColor());
115  painter->setBrush(getBrushColor());
117  painter->restore();
118 }
119 
120 void SceneComposedNodeItem::update(GuiEvent event, int type, Subject* son)
121 {
122  DEBTRACE("SceneComposedNodeItem::update "<< eventName(event)<<" "<<type<<" "<<son);
123  SceneNodeItem::update(event, type, son);
124  AbstractSceneItem *item;
125  switch (event)
126  {
127  case YACS::HMI::ADD:
128  switch (type)
129  {
130  case YACS::HMI::BLOC:
131  item = new SceneBlocItem(_scene,
132  this,
133  son->getName().c_str(),
134  son);
135  item->addHeader();
136  autoPosNewChild(item, _children, true);
137  break;
138  case YACS::HMI::FORLOOP:
140  case YACS::HMI::SWITCH:
143  item = new SceneComposedNodeItem(_scene,
144  this,
145  son->getName().c_str(),
146  son);
147  item->addHeader();
148  if ( !QtGuiContext::getQtCurrent()->isEdition()
149  && (type == YACS::HMI::FORLOOP || type == YACS::HMI::FOREACHLOOP) )
150  {
151  item->addProgressItem();
152  }
153  autoPosNewChild(item, _children, true);
154  break;
158  case YACS::HMI::CPPNODE:
161  case YACS::HMI::XMLNODE:
163  case YACS::HMI::OUTNODE:
166  item = new SceneElementaryNodeItem(_scene,
167  this,
168  son->getName().c_str(),
169  son);
170  item->addHeader();
171  autoPosNewChild(item, _children, true);
172  break;
175  item = new SceneInPortItem(_scene,
176  _header,
177  son->getName().c_str(),
178  son);
179  _header->autoPosNewPort(item);
180  _inPorts.push_back(item);
182  {
185  SceneComposedNodeItem *proc = dynamic_cast<SceneComposedNodeItem*>(item);
186  proc->rebuildLinks();
187  }
188  break;
191  item = new SceneOutPortItem(_scene,
192  _header,
193  son->getName().c_str(),
194  son);
195  _header->autoPosNewPort(item);
196  _outPorts.push_back(item);
198  {
201  SceneComposedNodeItem *proc = dynamic_cast<SceneComposedNodeItem*>(item);
202  proc->rebuildLinks();
203  }
204  break;
205  default:
206  DEBTRACE("SceneComposedNodeItem::update() ADD, type not handled:" << type);
207  }
208  break;
209  case YACS::HMI::ADDLINK:
210  switch (type)
211  {
212  case YACS::HMI::DATALINK:
213  if (SubjectLink* slink = dynamic_cast<SubjectLink*>(son))
214  {
215  SubjectDataPort* soutp = slink->getSubjectOutPort();
216  SubjectDataPort* sinp = slink->getSubjectInPort();
219  ScenePortItem* from = dynamic_cast<ScenePortItem*>(scout);
220  ScenePortItem* to = dynamic_cast<ScenePortItem*>(scin);
221  if (dynamic_cast<SubjectInputDataStreamPort*>(sinp))
222  {
224  this,
225  from, to,
226  son->getName().c_str(),
227  son);
228  item->updateShape();
229  }
230  else
231  {
232  SceneLinkItem* item = new SceneLinkItem(_scene,
233  this,
234  from, to,
235  son->getName().c_str(),
236  son);
237  item->updateShape();
238  }
240  {
243  SceneComposedNodeItem *proc = dynamic_cast<SceneComposedNodeItem*>(item);
244  proc->rebuildLinks();
245  }
246  }
247  break;
248  }
249  break;
251  switch (type)
252  {
254  if (SubjectControlLink* slink = dynamic_cast<SubjectControlLink*>(son))
255  {
256  SubjectNode* soutn = slink->getSubjectOutNode();
257  SubjectNode* sinn = slink->getSubjectInNode();
260  SceneNodeItem* nodefrom = dynamic_cast<SceneNodeItem*>(scout);
261  SceneNodeItem* nodeto = dynamic_cast<SceneNodeItem*>(scin);
262  if (!nodeto || !nodefrom) DEBTRACE("CONTROLLINK problem -----------------");
263  ScenePortItem* from = nodefrom->getCtrlOutPortItem();
264  ScenePortItem* to = nodeto->getCtrlInPortItem();
265  if (!to || !from) DEBTRACE("CONTROLLINK problem -----------------");
267  this,
268  from, to,
269  son->getName().c_str(),
270  son);
271  item->updateShape();
273  {
276  SceneComposedNodeItem *proc = dynamic_cast<SceneComposedNodeItem*>(item);
277  proc->rebuildLinks();
278  }
279  }
280  break;
281  }
282  break;
283  case YACS::HMI::REMOVE:
284  //SceneObserverItem::update(event, type, son);
285  break;
286  case YACS::HMI::SETCASE:
287  {
288  SubjectSwitch *sSwitch = dynamic_cast<SubjectSwitch*>(_subject);
289  if (sSwitch)
290  {
291  Switch *aSwitch = dynamic_cast<Switch*>(sSwitch->getNode());
292  Node *node = aSwitch->edGetNode(type);
293  if (node)
294  {
295  if (GuiContext::getCurrent()->_mapOfSubjectNode.count(node))
296  {
298  if (QtGuiContext::getQtCurrent()->_mapOfSceneItem.count(sub))
299  {
301  SceneNodeItem *scnode = dynamic_cast<SceneNodeItem*>(item);
302  if (scnode) scnode->updateName();
303  }
304  }
305  }
306  }
307  }
308  break;
309  case YACS::HMI::CUT:
310  {
312  removeChildFromList(sinode);
313  }
314  break;
315  case YACS::HMI::PASTE:
316  {
318  sinode->setParent(this);
319  sinode->setLevel();
320  if (SceneComposedNodeItem *scnode = dynamic_cast<SceneComposedNodeItem*>(sinode))
321  scnode->adjustColors();
322  autoPosNewChild(sinode, _children, true);
323  }
324  break;
325  case PROGRESS:
326  {
327  if (dynamic_cast<SubjectForLoop*>(son) || dynamic_cast<SubjectForEachLoop*>(son))
328  {
329  if (SceneProgressItem* spitem = getProgressItem())
330  spitem->setProgress(son->getProgress().c_str());
331  }
332  }
333  break;
334  default:
335  ;
336 // DEBTRACE("SceneComposedNodeItem::update(), event not handled: "<< eventName(event));
337  }
338 }
339 
341  const std::list<AbstractSceneItem*> alreadySet,
342  bool isNew)
343 {
344  SceneItem *it = dynamic_cast<SceneItem*>(item);
345  YASSERT(it);
346 
347  QRectF childrenBox;
348  qreal xLeft = Resource::Corner_Margin;
349  qreal yTop = getHeaderBottom() + Resource::Space_Margin;
350  for (list<AbstractSceneItem*>::const_iterator it=alreadySet.begin(); it!=alreadySet.end(); ++it)
351  {
352  childrenBox = childrenBox.united(childBoundingRect(*it));
353  DEBTRACE((*it)->getLabel().toStdString());
354  DEBTRACE("childrenBox valid " << childrenBox.right() << " " << childrenBox.bottom());
355  }
356  if (childrenBox.isValid())
357  yTop = childrenBox.bottom() + 1.; // +1. to avoid collision with bottom (penwidth)
358  //xLeft += childrenBox.right();
359  DEBTRACE("left, top " << xLeft << " " << yTop);
360  QPointF topLeft(xLeft, yTop);
361  if (isNew) _children.push_back(item);
362  if (_eventPos.isNull())
363  {
364  //DEBTRACE("_eventPos.isNull");
365  item->setTopLeft(topLeft);
366  }
367  else
368  {
369  //DEBTRACE("_eventPos " << _eventPos.x() << " " << _eventPos.y());
370  item->setTopLeft(_eventPos);
371  }
372  collisionResolv(it, -it->boundingRect().bottomRight()); // as if the new item was coming from top left (previous position outside)
374  _eventPos.setX(0);
375  _eventPos.setY(0);
376 }
377 
378 void SceneComposedNodeItem::popupMenu(QWidget *caller, const QPoint &globalPos)
379 {
381  m.popupMenu(caller, globalPos);
382 }
383 
384 std::list<AbstractSceneItem*> SceneComposedNodeItem::getChildren()
385 {
386  return _children;
387 }
388 
390 {
391  _children.remove(child);
392 }
393 
395 {
396  //update control links
397  std::list<SubjectControlLink*> lscl=dynamic_cast<SubjectNode*>(getSubject())->getSubjectControlLinks();
398  for (std::list<SubjectControlLink*>::const_iterator it = lscl.begin(); it != lscl.end(); ++it) {
400 
401  bool b1 = true, b2 = true;
402 
403  SceneNodeItem* no = lk->getFromNode();
404  if (no) {
405  SceneComposedNodeItem* scni = dynamic_cast<SceneComposedNodeItem*>(no);
406  if (scni) {
407  b1 = scni!=this;
408  };
409  };
410 
411  no = lk->getToNode();
412  if (no) {
413  SceneComposedNodeItem* scni = dynamic_cast<SceneComposedNodeItem*>(no);
414  if (scni) {
415  b2 = scni!=this;
416  };
417  };
418 
419  if (b1 && b2) {
420  if (toExpand) {
421  lk->show();
422  } else {
423  lk->hide();
424  };
425  };
426  };
427 }
428 
430  DEBTRACE("SceneComposedNodeItem::reorganizeShrinkExpand " << _expanded << " " << _label.toStdString());
431 
432  bool toExpand = true;
433  if (theShrinkMode == CurrentNode) {
434  // shrink/expand current node only
435  toExpand = !isExpanded();
436 
437  updateControlLinks(toExpand);
438  shrinkExpandRecursive(toExpand, true, theShrinkMode);
439 
440  } else {
441  if (!isExpanded())
442  return;
443  // shrink/expand child nodes
444  toExpand = !hasExpandedChildren(theShrinkMode == ElementaryNodes);
445  for (list<AbstractSceneItem*>::const_iterator it=_children.begin(); it!=_children.end(); ++it) {
446  SceneItem* item = dynamic_cast<SceneItem*>(*it);
447  SceneNodeItem *sni = dynamic_cast<SceneNodeItem*>(item);
448  item->shrinkExpandRecursive(toExpand, true, theShrinkMode);
449  }
450  _ancestorShrinked = !toExpand;
454  adjustHeader();
455  rebuildLinks();
456  }
457 
459  {
462  SceneComposedNodeItem *proc = dynamic_cast<SceneComposedNodeItem*>(item);
463  proc->rebuildLinks();
464  }
465 }
466 
468 {
469  bool res = false;
470  for (list<AbstractSceneItem*>::const_iterator it=_children.begin(); it!=_children.end() && !res; ++it) {
471  SceneItem* item = dynamic_cast<SceneItem*>(*it);
472  SceneNodeItem *sni = dynamic_cast<SceneNodeItem*>(item);
473  if (sni->isExpanded()) {
474  res = true;
475  if (recursively)
476  if (SceneComposedNodeItem *scni = dynamic_cast<SceneComposedNodeItem*>(sni))
477  res = scni->hasExpandedChildren(recursively);
478  }
479  }
480  return res;
481 }
482 
483 void SceneComposedNodeItem::shrinkExpandRecursive(bool toExpand, bool fromHere, ShrinkMode theShrinkMode)
484 {
485  DEBTRACE("SceneComposedNodeItem::shrinkExpandRecursive " << isExpanding << " " << fromHere << " " << isExpanded() << " " << _label.toStdString());
486 
487  bool toChangeShrinkState = false;
488  switch (theShrinkMode) {
489  case CurrentNode:
490  if (fromHere)
491  toChangeShrinkState = true;
492  break;
493  case ChildrenNodes:
494  if (fromHere)
495  toChangeShrinkState = true;
496  break;
497  case ElementaryNodes:
498  toChangeShrinkState = false;
499  break;
500  }
501  if (toChangeShrinkState) {
502  if (toExpand != isExpanded())
503  setExpanded(toExpand);
504  } else if (!isExpanded() && theShrinkMode == ElementaryNodes) {
505  return;
506  }
507 
508  updateControlLinks(toExpand);
509 
510  if (!toExpand)
511  { // ---collapsing: hide first children , then resize
512  for (list<AbstractSceneItem*>::const_iterator it=_children.begin(); it!=_children.end(); ++it)
513  {
514  SceneItem* item = dynamic_cast<SceneItem*>(*it);
515  item->shrinkExpandRecursive(toExpand, false, theShrinkMode);
516  if (theShrinkMode != ElementaryNodes) {
517  item->hide();
518  DEBTRACE("------------------------------- Hide " << item->getLabel().toStdString());
519  item->shrinkExpandLink(false);
520  }
521  }
522 
523  if (toChangeShrinkState || theShrinkMode != ElementaryNodes) {
524  if (_shownState == expandShown)
525  {
528  }
529 
530  if (fromHere)
531  {
533  }
534  else
535  {
536  _ancestorShrinked = true;
538  }
539 
541  if (_shownState == shrinkShown)
543  else
545 
546  if (_shownState == shrinkHidden) // shrink of ancestor
547  setPos(0 ,0);
548  else
549  setPos(_expandedPos);
550  adjustHeader();
551  if (_progressItem)
553  }
554  }
555  else
556  { // --- expanding: resize, then show children
557  if (toChangeShrinkState)
558  _ancestorShrinked = false;
559 
560  for (list<AbstractSceneItem*>::const_iterator it=_children.begin(); it!=_children.end(); ++it)
561  {
562  SceneItem* item = dynamic_cast<SceneItem*>(*it);
563  item->shrinkExpandRecursive(isExpanded(), false, theShrinkMode);
564  if (theShrinkMode != ElementaryNodes) {
565  if (isExpanded())
566  {
567  item->show();
568  DEBTRACE("------------------------------- Show " << item->getLabel().toStdString());
569  }
570  else
571  {
572  item->hide();
573  DEBTRACE("------------------------------- Hide " << item->getLabel().toStdString());
574  }
575  item->shrinkExpandLink(fromHere);
576  }
577  }
578 
579  if (isExpanded())
580  {
584  }
585  else
586  {
590  }
591  setPos(_expandedPos);
592  adjustHeader();
593  if (_progressItem)
595  }
596 }
597 
599  DEBTRACE("SceneComposedNodeItem::shrinkExpandLink " << se << " " << _label.toStdString());
600  se = se && isExpanded();
601  foreach (QGraphicsItem *child, childItems()) {
602  if (SceneItem *sci = dynamic_cast<SceneItem*>(child)) {
603  sci->shrinkExpandLink(se);
604  };
605  };
606 }
607 
609 {
610  DEBTRACE("SceneComposedNodeItem::reorganize() " << _label.toStdString());
611  list<AbstractSceneItem*> alreadySet;
612  for (list<AbstractSceneItem*>::const_iterator it=_children.begin(); it!=_children.end(); ++it)
613  {
614  autoPosNewChild(*it, alreadySet);
615  alreadySet.push_back(*it);
616  }
617 }
618 
620 {
621  _shownState = ss;
622  if (_shownState == shrinkHidden)
623  {
624  _ancestorShrinked = true;
625  hide();
626  }
627  else
628  {
629  _ancestorShrinked = false;
630  show();
631  }
632  adjustHeader();
633  if (_progressItem)
635 }
636 
638 {
639  //DEBTRACE("SceneComposedNodeItem::collisionResolv " << _label.toStdString());
640  for (list<AbstractSceneItem*>::const_iterator it=_children.begin(); it!=_children.end(); ++it)
641  {
642  SceneNodeItem *other = dynamic_cast<SceneNodeItem*>(*it);
643  if (other && (other != child))
644  {
645  if (child->collidesWithItem(other))
646  {
647  //DEBTRACE("collision detected with " << other->getLabel().toStdString());
648  QRectF otherBR = (other->mapToParent(other->boundingRect())).boundingRect();
649  qreal oldX = oldPos.x();
650  qreal oldY = oldPos.y();
651  qreal newX = child->pos().x();
652  qreal newY = child->pos().y();
653  qreal othX = otherBR.left()+0.5;
654  qreal othY = otherBR.top()+0.5;
655  //DEBTRACE("oldX=" << oldX << " oldY=" << oldY << " newX=" << newX << " newY=" << newY);
656  //DEBTRACE("otherLeft=" << otherBR.left() << " otherRight=" << otherBR.right() <<
657  // " otherTop=" << otherBR.top() << " otherBottom=" << otherBR.bottom());
658  //DEBTRACE("width=" << child->boundingRect().width() <<
659  // " height=" << child->boundingRect().height());
660  bool fromTop = (((oldY + child->boundingRect().height()) <= otherBR.top()+1) &&
661  ((newY + child->boundingRect().height()) >= otherBR.top()));
662  bool fromBottom = (( oldY >= otherBR.bottom()) &&
663  ( newY <= otherBR.bottom()));
664  bool fromRight = (( oldX >= otherBR.right()) &&
665  ( newX <= otherBR.right()));
666  bool fromLeft = (((oldX+ child->boundingRect().width()) <= otherBR.left()+1) &&
667  ((newX+ child->boundingRect().width()) >= otherBR.left()));
668  //DEBTRACE("fromTop=" << fromTop << " fromBottom=" << fromBottom
669  // << " fromRight=" << fromRight << " fromLeft=" << fromLeft);
670  bool pushOther =false;
671  bool blocThis = false;
672  if (fromTop)
673  {
674  othY = newY + child->boundingRect().height();
675  pushOther = true;
676  other->_blocY = false;
677  }
678  if (fromLeft)
679  {
680  othX = newX+ child->boundingRect().width();
681  pushOther = true;
682  other->_blocX = false;
683  }
684  if (fromBottom)
685  {
686  if (other->_blocY)
687  {
688  newY = otherBR.bottom() + 1;
689  blocThis = true;
690  _blocY = true;
691  }
692  else
693  {
694  othY = newY - otherBR.height();
695  if ( othY < Resource::Space_Margin + getHeaderBottom() )
696  {
698  other->_blocY = true;
699  newY = otherBR.bottom() + 1;
700  _blocY = true;
701  blocThis = true;
702  }
703  else
704  pushOther = true;
705  }
706  }
707  if (fromRight)
708  {
709  if (other->_blocX)
710  {
711  newX = otherBR.right()+ 1;
712  blocThis = true;
713  _blocX = true;
714  }
715  else
716  {
717  othX = newX - otherBR.width();
718  if (othX < Resource::Space_Margin)
719  {
720  othX = Resource::Space_Margin;
721  other->_blocX = true;
722  newX = otherBR.right()+ 1;
723  _blocX = true;
724  blocThis = true;
725  }
726  else
727  pushOther = true;
728  }
729  }
730  //DEBTRACE("newX=" << newX << " newY=" << newY);
731  if (blocThis) child->setTopLeft(QPointF(newX, newY));
732  if (pushOther)
733  {
734  other->setTopLeft(QPointF(othX, othY));
735  }
736  }
737  }
738  }
739 }
740 
742 {
743  DEBTRACE("SceneComposedNodeItem::rebuildLinks " << QtGuiContext::_delayCalc);
745  return;
746  CHRONO(1);
747  CHRONO(2);
748  LinkMatrix matrix(this);
749  matrix.compute();
750  CHRONOSTOP(2);
751  CHRONO(3);
752  list<linkdef> alist = matrix.getListOfDataLinkDef();
753  list<linkdef> blist = matrix.getListOfCtrlLinkDef(); // add list operator ?
754  for (list<linkdef>::const_iterator ii = blist.begin(); ii != blist.end(); ++ii)
755  alist.push_back(*ii);
756 
757  CHRONOSTOP(3);
758  CHRONO(4);
759  LinkAStar astar(matrix);
760  for (list<linkdef>::const_iterator it = alist.begin(); it != alist.end(); ++it)
761  {
762  linkdef ali = *it;
763  DEBTRACE("from("<<ali.from.first<<","<<ali.from.second
764  <<") to ("<<ali.to.first<<","<<ali.to.second
765  <<") " << ali.item->getLabel().toStdString());
766  if(ali.from.first<0||ali.from.second<0||ali.to.first<0||ali.to.second<0) continue;
767  CHRONO(5);
768  bool isPath = astar.computePath(LNode(ali.from), LNode(ali.to));
769  CHRONOSTOP(5);
770  CHRONO(6);
771  if (! isPath) DEBTRACE("Link Path not found !");
772  if (! isPath) continue;
773  LNodePath ijPath = astar.givePath();
775  matrix.incrementCost(ijPath);
776  LinkPath apath = matrix.getPath(ijPath);
777 // DEBTRACE(apath.size());
778  CHRONOSTOP(6);
779  CHRONO(7);
780  ali.item->setPath(apath);
781  }
782 }
783 
785 {
786  DEBTRACE("SceneComposedItem::arrangeNodes " << isRecursive);
787 
788  bool isExtern = !QtGuiContext::_delayCalc;
789  QtGuiContext::_delayCalc = true; // avoid rebuildLinks
790 
791  SubjectComposedNode *scnode = dynamic_cast<SubjectComposedNode*>(getSubject());
792  YASSERT(scnode);
793  ComposedNode *cnode = dynamic_cast<ComposedNode*>(scnode->getNode());
794  YASSERT(cnode);
795 
796  if (isRecursive)
797  {
798  list<Node*> children = cnode->edGetDirectDescendants();
799  for (list<Node*>::iterator it = children.begin(); it != children.end(); ++it)
800  {
801  DEBTRACE("child " << (*it)->getName());
802  SceneComposedNodeItem *scni = 0;
803  ComposedNode *cchild = dynamic_cast<ComposedNode*>(*it);
804  if (cchild)
805  {
808  if (sci) scni = dynamic_cast<SceneComposedNodeItem*>(sci);
809  }
810  if (scni && (scni->getShownState() == expandShown))
811  {
812  DEBTRACE("call arrangeNode on child " << (*it)->getName());
813  scni->arrangeNodes(isRecursive);
814  }
815  }
817  }
818  else
820 
821  if (isExtern)
822  {
823  QtGuiContext::_delayCalc = false; // allow rebuildLinks
825  rebuildLinks();
826  }
827 }
828 
830 {
831  reorganize();
832 }
833 
834 void SceneComposedNodeItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
835 {
836  bool accepted = false;
837  const ItemMimeData *myData = dynamic_cast<const ItemMimeData*>(event->mimeData());
838  if (myData)
839  {
840  if (myData->hasFormat("yacs/cataService") ||
841  myData->hasFormat("yacs/cataNode") ||
842  myData->hasFormat("yacs/subjectNode"))
843  {
844  event->setAccepted(true);
845  _dragOver = true;
846  QGraphicsItem::update();
847  return;
848  }
849  }
850  event->setAccepted(accepted);
851 }
852 
853 void SceneComposedNodeItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
854 {
855  Q_UNUSED(event);
856  _dragOver = false;
857  QGraphicsItem::update();
858 }
859 
860 void SceneComposedNodeItem::dropEvent(QGraphicsSceneDragDropEvent *event)
861 {
862  Q_UNUSED(event);
863  _dragOver = false;
864  QGraphicsItem::update();
865 
866  const ItemMimeData *myData = dynamic_cast<const ItemMimeData*>(event->mimeData());
867  if (!myData) return;
868  setEventPos(event->scenePos());
869  if (myData->hasFormat("yacs/cataService") || myData->hasFormat("yacs/cataNode"))
870  {
871  SubjectComposedNode *cnode = dynamic_cast<SubjectComposedNode*>(getSubject());
872  bool createNewComponentInstance=Resource::COMPONENT_INSTANCE_NEW;
873  // by default getControl gives false. In this case we use the user preference COMPONENT_INSTANCE_NEW
874  // to create the node. If getControl gives true we invert the user preference
875  if(myData->getControl())
876  createNewComponentInstance=!Resource::COMPONENT_INSTANCE_NEW;
877  QtGuiContext::getQtCurrent()->getGMain()->_guiEditor->CreateNodeFromCatalog(myData, cnode,createNewComponentInstance);
878  }
879  else if(myData->hasFormat("yacs/subjectNode"))
880  {
881  Subject *sub = myData->getSubject();
882  if (!sub) return;
883  SubjectNode *node = dynamic_cast<SubjectNode*>(sub);
884  if (!node) return;
885  if (dynamic_cast<SubjectProc*>(node)) return; // --- do not reparent proc !
886  SubjectComposedNode *cnode = dynamic_cast<SubjectComposedNode*>(getSubject());
887  if (cnode)
888  if (!node->reparent(cnode))
889  Message mess;
890  }
891 }
892 
894 {
895  if (_dragOver)
896  return Resource::dragOver;
897  if (isSelected())
898  return _hiPenColor;
899  else
900  return _penColor;
901 }
902 
904 {
905  if (_dragOver)
906  return _hiBrushColor;
907 
908  QColor color;
909  if (isSelected())
910  color = _hiBrushColor;
911  else if (_emphasized)
913  else
914  color = _brushColor;
915 
916  if (_hover)
917  color = hoverColor(color);
918  return color;
919 }
920 
922 {
924  if(!_header)
925  return;
926  foreach (QGraphicsItem *child, _header->childItems())
927  {
928  if (SceneItem *sci = dynamic_cast<SceneItem*>(child))
929  {
930  sci->updateLinks();
931  }
932  }
933 }
934