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