]> SALOME platform Git repositories - modules/superv.git/blob - src/SUPERVGUI/SUPERVGUI_Main.cxx
Salome HOME
DCQ : Merge with Ecole_Ete_a6.
[modules/superv.git] / src / SUPERVGUI / SUPERVGUI_Main.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_Main.cxx
25 //  Author : Francis KLOSS
26 //  Module : SUPERV
27
28 using namespace std;
29 #include "QAD_Splitter.h"
30 #include "QAD_LeftFrame.h"
31 #include "QAD_ObjectBrowser.h"
32 #include "QAD_ObjectBrowserItem.h"
33 #include "QAD_PyEditor.h"
34 #include "QAD_Message.h"
35 #include "QAD_FileDlg.h"
36 #include "QAD_Application.h"
37 #include "SUPERVGUI_Def.h"
38 #include "QAD_RightFrame.h"
39 #include "SALOME_Event.hxx"
40 #include "SUPERVGraph_ViewFrame.h"
41 #include <qlayout.h>
42 #include <qfile.h>
43 #include "SUPERVGUI_Main.h"
44 #include "SUPERVGUI.h"
45 #include "SUPERVGUI_ComputeNode.h"
46 #include "SUPERVGUI_ControlNode.h"
47 #include "NOTIFICATION.hxx"
48 #include "SUPERVGUI_Notification.h"
49 #include "SALOMEGUI_ImportOperation.h"
50 #include "SUPERVGUI_Information.h"
51
52
53 SUPERVGUI_Main::SUPERVGUI_Main(SUPERVGraph_ViewFrame* theParent, QAD_Desktop* theDesktop, bool fromIOR)
54      : SUPERVGraph_View(theParent), 
55        myLogged( false ),
56        myFiltered( false ),
57        myLogFileName( QString::null ),
58        myLogFile( NULL ),
59        myWarning( false ),
60        myStep( false ),
61        myTrace( false ),
62        myVerbose( false )
63 {
64   Trace("SUPERVGUI_Main::SUPERVGUI_Main (new)");
65   theParent->setViewWidget(this); 
66   if (fromIOR) {
67     //SUPERVGUI_Main* am = Supervision.getMain();
68     QAD_ObjectBrowser* ob = ((QAD_StudyFrame*)(theDesktop->getMainFrame()->activeWindow()))->getLeftFrame()->getObjectBrowser();
69     //        if (am == 0) {
70     //  ob = ((QAD_StudyFrame*)(theDesktop->getMainFrame()->activeWindow()))->getLeftFrame()->getObjectBrowser();
71     //} else {
72     //ob = am->objectBrowser;
73     //}; 
74     QAD_ObjectBrowserItem* item = (QAD_ObjectBrowserItem*)(ob->getListView()->currentItem());
75     SALOMEDS::SObject_var obj = theDesktop->getActiveStudy()->getStudyDocument()->FindObjectID(item->getEntry().latin1());
76     SALOMEDS::GenericAttribute_var anAttr;
77     if (obj->FindAttribute(anAttr, "AttributeIOR")) {
78       SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
79       Standard_CString ior = anIOR->Value();
80       dataflow = Supervision.getEngine()->getStreamGraph(ior);
81       if (SUPERV_isNull(dataflow)) {
82         QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_ACCESS_BAD_IOR"));
83         close();
84       } else {
85         init(theDesktop);
86       }
87     } else {
88       QMessageBox::warning(0, tr("ERROR"), tr("MSG_NOACCESS_BY_IOR"));
89       close();
90     }
91   } else {
92     dataflow = Supervision.getEngine()->StreamGraph(MAIN_NEW);
93     if (SUPERV_isNull(dataflow)) {
94       QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_CREATE_DF"));
95       close();
96     } else {
97       init(theDesktop);
98     }
99   }
100 }
101
102 SUPERVGUI_Main::SUPERVGUI_Main(SUPERVGraph_ViewFrame* theParent, QAD_Desktop* theDesktop, bool isModify, const char* f)
103      : SUPERVGraph_View(theParent),
104        myLogged( false ),
105        myFiltered( false ),
106        myLogFileName( QString::null ),
107        myLogFile( NULL ),
108        myWarning( false ),
109        myStep( false ),
110        myTrace( false ),
111        myVerbose( false )
112 {
113   Trace("SUPERVGUI_Main::SUPERVGUI_Main (file)")
114     theParent->setViewWidget(this);  
115   if (isModify) {
116     dataflow = Supervision.getEngine()->StreamGraph(f);
117   } else {
118     dataflow = Supervision.getEngine()->StreamGraphE(f);
119   }
120   if (SUPERV_isNull(dataflow)) {
121     QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_BAD_FILE").arg(f));
122     close();
123   } else {
124     init(theDesktop);
125   }
126 }
127
128 SUPERVGUI_Main::SUPERVGUI_Main(SUPERVGraph_ViewFrame* theParent, QAD_Desktop* theDesktop, SUPERV_Graph cp)
129      : SUPERVGraph_View(theParent),
130        myLogged( false ),
131        myFiltered( false ),
132        myLogFileName( QString::null ),
133        myLogFile( NULL ),
134        myWarning( false ),
135        myStep( false ),
136        myTrace( false ),
137        myVerbose( false )
138 {
139   Trace("SUPERVGUI_Main::SUPERVGUI_Main (copy)");
140   theParent->setViewWidget(this);  
141   //  dataflow = cp->Copy();
142   dataflow = cp;
143   if (SUPERV_isNull(dataflow)) {
144     QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_COPY"));
145     close();
146   } else {
147     init(theDesktop);
148   }
149 }
150
151 void SUPERVGUI_Main::init(QAD_Desktop* theDesktop) {
152   Trace("SUPERVGUI_Main::init");
153   if (theDesktop) myNService = theDesktop->getNameService();
154   myHashCode = "New";
155   myCopyNum = 0;
156   choosing  = false;
157   myIsLocked = false;
158
159   myThread = new SUPERVGUI_Thread();
160   myThread->setMain(this);
161   connect(this, SIGNAL(KillMyThread(bool)), myThread, SLOT(KillThread(bool)));
162
163   myIsKilled = false;
164   //myIsRunned = false;
165   myCurrentView = GRAPH;
166   myIsFromStudy = false;
167   study     = theDesktop->getActiveStudy();
168   
169   SALOMEDS::Study_var studyDoc = study->getStudyDocument();
170   bool aLocked = studyDoc->GetProperties()->IsLocked();
171   SALOMEDS::StudyBuilder_var builder = studyDoc->NewBuilder();
172   SALOMEDS::SComponent_var father = studyDoc->FindComponent(STUDY_SUPERVISION);
173   SALOMEDS::GenericAttribute_var anAttr;
174   SALOMEDS::AttributeName_var    aName;
175   SALOMEDS::AttributePixMap_var  aPixmap;
176   if (father->_is_nil()) {
177     QAD_Operation* op = new SALOMEGUI_ImportOperation( study );
178     op->start();
179     if (aLocked) studyDoc->GetProperties()->SetLocked(false);
180     father = builder->NewComponent(STUDY_SUPERVISION);
181     anAttr = builder->FindOrCreateAttribute(father, "AttributeName");
182     aName = SALOMEDS::AttributeName::_narrow(anAttr);
183     //aName->SetValue("Supervision");
184     aName->SetValue(QAD_Application::getDesktop()->getComponentUserName( "SUPERV" ) );
185     
186     anAttr = builder->FindOrCreateAttribute(father, "AttributePixMap");
187     aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
188     aPixmap->SetPixMap( "ICON_OBJBROWSER_Supervision" );
189     
190     builder->DefineComponentInstance(father, Supervision.getEngine());
191     if (aLocked) studyDoc->GetProperties()->SetLocked(true);
192     op->finish();
193   };
194
195   objectBrowser = study->getActiveStudyFrame()->getLeftFrame()->getObjectBrowser();
196     
197
198   graph = new SUPERVGUI_Graph(this);
199   array = new SUPERVGUI_Array(this);
200   
201   message = study->getActiveStudyFrame()->getRightFrame()->getMessage();
202   notification = new NOTIFICATION_Consumer();
203
204   QBoxLayout * layout = new QVBoxLayout(this);
205   layout->setMargin(0);
206   layout->setSpacing(0);
207   layout->addWidget(graph);
208   layout->addWidget(array);
209
210   sync();
211   show();
212   if ( myLogged && !myLogFileName.isEmpty() && QFile::exists( myLogFileName ) ) {
213     myLogFile = fopen( myLogFileName.latin1(), "a" );
214     if (  myLogFile == NULL )
215       myLogged = false;
216   }
217   myTimer = new QTimer( this );
218   connect( myTimer, SIGNAL(timeout()), this, SLOT(checkExecution()) );
219 }
220
221 SUPERVGUI_Main::~SUPERVGUI_Main() {
222   Trace("SUPERVGUI_Main::~SUPERVGUI_Main");
223   if ( myLogFile != NULL) {
224     fclose( myLogFile );
225   }
226   graph->removeLinks();
227   delete notification; // kloss : nota bene : quand un datalow est detruit : verifier que les canaux de notification sont aussi detruit
228   if (!SUPERV_isNull(dataflow)) {
229     if (dataflow->IsExecuting()) {
230       if (QMessageBox::warning(QAD_Application::getDesktop(),
231                                tr("WARNING"), 
232                                tr("MSG_DF_RUNNING"), 
233                                tr("MSG_DF_EXECUTION"), 
234                                tr("MSG_DF_KILL")) == 1) {
235         if (dataflow->Kill()) {
236           if (myThread->running()) 
237             myThread->wait();
238         }
239       }
240       else {
241         emit KillMyThread(true);
242         if (myThread->running()) 
243           myThread->wait();
244       }
245     }
246     else {
247       emit KillMyThread(true);
248       if (myThread->running()) 
249         myThread->wait();
250     }
251   }
252 }
253
254 void SUPERVGUI_Main::filterNotification() {
255   Trace("SUPERVGUI_Main::filterNotification");
256   SUPERVGUI_Notification* dlg = new SUPERVGUI_Notification(this);
257   dlg->setFiltered( myFiltered );
258   dlg->setLogged( myLogged, myLogFileName );
259   dlg->setWarning( myWarning );
260   dlg->setStep( myStep );
261   dlg->setTrace( myTrace );
262   dlg->setVerbose( myVerbose );
263   if ( dlg->exec() == QDialog::Accepted ) {
264     myLogged      = dlg->getLogged();
265     myLogFileName = dlg->getLogFile();
266     myFiltered    = dlg->getFiltered();
267     myWarning     = dlg->getWarning();
268     myStep        = dlg->getStep();
269     myTrace       = dlg->getTrace();
270     myVerbose     = dlg->getVerbose();
271     delete dlg;
272     if ( myLogFile != NULL) {
273       fclose( myLogFile );
274     }
275     myLogFile = NULL;
276     if ( myLogged && !myLogFileName.isEmpty() && QFile::exists( myLogFileName ) ) {
277       myLogFile = fopen( myLogFileName.latin1(), "a" );
278       if (  myLogFile == NULL ) {
279         myLogged = false;
280         QMessageBox::warning( QAD_Application::getDesktop(), tr("ERROR"), tr( "ERR_CANT_OPEN_LOG_FILE" ) );
281       }
282     }
283   }
284 }
285
286 void SUPERVGUI_Main::changeDSGraphParameters() {
287   SUPERVGUI_DSGraphParameters* aDlg = new SUPERVGUI_DSGraphParameters(dataflow, dataflow->IsReadOnly());
288   if (aDlg->exec() )
289     sync();
290   delete aDlg;
291 }
292
293 void SUPERVGUI_Main::syncAsync() {
294     Trace("SUPERVGUI_Main::syncAsync")
295     QTimer::singleShot(1, this, SLOT(sync()));
296 }
297
298
299 /**
300  * Called by thread when dataflow is executing
301  */
302 void SUPERVGUI_Main::execute(char *  theNodeName, SUPERV::GraphState theNodeState) {
303   
304   SUPERVGUI_Node* aNodePrs; 
305   SUPERVGUI_GraphNode* aGraphNodePrs;
306   if (myCurrentView == TABLE) {
307     aNodePrs = (SUPERVGUI_Node*) array->child(theNodeName, "SUPERVGUI_Node");
308     aGraphNodePrs = (SUPERVGUI_GraphNode*) array->child(theNodeName, "SUPERVGUI_GraphNode");
309   } else {
310     aNodePrs = (SUPERVGUI_Node*) graph->child(theNodeName, "SUPERVGUI_Node");
311     aGraphNodePrs = (SUPERVGUI_GraphNode*) graph->child(theNodeName, "SUPERVGUI_GraphNode");
312   }
313   if (aGraphNodePrs) {
314     aGraphNodePrs->sync();
315   }
316   else if (aNodePrs) {
317     //aNodePrs->sync();
318     aNodePrs->syncOnEvent(theNodeState);
319   }
320 }
321
322
323
324 void SUPERVGUI_Main::sync() {
325     Trace("SUPERVGUI_Main::sync")
326     if ((SUPERV_isNull(dataflow))) return;
327     QString t = tr("GRAPH_TITLE");
328     
329     t += dataflow->Name();
330     setCaption(t);
331
332     study->updateObjBrowser();
333     if (myCurrentView == TABLE) {
334         array->sync();
335     } else {
336         graph->sync();
337     }
338 }
339
340
341 void SUPERVGUI_Main::showTable() {
342   if (myCurrentView == TABLE) return;
343
344   if (array->create()) {
345     myCurrentView = TABLE;
346     graph->hide();
347   }
348   sync();
349 }
350
351
352 void SUPERVGUI_Main::showFullGraph() {
353   if (myCurrentView == TABLE) {
354     array->destroy();
355     graph->show();    
356   }
357   myCurrentView = GRAPH;
358   graph->sync();
359   graph->setFullView();
360 }
361
362
363 void SUPERVGUI_Main::showContolFlow() {
364   if (myCurrentView == TABLE) {
365     array->destroy();
366     graph->show();    
367   }
368   myCurrentView = CONTROLFLOW;
369   graph->sync();
370   graph->setControlView();
371 }
372
373
374 bool SUPERVGUI_Main::exportDataflow(QString theFile) {
375   Trace("SUPERVGUI_Main::exportDataflow");
376   if ((SUPERV_isNull(dataflow))) return false;
377
378   if (!theFile.isEmpty()) {
379     if (!dataflow->Export(theFile.latin1())) {
380       QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_BAD_WRITING"));
381       return false;
382     }
383   }
384   return true;
385 }
386
387 void SUPERVGUI_Main::insertFile() {
388     Trace("SUPERVGUI_Main::insertFile")
389     if ((SUPERV_isNull(dataflow))) return;
390
391     QString f = QAD_FileDlg::getFileName(QAD_Application::getDesktop(),
392                                          "",
393                                          "*.xml",
394                                          tr("MSG_GRAPH_INSERT"),
395                                          true);
396     if (!f.isEmpty()) {
397         if (dataflow->Import(f.latin1())) {
398           if (myCurrentView == TABLE) {
399             array->destroy();
400             array->create();
401           }
402           sync();
403         } else {
404             QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_BAD_FILE").arg(f));
405         };
406     };
407 }
408
409 void SUPERVGUI_Main::copy() {
410   Trace("SUPERVGUI_Main::copy");
411   if (dataflow->ThreadsMax() == 0) {
412     QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), tr("MSG_NOTHING_COPY"));
413     return;
414   }
415   QAD_StudyFrame* aStudyFrame = Supervision.createGraph();
416   SUPERVGraph_ViewFrame* aViewFrame = dynamic_cast<SUPERVGraph_ViewFrame*>
417     (aStudyFrame->getRightFrame()->getViewFrame());
418   if(aViewFrame){
419     SUPERV_Graph aNewGraph = dataflow->StreamCopy();
420     QString aNewName(tr("MSG_COPY_PREFIX").arg(++myCopyNum));
421     aNewName += dataflow->Name();
422     aNewGraph->SetName(aNewName);
423     SUPERVGUI_Main* m = new SUPERVGUI_Main(aViewFrame, 
424                                            Supervision.getDesktop(), 
425                                            aNewGraph);
426     study->showFrame(aStudyFrame);
427   }
428 }
429
430 void SUPERVGUI_Main::run() {
431   Trace("SUPERVGUI_Main::run")
432     if ((SUPERV_isNull(dataflow))) return;
433   
434   if (dataflow->IsEditing()) {
435     if (!dataflow->IsValid()) {
436       QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_DF_NOTVALID"));
437     } else if (!dataflow->IsExecutable()) {
438       QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_DF_NOTEXECUTABLE"));
439     } else if (graph->isAnyLinkCreating()) {
440       QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CRL_NOTCOMPLETE"));
441     } else {
442       myRunTime = QDateTime::currentDateTime();
443       if (myIsKilled) {
444       //if (myIsRunned) {
445         if (!dataflow->ReRun()) {
446           QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_DF_BADEXECUTE"));
447           if (dataflow->State() == SUPERV::ErrorState) {
448             kill();
449           }
450         } else {
451           myThread->startThread(tr("MSG_GRAPH_STARTED"));
452           sync();
453         }
454       } else {
455         if (!dataflow->Run()) {
456           QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_DF_BADEXECUTE"));
457           if (dataflow->State() == SUPERV::ErrorState) {
458             kill();
459           }
460         } else {
461           myThread->startThread(tr("MSG_GRAPH_STARTED"));
462           sync();
463         }
464       }
465     }
466   } else {
467     QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_DF_RUNNING"));
468   }
469 }
470
471
472
473 void SUPERVGUI_Main::startExecute() {
474   Trace("SUPERVGUI_Main::startExecute")
475   if ((SUPERV_isNull(dataflow))) return;
476   
477   if (dataflow->IsEditing()) {
478     if (!dataflow->IsValid()) {
479       QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_DF_NOTVALID"));
480     } else if (!dataflow->IsExecutable()) {
481       QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_DF_NOTEXECUTABLE"));
482     } else if (graph->isAnyLinkCreating()) {
483       QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CRL_NOTCOMPLETE"));
484     } else {
485       myRunTime = QDateTime::currentDateTime();
486       if (myIsKilled) {
487       //if (myIsRunned) {
488         if (!dataflow->ReStart()) {
489           QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_DF_BADEXECUTE"));
490         } else {
491           myThread->startThread(tr("MSG_GRAPH_STARTED"));
492         }
493       }
494       else {
495         if (!dataflow->Start()) {
496           QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_DF_BADEXECUTE"));
497         } else {
498           myThread->startThread(tr("MSG_GRAPH_STARTED"));
499         }
500       }
501     }
502   } else {
503     QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_DF_RUNNING"));
504   }
505 }
506
507
508 void SUPERVGUI_Main::kill() {
509     Trace("SUPERVGUI_Main::kill")
510     if ((SUPERV_isNull(dataflow))) return;
511
512     if (dataflow->IsEditing()) {
513       QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_DF_NOTRUNNING"));
514     } else if (dataflow->Kill()) {
515       myIsKilled = true;
516       myThread->stopThread(tr("MSG_GRAPH_KILLED"));
517       sync();
518     } else {
519       QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANTKILL_DF"));
520     }
521 }
522
523 void SUPERVGUI_Main::suspendResume() {
524     Trace("SUPERVGUI_Main::suspendResume")
525     if ((SUPERV_isNull(dataflow))) return;
526
527     if (dataflow->IsEditing()) {
528         QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_DF_NOTRUNNING"));
529     } else if (dataflow->State() == SUPERV_Suspend) {
530       if (dataflow->Resume()) {
531         myThread->startThread(tr("MSG_DF_RESUMED"));
532       } else {
533         QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_RESUME"));
534       }
535     } else {
536       if (dataflow->Suspend()) {
537         sync();
538         myThread->stopThread(tr("MSG_GRAPH_SUSPENDED"));
539       } else {
540         QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_SUSPEND"));
541       }
542     }
543 }
544
545 void SUPERVGUI_Main::stopRestart() { // kloss : a reviser et a connecter dans le popup du dataflow (pas de creation de bouton)
546     Trace("SUPERVGUI_Main::stopRestart")
547     if ((SUPERV_isNull(dataflow))) return;
548
549     if (dataflow->IsEditing()) {
550         QMessageBox::warning(0, tr("ERROR"),  tr("MSG_DF_NOTRUNNING"));
551     } else if (dataflow->State() == SUPERV_Stop) {
552         if (dataflow->ReStart()) {
553             message->setMessage(tr("MSG_DF_RESTARTED"));
554             sync();
555         } else {
556             QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_RESTART"));
557         };
558     } else {
559         if (dataflow->Stop()) {
560             sync();
561         } else {
562             QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_STOP"));
563         };
564     };
565 }
566
567 void SUPERVGUI_Main::addNode() {
568   Trace("SUPERVGUI_Main::addNode");
569   if (SUPERV_isNull(dataflow)) return;
570
571   if (dataflow->IsExecuting()) {
572     if (QMessageBox::warning(QAD_Application::getDesktop(), 
573                              tr("WARNING"), tr("MSG_GRAPH_ISRUN"),
574                              QMessageBox::Yes, QMessageBox::No) == QMessageBox::No) {
575       return;        
576     } else {
577       kill();
578     }
579   }
580   Supervision.getBrowser()->choose();
581 }
582
583
584
585 /**
586  * Add Computation node
587  */
588 void SUPERVGUI_Main::addComputeNode(SUPERV_CNode theNode) {
589   //cout<<"### X="<<theNode->X()<<"  Y="<<theNode->Y()<<endl;
590   switch (myCurrentView) {
591   case GRAPH:
592     {
593       SUPERVGUI_Node* aNode = new SUPERVGUI_ComputeNode(graph->viewport(), this, theNode);
594       graph->ResizeGraph(aNode, theNode->X(), theNode->Y());
595       graph->addChild(aNode, theNode->X(), theNode->Y());
596       aNode->sync();
597     }
598     break;
599   case CONTROLFLOW: 
600     {
601       SUPERVGUI_Node* aNode = new SUPERVGUI_ComputeNode(graph->viewport(), this, theNode);
602       aNode->hideAll();
603       graph->ResizeGraph(aNode, theNode->X(), theNode->Y());
604       graph->addChild(aNode, theNode->X(), theNode->Y());
605       aNode->sync();
606     }
607     break;
608   case TABLE:
609     array->destroy();
610     array->create();
611     break;
612   }
613 }
614
615 /**
616  * Add GOTO node
617  */
618 void SUPERVGUI_Main::addGOTONode(SUPERV_CNode theNode) {
619   switch (myCurrentView) {
620   case GRAPH:
621     {
622       SUPERVGUI_Node* aNode = new SUPERVGUI_GotoNode(graph->viewport(), this, theNode);
623       graph->ResizeGraph(aNode, theNode->X(), theNode->Y());
624       graph->addChild(aNode, theNode->X(), theNode->Y());
625       aNode->sync();
626     }
627     break;
628   case CONTROLFLOW: 
629     {
630       SUPERVGUI_Node* aNode = new SUPERVGUI_GotoNode(graph->viewport(), this, theNode);
631       aNode->hideAll();
632       graph->ResizeGraph(aNode, theNode->X(), theNode->Y());
633       graph->addChild(aNode, theNode->X(), theNode->Y());
634       aNode->sync();
635     }
636     break;
637   case TABLE:
638     array->destroy();
639     array->create();
640     break;
641   }
642 }
643
644 /**
645  * Add Control node
646  */
647 void SUPERVGUI_Main::addControlNode(SUPERV_CNode theStartNode, SUPERV_CNode theEndNode, bool Update) {
648   switch (myCurrentView) {
649   case GRAPH:
650     {
651       SUPERVGUI_StartControlNode* aStartPrs = 
652         new SUPERVGUI_StartControlNode(graph->viewport(), this, theStartNode);
653       SUPERVGUI_EndControlNode* aEndPrs = 
654         new SUPERVGUI_EndControlNode(graph->viewport(), this, theEndNode, aStartPrs);
655
656       graph->ResizeGraph(aStartPrs, theStartNode->X(), theStartNode->Y());            
657       graph->addChild(aStartPrs, theStartNode->X(), theStartNode->Y());
658       graph->ResizeGraph(aEndPrs, theEndNode->X(), theEndNode->Y());
659       graph->addChild(aEndPrs, theEndNode->X(), theEndNode->Y());
660       if (Update) {
661         aStartPrs->updateLinksPrs();
662         aEndPrs->updateLinksPrs();
663       }
664       aStartPrs->sync();
665       aEndPrs->sync();
666       graph->repaintContents();
667     }
668     break;
669   case CONTROLFLOW: 
670     {
671       SUPERVGUI_StartControlNode* aStartPrs = 
672         new SUPERVGUI_StartControlNode(graph->viewport(), this, theStartNode);
673       SUPERVGUI_EndControlNode* aEndPrs = 
674         new SUPERVGUI_EndControlNode(graph->viewport(), this, theEndNode, aStartPrs);
675       
676       aStartPrs->hideAll();
677       aEndPrs->hideAll();
678       
679       graph->ResizeGraph(aStartPrs, theStartNode->X(), theStartNode->Y());
680       graph->addChild(aStartPrs, theStartNode->X(), theStartNode->Y());
681       graph->ResizeGraph(aEndPrs, theEndNode->X(), theEndNode->Y());
682       graph->addChild(aEndPrs, theEndNode->X(), theEndNode->Y());
683       if (Update) {
684         aStartPrs->updateLinksPrs();
685         aEndPrs->updateLinksPrs();
686       }
687       aStartPrs->sync();
688       aEndPrs->sync();
689       graph->repaintContents();
690     }
691     break;
692   case TABLE:
693     array->destroy();
694     array->create();
695     break;
696   }
697 }
698
699
700
701 SUPERVGUI_Graph* SUPERVGUI_Main::getGraph() {
702     Trace("SUPERVGUI_Main::getGraph")
703     return(graph);
704 }
705
706 SUPERVGUI_Array* SUPERVGUI_Main::getArray() {
707     Trace("SUPERVGUI_Main::getArray")
708     return(array);
709 }
710
711 SUPERV_Graph SUPERVGUI_Main::getDataflow() {
712     Trace("SUPERVGUI_Main::getDataflow")
713     return(dataflow);
714 }
715
716 QAD_Message* SUPERVGUI_Main::getMessage() {
717     Trace("SUPERVGUI_Main::getMessage")
718     return(message);
719 }
720
721 QAD_Study* SUPERVGUI_Main::getStudy() {
722     Trace("SUPERVGUI_Main::getStudy")
723     return(study);
724 }
725
726 bool SUPERVGUI_Main::isArrayShown() {
727     Trace("SUPERVGUI_Main::isArrayShown")
728     return(myCurrentView == TABLE);
729 }
730
731 void SUPERVGUI_Main::showPopup(QPopupMenu* p, QMouseEvent* e) {
732   Trace("SUPERVGUI_Main::showPopup");
733   // To check is Supervision active?
734   if (myIsLocked) return;
735   //if (dataflow->IsExecuting()) return;
736
737   //if (QAD_Application::getDesktop()->getActiveComponent().compare(STUDY_SUPERVISION) !=0) return;
738   if (QAD_Application::getDesktop()->getActiveComponent().compare(QAD_Application::getDesktop()->getComponentUserName( "SUPERV" ) ) !=0) return;
739
740   checkIsInStudy();
741   if (e->button() == RightButton) {
742     p->exec(e->globalPos());
743   }
744 }
745
746
747
748 void SUPERVGUI_Main::changeInformation() {
749   SUPERVGUI_Information* aDlg = new SUPERVGUI_Information(SUPERV::CNode::_narrow(dataflow), dataflow->IsReadOnly());
750   if (aDlg->exec() )
751     sync();
752   delete aDlg;
753   /*    Trace("SUPERVGUI_Main::changeInformation")
754     if (Supervision.information(SUPERV::CNode::_narrow(dataflow), dataflow->IsReadOnly())) {
755       sync();
756       }*/
757 }
758
759 // returns false, if can't add dataflow into the study
760 bool SUPERVGUI_Main::addStudy() {
761   Trace("SUPERVGUI_Main::addStudy");
762   if (myIsFromStudy) return false;
763   if ((SUPERV_isNull(dataflow))) return false;
764   
765   SALOMEDS::Study_var            aStudy = study->getStudyDocument();
766   SALOMEDS::StudyBuilder_var     aBuilder  = aStudy->NewBuilder();
767   SALOMEDS::GenericAttribute_var anAttr;
768   SALOMEDS::AttributeName_var    aName;
769   SALOMEDS::AttributeIOR_var     anIORAttr;
770   SALOMEDS::AttributePixMap_var  aPixmap;
771   bool                           aLocked = aStudy->GetProperties()->IsLocked();
772   QAD_Operation*                 op = new SALOMEGUI_ImportOperation( study );
773   
774   // searching dataflow
775   SALOMEDS::SObject_var aSO = aStudy->FindObjectIOR(dataflow->getIOR());
776   if (aSO->_is_nil()) { // create new dataflow SObject
777     SALOMEDS::SComponent_ptr aComponent = aStudy->FindComponent(STUDY_SUPERVISION);
778     if (aComponent->_is_nil()) { // is supervision component not found, then create it
779       QAD_Operation* anOperation = new SALOMEGUI_ImportOperation( study );
780       anOperation->start();
781       if (aLocked) aStudy->GetProperties()->SetLocked(false);
782       aComponent = aBuilder->NewComponent(STUDY_SUPERVISION);
783       anAttr = aBuilder->FindOrCreateAttribute(aComponent, "AttributeName");
784       aName = SALOMEDS::AttributeName::_narrow(anAttr);
785       //aName->SetValue(STUDY_SUPERVISION);
786       aName->SetValue(QAD_Application::getDesktop()->getComponentUserName( "SUPERV" ) );
787       anAttr = aBuilder->FindOrCreateAttribute(aComponent, "AttributePixMap");
788       aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
789       aPixmap->SetPixMap( "ICON_OBJBROWSER_Supervision" );
790       aBuilder->DefineComponentInstance(aComponent, Supervision.getEngine());
791       if (aLocked) aStudy->GetProperties()->SetLocked(true);
792       anOperation->finish();
793     }
794     op->start();
795     aSO = aBuilder->NewObject(aComponent);
796     anAttr =  aBuilder->FindOrCreateAttribute(aSO, "AttributeName");
797     aName = SALOMEDS::AttributeName::_narrow(anAttr);
798     aName->SetValue(dataflow->Name());
799     anAttr =  aBuilder->FindOrCreateAttribute(aSO, "AttributeIOR");
800     anIORAttr = SALOMEDS::AttributeIOR::_narrow(anAttr);
801     anIORAttr->SetValue(dataflow->getIOR());
802     op->finish();
803     if (aLocked) return false;
804   }
805
806   sync();
807   Supervision.unregisterGraph(this);
808   Supervision.registerGraph(dataflow->getIOR(), this);
809   myIsFromStudy = true;
810   return true;
811 }
812
813
814 void SUPERVGUI_Main::chooseData(QListViewItem* item) {
815     Trace("SUPERVGUI_Main::chooseData")
816     if (choosing) {
817         QString id = ((QAD_ObjectBrowserItem*)item)->getEntry();
818         if (!id.isEmpty()) {
819             SALOMEDS::SObject_var object = study->getStudyDocument()->FindObjectID(id.latin1());
820             SALOMEDS::GenericAttribute_var anAttr;
821             SALOMEDS::AttributeIOR_var     anIOR;
822             Standard_CString      ior    = "";
823             if (object->FindAttribute(anAttr, "AttributeIOR")) {
824               anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
825               ior = anIOR->Value();
826               portIn->setValue(ior);
827
828               // stop selection
829               choosing = false;
830               setCursor(Supervision.getCursor());
831               objectBrowser->setCursor(Supervision.getCursor());
832               Supervision.putInfo("");
833             }
834         }
835     }
836 }
837
838 void SUPERVGUI_Main::setData(SUPERVGUI_PortIn* p) {
839     Trace("SUPERVGUI_Main::setData")
840     portIn   = p;
841     choosing = true;
842     setCursor(forbiddenCursor);
843     objectBrowser->setCursor(pointingHandCursor);
844     Supervision.putInfo(tr("MSG_CHOOSE_DATA"));
845 }
846
847 SALOMEDS::SObject_var SearchOrCreateSOWithName(const SALOMEDS::Study_var theStudy,
848                                                const SALOMEDS::SObject_var theSO,
849                                                const char* theName,
850                                                //QAD_Operation* theOperation,
851                                                bool* theStarted) {
852   SALOMEDS::SObject_var aResult;
853   SALOMEDS::AttributeName_var aName;
854   SALOMEDS::GenericAttribute_var anAttr;
855   if (!*theStarted) { // optimisation
856     SALOMEDS::ChildIterator_var anIterator = theStudy->NewChildIterator(theSO);
857     for (; anIterator->More(); anIterator->Next()) {
858       if (anIterator->Value()->FindAttribute(anAttr, "AttributeName")) {
859         aName = SALOMEDS::AttributeName::_narrow(anAttr);
860         if (strcmp(aName->Value(), theName) == 0) {
861           aResult = anIterator->Value();
862           break;
863         }
864       }
865     }
866   }
867   if (!aResult->_is_nil()) return aResult;
868   // add new SObject
869   SALOMEDS::StudyBuilder_var aBuilder = theStudy->NewBuilder();
870   if (!*theStarted) {
871     *theStarted = true;
872     //theOperation->start();
873     aBuilder->NewCommand();
874   }
875   aResult = aBuilder->NewObject(theSO);
876   anAttr = aBuilder->FindOrCreateAttribute(aResult, "AttributeName");
877   aName = SALOMEDS::AttributeName::_narrow(anAttr);
878   aName->SetValue(theName);
879   return aResult;
880 }
881
882 bool SUPERVGUI_Main::putDataStudy(SUPERV_Port p, const char* inout) {
883   Trace("SUPERVGUI_Main::putDataStudy");
884
885   static bool isIn = false;
886   if (isIn) return true; else isIn = true;
887
888   SALOMEDS::Study_var            aStudy = study->getStudyDocument();
889   SALOMEDS::StudyBuilder_var     aBuilder  = aStudy->NewBuilder();
890   SALOMEDS::GenericAttribute_var anAttr;
891   SALOMEDS::AttributeName_var    aName;
892   SALOMEDS::AttributeIOR_var     anIORAttr;
893   SALOMEDS::AttributePixMap_var  aPixmap;
894   bool                           aTransaction = false;
895   bool                           aLocked = aStudy->GetProperties()->IsLocked();
896   //  QAD_Operation*                 op = new SALOMEGUI_ImportOperation( study );
897   
898   // searching dataflow
899   SALOMEDS::SObject_var aSO = aStudy->FindObjectIOR(dataflow->getIOR());
900   if (aSO->_is_nil()) { // create new dataflow SObject
901     SALOMEDS::SComponent_ptr aComponent = aStudy->FindComponent(STUDY_SUPERVISION);
902     if (aComponent->_is_nil()) { // is supervision component not found, then create it
903       //QAD_Operation* anOperation = new SALOMEGUI_ImportOperation( study );
904       //anOperation->start();
905       aBuilder->NewCommand();
906       if (aLocked) aStudy->GetProperties()->SetLocked(false);
907       aComponent = aBuilder->NewComponent(STUDY_SUPERVISION);
908       anAttr = aBuilder->FindOrCreateAttribute(aComponent, "AttributeName");
909       aName = SALOMEDS::AttributeName::_narrow(anAttr);
910       //aName->SetValue(STUDY_SUPERVISION);
911       aName->SetValue(QAD_Application::getDesktop()->getComponentUserName( "SUPERV" ) );
912         
913       anAttr = aBuilder->FindOrCreateAttribute(aComponent, "AttributePixMap");
914       aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
915       aPixmap->SetPixMap( "ICON_OBJBROWSER_Supervision" );
916       aBuilder->DefineComponentInstance(aComponent, Supervision.getEngine());
917       if (aLocked) aStudy->GetProperties()->SetLocked(true);
918       //      anOperation->finish();
919       aBuilder->CommitCommand();
920     }
921     aTransaction = true;
922     //op->start();
923     aBuilder->NewCommand();
924     aSO = aBuilder->NewObject(aComponent);
925     anAttr =  aBuilder->FindOrCreateAttribute(aSO, "AttributeName");
926     aName = SALOMEDS::AttributeName::_narrow(anAttr);
927     aName->SetValue(dataflow->Name());
928     anAttr =  aBuilder->FindOrCreateAttribute(aSO, "AttributeIOR");
929     anIORAttr = SALOMEDS::AttributeIOR::_narrow(anAttr);
930     anIORAttr->SetValue(dataflow->getIOR());
931   }
932   //QAD_Operation* anOperation = new SALOMEGUI_ImportOperation( study );
933   aSO = SearchOrCreateSOWithName(aStudy, aSO,  // get run time SO
934                                  QString("Run ") + myRunTime.toString() /*, anOperation*/, &aTransaction);
935   aSO = SearchOrCreateSOWithName(aStudy, aSO, p->Node()->Name()/*, anOperation*/, &aTransaction); // get node SO
936   aSO = SearchOrCreateSOWithName(aStudy, aSO, inout/*, anOperation*/, &aTransaction); // get in/out SO
937   aSO = SearchOrCreateSOWithName(aStudy, aSO, p->Name()/*, anOperation*/, &aTransaction); // get port SO
938
939   if (aLocked) {
940     if (aTransaction) aBuilder->CommitCommand();
941       //op->finish();
942     isIn = false;
943     return false;
944   }
945
946   anAttr = aBuilder->FindOrCreateAttribute(aSO, "AttributeIOR");
947   anIORAttr  = SALOMEDS::AttributeIOR::_narrow(anAttr);
948   if (!aTransaction && strcmp(anIORAttr->Value(), p->ToString()) == 0) {
949     isIn = false;
950     return true;
951   }
952   // set object value to the study: if object is external, then put it with
953   //                                 help of the specific component - owner
954   if (p->IsIOR()) {
955     // get according component driver for result object
956     SALOME_LifeCycleCORBA aLCC(myNService);
957     SUPERV_FNode aFNode = SUPERV::FNode::_narrow(p->Node());
958     if (!aFNode->_is_nil()) {
959       Engines::Component_var aComponent = aLCC.FindOrLoad_Component(aFNode->GetContainer(),
960                                                                     aFNode->GetComponentName());
961       SALOMEDS::Driver_var aDriver = SALOMEDS::Driver::_narrow(aComponent);
962       if (!CORBA::is_nil(aDriver)) { // if driver was found, publish object
963         CORBA::Object_ptr anObject = new CORBA::Object();
964         CORBA::Any* anAny = p->ToAny();
965         (*anAny) >>= anObject;
966         
967         if (aDriver->CanPublishInStudy(anObject)) {
968           SALOMEDS::SObject_var aTmpSO;
969           if (!aTransaction) {
970             aTmpSO = aSO;
971             aTransaction = true;
972             //op->start();
973             aBuilder->NewCommand();
974           }
975           aTmpSO = aDriver->PublishInStudy(aStudy, aTmpSO, anObject, "");
976           aBuilder->Addreference(aSO, aTmpSO);
977         } else { // can't publish object: abort transaction
978           if (aTransaction) aBuilder->AbortCommand();
979           //op->abort();
980           isIn = false;
981           return false;
982         }
983       } else { // component has no drivel, but could store IORs (like Calculator)
984         SALOMEDS::SObject_var anIORSO = aStudy->FindObjectIOR(p->ToString());
985         if (!CORBA::is_nil(anIORSO)) aBuilder->Addreference(aSO, anIORSO);
986       }
987     }
988   } else {
989     if (!aTransaction) {
990       aTransaction = true;
991       //      op->start();
992       aBuilder->NewCommand();
993     }
994     anIORAttr->SetValue(p->ToString()); // ior attribute already set for the prevoius condition
995   }
996   
997   if (aTransaction) 
998     //op->finish();
999     aBuilder->CommitCommand();
1000   if (!myThread->running())
1001     study->updateObjBrowser();
1002   isIn = false;
1003   return true;
1004 }
1005
1006
1007 void SUPERVGUI_Main::ActivatePanning()
1008 {
1009   if (graph->isVisible()) {
1010     graph->ActivatePanning();
1011   } else if (array->isVisible()) {
1012     array->ActivatePanning();
1013   }
1014 }
1015
1016
1017 void SUPERVGUI_Main::ResetView()
1018 {
1019   if (graph->isVisible()) {
1020     graph->ResetView();
1021   } else if (array->isVisible()) {
1022     array->ResetView();
1023   }
1024 }
1025
1026
1027 void SUPERVGUI_Main::setAsFromStudy(bool theToStudy) {
1028   myIsFromStudy = theToStudy;
1029   graph->setAsFromStudy(theToStudy);
1030   array->setAsFromStudy(theToStudy);
1031 }
1032
1033 void SUPERVGUI_Main::checkIsInStudy() {
1034   if (!myIsFromStudy) return;
1035
1036   SALOMEDS::Study_var aStudyDoc = study->getStudyDocument();
1037   SALOMEDS::SComponent_var aFatherLbl = aStudyDoc->FindComponent(STUDY_SUPERVISION);
1038   SALOMEDS::ChildIterator_var aChildIterator = aStudyDoc->NewChildIterator(aFatherLbl);
1039   SALOMEDS::SObject_var aDataflowLbl;
1040   SALOMEDS::GenericAttribute_var anAttr;
1041
1042   for (; aChildIterator->More(); aChildIterator->Next()) {
1043     aDataflowLbl = aChildIterator->Value();
1044     if (!aDataflowLbl->FindAttribute(anAttr, "AttributeIOR"))
1045       continue;
1046
1047     SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
1048     if (strcmp(anIOR->Value(), dataflow->getIOR()) == 0) return;
1049   }
1050   // This Graph considered as in study but in study it is not exists
1051   Supervision.unregisterGraph(this);
1052   setAsFromStudy(false);
1053 }
1054
1055 void SUPERVGUI_Main::syncNotification() {
1056   char* graph;
1057   char* node;
1058   char* type;
1059   char* message;
1060   char* sender;
1061   long  counter;
1062   char* date;
1063   long  stamp;
1064   
1065   while (notification->Receive(&graph, &node, &type, &message, &sender, &counter, &date, &stamp)) {
1066     if (isFiltered(graph, node, type, message, sender, counter, date, stamp)) {
1067       QString mess("");
1068       mess += "NOTIF: "; mess += graph;
1069       mess += " / "    ; mess += node;
1070       mess += " / "    ; mess += type;
1071       mess += " / "    ; mess += message;
1072       getMessage()->setMessage(mess.latin1());
1073     };
1074   };
1075 }
1076   
1077 bool SUPERVGUI_Main::isFiltered(char* graph,  char* node,   char* type, char* message, 
1078                                 char* sender, long counter, char* date, long stamp) {
1079   Trace("SUPERVGUI_Main::isFiltered");
1080   bool b = false;
1081   if (strcmp(getDataflow()->Name(), graph) == 0) {
1082     SUPERVGUI_Node* n;
1083     QObjectList* nodes = queryList("SUPERVGUI_Node");
1084     QObjectListIt i(*nodes);
1085     while ((n=(SUPERVGUI_Node*)i.current()) != 0) {
1086       ++i;
1087       if (strcmp(n->name(), node) == 0) {
1088         if (strcmp(type, NOTIF_WARNING) == 0) {
1089           b = n->isWarning();
1090         } else if (strcmp(type, NOTIF_STEP) == 0) {
1091           b = n->isStep();
1092         } else if (strcmp(type, NOTIF_TRACE) == 0) {
1093           b = n->isTrace();
1094         } else if (strcmp(type, NOTIF_VERBOSE) == 0) {
1095           b = n->isVerbose();
1096         };
1097         break;
1098       };
1099     };
1100     delete nodes;
1101     if ( myLogged && myLogFile && ( ( !myFiltered ) || b ) ) {
1102       fprintf( myLogFile, "NOTIF %ld\t%s\t%s\t%ld\t%s\t%s\t%s\t%s\n", stamp, date, sender, counter, graph, node, type, message );
1103       fflush( myLogFile );
1104     };
1105   };
1106   return( b );
1107 }
1108
1109
1110
1111 void SUPERVGUI_Main::setPaletteBackgroundColor(const QColor& color) { 
1112   array->setPaletteBackgroundColor(color);
1113   graph->setPaletteBackgroundColor(color);
1114   
1115   SUPERVGraph_View::setPaletteBackgroundColor(color); 
1116 }
1117
1118 QPtrList< char * > SUPERVGUI_Main::getEventNodes() {
1119   return myEventNodes;
1120 }
1121
1122 void SUPERVGUI_Main::setEventNodes(QPtrList< char * > theEventNodes) {
1123   myEventNodes = theEventNodes;
1124 }
1125
1126 QPtrList< SUPERV::GraphState > SUPERVGUI_Main::getStates() {
1127   return myStates;
1128 }
1129
1130 void SUPERVGUI_Main::setStates(QPtrList< SUPERV::GraphState > theStates) {
1131   myStates = theStates;
1132 }
1133
1134 int SUPERVGUI_Main::getNodesNumber() {
1135   //create a list of nodes of the graph
1136   SUPERV_Nodes nodes = getDataflow()->Nodes();
1137   int RetVal = nodes->CNodes.length() + nodes->FNodes.length() +
1138                nodes->INodes.length() + nodes->GNodes.length() +
1139                nodes->LNodes.length() + nodes->SNodes.length();
1140   return RetVal;
1141 }
1142
1143 SUPERVGUI_Thread* SUPERVGUI_Main::getMyThread() {
1144   return myThread;
1145 }
1146
1147 void SUPERVGUI_Main::startTimer() {
1148   myTimer->start(500);
1149 }
1150
1151 void SUPERVGUI_Main::executionFinished() {
1152   getStudy()->updateObjBrowser();
1153 }
1154
1155 void SUPERVGUI_Main::checkExecution() {
1156   if (myThread->finished()) {
1157     myTimer->stop();
1158     executionFinished();
1159   }
1160 }
1161
1162 /******************************* SUPERVGUI_Thread class ****************************************/
1163 SUPERVGUI_Thread::SUPERVGUI_Thread()
1164      :QThread()
1165 {
1166   myIsActive = false;
1167 }
1168
1169 SUPERVGUI_Thread::~SUPERVGUI_Thread()
1170 {
1171   //it is a virtual destructor and needs to be determine here
1172 }
1173
1174 void SUPERVGUI_Thread::startThread(const char* m)
1175 {
1176   if (!myIsActive) {
1177     myIsActive = true;
1178     QThread::start();
1179     myMain->getMessage()->setMessage(m); 
1180     myMain->sync();
1181   }
1182 }
1183
1184 void SUPERVGUI_Thread::stopThread(const char* m)
1185 {
1186   myMain->getMessage()->setMessage(m);
1187 }
1188
1189 void SUPERVGUI_Thread::setMain(SUPERVGUI_Main* theMain)
1190 {
1191   myMain = theMain;
1192 }
1193
1194 void SUPERVGUI_Thread::KillThread(bool theValue)
1195 {
1196   myMutex.lock();
1197   myIsActive = !(theValue);
1198   myMutex.unlock();
1199 }
1200
1201 typedef TVoidMemFun2ArgEvent<SUPERVGUI_Main, char*, SUPERV::GraphState> TNodeSyncEvent;
1202
1203 void SUPERVGUI_Thread::run()
1204 {
1205   SUPERV_CNode aNode = NULL;
1206   SUPERV::GraphEvent aEvent = SUPERV::UndefinedEvent ;
1207   SUPERV::GraphState aState = SUPERV::UndefinedState ;
1208
1209   SUPERV_CNode aPrevNode = NULL;
1210   SUPERV::GraphEvent aPrevEvent = SUPERV::UndefinedEvent ;
1211   SUPERV::GraphState aPrevState = SUPERV::UndefinedState ;
1212
1213   char * aName;
1214   char * aPrevName;
1215
1216   QPtrList< char * > anEventNodes;
1217   QPtrList< SUPERV::GraphState > aStates;
1218
1219   myMain->startTimer();
1220   while(myIsActive) {
1221     myMain->getDataflow()->Event(aNode, aEvent, aState);
1222       
1223     if (aEvent == SUPERV::UndefinedEvent && aState == SUPERV::UndefinedState
1224         ||
1225         aEvent == SUPERV::NoEvent && aState == SUPERV::NoState
1226         ||
1227         aEvent == SUPERV::KillEvent && aState == SUPERV::KillState) {
1228       if (myMain->getEventNodes().count()) {
1229         myMain->removeEventNodes();
1230       }
1231       if (myMain->getStates().count()) {
1232         myMain->removeStates();
1233       }
1234       myIsActive = false;
1235     }
1236     else {
1237       if ( aNode != NULL) {
1238         aName = aNode->Name();
1239       }
1240
1241       if ( aPrevNode == NULL ) {  //first initialize aPrev... variables
1242         anEventNodes = myMain->getEventNodes();
1243         anEventNodes.append( &aName ) ;
1244         myMain->setEventNodes(anEventNodes);
1245         
1246         aStates = myMain->getStates();
1247         aStates.append( &aState ) ;
1248         myMain->setStates(aStates);
1249       }
1250       else {
1251         if ( aEvent == aPrevEvent && aState == aPrevState) {
1252           QString aNameStr = aName;
1253           QString aPrevNameStr = aPrevName;
1254           if ( aNameStr != aPrevNameStr ) {
1255             anEventNodes = myMain->getEventNodes();
1256             anEventNodes.append( &aName ) ;
1257             myMain->setEventNodes(anEventNodes);
1258             
1259             aStates = myMain->getStates();
1260             aStates.append( &aState ) ;
1261             myMain->setStates(aStates);
1262           }
1263         }
1264         else {
1265           anEventNodes = myMain->getEventNodes();
1266           anEventNodes.append( &aName ) ;
1267           myMain->setEventNodes(anEventNodes);
1268           
1269           aStates = myMain->getStates();
1270           aStates.append( &aState ) ;
1271           myMain->setStates(aStates);
1272         }
1273       }
1274     }
1275     if (!myIsActive) {
1276       switch (myMain->getDataflow()->State()) {
1277       case SUPERV_Editing : 
1278         stopThread(myMain->getDataflow()->IsReadOnly()? tr("MSG_GRAPH_READONLY"): tr("MSG_GRAPH_EDITING"));
1279         break;
1280         
1281       case SUPERV_Suspend : 
1282         stopThread(tr("MSG_GRAPH_SUSPENDED"));
1283         break;
1284  
1285       case SUPERV_Done : 
1286         stopThread(tr("MSG_GRAPH_FINISHED"));
1287         break;
1288         
1289       case SUPERV_Error : 
1290         stopThread(tr("MSG_GRAPH_ABORTED"));
1291         break;
1292         
1293       case SUPERV_Kill:
1294         stopThread(tr("MSG_GRAPH_KILLED"));
1295         break;
1296       }
1297
1298       break;
1299     }
1300
1301     if (myMain->getEventNodes().count()) {
1302       //if list not empty call execute() -> sync()
1303       char * aNodeName = *(myMain->getEventNodes().getFirst());
1304       SUPERV::GraphState aNodeState = *(myMain->getStates().getFirst());
1305
1306       // It is PROHIBITED to deal with widgets in a secondary thread, so event posting is used here
1307       ProcessVoidEvent( new TNodeSyncEvent( myMain, &SUPERVGUI_Main::execute, aNodeName, aNodeState ) );
1308             
1309       myMain->removeFirstEN();
1310       myMain->removeFirstS();
1311
1312     }
1313
1314     aPrevNode = aNode;
1315     aPrevEvent = aEvent;
1316     aPrevState = aState;
1317     aPrevName = aPrevNode->Name();
1318     
1319     //usleep(10);
1320     //msleep(5);
1321   }
1322   // VSR: 04/12/03 ---> update object browser ufter finishing
1323 //   qApp->lock();
1324 //   myMain->getStudy()->updateObjBrowser();
1325 //   qApp->unlock();
1326   // VSR: 04/12/03 <---
1327   QThread::exit();
1328 }
1329