]> SALOME platform Git repositories - modules/yacs.git/blob - src/genericgui/SceneNodeItem.cxx
Salome HOME
Fix make check with Python 2.7
[modules/yacs.git] / src / genericgui / SceneNodeItem.cxx
1 // Copyright (C) 2006-2012  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.
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 #include "SceneNodeItem.hxx"
21 #include "SceneComposedNodeItem.hxx"
22 #include "SceneProcItem.hxx"
23 #include "SceneHeaderNodeItem.hxx"
24 #include "SceneInPortItem.hxx"
25 #include "SceneOutPortItem.hxx"
26 #include "SceneCtrlInPortItem.hxx"
27 #include "SceneCtrlOutPortItem.hxx"
28 #include "SceneLinkItem.hxx"
29 #include "Scene.hxx"
30 #include "QtGuiContext.hxx"
31 #include "Menus.hxx"
32 #include "GuiEditor.hxx"
33 #include "InPort.hxx"
34 #include "OutPort.hxx"
35
36 #include "Switch.hxx"
37 #include "Resource.hxx"
38
39 #include <QGraphicsSceneHoverEvent>
40 #include <QPointF>
41
42 #include <cmath>
43 #include <sstream>
44 #include <cassert>
45 #include <vector>
46
47 //#define _DEVDEBUG_
48 #include "YacsTrace.hxx"
49
50 using namespace std;
51 using namespace YACS::ENGINE;
52 using namespace YACS::HMI;
53
54 SceneNodeItem::SceneNodeItem(QGraphicsScene *scene, SceneItem *parent,
55                              QString label, Subject *subject)
56   : SceneObserverItem(scene, parent, label, subject)
57 {
58   _inPorts.clear();
59   _outPorts.clear();
60   _header = 0;
61   _brushColor = Resource::Scene_pen;
62   _moving = false;
63   _moved = false;
64   _blocX = false;
65   _blocY = false;
66   _dragable = true;
67   _dragButton = Qt::MidButton;
68   _execState = YACS::UNDEFINED;
69   _expanded = true;
70   _expandedPos = QPointF(0,0);
71   _expandedWidth = _width;
72   _expandedHeight = _height;
73   _shownState = expandShown;
74 }
75
76 SceneNodeItem::~SceneNodeItem()
77 {
78   if (SceneComposedNodeItem* parent = getParent())
79     parent->removeChildFromList(this);
80 }
81
82 void SceneNodeItem::setWidth(qreal width)
83 {
84   if (width != _width)
85     {
86       prepareGeometryChange();
87       _width = width;
88       _expandedWidth = _width;
89       adjustHeader();
90       QGraphicsItem::update();
91     }
92 }
93
94 void SceneNodeItem::setHeight(qreal height)
95 {
96   if (height != _height)
97     {
98       prepareGeometryChange();
99       _height = height;
100       _expandedHeight = _height;
101       QGraphicsItem::update();
102     }
103 }
104
105 void SceneNodeItem::addHeader()
106 {
107   DEBTRACE("SceneNodeItem::addHeader " << _label.toStdString());
108   if (!_hasHeader)
109     {
110       _hasHeader = true;
111       _header = new SceneHeaderNodeItem(_scene,
112                                         this,
113                                         getHeaderLabel());
114       updateState();
115       checkGeometryChange();
116     }
117 }
118
119 SceneHeaderItem* SceneNodeItem::getHeader()
120 {
121   return _header;
122 }
123
124 void SceneNodeItem::paint(QPainter *painter,
125                           const QStyleOptionGraphicsItem *option,
126                           QWidget *widget)
127 {
128   //DEBTRACE("SceneNodeItem::paint");
129 }
130
131 void SceneNodeItem::update(GuiEvent event, int type, Subject* son)
132 {
133   DEBTRACE("SceneNodeItem::update "<< eventName(event)<<" "<<type<<" "<<son);
134   SceneObserverItem::update(event, type, son);
135   SubjectNode *snode = 0;
136   Node *node = 0;
137   switch (event)
138     {
139     case YACS::HMI::RENAME:
140       DEBTRACE("SceneNodeItem::update RENAME " << _subject->getName());
141       updateName();
142       break;
143     case YACS::HMI::EDIT:
144       if (_header) _header->setEdited(type);
145       break;
146     case YACS::HMI::UPDATE:
147       updateState();
148       break;
149     case YACS::HMI::UPDATEPROGRESS:
150       setExecState(type);
151       break;
152     default:
153       ;
154     }
155 }
156
157 //! generic method to compute a graph for child nodes. implemented in some derived classes
158 void SceneNodeItem::arrangeNodes(bool isRecursive)
159 {
160 }
161
162 void SceneNodeItem::arrangeChildNodes()
163 {
164 }
165
166 void SceneNodeItem::reorganizeShrinkExpand()
167 {
168 }
169
170 qreal SceneNodeItem::getHeaderBottom()
171 {
172   if (_hasHeader) {
173     return _header->getHeaderBottom();
174   } else {
175     return 0;
176   };
177 }
178
179 void SceneNodeItem::autoPosNewPort(AbstractSceneItem *item, int nbPorts) {
180 }
181
182 void SceneNodeItem::popupMenu(QWidget *caller, const QPoint &globalPos)
183 {
184   NodeMenu m;
185   m.popupMenu(caller, globalPos);
186 }
187
188 SceneComposedNodeItem* SceneNodeItem::getParent()
189 {
190   if (_parent)
191     return dynamic_cast<SceneComposedNodeItem*>(_parent);
192   else
193     return 0;
194 }
195 void SceneNodeItem::removeInPortFromList(AbstractSceneItem* inPort)
196 {
197   _inPorts.remove(inPort);
198 }
199
200 void SceneNodeItem::removeOutPortFromList(AbstractSceneItem* outPort)
201 {
202   _outPorts.remove(outPort);
203 }
204
205 void SceneNodeItem::setMoving(bool moving)
206 {
207   //DEBTRACE("SceneNodeItem::setMoving " << _label.toStdString() << " " << moving);
208   _moving = moving;
209   SceneNodeItem *nodep = 0;
210   if (_parent && (nodep = dynamic_cast<SceneNodeItem*>(_parent)))
211     nodep->setMoving(false);
212 }
213
214 ScenePortItem* SceneNodeItem::getCtrlInPortItem()
215 {
216   if (! _header) return 0;
217   return _header->getCtrlInPortItem();
218 }
219
220 ScenePortItem* SceneNodeItem::getCtrlOutPortItem()
221 {
222   if (! _header) return 0;
223   return _header->getCtrlOutPortItem();
224 }
225
226 void SceneNodeItem::updateName()
227 {
228   if (_header) _header->setText(getHeaderLabel());
229 }
230
231 QString SceneNodeItem::getMimeFormat()
232 {
233   return "yacs/subjectNode";
234 }
235
236 void SceneNodeItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
237 {
238   DEBTRACE("SceneNodeItem::mousePressEvent " << _label.toStdString());
239   SceneObserverItem::mousePressEvent(event);
240   if (!_scene->isZooming())
241     {
242       if (!_draging) setMoving(true);
243       _prevPos = pos();
244     }
245 }
246
247 void SceneNodeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
248 {
249   //DEBTRACE("SceneNodeItem::mouseReleaseEvent " << _label.toStdString());
250   SceneObserverItem::mouseReleaseEvent(event);
251   setMoving(false);
252   if ((pos() != _prevPos) && Scene::_autoComputeLinks)
253     {
254       YACS::HMI::SubjectProc* subproc = QtGuiContext::getQtCurrent()->getSubjectProc();
255       SceneItem *item = QtGuiContext::getQtCurrent()->_mapOfSceneItem[subproc];
256       SceneComposedNodeItem *proc = dynamic_cast<SceneComposedNodeItem*>(item);
257       proc->rebuildLinks();
258     }
259   if (_moved)
260     if (Resource::ensureVisibleWhenMoved)
261       QtGuiContext::getQtCurrent()->getView()->ensureVisible(this);
262   _moved = false;
263 }
264
265 void SceneNodeItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
266 {
267   SceneObserverItem::mouseMoveEvent(event);
268   if (_moving)
269     {
270       if (SceneComposedNodeItem *bloc = dynamic_cast<SceneComposedNodeItem*>(_parent))
271         {
272           QPointF oldPos = pos();
273           QPointF aPos = oldPos + event->scenePos() - event->lastScenePos();
274           if (aPos != oldPos)
275             _moved = true;
276           if (aPos.x() > oldPos.x()) _blocX = false;
277           if (aPos.y() > oldPos.y()) _blocY = false;
278           if (aPos.x() < Resource::Border_Margin)
279             {
280               aPos.setX(Resource::Border_Margin);
281               _blocX = true;
282             }
283           if ( aPos.y() < bloc->getHeaderBottom() )
284             {
285               aPos.setY(bloc->getHeaderBottom());
286               _blocY = true;
287             }
288           setTopLeft(aPos);
289           bloc->collisionResolv(this, oldPos);
290         }
291     }
292 }
293
294 void SceneNodeItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
295 {
296   DEBTRACE("SceneNodeItem::mouseDoubleClickEvent");
297   if (dynamic_cast<SceneProcItem*>(this))
298     return;
299   QtGuiContext::getQtCurrent()->getGMain()->_guiEditor->shrinkExpand();
300 }
301
302 void SceneNodeItem::setTopLeft(QPointF topLeft)
303 {
304   QPointF oldPos = pos();
305   setPos(topLeft);
306
307   //update links
308   updateLinks();
309
310   if (_parent)
311     {
312       if (SceneComposedNodeItem *bloc = dynamic_cast<SceneComposedNodeItem*>(_parent))
313         bloc->collisionResolv(this, oldPos);
314       _parent->checkGeometryChange();
315     }
316   _expandedPos = pos();
317 }
318
319 void SceneNodeItem::adjustHeader()
320 {
321   if (_header) _header->adjustGeometry();
322 }
323
324  void SceneNodeItem::updateState()
325 {
326   SubjectNode *snode = dynamic_cast<SubjectNode*>(_subject);
327   YASSERT(snode);
328   Node *node = snode->getNode();
329   YASSERT(node);
330   switch (node->getState())
331     {
332     case YACS::INVALID:
333       if (_header) _header->setValid(false);
334       break;
335     case YACS::READY:
336       if (_header) _header->setValid(true);
337       break;
338     default:
339       break;
340     }
341 }
342
343 void SceneNodeItem::setExecState(int execState)
344 {
345   DEBTRACE("SceneNodeItem::setExecState " << execState);
346   _execState = execState;
347   if (_header) _header->setExecState(execState);
348 }
349
350 QString SceneNodeItem::getHeaderLabel()
351 {
352   DEBTRACE("SceneNodeItem::getHeaderLabel");
353   QString extLabel = _subject->getName().c_str();
354
355   SceneObserverItem *soi = 0;
356   SubjectSwitch* sswi = 0;
357
358   if ((_parent)
359       && (soi = dynamic_cast<SceneObserverItem*>(_parent))
360       && (sswi = dynamic_cast<SubjectSwitch*>(soi->getSubject())))
361     {
362       Switch *aswi = dynamic_cast<Switch*>(sswi->getNode());
363       SubjectNode *sno = dynamic_cast<SubjectNode*>(_subject);
364       int idcase = aswi->getRankOfNode(sno->getNode());
365       stringstream caseid;
366       if (idcase == Switch::ID_FOR_DEFAULT_NODE)
367         caseid << "default";
368       else
369         caseid << idcase;
370       extLabel += " (";
371       //extLabel += aswi->getCaseId(sno->getNode()).c_str();
372       extLabel += caseid.str().c_str();
373       extLabel += ")";
374       DEBTRACE(extLabel.toStdString());
375     }
376
377   return extLabel;
378 }
379
380 void SceneNodeItem::updateLinks()
381 {
382   //update control links
383   std::list<SubjectControlLink*> lscl=dynamic_cast<SubjectNode*>(_subject)->getSubjectControlLinks();
384   for (std::list<SubjectControlLink*>::const_iterator it = lscl.begin(); it != lscl.end(); ++it)
385     {
386       SceneLinkItem* item = dynamic_cast<SceneLinkItem*>(QtGuiContext::getQtCurrent()->_mapOfSceneItem[*it]);
387       item->updateShape();
388     }
389
390   //update data links through child items update (SceneDataPortItem)
391   updateChildItems();
392 }
393
394 void SceneNodeItem::updateChildItems()
395 {
396   foreach (QGraphicsItem *child, childItems())
397     {
398       if (SceneItem *sci = dynamic_cast<SceneItem*>(child))
399         {
400            sci->updateLinks();
401         }
402     }
403 }
404
405 void SceneNodeItem::shrinkExpandLink(bool se)
406 {
407   foreach (QGraphicsItem *child, childItems())
408     {
409       if (SceneItem *sci = dynamic_cast<SceneItem*>(child))
410         {
411            sci->shrinkExpandLink(se);
412         }
413     }
414 }
415
416 void SceneNodeItem::showOutScopeLinks()
417 {
418   SubjectNode *snode = dynamic_cast<SubjectNode*>(_subject);
419   YASSERT(snode);
420   Node *node = snode->getNode();
421   YASSERT(node);
422   vector<pair<OutPort *, InPort *> > listLeaving  = node->getSetOfLinksLeavingCurrentScope();
423   vector<pair<InPort *, OutPort *> > listIncoming = node->getSetOfLinksComingInCurrentScope();
424   vector<pair<OutPort *, InPort *> > outScope = listLeaving;
425   vector<pair<InPort *, OutPort *> >::iterator it1;
426   for (it1 = listIncoming.begin(); it1 != listIncoming.end(); ++it1)
427     {
428       pair<OutPort *, InPort *> outin = pair<OutPort *, InPort *>((*it1).second, (*it1).first);
429       outScope.push_back(outin);
430     }
431   vector<pair<OutPort*, InPort*> >::const_iterator it = outScope.begin();
432   for( ; it != outScope.end(); ++it)
433   {
434     YASSERT(QtGuiContext::getQtCurrent()->_mapOfSubjectLink.count(*it));
435     SubjectLink* slink = QtGuiContext::getQtCurrent()->_mapOfSubjectLink[*it];
436     YASSERT(QtGuiContext::getQtCurrent()->_mapOfSceneItem.count(slink));
437     SceneItem *item = QtGuiContext::getQtCurrent()->_mapOfSceneItem[slink];
438     item->show();
439   }
440 }
441
442 void SceneNodeItem::setShownState(shownState ss)
443 {
444   _shownState = ss;
445 }