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