1 // Copyright (C) 2006-2014 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "SceneBlocItem.hxx"
24 #include "SceneComposedNodeItem.hxx"
25 #include "SceneElementaryNodeItem.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"
39 #include "Message.hxx"
40 #include "guiObservers.hxx"
41 #include "GuiEditor.hxx"
46 #include <QGraphicsSceneDragDropEvent>
50 #include "Resource.hxx"
53 #include "YacsTrace.hxx"
56 using namespace YACS::ENGINE;
57 using namespace YACS::HMI;
59 SceneComposedNodeItem::SceneComposedNodeItem(QGraphicsScene *scene, SceneItem *parent,
60 QString label, Subject *subject)
61 : SceneNodeItem(scene, parent, label, subject)
63 DEBTRACE("SceneComposedNodeItem::SceneComposedNodeItem " <<label.toStdString());
65 _width = 2*Resource::Corner_Margin + 2*Resource::DataPort_Width + Resource::Space_Margin;
66 _height = Resource::Header_Height + Resource::DataPort_Height + Resource::Corner_Margin;
68 _hiBrushColor = Resource::ComposedNode_hiBrush;
69 _penColor = Resource::ComposedNode_pen;
70 _hiPenColor = Resource::ComposedNode_hiPen;
76 SceneComposedNodeItem::~SceneComposedNodeItem()
80 void SceneComposedNodeItem::adjustColors()
82 _brushColor = Resource::ComposedNode_brush.darker(100 +5*_level);
83 for (list<AbstractSceneItem*>::const_iterator it=_children.begin(); it!=_children.end(); ++it)
85 if (SceneComposedNodeItem *scnode = dynamic_cast<SceneComposedNodeItem*>(*it))
86 scnode->adjustColors();
90 QRectF SceneComposedNodeItem::childrenBoundingRect() const
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);
101 void SceneComposedNodeItem::paint(QPainter *painter,
102 const QStyleOptionGraphicsItem *option,
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;
114 painter->setPen(getPenColor());
115 painter->setBrush(getBrushColor());
116 painter->drawRect(QRectF(Resource::Border_Margin, Resource::Border_Margin, _width - 2*Resource::Border_Margin, _height - 2*Resource::Border_Margin));
120 void SceneComposedNodeItem::update(GuiEvent event, int type, Subject* son)
122 DEBTRACE("SceneComposedNodeItem::update "<< eventName(event)<<" "<<type<<" "<<son);
123 SceneNodeItem::update(event, type, son);
124 AbstractSceneItem *item;
130 case YACS::HMI::BLOC:
131 item = new SceneBlocItem(_scene,
133 son->getName().c_str(),
136 autoPosNewChild(item, _children, true);
138 case YACS::HMI::FORLOOP:
139 case YACS::HMI::WHILELOOP:
140 case YACS::HMI::SWITCH:
141 case YACS::HMI::FOREACHLOOP:
142 case YACS::HMI::OPTIMIZERLOOP:
143 item = new SceneComposedNodeItem(_scene,
145 son->getName().c_str(),
148 if ( !QtGuiContext::getQtCurrent()->isEdition()
149 && (type == YACS::HMI::FORLOOP || type == YACS::HMI::FOREACHLOOP) )
151 item->addProgressItem();
153 autoPosNewChild(item, _children, true);
155 case YACS::HMI::PYTHONNODE:
156 case YACS::HMI::PYFUNCNODE:
157 case YACS::HMI::CORBANODE:
158 case YACS::HMI::CPPNODE:
159 case YACS::HMI::SALOMENODE:
160 case YACS::HMI::SALOMEPYTHONNODE:
161 case YACS::HMI::XMLNODE:
162 case YACS::HMI::PRESETNODE:
163 case YACS::HMI::OUTNODE:
164 case YACS::HMI::STUDYINNODE:
165 case YACS::HMI::STUDYOUTNODE:
166 item = new SceneElementaryNodeItem(_scene,
168 son->getName().c_str(),
171 autoPosNewChild(item, _children, true);
173 case YACS::HMI::INPUTPORT:
174 case YACS::HMI::INPUTDATASTREAMPORT:
175 item = new SceneInPortItem(_scene,
177 son->getName().c_str(),
179 _header->autoPosNewPort(item);
180 _inPorts.push_back(item);
181 if (Scene::_autoComputeLinks && !QtGuiContext::getQtCurrent()->isLoading())
183 YACS::HMI::SubjectProc* subproc = QtGuiContext::getQtCurrent()->getSubjectProc();
184 SceneItem *item = QtGuiContext::getQtCurrent()->_mapOfSceneItem[subproc];
185 SceneComposedNodeItem *proc = dynamic_cast<SceneComposedNodeItem*>(item);
186 proc->rebuildLinks();
189 case YACS::HMI::OUTPUTPORT:
190 case YACS::HMI::OUTPUTDATASTREAMPORT:
191 item = new SceneOutPortItem(_scene,
193 son->getName().c_str(),
195 _header->autoPosNewPort(item);
196 _outPorts.push_back(item);
197 if (Scene::_autoComputeLinks && !QtGuiContext::getQtCurrent()->isLoading())
199 YACS::HMI::SubjectProc* subproc = QtGuiContext::getQtCurrent()->getSubjectProc();
200 SceneItem *item = QtGuiContext::getQtCurrent()->_mapOfSceneItem[subproc];
201 SceneComposedNodeItem *proc = dynamic_cast<SceneComposedNodeItem*>(item);
202 proc->rebuildLinks();
206 DEBTRACE("SceneComposedNodeItem::update() ADD, type not handled:" << type);
209 case YACS::HMI::ADDLINK:
212 case YACS::HMI::DATALINK:
213 if (SubjectLink* slink = dynamic_cast<SubjectLink*>(son))
215 SubjectDataPort* soutp = slink->getSubjectOutPort();
216 SubjectDataPort* sinp = slink->getSubjectInPort();
217 SceneItem * scout = QtGuiContext::getQtCurrent()->_mapOfSceneItem[soutp];
218 SceneItem * scin = QtGuiContext::getQtCurrent()->_mapOfSceneItem[sinp];
219 ScenePortItem* from = dynamic_cast<ScenePortItem*>(scout);
220 ScenePortItem* to = dynamic_cast<ScenePortItem*>(scin);
221 if (dynamic_cast<SubjectInputDataStreamPort*>(sinp))
223 SceneDSLinkItem* item = new SceneDSLinkItem(_scene,
226 son->getName().c_str(),
232 SceneLinkItem* item = new SceneLinkItem(_scene,
235 son->getName().c_str(),
239 if (Scene::_autoComputeLinks && !QtGuiContext::getQtCurrent()->isLoading())
241 YACS::HMI::SubjectProc* subproc = QtGuiContext::getQtCurrent()->getSubjectProc();
242 SceneItem *item = QtGuiContext::getQtCurrent()->_mapOfSceneItem[subproc];
243 SceneComposedNodeItem *proc = dynamic_cast<SceneComposedNodeItem*>(item);
244 proc->rebuildLinks();
250 case YACS::HMI::ADDCONTROLLINK:
253 case YACS::HMI::CONTROLLINK:
254 if (SubjectControlLink* slink = dynamic_cast<SubjectControlLink*>(son))
256 SubjectNode* soutn = slink->getSubjectOutNode();
257 SubjectNode* sinn = slink->getSubjectInNode();
258 SceneItem * scout = QtGuiContext::getQtCurrent()->_mapOfSceneItem[soutn];
259 SceneItem * scin = QtGuiContext::getQtCurrent()->_mapOfSceneItem[sinn];
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 -----------------");
266 SceneCtrlLinkItem* item = new SceneCtrlLinkItem(_scene,
269 son->getName().c_str(),
272 if (Scene::_autoComputeLinks && !QtGuiContext::getQtCurrent()->isLoading())
274 YACS::HMI::SubjectProc* subproc = QtGuiContext::getQtCurrent()->getSubjectProc();
275 SceneItem *item = QtGuiContext::getQtCurrent()->_mapOfSceneItem[subproc];
276 SceneComposedNodeItem *proc = dynamic_cast<SceneComposedNodeItem*>(item);
277 proc->rebuildLinks();
283 case YACS::HMI::REMOVE:
284 //SceneObserverItem::update(event, type, son);
286 case YACS::HMI::SETCASE:
288 SubjectSwitch *sSwitch = dynamic_cast<SubjectSwitch*>(_subject);
291 Switch *aSwitch = dynamic_cast<Switch*>(sSwitch->getNode());
292 Node *node = aSwitch->edGetNode(type);
295 if (GuiContext::getCurrent()->_mapOfSubjectNode.count(node))
297 Subject* sub = GuiContext::getCurrent()->_mapOfSubjectNode[node];
298 if (QtGuiContext::getQtCurrent()->_mapOfSceneItem.count(sub))
300 SceneItem* item = QtGuiContext::getQtCurrent()->_mapOfSceneItem[sub];
301 SceneNodeItem *scnode = dynamic_cast<SceneNodeItem*>(item);
302 if (scnode) scnode->updateName();
311 SceneItem * sinode = QtGuiContext::getQtCurrent()->_mapOfSceneItem[son];
312 removeChildFromList(sinode);
315 case YACS::HMI::PASTE:
317 SceneItem * sinode = QtGuiContext::getQtCurrent()->_mapOfSceneItem[son];
318 sinode->setParent(this);
320 if (SceneComposedNodeItem *scnode = dynamic_cast<SceneComposedNodeItem*>(sinode))
321 scnode->adjustColors();
322 autoPosNewChild(sinode, _children, true);
327 if (dynamic_cast<SubjectForLoop*>(son) || dynamic_cast<SubjectForEachLoop*>(son))
329 if (SceneProgressItem* spitem = getProgressItem())
330 spitem->setProgress(son->getProgress().c_str());
336 // DEBTRACE("SceneComposedNodeItem::update(), event not handled: "<< eventName(event));
340 void SceneComposedNodeItem::autoPosNewChild(AbstractSceneItem *item,
341 const std::list<AbstractSceneItem*> alreadySet,
344 SceneItem *it = dynamic_cast<SceneItem*>(item);
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)
352 childrenBox = childrenBox.united(childBoundingRect(*it));
353 DEBTRACE((*it)->getLabel().toStdString());
354 DEBTRACE("childrenBox valid " << childrenBox.right() << " " << childrenBox.bottom());
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())
364 //DEBTRACE("_eventPos.isNull");
365 item->setTopLeft(topLeft);
369 //DEBTRACE("_eventPos " << _eventPos.x() << " " << _eventPos.y());
370 item->setTopLeft(_eventPos);
372 collisionResolv(it, -it->boundingRect().bottomRight()); // as if the new item was coming from top left (previous position outside)
373 if (Scene::_autoComputeLinks && !QtGuiContext::getQtCurrent()->isLoading()) rebuildLinks();
378 void SceneComposedNodeItem::popupMenu(QWidget *caller, const QPoint &globalPos)
381 m.popupMenu(caller, globalPos);
384 std::list<AbstractSceneItem*> SceneComposedNodeItem::getChildren()
389 void SceneComposedNodeItem::removeChildFromList(AbstractSceneItem* child)
391 _children.remove(child);
394 void SceneComposedNodeItem::updateControlLinks(bool toExpand)
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) {
399 SceneLinkItem* lk = dynamic_cast<SceneLinkItem*>(QtGuiContext::getQtCurrent()->_mapOfSceneItem[*it]);
401 bool b1 = true, b2 = true;
403 SceneNodeItem* no = lk->getFromNode();
405 SceneComposedNodeItem* scni = dynamic_cast<SceneComposedNodeItem*>(no);
411 no = lk->getToNode();
413 SceneComposedNodeItem* scni = dynamic_cast<SceneComposedNodeItem*>(no);
429 void SceneComposedNodeItem::reorganizeShrinkExpand(ShrinkMode theShrinkMode) {
430 DEBTRACE("SceneComposedNodeItem::reorganizeShrinkExpand " << _expanded << " " << _label.toStdString());
432 bool toExpand = true;
433 if (theShrinkMode == CurrentNode) {
434 // shrink/expand current node only
435 toExpand = !isExpanded();
437 updateControlLinks(toExpand);
438 shrinkExpandRecursive(toExpand, true, theShrinkMode);
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);
450 _ancestorShrinked = !toExpand;
451 _width = _expandedWidth;
452 _height = _expandedHeight;
453 _shownState = expandShown;
458 if (Scene::_autoComputeLinks)
460 SubjectProc* subproc = QtGuiContext::getQtCurrent()->getSubjectProc();
461 SceneItem *item = QtGuiContext::getQtCurrent()->_mapOfSceneItem[subproc];
462 SceneComposedNodeItem *proc = dynamic_cast<SceneComposedNodeItem*>(item);
463 proc->rebuildLinks();
467 bool SceneComposedNodeItem::hasExpandedChildren(bool recursively)
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()) {
476 if (SceneComposedNodeItem *scni = dynamic_cast<SceneComposedNodeItem*>(sni))
477 res = scni->hasExpandedChildren(recursively);
483 void SceneComposedNodeItem::shrinkExpandRecursive(bool toExpand, bool fromHere, ShrinkMode theShrinkMode)
485 DEBTRACE("SceneComposedNodeItem::shrinkExpandRecursive " << isExpanding << " " << fromHere << " " << isExpanded() << " " << _label.toStdString());
487 bool toChangeShrinkState = false;
488 switch (theShrinkMode) {
491 toChangeShrinkState = true;
495 toChangeShrinkState = true;
497 case ElementaryNodes:
498 toChangeShrinkState = false;
501 if (toChangeShrinkState) {
502 if (toExpand != isExpanded())
503 setExpanded(toExpand);
504 } else if (!isExpanded() && theShrinkMode == ElementaryNodes) {
508 updateControlLinks(toExpand);
511 { // ---collapsing: hide first children , then resize
512 for (list<AbstractSceneItem*>::const_iterator it=_children.begin(); it!=_children.end(); ++it)
514 SceneItem* item = dynamic_cast<SceneItem*>(*it);
515 item->shrinkExpandRecursive(toExpand, false, theShrinkMode);
516 if (theShrinkMode != ElementaryNodes) {
518 DEBTRACE("------------------------------- Hide " << item->getLabel().toStdString());
519 item->shrinkExpandLink(false);
523 if (toChangeShrinkState || theShrinkMode != ElementaryNodes) {
524 if (_shownState == expandShown)
526 _expandedWidth = _width;
527 _expandedHeight = _height;
532 _shownState = shrinkShown;
536 _ancestorShrinked = true;
537 _shownState = shrinkHidden;
540 _width = 2*Resource::Corner_Margin + 2*Resource::DataPort_Width + Resource::Space_Margin;
541 if (_shownState == shrinkShown)
542 _height = getHeaderBottom() + Resource::Corner_Margin;
544 _height = Resource::Header_Height + Resource::Corner_Margin;
546 if (_shownState == shrinkHidden) // shrink of ancestor
549 setPos(_expandedPos);
552 _progressItem->adjustGeometry();
556 { // --- expanding: resize, then show children
557 if (toChangeShrinkState)
558 _ancestorShrinked = false;
560 for (list<AbstractSceneItem*>::const_iterator it=_children.begin(); it!=_children.end(); ++it)
562 SceneItem* item = dynamic_cast<SceneItem*>(*it);
563 item->shrinkExpandRecursive(isExpanded(), false, theShrinkMode);
564 if (theShrinkMode != ElementaryNodes) {
568 DEBTRACE("------------------------------- Show " << item->getLabel().toStdString());
573 DEBTRACE("------------------------------- Hide " << item->getLabel().toStdString());
575 item->shrinkExpandLink(fromHere);
581 _width = _expandedWidth;
582 _height = _expandedHeight;
583 _shownState = expandShown;
587 _shownState = shrinkShown;
588 _width = 2*Resource::Corner_Margin + 2*Resource::DataPort_Width + Resource::Space_Margin;
589 _height = getHeaderBottom() + Resource::Corner_Margin;
591 setPos(_expandedPos);
594 _progressItem->adjustGeometry();
598 void SceneComposedNodeItem::shrinkExpandLink(bool se) {
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);
608 void SceneComposedNodeItem::reorganize()
610 DEBTRACE("SceneComposedNodeItem::reorganize() " << _label.toStdString());
611 list<AbstractSceneItem*> alreadySet;
612 for (list<AbstractSceneItem*>::const_iterator it=_children.begin(); it!=_children.end(); ++it)
614 autoPosNewChild(*it, alreadySet);
615 alreadySet.push_back(*it);
619 void SceneComposedNodeItem::setShownState(shownState ss)
622 if (_shownState == shrinkHidden)
624 _ancestorShrinked = true;
629 _ancestorShrinked = false;
634 _progressItem->adjustGeometry();
637 void SceneComposedNodeItem::collisionResolv(SceneItem* child, QPointF oldPos)
639 //DEBTRACE("SceneComposedNodeItem::collisionResolv " << _label.toStdString());
640 for (list<AbstractSceneItem*>::const_iterator it=_children.begin(); it!=_children.end(); ++it)
642 SceneNodeItem *other = dynamic_cast<SceneNodeItem*>(*it);
643 if (other && (other != child))
645 if (child->collidesWithItem(other))
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;
674 othY = newY + child->boundingRect().height();
676 other->_blocY = false;
680 othX = newX+ child->boundingRect().width();
682 other->_blocX = false;
688 newY = otherBR.bottom() + 1;
694 othY = newY - otherBR.height();
695 if ( othY < Resource::Space_Margin + getHeaderBottom() )
697 othY = Resource::Space_Margin + getHeaderBottom();
698 other->_blocY = true;
699 newY = otherBR.bottom() + 1;
711 newX = otherBR.right()+ 1;
717 othX = newX - otherBR.width();
718 if (othX < Resource::Space_Margin)
720 othX = Resource::Space_Margin;
721 other->_blocX = true;
722 newX = otherBR.right()+ 1;
730 //DEBTRACE("newX=" << newX << " newY=" << newY);
731 if (blocThis) child->setTopLeft(QPointF(newX, newY));
734 other->setTopLeft(QPointF(othX, othY));
741 void SceneComposedNodeItem::rebuildLinks()
743 DEBTRACE("SceneComposedNodeItem::rebuildLinks " << QtGuiContext::_delayCalc);
744 if (QtGuiContext::_delayCalc)
748 LinkMatrix matrix(this);
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);
759 LinkAStar astar(matrix);
760 for (list<linkdef>::const_iterator it = alist.begin(); it != alist.end(); ++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;
768 bool isPath = astar.computePath(LNode(ali.from), LNode(ali.to));
771 if (! isPath) DEBTRACE("Link Path not found !");
772 if (! isPath) continue;
773 LNodePath ijPath = astar.givePath();
774 if(Scene::_addRowCols)
775 matrix.incrementCost(ijPath);
776 LinkPath apath = matrix.getPath(ijPath);
777 // DEBTRACE(apath.size());
780 ali.item->setPath(apath);
784 void SceneComposedNodeItem::arrangeNodes(bool isRecursive)
786 DEBTRACE("SceneComposedItem::arrangeNodes " << isRecursive);
788 bool isExtern = !QtGuiContext::_delayCalc;
789 QtGuiContext::_delayCalc = true; // avoid rebuildLinks
791 SubjectComposedNode *scnode = dynamic_cast<SubjectComposedNode*>(getSubject());
793 ComposedNode *cnode = dynamic_cast<ComposedNode*>(scnode->getNode());
798 list<Node*> children = cnode->edGetDirectDescendants();
799 for (list<Node*>::iterator it = children.begin(); it != children.end(); ++it)
801 DEBTRACE("child " << (*it)->getName());
802 SceneComposedNodeItem *scni = 0;
803 ComposedNode *cchild = dynamic_cast<ComposedNode*>(*it);
806 SubjectNode* sn = GuiContext::getCurrent()->_mapOfSubjectNode[cchild];
807 SceneItem* sci = QtGuiContext::getQtCurrent()->_mapOfSceneItem[sn];
808 if (sci) scni = dynamic_cast<SceneComposedNodeItem*>(sci);
810 if (scni && (scni->getShownState() == expandShown))
812 DEBTRACE("call arrangeNode on child " << (*it)->getName());
813 scni->arrangeNodes(isRecursive);
823 QtGuiContext::_delayCalc = false; // allow rebuildLinks
824 if (Scene::_autoComputeLinks)
829 void SceneComposedNodeItem::arrangeChildNodes()
834 void SceneComposedNodeItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
836 bool accepted = false;
837 const ItemMimeData *myData = dynamic_cast<const ItemMimeData*>(event->mimeData());
840 if (myData->hasFormat("yacs/cataService") ||
841 myData->hasFormat("yacs/cataNode") ||
842 myData->hasFormat("yacs/subjectNode"))
844 event->setAccepted(true);
846 QGraphicsItem::update();
850 event->setAccepted(accepted);
853 void SceneComposedNodeItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
857 QGraphicsItem::update();
860 void SceneComposedNodeItem::dropEvent(QGraphicsSceneDragDropEvent *event)
864 QGraphicsItem::update();
866 const ItemMimeData *myData = dynamic_cast<const ItemMimeData*>(event->mimeData());
868 setEventPos(event->scenePos());
869 if (myData->hasFormat("yacs/cataService") || myData->hasFormat("yacs/cataNode"))
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);
879 else if(myData->hasFormat("yacs/subjectNode"))
881 Subject *sub = myData->getSubject();
883 SubjectNode *node = dynamic_cast<SubjectNode*>(sub);
885 if (dynamic_cast<SubjectProc*>(node)) return; // --- do not reparent proc !
886 SubjectComposedNode *cnode = dynamic_cast<SubjectComposedNode*>(getSubject());
888 if (!node->reparent(cnode))
893 QColor SceneComposedNodeItem::getPenColor()
896 return Resource::dragOver;
903 QColor SceneComposedNodeItem::getBrushColor()
906 return _hiBrushColor;
910 color = _hiBrushColor;
911 else if (_emphasized)
912 color = Resource::emphasizeBrushColor;
917 color = hoverColor(color);
921 void SceneComposedNodeItem::updateChildItems()
923 SceneNodeItem::updateChildItems();
926 foreach (QGraphicsItem *child, _header->childItems())
928 if (SceneItem *sci = dynamic_cast<SceneItem*>(child))