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