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