Salome HOME
Modifications for correct adding factory nodes into the dataflow.
[modules/superv.git] / src / SUPERVGUI / SUPERVGUI.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.cxx
25 //  Author : Francis KLOSS
26 //  Module : SUPERV
27
28 using namespace std;
29 #include "SUPERVGUI.h"
30 #include "SUPERVGUI_DataModel.h"
31
32 #include "SALOMEDSClient.hxx"
33 #include <boost/shared_ptr.hpp>
34 using namespace boost;
35
36 #include "CAM_Application.h"
37 #include "OB_Browser.h"
38 #include "OB_ListItem.h"
39 #include "SalomeApp_Application.h"
40 #include "SalomeApp_ImportOperation.h"
41 #include "SalomeApp_NameDlg.h"
42 #include "SalomeApp_SelectionMgr.h"
43 #include "SalomeApp_Study.h"
44 #include "SUIT_Desktop.h"
45 #include "SUIT_FileDlg.h"
46 #include "SUIT_MessageBox.h"
47 #include "SUIT_Operation.h"
48 #include "SUIT_ResourceMgr.h"
49 #include "SUIT_Session.h"
50 #include "SUIT_Study.h"
51
52 #include "SUPERVGraph_ViewManager.h"
53
54 #include "SALOME_ListIO.hxx"
55 #include "SALOME_ListIteratorOfListIO.hxx"
56 #include "SALOME_InteractiveObject.hxx"
57 #include "Utils_ORB_INIT.hxx"
58
59 #include CORBA_SERVER_HEADER(SALOMEDS_Attributes)
60
61 #include <qmenubar.h>
62
63 int SUPERVGUI::factory = 0;
64
65 extern "C" {
66   Standard_EXPORT CAM_Module* createModule() {
67     return new SUPERVGUI();
68   }
69 }
70
71
72 SUPERVGUI::SUPERVGUI()
73      : SalomeApp_Module( "SUPERV" ),
74        study(0),
75        browser(0)
76   //info(0)
77 {
78     Trace("SUPERVGUI::SUPERVGUI")
79     if (factory==0) {
80         factory = 1;
81         MESSAGE("SUPERVGUI Info : factory build");
82     } else {
83         MESSAGE("SUPERVGUI Error : another call to factory constructor");
84     };
85 }
86
87 SUPERVGUI::~SUPERVGUI() {
88     Trace("SUPERVGUI::~SUPERVGUI")
89     if (factory==1) {
90         factory = 0;
91         //if (!engine->_is_nil()) CORBA::release(engine);         
92         //info->close();
93         if (browser) {
94           if (browser->isVisible())
95             browser->close();
96           delete browser;
97         }
98         MESSAGE("SUPERVGUI Info : factory destroy");
99     } else {
100         MESSAGE("SUPERVGUI Error : another call to factory destructor");
101     };
102 }
103
104 SUPERVGUI* SUPERVGUI::Supervision() {
105   CAM_Application* anApp = dynamic_cast<CAM_Application*>( SUIT_Session::session()->activeApplication() );
106   if ( anApp ) {
107     SUPERVGUI* aSupervModule = dynamic_cast<SUPERVGUI*>( anApp->activeModule() );
108     return aSupervModule;
109   }
110   return NULL;
111 }
112
113 void SUPERVGUI::createSupervAction( const int id, const QString& po_id, const QString& icon_id, const int key, const bool toggle  )
114 {
115   QIconSet icon;
116   QWidget* parent = application()->desktop();
117   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
118   QPixmap pix;
119   if ( icon_id.length() ) 
120     pix = resMgr->loadPixmap( "SUPERV", tr( icon_id ) );
121   else
122     pix = resMgr->loadPixmap( "SUPERV", tr( QString( "ICO_" )+po_id ) );
123   if ( !pix.isNull() )
124     icon = QIconSet( pix );
125
126   QString tooltip    = tr( QString( "TOP_" )+po_id ),
127           menu       = tr( QString( "MEN_" )+po_id ),
128           status_bar = tr( QString( "STB_" )+po_id );
129
130   createAction( id, tooltip, icon, menu, status_bar, key, parent, toggle, this, SLOT( OnGUIEvent() )  );
131 }
132
133 void SUPERVGUI::initialize( CAM_Application* app )
134 {
135   SalomeApp_Module::initialize( app );
136
137   SALOME_NamingService* namingService = (( SalomeApp_Application* )application())->namingService();
138   loadEngine(namingService);
139
140   browser = new SUPERVGUI_Service(namingService);
141   //info    = new SUPERVGUI_Information();
142   cursor  = application()->desktop()->cursor();
143
144   fillInterfaceNameMap();
145
146   // ----- create actions --------------
147   createSupervAction( 301, "IMPORT" );
148   createSupervAction( 302, "EXPORT" );
149
150   createSupervAction( 303, "NEW" );
151   createSupervAction( 304, "MODIFY" );
152
153   createSupervAction( 305, "RELOAD" );
154   createSupervAction( 306, "RUN" );
155   createSupervAction( 307, "KILL" );
156   createSupervAction( 308, "SUSPEND/RESUME" );
157   createSupervAction( 309, "ADDNODE" );
158   createSupervAction( 310, "STEPBYSTEP" );
159
160   // ----- create menu -----------------
161   int fileId = createMenu( tr( "MEN_FILE" ), -1, -1 );
162   createMenu( 301, fileId, 10 );
163   createMenu( 302, fileId, 10 );
164   createMenu( separator(), fileId, 10 );
165
166   int editId = createMenu( tr( "MEN_EDIT" ), -1, -1 );
167   createMenu( separator(), fileId, 7 );
168   createMenu( 303, editId, -1 );
169   createMenu( 304, editId, -1 );
170
171   int supervId = createMenu( tr( "MEN_SUPERV" ), -1, -1, 10/*, 300*/ );
172   createMenu( 305, supervId, -1 );
173   createMenu( 309, supervId, -1 );
174   createMenu( separator(), fileId, 3 );
175   createMenu( 306, supervId, -1 );
176   createMenu( 310, supervId, -1 );
177   createMenu( 307, supervId, -1 );
178   createMenu( 308, supervId, -1 );     
179
180   // ----- create toolbars -------------
181   int supervisorId = createTool( tr( "TOOL_SUPERVISOR" ) );
182   createTool( 301, supervisorId );
183   createTool( 302, supervisorId );
184   createTool( 303, supervisorId );
185   createTool( 304, supervisorId );
186   createTool( 305, supervisorId );
187   createTool( 309, supervisorId );
188
189   int executionId = createTool( tr( "TOOL_EXECUTION" ) );
190   createTool( 306, executionId );
191   createTool( 310, executionId );
192   createTool( 307, executionId );
193   createTool( 308, executionId );
194
195 }
196
197 bool SUPERVGUI::activateModule( SUIT_Study* theStudy )
198 {
199   if ( CORBA::is_nil( engine ) )
200     return false;
201
202   if ( !SalomeApp_Module::activateModule( theStudy ) )
203     return false;
204
205
206
207   //---------------------------------------
208   setMenuShown( true );
209   setToolShown( true );
210
211   study = application()->activeStudy();
212
213   connect( application()->desktop(), SIGNAL( windowActivated( SUIT_ViewWindow* ) ), 
214            this, SLOT( setMain( SUIT_ViewWindow* ) ) );
215
216   return true;
217 }
218
219 QString SUPERVGUI::engineIOR() const 
220 {
221  if ( !CORBA::is_nil( engine ) )
222     return QString( getApp()->orb()->object_to_string( engine));
223   return QString( "" );
224 }
225
226 bool SUPERVGUI::deactivateModule( SUIT_Study* theStudy )
227 {
228   setMenuShown( false );
229   setToolShown( false );
230
231   disconnect( application()->desktop(), SIGNAL( windowActivated( SUIT_ViewWindow* ) ), 
232               this, SLOT( setMain( SUIT_ViewWindow* ) ) );
233   //---------------------------------------
234
235   return SalomeApp_Module::deactivateModule( theStudy );
236 }
237
238 CAM_DataModel* SUPERVGUI::createDataModel()
239 {
240   return new SUPERVGUI_DataModel( this );
241 }
242
243 SUIT_ViewWindow* SUPERVGUI::createGraph() {
244   SUPERVGraph_ViewManager* aVM = new SUPERVGraph_ViewManager( study, application()->desktop(), new SUPERVGraph_Viewer() );
245   SUIT_ViewWindow* aVW = aVM->createViewWindow();
246   if ( aVW ) {
247     connect( aVM, 
248              SIGNAL( deleteView( SUIT_ViewWindow* ) ),
249              this,
250              SLOT( onGraphClosed( SUIT_ViewWindow* ) ) );
251   }
252   return aVW;
253 }
254
255
256
257 void SUPERVGUI::loadEngine(SALOME_NamingService* namingService) {
258     Trace("SUPERVGUI::loadEngine")
259     SALOME_LifeCycleCORBA LCC(namingService);
260     Engines::Component_var objComponent = LCC.FindOrLoad_Component("SuperVisionContainer", "SUPERV");
261     if (CORBA::is_nil(objComponent)) {
262         QMessageBox::warning(application()->desktop(), tr("ERROR"), tr("MSG_CANT_LOAD_SUPERV"));
263         return;
264     };
265
266     SUPERV::SuperG_var aSuperVisionComponent;
267     aSuperVisionComponent = SUPERV::SuperG::_narrow(objComponent);
268     if (CORBA::is_nil(aSuperVisionComponent)) {
269         QMessageBox::warning(application()->desktop(), tr("ERROR"), tr("MSG_CANT_NARROW_SUPERV"));
270         return;
271     };
272
273     //    engine  = new SUPERV::SuperG_var;
274     engine = aSuperVisionComponent;
275 }
276
277 /*
278 bool SUPERVGUI::information(SUPERV_CNode node, bool isReadOnly) {
279     Trace("SUPERVGUI::information")
280     return(info->run(node, isReadOnly));
281 }
282 */
283 void SUPERVGUI::putInfo(const char* mess) {
284     Trace("SUPERVGUI::putInfo")
285     application()->putInfo(mess);
286 }
287
288 SUPERV_Engine SUPERVGUI::getEngine() {
289     Trace("SUPERVGUI::getEngine")
290     return(engine);
291 }
292
293 SUPERVGUI_Service* SUPERVGUI::getBrowser() {
294     Trace("SUPERVGUI::getBrowser")
295     return(browser);
296 }
297
298 QCursor SUPERVGUI::getCursor() {
299     Trace("SUPERVGUI::getCursor")
300     return(cursor);
301 }
302
303 SUPERVGUI_Main* SUPERVGUI::getMain() {
304     Trace("SUPERVGUI::getMain")
305     return main;
306 }
307
308
309 void SUPERVGUI::registerGraph(QString theName, SUPERVGUI_Main* theGraph){
310   theGraph->setHashCode(theName);
311   myGraphList.append(theGraph);
312 }
313
314
315 void SUPERVGUI::unregisterGraph(SUPERVGUI_Main* theGraph) {
316   SUPERVGUI_Main* aMain;
317   for (aMain = myGraphList.first(); aMain; aMain = myGraphList.next()) {
318     if (aMain == theGraph)
319       myGraphList.remove(aMain);
320   }
321 }
322
323
324 bool SUPERVGUI::isContains(SUIT_Study* theStudy, const QString theKey) {
325   SUPERVGUI_Main* aMain;
326   for (aMain = myGraphList.first(); aMain; aMain = myGraphList.next()) {
327     if ((aMain->getStudy() == theStudy) && (aMain->getHashCode() == theKey))
328       return true;
329   }
330   return false;
331 }
332
333
334 void SUPERVGUI::onGraphClosed(SUIT_ViewWindow* theViewWindow) {
335   if( SUPERVGraph_ViewFrame* supervFrame = dynamic_cast<SUPERVGraph_ViewFrame*>(theViewWindow) ) {
336     disconnect(supervFrame->getViewManager(), 0 , this, 0);
337     SUPERVGraph_View* view = supervFrame->getViewWidget();
338     SUPERVGUI_Main* aGraph = dynamic_cast<SUPERVGUI_Main*>(view);
339     if ( aGraph ) {
340       unregisterGraph(aGraph);
341       SUPERV_Graph aDataFlow = aGraph->getDataflow();
342       if ( !SUPERV_isNull( aDataFlow ) ) {
343         if ( aDataFlow->IsExecuting() ) {
344           const int aMsgResult = QMessageBox::warning(application()->desktop(),
345                                                       tr("WARNING"), 
346                                                       tr("MSG_DF_RUNNING"), 
347                                                       tr("MSG_DF_EXECUTION"), 
348                                                       tr("MSG_DF_KILL"));
349           if ( aMsgResult == 1 ) {
350             // KILL EXECUTION
351             if ( aDataFlow->Kill() ) {
352               // Kill() sends KillEvent and KillState to SUPERVGUI_Thread
353               // while sets myIsActive flag to false when it receives such event/state
354               // after myIsActive is false it calls QThread::exit() to terminate.
355
356               // why while() { qApp->processEvents() } ?
357               // because: SUPERVGUI_Thread::run() receives events, and calls myMain->execute()
358               // method using SALOME_Event paradigm, ProcessVoidEvent() function - 
359               // it puts this event to the main application event loop, in which we are being now.
360               // So if we block main GUI application thread (by calling aGraph->getMyThread()->wait() here)
361               // then we will have a deadlock of 2 threads waiting for one another 
362               while (aGraph->getMyThread()->running()) 
363                 qApp->processEvents();
364             }
365           }
366           else { // BACKGROUND EXECUTION
367             emit KillMainThread(true); // set SUPERVGUI_Thread::myIsActive to false
368             while ( aGraph->getMyThread()->running() )
369               qApp->processEvents();
370           }
371         }
372         else { // EXECUTION IS FINISHED, JUST DESTROY THE SUPERVGUI_Thread object and return.
373           emit KillMainThread(true);
374           while ( aGraph->getMyThread()->running() ) 
375             qApp->processEvents();
376         }
377       }
378     }
379   }
380 }
381
382 void SUPERVGUI::setMain( SUIT_ViewWindow* w) {
383   main = 0;
384   if ( !w ) return;
385
386   study = w->getViewManager()->study();
387   if (!study) {
388     cout<<" setMain(...) : NULL study!";
389     return;
390   }
391
392   if(SUPERVGraph_ViewFrame* supervFrame = dynamic_cast<SUPERVGraph_ViewFrame*>(w)){
393     SUPERVGraph_View* view = supervFrame->getViewWidget();
394     if (view) {
395       main = dynamic_cast<SUPERVGUI_Main*>(view);
396       connect(this, SIGNAL(KillMainThread(bool)), main->getMyThread(), SLOT(KillThread(bool)));
397     }
398   }
399   Trace("SUPERVGUI::setMain - main: "<<main);
400 }
401
402 void SUPERVGUI::displayDataflow() {
403     Trace("SUPERVGUI::displayDataflow");
404     OB_Browser* aBrowser = (( SalomeApp_Application* )application())->objectBrowser();
405     SUPERV_Graph aDataFlow;
406     QString aIORName;
407
408     OB_ListItem* item = (OB_ListItem*)(aBrowser->listView()->currentItem());
409     _PTR(SObject) aObj 
410       ( (( SalomeApp_Study* )(application()->activeStudy()))->studyDS()->FindObjectID(item->text(2).latin1()) );
411     _PTR(GenericAttribute) anAttr;
412     if (aObj->FindAttribute(anAttr, "AttributeIOR")) {
413       _PTR(AttributeIOR) anIOR ( anAttr );
414       aIORName = QString(anIOR->Value().c_str());
415       if (isContains(study, aIORName)) {
416         if (QMessageBox::warning(application()->desktop(), tr("WARNING"), 
417                                  tr("MSG_GRAPH_DISPLAYED").arg(""), 
418                                  QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
419           return;
420       }
421       //aDataFlow = engine->getStreamGraph(anIOR->Value().c_str());
422       aDataFlow = engine->getGraph(anIOR->Value().c_str());
423       if (SUPERV_isNull(aDataFlow)) {
424         QMessageBox::warning(0, tr("ERROR"), tr("MSG_ACCESS_BAD_IOR"));
425         return;
426       }
427       /* ASV: 20.10.04: fix for 6896
428       if (aDataFlow->IsStreamGraph()) {
429         SUPERV_StreamGraph aDataFlowStream = aDataFlow->ToStreamGraph();
430         if (SUPERV_isNull(aDataFlowStream)) {
431           QMessageBox::warning(0, tr("ERROR"), tr("MSG_ACCESS_BAD_IOR"));
432           return;
433         }
434         aDataFlow = aDataFlowStream;
435       }
436       */
437     }
438     SUPERVGraph_ViewFrame* aViewFrame = dynamic_cast<SUPERVGraph_ViewFrame*>( createGraph() );
439     if( aViewFrame ) {
440       main = new SUPERVGUI_Main( aViewFrame, application()->desktop(), aDataFlow );
441       registerGraph( aIORName, main );
442       aViewFrame->show();
443     }
444 }
445
446
447 void SUPERVGUI::renameDataflow() {
448   SALOME_ListIO aList;
449   aList.Clear();
450   (( SalomeApp_Application* )application())->selectionMgr()->selectedObjects( aList );
451
452   SALOME_ListIteratorOfListIO It( aList );
453   for ( ; It.More(); It.Next() ) {
454     Handle(SALOME_InteractiveObject) IObject = It.Value();
455     
456     _PTR(Study) aStudy = (( SalomeApp_Study* )study)->studyDS();
457     _PTR(SObject) obj ( aStudy->FindObjectID( IObject->getEntry() ) );
458     _PTR(GenericAttribute) anAttr;
459     if ( obj ) {
460       if ( obj->FindAttribute(anAttr, "AttributeName") ) {
461         _PTR(AttributeName) aName ( anAttr );
462         QString nm = QString( aName->Value().c_str() );
463         nm = SalomeApp_NameDlg::getName( application()->desktop(), nm );
464         if ( !nm.isEmpty() ) {
465           // sak : 24.11.04 : fix for PAL6898 : if rename fails (study locked), 
466           // a message box is displayed, and cursor is "wait cursor".  We think that "wait cursor"
467           // is not neccessary here, because the rename operation is fast.
468           //QApplication::setOverrideCursor( Qt::waitCursor );
469           //study->renameIObject( IObject, nm );
470
471           //--->
472           aName->SetValue( nm.latin1() );
473           //rename Interactive object 
474           IObject->setName( ( char* )nm.latin1() );
475           //<---
476
477           updateObjBrowser();
478           //QApplication::restoreOverrideCursor();
479         }
480       }
481     }
482   }
483 }
484
485 void SUPERVGUI::exportDataflow() {
486     Trace("SUPERVGUI::exportDataflow")
487     if ( main==0 ) {
488       QMessageBox::warning(application()->desktop(), tr("WARNING"), tr("MSG_NOWINDOW_TO_EXPORT"));
489     } 
490     else if ( SUPERV_isNull( main->getDataflow() ) ) { // should not normally happen..
491       QMessageBox::warning(application()->desktop(), tr("WARNING"), tr("MSG_NOWINDOW_TO_EXPORT"));
492     } 
493     else {
494       QString f = SUIT_FileDlg::getFileName(application()->desktop(),
495                                             "",
496                                             "*.xml",
497                                             tr("TTL_EXPORT_DATAFLOW"),
498                                             false);
499       if ( !f.isEmpty() ) {
500         
501         // asv : bug [VSR Bugs and Improvements in Supervisor] 1.8 : when exporting a file, 
502         // a backup copy of an existing file must be created (in case Export fails..)
503         QString aBackupFile = SUPERVGUI::createBackupFile( f );
504
505         if ( main->getDataflow()->Export(f.latin1()) ) {
506           unregisterGraph(main);
507           registerGraph(f, main);
508
509           // remove a backup file if export was successfull
510           if ( !aBackupFile.isNull() && !aBackupFile.isEmpty() )
511             QFile::remove( aBackupFile );
512         }
513         else {
514           QMessageBox::warning(application()->desktop(), tr("ERROR"), tr("MSG_BAD_WRITING").arg(aBackupFile));
515         }
516       }
517     }
518 }
519
520 /** 
521  *If a file with theOriginalFileName exists, then the function tries to create 
522  * its backup copy of it (the_name + ".bakX", X = 0,1,2,..,99).  Returns backup file's name
523  * If a file with theOriginalFileName does not exist, or creation fails - Return empty string.
524  */
525 QString SUPERVGUI::createBackupFile( const QString& theOriginalFileName ) {
526   QString theBackupFileName("");
527   if ( QFile::exists( theOriginalFileName ) ) {
528     // 1. construct a backup file name
529     int i = 0;
530     do {
531       theBackupFileName = theOriginalFileName;
532       theBackupFileName += ".bak";
533       theBackupFileName += QString::number(i++);
534     } 
535     while ( QFile::exists( theBackupFileName ) && i < 100 ); // max 99 backup files
536     // if *.bak99 exists -- it will be overwritten 
537     
538     // 2. copy the original file to theBackupFileName
539     QString cmd( "cp \"");
540     cmd += theOriginalFileName;
541     cmd += "\" \"";
542     cmd += theBackupFileName;
543     cmd += "\"";
544     bool res = system( cmd.latin1() );
545     if ( res ) 
546       theBackupFileName = QString("");
547   }
548   return theBackupFileName;
549 }
550
551 void SUPERVGUI::windows( QMap<int, int>& mappa ) const
552 {
553   mappa.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::DockLeft );
554   mappa.insert( SalomeApp_Application::WT_PyConsole, Qt::DockBottom );
555   mappa.insert( SalomeApp_Application::WT_LogWindow, Qt::DockBottom );
556 }
557
558 void SUPERVGUI::newDataflow() {
559   createDataflow( New );
560 }
561
562 void SUPERVGUI::importDataflow() {
563   createDataflow( Import );
564 }
565
566 void SUPERVGUI::modifyDataflow() {
567   createDataflow( Modify );
568 }
569
570 bool SUPERVGUI::createDataflow( const NEW_DF_MODE mode ) {
571   Trace("SUPERVGUI::createDataflow, mode = " << mode );
572
573   // asv : 27.01.05 : fix for PAL7823 : if the study is locked - warn the user and return.
574   _PTR(Study) aStudy = (( SalomeApp_Study* )study)->studyDS();
575   if ( aStudy->GetProperties()->IsLocked() ) {
576     QMessageBox::warning(application()->desktop(), tr("WRN_WARNING"), tr("WRN_STUDY_LOCKED"));
577     return false;
578   }
579
580   SUPERV::Graph_var aGraph;
581
582   QString f; // file name.  declared here because may be used below in error msg construction..
583   if ( mode == Import || mode == Modify ) { // 0. import or modify existing dataflow - select XML file
584     QString title = QString( "TLT_CREATE_DF_%1" ).arg( mode );
585     f = SUIT_FileDlg::getFileName( application()->desktop(), "", "*.xml", tr( title ), true );
586     if ( f.isEmpty() ) // pressed Cancel in file select dialog
587       return false;
588     
589     // check if study already contains a graph imported from the same file
590     if ( isContains( study, f ) ) {
591       if ( QMessageBox::warning( application()->desktop(), tr("WARNING"), tr("MSG_GRAPH_DISPLAYED").arg(f), 
592                                  QMessageBox::Yes, QMessageBox::No) == QMessageBox::No )
593         return false;
594     }
595     
596     // 1. create a graph
597     aGraph = ( mode == Import ) ? engine->StreamGraphE( f ) : engine->StreamGraph( f );        
598   }
599   else
600     aGraph = engine->StreamGraph( MAIN_NEW );
601
602   if ( CORBA::is_nil( aGraph ) ) {
603     QString msg( mode == New ? tr("MSG_CANT_CREATE_DF") : tr("MSG_BAD_FILE").arg(f) );
604     SUIT_MessageBox::warn1( application()->desktop(), tr("ERROR"), tr(msg), tr("BUT_OK") );
605     return false;
606   }
607
608   // 2. create a ViewFrame object
609   SUPERVGraph_ViewFrame* aViewFrame = dynamic_cast<SUPERVGraph_ViewFrame*>( createGraph() );
610   if ( aViewFrame ) {
611
612     // 3. bind Graph and ViewFrame == create SUPERVGUI_Main object
613     main = new SUPERVGUI_Main( aViewFrame, application()->desktop(), aGraph );
614     if ( mode == New )
615       main->addNode();
616     else
617       registerGraph( f, main );
618     aViewFrame->show();
619   }
620
621   return true;
622 }
623
624 void SUPERVGUI::reloadDataflow() {
625   Trace("SUPERVGUI::reloadDataflow");
626   if ( main )  
627     main->sync();
628   else 
629     QMessageBox::warning(application()->desktop(), tr("WARNING"), tr("MSG_NOWINDOW_TO_RELOAD"));
630 }
631
632 void SUPERVGUI::runDataflow() {
633   Trace("SUPERVGUI::runDataflow");
634   if ( main )
635     main->run( /*andSuspend=*/false );
636   else
637     QMessageBox::warning(application()->desktop(), tr("WARNING"), tr("MSG_NOWINDOW_TO_RUN"));
638 }
639
640 void SUPERVGUI::stepByStep() {
641   Trace("SUPERVGUI::stepByStep");
642   if ( main )
643     main->run( /*andSuspend=*/true );
644   else
645     QMessageBox::warning(application()->desktop(), tr("WARNING"), tr("MSG_NOWINDOW_TO_RUN"));
646 }
647
648 void SUPERVGUI::killDataflow() {
649   Trace("SUPERVGUI::killDataflow");
650   if ( main )
651     main->kill();
652   else
653     QMessageBox::warning(application()->desktop(), tr("WARNING"), tr("MSG_NOWINDOW_TO_KILL"));
654 }
655
656 void SUPERVGUI::suspendResumeDataflow() {
657   Trace("SUPERVGUI::suspendResumeDataflow");
658   if ( main )
659     main->suspendResume();
660   else
661     QMessageBox::warning(application()->desktop(), tr("WARNING"), tr("MSG_NOWINDOW_TO_SUSPEND"));
662 }
663
664 void SUPERVGUI::showComponents() {
665   Trace("SUPERVGUI::showComponents");
666   if ( main ) {
667     if ( main->isEditable() )
668       main->addNode();
669     else
670       QMessageBox::warning(application()->desktop(), tr("WARNING"), tr("MSG_NOTEDITABLE"));
671   }
672   else
673     QMessageBox::warning(application()->desktop(), tr("WARNING"), tr("MSG_NOWINDOW_TO_ADD"));
674
675 }
676
677
678 /*bool SUPERVGUI::CustomPopup(QPopupMenu* popup, const QString& theContext, const QString& theParent, const QString& theObject) {
679   Trace("SUPERVGUI::customPopup");
680   Supervision.init();
681   if(popup->count() > 3) {
682     // Temporary code: is to be deleted soon
683     popup->removeItem(QAD_Display_Popup_ID);
684     popup->removeItem(QAD_DisplayOnly_Popup_ID);
685     popup->removeItem(QAD_Erase_Popup_ID);
686     int id = popup->idAt(popup->count() - 1);
687     if (id < 0 && id != -1) popup->removeItem(id); // separator
688     // Temporary code end
689   }
690   
691   SALOME_ListIO aList;
692   aList.Clear();
693   (( SalomeApp_Application* )application())->selectionMgr()->selectedObjects( aList );
694   if ( aList.Extent() == 0 ) return false;
695   
696   if ( aList.Extent() == 1 ) {
697     Handle(SALOME_InteractiveObject) anIObj = aList.First();
698     
699     // insert SUPERV-specific popup items here
700     
701     bool isDataflow, ownObj;
702     whatIsSelected(anIObj, ownObj, isDataflow);
703     
704     if (isDataflow) {
705       popup->insertItem(tr( "MSG_RENAME" ), this, SLOT(renameDataflow()));
706       popup->insertItem("Display", this, SLOT(displayDataflow()));
707       popup->insertSeparator();
708     }
709     if (ownObj)
710       popup->insertItem(tr("MSG_DELETE"), this, SLOT(deleteObject()));
711   }
712
713   if ( aList.Extent() > 1 ) {
714     int aIObjCount = 0;
715     SALOME_ListIteratorOfListIO It_forCheckOwner( aList );
716     for(;It_forCheckOwner.More();It_forCheckOwner.Next()) {
717       Handle(SALOME_InteractiveObject) anIObj = It_forCheckOwner.Value();
718       bool aIsOwner, aIsDataflow;
719       whatIsSelected(anIObj, aIsOwner, aIsDataflow);
720       
721       if (aIsOwner) aIObjCount++;
722     }
723     if ( aIObjCount == aList.Extent() )  //all selected objects belong to Supervision
724       popup->insertItem(tr("MSG_DELETE"), this, SLOT(deleteObject()));
725   }
726
727   return(true);
728   }*/
729
730  
731
732 /** Returns:
733     theIsOwner = true if Selected object belongs to Suipervision.
734     theIsDataflow = true if Selected object is Dataflow
735 */
736 void SUPERVGUI::whatIsSelected(const Handle(SALOME_InteractiveObject)& theObj, bool& theIsOwner, bool& theIsDataflow) {
737   theIsOwner = false;
738   theIsDataflow = false;
739
740   if (theObj.IsNull()) return;
741   
742   _PTR(Study) aStudy = (( SalomeApp_Study* )study)->studyDS();
743   _PTR(SObject) obj ( aStudy->FindObjectID( theObj->getEntry() ) );
744
745   if ( obj ) {
746     _PTR(SComponent) comp ( obj->GetFatherComponent() );
747     if ( comp ) {
748       _PTR(GenericAttribute) anAttr;
749       if (comp->FindAttribute(anAttr, "AttributeName")) {
750         _PTR(AttributeName) aName ( anAttr );
751         QString compName(aName->Value().c_str());
752         if ( compName.compare( (( CAM_Application* )application())->moduleTitle( moduleName() ) ) == 0 ) {
753           _PTR(GenericAttribute) anAttr;
754           if (obj->FindAttribute(anAttr, "AttributeIOR")) {
755             _PTR(AttributeIOR) anIOR ( anAttr );
756             SUPERV_Graph aDataFlow = engine->getGraph(anIOR->Value().c_str());
757             if (!SUPERV_isNull(aDataFlow)) {
758               if (aDataFlow->IsStreamGraph()) {
759                 if (!SUPERV_isNull(aDataFlow->ToStreamGraph()))
760                   theIsDataflow = true;
761               }
762               else
763                 theIsDataflow = true;
764             }
765           }
766           CORBA::String_var anObjectID = obj->GetID().c_str();
767           CORBA::String_var aComponentID = comp->GetID().c_str();
768           if (strcmp(anObjectID, aComponentID)) theIsOwner = true;          
769         }
770       }
771     }
772   }
773 }
774
775 void SUPERVGUI::deleteObject() {
776   SALOME_ListIO aList;
777   aList.Clear();
778   (( SalomeApp_Application* )application())->selectionMgr()->selectedObjects( aList );
779   if ( aList.Extent() == 0 ) return;
780    
781   // sak : 24.11.04 : fix for PAL6899 : if the study is locked - warn the user and return.
782   _PTR(Study) aStudy = (( SalomeApp_Study* )study)->studyDS();
783   if ( aStudy->GetProperties()->IsLocked() ) {
784     QMessageBox::warning(application()->desktop(), tr("WRN_WARNING"), tr("WRN_STUDY_LOCKED"));
785     return;
786   }
787
788   // sak : 24.11.04 : fix for PAL6901 : Incorrect deletion of the objects : pressing ESC button
789   // emitted "YES" button click, now it is corrected, and treated as "NO" button click.
790   if (QMessageBox::warning(application()->desktop(),
791                            tr("WARNING"),
792                            tr("MSG_ASK_DELETE"),
793                            QMessageBox::No, QMessageBox::Yes) != QMessageBox::Yes)
794     return;
795    
796   SALOME_ListIteratorOfListIO It( aList );
797   for(;It.More();It.Next()) {
798     Handle(SALOME_InteractiveObject) anIObj = It.Value();
799     bool aIsOwner, aIsDataflow;
800     whatIsSelected(anIObj, aIsOwner, aIsDataflow);
801     
802     _PTR(SObject) aObj ( aStudy->FindObjectID( anIObj->getEntry() ) );
803     if ( aObj ) {
804       SUIT_Operation* op = new SalomeApp_ImportOperation( application() );
805       _PTR(StudyBuilder) aBuilder ( aStudy->NewBuilder() );
806       op->start();
807       aBuilder->RemoveObjectWithChildren( aObj );
808       op->commit();
809     }
810   }
811   (( SalomeApp_Application* )application())->selectionMgr()->clearSelected();
812 }
813
814 void SUPERVGUI::OnGUIEvent()
815 {
816   const QObject* obj = sender();
817   if ( !obj || !obj->inherits( "QAction" ) )
818     return;
819   int id = actionId((QAction*)obj);
820   if ( id != -1 )
821     OnGUIEvent( id );
822 }
823
824 bool SUPERVGUI::OnGUIEvent(int command) {
825   switch (command) {
826   case 301: 
827     importDataflow();
828     return(false);
829     
830   case 302: 
831     exportDataflow();
832     return(false);
833     
834   case 303: 
835     newDataflow();
836     return(false);
837     
838   case 304: 
839     modifyDataflow();
840     return(false);
841     
842   case 305:
843     reloadDataflow();
844     return(false);
845     
846   case 306:
847     runDataflow();
848     return(false);
849     
850   case 307: 
851     killDataflow();
852     return(false);
853     
854   case 308:
855     suspendResumeDataflow();
856     return(false);
857     
858   case 309: 
859     showComponents();
860     return(false);
861     
862   case 310: 
863     stepByStep();
864     return(false);
865     
866   default: 
867     QMessageBox::warning(application()->desktop(), "Supervision Error", "Unknown Command From Salome");
868     return(false);
869   }
870 }
871
872 /*bool SUPERVGUI::SetSettings() {
873   Trace("SUPERVGUI::SetSettings");
874   Supervision.init();
875   return(true);
876   }*/
877
878 /*void SUPERVGUI::DefinePopup(QString& theContext, QString& theParent, QString& theObject) {
879   theObject  = "";
880   theContext = "";
881   }*/
882
883 bool SUPERVGUI::ActiveStudyChanged() {
884   Trace("SUPERVGUI::activeStudyChanged");
885   study = application()->activeStudy();
886   return true;
887 }
888
889 /*void SUPERVGUI::SupportedViewType (int* buffer, int bufferSize)
890 {
891   if (!buffer || !bufferSize) return;
892   buffer[0] = (int)VIEW_GRAPHSUPERV;
893 }*/
894
895 void SUPERVGUI::fillInterfaceNameMap() {
896   //fill map: interface_name <-> component_name for all
897   //interfaces of all loaded components, it is necessary
898   //for correct adding factory nodes from AddComponent,
899   //SubComponent, MulComponent, etc. components.
900   myInterfaceNameMap.clear();
901
902   //get naming service
903   SALOME_NamingService* namingService = (( SalomeApp_Application* )application())->namingService();
904   //get module catalog
905   CORBA::Object_ptr obj  = namingService->Resolve("/Kernel/ModulCatalog");
906   SALOME_ModuleCatalog::ModuleCatalog_var* aModuleCatalog = new SALOME_ModuleCatalog::ModuleCatalog_var;
907   *aModuleCatalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj);
908   if (!CORBA::is_nil(*aModuleCatalog)) {
909     //get component list
910     SALOME_ModuleCatalog::ListOfComponents_var aCompList = (*aModuleCatalog)->GetComponentList();
911     for (int ind1 = 0; ind1 < aCompList->length(); ind1++) {
912       //get component
913       SALOME_ModuleCatalog::Acomponent_ptr aComponent = (*aModuleCatalog)->GetComponent(aCompList[ind1]);
914       if ( aComponent != NULL ) {
915         //get interface list 
916         SALOME_ModuleCatalog::ListOfInterfaces_var anIntList = aComponent->GetInterfaceList();
917         for (int ind2 = 0; ind2 < anIntList->length(); ind2++) {
918           const char* anIntName = anIntList[ind2];
919           myInterfaceNameMap.insert(QString(anIntName), QString(aComponent->componentname()));
920         }
921       }
922     }
923   }
924 }
925
926 QMap<QString, QString> SUPERVGUI::getInterfaceNameMap() const {
927   return myInterfaceNameMap;
928 }