Salome HOME
NRI : Merge from V1_2.
[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   QPushButton* aComputeCBtn = new QPushButton(tr("TIT_ADDCNODE"), aCorbaPane); //!!
131   connect(aComputeCBtn, SIGNAL(clicked()), this, SLOT(addComputeNode())); //!!
132
133   QPushButton* aComputeBtn = new QPushButton(tr("TIT_ADDFNODE"), aCorbaPane);
134   connect(aComputeBtn, SIGNAL(clicked()), this, SLOT(addFactoryNode()));
135
136   aBaseLayout->addWidget(aComputeBtn);
137   aBaseLayout->addWidget(aComputeCBtn); //!!
138
139   aBaseLayoutV->insertLayout(-1, aBaseLayout);
140   myTabPane->addTab(aCorbaPane, tr("MODULES_PANE"));
141
142
143   // Create Tab for Python services
144   QWidget* aPythonPane = new QWidget(myTabPane);
145   QVBoxLayout* aPythonLayout = new QVBoxLayout(aPythonPane, 0, 4);
146   aPythonLayout->setMargin(5);
147   aPythonLayout->setSpacing(10);
148
149   // Type pane
150   QHGroupBox* aAddBox2 = new QHGroupBox(tr("TIT_ADDNODE"), aPythonPane);
151   aAddBox2->setInsideSpacing(20);
152
153   QLabel* aTypeLbl = new QLabel(tr("LBL_NODETYPE"), aAddBox2);
154
155   myTypeCombo = new QComboBox(aAddBox2);
156   myTypeCombo->insertItem("Computation");
157   myTypeCombo->insertItem("Switch");
158   myTypeCombo->insertItem("Loop");
159   myTypeCombo->insertItem("GoTo");
160   //myTypeCombo->insertItem("Label");
161   connect(myTypeCombo, SIGNAL(activated(int)), this, SLOT(typeNodeSelected(int)));
162
163   aPythonLayout->addWidget(aAddBox2);
164
165   // Edit pane
166   myStackWidget = new QWidgetStack(aPythonPane);
167
168   // other pane
169   myScriptPane = new SUPERVGUI_PythonEditPane(myStackWidget);
170   myOtherId = myStackWidget->addWidget(myScriptPane);
171
172   // loop pane
173   QTabWidget* aLoopTabPane = new QTabWidget(myStackWidget);
174   myInitPane = new SUPERVGUI_PythonEditPane(myStackWidget); 
175   aLoopTabPane->addTab(myInitPane, "Init");
176
177   myMorePane = new SUPERVGUI_PythonEditPane(myStackWidget);
178   aLoopTabPane->addTab(myMorePane, "More");
179
180   myNextPane = new SUPERVGUI_PythonEditPane(myStackWidget);
181   aLoopTabPane->addTab(myNextPane, "Next");
182   myLoopId = myStackWidget->addWidget(aLoopTabPane);
183
184   myStackWidget->raiseWidget(myOtherId);
185
186   aPythonLayout->addWidget(myStackWidget, 1);
187
188   // Create button
189   QPushButton* aCreateBtn = new QPushButton(tr("TIT_ADDNODE"), aPythonPane);
190   connect(aCreateBtn, SIGNAL(clicked()), this, SLOT(addInlineNode()));
191   aPythonLayout->addWidget(aCreateBtn);
192
193   myTabPane->addTab(aPythonPane, tr("INLINE_PANE"));
194
195   aMainLayout->addWidget(myTabPane);
196
197   // Close button
198   QHBox* aBtnBox = new QHBox(this);
199   QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout()); 
200   aBtnLayout->addStretch();
201
202   QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
203   connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(reject()));
204   
205   aMainLayout->addWidget(aBtnBox);
206
207   initialise();
208   myX = 0;
209   myY = 0;
210   myIsInline = false;
211 }
212
213
214
215 void SUPERVGUI_Service::initialise() {
216   CORBA::Object_ptr obj  = naming->Resolve("/Kernel/ModulCatalog");
217   SALOME_ModuleCatalog::ModuleCatalog_var *aModuleCatalog = new SALOME_ModuleCatalog::ModuleCatalog_var;
218   *aModuleCatalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj);
219   if (CORBA::is_nil(*aModuleCatalog)) {
220     setCaption("Error in Connexion to omniNames with '/Kernel/ModulCatalog'");
221     return;
222   }
223   
224   QAD_ResourceMgr* aResMgr = QAD_Desktop::createResourceManager();
225
226   SALOME_ModuleCatalog::ListOfComponents_var lComponents = (*aModuleCatalog)->GetComponentList();
227   long nbComp = lComponents->length();
228   for (int i=0; i<nbComp; i++) {
229     SALOME_ModuleCatalog::Acomponent_ptr C = (*aModuleCatalog)->GetComponent((char *)lComponents[i]);
230     QListViewItem* myComponentItem = new QListViewItem(components, (char*)lComponents[i]);
231     myComponentItem->setSelectable(false);
232     QString aIconName = C->component_icone();
233     if (!aIconName.isEmpty()) {
234       QString resDir = aResMgr->findFile(aIconName, C->componentname()) ;
235       if (resDir) {
236         resDir = QAD_Tools::addSlash(resDir);
237         QPixmap aIcone(resDir + aIconName);
238         QIconSet aIconSet(aIcone);
239         myComponentItem->setPixmap(0, aIconSet.pixmap(QIconSet::Small, QIconSet::Normal));
240       } else {
241         myComponentItem->setPixmap(0, ComponentIcon);
242       }
243     } else {
244       myComponentItem->setPixmap(0, ComponentIcon);
245     }
246     SALOME_ModuleCatalog::ListOfInterfaces* lInterfaces = C->GetInterfaceList();
247     long nbInterf = lInterfaces->length();
248     for (int j=0; j<nbInterf; j++) {
249       SALOME_ModuleCatalog::DefinitionInterface* Interface = C->GetInterface((char*)(*lInterfaces)[j]);
250       QListViewItem* myInterfaceItem = new QListViewItem(myComponentItem, (char*)Interface->interfacename);
251       myInterfaceItem->setSelectable(false);
252       myInterfaceItem->setPixmap(0, InterfaceIcon);
253       
254       long nbServices = Interface->interfaceservicelist.length();
255       for (int k=0; k<nbServices; k++) {
256         SALOME_ModuleCatalog::Service* Service = &(Interface->interfaceservicelist[k]);
257         QListViewItem* myServiceItem = new QListViewItem(myInterfaceItem, (char*)Service->ServiceName);
258         myServiceItem->setSelectable(true);
259         components->ensureItemVisible(myServiceItem);
260         
261         long nbPortsOut = Service->ServiceoutParameter.length();
262         for (int m=0; m<nbPortsOut; m++) {
263           SALOME_ModuleCatalog::ServicesParameter* PortOut = &(Service->ServiceoutParameter[m]);
264           QListViewItem* myPortOutItem = new QListViewItem(myServiceItem, (char*)PortOut->Parametername, (char*)PortOut->Parametertype, "Out");
265           myPortOutItem->setSelectable(false);
266         }
267         
268         long nbPortsIn = Service->ServiceinParameter.length();
269         for (int l=0; l<nbPortsIn; l++) {
270           SALOME_ModuleCatalog::ServicesParameter* PortIn = &(Service->ServiceinParameter[l]);
271           QListViewItem* myPortInItem = new QListViewItem(myServiceItem, (char*)PortIn->Parametername, (char*)PortIn->Parametertype, "In");
272           myPortInItem->setSelectable(false);
273         }
274       }
275     }
276   }
277 }
278
279
280
281 SUPERVGUI_Service::~SUPERVGUI_Service() {
282     Trace("SUPERVGUI_Service::~SUPERVGUI_Service")
283 }
284
285 void SUPERVGUI_Service::addComputeNode() {
286   SUPERVGUI_Main* aMain = Supervision.getMain();
287   if (aMain==0) {
288     QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
289   } else {
290     CORBA::Object_ptr obj  = naming->Resolve("/Kernel/ModulCatalog");
291     SALOME_ModuleCatalog::ModuleCatalog_var* aModuleCatalog = new SALOME_ModuleCatalog::ModuleCatalog_var;
292     *aModuleCatalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj);
293     if (CORBA::is_nil(*aModuleCatalog)) {
294       QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE"));
295     } else {
296       QListViewItem*        item;
297       bool                  b = false;
298       QListViewItemIterator i(components);
299       for (; i.current(); ++i) {
300         item = i.current();
301         if (item->isSelected()) {
302           const char* service   = item->text(0).latin1();
303           const char* interface = item->parent()->text(0).latin1();
304           const char* component = item->parent()->parent()->text(0).latin1();
305           SALOME_ModuleCatalog::Acomponent_ptr myComponent = (*aModuleCatalog)->GetComponent(component);
306           if (myComponent==NULL) {
307             QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE"));
308           } else {
309             const SALOME_ModuleCatalog::Service* myService = myComponent->GetService(interface, service);
310             b  = true;
311             
312             SUPERV_CNode node = aMain->getDataflow()->CNode(*myService);
313             if (CORBA::is_nil(node)) {
314               QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));   
315               return;
316             }
317             node->Coords(myX, myY);
318             myX += NODE_DX;
319             myY += NODE_DY;
320             aMain->addComputeNode(SUPERV::CNode::_narrow(node));
321           }
322         }
323       }
324       if (!b) {
325         QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), tr("MSG_NONODE_TOADD"));
326       }
327     }
328   }
329 }
330
331 void SUPERVGUI_Service::addFactoryNode() {
332   SUPERVGUI_Main* aMain = Supervision.getMain();
333   if (aMain==0) {
334     QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
335   } else {
336     CORBA::Object_ptr obj  = naming->Resolve("/Kernel/ModulCatalog");
337     SALOME_ModuleCatalog::ModuleCatalog_var* aModuleCatalog = new SALOME_ModuleCatalog::ModuleCatalog_var;
338     *aModuleCatalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj);
339     if (CORBA::is_nil(*aModuleCatalog)) {
340       QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE"));
341     } else {
342       QListViewItem*        item;
343       bool                  b = false;
344       QListViewItemIterator i(components);
345       for (; i.current(); ++i) {
346         item = i.current();
347         if (item->isSelected()) {
348           const char* service   = item->text(0).latin1();
349           const char* interface = item->parent()->text(0).latin1();
350           const char* component = item->parent()->parent()->text(0).latin1();
351           SALOME_ModuleCatalog::Acomponent_ptr myComponent = (*aModuleCatalog)->GetComponent(component);
352           if (myComponent==NULL) {
353             QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE"));
354           } else {
355             const SALOME_ModuleCatalog::Service* myService = myComponent->GetService(interface, service);
356             b  = true;
357             
358             SUPERV_FNode node = aMain->getDataflow()->FNode(component, interface, *myService);
359             if (CORBA::is_nil(node)) {
360               QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));   
361               return;
362             }
363             node->Coords(myX, myY);
364             myX += NODE_DX;
365             myY += NODE_DY;
366             aMain->addComputeNode(SUPERV::CNode::_narrow(node));
367           }
368         }
369       }
370       if (!b) {
371         QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), tr("MSG_NONODE_TOADD"));
372       }
373     }
374   }
375 }
376
377
378 void SUPERVGUI_Service::addInlineNode() {
379   SUPERVGUI_Main* aMain = Supervision.getMain();
380   if (aMain==0) {
381     QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW"));
382   } else {
383     int aSel = myTypeCombo->currentItem();
384     switch (aSel) {
385     case 0: // Computation
386       if (myScriptPane->isDefined()) {  
387         SUPERV_INode aNode = aMain->getDataflow()->INode(myScriptPane->getFuncName().latin1(), 
388                                                          (myScriptPane->getFunction()).in());
389         if (CORBA::is_nil(aNode)) {
390           QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
391           return;
392         }
393         aNode->Coords(myX, myY);
394         myX += NODE_DX;
395         myY += NODE_DY;
396         aMain->addComputeNode(SUPERV::CNode::_narrow(aNode));
397       }
398       break;
399       
400     case 1: // Switch
401       if (myScriptPane->isDefined()) {
402         SUPERV_INode aEndNode;
403         SUPERV_SNode aStartNode = aMain->getDataflow()->SNode(myScriptPane->getFuncName().latin1(),
404                                                               (myScriptPane->getFunction()).in(),
405                                                               aEndNode);
406         if (CORBA::is_nil(aStartNode) || CORBA::is_nil(aEndNode)) {
407           QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
408           return;
409         }
410         aStartNode->Coords(myX, myY);
411         aEndNode->Coords(myX + LABEL_WIDTH*2, myY);
412         myX += NODE_DX;
413         myY += NODE_DY;
414         aMain->addControlNode(SUPERV::CNode::_narrow(aStartNode), SUPERV::CNode::_narrow(aEndNode));
415       }
416       break;
417       
418     case 2: // Loop
419       {
420         SUPERV_INode aEndNode;
421         SUPERV_LNode aStartNode = aMain->getDataflow()->LNode(myInitPane->getFuncName().latin1(), (myInitPane->getFunction()).in(),
422                                                               myMorePane->getFuncName().latin1(), (myMorePane->getFunction()).in(),
423                                                               myNextPane->getFuncName().latin1(), (myNextPane->getFunction()).in(),
424                                                               aEndNode);
425         if (CORBA::is_nil(aStartNode) || CORBA::is_nil(aEndNode)) {
426           QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
427           return;
428         }
429         aStartNode->Coords(myX, myY);
430         aEndNode->Coords(myX + LABEL_WIDTH*2, myY);
431         myX += NODE_DX;
432         myY += NODE_DY;
433         aMain->addControlNode(SUPERV::CNode::_narrow(aStartNode), SUPERV::CNode::_narrow(aEndNode));
434       }
435       break;
436       
437     case 3: // GoTo
438       {
439         SUPERV_GNode aGotoNode;
440         if (myScriptPane->isDefined()) 
441           aGotoNode = aMain->getDataflow()->GNode(myScriptPane->getFuncName().latin1(), 
442                                                   (myScriptPane->getFunction()).in(), "");
443         else
444           aGotoNode = aMain->getDataflow()->GNode("GoTo", (myScriptPane->getFunction()).in(), "");
445         if (CORBA::is_nil(aGotoNode)) {
446           QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));       
447           return;
448         }
449         aGotoNode->Coords(myX, myY);
450         myX += NODE_DX;
451         myY += NODE_DY;
452         aMain->addGOTONode(SUPERV::GNode::_narrow(aGotoNode));
453       }
454       break;
455     }
456   }
457 }
458
459
460
461 void SUPERVGUI_Service::typeNodeSelected(int theRow) {
462   if (theRow == 2)
463     myStackWidget->raiseWidget(myLoopId);
464   else
465     myStackWidget->raiseWidget(myOtherId);
466 }
467
468
469
470 void SUPERVGUI_Service::choose() {
471     Trace("SUPERVGUI_Service::choose")
472     show();
473     raise();
474 }
475     
476
477 void SUPERVGUI_Service::showEvent(QShowEvent* theEvent) {
478   SUPERVGUI_Main* aMain = Supervision.getMain();
479   if (aMain && (!aMain->isArrayShown())) {
480     aMain->getGraph()->viewportToContents(0, 0, myX, myY);
481   }
482   QDialog::showEvent(theEvent);
483 }
484
485
486 void SUPERVGUI_Service::tabChanged(QWidget* theWidget) {
487   myIsInline = (myTabPane->currentPageIndex() == 1);
488 }
489
490
491
492 //*****************************************************
493 //  Pane for Python script editing
494 //*****************************************************
495 SUPERVGUI_PythonEditPane::SUPERVGUI_PythonEditPane(QWidget* theParent) 
496   : QFrame(theParent),
497     myIStream(0)
498 {
499   QGridLayout* aEditLayout = new QGridLayout(this, 2, 4);
500
501   // First row
502   QPushButton* aLoadBtn = new QPushButton(tr("BUT_LOAD"), this);
503   connect(aLoadBtn, SIGNAL(clicked()), this, SLOT(loadFile()));
504   
505   aEditLayout->addWidget(aLoadBtn, 0, 2);
506
507   myNextBtn = new QPushButton(tr("BUT_NEXT"), this);
508   myNextBtn->setEnabled(false);
509   connect(myNextBtn, SIGNAL(clicked()), this, SLOT(readFunction()));
510   
511   aEditLayout->addWidget(myNextBtn, 0, 3);
512   
513   //Second row
514   myText = new QTextEdit(this);
515   myText->setWordWrap(QTextEdit::FixedColumnWidth);
516   myText->setWrapColumnOrWidth(80);
517
518   aEditLayout->addMultiCellWidget(myText, 1, 1, 0, 3);
519 }
520    
521
522 /**
523  * Load existing Python script
524  */
525 void SUPERVGUI_PythonEditPane::loadFile() {
526   QString aFileName = QAD_FileDlg::getFileName(QAD_Application::getDesktop(),
527                                                "",
528                                                "*.py",
529                                                tr("TIT_LOADSCRIPT"),
530                                                true);
531   if (aFileName.isEmpty()) return;
532
533   myFile = new QFile(aFileName);
534   if (!myFile->open(IO_ReadOnly)) {
535     QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), 
536                          tr("MSG_CANT_LOADSCRIPT"));
537     return;
538   }
539   myIStream = new QTextStream(myFile);
540
541   if (myIStream->atEnd()) {
542     QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), 
543                          tr("MSG_EMTY_FILE"));
544     myNextBtn->setEnabled(false);
545     delete myIStream;
546     myIStream = 0;
547     myFile->close();
548     delete myFile;
549     return;
550   }
551   myNextBtn->setEnabled(true);
552   readFunction();
553 }
554   
555
556 /**
557  * Finds and Reads a function from current position in the opened file
558  */
559 void SUPERVGUI_PythonEditPane::readFunction() {
560   if (!myIStream) return;
561
562   while (!myIStream->atEnd()) {
563     QString aLine = myIStream->readLine();
564     if (aLine.isNull()) return;
565
566     // find first function
567     int aDefPos = aLine.find("def");
568     if (aDefPos == 0) { // only not a class members
569       myText->clear();
570       // find name
571       /*int aStart = aLine.find(" ", aDefPos);
572       int aEnd = aLine.find("(", aStart);
573       QString aName = aLine.mid(aStart, (aEnd-aStart));
574       aName = aName.stripWhiteSpace();
575       myNameEdt->setText(aName);*/
576       
577       // find input params
578       /*aStart = aEnd+1;
579       aEnd = aLine.find(")", aStart);
580       QString aParams = aLine.mid(aStart, (aEnd-aStart));
581       aParams = aParams.stripWhiteSpace();
582       myParamEdt->setText(aParams);*/
583
584       myText->append(aLine);
585       // read body
586       QString aBodyLine = myIStream->readLine();
587       while ((!aBodyLine.isNull()) && aBodyLine[0].isSpace()) {
588         myText->append(aBodyLine);
589         aBodyLine = myIStream->readLine();
590       }
591       return;
592     }
593   }
594   QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), 
595                          tr("MSG_NOMORE_FUNCTIONS"));
596   delete myIStream;
597   myIStream = 0;
598   myNextBtn->setEnabled(false);
599   myFile->close();
600   delete myFile;
601 }
602
603
604 QString SUPERVGUI_PythonEditPane::getFuncName() {
605   QString aName("");
606   for (int i=0; i < myText->paragraphs(); i++) {
607     QString aLine = myText->text(i);
608     int aDefPos = aLine.find("def");
609     if (aDefPos == 0) {
610       int aStart = aLine.find(" ", aDefPos);
611       int aEnd = aLine.find("(", aStart);
612       QString aName = aLine.mid(aStart, (aEnd-aStart));
613       return aName.stripWhiteSpace();
614     }
615   }
616   return aName;
617 }
618
619
620 SUPERV_Strings SUPERVGUI_PythonEditPane::getFunction() {
621   SUPERV_Strings aStrings = new SUPERV::ListOfStrings();
622   aStrings->length(myText->paragraphs());
623   for (int i=0; i < myText->paragraphs(); i++) {
624     aStrings[i] = CORBA::string_dup(myText->text(i).latin1());
625   }
626   return aStrings._retn();
627 }
628
629
630 void SUPERVGUI_PythonEditPane::setFunction(SUPERV_Strings theStr) {
631   int aLen = theStr->length();
632   for (int i=0; i < aLen; i++)
633     myText->append(QString(theStr[i]));
634 }
635
636
637
638 /*!
639  * Edit Python dialog
640  */
641 SUPERVGUI_EditPythonDlg::SUPERVGUI_EditPythonDlg(bool isLoop)
642   :QDialog(QAD_Application::getDesktop(), 0, true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu)
643 {
644   setSizeGripEnabled( true );
645   setCaption(tr("TIT_FUNC_PYTHON"));
646   resize( 500, 250 );
647   QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 4);
648   if (isLoop) {
649     QTabWidget* aLoopTabPane = new QTabWidget(this);
650     myInitPane = new SUPERVGUI_PythonEditPane(this); 
651     aLoopTabPane->addTab(myInitPane, "Init");
652     
653     myMorePane = new SUPERVGUI_PythonEditPane(this);
654     aLoopTabPane->addTab(myMorePane, "More");
655     
656     myNextPane = new SUPERVGUI_PythonEditPane(this);
657     aLoopTabPane->addTab(myNextPane, "Next");
658
659     aMainLayout->addWidget(aLoopTabPane);    
660   } else {
661     myEditPane = new SUPERVGUI_PythonEditPane(this);
662     aMainLayout->addWidget(myEditPane);
663   }
664   QGroupBox* aBtnBox = new QGroupBox( this );
665   aBtnBox->setColumnLayout( 0, Qt::Vertical );
666   aBtnBox->layout()->setSpacing( 0 ); aBtnBox->layout()->setMargin( 0 );
667   QHBoxLayout* aBtnLayout = new QHBoxLayout( aBtnBox->layout() );
668   aBtnLayout->setAlignment( Qt::AlignTop );
669   aBtnLayout->setSpacing( 6 ); aBtnLayout->setMargin( 11 );
670   
671   QPushButton* aOKBtn = new QPushButton( tr( "BUT_OK" ), aBtnBox );
672   connect( aOKBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
673   aBtnLayout->addWidget( aOKBtn );
674
675   aBtnLayout->addStretch();
676
677   QPushButton* aCancelBtn = new QPushButton( tr("BUT_CANCEL"), aBtnBox );
678   connect( aCancelBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
679   aBtnLayout->addWidget( aCancelBtn );
680
681   aMainLayout->addWidget(aBtnBox);
682 }