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