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