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