Salome HOME
Merge from OCC_development_generic_2006
[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 #include "SALOMEDSClient.hxx"
29 #include "SALOMEDS_Study.hxx"
30 #include "SALOMEDS_SObject.hxx"
31
32 #include "NOTIFICATION.hxx"
33 #include "SALOME_Event.hxx"
34 #include "SUPERVGraph_ViewFrame.h"
35 #include "SUPERVGraph_ViewModel.h"
36
37 #include "LogWindow.h"
38 #include "OB_Browser.h"
39 #include "OB_ListItem.h"
40 #include "SalomeApp_Application.h"
41 #include "SalomeApp_ImportOperation.h"
42 #include "SalomeApp_Study.h"
43 #include "SUIT_FileDlg.h"
44 #include "SUIT_MessageBox.h"
45 #include "SUIT_Operation.h"
46 #include "SUIT_Session.h"
47 #include "SUIT_Study.h"
48 #include "QtxDblSpinBox.h"
49
50 #include "SUPERVGUI.h"
51 #include "SUPERVGUI_Def.h"
52 #include "SUPERVGUI_Main.h"
53 #include "SUPERVGUI_Notification.h"
54 #include "SUPERVGUI_Information.h"
55 #include "SUPERVGUI_CanvasControlNode.h"
56 #include "SUPERVGUI_CanvasPort.h"
57
58 #include <qvalidator.h>
59 #include <qlabel.h>
60 #include <qlayout.h>
61 #include <qfile.h>
62 #include <qlineedit.h>
63 #include <qcombobox.h>
64
65 #include <boost/shared_ptr.hpp>
66 using namespace boost;
67
68 SUPERVGUI_Main::SUPERVGUI_Main( SUPERVGraph_ViewFrame* theParent, 
69                                 SUIT_Desktop* theDesktop, SUPERV_Graph theDataFlow )
70      : SUPERVGraph_View(theParent),
71        myLogged( false ),
72        myFiltered( false ),
73        myLogFileName( QString::null ),
74        myLogFile( NULL ),
75        myWarning( false ),
76        myStep( false ),
77        myTrace( false ),
78        myVerbose( false )
79   //myExecuted( false )
80 {
81   Trace("SUPERVGUI_Main::SUPERVGUI_Main (copy)");
82   setFocusPolicy( StrongFocus );  // mkr : IPAL11388
83   theParent->setViewWidget(this);
84   dataflow = theDataFlow;
85   if (SUPERV_isNull(dataflow)) {
86     QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_COPY"));
87     close();
88   } else {
89     init(theDesktop);
90   }
91   // mkr : IPAL11362
92   connect(this, SIGNAL(EventToSync()), this, SLOT(onObjectCreatedDeleted()));
93 }
94
95 void SUPERVGUI_Main::init(SUIT_Desktop* theDesktop) {
96   Trace("SUPERVGUI_Main::init");
97   SUIT_Application* anActApp = SUIT_Session::session()->activeApplication();
98
99   if (theDesktop) 
100     myNService = dynamic_cast<SalomeApp_Application*>( anActApp )->namingService();
101   myHashCode = "New";
102   myCopyNum = 0;
103   choosing  = false;
104   myIsLocked = false;
105
106   myThread = new SUPERVGUI_Thread();
107   myThread->setMain(this);
108
109   myCurrentView = CANVAS;
110   myIsFromStudy = false;
111   myLastGraph = 0;
112   study = anActApp->activeStudy();
113
114   //mkr: Supervision module already connected to the 
115   //active study. So, we have to commented this code!
116   /*_PTR(Study) studyDoc = (( SalomeApp_Study* )study)->studyDS();
117   bool aLocked = studyDoc->GetProperties()->IsLocked();
118   _PTR(StudyBuilder) builder ( studyDoc->NewBuilder() );
119   _PTR(SComponent) father = studyDoc->FindComponent(STUDY_SUPERVISION);
120   if ( !father ) {
121     SUIT_Operation* op = new SalomeApp_ImportOperation( study->application() );
122     op->start();
123     if (aLocked) studyDoc->GetProperties()->SetLocked(false);
124     father = builder->NewComponent(STUDY_SUPERVISION);
125     _PTR(GenericAttribute) anAttr = builder->FindOrCreateAttribute(father, "AttributeName");
126     _PTR(AttributeName) aName ( anAttr );
127     aName->SetValue( dynamic_cast<CAM_Application*>( study->application() )->moduleTitle( "SUPERV" ).latin1() );
128     
129     anAttr = builder->FindOrCreateAttribute(father, "AttributePixMap");
130     _PTR(AttributePixMap) aPixmap ( anAttr );
131     aPixmap->SetPixMap( "ICON_OBJBROWSER_Supervision" );
132     
133     SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
134     if ( !aSupMod ) {
135       MESSAGE("NULL Supervision module!");
136       return;
137     }
138
139     builder->DefineComponentInstance(father, SalomeApp_Application::orb()->object_to_string(aSupMod->getEngine()));
140                                              //dynamic_cast<SALOMEDS_Study*>( studyDoc )->ConvertObjectToIOR(aSupMod->getEngine()));
141     if (aLocked) studyDoc->GetProperties()->SetLocked(true);
142     op->commit();
143   };
144   */
145
146   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( study->application() );
147
148   objectBrowser = app->objectBrowser();
149     
150   myArray = new SUPERVGUI_CanvasArray( this, resMgr() );
151   myArrayView = new SUPERVGUI_ArrayView( myArray, this );
152
153   myCanvas = new SUPERVGUI_Canvas( this, resMgr() );
154   myCanvasView = new SUPERVGUI_CanvasView(myCanvas, this);
155   
156   message = app->logWindow();
157   notification = new NOTIFICATION_Consumer();
158
159   QBoxLayout * layout = new QVBoxLayout(this);
160   layout->setMargin(0);
161   layout->setSpacing(0);
162   layout->addWidget(myCanvasView);
163   layout->addWidget(myArrayView);
164
165   if (myCurrentView == CANVAS || myCurrentView == CONTROLFLOW) {
166     myCanvas->merge();
167   }
168
169   sync();
170   show();
171   if ( myLogged && !myLogFileName.isEmpty() && QFile::exists( myLogFileName ) ) {
172     myLogFile = fopen( myLogFileName.latin1(), "a" );
173     if (  myLogFile == NULL )
174       myLogged = false;
175   }
176   myTimer = new QTimer( this );
177   connect( myTimer, SIGNAL(timeout()), this, SLOT(checkExecution()) );
178 }
179
180 SUPERVGUI_Main::~SUPERVGUI_Main() {
181   Trace("SUPERVGUI_Main::~SUPERVGUI_Main");
182
183   // close all opened SubGraphs 
184   QMap<QString, SUIT_ViewWindow*/*QAD_StudyFrame**/>::iterator it;
185   for (it = mySubGraphs.begin(); it != mySubGraphs.end(); ++it) {
186     it.data()->removeEventFilter(this);
187     it.data()->disconnect();
188     //it.data()->close();
189
190     //QAD_Study* aStudy = it.data()->getStudy();
191     //aStudy->removeStudyFrame(it.data());
192     //remove view from internal view manager's list of views
193     //it.data()->getViewManager()->removeView(it.data());
194     SUIT_ViewManager* aVM = it.data()->getViewManager();
195     STD_Application* anApp = dynamic_cast<STD_Application*>( SUIT_Session::session()->activeApplication() );
196     if ( anApp ) anApp->removeViewManager(aVM);
197     if ( aVM ) delete aVM;
198     
199   }
200   mySubGraphs.clear();
201   mySubGraphMap.clear();
202   /*
203   QAD_StudyFrame* aSubGraph;
204   for (aSubGraph = mySubGraphs.first(); aSubGraph; aSubGraph = mySubGraphs.next()) {
205     aSubGraph->removeEventFilter(this);
206     aSubGraph->close();
207   }
208   */
209
210   if ( myLogFile != NULL) {
211     fclose( myLogFile );
212   }
213   
214   //  delete notification; // kloss : nota bene : quand un datalow est detruit : verifier que les canaux de notification sont aussi detruit
215   notification->_remove_ref();  // kloss : nota bene : quand un datalow est detruit : verifier que les canaux de notification sont aussi detruit
216
217   delete myCanvas;
218   delete myArray;
219 }
220
221 SUIT_ResourceMgr* SUPERVGUI_Main::resMgr() const
222 {
223   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( study->application() );
224   return app ? app->resourceMgr() : 0;
225 }
226
227 void SUPERVGUI_Main::filterNotification() {
228   Trace("SUPERVGUI_Main::filterNotification");
229   SUPERVGUI_Notification* dlg = new SUPERVGUI_Notification(this);
230   dlg->setFiltered( myFiltered );
231   dlg->setLogged( myLogged, myLogFileName );
232   dlg->setWarning( myWarning );
233   dlg->setStep( myStep );
234   dlg->setTrace( myTrace );
235   dlg->setVerbose( myVerbose );
236   if ( dlg->exec() == QDialog::Accepted ) {
237     myLogged      = dlg->getLogged();
238     myLogFileName = dlg->getLogFile();
239     myFiltered    = dlg->getFiltered();
240     myWarning     = dlg->getWarning();
241     myStep        = dlg->getStep();
242     myTrace       = dlg->getTrace();
243     myVerbose     = dlg->getVerbose();
244     delete dlg;
245     if ( myLogFile != NULL) {
246       fclose( myLogFile );
247     }
248     myLogFile = NULL;
249     if ( myLogged && !myLogFileName.isEmpty() && QFile::exists( myLogFileName ) ) {
250       myLogFile = fopen( myLogFileName.latin1(), "a" );
251       if (  myLogFile == NULL ) {
252         myLogged = false;
253         QMessageBox::warning( SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr( "ERR_CANT_OPEN_LOG_FILE" ) );
254       }
255     }
256   }
257 }
258
259 void SUPERVGUI_Main::changeDSGraphParameters() {
260   SUPERVGUI_DSGraphParameters* aDlg = new SUPERVGUI_DSGraphParameters(dataflow, dataflow->IsReadOnly());
261   if (aDlg->exec() )
262     sync();
263   delete aDlg;
264 }
265
266 void SUPERVGUI_Main::syncAsync() {
267   Trace("SUPERVGUI_Main::syncAsync");
268   QTimer::singleShot(1, this, SLOT(sync()));
269 }
270
271
272 /**
273  * Called by thread when dataflow is executing
274  */
275 void SUPERVGUI_Main::execute( char *  theNodeName, SUPERV::GraphState theNodeState ) {
276   if (myCurrentView == CANVAS || myCurrentView == CONTROLFLOW) {
277     SUPERVGUI_CanvasNode* aNode = (SUPERVGUI_CanvasNode*) myCanvas->child(theNodeName, "SUPERVGUI_CanvasNode");
278     if ( aNode ) {
279       aNode->sync();
280       emit EventToSync(); // mkr : IPAL11362
281     }
282   }
283   else if (myCurrentView == CANVASTABLE) {
284     SUPERVGUI_CanvasCellNode* aNode = (SUPERVGUI_CanvasCellNode*) myArray->child(theNodeName, "SUPERVGUI_CanvasCellNode");
285     if (aNode) {
286       aNode->sync();
287       emit EventToSync(); // mkr : IPAL11362
288     }
289   }
290
291   // asv : 26.01.05 : Bug PAL7164 : puting out-value to study if the "put_to_Study" flag is set on a 
292   // CanvasPort the functionality was moved from SUPERVGUI_CanvasPortOut::sync() method please, see 
293   // comment in that method for details.
294   if ( theNodeState == SUPERV::DoneState ) {
295     SUPERVGUI_CanvasNode* aNode = (SUPERVGUI_CanvasNode*) myCanvas->child(theNodeName, "SUPERVGUI_CanvasNode");
296     if ( aNode ) {
297       //cout << " *** theNode " << theNodeName << " received DONE_STATE *** " << endl;
298       SUPERVGUI_CanvasPortOut* aPortOut;
299       QObjectList* aPortList = aNode->queryList("SUPERVGUI_CanvasPortOut");
300       QObjectListIt aPortIt(*aPortList);
301       while ((aPortOut=(SUPERVGUI_CanvasPortOut*)aPortIt.current()) != 0) {
302         ++aPortIt;
303         if ( aPortOut->isInStudy() && aPortOut->getEngine()->State() == SUPERV::ReadyState ) {
304           //cout << " *** " << theNodeName << "[" << aPortOut->name() << "]--> goes into study *** " << endl;
305           putDataStudy( aPortOut->getEngine(), STUDY_PORT_OUT );
306         }
307       }
308       delete aPortList;      
309     } 
310     //else //normal case if Node is not found is when node is a graph!  it can receive DoneState as well!  
311     //  MESSAGE( "ERROR in SUPERVGUI_Main::execute() : CanvasNode \"" << theNodeName << "\" NOT FOUND in myCanvas" );
312   }
313 }
314
315
316 void SUPERVGUI_Main::sync() {
317   Trace("SUPERVGUI_Main::sync");
318   if ((SUPERV_isNull(dataflow))) 
319     return;
320   QString t = tr("GRAPH_TITLE");
321   
322   t += dataflow->Name();
323   setCaption(t);
324
325   //study->updateObjBrowser();
326   //mkr: we have to update object browser only if there are some ports datas in the study
327   //or if dataflow is in the study itself. It is done in the 
328   //1) putDataStudy(...) method (it called when we put in study data of port
329   //                             or if port is in study and execution is finished)
330   //2) addDataflowToStudy() method (it is called as a slot when we add in study dataflow itself).
331   //So, we commented updateObjBrowser function here!
332   //SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
333   //if ( aSupMod ) aSupMod->updateObjBrowser();
334   //else MESSAGE("NULL Supervision module!");
335
336   if (myCurrentView == CANVASTABLE) {
337     myArray->sync();
338     myArray->update();
339   } else {
340     myCanvas->sync();
341     myCanvas->update();
342   }
343 }
344
345 void SUPERVGUI_Main::showCanvasTable() {
346   if (myCurrentView == CANVASTABLE) 
347     return;
348
349   if (myArray->create()) {
350     myCanvasView->hide();
351     myArrayView->show();
352     myCurrentView = CANVASTABLE;
353   }
354   sync();
355 }
356
357 void SUPERVGUI_Main::showContolFlow() {
358   bool merge = false;
359   if (myCurrentView == CANVASTABLE) {
360     myArrayView->hide();
361     myArray->destroy();
362     merge = true;
363   }
364   myCurrentView = CONTROLFLOW;
365   myCanvas->setControlView();
366   if (merge) {
367     myCanvas->merge();
368     myCanvasView->show();
369   }
370 }
371
372 void SUPERVGUI_Main::showCanvas() {
373   if (myCurrentView == CANVAS) 
374     return;
375
376   bool merge = false;
377   if (myCurrentView == CANVASTABLE) {
378     myArrayView->hide();
379     myArray->destroy();
380     merge = true;
381   }
382   myCurrentView = CANVAS;
383   myCanvas->setFullView();
384   if (merge) {
385     myCanvas->merge();
386     myCanvasView->show();
387   }
388 }
389
390 void SUPERVGUI_Main::insertFile() {
391   Trace("SUPERVGUI_Main::insertFile");
392
393   if ( !ReadyToModify() ) // null dataflow or executing, ..
394     return;
395
396   QString f = SUIT_FileDlg::getFileName(SUIT_Session::session()->activeApplication()->desktop(),
397                                         "",
398                                         "*.xml",
399                                         tr("MSG_GRAPH_INSERT"),
400                                         true);
401   if ( !f.isEmpty() ) { // not Cancel, but "OK" was pressed with valid file name
402       
403     Editing(); // PAL6170: GUI->Engine: setting "Editing" flag, why here? -> see 7960
404
405     if (dataflow->Import(f.latin1())) {
406       if (myCurrentView == CANVASTABLE) {
407         myArray->destroy();
408         myArray->create();
409       }
410       else { // (myCurrentView == CANVAS || myCurrentView == CONTROLFLOW) {
411         myCanvas->merge();
412       }
413       sync();
414     } else {
415       QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_BAD_FILE").arg(f));
416     }
417   }
418 }
419
420 void SUPERVGUI_Main::copy() {
421   Trace("SUPERVGUI_Main::copy");
422   if (dataflow->ThreadsMax() == 0) {
423     QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("WARNING"), tr("MSG_NOTHING_COPY"));
424     return;
425   }
426   
427   SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
428   if ( !aSupMod ) {
429     MESSAGE("NULL Supervision module!");
430     return;
431   }
432
433   SUPERVGraph_ViewFrame* aViewFrame = dynamic_cast<SUPERVGraph_ViewFrame*>( aSupMod->createGraph() );
434   if( aViewFrame ) {
435     SUPERV_Graph aNewGraph; //  = dataflow->StreamCopy();
436     if ( dataflow->IsStreamGraph() ) {
437       SUPERV_StreamGraph aSGraph = dataflow->ToStreamGraph();
438       if ( SUPERV_isNull(aSGraph) ) {
439         QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("WARNING"), tr("MSG_CANT_COPY"));
440         return;
441       }
442       aNewGraph = aSGraph->StreamCopy();
443     }
444     else {
445       aNewGraph = dataflow->Copy();
446     }
447     QString aNewName(tr("MSG_COPY_PREFIX").arg(++myCopyNum));
448     aNewName += dataflow->Name();
449     aNewGraph->SetName(aNewName);
450     /*SUPERVGUI_Main* m = */new SUPERVGUI_Main(aViewFrame, 
451                                                aSupMod->application()->desktop(),//getDesktop(), 
452                                                aNewGraph);
453     aViewFrame->show();
454   }
455 }
456
457 void SUPERVGUI_Main::openSubGraph(SUPERV_CNode theNode, bool correct)
458 {
459   if (theNode->IsMacro()) {
460     // get SubGraph from MacroNode
461     SUPERV_Graph aMacro = SUPERV::Graph::_narrow(theNode);
462     SUPERV_Graph aGraph;
463     if (aMacro->IsStreamMacro())
464       aGraph = aMacro->StreamObjRef();
465     else
466       aGraph = aMacro->FlowObjRef();
467
468     // display SubGraph
469     if (SUPERV_isNull(aGraph)) {
470       QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("WARNING"), tr("MSG_NOACCESS"));
471       return;
472     }
473     else {
474       QString aGraphName = aGraph->Name();
475       SUIT_ViewWindow* aStudyFrame;
476       if (mySubGraphs.contains(aGraphName)) {
477         aStudyFrame = mySubGraphs[aGraphName];
478         aStudyFrame->setActiveWindow();
479         aStudyFrame->setFocus();
480       }
481       else {
482         SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
483         if ( !aSupMod ) {
484           MESSAGE("NULL Supervision module!");
485           return;
486         }
487         
488         aStudyFrame = aSupMod->createGraph();
489         if ( aStudyFrame ) {
490           SUPERVGraph_ViewFrame* aViewFrame = dynamic_cast<SUPERVGraph_ViewFrame*>( aStudyFrame );
491           if( aViewFrame ) {
492             /*SUPERVGUI_Main* m = */new SUPERVGUI_Main(aViewFrame, 
493                                                        aSupMod->application()->desktop(),//getDesktop(), 
494                                                        aGraph);
495             //    connect(aStudyFrame, SIGNAL(sfStudyFrameClosing(QAD_StudyFrame*)), 
496             //            this,  SLOT(onSubGraphClosed(QAD_StudyFrame*)));
497             connect(aSupMod->application()->desktop(), SIGNAL(windowActivated( SUIT_ViewWindow* )), 
498                     this,  SLOT(onSubGraphActivated( SUIT_ViewWindow* )));
499             aStudyFrame->installEventFilter(this);
500
501             mySubGraphs.insert(aGraphName, aStudyFrame);
502             mySubGraphMap.insert(aGraphName, theNode->Name());
503
504           }
505         }
506       }
507       aStudyFrame->show();
508       if (!correct) myLastGraph = aStudyFrame;
509     }
510   }
511 }
512
513 bool SUPERVGUI_Main::eventFilter( QObject* o, QEvent* e)
514 {
515   // workaround to get close event
516   if (o->inherits("SUIT_ViewWindow"/*"QAD_StudyFrame"*/) && e->type() == QEvent::Close) {
517     SUIT_ViewWindow* aFrame = (SUIT_ViewWindow*) o;
518     onSubGraphClosed(aFrame);
519   }
520   return SUPERVGraph_View::eventFilter(o, e);
521 }
522
523 // workaround to fix PAL6255 -> opened SubGraph is not on top
524 void SUPERVGUI_Main::onSubGraphActivated(SUIT_ViewWindow* theStudyFrame)
525 {
526   if (myLastGraph) {
527     SUIT_ViewWindow* aFrame = myLastGraph;
528     myLastGraph = 0;
529     aFrame->setActiveWindow();
530     aFrame->setFocus();
531   }
532 }
533
534 void SUPERVGUI_Main::onSubGraphClosed(SUIT_ViewWindow* theStudyFrame)
535 {
536   if ( SUPERVGraph_ViewFrame* supervFrame = dynamic_cast<SUPERVGraph_ViewFrame*>( theStudyFrame ) ) {
537     theStudyFrame->removeEventFilter(this);
538     disconnect(theStudyFrame, 0, this, 0);
539
540     SUPERVGraph_View* view = supervFrame->getViewWidget();
541     SUPERVGUI_Main* aGraph = dynamic_cast<SUPERVGUI_Main*>(view);
542     if (aGraph) {
543       QString aGraphName = aGraph->getDataflow()->Name();
544       QMap<QString, QString>::iterator it = mySubGraphMap.find(aGraphName);
545       if (it != mySubGraphMap.end()) {
546         QString aNodeName = it.data();
547         SUPERVGUI_CanvasNode* aNode = (SUPERVGUI_CanvasNode*) 
548           myCanvas->child(aNodeName, "SUPERVGUI_CanvasNode");
549         if (aNode) {
550           aNode->merge();
551           myCanvas->update();
552         }
553         mySubGraphMap.remove(it);
554       }
555       mySubGraphs.remove(aGraphName);
556     }
557   }
558 }
559
560 void SUPERVGUI_Main::onShowToolbar()
561 {
562   SUPERVGraph_ViewFrame* aVF = (SUPERVGraph_ViewFrame*)this->parent();
563   if ( aVF )
564     aVF->getToolBar()->show();
565 }
566
567 // mkr : PAL8237 : synchronize many views of the same dataflow (objects creation/deletion)
568 void SUPERVGUI_Main::onObjectCreatedDeleted()
569 {
570   if ( study ) {
571     if ( STD_Application* app = dynamic_cast<STD_Application*>( study->application() ) ) {
572       ViewManagerList aVMList;
573       app->viewManagers( SUPERVGraph_Viewer::Type(), aVMList );
574       SUIT_ViewManager* aVM;
575       for ( aVM = aVMList.first(); aVM; aVM = aVMList.next() ) {
576         QPtrVector<SUIT_ViewWindow> aVWList = aVM->getViews();
577         for ( int i = 0; i < aVWList.count(); i++ ) {
578           SUPERVGraph_ViewFrame* aVW = dynamic_cast<SUPERVGraph_ViewFrame*>( aVWList[i] );
579           QObjectList* aMainList = aVW->queryList("SUPERVGUI_Main");
580           if ( aMainList->count() == 1 ) {
581             SUPERVGUI_Main* aMain = dynamic_cast<SUPERVGUI_Main*>( aMainList->first() );
582             if ( aMain )
583               if ( !QString(aMain->getDataflow()->getIOR()).compare(getDataflow()->getIOR()) // equal dataflows
584                    && 
585                    aMain != this ) // not equal mains
586                 aMain->getCanvas()->merge();
587           }
588         }
589       }
590     }
591   }
592 }
593
594 void SUPERVGUI_Main::run( const bool andSuspend ) {
595   Trace("SUPERVGUI_Main::run");
596   if ( SUPERV_isNull(dataflow) ) 
597     return;
598   
599   if ( dataflow->IsEditing() ) { // not currently Executing
600
601     // asv 31.01.05 : fix for PAL7854, Editing moved from SUPERVGUI.cxx runDataflow(), stepByStep() to here..
602     Editing(); // remove old executor, update GUI (all nodes to "No Status")
603
604     if ( !dataflow->IsValid() ) {
605       QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_DF_NOTVALID") + QString(" : ") + QString(dataflow->Messages()));
606     } 
607     else if (!dataflow->IsExecutable()) {
608       QString aMessage = QString(dataflow->Messages());
609       if ( aMessage.isEmpty() ) // mkr : IPAL11471
610         QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_DF_NOTEXECUTABLE"));
611       else
612         QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_DF_NOTEXECUTABLE") + QString(" : ") + aMessage);
613     } 
614     else if (myCanvasView->isAnyLinkCreating()) {
615       QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_CRL_NOTCOMPLETE"));
616     } 
617     else {
618       myRunTime = QDateTime::currentDateTime();
619       const bool result = andSuspend ? dataflow->Start() : dataflow->Run();
620       if ( !result ) {
621         QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_DF_BADEXECUTE"));
622         if ( dataflow->State() == SUPERV::ErrorState ) {
623           kill();
624         }
625       } 
626       else {
627         //myExecuted = true; // set to true on first execution. for correct publishing in Study
628         myThread->startThread(tr("MSG_GRAPH_STARTED"));
629       }
630     }
631   } 
632   else {
633     QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_DF_RUNNING"));
634   }
635 }
636
637
638 void SUPERVGUI_Main::kill() {
639   Trace("SUPERVGUI_Main::kill");
640   if ((SUPERV_isNull(dataflow))) 
641     return;
642
643   if (dataflow->IsEditing()) {
644     QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_DF_NOTRUNNING"));
645   } 
646   else if (dataflow->Kill()) {
647     getMessage()->putMessage( tr("MSG_GRAPH_KILLED") );
648     sync();
649   } 
650   else {
651     QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_CANTKILL_DF"));
652   }
653 }
654
655 void SUPERVGUI_Main::suspendResume() {
656     Trace("SUPERVGUI_Main::suspendResume");
657     if ((SUPERV_isNull(dataflow))) return;
658
659     if (dataflow->IsEditing()) {
660         QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_DF_NOTRUNNING"));
661     } else if (dataflow->State() == SUPERV_Suspend) {
662       if (dataflow->Resume()) {
663         myThread->startThread(tr("MSG_DF_RESUMED"));
664       } else {
665         QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_CANT_RESUME"));
666       }
667     } else {
668       if (dataflow->Suspend()) {
669         sync();
670         getMessage()->putMessage( tr("MSG_GRAPH_SUSPENDED") );
671       } else {
672         QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_CANT_SUSPEND"));
673       }
674     }
675 }
676 /* asv : 15.12.04 : commented out stopRestart() in Main and CanvasNode because it's not called from anywhere,
677    the comment from kloss below may be explaining it, but it's in French and I do not understand it..
678    It also calls deprecated method of Engine: ReStart(). 
679 void SUPERVGUI_Main::stopRestart() { // kloss : a reviser et a connecter dans le popup du dataflow (pas de creation de bouton)
680     Trace("SUPERVGUI_Main::stopRestart");
681     if ((SUPERV_isNull(dataflow))) return;
682
683     if (dataflow->IsEditing()) {
684         QMessageBox::warning(0, tr("ERROR"),  tr("MSG_DF_NOTRUNNING"));
685     } else if (dataflow->State() == SUPERV_Stop) {
686         if (dataflow->ReStart()) {
687             message->setMessage(tr("MSG_DF_RESTARTED"));
688             sync();
689         } else {
690             QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_RESTART"));
691         };
692     } else {
693         if (dataflow->Stop()) {
694             sync();
695         } else {
696             QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_STOP"));
697         };
698     };
699 }
700 */
701 void SUPERVGUI_Main::addNode() {
702   Trace("SUPERVGUI_Main::addNode");
703   
704   if ( !ReadyToModify() ) // null dataflow or executing, ..
705     return;
706   
707   SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
708   if ( !aSupMod ) {
709     MESSAGE("NULL Supervision module!");
710     return;
711   }
712
713   //Editing(); // PAL6170: GUI->Engine: setting "Editing" flag, commented: PAL7960
714   aSupMod->getBrowser()->choose();
715 }
716
717 /**
718  * Add Computation node
719  */
720 void SUPERVGUI_Main::addComputeNode(SUPERV_CNode theNode) {
721   switch (myCurrentView) {
722   case CANVASTABLE:
723     myArray->destroy();
724     myArray->create();
725     break;  
726   case CANVAS:
727   case CONTROLFLOW: 
728     {
729       SUPERVGUI_CanvasNode* aNode = new SUPERVGUI_CanvasComputeNode( resMgr(), myCanvas, this, theNode);
730       aNode->move(theNode->X(), theNode->Y());
731       if (myCurrentView == CONTROLFLOW) aNode->hideAll();
732       aNode->show();
733       myCanvas->update();
734     }
735     break;
736   }
737 }
738
739 /**
740  * Add GOTO node
741  */
742 void SUPERVGUI_Main::addGOTONode(SUPERV_CNode theNode) {
743   switch (myCurrentView) {
744   case CANVASTABLE:
745     myArray->destroy();
746     myArray->create();
747     break;
748   case CANVAS:
749   case CONTROLFLOW: 
750     {
751       SUPERVGUI_CanvasNode* aNode = new SUPERVGUI_CanvasGotoNode( resMgr(), myCanvas, this, theNode);
752       aNode->move(theNode->X(), theNode->Y());
753       if (myCurrentView == CONTROLFLOW) aNode->hideAll();
754       aNode->show();
755       myCanvas->update();
756     }
757     break;
758   }
759 }
760
761 /**
762  * Add Control node
763  */
764 void SUPERVGUI_Main::addControlNode(SUPERV_CNode theStartNode, SUPERV_CNode theEndNode, bool Update) {
765   switch (myCurrentView) {
766   case CANVASTABLE:
767     myArray->destroy();
768     myArray->create();
769     break;
770   case CANVAS:
771   case CONTROLFLOW: 
772     {
773       SUPERVGUI_CanvasStartNode* aStartNode = new SUPERVGUI_CanvasStartNode( resMgr(), myCanvas, this, theStartNode);
774       aStartNode->move(theStartNode->X(), theStartNode->Y());
775       if (myCurrentView == CONTROLFLOW) aStartNode->hideAll();
776
777       SUPERVGUI_CanvasEndNode* aEndNode = new SUPERVGUI_CanvasEndNode( resMgr(), myCanvas, this, theEndNode, aStartNode);
778       aEndNode->move(theEndNode->X(), theEndNode->Y());
779       if (myCurrentView == CONTROLFLOW) aEndNode->hideAll();
780
781       aStartNode->show();
782       aEndNode->show();
783       myCanvas->update();
784     }
785     break;
786   }
787 }
788
789
790 /**
791  * Add Macro node
792  */
793 void SUPERVGUI_Main::addMacroNode(SUPERV_CNode theNode) {
794   switch (myCurrentView) {
795   case CANVASTABLE:
796     myArray->destroy();
797     myArray->create();
798     break;
799   case CANVAS:
800   case CONTROLFLOW: 
801     {
802       SUPERVGUI_CanvasNode* aNode = new SUPERVGUI_CanvasMacroNode( resMgr(), myCanvas, this, theNode);
803       aNode->move(theNode->X(), theNode->Y());
804       if (myCurrentView == CONTROLFLOW) aNode->hideAll();
805       aNode->show();
806       myCanvas->update();
807     }
808     break;
809   }
810 }
811
812 SUPERVGUI_CanvasArray*  SUPERVGUI_Main::getCanvasArray() {
813   Trace("SUPERVGUI_Main::getCanvasArray");
814   return(myArray);
815 }
816
817 SUPERVGUI_ArrayView* SUPERVGUI_Main::getArrayView() {
818   Trace("SUPERVGUI_Main::getArrayView");
819   return(myArrayView);
820 }
821
822 SUPERVGUI_Canvas* SUPERVGUI_Main::getCanvas() {
823   Trace("SUPERVGUI_Main::getCanvas");
824   return(myCanvas);
825 }
826
827 SUPERVGUI_CanvasView* SUPERVGUI_Main::getCanvasView() {
828     Trace("SUPERVGUI_Main::getCanvasView");
829     return(myCanvasView);
830 }
831
832 SUPERV_Graph SUPERVGUI_Main::getDataflow() {
833   Trace("SUPERVGUI_Main::getDataflow");
834   return(dataflow);
835 }
836
837 LogWindow* SUPERVGUI_Main::getMessage() {
838   Trace("SUPERVGUI_Main::getMessage");
839   return(message);
840 }
841
842 SUIT_Study* SUPERVGUI_Main::getStudy() {
843   Trace("SUPERVGUI_Main::getStudy");
844   return(study);
845 }
846
847 bool SUPERVGUI_Main::isArrayShown() {
848   Trace("SUPERVGUI_Main::isArrayShown");
849   return(myCurrentView == CANVASTABLE);  
850 }
851
852 void SUPERVGUI_Main::showPopup(QPopupMenu* p, QMouseEvent* e) {
853   Trace("SUPERVGUI_Main::showPopup");
854   // To check is Supervision active?
855   if (myIsLocked) return;
856   //if (dataflow->IsExecuting()) return;
857
858   CAM_Application* anApp = ( CAM_Application* )(SUIT_Session::session()->activeApplication());
859   if ( !anApp->activeModule() ) return;
860   if ( anApp->activeModule()->moduleName().compare( anApp->moduleTitle( "SUPERV" ) ) !=0 ) return;
861
862   if (e->button() == RightButton) {
863     p->exec(e->globalPos());
864   }
865 }
866
867 void SUPERVGUI_Main::changeInformation() {
868   SUPERVGUI_Information* aDlg = new SUPERVGUI_Information(SUPERV::CNode::_narrow(dataflow), dataflow->IsReadOnly());
869   if (aDlg->exec() )
870     sync();
871   delete aDlg;
872 }
873
874 void SUPERVGUI_Main::chooseData(QListViewItem* item) {
875     Trace("SUPERVGUI_Main::chooseData");
876     if (choosing) {
877       QString id = ((OB_ListItem*)item)->text(2);// <=> get entry
878       if (!id.isEmpty()) {
879         _PTR(SObject) object ( (( SalomeApp_Study* )study)->studyDS()->FindObjectID(id.latin1()) );
880         _PTR(GenericAttribute) anAttr;
881         if (object->FindAttribute(anAttr, "AttributeIOR")) {
882           _PTR(AttributeIOR) anIOR ( anAttr );
883           
884           // asv : 13.12.04 : commented out use of portIn field, but it seems that it 
885           // should be replaced with some analogious code... selection of IOR was done -
886           // put its value into port.
887           //portIn->setValue(ior);
888           
889           SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
890           if ( !aSupMod ) {
891             MESSAGE("NULL Supervision module!");
892             return;
893           }
894
895           // stop selection
896           choosing = false;
897           setCursor(aSupMod->getCursor());
898           objectBrowser->setCursor(aSupMod->getCursor());
899           aSupMod->putInfo("");
900         }
901       }
902     }
903 }
904
905 _PTR(SObject) SearchOrCreateSOWithName( _PTR(Study) const theStudy,
906                                         _PTR(StudyBuilder) const theBuilder,
907                                         _PTR(SObject) const theSO,
908                                         const char* theName,
909                                         bool* theDoneSomething ) {
910   _PTR(SObject) aResult;
911   _PTR(AttributeName) aName;
912   _PTR(GenericAttribute) anAttr;
913   _PTR(ChildIterator) anIterator ( theStudy->NewChildIterator(theSO) );
914   for (; anIterator->More(); anIterator->Next()) {
915     if (anIterator->Value()->FindAttribute(anAttr, "AttributeName")) {
916       aName = anAttr;
917       if (strcmp(aName->Value().c_str(), theName) == 0) {
918         aResult = anIterator->Value();
919         break;
920       }
921     }
922   }
923
924   // if aResule was found then theDoneSomething=false and we return
925   *theDoneSomething = !aResult ? 1 : 0;//->_is_nil();
926   if ( !*theDoneSomething )
927     return aResult;
928
929   // add new SObject
930   aResult = theBuilder->NewObject( theSO );
931   anAttr = theBuilder->FindOrCreateAttribute(aResult, "AttributeName");
932   aName = anAttr;
933   aName->SetValue(theName);
934   return aResult;
935 }
936     
937 /**
938  * Return true if dataflow is already in the study
939  */
940 bool SUPERVGUI_Main::isDataflowInStudy() const {
941   _PTR(Study) aStudy = (( SalomeApp_Study* )study)->studyDS();
942   _PTR(SObject) aSO ( aStudy->FindObjectIOR( dataflow->getIOR() ) );
943   return ( aSO ? true : false );
944 }
945
946 /**
947  * Create a "Supervision" object in the Study and a "dataflow" object under it
948  * aDoneSomething will be true if "Supervision" or "dataflow" object were created (not found).
949  */
950 _PTR(SObject) createDataflowSObj( SUIT_Study* study, 
951                                   SUPERV::Graph_var dataflow, 
952                                   _PTR(StudyBuilder) aBuilder,
953                                   bool& aDoneSomething ) {
954   _PTR(Study)            aStudy = (( SalomeApp_Study* )study)->studyDS();
955   _PTR(GenericAttribute) anAttr;
956   _PTR(AttributeName)    aName;
957
958   // Find or create "Supervisor -> aNewDataflow_1" SObjects in the study
959   _PTR(SObject) aSO = aStudy->FindObjectIOR( dataflow->getIOR() );
960   if ( !aSO ) { // dataflow SObject not found in the study
961     aDoneSomething = true; 
962     _PTR(SComponent) aComponent = aStudy->FindComponent(STUDY_SUPERVISION);
963     if ( !aComponent ) { // is supervision component not found, then create it
964       aComponent = aBuilder->NewComponent(STUDY_SUPERVISION);
965       anAttr = aBuilder->FindOrCreateAttribute(aComponent, "AttributeName");
966       aName = anAttr;
967       aName->SetValue( (( CAM_Application* )(study->application()))->moduleTitle( "SUPERV" ).latin1() );
968         
969       anAttr = aBuilder->FindOrCreateAttribute(aComponent, "AttributePixMap");
970       _PTR(AttributePixMap) aPixmap ( anAttr );
971       aPixmap->SetPixMap( "ICON_OBJBROWSER_Supervision" );
972
973       SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
974       if ( aSupMod )
975         aBuilder->DefineComponentInstance(aComponent, SalomeApp_Application::orb()->object_to_string(aSupMod->getEngine()));
976                                                     //dynamic_cast<SALOMEDS_Study*>( aStudy )->ConvertObjectToIOR(aSupMod->getEngine()));
977       else MESSAGE("NULL Supervision module!");
978       
979     }
980     // create dataflow SObject ("aNewDataflow_1") 
981     aSO = aBuilder->NewObject(aComponent);
982     anAttr =  aBuilder->FindOrCreateAttribute(aSO, "AttributeName");
983     aName = anAttr;
984     aName->SetValue(dataflow->Name());
985     anAttr =  aBuilder->FindOrCreateAttribute(aSO, "AttributeIOR");
986     _PTR(AttributeIOR) anIORAttr ( anAttr );
987     anIORAttr->SetValue(dataflow->getIOR());
988   }
989
990   return aSO;
991 }
992
993 void SUPERVGUI_Main::addDataflowToStudy() {
994   bool isCreated;
995   _PTR(StudyBuilder) aBuilder ( (( SalomeApp_Study* )study)->studyDS()->NewBuilder() );
996   aBuilder->NewCommand();
997   _PTR(SObject) aDF ( createDataflowSObj( study, dataflow, aBuilder, isCreated ) );
998   if ( aDF ) {
999     aBuilder->CommitCommand();
1000     // what is this register/unregister?? don't know..
1001     SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
1002     if ( !aSupMod ) {
1003       MESSAGE("NULL Supervision module!");
1004       return;
1005     }
1006     aSupMod->unregisterGraph(this);
1007     aSupMod->registerGraph(dataflow->getIOR(), this);
1008
1009     if ( !myThread->running() )
1010       aSupMod->updateObjBrowser();
1011   }
1012   else {
1013     MESSAGE( "ERROR: failed to find or create dataflow SObject" );
1014     aBuilder->AbortCommand();
1015   }
1016 }
1017
1018 bool SUPERVGUI_Main::putDataStudy( SUPERV_Port p, const char* inout ) {
1019   Trace("SUPERVGUI_Main::putDataStudy");
1020
1021   bool PublishOtherComponent = false;
1022
1023   // static variable to ensure that only one instance (thread) is executing this function 
1024   static bool isIn = false;
1025   if (isIn)   return true; 
1026   else        isIn = true;
1027
1028   _PTR(Study)        aStudy = (( SalomeApp_Study* )study)->studyDS();
1029   const bool         aLocked = aStudy->GetProperties()->IsLocked();
1030   _PTR(StudyBuilder) aBuilder ( aStudy->NewBuilder() );
1031   bool                           aDoneSomething = false;
1032
1033   // asv 23.11.04 : fix for PAL6852 if the study is locked -- then we can't put anything in it.
1034   if ( aLocked ) {
1035     MESSAGE( "The study is locked and can not be modified!" );
1036     isIn = false;
1037     return false;
1038   }
1039
1040   // check if the port and its node are good
1041   if ( CORBA::is_nil( p ) || CORBA::is_nil( p->Node() ) ) {
1042     MESSAGE( "putInStudy ERROR: port or node are NULL!" );
1043     isIn = false;
1044     return false;
1045   }
1046
1047   // open new command.  Commit or Abort it depending on aDoneSomething variable or error
1048   aBuilder->NewCommand();
1049   
1050   // Find or create "Supervisor -> aNewDataflow_1" SObjects in the study
1051   _PTR(SObject) aSO = createDataflowSObj( study, dataflow, aBuilder, aDoneSomething );
1052
1053   if ( !aSO ) {
1054     MESSAGE( "ERROR: putDataStudy() could not find or create dataflow SObject" ); 
1055     aBuilder->AbortCommand();
1056     isIn = false;
1057     return false;
1058   }
1059
1060   // Create "Run -> Time and date, etc." SObjects
1061   if  ( p->State() == SUPERV::ReadyState ) { // if port contains valid computed value
1062
1063     aSO = SearchOrCreateSOWithName( aStudy, aBuilder, aSO, QString("Run ") + myRunTime.toString(), &aDoneSomething ); // get run time SO
1064     aSO = SearchOrCreateSOWithName( aStudy, aBuilder, aSO, p->Node()->Name(), &aDoneSomething ); // get node SO
1065     aSO = SearchOrCreateSOWithName( aStudy, aBuilder, aSO, inout, &aDoneSomething ); // get in/out SO
1066     aSO = SearchOrCreateSOWithName( aStudy, aBuilder, aSO, p->Name(), &aDoneSomething ); // get port SO
1067
1068     // create IOR attribute for port SObject (usually with "return" name)
1069     _PTR(GenericAttribute) anAttr ( aBuilder->FindOrCreateAttribute(aSO, "AttributeIOR") );
1070     _PTR(AttributeIOR) anIORAttr  ( anAttr );
1071
1072     // if we have not created anything (all SObject already existed) and we have the same IORAttribute
1073     // on the needed SObject -> then don't do anything! it's already there!
1074     if ( !aDoneSomething && strcmp(anIORAttr->Value().c_str(), p->ToString()) == 0 ) {
1075       aBuilder->AbortCommand();
1076       isIn = false;
1077       return true;
1078     }
1079
1080     aDoneSomething = true; // going to set some value to anIORAttr any way from this point..
1081
1082     // set object value to the study: if object is external, then put it with
1083     //  help of the specific component - owner
1084     if ( p->IsIOR() ) {
1085       // get according component driver for result object
1086       SALOME_LifeCycleCORBA aLCC( myNService );
1087       SUPERV_FNode aFNode = SUPERV::FNode::_narrow( p->Node() );
1088       if ( !aFNode->_is_nil() ) {
1089         Engines::Component_var aComponent = aLCC.FindOrLoad_Component( aFNode->GetContainer(), aFNode->GetComponentName() );
1090         SALOMEDS::Driver_var aDriver = SALOMEDS::Driver::_narrow( aComponent );
1091         if ( !CORBA::is_nil( aDriver ) ) { // if driver was found, publish object
1092           CORBA::Object_ptr anObject = new CORBA::Object();
1093           CORBA::Any* anAny = p->ToAny();
1094           (*anAny) >>= anObject;
1095         
1096           if ( aDriver->CanPublishInStudy( anObject ) ) {
1097             SALOMEDS::SObject_var aTmpSO;// = aSO;
1098             SALOMEDS_Study* aSStudy = dynamic_cast<SALOMEDS_Study*>( aStudy.get() );
1099             if ( !aSStudy ) return false;
1100             try {
1101               aTmpSO = aDriver->PublishInStudy( aSStudy->GetStudy(), aTmpSO, anObject, "" );
1102               aBuilder->Addreference(aSO, _PTR(SObject)(new SALOMEDS_SObject( aTmpSO )) );
1103               PublishOtherComponent = true;
1104             }
1105             catch ( ... ) { // mkr : PAL8150
1106             }
1107           } 
1108           else { // can't publish object: abort transaction
1109             MESSAGE( "CanPublishInStudy() returned FALSE.  ok, AbortCommand.." );
1110             aBuilder->AbortCommand();
1111             isIn = false;
1112             return false;
1113           }
1114         }
1115         else { // component has no driver, but could store IORs (like Calculator)
1116           _PTR(SObject) anIORSO ( aStudy->FindObjectIOR( p->ToString() ) );
1117           if ( anIORSO ) {
1118             aBuilder->Addreference(aSO, anIORSO);
1119             // mkr : IPAL9672
1120             PublishOtherComponent = true;
1121           }
1122           else { // Hm... the object (==port value) was not found, so we don't publish it.
1123             MESSAGE( "The object (==port value) was not found, so we don't publish it" );
1124             aBuilder->AbortCommand();
1125             isIn = false;
1126             return false;
1127           }
1128         }
1129       }
1130       else { // FNode is NULL -> bad
1131         MESSAGE( "FNode is NULL." );
1132         if ( SUPERV::INode::_narrow( p->Node() ) ) { // mkr : IPAL10175
1133           _PTR(SObject) anIORSO ( aStudy->FindObjectIOR( p->ToString() ) );
1134           if ( anIORSO )
1135             aBuilder->Addreference(aSO, anIORSO);
1136         }
1137         else {
1138           MESSAGE( "FNode and INode are NULL.  Not good at all.  Aborting command." );
1139           aBuilder->AbortCommand();
1140           isIn = false;
1141           return false;
1142         }
1143       }
1144     } 
1145     else {
1146       anIORAttr->SetValue( p->ToString() ); // ior attribute already set for the prevoius condition
1147     }
1148   }
1149
1150   if ( aDoneSomething )
1151     aBuilder->CommitCommand();
1152   else
1153     aBuilder->AbortCommand();
1154
1155   SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
1156   if ( aSupMod ) {
1157     if ( PublishOtherComponent )
1158       dynamic_cast<SalomeApp_Application*>( study->application() )->updateObjectBrowser(true);
1159     else
1160       aSupMod->updateObjBrowser();
1161   }
1162   else MESSAGE("NULL Supervision module!");
1163   
1164   isIn = false;
1165   return true;
1166 }
1167
1168
1169 void SUPERVGUI_Main::ActivatePanning()
1170 {
1171   if (myCanvasView->isVisible()) {
1172     myCanvasView->ActivatePanning();
1173   } else if (myArrayView->isVisible()) {
1174     myArrayView->ActivatePanning();
1175   }
1176 }
1177
1178
1179 void SUPERVGUI_Main::ResetView()
1180 {
1181   if (myCanvasView->isVisible()) {
1182     myCanvasView->ResetView();
1183   } else if (myArrayView->isVisible()) {
1184     myArrayView->ResetView();
1185   }
1186 }
1187
1188 void SUPERVGUI_Main::syncNotification() {
1189   char* graph;
1190   char* node;
1191   char* type;
1192   char* message;
1193   char* sender;
1194   long  counter;
1195   char* date;
1196   long  stamp;
1197   
1198   while (notification->Receive(&graph, &node, &type, &message, &sender, &counter, &date, &stamp)) {
1199 //    if (isFiltered(graph, node, type, message, sender, counter, date, stamp)) {
1200       QString mess("");
1201       mess += "NOTIF: "; mess += graph;
1202       mess += " / "    ; mess += node;
1203       mess += " / "    ; mess += type;
1204       mess += " / "    ; mess += message;
1205       getMessage()->putMessage(mess.latin1());
1206 //    };
1207   };
1208 }
1209   
1210 bool SUPERVGUI_Main::isFiltered(char* graph,  char* node,   char* type, char* message, 
1211                                 char* sender, long counter, char* date, long stamp) {
1212   Trace("SUPERVGUI_Main::isFiltered");
1213   bool b = false;
1214   if (strcmp(getDataflow()->Name(), graph) == 0) {
1215     SUPERVGUI_CanvasNode* n;
1216     QObjectList* nodes = queryList("SUPERVGUI_CanvasNode");
1217     QObjectListIt i(*nodes);
1218     while ((n=(SUPERVGUI_CanvasNode*)i.current()) != 0) {
1219       ++i;
1220       if (strcmp(n->name(), node) == 0) {
1221         if (strcmp(type, NOTIF_WARNING) == 0) {
1222           b = n->isWarning();
1223         } else if (strcmp(type, NOTIF_STEP) == 0) {
1224           b = n->isStep();
1225         } else if (strcmp(type, NOTIF_TRACE) == 0) {
1226           b = n->isTrace();
1227         } else if (strcmp(type, NOTIF_VERBOSE) == 0) {
1228           b = n->isVerbose();
1229         };
1230         break;
1231       };
1232     };
1233     delete nodes;
1234     if ( myLogged && myLogFile && ( ( !myFiltered ) || b ) ) {
1235       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 );
1236       fflush( myLogFile );
1237     };
1238   };
1239   return( b );
1240 }
1241
1242 void SUPERVGUI_Main::closeEvent(QCloseEvent* e) {
1243   e->accept();
1244 }
1245
1246
1247 void SUPERVGUI_Main::setPaletteBackgroundColor(const QColor& color) { 
1248
1249   myCanvas->setBackgroundColor(color);
1250   myCanvasView->setPaletteBackgroundColor(color.light());
1251   myArray->setBackgroundColor(color);
1252   myArrayView->setPaletteBackgroundColor(color.light());
1253   
1254   SUPERVGraph_View::setPaletteBackgroundColor(color); 
1255 }
1256
1257 QPtrList< char * > SUPERVGUI_Main::getEventNodes() {
1258   return myEventNodes;
1259 }
1260
1261 void SUPERVGUI_Main::setEventNodes(QPtrList< char * > theEventNodes) {
1262   myEventNodes = theEventNodes;
1263 }
1264
1265 QPtrList< SUPERV::GraphState > SUPERVGUI_Main::getStates() {
1266   return myStates;
1267 }
1268
1269 void SUPERVGUI_Main::setStates(QPtrList< SUPERV::GraphState > theStates) {
1270   myStates = theStates;
1271 }
1272
1273 int SUPERVGUI_Main::getNodesNumber() {
1274   //create a list of nodes of the graph
1275   SUPERV_Nodes nodes = getDataflow()->Nodes();
1276   int RetVal = nodes->CNodes.length() + nodes->FNodes.length() +
1277                nodes->INodes.length() + nodes->GNodes.length() +
1278                nodes->LNodes.length() + nodes->SNodes.length();
1279   return RetVal;
1280 }
1281
1282 SUPERVGUI_Thread* SUPERVGUI_Main::getMyThread() {
1283   return myThread;
1284 }
1285
1286 void SUPERVGUI_Main::startTimer() {
1287   myTimer->start(500);
1288 }
1289
1290 void SUPERVGUI_Main::executionFinished() {
1291   SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
1292   if ( aSupMod ) 
1293     //aSupMod->updateObjBrowser();
1294     // PAL10611: update all modules data
1295     aSupMod->getApp()->updateObjectBrowser(true);
1296   else MESSAGE("NULL Supervision module!");
1297   
1298   myCanvas->update();
1299   myArray->update();
1300 }
1301
1302 void SUPERVGUI_Main::checkExecution() {
1303   if (myThread->finished()) {
1304     myTimer->stop();
1305     executionFinished();
1306   }
1307 }
1308
1309 /**
1310  * Editing() is to be called by any operation in GUI before modification of a datamodel
1311  * (add/remove ports or nodes, etc.).  It is used to resolve inconsistancies between 2 data models
1312  * in Engine: Editor and Executor.  During and after execution, the values of ports and statuses of nodes
1313  * are taken from Executor data model.  But when user starts editing the graph - these changes must
1314  * be applied to Editor data model.  This function destroys Executor data model and moves to Editor.   
1315  */ 
1316 void SUPERVGUI_Main::Editing() {
1317   if ( !SUPERV_isNull( dataflow ) )
1318     dataflow->Editing();
1319   
1320   // updata GUI, Nodes' statuses and Ports' values could change.
1321   sync();
1322 }
1323
1324 void SUPERVGUI_Main::removeArrayChild(SUPERV::CNode_ptr theNode)
1325 {
1326   // mkr: since the deletion of the node allow only in CANVAS view,
1327   // it is necessary to remove the CanvasArray's children, which
1328   // have the same CNode engine as deleting node. This CNode is given
1329   // as argument
1330   if (myArray) {
1331     const QObjectList* aChList = myArray->children();
1332     if ( aChList ) { // asv 27.01.05 : fix for 7817
1333       QObjectListIt aItChList(*aChList);
1334       SUPERVGUI_CanvasNode* anObjNode;
1335       while ((anObjNode = (SUPERVGUI_CanvasNode*)aItChList.current()) != 0) {
1336         ++aItChList;
1337         if ((QString(anObjNode->getEngine()->Name())).compare(QString(theNode->Name())) == 0) {
1338           myArray->removeChild(anObjNode);
1339           delete anObjNode;
1340         }
1341       }
1342     } // end of if ( ChList )
1343   }
1344 }
1345
1346 /**
1347  * ReadyToModify() must be called before any modification
1348  * operation - asks to kill execution of dataflow.  If returns false - 
1349  * modification (==Editing() ) is not allowed.
1350  */
1351 bool SUPERVGUI_Main::ReadyToModify() {
1352   if ( CORBA::is_nil( dataflow ) )
1353     return false;
1354   if ( dataflow->IsExecuting() ) {
1355     bool quit = SUIT_MessageBox::warn2( SUIT_Session::session()->activeApplication()->desktop(), // 0=Yes, 1=No
1356       tr("WARNING"), tr("MSG_GRAPH_ISRUN"), tr( "BUT_YES" ), tr( "BUT_CANCEL" ), 0, 1, 0 );
1357     if ( quit ) // user selected NOT to kill dataflow and NOT to add new node
1358       return false;
1359     else  if ( dataflow->IsExecuting() ) // user selected to kill the dataflow and add new node after that
1360       kill();   // checking again for IsExecuting to be sure that it was not finished while MB was up
1361   }
1362   return true;
1363 }
1364
1365 void SUPERVGUI_Main::resizeView( QResizeEvent* theEvent )
1366 {
1367   if ( (myCurrentView == CANVAS || myCurrentView == CONTROLFLOW) && getCanvas() )
1368     if ( getCanvas()->width() < theEvent->size().width()
1369          ||
1370          getCanvas()->height() < theEvent->size().height() )
1371       getCanvas()->resize( theEvent->size().width(), theEvent->size().height() );
1372   if ( myCurrentView == CANVASTABLE && getCanvasArray() )
1373     if ( getCanvasArray()->width() < theEvent->size().width()
1374          ||
1375          getCanvasArray()->height() < theEvent->size().height() )
1376       getCanvasArray()->resize( theEvent->size().width(), theEvent->size().height() );
1377 }
1378
1379 /******************************* SUPERVGUI_Thread class ****************************************/
1380 SUPERVGUI_Thread::SUPERVGUI_Thread()
1381      :QThread()
1382 {
1383   myIsActive = false;
1384 }
1385
1386 SUPERVGUI_Thread::~SUPERVGUI_Thread()
1387 {
1388   //it is a virtual destructor and needs to be determine here
1389 }
1390
1391 void SUPERVGUI_Thread::startThread(const char* m)
1392 {
1393   if (!myIsActive) {
1394     myIsActive = true;
1395     
1396     myMain->getMessage()->putMessage(m); 
1397     myMain->sync();
1398
1399     start();
1400   }
1401 }
1402
1403 void SUPERVGUI_Thread::setMain( SUPERVGUI_Main* theMain )
1404 {
1405   myMain = theMain;
1406 }
1407
1408 void SUPERVGUI_Thread::KillThread( bool theValue )
1409 {
1410   myMutex.lock();
1411   myIsActive = !(theValue);
1412   myMutex.unlock();
1413 }
1414
1415 template<class TObject, typename TArg, typename TArg1, typename TArg2,
1416          typename TStoreArg = TArg, typename TStoreArg1 = TArg1, typename TStoreArg2 = TArg2>
1417 class TVoidMemFun3ArgEvent: public SALOME_Event{
1418 public:
1419   typedef void (TObject::* TAction)(TArg,TArg1,TArg2);
1420   TVoidMemFun3ArgEvent(TObject* theObject, TAction theAction, TArg theArg, TArg1 theArg1, TArg2 theArg2):
1421     myObject(theObject),
1422     myAction(theAction),
1423     myArg(theArg),
1424     myArg1(theArg1),
1425     myArg2(theArg2)
1426   {}
1427   virtual void Execute(){
1428     (myObject->*myAction)(myArg,myArg1,myArg2);
1429   }
1430 private:
1431   TObject* myObject;
1432   TAction myAction;
1433   TStoreArg myArg;
1434   TStoreArg1 myArg1;
1435   TStoreArg2 myArg2;
1436 };
1437
1438 typedef TVoidMemFun3ArgEvent<SUPERVGUI_Thread, SUPERV_CNode&, SUPERV::GraphEvent&, SUPERV::GraphState&> TMainRunEvent;
1439
1440 /**
1441  * main_thread_run must be executed in the qt main thread
1442  * It is activated by calling ProcessVoidEvent
1443  */
1444 void SUPERVGUI_Thread::main_thread_run(SUPERV_CNode& aNode, SUPERV::GraphEvent& aEvent, SUPERV::GraphState& aState)
1445 {
1446     // in case node "said" something during changing state through notification mechanism - output it
1447     myMain->syncNotification();
1448     
1449     // "kill" or undefined event came
1450     if (( aEvent == SUPERV::UndefinedEvent && aState == SUPERV::UndefinedState ) ||
1451        ( aEvent == SUPERV::NoEvent && aState == SUPERV::NoState ) ||
1452        ( aEvent == SUPERV::KillEvent && aState == SUPERV::KillState )) {
1453
1454       myIsActive = false;
1455     }
1456     else { // a "normal" execution event came
1457       char* aName = NULL;
1458       if ( aNode != NULL && !CORBA::is_nil( aNode ) ) 
1459        aName = aNode->Name();      
1460
1461       // What follow is not quite sure. The entire function is posted to the main qt thread.
1462       // So all executions are serialized. Is it really possible to call execute when another
1463       // execute is running. I don't think so (C Caremoli)
1464       // this function is asynchronious.  The call does NOT wait when SUPERVGUI_Main::execute finishes
1465       // handling the event.  So: SUPERVGUI_Main::execute must be fast, in order we don't get here again
1466       // on the next loop iteration, BEFORE  previous SUPERVGUI_Main::execute finished.
1467       myMain->execute(aName, aState );
1468     }    
1469
1470     // execution is finished.  just set a "finished" message(s)
1471     if ( !myIsActive ) {
1472       switch ( myMain->getDataflow()->State() ) {
1473       case SUPERV_Editing :     
1474        myMain->getMessage()->putMessage( myMain->getDataflow()->IsReadOnly()? 
1475                                         tr("MSG_GRAPH_READONLY"): tr("MSG_GRAPH_EDITING") );
1476        break;  
1477       case SUPERV_Suspend : 
1478        myMain->getMessage()->putMessage( tr("MSG_GRAPH_SUSPENDED") );
1479        break; 
1480       case SUPERV_Done : 
1481        myMain->getMessage()->putMessage( tr("MSG_GRAPH_FINISHED") );
1482        break;  
1483       case SUPERV_Error :
1484        myMain->getMessage()->putMessage( tr("MSG_GRAPH_ABORTED") );
1485        break;  
1486       case SUPERV_Kill:
1487        myMain->getMessage()->putMessage( tr("MSG_GRAPH_KILLED") );
1488        break;
1489       } // end of switch
1490
1491       // asv 03.02.05 : fix for PAL6859, not very good, but works..
1492       myMain->sync();
1493     } // end of if !myIsActive
1494 }
1495
1496 void SUPERVGUI_Thread::run()
1497 {
1498   myMain->startTimer();
1499   
1500   // GUI cycle to handle events coming for Engine
1501   while ( myIsActive ) {
1502     
1503     SUPERV_CNode aNode = NULL;
1504     SUPERV::GraphEvent aEvent = SUPERV::UndefinedEvent ;
1505     SUPERV::GraphState aState = SUPERV::UndefinedState ;
1506     
1507     // blocking function of Engine.  Return from there only after anEvent happens on node aNode
1508     myMain->getDataflow()->Event(aNode, aEvent, aState);
1509     
1510     ProcessVoidEvent( new TMainRunEvent( this, &SUPERVGUI_Thread::main_thread_run,aNode, aEvent, aState ) );
1511     
1512   } // end of while( myIsActive )
1513   
1514   QThread::exit();
1515 }
1516
1517 /******************************* SUPERVGUI_DSGraphParameters class ****************************************/
1518 /*!
1519   Constructor
1520 */
1521 SUPERVGUI_DSGraphParameters::SUPERVGUI_DSGraphParameters(SUPERV_Graph theGraph, bool isReadOnly)
1522      : QDialog( SUIT_Session::session()->activeApplication()->desktop(), "", true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ) 
1523 {
1524   Trace("SUPERVGUI_DSGraphParameters::SUPERVGUI_DSGraphParameters");
1525   setCaption( tr( "TLT_DSGRAPHPARAMS" ) );
1526   setSizeGripEnabled( true );
1527   myGraph = theGraph;
1528
1529   QGridLayout* TopLayout = new QGridLayout( this );
1530   TopLayout->setSpacing( 6 );
1531   TopLayout->setMargin( 11 );
1532     
1533   QGroupBox* TopGroup = new QGroupBox( this, "TopGroup" );
1534   TopGroup->setColumnLayout(0, Qt::Vertical );
1535   TopGroup->layout()->setSpacing( 0 );
1536   TopGroup->layout()->setMargin( 0 );
1537   QGridLayout* TopGroupLayout = new QGridLayout( TopGroup->layout() );
1538   TopGroupLayout->setAlignment( Qt::AlignTop );
1539   TopGroupLayout->setSpacing( 6 );
1540   TopGroupLayout->setMargin( 11 );
1541
1542   // DeltaTime
1543   QLabel* DeltaTimeL = new QLabel( tr( "DELTATIME_LBL" ), TopGroup );  
1544   TopGroupLayout->addWidget( DeltaTimeL, 0, 0 );
1545   
1546   myDeltaTime = new QtxDblSpinBox( 0.0, 1.0, 0.1, TopGroup );
1547   myDeltaTime->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
1548   TopGroupLayout->addWidget( myDeltaTime, 0, 1 );
1549
1550   // TimeOut
1551   QLabel* TimeOutL = new QLabel( tr( "TIMEOUT_LBL" ), TopGroup); 
1552   TopGroupLayout->addWidget( TimeOutL, 1, 0 );
1553
1554   myTimeOut = new QLineEdit( TopGroup );
1555   myTimeOut->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
1556   myTimeOut->setValidator( new QIntValidator(this) );
1557   myTimeOut->setMinimumSize( 100, 0 );
1558   myTimeOut->setReadOnly( isReadOnly );
1559   TopGroupLayout->addWidget( myTimeOut, 1, 1 );
1560
1561   // DataStreamTrace
1562   QLabel* DataStreamTraceL = new QLabel( tr( "DATASTREAMTRACE_LBL" ), TopGroup); 
1563   TopGroupLayout->addWidget( DataStreamTraceL, 2, 0 );
1564
1565   myDataStreamTrace = new QComboBox( TopGroup );
1566   myDataStreamTrace->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
1567   myDataStreamTrace->insertItem("WithoutTrace");
1568   myDataStreamTrace->insertItem("SummaryTrace");
1569   myDataStreamTrace->insertItem("DetailedTrace");
1570   TopGroupLayout->addWidget( myDataStreamTrace, 2, 1 );
1571
1572   QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" );
1573   GroupButtons->setColumnLayout(0, Qt::Vertical );
1574   GroupButtons->layout()->setSpacing( 0 );
1575   GroupButtons->layout()->setMargin( 0 );
1576   QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
1577   GroupButtonsLayout->setAlignment( Qt::AlignTop );
1578   GroupButtonsLayout->setSpacing( 6 );
1579   GroupButtonsLayout->setMargin( 11 );
1580   
1581   QPushButton* okB     = new QPushButton( tr( "BUT_OK" ),     GroupButtons );
1582   QPushButton* cancelB = new QPushButton( tr( "BUT_CANCEL" ), GroupButtons );
1583
1584   GroupButtonsLayout->addWidget( okB, 0, 0 );
1585   GroupButtonsLayout->addItem  ( new QSpacerItem( 5, 5, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 1 );
1586   GroupButtonsLayout->addWidget( cancelB, 0, 2 );
1587
1588   TopLayout->addWidget( TopGroup,     0, 0 );
1589   TopLayout->addWidget( GroupButtons, 1, 0 );
1590
1591   connect( okB,     SIGNAL( clicked() ), this, SLOT( accept() ) );
1592   connect( cancelB, SIGNAL( clicked() ), this, SLOT( reject() ) );
1593
1594   setData();
1595 }
1596
1597 /*!
1598   Destructor
1599 */
1600 SUPERVGUI_DSGraphParameters::~SUPERVGUI_DSGraphParameters() {
1601   Trace("SUPERVGUI_DSGraphParameters::~SUPERVGUI_DSGraphParameters");
1602 }
1603
1604 /*!
1605   Sets data function
1606 */
1607 void SUPERVGUI_DSGraphParameters::setData() {
1608   double aDeltaTime;
1609   long aTimeOut;
1610   SUPERV::KindOfDataStreamTrace aDataStreamTrace;
1611
1612 //  myGraph->StreamParams(aTimeOut, aDataStreamTrace, aDeltaTime);
1613   if (myGraph->IsStreamGraph()) {
1614     SUPERV_StreamGraph aSGraph = myGraph->ToStreamGraph();
1615     if (!SUPERV_isNull(aSGraph)) 
1616       aSGraph->StreamParams(aTimeOut, aDataStreamTrace, aDeltaTime);
1617   }
1618
1619   myDeltaTime->setValue(aDeltaTime);
1620   myTimeOut->setText(QString("%1").arg(aTimeOut));
1621   myDataStreamTrace->setCurrentItem((int)aDataStreamTrace);
1622 }
1623
1624 /*!
1625   <OK> button slot
1626 */
1627 void SUPERVGUI_DSGraphParameters::accept() {
1628 //   myGraph->SetStreamParams( myTimeOut->text().toLong(),
1629 //                          (SUPERV::KindOfDataStreamTrace) myDataStreamTrace->currentItem(),
1630 //                          myDeltaTime->value());
1631   if (myGraph->IsStreamGraph()) {
1632     SUPERV_StreamGraph aSGraph = myGraph->ToStreamGraph();
1633     if (!SUPERV_isNull(aSGraph)) 
1634       aSGraph->SetStreamParams( myTimeOut->text().toLong(),
1635                                 (SUPERV::KindOfDataStreamTrace) myDataStreamTrace->currentItem(),
1636                                 myDeltaTime->value());
1637   }
1638   QDialog::accept();
1639 }