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