Salome HOME
DCQ : Merge with Ecole_Ete_a6.
[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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SUPERVGUI_Service.cxx
25 //  Author : Francis KLOSS
26 //  Module : SUPERV
27
28 using namespace std;
29 #include "SUPERVGUI_Service.h"
30 #include "SUPERVGUI_Main.h"
31 #include "SUPERVGUI.h"
32 #include "QAD_Tools.h"
33 #include "QAD_FileDlg.h"
34
35 #include "SALOME_NamingService.hxx"
36 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
37 #include <qlayout.h>
38 #include <qtextstream.h>
39
40
41 static const char * ComponentIcon[] = {
42 "20 20 2 1",
43 "       c None",
44 ".      c #000000",
45 "                    ",
46 "                    ",
47 "                    ",
48 " .................. ",
49 " .                . ",
50 " .                . ",
51 " .                . ",
52 " .                . ",
53 " .                . ",
54 " .                . ",
55 " .                . ",
56 " .                . ",
57 " .................. ",
58 "    .     .     .   ",
59 "    .     .     .   ",
60 "   ...   ...   ...  ",
61 "  .. .. .. .. .. .. ",
62 "  .   . .   . .   . ",
63 "  .. .. .. .. .. .. ",
64 "   ...   ...   ...  "};
65
66
67 static const char * InterfaceIcon[] = {
68 "20 20 2 1",
69 "       c None",
70 ".      c #000000",
71 "                    ",
72 "                    ",
73 "                    ",
74 "                    ",
75 "                    ",
76 "            ..      ",
77 "          ......    ",
78 "         ..    ..   ",
79 "         .      .   ",
80 "..........      ..  ",
81 "         .      .   ",
82 "         ..    ..   ",
83 "          ......    ",
84 "            ..      ",
85 "                    ",
86 "                    ",
87 "                    ",
88 "                    ",
89 "                    ",
90 "                    "};
91
92
93
94
95 SUPERVGUI_Service::SUPERVGUI_Service(SALOME_NamingService* ns):
96     QDialog(QAD_Application::getDesktop(), 0, false, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
97     naming(ns)
98 {
99   setSizeGripEnabled( true );
100   setCaption(tr("TIT_SERVICES"));
101
102   QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 4);
103
104   myTabPane = new QTabWidget(this);
105   connect(myTabPane, SIGNAL(currentChanged(QWidget *)), this, SLOT(tabChanged(QWidget *)));
106
107   // Create Tab for Corba services
108   QWidget* aCorbaPane = new QWidget(myTabPane);
109   QVBoxLayout* aBaseLayoutV= new QVBoxLayout(aCorbaPane, 0, 4);
110   aBaseLayoutV->setMargin(5);
111   aBaseLayoutV->setSpacing(10);
112
113   QHBoxLayout* aBaseLayout = new QHBoxLayout(aCorbaPane); //!!
114  
115   components = new QListView(aCorbaPane);
116   components->addColumn(tr("COL_COMPONENTS"));
117   components->addColumn(tr("COL_PORTTYPE"));
118   components->addColumn(tr("COL_PORTWAY"));
119   components->setColumnAlignment(1, AlignLeft);
120   components->setColumnAlignment(2, AlignLeft);
121   components->setColumnAlignment(3, AlignLeft);
122   components->setSelectionMode(QListView::Extended);
123   components->setRootIsDecorated(true);
124 //  aBaseLayout->addWidget(components);
125   aBaseLayoutV->addWidget(components); //!!
126
127   //QHGroupBox* aAddBox = new QHGroupBox(tr("TIT_ADDNODE"), aCorbaPane); //!!
128   //aAddBox->setInsideSpacing(20); //!!
129
130 //NRI   QPushButton* aComputeCBtn = new QPushButton(tr("TIT_ADDCNODE"), aCorbaPane); //!!
131 //NRI   connect(aComputeCBtn, SIGNAL(clicked()), this, SLOT(addComputeNode())); //!!
132 //NRI   aComputeCBtn->setDefault(false); 
133
134   QPushButton* aComputeBtn = new QPushButton(tr("TIT_ADDFNODE"), aCorbaPane);
135   connect(aComputeBtn, SIGNAL(clicked()), this, SLOT(addFactoryNode()));
136   aComputeBtn->setDefault(true); 
137
138   aBaseLayout->addWidget(aComputeBtn);
139   //NRI  aBaseLayout->addWidget(aComputeCBtn); //!!
140
141   aBaseLayoutV->insertLayout(-1, aBaseLayout);
142   myTabPane->addTab(aCorbaPane, tr("MODULES_PANE"));
143
144
145   // Create Tab for Python services
146   QWidget* aPythonPane = new QWidget(myTabPane);
147   QVBoxLayout* aPythonLayout = new QVBoxLayout(aPythonPane, 0, 4);
148   aPythonLayout->setMargin(5);
149   aPythonLayout->setSpacing(10);
150
151   // Type pane
152   QHGroupBox* aAddBox2 = new QHGroupBox(tr("TIT_ADDNODE"), aPythonPane);
153   aAddBox2->setInsideSpacing(20);
154
155   QLabel* aTypeLbl = new QLabel(tr("LBL_NODETYPE"), aAddBox2);
156
157   myTypeCombo = new QComboBox(aAddBox2);
158   myTypeCombo->insertItem("Computation");
159   myTypeCombo->insertItem("Switch");
160   myTypeCombo->insertItem("Loop");
161   myTypeCombo->insertItem("GoTo");
162   //myTypeCombo->insertItem("Label");
163   connect(myTypeCombo, SIGNAL(activated(int)), this, SLOT(typeNodeSelected(int)));
164
165   aPythonLayout->addWidget(aAddBox2);
166
167   // Edit pane
168   myStackWidget = new QWidgetStack(aPythonPane);
169
170   // other pane
171   myScriptPane = new SUPERVGUI_PythonEditPane(myStackWidget);
172   myOtherId = myStackWidget->addWidget(myScriptPane);
173
174   // loop pane
175   QTabWidget* aLoopTabPane = new QTabWidget(myStackWidget);
176   myInitPane = new SUPERVGUI_PythonEditPane(myStackWidget); 
177   aLoopTabPane->addTab(myInitPane, "Init");
178
179   myMorePane = new SUPERVGUI_PythonEditPane(myStackWidget);
180   aLoopTabPane->addTab(myMorePane, "More");
181
182   myNextPane = new SUPERVGUI_PythonEditPane(myStackWidget);
183   aLoopTabPane->addTab(myNextPane, "Next");
184   myLoopId = myStackWidget->addWidget(aLoopTabPane);
185
186   myStackWidget->raiseWidget(myOtherId);
187
188   aPythonLayout->addWidget(myStackWidget, 1);
189
190   // Create button
191   QPushButton* aCreateBtn = new QPushButton(tr("TIT_ADDNODE"), aPythonPane);
192   connect(aCreateBtn, SIGNAL(clicked()), this, SLOT(addInlineNode()));
193   aPythonLayout->addWidget(aCreateBtn);
194
195   myTabPane->addTab(aPythonPane, tr("INLINE_PANE"));
196
197   aMainLayout->addWidget(myTabPane);
198
199   // Close button
200   QHBox* aBtnBox = new QHBox(this);
201   QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout()); 
202   aBtnLayout->addStretch();
203
204   QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
205   connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(reject()));
206   
207   aMainLayout->addWidget(aBtnBox);
208
209   initialise();
210   myX = 0;
211   myY = 0;
212   myIsInline = false;
213 }
214
215
216 char* getDataStreamParameterName(int aType)
217 {
218   switch(aType) {
219   case 1:
220     return "integer";
221   case 2:
222     return "float";
223   case 3:
224     return "double";
225   case 4:
226     return "string";
227   case 6:
228     return "boolean";
229   default:
230     return "unknown";
231   }
232 }
233
234 void SUPERVGUI_Service::initialise() {
235   CORBA::Object_ptr obj  = naming->Resolve("/Kernel/ModulCatalog");
236   SALOME_ModuleCatalog::ModuleCatalog_var *aModuleCatalog = new SALOME_ModuleCatalog::ModuleCatalog_var;
237   *aModuleCatalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj);
238   if (CORBA::is_nil(*aModuleCatalog)) {
239     setCaption("Error in Connexion to omniNames with '/Kernel/ModulCatalog'");
240     return;
241   }
242   
243   QAD_ResourceMgr* aResMgr = QAD_Desktop::createResourceManager();
244
245   SALOME_ModuleCatalog::ListOfComponents_var lComponents = (*aModuleCatalog)->GetComponentList();
246   long nbComp = lComponents->length();
247   for (int i=0; i<nbComp; i++) {
248     SALOME_ModuleCatalog::Acomponent_ptr C = (*aModuleCatalog)->GetComponent((char *)lComponents[i]);
249     QListViewItem* myComponentItem = new QListViewItem(components, (char*)C->componentusername());
250     myComponentItem->setSelectable(false);
251     QString aIconName = C->component_icone();
252     if (!aIconName.isEmpty()) {
253       QString resDir = aResMgr->findFile(aIconName, C->componentname()) ;
254       if (resDir) {
255         resDir = QAD_Tools::addSlash(resDir);
256         QPixmap aIcone(resDir + aIconName);
257         QIconSet aIconSet(aIcone);
258         myComponentItem->setPixmap(0, aIconSet.pixmap(QIconSet::Small, QIconSet::Normal));
259       } else {
260         myComponentItem->setPixmap(0, ComponentIcon);
261       }
262     } else {
263       myComponentItem->setPixmap(0, ComponentIcon);
264     }
265     SALOME_ModuleCatalog::ListOfInterfaces* lInterfaces = C->GetInterfaceList();
266     long nbInterf = lInterfaces->length();
267     for (int j=0; j<nbInterf; j++) {
268       SALOME_ModuleCatalog::DefinitionInterface* Interface = C->GetInterface((char*)(*lInterfaces)[j]);
269       QListViewItem* myInterfaceItem = new QListViewItem(myComponentItem, (char*)Interface->interfacename);
270       myInterfaceItem->setSelectable(false);
271       myInterfaceItem->setPixmap(0, InterfaceIcon);
272       
273       long nbServices = Interface->interfaceservicelist.length();
274       for (int k=0; k<nbServices; k++) {
275         SALOME_ModuleCatalog::Service* Service = &(Interface->interfaceservicelist[k]);
276         QListViewItem* myServiceItem = new QListViewItem(myInterfaceItem, (char*)Service->ServiceName);
277         myServiceItem->setSelectable(true);
278         components->ensureItemVisible(myServiceItem);
279         
280         long nbPortsOut = Service->ServiceoutParameter.length();
281         for (int m=0; m<nbPortsOut; m++) {
282           SALOME_ModuleCatalog::ServicesParameter* PortOut = &(Service->ServiceoutParameter[m]);
283           QListViewItem* myPortOutItem = 
284             new QListViewItem(myServiceItem, (char*)PortOut->Parametername, (char*)PortOut->Parametertype, "Out");
285           myPortOutItem->setSelectable(false);
286         }
287
288         long nbStreamPortsOut = Service->ServiceoutDataStreamParameter.length();
289         for (int m=0; m<nbStreamPortsOut; m++) {
290           SALOME_ModuleCatalog::ServicesDataStreamParameter* PortOut = &(Service->ServiceoutDataStreamParameter[m]);
291           QListViewItem* myPortOutItem = 
292             new QListViewItem(myServiceItem, (char*)PortOut->Parametername, 
293                               getDataStreamParameterName(PortOut->Parametertype), "DataStream Out");
294           myPortOutItem->setSelectable(false);
295         }
296         
297         long nbPortsIn = Service->ServiceinParameter.length();
298         for (int l=0; l<nbPortsIn; l++) {
299           SALOME_ModuleCatalog::ServicesParameter* PortIn = &(Service->ServiceinParameter[l]);
300           QListViewItem* myPortInItem = 
301             new QListViewItem(myServiceItem, (char*)PortIn->Parametername, (char*)PortIn->Parametertype, "In");
302           myPortInItem->setSelectable(false);
303         }
304
305         long nbStreamPortsIn = Service->ServiceinDataStreamParameter.length();
306         for (int l=0; l<nbStreamPortsIn; l++) {
307           SALOME_ModuleCatalog::ServicesDataStreamParameter* PortIn = &(Service->ServiceinDataStreamParameter[l]);
308           QListViewItem* myPortInItem = 
309             new QListViewItem(myServiceItem, (char*)PortIn->Parametername, 
310                               getDataStreamParameterName(PortIn->Parametertype), "DataStream In");
311           myPortInItem->setSelectable(false);
312         }
313       }
314     }
315   }
316 }
317
318
319
320 SUPERVGUI_Service::~SUPERVGUI_Service() {
321     Trace("SUPERVGUI_Service::~SUPERVGUI_Service")
322 }
323
324 void SUPERVGUI_Service::addComputeNode() {
325   QAD_Desktop* aDesktop = QAD_Application::getDesktop();
326   SUPERVGUI_Main* aMain = Supervision.getMain();
327   if (aMain==0) {
328     QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
329   } else {
330     CORBA::Object_ptr obj  = naming->Resolve("/Kernel/ModulCatalog");
331     SALOME_ModuleCatalog::ModuleCatalog_var* aModuleCatalog = new SALOME_ModuleCatalog::ModuleCatalog_var;
332     *aModuleCatalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj);
333     if (CORBA::is_nil(*aModuleCatalog)) {
334       QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE"));
335     } else {
336       QListViewItem*        item;
337       bool                  b = false;
338       QListViewItemIterator i(components);
339       for (; i.current(); ++i) {
340         item = i.current();
341         if (item->isSelected()) {
342           const char* service   = item->text(0).latin1();
343           const char* interface = item->parent()->text(0).latin1();
344           const char* component = item->parent()->parent()->text(0).latin1();
345           SALOME_ModuleCatalog::Acomponent_ptr myComponent = (*aModuleCatalog)->GetComponent(aDesktop->getComponentName(component));
346           if (myComponent==NULL) {
347             QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE"));
348           } else {
349             const SALOME_ModuleCatalog::Service* myService = myComponent->GetService(interface, service);
350             b  = true;
351             
352             SUPERV_CNode node = aMain->getDataflow()->CNode(*myService);
353             if (CORBA::is_nil(node)) {
354               QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));   
355               return;
356             }
357             node->Coords(myX, myY);
358             myX += NODE_DX;
359             myY += NODE_DY;
360             aMain->addComputeNode(SUPERV::CNode::_narrow(node));
361           }
362         }
363       }
364       if (!b) {
365         QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NONODE_TOADD"));
366       }
367     }
368   }
369 }
370
371 void SUPERVGUI_Service::addFactoryNode() {
372   QAD_Desktop* aDesktop = QAD_Application::getDesktop();
373   SUPERVGUI_Main* aMain = Supervision.getMain();
374   if (aMain==0) {
375     QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
376   } else {
377     CORBA::Object_ptr obj  = naming->Resolve("/Kernel/ModulCatalog");
378     SALOME_ModuleCatalog::ModuleCatalog_var* aModuleCatalog = new SALOME_ModuleCatalog::ModuleCatalog_var;
379     *aModuleCatalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj);
380     if (CORBA::is_nil(*aModuleCatalog)) {
381       QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE"));
382     } else {
383       QListViewItem*        item;
384       bool                  b = false;
385       QListViewItemIterator i(components);
386       for (; i.current(); ++i) {
387         item = i.current();
388         if (item->isSelected()) {
389           const char* service   = item->text(0).latin1();
390           const char* interface = item->parent()->text(0).latin1();
391           const char* component = aDesktop->getComponentName(item->parent()->parent()->text(0).latin1());
392           SALOME_ModuleCatalog::Acomponent_ptr myComponent = (*aModuleCatalog)->GetComponent(component);
393           if (myComponent==NULL) {
394             QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE"));
395           } else {
396             const SALOME_ModuleCatalog::Service* myService = myComponent->GetService(interface, service);
397             b  = true;
398             
399             MESSAGE ( " myService->TypeOfNode == " << myService->TypeOfNode ) 
400
401             if ( myService->TypeOfNode == 0 ) { // ComputeNode
402               SUPERV_CNode node = aMain->getDataflow()->CNode(*myService);
403               if (CORBA::is_nil(node)) {
404                 QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));         
405                 return;
406               }
407               node->Coords(myX, myY);
408               myX += NODE_DX;
409               myY += NODE_DY;
410               aMain->addComputeNode(SUPERV::CNode::_narrow(node));
411             } else { // Factory Node
412               SUPERV_FNode node = aMain->getDataflow()->FNode(component, interface, *myService);
413               if (CORBA::is_nil(node)) {
414                 QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));         
415                 return;
416               }
417               node->Coords(myX, myY);
418               myX += NODE_DX;
419               myY += NODE_DY;
420               aMain->addComputeNode(SUPERV::CNode::_narrow(node));
421               
422             }
423
424 //          SUPERV_FNode node = aMain->getDataflow()->FNode(component, interface, *myService);
425 //          if (CORBA::is_nil(node)) {
426 //            QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));   
427 //            return;
428 //          }
429 //          node->Coords(myX, myY);
430 //          myX += NODE_DX;
431 //          myY += NODE_DY;
432 //          aMain->addComputeNode(SUPERV::CNode::_narrow(node));
433           }
434         }
435       }
436       if (!b) {
437         QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), tr("MSG_NONODE_TOADD"));
438       }
439     }
440   }
441 }
442
443
444 void SUPERVGUI_Service::addInlineNode() {
445   SUPERVGUI_Main* aMain = Supervision.getMain();
446   if (aMain==0) {
447     QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
448   } else {
449     int aSel = myTypeCombo->currentItem();
450     switch (aSel) {
451     case 0: // Computation
452       if (myScriptPane->isDefined()) {  
453         SUPERV_INode aNode = aMain->getDataflow()->INode(myScriptPane->getFuncName().latin1(), 
454                                                          (myScriptPane->getFunction()).in());
455         if (CORBA::is_nil(aNode)) {
456           QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
457           return;
458         }
459         aNode->Coords(myX, myY);
460         myX += NODE_DX;
461         myY += NODE_DY;
462         aMain->addComputeNode(SUPERV::CNode::_narrow(aNode));
463       }
464       break;
465       
466     case 1: // Switch
467       if (myScriptPane->isDefined()) {
468         SUPERV_INode aEndNode;
469         SUPERV_SNode aStartNode = aMain->getDataflow()->SNode(myScriptPane->getFuncName().latin1(),
470                                                               (myScriptPane->getFunction()).in(),
471                                                               aEndNode);
472         if (CORBA::is_nil(aStartNode) || CORBA::is_nil(aEndNode)) {
473           QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
474           return;
475         }
476         aStartNode->Coords(myX, myY);
477         aEndNode->Coords(myX + LABEL_WIDTH*2, myY);
478         myX += NODE_DX;
479         myY += NODE_DY;
480         aMain->addControlNode(SUPERV::CNode::_narrow(aStartNode), SUPERV::CNode::_narrow(aEndNode), true);
481       }
482       break;
483       
484     case 2: // Loop
485       {
486         SUPERV_INode aEndNode;
487         SUPERV_LNode aStartNode = aMain->getDataflow()->LNode(myInitPane->getFuncName().latin1(), (myInitPane->getFunction()).in(),
488                                                               myMorePane->getFuncName().latin1(), (myMorePane->getFunction()).in(),
489                                                               myNextPane->getFuncName().latin1(), (myNextPane->getFunction()).in(),
490                                                               aEndNode);
491         if (CORBA::is_nil(aStartNode) || CORBA::is_nil(aEndNode)) {
492           QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
493           return;
494         }
495         aStartNode->Coords(myX, myY);
496         aEndNode->Coords(myX + LABEL_WIDTH*2, myY);
497         myX += NODE_DX;
498         myY += NODE_DY;
499         aMain->addControlNode(SUPERV::CNode::_narrow(aStartNode), SUPERV::CNode::_narrow(aEndNode), true);
500       }
501       break;
502       
503     case 3: // GoTo
504       {
505         SUPERV_GNode aGotoNode;
506         if (myScriptPane->isDefined()) 
507           aGotoNode = aMain->getDataflow()->GNode(myScriptPane->getFuncName().latin1(), 
508                                                   (myScriptPane->getFunction()).in(), "");
509         else
510           aGotoNode = aMain->getDataflow()->GNode("GoTo", (myScriptPane->getFunction()).in(), "");
511         if (CORBA::is_nil(aGotoNode)) {
512           QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
513           return;
514         }
515         aGotoNode->Coords(myX, myY);
516         myX += NODE_DX;
517         myY += NODE_DY;
518         aMain->addGOTONode(SUPERV::GNode::_narrow(aGotoNode));
519       }
520       break;
521     }
522   }
523 }
524
525
526
527 void SUPERVGUI_Service::typeNodeSelected(int theRow) {
528   if (theRow == 2)
529     myStackWidget->raiseWidget(myLoopId);
530   else
531     myStackWidget->raiseWidget(myOtherId);
532 }
533
534
535
536 void SUPERVGUI_Service::choose() {
537     Trace("SUPERVGUI_Service::choose")
538     show();
539     raise();
540 }
541     
542
543 void SUPERVGUI_Service::showEvent(QShowEvent* theEvent) {
544   SUPERVGUI_Main* aMain = Supervision.getMain();
545   if (aMain && (!aMain->isArrayShown())) {
546     aMain->getGraph()->viewportToContents(0, 0, myX, myY);
547   }
548   QDialog::showEvent(theEvent);
549 }
550
551
552 void SUPERVGUI_Service::tabChanged(QWidget* theWidget) {
553   myIsInline = (myTabPane->currentPageIndex() == 1);
554 }
555
556
557
558 //*****************************************************
559 //  Pane for Python script editing
560 //*****************************************************
561 SUPERVGUI_PythonEditPane::SUPERVGUI_PythonEditPane(QWidget* theParent) 
562   : QFrame(theParent),
563     myIStream(0)
564 {
565   QGridLayout* aEditLayout = new QGridLayout(this, 2, 4);
566
567   // First row
568   QPushButton* aLoadBtn = new QPushButton(tr("BUT_LOAD"), this);
569   connect(aLoadBtn, SIGNAL(clicked()), this, SLOT(loadFile()));
570   
571   aEditLayout->addWidget(aLoadBtn, 0, 2);
572
573   myNextBtn = new QPushButton(tr("BUT_NEXT"), this);
574   myNextBtn->setEnabled(false);
575   connect(myNextBtn, SIGNAL(clicked()), this, SLOT(readFunction()));
576   
577   aEditLayout->addWidget(myNextBtn, 0, 3);
578   
579   //Second row
580   myText = new QTextEdit(this);
581   myText->setWordWrap(QTextEdit::FixedColumnWidth);
582   myText->setWrapColumnOrWidth(80);
583
584   aEditLayout->addMultiCellWidget(myText, 1, 1, 0, 3);
585 }
586    
587
588 /**
589  * Load existing Python script
590  */
591 void SUPERVGUI_PythonEditPane::loadFile() {
592   QString aFileName = QAD_FileDlg::getFileName(QAD_Application::getDesktop(),
593                                                "",
594                                                "*.py",
595                                                tr("TIT_LOADSCRIPT"),
596                                                true);
597   if (aFileName.isEmpty()) return;
598
599   myFile = new QFile(aFileName);
600   if (!myFile->open(IO_ReadOnly)) {
601     QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), 
602                          tr("MSG_CANT_LOADSCRIPT"));
603     return;
604   }
605   myIStream = new QTextStream(myFile);
606
607   if (myIStream->atEnd()) {
608     QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), 
609                          tr("MSG_EMTY_FILE"));
610     myNextBtn->setEnabled(false);
611     delete myIStream;
612     myIStream = 0;
613     myFile->close();
614     delete myFile;
615     return;
616   }
617   myNextBtn->setEnabled(true);
618   readFunction();
619 }
620   
621
622 /**
623  * Finds and Reads a function from current position in the opened file
624  */
625 void SUPERVGUI_PythonEditPane::readFunction() {
626   if (!myIStream) return;
627
628   while (!myIStream->atEnd()) {
629     QString aLine = myIStream->readLine();
630     if (aLine.isNull()) return;
631
632     // find first function
633     int aDefPos = aLine.find("def");
634     if (aDefPos == 0) { // only not a class members
635       myText->clear();
636       // find name
637       /*int aStart = aLine.find(" ", aDefPos);
638       int aEnd = aLine.find("(", aStart);
639       QString aName = aLine.mid(aStart, (aEnd-aStart));
640       aName = aName.stripWhiteSpace();
641       myNameEdt->setText(aName);*/
642       
643       // find input params
644       /*aStart = aEnd+1;
645       aEnd = aLine.find(")", aStart);
646       QString aParams = aLine.mid(aStart, (aEnd-aStart));
647       aParams = aParams.stripWhiteSpace();
648       myParamEdt->setText(aParams);*/
649
650       myText->append(aLine);
651       // read body
652       QString aBodyLine = myIStream->readLine();
653       while ((!aBodyLine.isNull()) && aBodyLine[0].isSpace()) {
654         myText->append(aBodyLine);
655         aBodyLine = myIStream->readLine();
656       }
657       return;
658     }
659   }
660   QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), 
661                          tr("MSG_NOMORE_FUNCTIONS"));
662   delete myIStream;
663   myIStream = 0;
664   myNextBtn->setEnabled(false);
665   myFile->close();
666   delete myFile;
667 }
668
669
670 QString SUPERVGUI_PythonEditPane::getFuncName() {
671   QString aName("");
672   for (int i=0; i < myText->paragraphs(); i++) {
673     QString aLine = myText->text(i);
674     int aDefPos = aLine.find("def");
675     if (aDefPos == 0) {
676       int aStart = aLine.find(" ", aDefPos);
677       int aEnd = aLine.find("(", aStart);
678       QString aName = aLine.mid(aStart, (aEnd-aStart));
679       return aName.stripWhiteSpace();
680     }
681   }
682   return aName;
683 }
684
685
686 SUPERV_Strings SUPERVGUI_PythonEditPane::getFunction() {
687   SUPERV_Strings aStrings = new SUPERV::ListOfStrings();
688   aStrings->length(myText->paragraphs());
689   for (int i=0; i < myText->paragraphs(); i++) {
690     aStrings[i] = CORBA::string_dup(myText->text(i).latin1());
691   }
692   return aStrings._retn();
693 }
694
695
696 void SUPERVGUI_PythonEditPane::setFunction(SUPERV_Strings theStr) {
697   int aLen = theStr->length();
698   for (int i=0; i < aLen; i++)
699     myText->append(QString(theStr[i]));
700 }
701
702
703
704 /*!
705  * Edit Python dialog
706  */
707 SUPERVGUI_EditPythonDlg::SUPERVGUI_EditPythonDlg(bool isLoop)
708   :QDialog(QAD_Application::getDesktop(), 0, true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu)
709 {
710   setSizeGripEnabled( true );
711   setCaption(tr("TIT_FUNC_PYTHON"));
712   resize( 500, 250 );
713   QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 4);
714   if (isLoop) {
715     QTabWidget* aLoopTabPane = new QTabWidget(this);
716     myInitPane = new SUPERVGUI_PythonEditPane(this); 
717     aLoopTabPane->addTab(myInitPane, "Init");
718     
719     myMorePane = new SUPERVGUI_PythonEditPane(this);
720     aLoopTabPane->addTab(myMorePane, "More");
721     
722     myNextPane = new SUPERVGUI_PythonEditPane(this);
723     aLoopTabPane->addTab(myNextPane, "Next");
724
725     aMainLayout->addWidget(aLoopTabPane);    
726   } else {
727     myEditPane = new SUPERVGUI_PythonEditPane(this);
728     aMainLayout->addWidget(myEditPane);
729   }
730   QGroupBox* aBtnBox = new QGroupBox( this );
731   aBtnBox->setColumnLayout( 0, Qt::Vertical );
732   aBtnBox->layout()->setSpacing( 0 ); aBtnBox->layout()->setMargin( 0 );
733   QHBoxLayout* aBtnLayout = new QHBoxLayout( aBtnBox->layout() );
734   aBtnLayout->setAlignment( Qt::AlignTop );
735   aBtnLayout->setSpacing( 6 ); aBtnLayout->setMargin( 11 );
736   
737   QPushButton* aOKBtn = new QPushButton( tr( "BUT_OK" ), aBtnBox );
738   connect( aOKBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
739   aBtnLayout->addWidget( aOKBtn );
740
741   aBtnLayout->addStretch();
742
743   QPushButton* aCancelBtn = new QPushButton( tr("BUT_CANCEL"), aBtnBox );
744   connect( aCancelBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
745   aBtnLayout->addWidget( aCancelBtn );
746
747   aMainLayout->addWidget(aBtnBox);
748 }