Salome HOME
New Help for KERNEL & GUI.
[modules/gui.git] / src / SalomeApp / SalomeApp_Application.cxx
1 // File:      SalomeApp_Application.cxx
2 // Created:   10/22/2004 3:23:45 PM
3 // Author:    Sergey LITONIN
4 // Copyright (C) CEA 2004
5
6 #include "SalomeApp_PyInterp.h" // WARNING! This include must be the first!
7
8 #include "SalomeApp_Application.h"
9
10 #include "SalomeApp_Study.h"
11 #include "SalomeApp_Module.h"
12 #include "SalomeApp_OBFilter.h"
13 #include "SalomeApp_DataModel.h"
14 #include "SalomeApp_DataObject.h"
15 #include "SalomeApp_EventFilter.h"
16 #include "SalomeApp_WidgetContainer.h"
17
18 #include "SalomeApp_AboutDlg.h"
19 #include "SalomeApp_ModuleDlg.h"
20 #include "SalomeApp_Preferences.h"
21 #include "SalomeApp_PreferencesDlg.h"
22 #include "SalomeApp_StudyPropertiesDlg.h"
23 #include "SalomeApp_CheckFileDlg.h"
24
25 #include "SalomeApp_GLSelector.h"
26 #include "SalomeApp_OBSelector.h"
27 #include "SalomeApp_OCCSelector.h"
28 #include "SalomeApp_VTKSelector.h"
29 #include "SalomeApp_SelectionMgr.h"
30
31 #include <LogWindow.h>
32
33 #include <GLViewer_Viewer.h>
34 #include <GLViewer_ViewManager.h>
35
36 #include <Plot2d_ViewManager.h>
37 #include <SPlot2d_ViewModel.h>
38
39 #include <OCCViewer_ViewManager.h>
40 #include <SOCC_ViewModel.h>
41
42 #include <SVTK_ViewModel.h>
43 #include <SVTK_ViewManager.h>
44
45 #include <STD_TabDesktop.h>
46
47 #include "STD_LoadStudiesDlg.h"
48
49 #include <SUIT_Tools.h>
50 #include <SUIT_Session.h>
51 #include <SUIT_Accel.h>
52
53 #include <QtxToolBar.h>
54 #include <QtxMRUAction.h>
55 #include <QtxDockAction.h>
56 #include <QtxResourceEdit.h>
57
58 #include <OB_Browser.h>
59
60 #include <PythonConsole_PyConsole.h>
61
62 #include <SUIT_FileDlg.h>
63 #include <SUIT_MessageBox.h>
64 #include <SUIT_ResourceMgr.h>
65 #include <SUIT_ActionOperation.h>
66
67 #include <Utils_ORB_INIT.hxx>
68 #include <Utils_SINGLETON.hxx>
69 #include <SALOME_ModuleCatalog_impl.hxx>
70 #include <SALOME_LifeCycleCORBA.hxx>
71
72 #include <qmap.h>
73 #include <qdir.h>
74 #include <qlabel.h>
75 #include <qimage.h>
76 #include <qaction.h>
77 #include <qmenubar.h>
78 #include <qcombobox.h>
79 #include <qmessagebox.h>
80 #include <qapplication.h>
81 #include <qlistbox.h>
82 #include <qregexp.h>
83 #include <qthread.h>
84 #include <qstatusbar.h>
85
86 #include "SALOMEDS_StudyManager.hxx"
87
88 #include "SALOME_ListIteratorOfListIO.hxx"
89 #include "SALOME_ListIO.hxx"
90
91 #include "ToolsGUI_CatalogGeneratorDlg.h"
92 #include "ToolsGUI_RegWidget.h"
93
94 #define OBJECT_BROWSER_WIDTH 300
95 #define DEFAULT_BROWSER "mozilla"
96
97 /*!Image for empty icon.*/
98 static const char* imageEmptyIcon[] = {
99 "20 20 1 1",
100 ".      c None",
101 "....................",
102 "....................",
103 "....................",
104 "....................",
105 "....................",
106 "....................",
107 "....................",
108 "....................",
109 "....................",
110 "....................",
111 "....................",
112 "....................",
113 "....................",
114 "....................",
115 "....................",
116 "....................",
117 "....................",
118 "....................",
119 "....................",
120 "...................."};
121
122 /*!Create new instance of SalomeApp_Application.*/
123 extern "C" SALOMEAPP_EXPORT SUIT_Application* createApplication()
124 {
125   return new SalomeApp_Application();
126 }
127
128 SalomeApp_Preferences* SalomeApp_Application::_prefs_ = 0;
129
130 /*
131   Class       : SalomeApp_Application
132   Description : Application containing SalomeApp module
133 */
134
135 /*!Constructor.*/
136 SalomeApp_Application::SalomeApp_Application()
137 : CAM_Application( false ),
138 myPrefs( 0 )
139 {
140   STD_TabDesktop* desk = new STD_TabDesktop();
141
142   setDesktop( desk );
143
144   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
145   QPixmap aLogo = aResMgr->loadPixmap( "SalomeApp", tr( "APP_DEFAULT_ICO" ), false );
146
147   desktop()->setIcon( aLogo );
148   desktop()->setDockableMenuBar( true );
149   desktop()->setDockableStatusBar( false );
150
151   // base logo (salome itself)
152   desktop()->addLogo( "_app_base",  aResMgr->loadPixmap( "SalomeApp", tr( "APP_BASE_LOGO" ), false ) );
153   // extra logo (salome-based application)
154   desktop()->addLogo( "_app_extra", aResMgr->loadPixmap( "SalomeApp", tr( "APP_EXTRA_LOGO" ), false ) );
155
156   clearViewManagers();
157
158   mySelMgr = new SalomeApp_SelectionMgr( this );
159
160   myAccel = new SUIT_Accel( desktop() );
161   myAccel->setActionKey( SUIT_Accel::PanLeft,     CTRL+Key_Left,     OCCViewer_Viewer::Type() );
162   myAccel->setActionKey( SUIT_Accel::PanRight,    CTRL+Key_Right,    OCCViewer_Viewer::Type() );
163   myAccel->setActionKey( SUIT_Accel::PanUp,       CTRL+Key_Up,       OCCViewer_Viewer::Type() );
164   myAccel->setActionKey( SUIT_Accel::PanDown,     CTRL+Key_Down,     OCCViewer_Viewer::Type() );
165   myAccel->setActionKey( SUIT_Accel::ZoomIn,      CTRL+Key_Plus,     OCCViewer_Viewer::Type() );
166   myAccel->setActionKey( SUIT_Accel::ZoomOut,     CTRL+Key_Minus,    OCCViewer_Viewer::Type() );
167   myAccel->setActionKey( SUIT_Accel::ZoomFit,     CTRL+Key_Asterisk, OCCViewer_Viewer::Type() );
168   myAccel->setActionKey( SUIT_Accel::RotateLeft,  ALT+Key_Left,      OCCViewer_Viewer::Type() );
169   myAccel->setActionKey( SUIT_Accel::RotateRight, ALT+Key_Right,     OCCViewer_Viewer::Type() );
170   myAccel->setActionKey( SUIT_Accel::RotateUp,    ALT+Key_Up,        OCCViewer_Viewer::Type() );
171   myAccel->setActionKey( SUIT_Accel::RotateDown,  ALT+Key_Down,      OCCViewer_Viewer::Type() );
172   myAccel->setActionKey( SUIT_Accel::PanLeft,     CTRL+Key_Left,     SVTK_Viewer::Type() );
173   myAccel->setActionKey( SUIT_Accel::PanRight,    CTRL+Key_Right,    SVTK_Viewer::Type() );
174   myAccel->setActionKey( SUIT_Accel::PanUp,       CTRL+Key_Up,       SVTK_Viewer::Type() );
175   myAccel->setActionKey( SUIT_Accel::PanDown,     CTRL+Key_Down,     SVTK_Viewer::Type() );
176   myAccel->setActionKey( SUIT_Accel::ZoomIn,      CTRL+Key_Plus,     SVTK_Viewer::Type() );
177   myAccel->setActionKey( SUIT_Accel::ZoomOut,     CTRL+Key_Minus,    SVTK_Viewer::Type() );
178   myAccel->setActionKey( SUIT_Accel::ZoomFit,     CTRL+Key_Asterisk, SVTK_Viewer::Type() );
179   myAccel->setActionKey( SUIT_Accel::RotateLeft,  ALT+Key_Left,      SVTK_Viewer::Type() );
180   myAccel->setActionKey( SUIT_Accel::RotateRight, ALT+Key_Right,     SVTK_Viewer::Type() );
181   myAccel->setActionKey( SUIT_Accel::RotateUp,    ALT+Key_Up,        SVTK_Viewer::Type() );
182   myAccel->setActionKey( SUIT_Accel::RotateDown,  ALT+Key_Down,      SVTK_Viewer::Type() );
183
184   connect( mySelMgr, SIGNAL( selectionChanged() ), this, SLOT( onSelection() ) );
185 }
186
187 /*!Destructor.
188  *\li Save window geometry.
189  *\li Save desktop geometry.
190  *\li Save resource maneger.
191  *\li Delete selection manager.
192  *\li Destroy event filter.
193  */
194 SalomeApp_Application::~SalomeApp_Application()
195 {
196   saveWindowsGeometry();
197
198   if ( resourceMgr() )
199   {
200     if ( desktop() )
201       desktop()->saveGeometry( resourceMgr(), "desktop" );
202     resourceMgr()->save();
203   }
204
205   delete mySelMgr;
206
207   SalomeApp_EventFilter::Destroy();
208 }
209
210 /*!Start application.*/
211 void SalomeApp_Application::start()
212 {
213   if ( desktop() )
214     desktop()->loadGeometry( resourceMgr(), "desktop" );
215
216   CAM_Application::start();
217
218   QAction* a = action( ViewWindowsId );
219   if ( a && a->inherits( "QtxDockAction" ) )
220     ((QtxDockAction*)a)->setAutoPlace( true );
221
222   SalomeApp_EventFilter::Init();
223
224   updateWindows();
225   updateViewManagers();
226
227   putInfo( "" );
228   desktop()->statusBar()->message( "" );
229 }
230
231 /*!Gets application name.*/
232 QString SalomeApp_Application::applicationName() const
233 {
234   return tr( "APP_NAME" );
235 }
236
237 /*!Gets application version.*/
238 QString SalomeApp_Application::applicationVersion() const
239 {
240   static QString _app_version;
241
242   if ( _app_version.isEmpty() )
243   {
244     QString resVersion = tr( "APP_VERSION" );
245     if ( resVersion != "APP_VERSION" )
246     {
247       _app_version = resVersion;
248     }
249     else
250     {
251       QString path( ::getenv( "GUI_ROOT_DIR" ) );
252       if ( !path.isEmpty() )
253         path += QDir::separator();
254       path += QString( "bin/salome/VERSION" );
255
256       QFile vf( path );
257       if ( vf.open( IO_ReadOnly ) )
258       {
259         QString line;
260         vf.readLine( line, 1024 );
261         vf.close();
262
263         if ( !line.isEmpty() )
264         {
265           while ( !line.isEmpty() && line.at( line.length() - 1 ) == QChar( '\n' ) )
266             line.remove( line.length() - 1, 1 );
267
268           int idx = line.findRev( ":" );
269           if ( idx != -1 )
270             _app_version = line.mid( idx + 1 ).stripWhiteSpace();
271         }
272       }
273     }
274   }
275   return _app_version;
276 }
277
278 /*!Load module by \a name.*/
279 CAM_Module* SalomeApp_Application::loadModule( const QString& name )
280 {
281   CAM_Module* mod = CAM_Application::loadModule( name );
282   if ( mod )
283   {
284     connect( this, SIGNAL( studyOpened() ), mod, SLOT( onModelOpened() ) );
285     connect( this, SIGNAL( studySaved() ),  mod, SLOT( onModelSaved() ) );
286     connect( this, SIGNAL( studyClosed() ), mod, SLOT( onModelClosed() ) );
287   }
288   return mod;
289 }
290
291 /*!Activate module by \a modName*/
292 bool SalomeApp_Application::activateModule( const QString& modName )
293 {
294   QString actName;
295   CAM_Module* prevMod = activeModule();
296
297   if ( prevMod )
298     actName = prevMod->moduleName();
299
300   if ( actName == modName )
301     return true;
302
303   putInfo( tr( "ACTIVATING_MODULE" ).arg( modName ) );
304
305   saveWindowsGeometry();
306
307   bool status = CAM_Application::activateModule( modName );
308
309   updateModuleActions();
310
311   putInfo( "" );
312
313   if ( !status )
314     return false;
315
316   updateWindows();
317   updateViewManagers();
318
319   return true;
320 }
321
322 /*!Gets selection manager.*/
323 SalomeApp_SelectionMgr* SalomeApp_Application::selectionMgr() const
324 {
325   return mySelMgr;
326 }
327
328 /*!Create actions:*/
329 void SalomeApp_Application::createActions()
330 {
331   STD_Application::createActions();
332
333   SUIT_Desktop* desk = desktop();
334   SUIT_ResourceMgr* resMgr = resourceMgr();
335
336   //! Dump study
337   createAction( DumpStudyId, tr( "TOT_DESK_FILE_DUMP_STUDY" ), QIconSet(),
338                 tr( "MEN_DESK_FILE_DUMP_STUDY" ), tr( "PRP_DESK_FILE_DUMP_STUDY" ),
339                 0, desk, false, this, SLOT( onDumpStudy() ) );
340
341   //! Load script
342   createAction( LoadScriptId, tr( "TOT_DESK_FILE_LOAD_SCRIPT" ), QIconSet(),
343                 tr( "MEN_DESK_FILE_LOAD_SCRIPT" ), tr( "PRP_DESK_FILE_LOAD_SCRIPT" ),
344                 0, desk, false, this, SLOT( onLoadScript() ) );
345
346   //! Properties
347   createAction( PropertiesId, tr( "TOT_DESK_PROPERTIES" ), QIconSet(),
348                 tr( "MEN_DESK_PROPERTIES" ), tr( "PRP_DESK_PROPERTIES" ),
349                 0, desk, false, this, SLOT( onProperties() ) );
350
351   //! Preferences
352   createAction( PreferencesId, tr( "TOT_DESK_PREFERENCES" ), QIconSet(),
353                 tr( "MEN_DESK_PREFERENCES" ), tr( "PRP_DESK_PREFERENCES" ),
354                 CTRL+Key_P, desk, false, this, SLOT( onPreferences() ) );
355
356   //! Catalog Generator
357   createAction( CatalogGenId, tr( "TOT_DESK_CATALOG_GENERATOR" ),  QIconSet(),
358                 tr( "MEN_DESK_CATALOG_GENERATOR" ), tr( "PRP_DESK_CATALOG_GENERATOR" ),
359                 0, desk, false, this, SLOT( onCatalogGen() ) );
360
361   //! Registry Display
362   createAction( RegDisplayId, tr( "TOT_DESK_REGISTRY_DISPLAY" ),  QIconSet(),
363                 tr( "MEN_DESK_REGISTRY_DISPLAY" ), tr( "PRP_DESK_REGISTRY_DISPLAY" ),
364                 0, desk, false, this, SLOT( onRegDisplay() ) );
365
366   //! MRU
367   QtxMRUAction* mru = new QtxMRUAction( tr( "TOT_DESK_MRU" ), tr( "MEN_DESK_MRU" ), desk );
368   connect( mru, SIGNAL( activated( QString ) ), this, SLOT( onMRUActivated( QString ) ) );
369   registerAction( MRUId, mru );
370
371   //! default icon for neutral point ('SALOME' module)
372   QPixmap defIcon = resMgr->loadPixmap( "SalomeApp", tr( "APP_DEFAULT_ICO" ), false );
373   if ( defIcon.isNull() )
374     defIcon = QPixmap( imageEmptyIcon );
375
376   //! default icon for any module
377   QPixmap modIcon = resMgr->loadPixmap( "SalomeApp", tr( "APP_MODULE_ICO" ), false );
378   if ( modIcon.isNull() )
379     modIcon = QPixmap( imageEmptyIcon );
380
381   QToolBar* modTBar = new QtxToolBar( true, desk );
382   modTBar->setLabel( tr( "INF_TOOLBAR_MODULES" ) );
383
384   QActionGroup* modGroup = new QActionGroup( this );
385   modGroup->setExclusive( true );
386   modGroup->setUsesDropDown( true );
387
388   QAction* a = createAction( -1, tr( "APP_NAME" ), defIcon, tr( "APP_NAME" ),
389                              tr( "PRP_APP_MODULE" ), 0, desk, true );
390   modGroup->add( a );
391   myActions.insert( QString(), a );
392
393   QMap<QString, QString> iconMap;
394   moduleIconNames( iconMap );
395
396   const int iconSize = 20;
397
398   modGroup->addTo( modTBar );
399   modTBar->addSeparator();
400
401   QStringList modList;
402   modules( modList, false );
403
404   for ( QStringList::Iterator it = modList.begin(); it != modList.end(); ++it )
405   {
406     if ( (*it).isEmpty() )
407       continue;
408
409     QString iconName;
410     if ( iconMap.contains( *it ) )
411       iconName = iconMap[*it];
412
413     QString modName = moduleName( *it );
414
415     QPixmap icon = resMgr->loadPixmap( modName, iconName, false );
416     if ( icon.isNull() )
417       icon = modIcon;
418
419     icon.convertFromImage( icon.convertToImage().smoothScale( iconSize, iconSize, QImage::ScaleMin ) );
420
421     QAction* a = createAction( -1, *it, icon, *it, tr( "PRP_MODULE" ).arg( *it ), 0, desk, true );
422     a->addTo( modTBar );
423     modGroup->add( a );
424
425     myActions.insert( *it, a );
426   }
427
428   SUIT_Tools::simplifySeparators( modTBar );
429
430   //! New window
431
432   int windowMenu = createMenu( tr( "MEN_DESK_WINDOW" ), -1, 100 );
433   int newWinMenu = createMenu( tr( "MEN_DESK_NEWWINDOW" ), windowMenu, -1, 0 );
434   createMenu( separator(), windowMenu, -1, 1 );
435
436   QMap<int, int> accelMap;
437   accelMap[NewGLViewId]  = ALT+Key_G;
438   accelMap[NewPlot2dId]  = ALT+Key_P;
439   accelMap[NewOCCViewId] = ALT+Key_O;
440   accelMap[NewVTKViewId] = ALT+Key_K;
441
442   for ( int id = NewGLViewId; id <= NewVTKViewId; id++ )
443   {
444     QAction* a = createAction( id, tr( QString( "NEW_WINDOW_%1" ).arg( id - NewGLViewId ) ), QIconSet(),
445                                tr( QString( "NEW_WINDOW_%1" ).arg( id - NewGLViewId ) ),
446                                tr( QString( "NEW_WINDOW_%1" ).arg( id - NewGLViewId ) ),
447                                accelMap.contains( id ) ? accelMap[id] : 0, desk, false, this, SLOT( onNewWindow() ) );
448     createMenu( a, newWinMenu, -1 );
449   }
450   connect( modGroup, SIGNAL( selected( QAction* ) ), this, SLOT( onModuleActivation( QAction* ) ) );
451
452   //! Help for modules
453   int helpMenu = createMenu( tr( "MEN_DESK_HELP" ), -1, -1, 1000 );
454   int helpModuleMenu = createMenu( tr( "MEN_DESK_MODULE_HELP" ), helpMenu, -1, 0 );
455   createMenu( separator(), helpMenu, -1, 1 );
456
457   QStringList aModuleList;
458   modules( aModuleList, false );
459   
460   int id = SalomeApp_Application::UserID;
461   // help for KERNEL and GUI
462   QCString dir;
463   if (dir = getenv("GUI_ROOT_DIR")) {
464     a = createAction( id, tr( QString("Kernel & GUI Help") ), QIconSet(),
465                       tr( QString("Kernel && GUI Help") ),
466                       tr( QString("Kernel & GUI Help") ),
467                       0, desk, false, this, SLOT( onHelpContentsModule() ) );
468     a->setName( QString("GUI") );
469     createMenu( a, helpModuleMenu, -1 );
470     id++;
471   }
472   // help for other existing modules
473   for ( QStringList::Iterator it = aModuleList.begin(); it != aModuleList.end(); ++it )
474   {
475     if ( (*it).isEmpty() )
476       continue;
477
478     QString modName = moduleName( *it );
479     if ( modName.compare("GEOM") == 0 ) { // to be removed when documentation for other modules will be done
480       QAction* a = createAction( id, tr( moduleTitle(modName) + QString(" Help") ), QIconSet(),
481                                  tr( moduleTitle(modName) + QString(" Help") ),
482                                  tr( moduleTitle(modName) + QString(" Help") ),
483                                  0, desk, false, this, SLOT( onHelpContentsModule() ) );
484       a->setName( modName );
485       createMenu( a, helpModuleMenu, -1 );
486       id++;
487     }
488   }
489
490   int fileMenu = createMenu( tr( "MEN_DESK_FILE" ), -1 );
491
492   createMenu( DumpStudyId, fileMenu, 10, -1 );
493   createMenu( separator(), fileMenu, -1, 15, -1 );
494   createMenu( LoadScriptId, fileMenu, 10, -1 );
495   createMenu( separator(), fileMenu, -1, 15, -1 );
496   createMenu( PropertiesId, fileMenu, 10, -1 );
497   createMenu( separator(), fileMenu, -1, 15, -1 );
498   createMenu( PreferencesId, fileMenu, 15, -1 );
499   createMenu( separator(), fileMenu, -1, 15, -1 );
500
501   int toolsMenu = createMenu( tr( "MEN_DESK_TOOLS" ), -1, -1, 50 );
502   createMenu( CatalogGenId, toolsMenu, 10, -1 );
503   createMenu( RegDisplayId, toolsMenu, 10, -1 );
504   createMenu( separator(), toolsMenu, -1, 15, -1 );
505
506   
507   /*
508   createMenu( separator(), fileMenu, -1, 100, -1 );
509   createMenu( MRUId, fileMenu, 100, -1 );
510   createMenu( separator(), fileMenu, -1, 100, -1 );
511   */
512 }
513
514 /*!On module activation action.*/
515 void SalomeApp_Application::onModuleActivation( QAction* a )
516 {
517   if ( !a )
518     return;
519
520   QString modName = a->menuText();
521   if ( modName == tr( "APP_NAME" ) )
522     modName = QString::null;
523
524   // Force user to create/open a study before module activation
525   QMap<QString, QString> iconMap;
526   moduleIconNames( iconMap );
527   QPixmap icon = resourceMgr()->loadPixmap( moduleName( modName ), iconMap[ modName ], false );
528   if ( icon.isNull() )
529     icon = resourceMgr()->loadPixmap( "SalomeApp", tr( "APP_MODULE_BIG_ICO" ), false ); // default icon for any module
530
531   bool cancelled = false;
532   while ( !modName.isEmpty() && !activeStudy() && !cancelled ){
533     SalomeApp_ModuleDlg aDlg( desktop(), modName, icon );
534     int res = aDlg.exec();
535
536     switch ( res ){
537     case 1:
538       onNewDoc();
539       break;
540     case 2:
541       onOpenDoc();
542       break;
543     case 3:
544       //onLoadStudy();
545       //break;
546     case 0:
547     default:
548       putInfo( tr("INF_CANCELLED") );
549       myActions[QString()]->setOn( true );
550       cancelled = true;
551     }
552   }
553
554   if ( !cancelled )
555     activateModule( modName );
556 }
557
558 /*!Default module activation.*/
559 QString SalomeApp_Application::defaultModule() const
560 {
561   QStringList aModuleNames;
562   modules( aModuleNames, false ); // obtain a complete list of module names for the current configuration
563   //! If there's the one and only module --> activate it automatically
564   //! TODO: Possible improvement - default module can be taken from preferences
565   return aModuleNames.count() > 1 ? "" : ( aModuleNames.count() ? aModuleNames.first() : "" );
566 }
567
568 /*!On new window slot.*/
569 void SalomeApp_Application::onNewWindow()
570 {
571   const QObject* obj = sender();
572   if ( !obj || !obj->inherits( "QAction" ) )
573     return;
574
575   QString type;
576   int id = actionId( (QAction*)obj );
577   switch ( id )
578   {
579   case NewGLViewId:
580     type = GLViewer_Viewer::Type();
581     break;
582   case NewPlot2dId:
583     type = Plot2d_Viewer::Type();
584     break;
585   case NewOCCViewId:
586     type = OCCViewer_Viewer::Type();
587     break;
588   case NewVTKViewId:
589     type = SVTK_Viewer::Type();
590     break;
591   }
592
593   if ( !type.isEmpty() )
594     createViewManager( type );
595 }
596
597 //=======================================================================
598 //  name    : onNewDoc
599 /*! Purpose : SLOT. Create new document*/
600 //=======================================================================
601 void SalomeApp_Application::onNewDoc()
602 {
603   SUIT_Study* study = activeStudy();
604
605   saveWindowsGeometry();
606
607   CAM_Application::onNewDoc();
608
609   if ( !study ) // new study will be create in THIS application
610   {
611     updateWindows();
612     updateViewManagers();
613   }
614 }
615
616 //=======================================================================
617 // name    : onOpenDoc
618 /*! Purpose : SLOT. Open new document*/
619 //=======================================================================
620 void SalomeApp_Application::onOpenDoc()
621 {
622   SUIT_Study* study = activeStudy();
623   saveWindowsGeometry();
624
625   CAM_Application::onOpenDoc();
626
627   if ( !study ) // new study will be create in THIS application
628   {
629     updateWindows();
630     updateViewManagers();
631   }
632 }
633
634 /*! Purpose : SLOT. Open new document with \a aName.*/
635 bool SalomeApp_Application::onOpenDoc( const QString& aName )
636 {
637   bool res = CAM_Application::onOpenDoc( aName );
638
639   QAction* a = action( MRUId );
640   if ( a && a->inherits( "QtxMRUAction" ) )
641   {
642     QtxMRUAction* mru = (QtxMRUAction*)a;
643     if ( res )
644       mru->insert( aName );
645     else
646       mru->remove( aName );
647   }
648   return res;
649 }
650
651 /*!SLOT. Load document.*/
652 void SalomeApp_Application::onLoadDoc()
653 {
654   QString name, studyname, ext;
655
656   STD_LoadStudiesDlg aDlg( desktop(), TRUE);
657
658   std::vector<std::string> List = studyMgr()->GetOpenStudies();
659
660   SUIT_Session* aSession = SUIT_Session::session();
661   QPtrList<SUIT_Application> aAppList = aSession->applications();
662   SUIT_Application* aApp = 0;
663
664   for (unsigned int ind = 0; ind < List.size(); ind++) {
665      studyname = List[ind].c_str();
666      //Add to list only unloaded studies
667      bool isAlreadyOpen = false;
668      for ( QPtrListIterator<SUIT_Application> it( aAppList ); it.current() && !isAlreadyOpen; ++it )
669        {
670          aApp = it.current();
671          if(!aApp || !aApp->activeStudy()) continue;
672          if ( aApp->activeStudy()->studyName() == studyname ) isAlreadyOpen = true;
673        }
674
675      if ( !isAlreadyOpen ) aDlg.ListComponent->insertItem( studyname );
676   }
677
678   int retVal = aDlg.exec();
679   studyname = aDlg.ListComponent->currentText();
680
681   if (retVal == QDialog::Rejected)
682     return;
683
684   if ( studyname.isNull() || studyname.isEmpty() )
685     return;
686
687   name = studyname;
688   name.replace( QRegExp(":"), "/" );
689
690   if(onLoadDoc(name)) {
691      updateWindows();
692      updateViewManagers();
693      updateObjectBrowser(true);
694   }
695 }
696
697
698 /*!SLOT. Load document with \a aName.*/
699 bool SalomeApp_Application::onLoadDoc( const QString& aName )
700 {
701   bool res = CAM_Application::onLoadDoc( aName );
702
703   /*jfa tmp:QAction* a = action( MRUId );
704   if ( a && a->inherits( "QtxMRUAction" ) )
705   {
706     QtxMRUAction* mru = (QtxMRUAction*)a;
707     if ( res )
708       mru->insert( aName );
709     else
710       mru->remove( aName );
711   }*/
712   return res;
713 }
714
715 /*!Private SLOT. Selection.*/
716 void SalomeApp_Application::onSelection()
717 {
718   onSelectionChanged();
719
720   if ( activeModule() && activeModule()->inherits( "SalomeApp_Module" ) )
721     ((SalomeApp_Module*)activeModule())->selectionChanged();
722 }
723
724 /*!SLOT. Copy objects to study maneger from selection maneger..*/
725 void SalomeApp_Application::onCopy()
726 {
727   SALOME_ListIO list;
728   SalomeApp_SelectionMgr* mgr = selectionMgr();
729   mgr->selectedObjects(list);
730
731   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
732   if(study == NULL) return;
733
734   _PTR(Study) stdDS = study->studyDS();
735   if(!stdDS) return;
736
737   SALOME_ListIteratorOfListIO it( list );
738   if(it.More())
739     {
740       _PTR(SObject) so = stdDS->FindObjectID(it.Value()->getEntry());
741       try {
742         studyMgr()->Copy(so);
743         onSelectionChanged();
744       }
745       catch(...) {
746       }
747     }
748 }
749
750 /*!SLOT. Paste objects to study maneger from selection manager.*/
751 void SalomeApp_Application::onPaste()
752 {
753   SALOME_ListIO list;
754   SalomeApp_SelectionMgr* mgr = selectionMgr();
755   mgr->selectedObjects(list);
756
757   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
758   if(study == NULL) return;
759
760   _PTR(Study) stdDS = study->studyDS();
761   if(!stdDS) return;
762
763   SALOME_ListIteratorOfListIO it( list );
764   if(it.More())
765     {
766       _PTR(SObject) so = stdDS->FindObjectID(it.Value()->getEntry());
767       try {
768         studyMgr()->Paste(so);
769         updateObjectBrowser( true );
770         updateActions(); //SRN: BugID IPAL9377, case 3
771       }
772       catch(...) {
773       }
774     }
775 }
776
777 /*!Sets enable or disable some actions on selection changed.*/
778 void SalomeApp_Application::onSelectionChanged()
779 {
780    SALOME_ListIO list;
781    SalomeApp_SelectionMgr* mgr = selectionMgr();
782    mgr->selectedObjects(list);
783
784    SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
785    if(study == NULL) return;
786
787    _PTR(Study) stdDS = study->studyDS();
788    if(!stdDS) return;
789
790    QAction* qaction;
791
792    SALOME_ListIteratorOfListIO it( list );
793    if(it.More() && list.Extent() == 1)
794    {
795       _PTR(SObject) so = stdDS->FindObjectID(it.Value()->getEntry());
796
797       qaction = action(EditCopyId);
798       if( so && studyMgr()->CanCopy(so) ) qaction->setEnabled(true);
799       else qaction->setEnabled(false);
800
801       qaction = action(EditPasteId);
802       if( so && studyMgr()->CanPaste(so) ) qaction->setEnabled(true);
803       else qaction->setEnabled(false);
804    }
805    else {
806      qaction = action(EditCopyId);
807      qaction->setEnabled(false);
808      qaction = action(EditPasteId);
809      qaction->setEnabled(false);
810    }
811 }
812
813 /*!Update object browser.*/
814 void SalomeApp_Application::onRefresh()
815 {
816   updateObjectBrowser( true );
817 }
818
819 /*!Delete references.*/
820 void SalomeApp_Application::onDeleteReferences()
821 {
822   SALOME_ListIO aList;
823   SalomeApp_SelectionMgr* mgr = selectionMgr();
824   mgr->selectedObjects(aList);
825
826   if (aList.Extent() < 1) return;
827
828   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(activeStudy());
829   _PTR(Study) aStudyDS = aStudy->studyDS();
830   _PTR(StudyBuilder) aStudyBuilder = aStudyDS->NewBuilder();
831   _PTR(SObject) anObj;
832
833   for ( SALOME_ListIteratorOfListIO it( aList ); it.More(); it.Next() )
834     {
835       if ( it.Value()->hasEntry() )
836         {
837           _PTR(SObject) aSObject = aStudyDS->FindObjectID( it.Value()->getEntry() );
838           if ( aSObject->ReferencedObject(anObj) )
839             aStudyBuilder->RemoveReference(aSObject);
840         }
841     }
842
843   updateObjectBrowser();
844 }
845
846 /*!Private SLOT. */
847 void SalomeApp_Application::onOpenWith()
848 {
849   QApplication::setOverrideCursor( Qt::waitCursor );
850   SALOME_ListIO aList;
851   SalomeApp_SelectionMgr* mgr = selectionMgr();
852   mgr->selectedObjects(aList);
853   if (aList.Extent() != 1)
854     {
855       QApplication::restoreOverrideCursor();
856       return;
857     }
858   Handle(SALOME_InteractiveObject) aIObj = aList.First();
859   QString aModuleName(aIObj->getComponentDataType());
860   QString aModuleTitle = moduleTitle(aModuleName);
861   activateModule(aModuleTitle);
862   QApplication::restoreOverrideCursor();
863 }
864
865 bool SalomeApp_Application::useStudy(const QString& theName)
866 {
867   createEmptyStudy();
868   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(activeStudy());
869   bool res = false;
870   if (aStudy)
871     res = aStudy->loadDocument( theName );
872   updateDesktopTitle();
873   updateCommandsStatus();
874   return res;
875 }
876
877 /*!Set active study.
878  *\param study - SUIT_Study.
879  */
880 void SalomeApp_Application::setActiveStudy( SUIT_Study* study )
881 {
882   CAM_Application::setActiveStudy( study );
883
884   activateWindows();
885 }
886
887 //=======================================================================
888 // name    : createNewStudy
889 /*! Purpose : Create new study*/
890 //=======================================================================
891 SUIT_Study* SalomeApp_Application::createNewStudy()
892 {
893   SalomeApp_Study* aStudy = new SalomeApp_Study( this );
894
895   // Set up processing of major study-related events
896   connect( aStudy, SIGNAL( created( SUIT_Study* ) ), this, SLOT( onStudyCreated( SUIT_Study* ) ) );
897   connect( aStudy, SIGNAL( opened ( SUIT_Study* ) ), this, SLOT( onStudyOpened ( SUIT_Study* ) ) );
898   connect( aStudy, SIGNAL( saved  ( SUIT_Study* ) ), this, SLOT( onStudySaved  ( SUIT_Study* ) ) );
899   connect( aStudy, SIGNAL( closed ( SUIT_Study* ) ), this, SLOT( onStudyClosed ( SUIT_Study* ) ) );
900
901   return aStudy;
902 }
903
904 //=======================================================================
905 // name    : createNewStudy
906 /*! Purpose : Enable/Disable menu items and toolbar buttons. Rebuild menu*/
907 //=======================================================================
908 void SalomeApp_Application::updateCommandsStatus()
909 {
910   CAM_Application::updateCommandsStatus();
911
912   for ( int id = NewGLViewId; id <= NewVTKViewId; id++ )
913   {
914     QAction* a = action( id );
915     if ( a )
916       a->setEnabled( activeStudy() );
917   }
918
919   // Dump study menu
920   QAction* a = action( DumpStudyId );
921   if ( a )
922     a->setEnabled( activeStudy() );
923
924   // Load script menu
925   a = action( LoadScriptId );
926   if ( a )
927     a->setEnabled( activeStudy() );
928
929   a = action( PropertiesId );
930   if( a )
931     a->setEnabled( activeStudy() );
932
933   a = action(EditCopyId);
934   a->setEnabled(false);
935   a = action(EditPasteId);
936   a->setEnabled(false);
937 }
938
939 //=======================================================================
940 // name    : onHelpAbout
941 /*! Purpose : SLOT. Display "About" message box*/
942 //=======================================================================
943 void SalomeApp_Application::onHelpAbout()
944 {
945   SalomeApp_AboutDlg* dlg = new SalomeApp_AboutDlg( applicationName(), applicationVersion(), desktop() );
946   dlg->exec();
947   delete dlg;
948 }
949
950 // Helps to execute command
951 class RunBrowser: public QThread {
952 public:
953   
954   RunBrowser(QString theApp, QString theParams, QString theHelpFile, QString theContext=NULL): 
955     myApp(theApp), myParams(theParams), myHelpFile("file:" + theHelpFile + theContext), myStatus(0) {};
956   
957   virtual void run()
958   {
959     QString aCommand;
960     
961     if ( !myApp.isEmpty())
962       {
963         aCommand.sprintf("%s %s %s",myApp.latin1(),myParams.latin1(),myHelpFile.latin1());
964         myStatus = system(aCommand);
965         if(myStatus != 0)
966           {
967             QCustomEvent* ce2000 = new QCustomEvent (2000);
968             postEvent (qApp, ce2000);
969           }
970       }
971     
972     if( myStatus != 0 || myApp.isEmpty())
973       {
974         myParams = "";
975         aCommand.sprintf("%s %s %s", QString(DEFAULT_BROWSER).latin1(),myParams.latin1(), myHelpFile.latin1()); 
976         myStatus = system(aCommand);
977         if(myStatus != 0)
978           {
979             QCustomEvent* ce2001 = new QCustomEvent (2001);
980             postEvent (qApp, ce2001);
981           }
982       }
983   }
984
985 private:
986   QString myApp;
987   QString myParams;
988   QString myHelpFile;
989   int myStatus;
990   
991 };
992
993 //=======================================================================
994 // name    : onHelpContentsModule
995 /*! Purpose : SLOT. Display help contents for choosen module*/
996 //=======================================================================
997 void SalomeApp_Application::onHelpContentsModule()
998 {
999   const QAction* obj = (QAction*) sender();
1000   
1001   QString aComponentName = obj->name();
1002   QString aFileName = aComponentName.lower() + ".htm";
1003
1004   QCString dir;
1005   QString root;
1006   QString homeDir;
1007   if (dir = getenv( aComponentName + "_ROOT_DIR")) {
1008     root = Qtx::addSlash( Qtx::addSlash(dir) +  Qtx::addSlash("doc") +  Qtx::addSlash("salome")  +  Qtx::addSlash(aComponentName));
1009     if ( QFileInfo( root + aFileName ).exists() ) {
1010       homeDir = root;
1011     } else {
1012       SUIT_MessageBox::warn1( desktop(), tr("WRN_WARNING"), 
1013                               QString( "%1"+ aFileName + " doesn't exist." ).arg(root), tr ("BUT_OK") );
1014       return;
1015     }
1016   }
1017
1018   QString helpFile = QFileInfo( homeDir + aFileName ).absFilePath();   
1019   SUIT_ResourceMgr* resMgr = resourceMgr();
1020   QString anApp = resMgr->stringValue("ExternalBrowser", "application");
1021   QString aParams = resMgr->stringValue("ExternalBrowser", "parameters");
1022    
1023   RunBrowser* rs = new RunBrowser(anApp, aParams, helpFile);
1024   rs->start();
1025 }
1026
1027 QWidget* SalomeApp_Application::window( const int flag, const int studyId ) const
1028 {
1029   QWidget* wid = 0;
1030
1031   int sId = studyId;
1032   if ( sId < 0 )
1033   {
1034     if ( !activeStudy() )
1035       return 0;
1036     else
1037       sId = activeStudy()->id();
1038   }
1039
1040   if ( myWindows.contains( flag ) )
1041     wid = myWindows[flag]->widget( sId );
1042
1043   return wid;
1044 }
1045
1046 /*!Adds window to application.
1047  *\param wid - QWidget
1048  *\param flag - key wor window
1049  *\param studyId - study id
1050  * Flag used how identificator of window in windows list.
1051  */
1052 void SalomeApp_Application::addWindow( QWidget* wid, const int flag, const int studyId )
1053 {
1054   if ( !wid )
1055     return;
1056
1057   int sId = studyId;
1058   if ( sId < 0 )
1059   {
1060     if ( !activeStudy() )
1061       return;
1062     else
1063       sId = activeStudy()->id();
1064   }
1065
1066   if ( !myWindows.contains( flag ) )
1067   {
1068     QMap<int, int> winMap;
1069     currentWindows( winMap );
1070
1071     myWindows.insert( flag, new SalomeApp_WidgetContainer( flag, desktop() ) );
1072     if ( winMap.contains( flag ) )
1073       desktop()->moveDockWindow( myWindows[flag], (Dock)winMap[flag] );
1074
1075     myWindows[flag]->setResizeEnabled( true );
1076     myWindows[flag]->setCloseMode( QDockWindow::Always );
1077     myWindows[flag]->setName( QString( "dock_window_%1" ).arg( flag ) );
1078   }
1079
1080   QFont f;
1081   if( wid->inherits( "PythonConsole" ) )
1082     f = ( ( PythonConsole* )wid )->font();
1083   else
1084     f = wid->font();
1085
1086   myWindows[flag]->insert( sId, wid );
1087   wid->setFont( f );
1088
1089   setWindowShown( flag, !myWindows[flag]->isEmpty() );
1090 }
1091
1092 /*!Remove window from application.
1093  *\param flag - key wor window
1094  *\param studyId - study id
1095  * Flag used how identificator of window in windows list.
1096  */
1097 void SalomeApp_Application::removeWindow( const int flag, const int studyId )
1098 {
1099   if ( !myWindows.contains( flag ) )
1100     return;
1101
1102   int sId = studyId;
1103   if ( sId < 0 )
1104   {
1105     if ( !activeStudy() )
1106       return;
1107     else
1108       sId = activeStudy()->id();
1109   }
1110
1111   QWidget* wid = myWindows[flag]->widget( sId );
1112   myWindows[flag]->remove( sId );
1113   delete wid;
1114
1115   setWindowShown( flag, !myWindows[flag]->isEmpty() );
1116 }
1117
1118 /*!Gets window.
1119  *\param flag - key wor window
1120  *\param studyId - study id
1121  * Flag used how identificator of window in windows list.
1122  */
1123 QWidget* SalomeApp_Application::getWindow( const int flag, const int studyId )
1124 {
1125   QWidget* wid = window( flag, studyId );
1126   if ( !wid )
1127     addWindow( wid = createWindow( flag ), flag, studyId );
1128
1129   return wid;
1130 }
1131
1132 /*!Check is window visible?(with identificator \a type)*/
1133 bool SalomeApp_Application::isWindowVisible( const int type ) const
1134 {
1135   bool res = false;
1136   if ( myWindows.contains( type ) )
1137   {
1138     SUIT_Desktop* desk = ((SalomeApp_Application*)this)->desktop();
1139     res = desk && desk->appropriate( myWindows[type] );
1140   }
1141   return res;
1142 }
1143
1144 /*!Sets window show or hide.
1145  *\param type - window identificator.
1146  *\param on   - true/false (window show/hide)
1147  */
1148 void SalomeApp_Application::setWindowShown( const int type, const bool on )
1149 {
1150   if ( !desktop() || !myWindows.contains( type ) )
1151     return;
1152
1153   QDockWindow* dw = myWindows[type];
1154   desktop()->setAppropriate( dw, on );
1155   on ? dw->show() : dw->hide();
1156 }
1157
1158 OB_Browser* SalomeApp_Application::objectBrowser()
1159 {
1160   OB_Browser* ob = 0;
1161   QWidget* wid = getWindow( WT_ObjectBrowser );
1162   if ( wid->inherits( "OB_Browser" ) )
1163     ob = (OB_Browser*)wid;
1164   return ob;
1165 }
1166
1167 /*!Gets "LogWindow".*/
1168 LogWindow* SalomeApp_Application::logWindow()
1169 {
1170   LogWindow* lw = 0;
1171   QWidget* wid = getWindow( WT_LogWindow );
1172   if ( wid->inherits( "LogWindow" ) )
1173     lw = (LogWindow*)wid;
1174   return lw;
1175 }
1176
1177 /*!Get "PythonConsole"*/
1178 PythonConsole* SalomeApp_Application::pythonConsole()
1179 {
1180   PythonConsole* console = 0;
1181   QWidget* wid = getWindow( WT_PyConsole );
1182   if ( wid->inherits( "PythonConsole" ) )
1183     console = (PythonConsole*)wid;
1184   return console;
1185 }
1186
1187 /*!Gets preferences.*/
1188 SalomeApp_Preferences* SalomeApp_Application::preferences() const
1189 {
1190   return preferences( false );
1191 }
1192
1193 /*!Gets view manager*/
1194 SUIT_ViewManager* SalomeApp_Application::getViewManager( const QString& vmType, const bool create )
1195 {
1196   SUIT_ViewManager* aVM = viewManager( vmType );
1197   SUIT_ViewManager* anActiveVM = CAM_Application::activeViewManager();
1198
1199   if ( anActiveVM && anActiveVM->getType() == vmType )
1200     aVM = anActiveVM;
1201
1202   if ( aVM && create )
1203   {
1204     if ( !aVM->getActiveView() )
1205       aVM->createView();
1206     else
1207       aVM->getActiveView()->setFocus();
1208   }
1209   else if ( create )
1210     aVM = createViewManager( vmType );
1211
1212   return aVM;
1213 }
1214
1215 /*!Create view manager.*/
1216 SUIT_ViewManager* SalomeApp_Application::createViewManager( const QString& vmType )
1217 {
1218   SUIT_ResourceMgr* resMgr = resourceMgr();
1219
1220   SUIT_ViewManager* viewMgr = 0;
1221   if ( vmType == GLViewer_Viewer::Type() )
1222   {
1223     viewMgr = new GLViewer_ViewManager( activeStudy(), desktop() );
1224     new SalomeApp_GLSelector( (GLViewer_Viewer2d*)viewMgr->getViewModel(), mySelMgr );
1225   }
1226   else if ( vmType == Plot2d_Viewer::Type() )
1227   {
1228     viewMgr = new Plot2d_ViewManager( activeStudy(), desktop() );
1229     viewMgr->setViewModel( new SPlot2d_Viewer() );// custom view model, which extends SALOME_View interface
1230   }
1231   else if ( vmType == OCCViewer_Viewer::Type() )
1232   {
1233     viewMgr = new OCCViewer_ViewManager( activeStudy(), desktop() );
1234     SOCC_Viewer* vm = new SOCC_Viewer();
1235     vm->setBackgroundColor( resMgr->colorValue( "OCCViewer", "background", vm->backgroundColor() ) );
1236     vm->setTrihedronSize( resMgr->integerValue( "OCCViewer", "trihedron_size", vm->trihedronSize() ) );
1237     int u( 1 ), v( 1 );
1238     vm->isos( u, v );
1239     u = resMgr->integerValue( "OCCViewer", "iso_number_u", u );
1240     v = resMgr->integerValue( "OCCViewer", "iso_number_v", v );
1241     vm->setIsos( u, v );
1242     viewMgr->setViewModel( vm );// custom view model, which extends SALOME_View interface
1243     new SalomeApp_OCCSelector( (OCCViewer_Viewer*)viewMgr->getViewModel(), mySelMgr );
1244   }
1245   else if ( vmType == SVTK_Viewer::Type() )
1246   {
1247     viewMgr = new SVTK_ViewManager( activeStudy(), desktop() );
1248     SVTK_Viewer* vm = dynamic_cast<SVTK_Viewer*>( viewMgr->getViewModel() );
1249     if( vm )
1250     {
1251       vm->setBackgroundColor( resMgr->colorValue( "VTKViewer", "background", vm->backgroundColor() ) );
1252       vm->setTrihedronSize( resMgr->integerValue( "VTKViewer", "trihedron_size", vm->trihedronSize() ) );
1253       new SalomeApp_VTKSelector( vm, mySelMgr );
1254     }
1255   }
1256
1257   if ( !viewMgr )
1258     return 0;
1259
1260   addViewManager( viewMgr );
1261   SUIT_ViewWindow* viewWin = viewMgr->createViewWindow();
1262
1263   if ( viewWin && desktop() )
1264     viewWin->resize( (int)( desktop()->width() * 0.6 ), (int)( desktop()->height() * 0.6 ) );
1265
1266   connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
1267            this, SLOT( onCloseView( SUIT_ViewManager* ) ) );
1268
1269   return viewMgr;
1270 }
1271
1272 void SalomeApp_Application::onCloseView( SUIT_ViewManager* theVM )
1273 {
1274   removeViewManager( theVM );
1275 }
1276
1277 /*!Private SLOT. On study created.*/
1278 void SalomeApp_Application::onStudyCreated( SUIT_Study* theStudy )
1279 {
1280   SUIT_DataObject* aRoot = 0;
1281   if ( theStudy && theStudy->root() )
1282   {
1283     aRoot = theStudy->root();
1284     //aRoot->setName( tr( "DATA_MODELS" ) );
1285   }
1286   if ( objectBrowser() != 0 )
1287     objectBrowser()->setRootObject( aRoot );
1288
1289   activateModule( defaultModule() );
1290
1291   activateWindows();
1292 }
1293
1294 /*!Private SLOT. On study opened.*/
1295 void SalomeApp_Application::onStudyOpened( SUIT_Study* theStudy )
1296 {
1297   SUIT_DataObject* aRoot = 0;
1298   if ( theStudy && theStudy->root() )
1299   {
1300     aRoot = theStudy->root();
1301     //aRoot->dump();
1302   }
1303   if ( objectBrowser() != 0 ) {
1304     objectBrowser()->setRootObject( aRoot );
1305   }
1306
1307   activateModule( defaultModule() );
1308
1309   activateWindows();
1310
1311   emit studyOpened();
1312 }
1313
1314 void SalomeApp_Application::onStudySaved( SUIT_Study* )
1315 {
1316   emit studySaved();
1317 }
1318
1319 /*!Private SLOT. On study closed.*/
1320 void SalomeApp_Application::onStudyClosed( SUIT_Study* )
1321 {
1322   emit studyClosed();
1323
1324   activateModule( "" );
1325
1326   saveWindowsGeometry();
1327 }
1328
1329 /*!Private SLOT. On dump study.*/
1330 void SalomeApp_Application::onDumpStudy( )
1331 {
1332   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( activeStudy() );
1333   if ( !appStudy ) return;
1334   _PTR(Study) aStudy = appStudy->studyDS();
1335
1336   QStringList aFilters;
1337   aFilters.append( tr( "PYTHON_FILES_FILTER" ) );
1338
1339   SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg( desktop(), false, tr("PUBLISH_IN_STUDY"), true, true);
1340   fd->setCaption( tr( "TOT_DESK_FILE_DUMP_STUDY" ) );
1341   fd->setFilters( aFilters );
1342   fd->SetChecked(true);
1343   fd->exec();
1344   QString aFileName = fd->selectedFile();
1345   bool toPublish = fd->IsChecked();
1346   delete fd;
1347
1348   if(!aFileName.isEmpty()) {
1349     QFileInfo aFileInfo(aFileName);
1350     aStudy->DumpStudy( aFileInfo.dirPath( true ).latin1(), aFileInfo.baseName().latin1(), toPublish );
1351   }
1352 }
1353
1354 /*!Private SLOT. On load script.*/
1355 void SalomeApp_Application::onLoadScript( )
1356 {
1357   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( activeStudy() );
1358   if ( !appStudy ) return;
1359   _PTR(Study) aStudy = appStudy->studyDS();
1360
1361   if ( aStudy->GetProperties()->IsLocked() ) {
1362     SUIT_MessageBox::warn1 ( desktop(),
1363                              QObject::tr("WRN_WARNING"),
1364                              QObject::tr("WRN_STUDY_LOCKED"),
1365                              QObject::tr("BUT_OK") );
1366     return;
1367   }
1368
1369   QStringList filtersList;
1370   filtersList.append(tr("PYTHON_FILES_FILTER"));
1371   filtersList.append(tr("ALL_FILES_FILTER"));
1372
1373   QString aFile = SUIT_FileDlg::getFileName( desktop(), "", filtersList, tr( "TOT_DESK_FILE_LOAD_SCRIPT" ), true, true );
1374
1375   if ( !aFile.isEmpty() )
1376   {
1377     QString command = QString("execfile(\"%1\")").arg(aFile);
1378
1379     PythonConsole* pyConsole = pythonConsole();
1380
1381     if ( pyConsole )
1382       pyConsole->exec( command );
1383   }
1384 }
1385
1386 /*!Private SLOT. On preferences.*/
1387 void SalomeApp_Application::onPreferences()
1388 {
1389   QApplication::setOverrideCursor( Qt::waitCursor );
1390
1391   SalomeApp_PreferencesDlg* prefDlg = new SalomeApp_PreferencesDlg( preferences( true ), desktop());
1392
1393   QApplication::restoreOverrideCursor();
1394
1395   if ( !prefDlg )
1396     return;
1397
1398   prefDlg->exec();
1399
1400   delete prefDlg;
1401 }
1402
1403 /*!Private SLOT. On open document with name \a aName.*/
1404 void SalomeApp_Application::onMRUActivated( QString aName )
1405 {
1406   onOpenDoc( aName );
1407 }
1408
1409 /*!Private SLOT. On preferences changed.*/
1410 void SalomeApp_Application::onPreferenceChanged( QString& modName, QString& section, QString& param )
1411 {
1412   SalomeApp_Module* sMod = 0;
1413   CAM_Module* mod = module( modName );
1414   if ( mod && mod->inherits( "SalomeApp_Module" ) )
1415     sMod = (SalomeApp_Module*)mod;
1416
1417   if ( sMod )
1418     sMod->preferencesChanged( section, param );
1419   else
1420     preferencesChanged( section, param );
1421 }
1422
1423 /*!Gets file filter.
1424  *\retval QString "(*.hdf)"
1425  */
1426 QString SalomeApp_Application::getFileFilter() const
1427 {
1428   return "(*.hdf)";
1429 }
1430
1431 /*!Remove all windows from study.*/
1432 void SalomeApp_Application::beforeCloseDoc( SUIT_Study* s )
1433 {
1434   CAM_Application::beforeCloseDoc( s );
1435
1436   for ( WindowMap::ConstIterator itr = myWindows.begin(); s && itr != myWindows.end(); ++itr )
1437     removeWindow( itr.key(), s->id() );
1438 }
1439
1440 /*!Update actions.*/
1441 void SalomeApp_Application::updateActions()
1442 {
1443   updateCommandsStatus();
1444 }
1445
1446 /*!Create window.*/
1447 QWidget* SalomeApp_Application::createWindow( const int flag )
1448 {
1449   QWidget* wid = 0;
1450
1451   SUIT_ResourceMgr* resMgr = resourceMgr();
1452
1453   if ( flag == WT_ObjectBrowser )
1454   {
1455     OB_Browser* ob = new OB_Browser( desktop() );
1456     ob->setAutoUpdate( true );
1457     ob->setAutoOpenLevel( 1 );
1458     ob->setCaption( tr( "OBJECT_BROWSER" ) );
1459     ob->resize( OBJECT_BROWSER_WIDTH, ob->height() );
1460     ob->setFilter( new SalomeApp_OBFilter( selectionMgr() ) );
1461
1462     ob->setNameTitle( tr( "OBJ_BROWSER_NAME" ) );
1463
1464     bool autoSize = resMgr->booleanValue( "ObjectBrowser", "auto_size", false );
1465     for ( int i = SalomeApp_DataObject::CT_Value; i <= SalomeApp_DataObject::CT_RefEntry; i++ )
1466     {
1467       ob->addColumn( tr( QString().sprintf( "OBJ_BROWSER_COLUMN_%d", i ) ), i );
1468       ob->setColumnShown( i, resMgr->booleanValue( "ObjectBrowser",
1469                                                    QString().sprintf( "visibility_column_%d", i ), true ) );
1470     }
1471     ob->setWidthMode( autoSize ? QListView::Maximum : QListView::Manual );
1472
1473     // Create OBSelector
1474     new SalomeApp_OBSelector( ob, mySelMgr );
1475
1476     wid = ob;
1477
1478     ob->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
1479   }
1480   else if ( flag == WT_PyConsole )
1481   {
1482     PythonConsole* pyCons = new PythonConsole( desktop(), new SalomeApp_PyInterp() );
1483     pyCons->setCaption( tr( "PYTHON_CONSOLE" ) );
1484     pyCons->setFont( resMgr->fontValue( "PyConsole", "font" ) );
1485     wid = pyCons;
1486
1487     //    pyCons->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
1488   }
1489   else if ( flag == WT_LogWindow )
1490   {
1491     LogWindow* logWin = new LogWindow( desktop() );
1492     logWin->setCaption( tr( "LOG_WINDOW" ) );
1493     wid = logWin;
1494
1495     logWin->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
1496   }
1497
1498   return wid;
1499 }
1500
1501 /*!Default windows(Object Browser, Python Console).
1502  * Adds to map \a aMap.
1503  */
1504 void SalomeApp_Application::defaultWindows( QMap<int, int>& aMap ) const
1505 {
1506   aMap.insert( WT_ObjectBrowser, Qt::DockLeft );
1507   aMap.insert( WT_PyConsole, Qt::DockBottom );
1508   //  aMap.insert( WT_LogWindow, Qt::DockBottom );
1509 }
1510
1511 /*!Default view manager.*/
1512 void SalomeApp_Application::defaultViewManagers( QStringList& ) const
1513 {
1514   /*!Do nothing.*/
1515 }
1516
1517 /*!Gets preferences.
1518  * Create preferences, if \a crt = true.
1519  */
1520 SalomeApp_Preferences* SalomeApp_Application::preferences( const bool crt ) const
1521 {
1522   if ( myPrefs )
1523     return myPrefs;
1524
1525   SalomeApp_Application* that = (SalomeApp_Application*)this;
1526
1527   if ( !_prefs_ && crt )
1528   {
1529     _prefs_ = new SalomeApp_Preferences( resourceMgr() );
1530     that->createPreferences( _prefs_ );
1531   }
1532
1533   that->myPrefs = _prefs_;
1534
1535   QPtrList<SUIT_Application> appList = SUIT_Session::session()->applications();
1536   for ( QPtrListIterator<SUIT_Application> appIt ( appList ); appIt.current(); ++appIt )
1537   {
1538     if ( !appIt.current()->inherits( "SalomeApp_Application" ) )
1539       continue;
1540
1541     SalomeApp_Application* app = (SalomeApp_Application*)appIt.current();
1542
1543     QStringList modNameList;
1544     app->modules( modNameList, false );
1545     for ( QStringList::const_iterator it = modNameList.begin(); it != modNameList.end(); ++it )
1546     {
1547       int id = _prefs_->addPreference( *it );
1548       _prefs_->setItemProperty( id, "info", tr( "PREFERENCES_NOT_LOADED" ).arg( *it ) );
1549     }
1550
1551     ModuleList modList;
1552     app->modules( modList );
1553     for ( ModuleListIterator itr( modList ); itr.current(); ++itr )
1554     {
1555       SalomeApp_Module* mod = 0;
1556       if ( itr.current()->inherits( "SalomeApp_Module" ) )
1557         mod = (SalomeApp_Module*)itr.current();
1558
1559       if ( mod && !_prefs_->hasModule( mod->moduleName() ) )
1560       {
1561         int modCat = _prefs_->addPreference( mod->moduleName() );
1562         _prefs_->setItemProperty( modCat, "info", QString::null );
1563         mod->createPreferences();
1564       }
1565     }
1566   }
1567
1568   connect( myPrefs, SIGNAL( preferenceChanged( QString&, QString&, QString& ) ),
1569            this, SLOT( onPreferenceChanged( QString&, QString&, QString& ) ) );
1570
1571   return myPrefs;
1572 }
1573
1574 /*!Add new module to application.*/
1575 void SalomeApp_Application::moduleAdded( CAM_Module* mod )
1576 {
1577   CAM_Application::moduleAdded( mod );
1578
1579   SalomeApp_Module* salomeMod = 0;
1580   if ( mod && mod->inherits( "SalomeApp_Module" ) )
1581     salomeMod = (SalomeApp_Module*)mod;
1582
1583   if ( myPrefs && salomeMod && !myPrefs->hasModule( salomeMod->moduleName() ) )
1584   {
1585     int modCat = myPrefs->addPreference( mod->moduleName() );
1586     myPrefs->setItemProperty( modCat, "info", QString::null );
1587     salomeMod->createPreferences();
1588   }
1589 }
1590
1591 /*!Create preferences.*/
1592 void SalomeApp_Application::createPreferences( SalomeApp_Preferences* pref )
1593 {
1594   if ( !pref )
1595     return;
1596
1597   int salomeCat = pref->addPreference( tr( "PREF_CATEGORY_SALOME" ) );
1598
1599   int genTab = pref->addPreference( tr( "PREF_TAB_GENERAL" ), salomeCat );
1600   int studyGroup = pref->addPreference( tr( "PREF_GROUP_STUDY" ), genTab );
1601   pref->setItemProperty( studyGroup, "columns", 1 );
1602
1603   pref->addPreference( tr( "PREF_MULTI_FILE" ), studyGroup, SalomeApp_Preferences::Bool, "Study", "multi_file" );
1604   pref->addPreference( tr( "PREF_ASCII_FILE" ), studyGroup, SalomeApp_Preferences::Bool, "Study", "ascii_file" );
1605   int undoPref = pref->addPreference( tr( "PREF_UNDO_LEVEL" ), studyGroup, SalomeApp_Preferences::IntSpin, "Study", "undo_level" );
1606   pref->setItemProperty( undoPref, "min", 1 );
1607   pref->setItemProperty( undoPref, "max", 100 );
1608
1609   int extgroup = pref->addPreference( tr( "PREF_GROUP_EXT_BROWSER" ), genTab );
1610   pref->setItemProperty( extgroup, "columns", 1 );
1611   int apppref = pref->addPreference( tr( "PREF_APP" ), extgroup, SalomeApp_Preferences::File, "ExternalBrowser", "application" );
1612   pref->setItemProperty( apppref, "existing", true );
1613   pref->setItemProperty( apppref, "flags", QFileInfo::ExeUser );
1614
1615   pref->addPreference( tr( "PREF_PARAM" ), extgroup, SalomeApp_Preferences::String, "ExternalBrowser", "parameters" );
1616
1617   int pythonConsoleGroup = pref->addPreference( tr( "PREF_GROUP_PY_CONSOLE" ), genTab );
1618   pref->setItemProperty( pythonConsoleGroup, "columns", 1 );
1619   pref->addPreference( tr( "PREF_FONT" ), pythonConsoleGroup, SalomeApp_Preferences::Font, "PyConsole", "font" );
1620
1621
1622
1623   int obTab = pref->addPreference( tr( "PREF_TAB_OBJBROWSER" ), salomeCat );
1624   int defCols = pref->addPreference( tr( "PREF_GROUP_DEF_COLUMNS" ), obTab );
1625   for ( int i = SalomeApp_DataObject::CT_Value; i <= SalomeApp_DataObject::CT_RefEntry; i++ )
1626   {
1627     pref->addPreference( tr( QString().sprintf( "OBJ_BROWSER_COLUMN_%d", i ) ), defCols,
1628                          SalomeApp_Preferences::Bool, "ObjectBrowser", QString().sprintf( "visibility_column_%d", i ) );
1629   }
1630   pref->setItemProperty( defCols, "columns", 1 );
1631
1632   int objSetGroup = pref->addPreference( tr( "PREF_OBJ_BROWSER_SETTINGS" ), obTab );
1633   pref->addPreference( tr( "PREF_AUTO_SIZE" ), objSetGroup, SalomeApp_Preferences::Bool, "ObjectBrowser", "auto_size" );
1634
1635   int viewTab = pref->addPreference( tr( "PREF_TAB_VIEWERS" ), salomeCat );
1636
1637   int occGroup = pref->addPreference( tr( "PREF_GROUP_OCCVIEWER" ), viewTab );
1638
1639   int vtkGroup = pref->addPreference( tr( "PREF_GROUP_VTKVIEWER" ), viewTab );
1640
1641   int plot2dGroup = pref->addPreference( tr( "PREF_GROUP_PLOT2DVIEWER" ), viewTab );
1642
1643   pref->setItemProperty( occGroup, "columns", 1 );
1644   pref->setItemProperty( vtkGroup, "columns", 1 );
1645   pref->setItemProperty( plot2dGroup, "columns", 1 );
1646
1647   int occTS = pref->addPreference( tr( "PREF_TRIHEDRON_SIZE" ), occGroup,
1648                                    SalomeApp_Preferences::IntSpin, "OCCViewer", "trihedron_size" );
1649   pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), occGroup,
1650                        SalomeApp_Preferences::Color, "OCCViewer", "background" );
1651
1652   pref->setItemProperty( occTS, "min", 1 );
1653   pref->setItemProperty( occTS, "max", 150 );
1654
1655   int isoU = pref->addPreference( tr( "PREF_ISOS_U" ), occGroup,
1656                                   SalomeApp_Preferences::IntSpin, "OCCViewer", "iso_number_u" );
1657   int isoV = pref->addPreference( tr( "PREF_ISOS_V" ), occGroup,
1658                                   SalomeApp_Preferences::IntSpin, "OCCViewer", "iso_number_v" );
1659
1660   pref->setItemProperty( isoU, "min", 0 );
1661   pref->setItemProperty( isoU, "max", 100000 );
1662
1663   pref->setItemProperty( isoV, "min", 0 );
1664   pref->setItemProperty( isoV, "max", 100000 );
1665
1666   int vtkTS = pref->addPreference( tr( "PREF_TRIHEDRON_SIZE" ), vtkGroup,
1667                                    SalomeApp_Preferences::IntSpin, "VTKViewer", "trihedron_size" );
1668   pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), vtkGroup,
1669                        SalomeApp_Preferences::Color, "VTKViewer", "background" );
1670
1671   pref->setItemProperty( vtkTS, "min", 1 );
1672   pref->setItemProperty( vtkTS, "max", 150 );
1673
1674   pref->addPreference( tr( "PREF_SHOW_LEGEND" ), plot2dGroup,
1675                        SalomeApp_Preferences::Bool, "Plot2d", "ShowLegend" );
1676
1677   int legendPosition = pref->addPreference( tr( "PREF_LEGEND_POSITION" ), plot2dGroup,
1678                                             SalomeApp_Preferences::Selector, "Plot2d", "LegendPos" );
1679   QStringList aLegendPosList;
1680   aLegendPosList.append( tr("PREF_LEFT") );
1681   aLegendPosList.append( tr("PREF_RIGHT") );
1682   aLegendPosList.append( tr("PREF_TOP") );
1683   aLegendPosList.append( tr("PREF_BOTTOM") );
1684
1685   QValueList<QVariant> anIndexesList;
1686   anIndexesList.append(0);
1687   anIndexesList.append(1);
1688   anIndexesList.append(2);
1689   anIndexesList.append(3);
1690
1691   pref->setItemProperty( legendPosition, "strings", aLegendPosList );
1692   pref->setItemProperty( legendPosition, "indexes", anIndexesList );
1693
1694   int curveType = pref->addPreference( tr( "PREF_CURVE_TYPE" ), plot2dGroup,
1695                                        SalomeApp_Preferences::Selector, "Plot2d", "CurveType" );
1696   QStringList aCurveTypesList;
1697   aCurveTypesList.append( tr("PREF_POINTS") );
1698   aCurveTypesList.append( tr("PREF_LINES") );
1699   aCurveTypesList.append( tr("PREF_SPLINE") );
1700
1701   anIndexesList.clear();
1702   anIndexesList.append(0);
1703   anIndexesList.append(1);
1704   anIndexesList.append(2);
1705
1706   pref->setItemProperty( curveType, "strings", aCurveTypesList );
1707   pref->setItemProperty( curveType, "indexes", anIndexesList );
1708
1709   int markerSize = pref->addPreference( tr( "PREF_MARKER_SIZE" ), plot2dGroup,
1710                                         SalomeApp_Preferences::IntSpin, "Plot2d", "MarkerSize" );
1711
1712   pref->setItemProperty( markerSize, "min", 0 );
1713   pref->setItemProperty( markerSize, "max", 100 );
1714
1715   QStringList aScaleModesList;
1716   aScaleModesList.append( tr("PREF_LINEAR") );
1717   aScaleModesList.append( tr("PREF_LOGARITHMIC") );
1718
1719   anIndexesList.clear();
1720   anIndexesList.append(0);
1721   anIndexesList.append(1);
1722
1723   int horScale = pref->addPreference( tr( "PREF_HOR_AXIS_SCALE" ), plot2dGroup,
1724                                       SalomeApp_Preferences::Selector, "Plot2d", "HorScaleMode" );
1725
1726   pref->setItemProperty( horScale, "strings", aScaleModesList );
1727   pref->setItemProperty( horScale, "indexes", anIndexesList );
1728
1729   int verScale = pref->addPreference( tr( "PREF_VERT_AXIS_SCALE" ), plot2dGroup,
1730                                       SalomeApp_Preferences::Selector, "Plot2d", "VerScaleMode" );
1731
1732   pref->setItemProperty( verScale, "strings", aScaleModesList );
1733   pref->setItemProperty( verScale, "indexes", anIndexesList );
1734
1735   pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), plot2dGroup,
1736                        SalomeApp_Preferences::Color, "Plot2d", "Background" );
1737
1738   int dirTab = pref->addPreference( tr( "PREF_TAB_DIRECTORIES" ), salomeCat );
1739   int dirGroup = pref->addPreference( tr( "PREF_GROUP_DIRECTORIES" ), dirTab );
1740   pref->setItemProperty( dirGroup, "columns", 1 );
1741   pref->addPreference( tr( "" ), dirGroup,
1742                        SalomeApp_Preferences::DirList, "FileDlg", "QuickDirList" );
1743 }
1744
1745 void SalomeApp_Application::preferencesChanged( const QString& sec, const QString& param )
1746 {
1747   SUIT_ResourceMgr* resMgr = resourceMgr();
1748   if ( !resMgr )
1749     return;
1750
1751   if ( sec == QString( "OCCViewer" ) && param == QString( "trihedron_size" ) )
1752   {
1753     int sz = resMgr->integerValue( sec, param, -1 );
1754     QPtrList<SUIT_ViewManager> lst;
1755     viewManagers( OCCViewer_Viewer::Type(), lst );
1756     for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current() && sz >= 0; ++it )
1757     {
1758       SUIT_ViewModel* vm = it.current()->getViewModel();
1759       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
1760         continue;
1761
1762       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
1763       occVM->setTrihedronSize( sz );
1764       occVM->getAISContext()->UpdateCurrentViewer();
1765     }
1766   }
1767
1768   if ( sec == QString( "VTKViewer" ) && param == QString( "trihedron_size" ) )
1769   {
1770     int sz = resMgr->integerValue( sec, param, -1 );
1771     QPtrList<SUIT_ViewManager> lst;
1772     viewManagers( SVTK_Viewer::Type(), lst );
1773     for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current() && sz >= 0; ++it )
1774     {
1775       SUIT_ViewModel* vm = it.current()->getViewModel();
1776       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
1777         continue;
1778
1779       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
1780       if( vtkVM )
1781       {
1782         vtkVM->setTrihedronSize( sz );
1783         vtkVM->Repaint();
1784       }
1785     }
1786   }
1787
1788   if ( sec == QString( "OCCViewer" ) && ( param == QString( "iso_number_u" ) || param == QString( "iso_number_v" ) ) )
1789   {
1790     QPtrList<SUIT_ViewManager> lst;
1791     viewManagers( OCCViewer_Viewer::Type(), lst );
1792     int u = resMgr->integerValue( sec, "iso_number_u" );
1793     int v = resMgr->integerValue( sec, "iso_number_v" );
1794     for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current(); ++it )
1795       ((OCCViewer_Viewer*)it.current())->setIsos( u, v );
1796   }
1797
1798   if( sec=="ObjectBrowser" )
1799   {
1800     if( param=="auto_size" )
1801     {
1802       OB_Browser* ob = objectBrowser();
1803       if( !ob )
1804         return;
1805
1806       bool autoSize = resMgr->booleanValue( "ObjectBrowser", "auto_size", false );
1807       ob->setWidthMode( autoSize ? QListView::Maximum : QListView::Manual );
1808
1809       updateObjectBrowser( false );
1810     }
1811   }
1812
1813   if( sec=="PyConsole" )
1814   {
1815     if( param=="font" )
1816       if( pythonConsole() )
1817         pythonConsole()->setFont( resMgr->fontValue( "PyConsole", "font" ) );
1818   }
1819 }
1820
1821 /*!Update desktop title.*/
1822 void SalomeApp_Application::updateDesktopTitle() {
1823   QString aTitle = applicationName();
1824   QString aVer = applicationVersion();
1825   if ( !aVer.isEmpty() )
1826     aTitle += QString( " " ) + aVer;
1827
1828   if ( activeStudy() )
1829   {
1830     QString sName = SUIT_Tools::file( activeStudy()->studyName().stripWhiteSpace(), false );
1831     if ( !sName.isEmpty() ) {
1832       SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
1833       _PTR(Study) stdDS = study->studyDS();
1834       if(stdDS) {
1835         if ( stdDS->GetProperties()->IsLocked() ) {
1836           aTitle += QString( " - [%1 (%2)]").arg( sName ).arg( tr( "STUDY_LOCKED" ) );
1837         } else {
1838           aTitle += QString( " - [%1]" ).arg( sName );
1839         }
1840       }
1841     }
1842   }
1843
1844   desktop()->setCaption( aTitle );
1845 }
1846
1847 /*!Update windows after close document.*/
1848 void SalomeApp_Application::afterCloseDoc()
1849 {
1850   updateWindows();
1851
1852   CAM_Application::afterCloseDoc();
1853 }
1854
1855 /*!Gets CORBA::ORB_var*/
1856 CORBA::ORB_var SalomeApp_Application::orb()
1857 {
1858   ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
1859   static CORBA::ORB_var _orb = init( qApp->argc(), qApp->argv() );
1860   return _orb;
1861 }
1862
1863 /*!Create and return SALOMEDS_StudyManager.*/
1864 SALOMEDSClient_StudyManager* SalomeApp_Application::studyMgr()
1865 {
1866   static SALOMEDSClient_StudyManager* _sm = new SALOMEDS_StudyManager();
1867   return _sm;
1868 }
1869
1870 /*!Create and return SALOME_NamingService.*/
1871 SALOME_NamingService* SalomeApp_Application::namingService()
1872 {
1873   static SALOME_NamingService* _ns = new SALOME_NamingService( orb() );
1874   return _ns;
1875 }
1876
1877 /*!Create and return SALOME_LifeCycleCORBA.*/
1878 SALOME_LifeCycleCORBA* SalomeApp_Application::lcc()
1879 {
1880   static SALOME_LifeCycleCORBA* _lcc = new SALOME_LifeCycleCORBA( namingService() );
1881   return _lcc;
1882 }
1883
1884 QString SalomeApp_Application::defaultEngineIOR()
1885 {
1886   /// Look for a default module engine (needed for CORBAless modules to use SALOMEDS persistence)
1887   QString anIOR( "" );
1888   CORBA::Object_ptr anEngine = namingService()->Resolve( "/SalomeAppEngine" );
1889   if ( !CORBA::is_nil( anEngine ) )
1890     anIOR = orb()->object_to_string( anEngine );
1891   return anIOR;
1892 }
1893
1894 /*!Adds icon names for modules.*/
1895 void SalomeApp_Application::moduleIconNames( QMap<QString, QString>& iconMap ) const
1896 {
1897   iconMap.clear();
1898
1899   SUIT_ResourceMgr* resMgr = resourceMgr();
1900   if ( !resMgr )
1901     return;
1902
1903   QStringList modList;
1904   modules( modList, false );
1905
1906   for ( QStringList::const_iterator it = modList.begin(); it != modList.end(); ++it )
1907   {
1908     QString modName = *it;
1909     QString modIntr = moduleName( modName );
1910     QString modIcon = resMgr->stringValue( modIntr, "icon", QString::null );
1911
1912     if ( modIcon.isEmpty() )
1913       continue;
1914
1915     if ( SUIT_Tools::extension( modIcon ).isEmpty() )
1916       modIcon += QString( ".png" );
1917
1918     iconMap.insert( modName, modIcon );
1919   }
1920 }
1921
1922 /*!Update module action.*/
1923 void SalomeApp_Application::updateModuleActions()
1924 {
1925   QString modName;
1926   if ( activeModule() )
1927     modName = activeModule()->moduleName();
1928
1929   if ( myActions.contains( modName ) )
1930     myActions[modName]->setOn( true );
1931 }
1932
1933 /*!Gets current windows.
1934  *\param winMap - output current windows map.
1935  */
1936 void SalomeApp_Application::currentWindows( QMap<int, int>& winMap ) const
1937 {
1938   winMap.clear();
1939   if ( !activeStudy() )
1940     return;
1941
1942   if ( activeModule() && activeModule()->inherits( "SalomeApp_Module" ) )
1943     ((SalomeApp_Module*)activeModule())->windows( winMap );
1944   else
1945     defaultWindows( winMap );
1946 }
1947
1948 /*!Gets current view managers.
1949  *\param lst - output current view managers list.
1950  */
1951 void SalomeApp_Application::currentViewManagers( QStringList& lst ) const
1952 {
1953   lst.clear();
1954   if ( !activeStudy() )
1955     return;
1956
1957   if ( activeModule() && activeModule()->inherits( "SalomeApp_Module" ) )
1958     ((SalomeApp_Module*)activeModule())->viewManagers( lst );
1959   else
1960     defaultViewManagers( lst );
1961 }
1962
1963 /*!Update windows.*/
1964 void SalomeApp_Application::updateWindows()
1965 {
1966   QMap<int, int> winMap;
1967   currentWindows( winMap );
1968
1969   for ( QMap<int, int>::ConstIterator it = winMap.begin(); it != winMap.end(); ++it )
1970     getWindow( it.key() );
1971
1972   loadWindowsGeometry();
1973
1974   for ( WindowMap::ConstIterator itr = myWindows.begin(); itr != myWindows.end(); ++itr )
1975     setWindowShown( itr.key(), !itr.data()->isEmpty() && winMap.contains( itr.key() ) );
1976 }
1977
1978 /*!Update view managers.*/
1979 void SalomeApp_Application::updateViewManagers()
1980 {
1981   QStringList lst;
1982   currentViewManagers( lst );
1983
1984   for ( QStringList::const_iterator it = lst.begin(); it != lst.end(); ++it )
1985     getViewManager( *it, true );
1986 }
1987
1988 /*!Load windows geometry.*/
1989 void SalomeApp_Application::loadWindowsGeometry()
1990 {
1991   QtxDockAction* dockMgr = 0;
1992
1993   QAction* a = action( ViewWindowsId );
1994   if ( a && a->inherits( "QtxDockAction" ) )
1995     dockMgr = (QtxDockAction*)a;
1996
1997   if ( !dockMgr )
1998     return;
1999
2000   QString modName;
2001   if ( activeModule() )
2002     modName = activeModule()->name("");
2003
2004   QString section = QString( "windows_geometry" );
2005   if ( !modName.isEmpty() )
2006     section += QString( "." ) + modName;
2007
2008   dockMgr->loadGeometry( resourceMgr(), section, false );
2009   dockMgr->restoreGeometry();
2010 }
2011
2012 /*!Save windows geometry.*/
2013 void SalomeApp_Application::saveWindowsGeometry()
2014 {
2015   QtxDockAction* dockMgr = 0;
2016
2017   QAction* a = action( ViewWindowsId );
2018   if ( a && a->inherits( "QtxDockAction" ) )
2019     dockMgr = (QtxDockAction*)a;
2020
2021   if ( !dockMgr )
2022     return;
2023
2024   QString modName;
2025   if ( activeModule() )
2026     modName = activeModule()->name("");
2027
2028   QString section = QString( "windows_geometry" );
2029   if ( !modName.isEmpty() )
2030     section += QString( "." ) + modName;
2031
2032   dockMgr->storeGeometry();
2033   dockMgr->saveGeometry( resourceMgr(), section, false );
2034 }
2035
2036 /*!Activate windows.*/
2037 void SalomeApp_Application::activateWindows()
2038 {
2039   if ( activeStudy() )
2040   {
2041     for ( WindowMap::Iterator itr = myWindows.begin(); itr != myWindows.end(); ++itr )
2042       itr.data()->activate( activeStudy()->id() );
2043   }
2044 }
2045
2046 /*!Private SLOT. On preferences.*/
2047 void SalomeApp_Application::onProperties()
2048 {
2049   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( activeStudy() );
2050   if( !study )
2051     return;
2052
2053   _PTR(StudyBuilder) SB = study->studyDS()->NewBuilder();
2054   SB->NewCommand();
2055
2056   SalomeApp_StudyPropertiesDlg aDlg( desktop() );
2057   int res = aDlg.exec();
2058   if( res==QDialog::Accepted && aDlg.isChanged() )
2059     SB->CommitCommand();
2060   else
2061     SB->AbortCommand();
2062
2063   //study->updateCaptions();
2064   updateDesktopTitle();
2065   updateActions();
2066 }
2067
2068 /*!*/
2069 QString SalomeApp_Application::getFileName( bool open, const QString& initial, const QString& filters,
2070                                             const QString& caption, QWidget* parent )
2071 {
2072   if ( !parent )
2073     parent = desktop();
2074   QStringList fls = QStringList::split( ";;", filters, false );
2075   return SUIT_FileDlg::getFileName( parent, initial, fls, caption, open, true );
2076 }
2077
2078 /*!*/
2079 QString SalomeApp_Application::getDirectory( const QString& initial, const QString& caption, QWidget* parent )
2080 {
2081   if ( !parent )
2082     parent = desktop();
2083   return SUIT_FileDlg::getExistingDirectory( parent, initial, caption, true );
2084 }
2085
2086 /*!*/
2087 QStringList SalomeApp_Application::getOpenFileNames( const QString& initial, const QString& filters,
2088                                                      const QString& caption, QWidget* parent )
2089 {
2090   if ( !parent )
2091     parent = desktop();
2092   QStringList fls = QStringList::split( ";;", filters, false );
2093   return SUIT_FileDlg::getOpenFileNames( parent, initial, fls, caption, true );
2094 }
2095
2096 /*!*/
2097 void SalomeApp_Application::contextMenuPopup( const QString& type, QPopupMenu* thePopup, QString& title )
2098 {
2099   CAM_Application::contextMenuPopup( type, thePopup, title );
2100
2101   OB_Browser* ob = objectBrowser();
2102   if ( !ob || type != ob->popupClientType() )
2103     return;
2104
2105   thePopup->insertSeparator();
2106   thePopup->insertItem( tr( "MEN_REFRESH" ), this, SLOT( onRefresh() ) );
2107
2108   // Get selected objects
2109   SALOME_ListIO aList;
2110   SalomeApp_SelectionMgr* mgr = selectionMgr();
2111   mgr->selectedObjects(aList);
2112
2113   // "Delete reference" item should appear only for invalid references
2114
2115   // Check if selected objects is invalid references
2116   bool isInvalidRefs = true;
2117
2118   if ( aList.Extent() < 1 )
2119     isInvalidRefs = false;
2120
2121   if ( isInvalidRefs )
2122     {
2123       SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(activeStudy());
2124       _PTR(Study) aStudyDS = aStudy->studyDS();
2125       _PTR(SObject) anObj;
2126
2127       for ( SALOME_ListIteratorOfListIO it( aList ); it.More() && isInvalidRefs; it.Next() )
2128         {
2129           if ( it.Value()->hasEntry() )
2130             {
2131               _PTR(SObject) aSObject = aStudyDS->FindObjectID( it.Value()->getEntry() );
2132               if ( aSObject->ReferencedObject(anObj) == false || !QString(anObj->GetName().c_str()).isEmpty() )
2133                 isInvalidRefs = false;
2134             }
2135         }
2136     }
2137
2138   // Add "Delete refrence" item to popup
2139   if ( isInvalidRefs )
2140     {
2141       thePopup->insertSeparator();
2142       thePopup->insertItem( tr( "MEN_DELETE_REFERENCE" ), this, SLOT( onDeleteReferences() ) );
2143       return;
2144     }
2145
2146   // "Activate module" item should appear only if it's necessary
2147   if (aList.Extent() != 1)
2148     return;
2149   Handle(SALOME_InteractiveObject) aIObj = aList.First();
2150   QString aModuleName(aIObj->getComponentDataType());
2151   QString aModuleTitle = moduleTitle(aModuleName);
2152   CAM_Module* currentModule = activeModule();
2153   if (currentModule && currentModule->moduleName() == aModuleTitle)
2154     return;
2155   thePopup->insertItem( tr( "MEN_OPENWITH" ), this, SLOT( onOpenWith() ) );
2156
2157 }
2158
2159 /*!Update obect browser*/
2160 void SalomeApp_Application::updateObjectBrowser( const bool updateModels )
2161 {
2162   // update existing data models (already loaded SComponents)
2163   if ( updateModels )
2164   {
2165     for ( ModuleListIterator it = modules(); it.current(); ++it )
2166     {
2167       CAM_DataModel* camDM = it.current()->dataModel();
2168       if ( camDM && camDM->inherits( "SalomeApp_DataModel" ) )
2169         ((SalomeApp_DataModel*)camDM)->update();
2170     }
2171   }
2172   // update "non-existing" (not loaded yet) data models
2173   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
2174   if ( study )
2175   {
2176     _PTR(Study) stdDS = study->studyDS();
2177     if( stdDS )
2178     {
2179       for ( _PTR(SComponentIterator) it ( stdDS->NewComponentIterator() ); it->More(); it->Next() )
2180       {
2181         _PTR(SComponent) aComponent ( it->Value() );
2182
2183         if ( aComponent->ComponentDataType() == "Interface Applicative" )
2184           continue; // skip the magic "Interface Applicative" component
2185
2186         SalomeApp_DataModel::BuildTree( aComponent, study->root(), study, /*skipExisitng=*/true );
2187       }
2188     }
2189   }
2190
2191   if ( objectBrowser() )
2192   {
2193     objectBrowser()->updateGeometry();
2194     objectBrowser()->updateTree();
2195   }
2196 }
2197
2198 /*!Protected SLOT.On desktop activated.*/
2199 void SalomeApp_Application::onDesktopActivated()
2200 {
2201   CAM_Application::onDesktopActivated();
2202   SalomeApp_Module* aModule = dynamic_cast<SalomeApp_Module*>(activeModule());
2203   if(aModule)
2204     aModule->studyActivated();
2205 }
2206
2207 /*!Create empty study.*/
2208 void SalomeApp_Application::createEmptyStudy()
2209 {
2210   CAM_Application::createEmptyStudy();
2211   if ( objectBrowser() )
2212     objectBrowser()->updateTree();
2213 }
2214
2215 /*!Activate module \a mod.*/
2216 bool SalomeApp_Application::activateModule( CAM_Module* mod )
2217 {
2218   bool res = CAM_Application::activateModule( mod );
2219   if ( objectBrowser() )
2220     objectBrowser()->updateTree();
2221   return res;
2222 }
2223
2224 /*!Display Catalog Genenerator dialog */
2225 void SalomeApp_Application::onCatalogGen()
2226 {
2227   ToolsGUI_CatalogGeneratorDlg aDlg( desktop() );
2228   aDlg.exec();
2229 }
2230
2231 /*!Display Registry Display dialog */
2232 void SalomeApp_Application::onRegDisplay()
2233 {
2234   CORBA::ORB_var anOrb = orb();
2235   ToolsGUI_RegWidget* regWnd = ToolsGUI_RegWidget::GetRegWidget( anOrb, desktop(), "Registry" );
2236   regWnd->show();
2237   regWnd->raise();
2238   regWnd->setActiveWindow();
2239 }
2240
2241 /*!return keyborad accelerators manager object */
2242 SUIT_Accel* SalomeApp_Application::accel() const
2243 {
2244   return myAccel;
2245 }