Salome HOME
Bug fix: don't set "Loading" state for MacroNodes in InitialState() function (called...
[modules/superv.git] / src / SUPERVGUI / SUPERVGUI_CanvasNode.cxx
1 //  SUPERV SUPERVGUI : GUI for Supervisor component
2 //
3 //  Copyright (C) 2003  OPEN CASCADE
4 //
5 //  File   : SUPERVGUI_CanvasNode.cxx
6 //  Author : Natalia KOPNOVA
7 //  Module : SUPERV
8
9 using namespace std;
10 #include "SUPERVGUI_CanvasNode.h"
11 #include "SUPERVGUI_CanvasNodePrs.h"
12 #include "SUPERVGUI_CanvasPort.h"
13 #include "SUPERVGUI_Main.h"
14 #include "SUPERVGUI.h"
15 #include "SUPERVGUI_BrowseNodeDlg.h"
16 #include "SUPERVGUI_ManagePortsDlg.h"
17 #include "SALOMEGUI_NameDlg.h"
18 #include "SUPERVGUI_Information.h"
19 /*
20 #include "SUPERVGUI_CanvasControlNode.h"
21
22 #include <qtooltip.h>
23 */
24
25 SUPERVGUI_CanvasNode::SUPERVGUI_CanvasNode(QObject* theParent, SUPERVGUI_Main* theMain, SUPERV_CNode theNode, bool theIsCell):
26     QObject(theParent),
27     myMain(theMain),
28     myNode(theNode),
29     myPrs(0),
30     myDestroyed(false),
31     warning(true),
32     step(true),
33     trace(true),
34     verbose(true),
35     myBrowseDlg(0)
36 {
37   Trace("SUPERVGUI_CanvasNode::SUPERVGUI_CanvasNode");
38
39   setName(myNode->Name());
40
41   QString aComment(myNode->Comment());
42   QString aNewComment = aComment;
43   if (getNodeType() == SUPERV::FactoryNode) {
44     aNewComment = QString(myNode->Service()->ServiceName) +
45       QString(tr("COMMENT_FROM")) +
46       QString(getFactoryNode()->GetComponentName());
47   }
48   else if (myNode->IsMacro()) {
49     aNewComment = tr("COMMENT_MNODE");
50   }
51   else {
52     aNewComment = tr("COMMENT_CNODE");
53   }
54   if (aComment.isEmpty()) {
55     myNode->SetComment(aNewComment.latin1());
56   }
57
58   myLabelText = aNewComment;
59
60   // create node ports
61   isIgnore = true;
62   //cout << "     get port list... " ;
63   SUPERV_Ports aPortList = myNode->Ports();
64   //cout << aPortList->length() << endl;
65   for (int i = 0; i < aPortList->length(); i++) {
66     createPort(aPortList[i].in());
67   }
68
69   //cout << "     get stream port list... " ;
70   SUPERV_StreamPorts aStreamPortList = myNode->StreamPorts();
71   //cout << aStreamPortList->length() << endl;
72   for (int i = 0; i < aStreamPortList->length(); i++) {
73     createStreamPort(aStreamPortList[i].in());
74   }
75
76   isIgnore = false;
77
78   QCanvasItemList anIL2 = ((QCanvas*)parent())->allItems();
79   cout<<" ===> 1 conatructor CanvasNode : CanvasArray has "<<anIL2.count()<<" children!"<<endl;
80 }
81
82 SUPERVGUI_CanvasNode::~SUPERVGUI_CanvasNode()
83 {
84   isIgnore = true;
85   if (myPrs) delete myPrs;
86 }
87
88 void SUPERVGUI_CanvasNode::setDestroyed()
89 {
90   myDestroyed = true;
91   getPrs()->hide();
92 }
93
94 SUPERVGUI_CanvasNodePrs* SUPERVGUI_CanvasNode::getPrs() const
95 {
96   if (myPrs == 0) {
97     ((SUPERVGUI_CanvasNode*)this)->myPrs = createPrs();
98   }
99   return myPrs;
100 }
101
102 SUPERVGUI_CanvasNodePrs* SUPERVGUI_CanvasNode::createPrs() const
103 {
104   return new SUPERVGUI_CanvasNodePrs(myMain->getCanvas(), (SUPERVGUI_CanvasNode*)this);
105 }
106
107 void SUPERVGUI_CanvasNode::createPort(SUPERV::Port_ptr thePort) const
108 {
109   SUPERVGUI_CanvasPort* aPort = 0;
110   if (thePort->IsInput())
111     aPort = new SUPERVGUI_CanvasPortIn((SUPERVGUI_CanvasNode*)this, myMain, thePort);
112   else
113     aPort = new SUPERVGUI_CanvasPortOut((SUPERVGUI_CanvasNode*)this, myMain, thePort);
114
115   if (aPort) {
116     connect(aPort, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroyed(QObject*)));
117     if (!isIgnore) getPrs()->updatePorts();
118   }
119 }
120
121 void SUPERVGUI_CanvasNode::createStreamPort(SUPERV::StreamPort_ptr thePort) const
122 {
123   SUPERVGUI_CanvasPort* aPort = 0;
124   if (thePort->IsInput())
125     aPort = new SUPERVGUI_CanvasStreamPortIn((SUPERVGUI_CanvasNode*)this, myMain, thePort);
126   else
127     aPort = new SUPERVGUI_CanvasStreamPortOut((SUPERVGUI_CanvasNode*)this, myMain, thePort);
128
129   if (aPort) {
130     connect(aPort, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroyed(QObject*)));
131     if (!isIgnore) getPrs()->updatePorts();
132   }
133 }
134
135 void SUPERVGUI_CanvasNode::onDestroyed(QObject* theObject)
136 {
137   if (!isIgnore) {
138     removeChild(theObject); // signal is sent before removing the object
139     getPrs()->updatePorts();
140   }
141 }
142
143 QPopupMenu* SUPERVGUI_CanvasNode::getPopupMenu(QWidget* theParent) 
144 {
145   QPopupMenu* popup = new QPopupMenu(theParent);
146   if (myMain->getDataflow()->IsExecuting()) {
147     popup->insertItem((myNode->IsSuspended()?tr("MSG_RESUME"):tr("MSG_SUSPEND")),
148                       this, SLOT(suspendResume()));
149     popup->insertItem(tr("MSG_KILL"), this, SLOT(kill()));
150   }
151   else {
152     if (myMain->isEditable() && getNodeType() != SUPERV::EndLoopNode
153                              && getNodeType() != SUPERV::EndSwitchNode) {
154       popup->insertItem(tr("MSG_RENAME"), this, SLOT(rename()));
155       myDeleteItem = popup->insertItem(tr("MSG_DELETE"), this, SLOT(remove()));
156       popup->insertSeparator();
157     }
158     popup->insertItem(tr("MSG_BROWSE"), this, SLOT(browse()));
159
160     if (getNodeType() != SUPERV::EndLoopNode && 
161         getNodeType() != SUPERV::EndSwitchNode)
162       popup->insertItem(tr("MSG_CHANGE_INFO"), this, SLOT(changeInformation()));
163
164     if (myMain->isEditable() && getNodeType() != SUPERV::FactoryNode
165                              && getNodeType() != SUPERV::ComputingNode
166                              && getNodeType() != SUPERV::EndLoopNode
167                              && getNodeType() != SUPERV::MacroNode) {
168       QPopupMenu* addPortMenu = new QPopupMenu(theParent);
169       addPortMenu->insertItem( tr( "MNU_INPUT" ), this, SLOT(addInputPort()));
170       if (getNodeType() != SUPERV::LoopNode)
171         addPortMenu->insertItem( tr( "MNU_OUTPUT" ), this, SLOT(addOutputPort()));
172       
173       popup->insertSeparator();
174       if ((getNodeType() != SUPERV::EndSwitchNode))
175         popup->insertItem( tr( "MNU_EDIT_FUNC" ), this, SLOT(editFunction()));
176       popup->insertItem( tr( "MNU_ADD_PORT" ), addPortMenu);
177       popup->insertItem( tr( "MNU_MANAGE_PORTS" ), this, SLOT(managePorts()));
178     }
179   }
180
181   return popup;
182 }
183
184 void SUPERVGUI_CanvasNode::show() 
185 {
186   getPrs()->show();
187 }
188
189 void SUPERVGUI_CanvasNode::showAll() 
190 {
191   getPrs()->showAll();
192 }
193
194 void SUPERVGUI_CanvasNode::hideAll() 
195 {
196   getPrs()->hideAll();
197 }
198
199 void SUPERVGUI_CanvasNode::switchLabel()
200 {
201   getPrs()->setLabelVisible(!getPrs()->isLabelVisible());
202 }
203
204 void SUPERVGUI_CanvasNode::switchPorts()
205 {
206   getPrs()->setPortVisible(!getPrs()->isPortVisible());
207 }
208
209 void SUPERVGUI_CanvasNode::move(int x, int y)
210 {
211   //  myNode->Coords(x, y); //  <<<- done inside Prs to reflect item movement by mouse press
212   if (x > GRAPH_MAX) x = (int) getPrs()->x();
213   if (y > GRAPH_MAX) y = (int) getPrs()->y();
214   getPrs()->move(x, y);
215 }
216
217 void SUPERVGUI_CanvasNode::merge() 
218 {
219   //MESSAGE("===> SUPERVGUI_CanvasNode::merge() " << myNode->Name());
220   // synchronize port list
221   bool update = false;
222   isIgnore = true;
223   SUPERVGUI_CanvasPort* aPort;
224   QObjectList* aPortList = queryList("SUPERVGUI_CanvasPort");
225   //cout << "     get port list... " ;
226   SUPERV_Ports aPorts = myNode->Ports();
227   //cout << aPorts->length() << endl;
228   for (int i = 0; i < aPorts->length(); i++) {
229     aPort = (SUPERVGUI_CanvasPort*) 
230       child(myMain->getCanvas()->getPortName(aPorts[i].in()), "SUPERVGUI_CanvasPort");
231     if (aPort) {
232   //cout << "     update port " << aPort->name() << endl;
233       aPortList->removeRef(aPort);
234       aPort->update();
235     }
236     else {
237   //cout << "     create port " << myMain->getCanvas()->getPortName(aPorts[i].in()) << endl;
238       createPort(aPorts[i].in());
239       update = true;
240     }
241   }
242
243   //cout << "     get stream port list... " ;
244   SUPERV_StreamPorts aStreamPorts = myNode->StreamPorts();
245   //cout << aStreamPorts->length() << endl;
246   for (int i = 0; i < aStreamPorts->length(); i++) {
247     aPort = (SUPERVGUI_CanvasPort*) 
248       child(myMain->getCanvas()->getPortName(aStreamPorts[i].in()), "SUPERVGUI_CanvasPort");
249     if (aPort) {
250   //cout << "     update stream port " << aPort->name() << endl;
251       aPortList->removeRef(aPort);
252       aPort->update();
253     }
254     else {
255   //cout << "     create stream port " << myMain->getCanvas()->getPortName(aStreamPorts[i].in()) << endl;
256       createPort(aStreamPorts[i].in());
257       update = true;
258     }
259   }
260
261   //cout << "     remove inexistant " << endl;
262   QObjectListIt it(*aPortList);
263   while ((aPort=(SUPERVGUI_CanvasPort*)it.current()) != 0) {
264     ++it;
265     aPortList->removeRef(aPort);
266     delete aPort;
267     update = true;
268   }
269   delete aPortList;
270   isIgnore = false;
271   if (update) getPrs()->updatePorts();
272
273   sync(); // update node state also
274 }
275
276 void SUPERVGUI_CanvasNode::sync() 
277 {
278   //MESSAGE("===> SUPERVGUI_CanvasNode::sync() " << myNode->Name() << ", state " << myNode->State());
279
280   const bool isExecuting = myMain->getDataflow()->IsExecuting();
281   //if myNode is a MacroNode then set it state to state of its subgraph
282   if ( myNode->IsMacro() && isExecuting ) {
283     // get SubGraph from MacroNode
284     SUPERV_Graph aMacro = SUPERV::Graph::_narrow(myNode);
285     if (!SUPERV_isNull(aMacro)) {
286       SUPERV_Graph aGraph;
287       if (aMacro->IsStreamMacro())
288         aGraph = aMacro->StreamObjRef();
289       else
290         aGraph = aMacro->FlowObjRef();
291       if (!SUPERV_isNull(aGraph)) {
292         if (aGraph->State() != SUPERV::UndefinedState && aGraph->State() != SUPERV::NoState)
293           getPrs()->setState(aGraph->State());
294         else 
295           getPrs()->setState(myNode->State());
296       }
297     }
298   }
299   else {
300     SUPERV::GraphState aState = myNode->State();
301
302     // asv : 18.11.04 : fix for 6170 : after execution is finished, nodes' status must be reset.
303     // asv : 13.12.04 : commented out setting EditingState.  See 2.21.
304     //if ( !isExecuting && myMain->IsGUIEventLoopFinished() && (aState == SUPERV::DoneState || 
305     //  aState == SUPERV::KillState || aState == SUPERV::StopState ) )
306     //  aState = SUPERV::EditingState;
307     getPrs()->setState(aState);
308   }
309   
310   // update child ports
311   const QObjectList* list = children();
312   if (list) {
313     QObjectListIt it(*list);
314     while (QObject* obj = it.current()) {
315       ++it;
316       if (obj->inherits("SUPERVGUI_CanvasPort")) {
317         ((SUPERVGUI_CanvasPort*)obj)->sync();
318       }
319     }
320   }
321 }
322
323 void SUPERVGUI_CanvasNode::syncOnEvent(SUPERV::GraphState theStateFromEvent) 
324 {
325   getPrs()->setState(theStateFromEvent);
326 }
327
328 bool SUPERVGUI_CanvasNode::setNodeName(QString aName) 
329 {
330   bool result = myNode->SetName(aName.latin1());
331   if (result) {
332     setName(myNode->Name());
333     getPrs()->updateInfo();
334     // TODO: update name of all the links to this node
335   } 
336   else {
337     QMessageBox::warning( QAD_Application::getDesktop(), tr( "ERROR" ), tr( "MSG_CANT_RENAMENODE" ) );
338   }
339   return result;
340 }
341
342 void SUPERVGUI_CanvasNode::rename()
343 {
344   QString aName = SALOMEGUI_NameDlg::getName(QAD_Application::getDesktop(), myNode->Name());
345   if (!aName.isEmpty()) {
346     setNodeName(aName);
347   }
348 }
349
350 void SUPERVGUI_CanvasNode::remove() {
351   Trace("SUPERVGUI_CanvasNode::remove");
352   SUPERVGUI_Canvas* aCanvas = myMain->getCanvas();
353   setDestroyed();
354   myNode->destroy();
355   delete this;
356   aCanvas->update();
357 }
358
359 void SUPERVGUI_CanvasNode::suspendResume() {
360   Trace("SUPERVGUI_CanvasNode::suspendResume");
361   int n = queryList("SUPERVGUI_CanvasNode")->count(); 
362   if (myNode->IsSuspended()) {
363     if (!((n==1)? myMain->getDataflow()->Resume() : myNode->Resume())) {
364       QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_RESUMENODE"));
365     }
366     else {
367       sync();
368       myMain->getMyThread()->startThread(tr("MSG_NODE_RESUMED1")+myNode->Name()+tr("MSG_NODE_RESUMED2"));
369     }
370   } else {
371     if (!((n==1)? myMain->getDataflow()->Suspend() : myNode->Suspend())) {
372       QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_SUSPENDNODE"));
373     } else {
374       syncOnEvent(SUPERV::SuspendReadyState);
375       myMain->getMyThread()->stopThread(tr("MSG_NODE_SUSPENDED1")+myNode->Name()+tr("MSG_NODE_SUSPENDED2"));
376     }
377   }
378 }
379
380 void SUPERVGUI_CanvasNode::kill() {
381   Trace("SUPERVGUI_CanvasNode::kill");
382   int n = queryList("SUPERVGUI_CanvasNode")->count(); 
383   if (!((n==1)? myMain->getDataflow()->Kill() : myNode->Kill())) {
384     QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_KILLNODE"));
385   } else {
386     syncOnEvent(SUPERV_Kill);
387     myMain->getMyThread()->stopThread(tr("MSG_NODE_KILLED1")+myNode->Name()+tr("MSG_NODE_KILLED2"));
388   }
389 }
390
391 void SUPERVGUI_CanvasNode::stopRestart() {
392   Trace("SUPERVGUI_CanvasNode::stopRestart");
393   
394   int n = queryList("SUPERVGUI_CanvasNode")->count(); 
395   if ((myNode->State() == SUPERV_Stop) || (myNode->State() == SUPERV_Kill)) {
396     if (!((n==1)? myMain->getDataflow()->Run() : myNode->ReStart())) {
397       QMessageBox::warning(QAD_Application::getDesktop(),  tr("ERROR"), tr("MSG_CANT_RESTARTNODE"));
398     }
399   } else {
400     if (!((n==1)? myMain->getDataflow()->Stop() : myNode->Stop())) {
401       QMessageBox::warning(QAD_Application::getDesktop(),  tr("ERROR"), tr("MSG_CANT_STOPNODE"));
402     }
403   }
404 }
405
406 void SUPERVGUI_CanvasNode::changeInformation() {
407   SUPERVGUI_Information* aDlg = new SUPERVGUI_Information(myNode, !myMain->isEditable());
408   if (aDlg->exec()) {
409     QString aName = myNode->Name();
410     if (!aName.isEmpty() && myMain->isEditable())
411       setNodeName(aName);
412   }
413   delete aDlg;
414 }
415
416 /* asv : 13.12.04 : The functions below are not called from anywhere, so commenting them out...
417 void SUPERVGUI_CanvasNode::configure() 
418 {
419   Trace("SUPERVGUI_CanvasNode::configure");
420   QMessageBox::warning(QAD_Application::getDesktop(),  tr("ERROR"), tr("MSG_NOT_IMPLEMENTED")); // kloss : a faire : lancer l'ihm DATA
421 }
422
423 void SUPERVGUI_CanvasNode::showPython() 
424 {
425   Trace("SUPERVGUI_CanvasNode::showPython");
426   SUPERVGUI_Python cp(myMain->getStudy()->get_PyInterp(), !myMain->isEditable());
427   cp.exec();
428 }
429 */
430
431 bool SUPERVGUI_CanvasNode::isWarning() 
432 {
433   Trace("SUPERVGUI_CanvasNode::isWarning");
434   return(warning);
435 }
436
437 bool SUPERVGUI_CanvasNode::isStep() 
438 {
439   Trace("SUPERVGUI_CanvasNode::isStep");
440   return(step);
441 }
442
443 bool SUPERVGUI_CanvasNode::isTrace() 
444 {
445   Trace("SUPERVGUI_CanvasNode::isTrace");
446   return(trace);
447 }
448
449 bool SUPERVGUI_CanvasNode::isVerbose() 
450 {
451   Trace("SUPERVGUI_CanvasNode::isVerbose");
452   return(verbose);
453 }
454
455 void SUPERVGUI_CanvasNode::setWarning(bool b) 
456 {
457   Trace("SUPERVGUI_CanvasNode::setWarning");
458   warning = b;
459 }
460
461 void SUPERVGUI_CanvasNode::setStep(bool b) 
462 {
463   Trace("SUPERVGUI_CanvasNode::setStep");
464   step = b;
465 }
466
467 void SUPERVGUI_CanvasNode::setTrace(bool b) 
468 {
469   Trace("SUPERVGUI_CanvasNode::setTrace");
470   trace = b;
471 }
472
473 void SUPERVGUI_CanvasNode::setVerbose(bool b) 
474 {
475   Trace("SUPERVGUI_CanvasNode::setVerbose");
476   verbose = b;
477 }
478
479
480 void SUPERVGUI_CanvasNode::browse() 
481 {
482   if (!myBrowseDlg) {
483     myBrowseDlg = new SUPERVGUI_BrowseNodeDlg(this);
484     myBrowseDlg->installEventFilter(this);
485   }
486   if (!myBrowseDlg->isVisible())
487     myBrowseDlg->show();
488   else {
489     myBrowseDlg->raise();
490     myBrowseDlg->setActiveWindow();
491     myBrowseDlg->setFocus();
492   }
493 }
494
495 bool SUPERVGUI_CanvasNode::eventFilter( QObject* o, QEvent* e )
496 {
497   if (o == myBrowseDlg && e->type() == QEvent::Close)
498     myBrowseDlg = 0;
499   return QObject::eventFilter(o, e);
500 }
501
502 QStringList SUPERVGUI_CanvasNode::getPortsNamesIN(SUPERV_INode theNode, bool theInputPorts)
503 {
504   QStringList aPNList;
505   if (!SUPERV_isNull(theNode)) {
506     SUPERV_Ports aPorts = theNode->Ports();
507     for (int i=0; i<aPorts->length(); i++) {
508       if (theInputPorts) {
509         if (aPorts[i]->IsInput()) aPNList.append(QString(aPorts[i]->Name()));
510       }
511       else 
512         if (!aPorts[i]->IsInput()) aPNList.append(QString(aPorts[i]->Name()));
513     }
514   }
515   return aPNList;
516 }
517
518 SUPERV_Port SUPERVGUI_CanvasNode::createInPort() 
519 {
520   SUPERV_INode aNode = getInlineNode();
521   if (SUPERV_isNull(aNode)) {
522     MESSAGE("SUPERVGUI_CanvasNode::createInPort: Node is wrong type");
523     return NULL;
524   }
525   SUPERVGUI_PortParamsDlg* aDlg = new SUPERVGUI_PortParamsDlg(getPortsNamesIN(aNode,true));
526   if (aDlg->exec()) {
527     SUPERV_Port aPort = aNode->InPort(aDlg->getName().latin1(),
528                                       aDlg->getType().latin1());    
529     delete aDlg;
530     return aPort;
531   }
532   delete aDlg;
533   return NULL;
534 }
535
536 SUPERV_Port SUPERVGUI_CanvasNode::createOutPort() 
537 {
538   SUPERV_INode aNode = getInlineNode();
539   if (SUPERV_isNull(aNode)) {
540     MESSAGE("SUPERVGUI_CanvasNode::createOutPort: Node is wrong type");
541     return NULL;
542   }
543   
544   SUPERVGUI_PortParamsDlg* aDlg = new SUPERVGUI_PortParamsDlg(getPortsNamesIN(aNode,false));
545   if (aDlg->exec()) {
546     SUPERV_Port aPort = aNode->OutPort(aDlg->getName().latin1(),
547                                        aDlg->getType().latin1());
548     delete aDlg;
549     return aPort;
550   }
551   delete aDlg;
552   return NULL;
553 }
554
555 void SUPERVGUI_CanvasNode::addInputPort() {
556   SUPERV_Port aPort = createInPort();
557   if (aPort == NULL) return;
558
559   createPort(aPort.in());
560 }
561
562
563 void SUPERVGUI_CanvasNode::addOutputPort() {
564   SUPERV_Port aPort = createOutPort();
565   if (aPort == NULL) return;
566
567   createPort(aPort.in());
568 }
569
570
571 void SUPERVGUI_CanvasNode::editFunction() 
572 {
573   if (getNodeType() == SUPERV::LoopNode) {
574     SUPERVGUI_EditPythonDlg* aDlg = new SUPERVGUI_EditPythonDlg(true);
575     SUPERV_LNode aLNode = getLoopNode();
576     aDlg->setInitFunction(aLNode->PyInit());
577     aDlg->setMoreFunction(aLNode->PyMore());
578     aDlg->setNextFunction(aLNode->PyNext());
579     if (aDlg->exec()) {
580       aLNode->SetPyInit(aDlg->getInitFuncName().latin1(), (aDlg->getInitFunction()).in());
581       aLNode->SetPyMore(aDlg->getMoreFuncName().latin1(), (aDlg->getMoreFunction()).in());
582       aLNode->SetPyNext(aDlg->getNextFuncName().latin1(), (aDlg->getNextFunction()).in());
583     }
584     delete aDlg;
585   } 
586   else {
587     SUPERVGUI_EditPythonDlg* aDlg = new SUPERVGUI_EditPythonDlg();
588     SUPERV_INode aINode = getInlineNode();
589     aDlg->setFunction(aINode->PyFunction());
590     if (aDlg->exec()) {
591       aINode->SetPyFunction(aDlg->getFuncName().latin1(), (aDlg->getFunction()).in());
592     }
593     delete aDlg;
594   }
595 }
596
597 /** 
598  * Called on "Edit ports" popup menu command. See SUPERVGUI_ManagePortsDlg.h
599  * for detailed description of the functionality
600  */
601 void SUPERVGUI_CanvasNode::managePorts() {
602   SUPERVGUI_ManagePortsDlg* aDlg = new SUPERVGUI_ManagePortsDlg( this );
603   aDlg->exec();
604   delete aDlg;
605 }