Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/superv.git] / src / SUPERVGUI / SUPERVGUI_Service.cxx
1 //  SUPERV SUPERVGUI : GUI for Supervisor component
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //
23 //
24 //  File   : SUPERVGUI_Service.cxx
25 //  Author : Francis KLOSS
26 //  Module : SUPERV
27
28 #include "SUPERVGUI_Service.h"
29 #include "SUPERVGUI_Main.h"
30 #include "SUPERVGUI_Library.h"
31 #include "SUPERVGUI.h"
32
33 #include "CAM_Application.h"
34 #include "SUIT_Desktop.h"
35 #include "SUIT_FileDlg.h"
36 #include "SUIT_Session.h"
37 #include "SUIT_Tools.h"
38
39 #include "SALOME_NamingService.hxx"
40 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
41 #include <qlabel.h>
42 #include <qlayout.h>
43 #include <qhbox.h>
44 #include <qtextstream.h>
45 #include <qregexp.h>
46
47 static const char * ComponentIcon[] = {
48 "20 20 2 1",
49 "       c None",
50 ".      c #000000",
51 "                    ",
52 "                    ",
53 "                    ",
54 " .................. ",
55 " .                . ",
56 " .                . ",
57 " .                . ",
58 " .                . ",
59 " .                . ",
60 " .                . ",
61 " .                . ",
62 " .                . ",
63 " .................. ",
64 "    .     .     .   ",
65 "    .     .     .   ",
66 "   ...   ...   ...  ",
67 "  .. .. .. .. .. .. ",
68 "  .   . .   . .   . ",
69 "  .. .. .. .. .. .. ",
70 "   ...   ...   ...  "};
71
72
73 static const char * InterfaceIcon[] = {
74 "20 20 2 1",
75 "       c None",
76 ".      c #000000",
77 "                    ",
78 "                    ",
79 "                    ",
80 "                    ",
81 "                    ",
82 "            ..      ",
83 "          ......    ",
84 "         ..    ..   ",
85 "         .      .   ",
86 "..........      ..  ",
87 "         .      .   ",
88 "         ..    ..   ",
89 "          ......    ",
90 "            ..      ",
91 "                    ",
92 "                    ",
93 "                    ",
94 "                    ",
95 "                    ",
96 "                    "};
97
98
99
100
101 SUPERVGUI_Service::SUPERVGUI_Service(SALOME_NamingService* ns):
102     QDialog(SUIT_Session::session()->activeApplication()->desktop(), 0, false, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
103     naming(ns), myMFile(0)
104 {
105   setSizeGripEnabled( true );
106   setCaption(tr("TIT_SERVICES"));
107
108   QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 4);
109
110   myTabPane = new QTabWidget(this);
111   connect(myTabPane, SIGNAL(currentChanged(QWidget *)), this, SLOT(tabChanged(QWidget *)));
112
113   // Create Tab for Corba services
114   QWidget* aCorbaPane = new QWidget(myTabPane);
115   QVBoxLayout* aBaseLayoutV= new QVBoxLayout(aCorbaPane, 0, 4);
116   aBaseLayoutV->setMargin(5);
117   aBaseLayoutV->setSpacing(10);
118
119   QHBoxLayout* aBaseLayout = new QHBoxLayout(aCorbaPane); //!!
120   aBaseLayout->setMargin(5);
121   aBaseLayout->setSpacing(10);
122  
123   components = new QListView(aCorbaPane);
124   components->addColumn(tr("COL_COMPONENTS"));
125   components->addColumn(tr("COL_PORTTYPE"));
126   components->addColumn(tr("COL_PORTWAY"));
127   components->setColumnAlignment(1, AlignLeft);
128   components->setColumnAlignment(2, AlignLeft);
129   components->setColumnAlignment(3, AlignLeft);
130   components->setSelectionMode(QListView::Extended);
131   components->setRootIsDecorated(true);
132
133 //  aBaseLayout->addWidget(components);
134   aBaseLayoutV->addWidget(components); //!!
135
136   //QHGroupBox* aAddBox = new QHGroupBox(tr("TIT_ADDNODE"), aCorbaPane); //!!
137   //aAddBox->setInsideSpacing(20); //!!
138
139 //NRI   QPushButton* aComputeCBtn = new QPushButton(tr("TIT_ADDCNODE"), aCorbaPane); //!!
140 //NRI   connect(aComputeCBtn, SIGNAL(clicked()), this, SLOT(addComputeNode())); //!!
141 //NRI   aComputeCBtn->setDefault(false); 
142
143   QPushButton* aComputeBtnDef = new QPushButton(tr("TIT_ADDFNODE"), aCorbaPane);
144   connect(aComputeBtnDef, SIGNAL(clicked()), this, SLOT(addFactoryNodeDef()));
145   aComputeBtnDef->setDefault(true); 
146
147   QPushButton* aComputeBtnCust = new QPushButton(tr("TIT_ADDFNODE_CUST"), aCorbaPane);
148   connect(aComputeBtnCust, SIGNAL(clicked()), this, SLOT(addFactoryNodeCust()));
149   aComputeBtnCust->setDefault(true); 
150
151   aBaseLayout->addWidget(aComputeBtnDef);
152   aBaseLayout->addWidget(aComputeBtnCust);
153   //NRI  aBaseLayout->addWidget(aComputeCBtn); //!!
154
155   aBaseLayoutV->insertLayout(-1, aBaseLayout);
156   myTabPane->addTab(aCorbaPane, tr("MODULES_PANE"));
157
158
159   // Create Tab for Python services
160   QWidget* aPythonPane = new QWidget(myTabPane);
161   QVBoxLayout* aPythonLayout = new QVBoxLayout(aPythonPane, 0, 4);
162   aPythonLayout->setMargin(5);
163   aPythonLayout->setSpacing(10);
164
165   // Type pane
166   QHGroupBox* aAddBox2 = new QHGroupBox(tr("TIT_ADDNODE"), aPythonPane);
167   aAddBox2->setInsideSpacing(20);
168
169   /*QLabel* aTypeLbl = */new QLabel(tr("LBL_NODETYPE"), aAddBox2);
170
171   myTypeCombo = new QComboBox(aAddBox2);
172   myTypeCombo->insertItem( tr( "INLINE_COMP" ) );
173   myTypeCombo->insertItem( tr( "INLINE_SWTC" ) );
174   myTypeCombo->insertItem( tr( "INLINE_LOOP" ) );
175   myTypeCombo->insertItem( tr( "INLINE_GOTO") );
176   connect(myTypeCombo, SIGNAL(activated(int)), this, SLOT(typeNodeSelected(int)));
177
178   aPythonLayout->addWidget(aAddBox2);
179
180   // Edit pane
181   myStackWidget = new QWidgetStack(aPythonPane);
182
183   // other pane
184   myScriptPane = new SUPERVGUI_PythonEditPane( myStackWidget, true, myX, myY );
185   myOtherId = myStackWidget->addWidget(myScriptPane);
186
187   // loop pane
188   QTabWidget* aLoopTabPane = new QTabWidget(myStackWidget);
189   myInitPane = new SUPERVGUI_PythonEditPane( myStackWidget, true, myX, myY ); 
190   aLoopTabPane->addTab(myInitPane, "Init");
191
192   myMorePane = new SUPERVGUI_PythonEditPane( myStackWidget, true, myX, myY );
193   aLoopTabPane->addTab(myMorePane, "More");
194
195   myNextPane = new SUPERVGUI_PythonEditPane( myStackWidget, true, myX, myY );
196   aLoopTabPane->addTab(myNextPane, "Next");
197   myLoopId = myStackWidget->addWidget(aLoopTabPane);
198
199   myStackWidget->raiseWidget(myOtherId);
200
201   aPythonLayout->addWidget(myStackWidget, 1);
202
203   // Create button
204   QPushButton* aCreateBtn = new QPushButton(tr("TIT_ADDNODE"), aPythonPane);
205   connect(aCreateBtn, SIGNAL(clicked()), this, SLOT(addInlineNode()));
206   aPythonLayout->addWidget(aCreateBtn);
207
208   myTabPane->addTab(aPythonPane, tr("INLINE_PANE"));
209
210   // Create Tab for Macro node only if environmental variable ENABLE_MACRO_NODE is set
211   if ( getenv( "ENABLE_MACRO_NODE" ) != NULL ) {
212     QWidget* aMacroPane = new QWidget(myTabPane);
213     QVBoxLayout* aMacroLayout = new QVBoxLayout(aMacroPane, 0, 4);
214     aMacroLayout->setMargin(5);
215     aMacroLayout->setSpacing(10);
216     
217     QHBoxLayout* aLoadLayout = new QHBoxLayout(aMacroPane); //!!
218     aLoadLayout->addStretch();
219     
220     QPushButton* aLoadBtn = new QPushButton(tr("BUT_LOAD"), aMacroPane);
221     connect(aLoadBtn, SIGNAL(clicked()), this, SLOT(loadGraph()));
222
223     aLoadLayout->addWidget(aLoadBtn);
224
225     aMacroLayout->addLayout(aLoadLayout);
226  
227     myMacroPane = new QListView(aMacroPane);
228     myMacroPane->addColumn(tr("COL_COMPONENTS"));
229     myMacroPane->addColumn(tr("COL_PORTTYPE"));
230     myMacroPane->addColumn(tr("COL_PORTWAY"));
231     myMacroPane->setColumnAlignment(1, AlignLeft);
232     myMacroPane->setColumnAlignment(2, AlignLeft);
233     myMacroPane->setColumnAlignment(3, AlignLeft);
234     myMacroPane->setSelectionMode(QListView::Extended);
235     myMacroPane->setRootIsDecorated(true);
236     aMacroLayout->addWidget(myMacroPane); //!!
237     
238     QPushButton* aAddBtn = new QPushButton(tr("TIT_ADDFNODE"), aMacroPane);
239     connect(aAddBtn, SIGNAL(clicked()), this, SLOT(addMacroNode()));
240     aAddBtn->setDefault(true); 
241     
242     aMacroLayout->addWidget(aAddBtn);
243
244     myTabPane->addTab(aMacroPane, tr("MACRO_PANE"));
245   }
246   
247   aMainLayout->addWidget(myTabPane);
248
249   // Close button
250   QHBox* aBtnBox = new QHBox(this);
251   QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout()); 
252   aBtnLayout->addStretch();
253
254   QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
255   connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(reject()));
256   
257   aMainLayout->addWidget(aBtnBox);
258
259   initialise();
260   myX = 0;
261   myY = 0;
262   myIsInline = false;
263 }
264
265
266 char* getDataStreamParameterName(const char * aType)
267 {
268   QString type (aType);
269
270   if (aType == "int") // 1
271     return "integer";
272   if (aType == "float") // 2
273     return "float";
274   if (aType == "double") // 3
275     return "double";
276   if (aType == "string") // 4
277     return "string";
278   if (aType == "bool") // 6 ??
279     return "boolean";
280
281   return "unknown";
282 }
283
284 void SUPERVGUI_Service::initialise() {
285   CORBA::Object_ptr obj  = naming->Resolve("/Kernel/ModulCatalog");
286   SALOME_ModuleCatalog::ModuleCatalog_var *aModuleCatalog = new SALOME_ModuleCatalog::ModuleCatalog_var;
287   *aModuleCatalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj);
288   if (CORBA::is_nil(*aModuleCatalog)) {
289     setCaption("Error in Connexion to omniNames with '/Kernel/ModulCatalog'");
290     return;
291   }
292   
293   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
294
295   SALOME_ModuleCatalog::ListOfComponents_var lComponents = (*aModuleCatalog)->GetComponentList();
296   long nbComp = lComponents->length();
297   for (int i=0; i<nbComp; i++) {
298     SALOME_ModuleCatalog::Acomponent_ptr C = (*aModuleCatalog)->GetComponent((char *)lComponents[i]);
299     QListViewItem* myComponentItem = new QListViewItem(components, (char*)C->componentusername());
300     myComponentItem->setSelectable(false);
301     QString aIconName = C->component_icone();
302     if (!aIconName.isEmpty()) {
303       QString resFilePath = aResMgr->path(aResMgr->resSection(), C->componentname(), aIconName) ;
304       if ( resFilePath ) {
305         QPixmap aIcone(resFilePath);
306         QIconSet aIconSet(aIcone);
307         myComponentItem->setPixmap(0, aIconSet.pixmap(QIconSet::Small, QIconSet::Normal));
308       } else {
309         myComponentItem->setPixmap(0, ComponentIcon);
310       }
311     } else {
312       myComponentItem->setPixmap(0, ComponentIcon);
313     }
314     SALOME_ModuleCatalog::ListOfInterfaces* lInterfaces = C->GetInterfaceList();
315     long nbInterf = lInterfaces->length();
316     for (int j=0; j<nbInterf; j++) {
317       SALOME_ModuleCatalog::DefinitionInterface* Interface = C->GetInterface((char*)(*lInterfaces)[j]);
318       QListViewItem* myInterfaceItem = new QListViewItem(myComponentItem, (char*)Interface->interfacename);
319       myInterfaceItem->setSelectable(false);
320       myInterfaceItem->setPixmap(0, InterfaceIcon);
321       
322       long nbServices = Interface->interfaceservicelist.length();
323       for (int k=0; k<nbServices; k++) {
324         SALOME_ModuleCatalog::Service* Service = &(Interface->interfaceservicelist[k]);
325         QListViewItem* myServiceItem = new QListViewItem(myInterfaceItem, (char*)Service->ServiceName);
326         myServiceItem->setSelectable(true);
327         //components->ensureItemVisible(myServiceItem);
328         
329         long nbPortsOut = Service->ServiceoutParameter.length();
330         for (int m=0; m<nbPortsOut; m++) {
331           SALOME_ModuleCatalog::ServicesParameter* PortOut = &(Service->ServiceoutParameter[m]);
332           QListViewItem* myPortOutItem = 
333             new QListViewItem(myServiceItem, (char*)PortOut->Parametername, (char*)PortOut->Parametertype, "Out");
334           myPortOutItem->setSelectable(false);
335         }
336
337         long nbStreamPortsOut = Service->ServiceoutDataStreamParameter.length();
338         for (int m=0; m<nbStreamPortsOut; m++) {
339           SALOME_ModuleCatalog::ServicesDataStreamParameter* PortOut =
340             &(Service->ServiceoutDataStreamParameter[m]);
341           QListViewItem* myPortOutItem = 
342             new QListViewItem(myServiceItem, (char*)PortOut->Parametername, 
343                               getDataStreamParameterName(PortOut->Parametertype), "DataStream Out");
344           myPortOutItem->setSelectable(false);
345         }
346         
347         long nbPortsIn = Service->ServiceinParameter.length();
348         for (int l=0; l<nbPortsIn; l++) {
349           SALOME_ModuleCatalog::ServicesParameter* PortIn = &(Service->ServiceinParameter[l]);
350           QListViewItem* myPortInItem = 
351             new QListViewItem(myServiceItem, (char*)PortIn->Parametername, (char*)PortIn->Parametertype, "In");
352           myPortInItem->setSelectable(false);
353         }
354
355         long nbStreamPortsIn = Service->ServiceinDataStreamParameter.length();
356         for (int l=0; l<nbStreamPortsIn; l++) {
357           SALOME_ModuleCatalog::ServicesDataStreamParameter* PortIn = &(Service->ServiceinDataStreamParameter[l]);
358           QListViewItem* myPortInItem = 
359             new QListViewItem(myServiceItem, (char*)PortIn->Parametername, 
360                               getDataStreamParameterName(PortIn->Parametertype), "DataStream In");
361           myPortInItem->setSelectable(false);
362         }
363       }
364     }
365   }
366 }
367
368
369
370 SUPERVGUI_Service::~SUPERVGUI_Service() {
371     Trace("SUPERVGUI_Service::~SUPERVGUI_Service")
372       if (myMFile) delete myMFile;
373 }
374
375 void SUPERVGUI_Service::addComputeNode() {
376   SUIT_Desktop* aDesktop = SUIT_Session::session()->activeApplication()->desktop();
377   CAM_Application* anApp = ( CAM_Application* )(SUIT_Session::session()->activeApplication());
378   if ( !anApp ) return;
379   
380   SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
381   if ( !aSupMod ) {
382     MESSAGE("NULL Supervision module!");
383     return;
384   }
385
386   SUPERVGUI_Main* aMain = aSupMod->getMain();
387   if (aMain==0) {
388     QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
389   } else if (!aMain->isEditable()) {
390     QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));      
391   } else {
392     CORBA::Object_ptr obj  = naming->Resolve("/Kernel/ModulCatalog");
393     SALOME_ModuleCatalog::ModuleCatalog_var* aModuleCatalog = new SALOME_ModuleCatalog::ModuleCatalog_var;
394     *aModuleCatalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj);
395     if (CORBA::is_nil(*aModuleCatalog)) {
396       QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE"));
397     } else {
398       QListViewItem*        item;
399       bool                  b = false;
400       QListViewItemIterator i(components);
401       for (; i.current(); ++i) {
402         item = i.current();
403         if (item->isSelected()) {
404           const char* service   = item->text(0).latin1();
405           const char* interface = item->parent()->text(0).latin1();
406           const char* component = item->parent()->parent()->text(0).latin1();
407           SALOME_ModuleCatalog::Acomponent_ptr myComponent = (*aModuleCatalog)->GetComponent(anApp->moduleName(component));
408           if ( myComponent == NULL ) {
409             QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE"));
410           } 
411           else {
412             const SALOME_ModuleCatalog::Service* myService = myComponent->GetService(interface, service);
413             SUPERV_CNode aNode = aMain->getDataflow()->CNode(*myService);
414             if ( CORBA::is_nil( aNode ) ) {
415               QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));    
416               return;
417             }
418
419             SUPERV::INode_var aDummyEndNode;
420             addNode( aNode, aDummyEndNode, myX, myY );
421             b = true; // at least one node was added
422           }
423         }
424       }
425       if ( !b ) {
426         QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NONODE_TOADD"));
427       }
428     }
429   }
430 }
431
432 void SUPERVGUI_Service::addFactoryNodeDef() {
433   SUIT_Desktop* aDesktop = SUIT_Session::session()->activeApplication()->desktop();
434   CAM_Application* anApp = ( CAM_Application* )(SUIT_Session::session()->activeApplication());
435   if ( !anApp ) return;
436
437   SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
438   if ( !aSupMod ) {
439     MESSAGE("NULL Supervision module!");
440     return;
441   }
442
443   SUPERVGUI_Main* aMain = aSupMod->getMain();
444   if (aMain==0) {
445     QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
446   } else if (!aMain->isEditable()) {
447     QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));      
448   } else {
449     CORBA::Object_ptr obj  = naming->Resolve("/Kernel/ModulCatalog");
450     SALOME_ModuleCatalog::ModuleCatalog_var* aModuleCatalog = new SALOME_ModuleCatalog::ModuleCatalog_var;
451     *aModuleCatalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj);
452     if (CORBA::is_nil(*aModuleCatalog)) {
453       QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE"));
454     } else {
455       QListViewItem*        item;
456       bool                  b = false;
457       QListViewItemIterator i(components);
458       for (; i.current(); ++i) {
459         item = i.current();
460         if (item->isSelected()) {
461           const char* service   = item->text(0).latin1();
462           const char* interface = item->parent()->text(0).latin1();
463           //const char* component = anApp->moduleName(item->parent()->parent()->text(0).latin1());
464           // mkr : PAL13135 -->
465           if ( aSupMod->getInterfaceNameMap().contains(item->parent()->parent()->text(0)) ) {
466             const char* component = aSupMod->getInterfaceNameMap().find(item->parent()->parent()->text(0)).data();
467             // mkr : PAL13135 <--
468
469             SALOME_ModuleCatalog::Acomponent_ptr myComponent = (*aModuleCatalog)->GetComponent(component);
470             if (myComponent==NULL) {
471               QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE"));
472             } 
473             else {
474               const SALOME_ModuleCatalog::Service* myService = myComponent->GetService(interface, service);
475               SUPERV_CNode aNode;
476               if ( myService->TypeOfNode == 0 ) { // ComputeNode
477                 aNode = aMain->getDataflow()->CNode(*myService);
478                 if (CORBA::is_nil( aNode ) ) {
479                   QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));        
480                   return;
481                 }
482               } 
483               else { // Factory Node
484                 aNode = aMain->getDataflow()->FNode(component, interface, *myService, myComponent->implementation_type()); // mkr : PAL11273
485                 if ( CORBA::is_nil( aNode ) ) {
486                   QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));        
487                   return;
488                 }
489               }
490               SUPERV::INode_var aDummyEndNode;
491               addNode( aNode, aDummyEndNode, myX, myY );
492               b = true;
493             }
494           }
495         }
496       }
497       if ( !b ) {
498         QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NONODE_TOADD"));
499       }
500     }
501   }
502 }
503
504 void SUPERVGUI_Service::addFactoryNodeCust() {
505   SUIT_Desktop* aDesktop = SUIT_Session::session()->activeApplication()->desktop();
506   CAM_Application* anApp = ( CAM_Application* )(SUIT_Session::session()->activeApplication());
507   if ( !anApp ) return;
508
509   SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
510   if ( !aSupMod ) {
511     MESSAGE("NULL Supervision module!");
512     return;
513   }
514
515   SUPERVGUI_Main* aMain = aSupMod->getMain();
516   if (aMain==0) {
517     QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
518   } else if (!aMain->isEditable()) {
519     QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));      
520   } else {
521     CORBA::Object_ptr obj  = naming->Resolve("/Kernel/ModulCatalog");
522     SALOME_ModuleCatalog::ModuleCatalog_var* aModuleCatalog = new SALOME_ModuleCatalog::ModuleCatalog_var;
523     *aModuleCatalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj);
524     if (CORBA::is_nil(*aModuleCatalog)) {
525       QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE"));
526     } else {
527       QListViewItem*        item;
528       bool                  b = false;
529       
530       QListViewItemIterator iSel(components);
531       int count = 0;
532       for (; iSel.current(); ++iSel) { // check : how many objects are selected (single or multi)
533         item = iSel.current();
534         if (item->isSelected()) count++;
535         if ( count > 1) break;
536       }
537            
538       QListViewItemIterator i(components);
539       QString anAuthor, aContainer, aComment;
540       bool DoneSetting = false;
541       int aRes = 0;
542       for (; i.current(); ++i) {
543         item = i.current();
544         if (item->isSelected()) {
545           const char* service   = item->text(0).latin1();
546           const char* interface = item->parent()->text(0).latin1();
547           //const char* component = anApp->moduleName(item->parent()->parent()->text(0).latin1());
548           // mkr : PAL13135 -->
549           if ( aSupMod->getInterfaceNameMap().contains(item->parent()->parent()->text(0)) ) {
550             const char* component = aSupMod->getInterfaceNameMap().find(item->parent()->parent()->text(0)).data();
551             // mkr : PAL13135 <--
552
553             SALOME_ModuleCatalog::Acomponent_ptr myComponent = (*aModuleCatalog)->GetComponent(component);
554             if (myComponent==NULL) {
555               QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE"));
556             } 
557             else {
558               const SALOME_ModuleCatalog::Service* myService = myComponent->GetService(interface, service);
559               SUPERV_CNode aNode;
560               if ( myService->TypeOfNode == 0 ) { // ComputeNode
561                 aNode = aMain->getDataflow()->CNode(*myService);
562                 if (CORBA::is_nil( aNode ) ) {
563                   QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));        
564                   return;
565                 }
566               } 
567               else { // Factory Node
568
569                 SUPERVGUI_CustomSettings* aCSDialog = 0;
570                 if ( count > 1 && !DoneSetting) { // multi selection
571                   DoneSetting = true;
572                   aCSDialog = new SUPERVGUI_CustomSettings(item, true, myComponent->implementation_type());
573                 }
574                 else if ( count == 1 ) // single selection
575                   aCSDialog = new SUPERVGUI_CustomSettings(item, false, myComponent->implementation_type());
576                 
577                 if ( aCSDialog ) {
578                   aRes = aCSDialog->exec();
579                   if (aRes) {
580                     anAuthor = aCSDialog->Author();
581                     aContainer = aCSDialog->Container();
582                     aComment = aCSDialog->Comment();
583                   }
584                   delete aCSDialog;
585                 }
586                 
587                 aNode = aMain->getDataflow()->FNode(component, interface, *myService, myComponent->implementation_type()); // mkr : PAL11273
588                 if ( CORBA::is_nil( aNode ) ) {
589                   QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));        
590                   return;
591                 }
592
593                 if (aRes) {
594                   aNode->SetAuthor(anAuthor.latin1());
595                   SUPERV::FNode::_narrow(aNode)->SetContainer(aContainer.latin1());
596                   aNode->SetComment(aComment.latin1());
597                 }
598                 
599               }
600               SUPERV::INode_var aDummyEndNode;
601               addNode( aNode, aDummyEndNode, myX, myY );
602               b = true;
603             }
604           }
605         }
606       }
607       if ( !b ) {
608         QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NONODE_TOADD"));
609       }
610     }
611   }
612 }
613
614 void SUPERVGUI_Service::addInlineNode() {
615   SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
616   if ( !aSupMod ) {
617     MESSAGE("NULL Supervision module!");
618     return;
619   }
620
621   SUPERVGUI_Main* aMain = aSupMod->getMain();
622   if (aMain==0) {
623     QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
624   } 
625   else if (!aMain->isEditable()) {
626     QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
627   } 
628   else {
629     int aSel = myTypeCombo->currentItem();
630     switch (aSel) {
631     case 0: // Computation
632       { 
633         SUPERV_CNode aNode = 
634           aMain->getDataflow()->INode(myScriptPane->getFuncName().isEmpty() ? "" : myScriptPane->getFuncName().latin1(), 
635                                       (myScriptPane->getFunction()).in());
636         if (CORBA::is_nil(aNode)) {
637           QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
638           return;
639         }
640         SUPERV::INode_var aDummyEndNode;
641         // here we have to 
642         // 1) parse nodes' python function to find ports names
643         // 2) create ports for engine node with found names and "undefined" types
644         //    ( aNode->InPort(name,type), aNode->OutPort(name,type) )
645         // P.S. CanvasNode->createPort(...) for create presentation of port
646         //      will be called from addNode(...) (inside CanvasNode constructor)
647         addNode( aNode, aDummyEndNode, myX, myY );
648       }
649       break;
650       
651     case 1: // Switch
652       {
653         SUPERV_INode aEndNode;
654         SUPERV_CNode aStartNode = 
655           aMain->getDataflow()->SNode(myScriptPane->getFuncName().isEmpty() ? "" : myScriptPane->getFuncName().latin1(),
656                                       (myScriptPane->getFunction()).in(),
657                                       aEndNode);
658         if (CORBA::is_nil(aStartNode) || CORBA::is_nil(aEndNode)) {
659           QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
660           return;
661         }
662         addNode( aStartNode, aEndNode, myX, myY );
663       }
664       break;
665       
666     case 2: // Loop
667       {
668         SUPERV_INode aEndNode;
669         SUPERV_CNode aStartNode = 
670           aMain->getDataflow()->LNode(myInitPane->getFuncName().isEmpty() ? "" : myInitPane->getFuncName().latin1(), 
671                                       (myInitPane->getFunction()).in(),
672                                       myMorePane->getFuncName().isEmpty() ? "" : myMorePane->getFuncName().latin1(), 
673                                       (myMorePane->getFunction()).in(),
674                                       myNextPane->getFuncName().isEmpty() ? "" : myNextPane->getFuncName().latin1(), 
675                                       (myNextPane->getFunction()).in(),
676                                       aEndNode);
677         if (CORBA::is_nil(aStartNode) || CORBA::is_nil(aEndNode)) {
678           QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
679           return;
680         }
681         addNode( aStartNode, aEndNode, myX, myY );
682       }
683       break;
684       
685     case 3: // GoTo
686       {
687         SUPERV_CNode aGotoNode;
688         if (myScriptPane->isDefined()) 
689           aGotoNode = aMain->getDataflow()->GNode(myScriptPane->getFuncName().latin1(), 
690                                                   (myScriptPane->getFunction()).in(), "");
691         else
692           aGotoNode = aMain->getDataflow()->GNode("GoTo", (myScriptPane->getFunction()).in(), "");
693         if (CORBA::is_nil(aGotoNode)) {
694           QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
695           return;
696         }
697         SUPERV::INode_var aDummyEndNode;
698         addNode( aGotoNode, aDummyEndNode, myX, myY );
699       }
700       break;
701     }
702   }
703 }
704
705 void SUPERVGUI_Service::addMacroNode() {
706   SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
707   if ( !aSupMod ) {
708     MESSAGE("NULL Supervision module!");
709     return;
710   }
711
712   SUPERVGUI_Main* aMain = aSupMod->getMain();
713   if (aMain==0) {
714     QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
715   } 
716   else if (!aMain->isEditable()) {
717     QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
718   } 
719   else {
720     if ( myMFile ) {
721       SUPERV_CNode aNode;
722       if (aMain->getDataflow()->IsStreamGraph()) {
723         SUPERV_StreamGraph aSGraph = aMain->getDataflow()->ToStreamGraph();
724         if (!SUPERV_isNull(aSGraph)) 
725           aNode = aSGraph->StreamMNode(myMFile->name().latin1());
726         // TMP: while stream macro nodes doesn't impemented 
727         if (CORBA::is_nil(aNode)) {
728           aNode = aSGraph->MNode(myMFile->name().latin1());
729         }
730       }
731       else 
732         aNode = aMain->getDataflow()->MNode(myMFile->name().latin1());
733       if (CORBA::is_nil(aNode)) {
734         QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));         
735         return;
736       }
737
738       SUPERV::INode_var aDummyEndNode;
739       addNode( aNode, aDummyEndNode, myX, myY );
740     }
741     else {
742       QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("WARNING"), tr("MSG_NONODE_TOADD"));
743     }
744   }
745 }
746
747 void SUPERVGUI_Service::loadGraph() {
748         if ( getenv( "ENABLE_MACRO_NODE" ) == NULL )
749         // error! if ENABLE_MACRO_NODE is set - we should NOT get here by any means..
750         {
751                 //MESSAGE("Error: ENABLE_MACRO_NODE is not set, but loadGraph() was called!");
752                 return;
753         }
754
755   QString aFileName = SUIT_FileDlg::getFileName(SUIT_Session::session()->activeApplication()->desktop(),
756                                                 "",
757                                                 "*.xml",
758                                                 tr("MSG_GRAPH_INSERT"),
759                                                 true);
760   if (aFileName.isEmpty()) return;
761
762   myMacroPane->clear();
763
764   myMFile = new QFile(aFileName);
765   if (!myMFile->open(IO_ReadOnly)) {
766     QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), 
767                          tr("MSG_CANT_LOADSCRIPT"));
768     delete myMFile; myMFile = 0;
769     return;
770   }
771
772   QTextStream* aStream = new QTextStream(myMFile);
773   if (aStream->atEnd()) {
774     QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), 
775                          tr("MSG_EMTY_FILE"));
776     delete aStream;
777     myMFile->close();
778     delete myMFile; myMFile = 0;
779     return;
780   }
781
782   // read graph info
783   // temporary display only file name
784   QFileInfo anInfo(*myMFile);
785   QListViewItem* anItem = new QListViewItem(myMacroPane, anInfo.baseName());
786   anItem->setSelectable(true);
787 }
788
789 void SUPERVGUI_Service::typeNodeSelected(int theRow) {
790   if (theRow == 2)
791     myStackWidget->raiseWidget(myLoopId);
792   else
793     myStackWidget->raiseWidget(myOtherId);
794 }
795
796
797
798 void SUPERVGUI_Service::choose() {
799     Trace("SUPERVGUI_Service::choose")
800     show();
801     raise();
802 }
803     
804
805 void SUPERVGUI_Service::showEvent(QShowEvent* theEvent) {
806   SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
807   if ( !aSupMod ) {
808     MESSAGE("NULL Supervision module!");
809     return;
810   }
811
812   SUPERVGUI_Main* aMain = aSupMod->getMain();
813   if (aMain && (!aMain->isArrayShown())) {
814     aMain->getArrayView()->viewportToContents(0, 0, myX, myY);
815     //aMain->getGraph()->viewportToContents(0, 0, myX, myY);
816   }
817   QDialog::showEvent(theEvent);
818 }
819
820
821 void SUPERVGUI_Service::tabChanged(QWidget* theWidget) {
822   myIsInline = (myTabPane->currentPageIndex() == 1);
823 }
824
825
826
827 //*****************************************************/
828 //  Pane for Python script editing
829 //*****************************************************/
830 SUPERVGUI_PythonEditPane::SUPERVGUI_PythonEditPane( QWidget* theParent, const bool isNodeCreation, int& theX, int& theY ) 
831   : myIsWithLibrary( isNodeCreation ), 
832     QFrame( theParent ),
833     myX( theX ), myY( theY )
834 {
835   QGridLayout* aEditLayout = new QGridLayout( this, 2, 8, 0, 6 );
836
837   // First row
838   if ( myIsWithLibrary ) {
839     QPushButton* aLibBtn = new QPushButton(tr("BUT_LIBRARY"), this);
840     connect(aLibBtn, SIGNAL(clicked()), this, SLOT(library()));
841     aEditLayout->addMultiCellWidget( aLibBtn, 0, 0, 1, 2 );
842   }
843
844   QPushButton* aLoadBtn = new QPushButton(tr("BUT_LOAD"), this);
845   connect(aLoadBtn, SIGNAL(clicked()), this, SLOT(loadFile()));
846   
847   aEditLayout->addMultiCellWidget( aLoadBtn, 0, 0, 3, 4 );
848
849   myFunctionsCombo = new QComboBox( this );
850   connect( myFunctionsCombo, SIGNAL( activated( int ) ), this, SLOT( readFunction( int ) ) );
851   
852   aEditLayout->addMultiCellWidget( myFunctionsCombo, 0, 0, 5, 7 );
853   
854   //Second row
855   myText = new QTextEdit(this);
856   myText->setTextFormat( Qt::PlainText ); // NOT rich text, so text() returns plain text
857   myText->setWordWrap( QTextEdit::FixedColumnWidth );
858   myText->setWrapColumnOrWidth( 80 );
859   connect( myText, SIGNAL( returnPressed() ), this, SLOT( autoIndentLine() ) );
860
861   aEditLayout->addMultiCellWidget( myText, 1, 1, 0, 7 );
862   //aEditLayout->setColStretch( 3, 1 ); // to allow myFunctionsCombo be larger when needed
863 }
864
865 /**
866  * Return a text between "def" and "("
867  * "def" must begin with position 0, which means that only global function definitions are possible
868  */ 
869 QString getFunctionName( const QString& aLine ) {
870   int aDefPos = aLine.find("def");
871   if ( aDefPos == 0 ) { // only global function definitions!
872     int aStart = aLine.find(" ", aDefPos);
873     int aEnd = aLine.find("(", aStart);
874     QString aName = aLine.mid(aStart, (aEnd-aStart));
875     return aName.stripWhiteSpace();
876   }
877   return QString();
878 }
879    
880 /**
881  * Searches for text beginning with "def" and ending with any meanful character at 
882  * beginning of line.  Starts searching with current position of given stream.
883  * Fills the myPyFunctions with strings corresponding to found fucntions.
884  */
885 void SUPERVGUI_PythonEditPane::initPyFunctions( QTextStream& theStream ) {
886
887   if ( theStream.atEnd() )
888     return;
889
890   QString aPyFunction;
891   QString aLine = theStream.readLine(); 
892
893   while ( !theStream.atEnd() ) { // not EOF
894
895     // asv : 23.11.04 : fix for PAL6870 : skip empty lines in the beginning or  between functions
896     //       find("def)==0 -> analizing only global function definitions which start with 0 indentation
897     while ( !aLine.isNull() && aLine.find( "def" ) != 0 ) 
898       aLine = theStream.readLine();
899     
900     if ( !aLine.isNull() && aLine.find("def") == 0 ) { 
901       myFunctionsCombo->insertItem( getFunctionName( aLine ) ); // aLine now == function name 
902
903       aPyFunction += aLine;
904       aPyFunction += '\n'; 
905
906       // read function body
907       aLine = theStream.readLine();
908       // asv : 23.11.04 : added "|| aLine.isEmpty()" - fix for PAL6870. readLine() returns an empty
909       //       string for "\n" string, it trails \n caracter.  but we accept such lines..
910       // asv : 22.12.04 : aLine[0].isSpace() || aLine[0]=='#' -> line must begin with space or tab
911       //       (a normal code with indentation) or comment sign.
912       while ( !aLine.isNull() && ( aLine.isEmpty() || aLine[0].isSpace() || aLine[0] == '#' ) ) {
913         aPyFunction += aLine;
914         aPyFunction += '\n'; 
915         aLine = theStream.readLine();
916       }
917
918       myPyFunctions << aPyFunction;
919       aPyFunction.setLength( 0 );
920     }
921   }
922 }
923
924 /**
925  * Load existing Python script
926  */
927 void SUPERVGUI_PythonEditPane::loadFile() {
928   QString aFileName = SUIT_FileDlg::getFileName(SUIT_Session::session()->activeApplication()->desktop(),
929                                                 "",
930                                                 "*.py",
931                                                 tr("TIT_LOADSCRIPT"),
932                                                 true);
933   if (aFileName.isEmpty()) return;
934
935   QFile aFile( aFileName );
936   if (!aFile.open(IO_ReadOnly)) {
937     QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), 
938                          tr("MSG_CANT_LOADSCRIPT"));
939     return;
940   }
941
942   myPyFunctions.clear();
943   myFunctionsCombo->clear();
944   myText->clear();
945
946   QTextStream aFileReader(&aFile);
947   if ( aFileReader.atEnd() ) {
948     QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_EMTY_FILE"));
949     aFile.close();
950     return;
951   }
952
953   initPyFunctions( aFileReader );
954
955   if ( myPyFunctions.size() )
956     readFunction( 0 );
957 }
958   
959 /**
960  * Finds and Reads a function from current position in the opened file
961  * asv : Comment above is old! Present model: just take an already read string = PyFunction
962  * from the list which is filled in loadFile().
963  */
964 void SUPERVGUI_PythonEditPane::readFunction( int i ) {
965   myText->clear();
966   if ( i != -1 && myPyFunctions.size() && myPyFunctions.size() > i )
967     myText->append( myPyFunctions[ i ] );
968
969   // asv : 30.11.04 : 2.7 - Inline node function editor improvement
970   // 2.7.1 - set focus to editor widget on editor window opening
971   // 2.7.2 - scroll to the beginning of function on editor window opening
972   myText->setFocus();
973   myText->ensureVisible( 0,0 );
974 }
975
976 /**
977  * Returns the text after "def" and before "(" -- first defined function name
978  */
979 QString SUPERVGUI_PythonEditPane::getFuncName() {
980   for (int i=0; i < myText->paragraphs(); i++) {
981     QString aName = getFunctionName( myText->text(i) );
982     if ( !aName.isEmpty() )
983       return aName;
984   }
985   return QString();
986 }
987
988 /**
989  * Returns the contents of the myText widget without trailing spacing 
990  */
991 SUPERV_Strings SUPERVGUI_PythonEditPane::getFunction() {
992   SUPERV_Strings aStrings = new SUPERV::ListOfStrings();
993   aStrings->length(myText->paragraphs());
994   for (int i=0; i < myText->paragraphs(); i++) {
995     QString aLine = myText->text(i);
996     // asv : 30.11.04 - why do we have to remove trailing spaces??  
997     // it's user's responsibility to enter correct Python code, we don't do anything with it.
998     // if (..) -- initial, while(..) -- my improvement, but also commented out -- needless.
999     //if (!aLine.right(1).compare(" ")) // replaced with the line below -- loop
1000     // uncommented by mkr to fix bugs IPAL12363, IPAL12885 -->
1001     while (aLine.at(aLine.length()-1).isSpace()) // remove trailing spaces
1002       aLine = aLine.remove(aLine.length()-1,1);
1003     // <--
1004     aStrings[i] = CORBA::string_dup(aLine.latin1());
1005   }
1006   return aStrings._retn();
1007 }
1008
1009
1010 void SUPERVGUI_PythonEditPane::setFunction(SUPERV_Strings theStr) {
1011   myText->clear();
1012   for ( int i=0, aLen = theStr->length(); i < aLen; i++ )
1013     myText->append(QString(theStr[i]));
1014
1015   // asv : 30.11.04 : 2.7 - Inline node function editor improvement
1016   // 2.7.1 - set focus to editor widget on editor window opening
1017   // 2.7.2 - scroll to the beginning of function on editor window opening
1018   myText->setFocus();
1019   myText->ensureVisible( 0,0 );
1020 }
1021
1022 /**
1023  * Automatic indentation rule: if a previous line ended with 
1024  * ':', then add N additional spaces in the current line.  If no ':' found, then 
1025  * the same amount of spaces as in the previous line is added. Connected to 
1026  * "returnPressed" signal of myText text edit.
1027 */
1028 void SUPERVGUI_PythonEditPane::autoIndentLine() {
1029   const int N = 4; // width of indentation "tab"
1030   if ( myText && myText->paragraphs() ) {
1031
1032     // get current cursor position and previous line (the one to be analized) 
1033     int pos, para, i;
1034     QString spacesStr;
1035     myText->getCursorPosition( &para, &pos ); // pos==0, beginning of line
1036     if ( myText->paragraphLength(para-1) > 0 ) { // mkr : IPAL9817
1037       QString line = myText->text( para-1 ); // previous paragraph line
1038
1039       // construct a string containing all leading space characters of previous line (tabs, etc.)
1040       i = -1;
1041       while ( line[++i].isSpace() ) // append all isSpace() characters at beginning of line to spacesStr
1042         spacesStr += line[i];
1043
1044       // if ':' was found -- add more spaces to spacesStr
1045       line = line.stripWhiteSpace();
1046       if ( line[ line.length()-1 ] == ':' ) {
1047         i = 0;
1048         while ( i++ < N ) 
1049           spacesStr += ' ';
1050       }
1051     }
1052
1053     // ok, append spacesStr at the beginning of the current line = make indentation
1054     myText->insertAt( spacesStr, para, pos );
1055     myText->setCursorPosition( para, pos+spacesStr.length() );
1056   }
1057 }
1058
1059 /**
1060  * Create a node by loading it from an external XML library file
1061  * This slot opens a dialog box which then "lives" by itself..
1062  */
1063 void SUPERVGUI_PythonEditPane::library() {
1064   // if CanImport() returns false, it displays an error message box, so there is no need to
1065   // display such message here ("library file not found", etc.).
1066   if ( SUPERVGUI_Library::getLibrary()->CanImport() ) {
1067     SUPERVGUI_LibDlg* aDlg = new SUPERVGUI_LibDlg( this, myX, myY );
1068     aDlg->exec();
1069   }
1070 }
1071
1072 /*!
1073  * Edit Python dialog
1074  */
1075 SUPERVGUI_EditPythonDlg::SUPERVGUI_EditPythonDlg( bool isLoop )
1076   :QDialog(SUIT_Session::session()->activeApplication()->desktop(), 0, true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu) 
1077 {
1078   setSizeGripEnabled( true );
1079   setCaption(tr("TIT_FUNC_PYTHON"));
1080   resize( 500, 250 );
1081   QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 4);
1082   int a,b; // dummies for PythonEditPane, not used, since library = false and myX, myY are not used in PythonEditPane
1083   myIsLoop = isLoop; // mkr : PAL12236
1084   if (isLoop) {
1085     QTabWidget* aLoopTabPane = new QTabWidget(this);
1086     myInitPane = new SUPERVGUI_PythonEditPane( this, false, a, b ); // library == false, since no creation of a node is needed here
1087     aLoopTabPane->addTab(myInitPane, "Init");
1088     
1089     myMorePane = new SUPERVGUI_PythonEditPane( this, false, a, b );
1090     aLoopTabPane->addTab(myMorePane, "More");
1091     
1092     myNextPane = new SUPERVGUI_PythonEditPane( this, false, a, b );
1093     aLoopTabPane->addTab(myNextPane, "Next");
1094
1095     aMainLayout->addWidget(aLoopTabPane);    
1096   } else {
1097     myEditPane = new SUPERVGUI_PythonEditPane( this, false, a, b );
1098     aMainLayout->addWidget(myEditPane);
1099   }
1100   QGroupBox* aBtnBox = new QGroupBox( this );
1101   aBtnBox->setColumnLayout( 0, Qt::Vertical );
1102   aBtnBox->layout()->setSpacing( 0 ); aBtnBox->layout()->setMargin( 0 );
1103   QHBoxLayout* aBtnLayout = new QHBoxLayout( aBtnBox->layout() );
1104   aBtnLayout->setAlignment( Qt::AlignTop );
1105   aBtnLayout->setSpacing( 6 ); aBtnLayout->setMargin( 11 );
1106   
1107   QPushButton* aOKBtn = new QPushButton( tr( "BUT_OK" ), aBtnBox );
1108   connect( aOKBtn, SIGNAL( clicked() ), this, SLOT( clickOnOk() ) );
1109   aBtnLayout->addWidget( aOKBtn );
1110
1111   aBtnLayout->addStretch();
1112
1113   QPushButton* aCancelBtn = new QPushButton( tr("BUT_CANCEL"), aBtnBox );
1114   connect( aCancelBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
1115   aBtnLayout->addWidget( aCancelBtn );
1116
1117   aMainLayout->addWidget(aBtnBox);
1118 }
1119
1120 // mkr : IPAL9817 : to avoid a SIGSEGV when INode_Impl::SetPyFunction(...)
1121 //                  will call with null python function name
1122 void SUPERVGUI_EditPythonDlg::clickOnOk()
1123 {
1124   // mkr : PAL12236
1125   bool hasEmptyName = myIsLoop ? 
1126     ( getInitFuncName().isEmpty() || getMoreFuncName().isEmpty() || getNextFuncName().isEmpty() ) :
1127     getFuncName().isEmpty();
1128
1129   if ( hasEmptyName )
1130     QMessageBox::warning( SUIT_Session::session()->activeApplication()->desktop(), tr( "ERROR" ), tr( "MSG_INCORRECT_INDENT" ) );
1131   else  
1132     accept();
1133 }
1134
1135 /**
1136  * Do the following actions for newly created Engine's CNode:
1137  * 1. Create a presentation for it (CanvasNode)
1138  * 2. Place the CanvasNode to the current top-left corner or the current viewport
1139  * 3. Increment the coordinates of the next CanvasNode (new nodes are "cascaded" when several of them are created at once)
1140  * PS theEndNode is passed only for Loop and Switch nodes (EndLoop and EndSwitch)
1141  */ 
1142 void SUPERVGUI_Service::addNode( SUPERV::CNode_var theNode, SUPERV::INode_var theEndNode, int& theX, int& theY )  {
1143   SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
1144   if ( !aSupMod ) {
1145     MESSAGE("NULL Supervision module!");
1146     return;
1147   }
1148   
1149   SUPERVGUI_Main* aMain = aSupMod->getMain();
1150
1151   if ( !CORBA::is_nil( theNode ) && aMain ) {
1152     
1153     aMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag, why here? -> PAL7960
1154
1155     int cx, cy;   //to appear a new node in the top-left corner of the current viewport
1156
1157     //2.8 point of improvements: Adding node to graph window with taking into account zoom factor
1158     QWMatrix aWM = aMain->getCanvasView()->worldMatrix();
1159     aMain->getCanvasView()->viewportToContents(theX, theY, cx, cy);
1160
1161     //2.8 point of improvements:
1162     cx = (int)((double)cx/aWM.m11());
1163     cy = (int)((double)cy/aWM.m22());
1164     theNode->Coords(cx, cy);
1165     if ( !CORBA::is_nil( theEndNode ) )
1166       theEndNode->Coords(cx + LABEL_WIDTH*2, cy);
1167     theX += (int)(NODE_DX*aWM.m11());
1168     theY += (int)(NODE_DY*aWM.m22());
1169
1170     if ( theNode->IsGOTO() )
1171       aMain->addGOTONode( theNode );
1172     else if ( theNode->IsMacro() )
1173       aMain->addMacroNode( theNode );
1174     else if ( theNode->IsLoop() || theNode->IsSwitch() )
1175       aMain->addControlNode( theNode, SUPERV::CNode::_narrow( theEndNode ), true );
1176     else 
1177       aMain->addComputeNode( theNode );
1178     aSupMod->nullifyInitialVF();
1179   }
1180 }
1181
1182 /*!
1183   Constructor
1184 */
1185 SUPERVGUI_CustomSettings::SUPERVGUI_CustomSettings(QListViewItem* theItem,
1186                                                    bool isMultiSel,
1187                                                    bool isCimpl)
1188      : QDialog( SUIT_Session::session()->activeApplication()->desktop(), "", true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ) 
1189 {
1190   Trace("SUPERVGUI_CustomSettings::SUPERVGUI_CustomSettings");
1191
1192   SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
1193   if ( !aSupMod ) {
1194     MESSAGE("NULL Supervision module!");
1195     return;
1196   }
1197
1198   SUIT_Desktop* aDesktop = SUIT_Session::session()->activeApplication()->desktop();
1199
1200   setSizeGripEnabled( true );
1201
1202   QGridLayout* TopLayout = new QGridLayout( this );
1203   TopLayout->setSpacing( 6 );
1204   TopLayout->setMargin( 11 );
1205     
1206   QGroupBox* TopGroup = new QGroupBox( this, "TopGroup" );
1207   TopGroup->setColumnLayout(0, Qt::Vertical );
1208   TopGroup->layout()->setSpacing( 0 );
1209   TopGroup->layout()->setMargin( 0 );
1210   QGridLayout* TopGroupLayout = new QGridLayout( TopGroup->layout() );
1211   TopGroupLayout->setAlignment( Qt::AlignTop );
1212   TopGroupLayout->setSpacing( 6 );
1213   TopGroupLayout->setMargin( 11 );
1214
1215   QLabel* authL = new QLabel( tr( "AUTHOR_LBL" ), TopGroup); 
1216   authV = new QLineEdit( TopGroup );
1217   authV->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
1218   authV->setMinimumSize( 200, 0 );
1219   authV->setText( "" );
1220
1221   contL = new QLabel( tr( "CONTAINER_LBL" ), TopGroup ); 
1222   contV = new QLineEdit( TopGroup );
1223   contV->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
1224   contV->setMinimumSize( 200, 0 );
1225   
1226   QLabel* commL = new QLabel( tr( "COMMENT_LBL" ), TopGroup); 
1227   commV = new QMultiLineEdit( TopGroup );
1228   commV->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
1229   commV->setMinimumSize( 200, 100 );
1230
1231   if ( !aSupMod->getInterfaceNameMap().contains(theItem->parent()->parent()->text(0)) ) {
1232     QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NONODE_TOADD"));
1233     return;
1234   }
1235   const char* component = aSupMod->getInterfaceNameMap().find(theItem->parent()->parent()->text(0)).data();
1236
1237   QString aNodeDefComment;
1238   if ( !isMultiSel ) {
1239     // 1) set caption
1240     const char* service = theItem->text(0).latin1();
1241     aNodeDefComment = QString(service) + QString(tr("COMMENT_FROM")) + QString(component);
1242     setCaption( tr( "TLT_CUSTOMPARAMETERS_SINGLE" ) + aNodeDefComment );
1243   }
1244   else {
1245     // 1) set caption
1246     aNodeDefComment = QString("Factory Node");
1247     setCaption( tr( "TLT_CUSTOMPARAMETERS_MULTI" ) );
1248   }
1249   
1250   // 2) set Container
1251   SUPERVGUI_Main* aMain = aSupMod->getMain();
1252   if (aMain==0) {
1253     QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
1254     return;
1255   }
1256   const char* aContainer = aMain->getDataflow()->ContainerNameForComponent(component);
1257   if ( aContainer && strlen(aContainer) > 0 )
1258     contV->setText( QString(aContainer) );
1259   else if ( isCimpl ) // C++ implementation
1260     contV->setText( QString(aMain->getDataflow()->DefaultCContainerName()) );
1261   else // Python implementation
1262     contV->setText( QString(aMain->getDataflow()->DefaultPythonContainerName()) );
1263
1264   // 3) set comment
1265   commV->setText( aNodeDefComment );
1266
1267   TopGroupLayout->addWidget( authL, 1, 0 );
1268   TopGroupLayout->addWidget( authV, 1, 1 );
1269   TopGroupLayout->addWidget( contL, 2, 0 );
1270   TopGroupLayout->addWidget( contV, 2, 1 );
1271   TopGroupLayout->addWidget( commL, 7, 0 );
1272   TopGroupLayout->addMultiCellWidget( commV, 7, 8, 1, 1 );
1273   TopGroupLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Minimum, QSizePolicy::Expanding  ), 8, 0 );
1274   TopGroupLayout->setColStretch( 1, 5 );
1275
1276   QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" );
1277   GroupButtons->setColumnLayout(0, Qt::Vertical );
1278   GroupButtons->layout()->setSpacing( 0 );
1279   GroupButtons->layout()->setMargin( 0 );
1280   QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
1281   GroupButtonsLayout->setAlignment( Qt::AlignTop );
1282   GroupButtonsLayout->setSpacing( 6 );
1283   GroupButtonsLayout->setMargin( 11 );
1284
1285   QPushButton* okB = new QPushButton( tr( "BUT_OK" ), GroupButtons );
1286   connect( okB,     SIGNAL( clicked() ), this, SLOT( okButton() ) );
1287   QPushButton* cancelB = new QPushButton( tr( "BUT_CANCEL" ), GroupButtons );
1288   connect( cancelB, SIGNAL( clicked() ), this, SLOT( koButton() ) );
1289
1290   GroupButtonsLayout->addWidget( okB, 0, 0 );
1291   GroupButtonsLayout->addItem  ( new QSpacerItem( 5, 5, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 1 );
1292   GroupButtonsLayout->addWidget( cancelB, 0, 2 );
1293
1294   TopLayout->addWidget( TopGroup,     0, 0 );
1295   TopLayout->addWidget( GroupButtons, 1, 0 );
1296   TopLayout->setRowStretch( 0, 1 );
1297   TopLayout->setRowStretch( 1, 0 );
1298
1299   resize(370,200);
1300 }
1301
1302 /*!
1303   Destructor
1304 */
1305 SUPERVGUI_CustomSettings::~SUPERVGUI_CustomSettings() {
1306   Trace("SUPERVGUI_CustomSettings::~SUPERVGUI_CustomSettings");
1307 }
1308
1309 /*!
1310   Get author
1311 */
1312 QString SUPERVGUI_CustomSettings::Author() {
1313   return authV->text();
1314 }
1315
1316 /*!
1317   Get container
1318 */
1319 QString SUPERVGUI_CustomSettings::Container() {
1320   return contV->text();
1321 }
1322
1323 /*!
1324   Get comment
1325 */
1326 QString SUPERVGUI_CustomSettings::Comment() {
1327   return commV->text();
1328 }
1329
1330 /*!
1331   <OK> button slot
1332 */
1333 void SUPERVGUI_CustomSettings::okButton() {
1334   Trace("SUPERVGUI_CustomSettings::okButton");
1335   accept();
1336 }
1337
1338 /*!
1339   <Cancel> button slot
1340 */
1341 void SUPERVGUI_CustomSettings::koButton() {
1342   Trace("SUPERVGUI_CustomSettings::koButton");
1343   reject();
1344 }