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