]> SALOME platform Git repositories - modules/gui.git/blob - src/LightApp/LightApp_Application.cxx
Salome HOME
PAL10635 - IMPROVEMENT: renaming of windows
[modules/gui.git] / src / LightApp / LightApp_Application.cxx
1 // File:      LightApp_Application.cxx
2 // Created:   6/20/2005 18:39:45 PM
3 // Author:    Natalia Donis
4 // Copyright (C) CEA 2005
5
6 #include "PythonConsole_PyInterp.h" // WARNING! This include must be the first!
7
8 #include "LightApp_Application.h"
9 #include "LightApp_WidgetContainer.h"
10 #include "LightApp_Module.h"
11 #include "LightApp_DataModel.h"
12 #include "LightApp_Study.h"
13 #include "LightApp_Preferences.h"
14 #include "LightApp_PreferencesDlg.h"
15 #include "LightApp_ModuleDlg.h"
16 #include "LightApp_AboutDlg.h"
17
18 #include "LightApp_OBFilter.h"
19
20 #include "LightApp_GLSelector.h"
21 #include "LightApp_OBSelector.h"
22 #include "LightApp_OCCSelector.h"
23 #include "LightApp_VTKSelector.h"
24 #include "LightApp_SelectionMgr.h"
25
26 #include <CAM_Module.h>
27 #include <CAM_DataModel.h>
28 #include <CAM_Study.h>
29 #include <STD_TabDesktop.h>
30
31 #include <SUIT_Session.h>
32 #include <SUIT_Study.h>
33 #include <SUIT_FileDlg.h>
34 #include <SUIT_ResourceMgr.h>
35 #include <SUIT_Tools.h>
36 #include <SUIT_Accel.h>
37
38 #include <QtxMRUAction.h>
39 #include <QtxDockAction.h>
40 #include <QtxToolBar.h>
41
42 #include <LogWindow.h>
43 #include <OB_Browser.h>
44 #include <PythonConsole_PyConsole.h>
45
46 #include <GLViewer_Viewer.h>
47 #include <GLViewer_ViewManager.h>
48
49 #include <Plot2d_ViewManager.h>
50 #include <Plot2d_ViewModel.h>
51 #include <SPlot2d_ViewModel.h>
52
53 #include <OCCViewer_ViewManager.h>
54 #include <SOCC_ViewModel.h>
55
56 #include <SVTK_ViewModel.h>
57 #include <SVTK_ViewManager.h>
58 #include <VTKViewer_ViewModel.h>
59
60 #include <SUPERVGraph_ViewModel.h>
61 #include <SUPERVGraph_ViewFrame.h>
62 #include <SUPERVGraph_ViewManager.h>
63
64 #include <QtxWorkstack.h>
65
66 #include <qdir.h>
67 #include <qimage.h>
68 #include <qstring.h>
69 #include <qwidget.h>
70 #include <qstringlist.h>
71 #include <qfile.h>
72 #include <qapplication.h>
73 #include <qmap.h>
74 #include <qstatusbar.h>
75 #include <qthread.h>
76
77 #define OBJECT_BROWSER_WIDTH 300
78 #define OBJECT_COLUMN_WIDTH 150
79
80 #define DEFAULT_BROWSER "mozilla"
81
82 #define FIRST_HELP_ID 1000000
83
84 #include "SALOME_InteractiveObject.hxx"
85 #include "SALOME_ListIO.hxx"
86
87 static const char* imageEmptyIcon[] = {
88 "20 20 1 1",
89 ".      c None",
90 "....................",
91 "....................",
92 "....................",
93 "....................",
94 "....................",
95 "....................",
96 "....................",
97 "....................",
98 "....................",
99 "....................",
100 "....................",
101 "....................",
102 "....................",
103 "....................",
104 "....................",
105 "....................",
106 "....................",
107 "....................",
108 "....................",
109 "...................."};
110
111 /*!Create new instance of LightApp_Application.*/
112 extern "C" LIGHTAPP_EXPORT SUIT_Application* createApplication()
113 {
114   return new LightApp_Application();
115 }
116
117 LightApp_Preferences* LightApp_Application::_prefs_ = 0;
118
119 /*
120   Class       : LightApp_Application
121   Description : Application containing LightApp module
122 */
123
124 /*!Constructor.*/
125 LightApp_Application::LightApp_Application()
126 : CAM_Application( false ),
127 myPrefs( 0 )
128 {
129   STD_TabDesktop* desk = new STD_TabDesktop();
130
131   setDesktop( desk );
132
133   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
134   QPixmap aLogo = aResMgr->loadPixmap( "LightApp", tr( "APP_DEFAULT_ICO" ), false );
135
136   desktop()->setIcon( aLogo );
137   desktop()->setDockableMenuBar( true );
138   desktop()->setDockableStatusBar( false );
139
140   // base logo (salome itself)
141   desktop()->addLogo( "_app_base",  aResMgr->loadPixmap( "LightApp", tr( "APP_BASE_LOGO" ), false ) );
142   // extra logo (salome-based application)
143   desktop()->addLogo( "_app_extra", aResMgr->loadPixmap( "LightApp", tr( "APP_EXTRA_LOGO" ), false ) );
144
145   clearViewManagers();
146
147   mySelMgr = new LightApp_SelectionMgr( this );
148
149   myAccel = new SUIT_Accel( desktop() );
150   myAccel->setActionKey( SUIT_Accel::PanLeft,     CTRL+Key_Left,     OCCViewer_Viewer::Type() );
151   myAccel->setActionKey( SUIT_Accel::PanRight,    CTRL+Key_Right,    OCCViewer_Viewer::Type() );
152   myAccel->setActionKey( SUIT_Accel::PanUp,       CTRL+Key_Up,       OCCViewer_Viewer::Type() );
153   myAccel->setActionKey( SUIT_Accel::PanDown,     CTRL+Key_Down,     OCCViewer_Viewer::Type() );
154   myAccel->setActionKey( SUIT_Accel::ZoomIn,      CTRL+Key_Plus,     OCCViewer_Viewer::Type() );
155   myAccel->setActionKey( SUIT_Accel::ZoomOut,     CTRL+Key_Minus,    OCCViewer_Viewer::Type() );
156   myAccel->setActionKey( SUIT_Accel::ZoomFit,     CTRL+Key_Asterisk, OCCViewer_Viewer::Type() );
157   myAccel->setActionKey( SUIT_Accel::RotateLeft,  ALT+Key_Left,      OCCViewer_Viewer::Type() );
158   myAccel->setActionKey( SUIT_Accel::RotateRight, ALT+Key_Right,     OCCViewer_Viewer::Type() );
159   myAccel->setActionKey( SUIT_Accel::RotateUp,    ALT+Key_Up,        OCCViewer_Viewer::Type() );
160   myAccel->setActionKey( SUIT_Accel::RotateDown,  ALT+Key_Down,      OCCViewer_Viewer::Type() );
161   myAccel->setActionKey( SUIT_Accel::PanLeft,     CTRL+Key_Left,     VTKViewer_Viewer::Type() );
162   myAccel->setActionKey( SUIT_Accel::PanRight,    CTRL+Key_Right,    VTKViewer_Viewer::Type() );
163   myAccel->setActionKey( SUIT_Accel::PanUp,       CTRL+Key_Up,       VTKViewer_Viewer::Type() );
164   myAccel->setActionKey( SUIT_Accel::PanDown,     CTRL+Key_Down,     VTKViewer_Viewer::Type() );
165   myAccel->setActionKey( SUIT_Accel::ZoomIn,      CTRL+Key_Plus,     VTKViewer_Viewer::Type() );
166   myAccel->setActionKey( SUIT_Accel::ZoomOut,     CTRL+Key_Minus,    VTKViewer_Viewer::Type() );
167   myAccel->setActionKey( SUIT_Accel::ZoomFit,     CTRL+Key_Asterisk, VTKViewer_Viewer::Type() );
168   myAccel->setActionKey( SUIT_Accel::RotateLeft,  ALT+Key_Left,      VTKViewer_Viewer::Type() );
169   myAccel->setActionKey( SUIT_Accel::RotateRight, ALT+Key_Right,     VTKViewer_Viewer::Type() );
170   myAccel->setActionKey( SUIT_Accel::RotateUp,    ALT+Key_Up,        VTKViewer_Viewer::Type() );
171   myAccel->setActionKey( SUIT_Accel::RotateDown,  ALT+Key_Down,      VTKViewer_Viewer::Type() );
172
173   connect( mySelMgr, SIGNAL( selectionChanged() ), this, SLOT( onSelection() ) );
174 }
175
176 /*!Destructor.
177  *\li Save window geometry.
178  *\li Save desktop geometry.
179  *\li Save resource maneger.
180  *\li Delete selection manager.
181  */
182 LightApp_Application::~LightApp_Application()
183 {
184   saveWindowsGeometry();
185
186   if ( resourceMgr() )
187   {
188     if ( desktop() )
189       desktop()->saveGeometry( resourceMgr(), "desktop" );
190     resourceMgr()->save();
191   }
192   delete mySelMgr;
193 }
194
195 /*!Start application.*/
196 void LightApp_Application::start()
197 {
198   if ( desktop() )
199     desktop()->loadGeometry( resourceMgr(), "desktop" );
200
201   CAM_Application::start();
202
203   QAction* a = action( ViewWindowsId );
204   if ( a && a->inherits( "QtxDockAction" ) )
205     ((QtxDockAction*)a)->setAutoPlace( true );
206
207   updateWindows();
208   updateViewManagers();
209
210   putInfo( "" );
211   desktop()->statusBar()->message( "" );
212 }
213
214 /*!Gets application name.*/
215 QString LightApp_Application::applicationName() const
216 {
217   return tr( "APP_NAME" );
218 }
219
220 /*!Gets application version.*/
221 QString LightApp_Application::applicationVersion() const
222 {
223   static QString _app_version;
224
225   if ( _app_version.isEmpty() )
226   {
227     QString resVersion = tr( "APP_VERSION" );
228     if ( resVersion != "APP_VERSION" )
229     {
230       _app_version = resVersion;
231     }
232     else
233     {
234       QString path( ::getenv( "GUI_ROOT_DIR" ) );
235       if ( !path.isEmpty() )
236         path += QDir::separator();
237       path += QString( "bin/salome/VERSION" );
238
239       QFile vf( path );
240       if ( vf.open( IO_ReadOnly ) )
241       {
242         QString line;
243         vf.readLine( line, 1024 );
244         vf.close();
245
246         if ( !line.isEmpty() )
247         {
248           while ( !line.isEmpty() && line.at( line.length() - 1 ) == QChar( '\n' ) )
249             line.remove( line.length() - 1, 1 );
250
251           int idx = line.findRev( ":" );
252           if ( idx != -1 )
253             _app_version = line.mid( idx + 1 ).stripWhiteSpace();
254         }
255       }
256     }
257   }
258   return _app_version;  
259 }
260
261 /*!Load module by \a name.*/
262 CAM_Module* LightApp_Application::loadModule( const QString& name )
263 {
264   CAM_Module* mod = CAM_Application::loadModule( name );
265   if ( mod )
266   {
267     connect( this, SIGNAL( studyOpened() ), mod, SLOT( onModelOpened() ) );
268     connect( this, SIGNAL( studySaved() ),  mod, SLOT( onModelSaved() ) );
269     connect( this, SIGNAL( studyClosed() ), mod, SLOT( onModelClosed() ) );
270   }
271   return mod;
272 }
273
274 /*!Activate module by \a modName*/
275 bool LightApp_Application::activateModule( const QString& modName )
276 {
277   QString actName;
278   CAM_Module* prevMod = activeModule();
279
280   if ( prevMod )
281     actName = prevMod->moduleName();
282
283   if ( actName == modName )
284     return true;
285
286   putInfo( tr( "ACTIVATING_MODULE" ).arg( modName ) );  
287
288   saveWindowsGeometry();
289
290   bool status = CAM_Application::activateModule( modName );
291
292   updateModuleActions();
293
294   putInfo( "" );  
295
296   if ( !status )
297     return false;
298
299   updateWindows();
300   updateViewManagers();
301
302   return true;
303 }
304
305 bool LightApp_Application::useStudy(const QString& theName)
306 {
307   createEmptyStudy();
308   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>(activeStudy());
309   bool res = false;
310   if (aStudy)
311     res = aStudy->loadDocument( theName );
312   updateDesktopTitle();
313   updateCommandsStatus();
314   return res;
315 }
316
317 /*!Gets selection manager.*/
318 LightApp_SelectionMgr* LightApp_Application::selectionMgr() const
319 {
320   return mySelMgr;
321 }
322
323 /*!Create actions:*/
324 void LightApp_Application::createActions()
325 {
326   STD_Application::createActions();
327
328   SUIT_Desktop* desk = desktop();
329   SUIT_ResourceMgr* resMgr = resourceMgr();
330
331   //! Preferences
332   createAction( PreferencesId, tr( "TOT_DESK_PREFERENCES" ), QIconSet(),
333                 tr( "MEN_DESK_PREFERENCES" ), tr( "PRP_DESK_PREFERENCES" ),
334                 CTRL+Key_P, desk, false, this, SLOT( onPreferences() ) );
335
336   //! Help for modules
337   int helpMenu = createMenu( tr( "MEN_DESK_HELP" ), -1, -1, 1000 );
338   int helpModuleMenu = createMenu( tr( "MEN_DESK_MODULE_HELP" ), helpMenu, -1, 0 );
339   createMenu( separator(), helpMenu, -1, 1 );
340
341   QStringList aModuleList;
342   modules( aModuleList, false );
343
344   int id = LightApp_Application::UserID + FIRST_HELP_ID;
345   // help for KERNEL and GUI
346   QCString dir;
347   QAction* a;
348   if (dir = getenv("GUI_ROOT_DIR")) {
349     a = createAction( id, tr( QString("Kernel & GUI Help") ), QIconSet(),
350                       tr( QString("Kernel && GUI Help") ),
351                       tr( QString("Kernel & GUI Help") ),
352                       0, desk, false, this, SLOT( onHelpContentsModule() ) );
353     a->setName( QString("GUI") );
354     createMenu( a, helpModuleMenu, -1 );
355     id++;
356   }
357   // help for other existing modules
358   QStringList::Iterator it;
359   for ( it = aModuleList.begin(); it != aModuleList.end(); ++it )
360   {
361     if ( (*it).isEmpty() )
362       continue;
363
364     QString modName = moduleName( *it );
365     if ( modName.compare("GEOM") == 0 ) { // to be removed when documentation for other modules will be done
366       QAction* a = createAction( id, tr( moduleTitle(modName) + QString(" Help") ), QIconSet(),
367                                  tr( moduleTitle(modName) + QString(" Help") ),
368                                  tr( moduleTitle(modName) + QString(" Help") ),
369                                  0, desk, false, this, SLOT( onHelpContentsModule() ) );
370       a->setName( modName );
371       createMenu( a, helpModuleMenu, -1 );
372       id++;
373     }
374   }
375
376   //! MRU
377   QtxMRUAction* mru = new QtxMRUAction( tr( "TOT_DESK_MRU" ), tr( "MEN_DESK_MRU" ), desk );
378   connect( mru, SIGNAL( activated( QString ) ), this, SLOT( onMRUActivated( QString ) ) );
379   registerAction( MRUId, mru );
380
381   // default icon for neutral point ('SALOME' module)
382   QPixmap defIcon = resMgr->loadPixmap( "LightApp", tr( "APP_DEFAULT_ICO" ), false );
383   if ( defIcon.isNull() )
384     defIcon = QPixmap( imageEmptyIcon );
385
386   //! default icon for any module
387   QPixmap modIcon = resMgr->loadPixmap( "LightApp", tr( "APP_MODULE_ICO" ), false );
388   if ( modIcon.isNull() )
389     modIcon = QPixmap( imageEmptyIcon );
390
391   QToolBar* modTBar = new QtxToolBar( true, desk );
392   modTBar->setLabel( tr( "INF_TOOLBAR_MODULES" ) );
393
394   QActionGroup* modGroup = new QActionGroup( this );
395   modGroup->setExclusive( true );
396   modGroup->setUsesDropDown( true );
397
398   a = createAction( -1, tr( "APP_NAME" ), defIcon, tr( "APP_NAME" ),
399                     tr( "PRP_APP_MODULE" ), 0, desk, true );
400   modGroup->add( a );
401   myActions.insert( QString(), a );
402
403   QMap<QString, QString> iconMap;
404   moduleIconNames( iconMap );
405
406   const int iconSize = 20;
407
408   modGroup->addTo( modTBar );
409   modTBar->addSeparator();
410
411   QStringList modList;
412   modules( modList, false );
413
414   for ( it = modList.begin(); it != modList.end(); ++it )
415   {
416     if ( (*it).isEmpty() )
417       continue;
418
419     QString iconName;
420     if ( iconMap.contains( *it ) )
421       iconName = iconMap[*it];
422
423     QString modName = moduleName( *it );
424
425     QPixmap icon = resMgr->loadPixmap( modName, iconName, false );
426     if ( icon.isNull() )
427       icon = modIcon;
428
429     icon.convertFromImage( icon.convertToImage().smoothScale( iconSize, iconSize, QImage::ScaleMin ) );
430
431     QAction* a = createAction( -1, *it, icon, *it, tr( "PRP_MODULE" ).arg( *it ), 0, desk, true );
432     a->addTo( modTBar );
433     modGroup->add( a );
434
435     myActions.insert( *it, a );
436   }
437
438   SUIT_Tools::simplifySeparators( modTBar );
439
440   // New window
441   int windowMenu = createMenu( tr( "MEN_DESK_WINDOW" ), -1, 100 );
442   int newWinMenu = createMenu( tr( "MEN_DESK_NEWWINDOW" ), windowMenu, -1, 0 );
443   createMenu( separator(), windowMenu, -1, 1 );
444
445   QMap<int, int> accelMap;
446   accelMap[NewGLViewId]  = ALT+Key_G;
447   accelMap[NewPlot2dId]  = ALT+Key_P;
448   accelMap[NewOCCViewId] = ALT+Key_O;
449   accelMap[NewVTKViewId] = ALT+Key_K;
450
451   for ( id = NewGLViewId; id <= NewVTKViewId; id++ )
452   {
453     QAction* a = createAction( id, tr( QString( "NEW_WINDOW_%1" ).arg( id - NewGLViewId ) ), QIconSet(),
454                                tr( QString( "NEW_WINDOW_%1" ).arg( id - NewGLViewId ) ),
455                                tr( QString( "NEW_WINDOW_%1" ).arg( id - NewGLViewId ) ),
456                                accelMap.contains( id ) ? accelMap[id] : 0, desk, false, this, SLOT( onNewWindow() ) );
457     createMenu( a, newWinMenu, -1 );
458   }
459
460   STD_TabDesktop* tab_desk = dynamic_cast<STD_TabDesktop*>( desk );
461   if( tab_desk )
462   {
463     QAction* a = createAction( RenameId, tr( "TOT_RENAME" ), QIconSet(), tr( "MEN_RENAME" ), tr( "PRP_RENAME" ),
464                                0, desk, false, tab_desk->workstack(), SLOT( onRenameActive() ) );
465     createMenu( a, windowMenu, -1 );
466   }
467
468   connect( modGroup, SIGNAL( selected( QAction* ) ), this, SLOT( onModuleActivation( QAction* ) ) );
469
470   int fileMenu = createMenu( tr( "MEN_DESK_FILE" ), -1 );
471   createMenu( PreferencesId, fileMenu, 15, -1 );
472   createMenu( separator(), fileMenu, -1, 15, -1 );
473
474   /*
475   createMenu( separator(), fileMenu, -1, 100, -1 );
476   createMenu( MRUId, fileMenu, 100, -1 );
477   createMenu( separator(), fileMenu, -1, 100, -1 );
478   */
479 }
480
481 /*!On module activation action.*/
482 void LightApp_Application::onModuleActivation( QAction* a )
483 {
484   if ( !a )
485     return;
486
487   QString modName = a->menuText();
488   if ( modName == tr( "APP_NAME" ) )
489     modName = QString::null;
490
491   // Force user to create/open a study before module activation
492   QMap<QString, QString> iconMap;
493   moduleIconNames( iconMap );
494   QPixmap icon = resourceMgr()->loadPixmap( moduleName( modName ), iconMap[ modName ], false );
495   if ( icon.isNull() )
496     icon = resourceMgr()->loadPixmap( "LightApp", tr( "APP_MODULE_BIG_ICO" ), false ); // default icon for any module
497
498   bool cancelled = false;
499   while ( !modName.isEmpty() && !activeStudy() && !cancelled ){
500     LightApp_ModuleDlg aDlg( desktop(), modName, icon );
501     int res = aDlg.exec();
502
503     switch ( res ){
504     case 1:
505       onNewDoc();
506       break;
507     case 2:
508       onOpenDoc();
509       break;
510     case 3:
511       //onLoadStudy();
512       //break;
513     case 0:
514     default:
515       putInfo( tr("INF_CANCELLED") );
516       myActions[QString()]->setOn( true );
517       cancelled = true;
518     }
519   }
520
521   if ( !cancelled )
522     activateModule( modName );
523 }
524
525 /*!Default module activation.*/
526 QString LightApp_Application::defaultModule() const
527 {
528   QStringList aModuleNames;
529   modules( aModuleNames, false ); // obtain a complete list of module names for the current configuration
530   //! If there's the one and only module --> activate it automatically
531   //! TODO: Possible improvement - default module can be taken from preferences
532   return aModuleNames.count() > 1 ? "" : ( aModuleNames.count() ? aModuleNames.first() : "" );
533 }
534
535 /*!On new window slot.*/
536 void LightApp_Application::onNewWindow()
537 {
538   const QObject* obj = sender();
539   if ( !obj || !obj->inherits( "QAction" ) )
540     return;
541
542   QString type;
543   int id = actionId( (QAction*)obj );
544   switch ( id )
545   {
546   case NewGLViewId:
547     type = GLViewer_Viewer::Type();
548     break;
549   case NewPlot2dId:
550     type = Plot2d_Viewer::Type();
551     break;
552   case NewOCCViewId:
553     type = OCCViewer_Viewer::Type();
554     break;
555   case NewVTKViewId:
556     type = VTKViewer_Viewer::Type();
557     break;
558   }
559
560   if ( !type.isEmpty() )
561     createViewManager( type );
562 }
563
564 //=======================================================================
565 //  name    : onNewDoc
566 /*! Purpose : SLOT. Create new document*/
567 //=======================================================================
568 void LightApp_Application::onNewDoc()
569 {
570   SUIT_Study* study = activeStudy();
571
572   saveWindowsGeometry();
573
574   CAM_Application::onNewDoc();
575
576   if ( !study ) // new study will be create in THIS application
577   {
578     updateWindows();
579     updateViewManagers();
580   }
581 }
582
583 //=======================================================================
584 // name    : onOpenDoc
585 /*! Purpose : SLOT. Open new document*/
586 //=======================================================================
587 void LightApp_Application::onOpenDoc()
588 {
589   SUIT_Study* study = activeStudy();
590   saveWindowsGeometry();
591
592   CAM_Application::onOpenDoc();
593
594   if ( !study ) // new study will be create in THIS application
595   {
596     updateWindows();
597     updateViewManagers();
598   }
599 }
600
601 #include "SUIT_MessageBox.h"
602 /*! Purpose : SLOT. Open new document with \a aName.*/
603 bool LightApp_Application::onOpenDoc( const QString& aName )
604 {
605   bool isAlreadyOpen = false;
606
607   // Look among opened studies
608   if (activeStudy()) { // at least one study is opened
609     SUIT_Session* aSession = SUIT_Session::session();
610     QPtrList<SUIT_Application> aAppList = aSession->applications();
611     QPtrListIterator<SUIT_Application> it (aAppList);
612     SUIT_Application* aApp = 0;
613     // iterate on all applications
614     for (; (aApp = it.current()) && !isAlreadyOpen; ++it) {
615       if (aApp->activeStudy()->studyName() == aName) {
616         isAlreadyOpen = true; // Already opened, ask user what to do
617
618         // The document ... is already open.
619         // Do you want to reload it?
620         int aAnswer = SUIT_MessageBox::warn2(desktop(), tr("WRN_WARNING"),
621                                              tr("QUE_DOC_ALREADYOPEN").arg(aName),
622                                              tr("BUT_YES"), tr("BUT_NO"), 1, 2, 2);
623         if (aAnswer == 1) { // reload
624           if (activeStudy()->studyName() == aName && aAppList.count() > 1) {
625             // Opened in THIS (active) application.
626             STD_Application* app1 = (STD_Application*)aAppList.at(0);
627             STD_Application* app2 = (STD_Application*)aAppList.at(1);
628             if (!app1 || !app2) {
629               // Error
630               return false;
631             }
632             if (app1->activeStudy()->studyName() == aName) {
633               // app1 is this application, we need another one
634               app1 = app2;
635             }
636             // Close document of this application. This application will be destroyed.
637             onCloseDoc(/*ask = */false);
638             // Open the file with another application, as this one will be destroyed.
639             return app1->onOpenDoc(aName);
640           } else {
641             // Opened in another application.
642             STD_Application* app = (STD_Application*)aApp;
643             if (app)
644               app->onCloseDoc(/*ask = */false);
645           }
646         } else { // do not reload
647           // OK, the study will not be reloaded, but we call
648           // CAM_Application::onOpenDoc( aName ) all the same.
649           // It will activate a desktop of the study <aName>.
650         }
651       }
652     }
653   }
654
655   bool res = CAM_Application::onOpenDoc( aName );
656
657   QAction* a = action( MRUId );
658   if ( a && a->inherits( "QtxMRUAction" ) )
659   {
660     QtxMRUAction* mru = (QtxMRUAction*)a;
661     if ( res )
662       mru->insert( aName );
663     else
664       mru->remove( aName );
665   }
666   return res;
667 }
668
669 //=======================================================================
670 // name    : onHelpAbout
671 /*! Purpose : SLOT. Display "About" message box*/
672 //=======================================================================
673 void LightApp_Application::onHelpAbout()
674 {
675   LightApp_AboutDlg* dlg = new LightApp_AboutDlg( applicationName(), applicationVersion(), desktop() );
676   dlg->exec();
677   delete dlg;
678 }
679
680 /*!SLOT. Load document with \a aName.*/
681 bool LightApp_Application::onLoadDoc( const QString& aName )
682 {
683   bool res = CAM_Application::onLoadDoc( aName );
684
685   /*jfa tmp:QAction* a = action( MRUId );
686   if ( a && a->inherits( "QtxMRUAction" ) )
687   {
688     QtxMRUAction* mru = (QtxMRUAction*)a;
689     if ( res )
690       mru->insert( aName );
691     else
692       mru->remove( aName );
693   }*/
694   return res;
695 }
696
697 /*!Private SLOT. Selection.*/
698 void LightApp_Application::onSelection()
699 {
700   onSelectionChanged();
701
702   if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) )
703     ((LightApp_Module*)activeModule())->selectionChanged();
704 }
705
706 /*!Set active study.
707  *\param study - SUIT_Study.
708  */
709 void LightApp_Application::setActiveStudy( SUIT_Study* study )
710 {
711   CAM_Application::setActiveStudy( study );
712
713   activateWindows();
714 }
715
716 //=======================================================================
717 // name    : updateCommandsStatus
718 /*! Purpose : Enable/Disable menu items and toolbar buttons. Rebuild menu*/
719 //=======================================================================
720 void LightApp_Application::updateCommandsStatus()
721 {
722   CAM_Application::updateCommandsStatus();
723
724   for ( int id = NewGLViewId; id <= NewVTKViewId; id++ )
725   {
726     QAction* a = action( id );
727     if ( a )
728       a->setEnabled( activeStudy() );
729   }
730 }
731
732 // Helps to execute command
733 class RunBrowser: public QThread {
734 public:
735
736   RunBrowser(QString theApp, QString theParams, QString theHelpFile, QString theContext=NULL):
737     myApp(theApp), myParams(theParams), myHelpFile("file:" + theHelpFile + theContext), myStatus(0) {};
738
739   virtual void run()
740   {
741     QString aCommand;
742
743     if ( !myApp.isEmpty())
744       {
745         aCommand.sprintf("%s %s %s",myApp.latin1(),myParams.latin1(),myHelpFile.latin1());
746         myStatus = system(aCommand);
747         if(myStatus != 0)
748           {
749             QCustomEvent* ce2000 = new QCustomEvent (2000);
750             postEvent (qApp, ce2000);
751           }
752       }
753
754     if( myStatus != 0 || myApp.isEmpty())
755       {
756         myParams = "";
757         aCommand.sprintf("%s %s %s", QString(DEFAULT_BROWSER).latin1(),myParams.latin1(), myHelpFile.latin1());
758         myStatus = system(aCommand);
759         if(myStatus != 0)
760           {
761             QCustomEvent* ce2001 = new QCustomEvent (2001);
762             postEvent (qApp, ce2001);
763           }
764       }
765   }
766
767 private:
768   QString myApp;
769   QString myParams;
770   QString myHelpFile;
771   int myStatus;
772
773 };
774
775 //=======================================================================
776 // name    : onHelpContentsModule
777 /*! Purpose : SLOT. Display help contents for choosen module*/
778 //=======================================================================
779 void LightApp_Application::onHelpContentsModule()
780 {
781   const QAction* obj = (QAction*) sender();
782
783   QString aComponentName = obj->name();
784   QString aFileName = aComponentName + "_index.html";
785
786   QCString dir;
787   QString root;
788   QString homeDir;
789   if (dir = getenv( aComponentName + "_ROOT_DIR")) {
790     root = Qtx::addSlash( Qtx::addSlash(dir) +  Qtx::addSlash("doc") +  Qtx::addSlash("salome") );
791     if ( QFileInfo( root + aFileName ).exists() ) {
792       homeDir = root;
793     } else {
794       SUIT_MessageBox::warn1( desktop(), tr("WRN_WARNING"),
795                               QString( "%1"+ aFileName + " doesn't exist." ).arg(root), tr ("BUT_OK") );
796       return;
797     }
798   }
799
800   QString helpFile = QFileInfo( homeDir + aFileName ).absFilePath();
801   SUIT_ResourceMgr* resMgr = resourceMgr();
802   QString anApp = resMgr->stringValue("ExternalBrowser", "application");
803   QString aParams = resMgr->stringValue("ExternalBrowser", "parameters");
804
805   RunBrowser* rs = new RunBrowser(anApp, aParams, helpFile);
806   rs->start();
807 }
808
809 /*!Sets enable or disable some actions on selection changed.*/
810 void LightApp_Application::onSelectionChanged()
811 {
812 }
813
814 /*!Return window.
815  *\param flag - key for window
816  *\param studyId - study id
817  * Flag used how identificator of window in windows list.
818  */
819 QWidget* LightApp_Application::window( const int flag, const int studyId ) const
820 {
821   QWidget* wid = 0;
822
823  int sId = studyId;
824   if ( sId < 0 )
825   {
826     if ( !activeStudy() )
827       return 0;
828     else
829       sId = activeStudy()->id();
830   }
831
832   if ( myWindows.contains( flag ) )
833     wid = myWindows[flag]->widget( sId );
834
835   return wid;
836 }
837
838 /*!Adds window to application.
839  *\param wid - QWidget
840  *\param flag - key wor window
841  *\param studyId - study id
842  * Flag used how identificator of window in windows list.
843  */
844 void LightApp_Application::addWindow( QWidget* wid, const int flag, const int studyId )
845 {
846   if ( !wid )
847     return;
848
849   int sId = studyId;
850   if ( sId < 0 )
851   {
852     if ( !activeStudy() )
853       return;
854     else
855       sId = activeStudy()->id();
856   }
857
858   if ( !myWindows.contains( flag ) )
859   {
860     QMap<int, int> winMap;
861     currentWindows( winMap );
862
863     LightApp_WidgetContainer* newWC = new LightApp_WidgetContainer( flag, desktop() );
864     connect( newWC, SIGNAL(  destroyed ( QObject* ) ), this, SLOT( onWCDestroyed( QObject* ) ) );
865     myWindows.insert( flag, newWC );
866     if ( winMap.contains( flag ) )
867       desktop()->moveDockWindow( myWindows[flag], (Dock)winMap[flag] );
868
869     myWindows[flag]->setResizeEnabled( true );
870     myWindows[flag]->setCloseMode( QDockWindow::Always );
871     myWindows[flag]->setName( QString( "dock_window_%1" ).arg( flag ) );
872   }
873
874   QFont f;
875   if( wid->inherits( "PythonConsole" ) )
876     f = ( ( PythonConsole* )wid )->font();
877   else
878     f = wid->font();
879
880   myWindows[flag]->insert( sId, wid );
881   wid->setFont(f);
882
883   setWindowShown( flag, !myWindows[flag]->isEmpty() );
884 }
885
886 /*!Remove window from application.
887  *\param flag - key wor window
888  *\param studyId - study id
889  * Flag used how identificator of window in windows list.
890  */
891 void LightApp_Application::removeWindow( const int flag, const int studyId )
892 {
893   if ( !myWindows.contains( flag ) )
894     return;
895
896   int sId = studyId;
897   if ( sId < 0 )
898   {
899     if ( !activeStudy() )
900       return;
901     else
902       sId = activeStudy()->id();
903   }
904
905   QWidget* wid = myWindows[flag]->widget( sId );
906   myWindows[flag]->remove( sId );
907   delete wid;
908
909   setWindowShown( flag, !myWindows[flag]->isEmpty() );
910 }
911
912 /*!Gets window.
913  *\param flag - key wor window
914  *\param studyId - study id
915  * Flag used how identificator of window in windows list.
916  */
917 QWidget* LightApp_Application::getWindow( const int flag, const int studyId )
918 {
919   QWidget* wid = window( flag, studyId );
920   if ( !wid )
921     addWindow( wid = createWindow( flag ), flag, studyId );
922
923   return wid;
924 }
925
926 /*!Check is window visible?(with identificator \a type)*/
927 bool LightApp_Application::isWindowVisible( const int type ) const
928 {
929   bool res = false;
930   if ( myWindows.contains( type ) )
931   {
932     SUIT_Desktop* desk = ((LightApp_Application*)this)->desktop();
933     res = desk && desk->appropriate( myWindows[type] );
934   }
935   return res;
936 }
937
938 /*!Sets window show or hide.
939  *\param type - window identificator.
940  *\param on   - true/false (window show/hide)
941  */
942 void LightApp_Application::setWindowShown( const int type, const bool on )
943 {
944   if ( !desktop() || !myWindows.contains( type ) )
945     return;
946
947   QDockWindow* dw = myWindows[type];
948   desktop()->setAppropriate( dw, on );
949   on ? dw->show() : dw->hide();
950 }
951
952 /*!Gets "ObjectBrowser".*/
953 OB_Browser* LightApp_Application::objectBrowser()
954 {
955   OB_Browser* ob = 0;
956   QWidget* wid = getWindow( WT_ObjectBrowser );
957   if ( wid->inherits( "OB_Browser" ) )
958     ob = (OB_Browser*)wid;
959   return ob;
960 }
961
962 /*!Gets "LogWindow".*/
963 LogWindow* LightApp_Application::logWindow()
964 {
965   LogWindow* lw = 0;
966   QWidget* wid = getWindow( WT_LogWindow );
967   if ( wid->inherits( "LogWindow" ) )
968     lw = (LogWindow*)wid;
969   return lw;
970 }
971
972 /*!Get "PythonConsole"*/
973 PythonConsole* LightApp_Application::pythonConsole()
974 {
975   PythonConsole* console = 0;
976   QWidget* wid = getWindow( WT_PyConsole );
977   if ( wid->inherits( "PythonConsole" ) )
978     console = (PythonConsole*)wid;
979   return console;
980 }
981
982 /*!Update obect browser*/
983 void LightApp_Application::updateObjectBrowser( const bool updateModels )
984 {
985   // update existing data models
986   if ( updateModels ) 
987   {
988     LightApp_Study* study = dynamic_cast<LightApp_Study*>(activeStudy());
989     if ( study ) {
990       CAM_Study::ModelList dm_list;
991       study->dataModels( dm_list );
992       for ( CAM_Study::ModelListIterator it( dm_list ); it.current(); ++it ) {
993         CAM_DataModel* camDM = it.current();
994         if ( camDM && camDM->inherits( "LightApp_DataModel" ) )
995           ((LightApp_DataModel*)camDM)->update();
996       }
997     }
998   }
999   if ( objectBrowser() )
1000   {
1001     objectBrowser()->updateGeometry();
1002     objectBrowser()->updateTree();
1003   }
1004 }
1005
1006 /*!Gets preferences.*/
1007 LightApp_Preferences* LightApp_Application::preferences() const
1008 {
1009   return preferences( false );
1010 }
1011
1012 /*!Gets view manager*/
1013 SUIT_ViewManager* LightApp_Application::getViewManager( const QString& vmType, const bool create )
1014 {
1015   SUIT_ViewManager* aVM = viewManager( vmType );
1016   SUIT_ViewManager* anActiveVM = CAM_Application::activeViewManager();
1017
1018   if ( anActiveVM && anActiveVM->getType() == vmType )
1019     aVM = anActiveVM;
1020
1021   if ( aVM && create )
1022   {
1023     if ( !aVM->getActiveView() )
1024       aVM->createView();
1025     else
1026       aVM->getActiveView()->setFocus();
1027   }
1028   else if ( create )
1029     aVM = createViewManager( vmType );
1030
1031   return aVM;
1032 }
1033
1034 /*!Create view manager.*/
1035 SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType )
1036 {
1037   SUIT_ResourceMgr* resMgr = resourceMgr();
1038
1039   SUIT_ViewManager* viewMgr = 0;
1040   if( vmType == GLViewer_Viewer::Type() )
1041   {
1042     viewMgr = new GLViewer_ViewManager( activeStudy(), desktop() );
1043     new LightApp_GLSelector( (GLViewer_Viewer2d*)viewMgr->getViewModel(), mySelMgr );
1044   }
1045   else if( vmType == Plot2d_Viewer::Type() )
1046   {
1047     viewMgr = new Plot2d_ViewManager( activeStudy(), desktop() );
1048     SPlot2d_Viewer* vm = new SPlot2d_Viewer();
1049     viewMgr->setViewModel( vm  );// custom view model, which extends SALOME_View interface 
1050     Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( viewMgr->getActiveView() );
1051     if( wnd )
1052     {
1053       Plot2d_ViewFrame* frame = wnd->getViewFrame();
1054       frame->setBackgroundColor( resMgr->colorValue( "Plot2d", "Background", frame->backgroundColor() ) );
1055     }
1056   }
1057   else if( vmType == SUPERVGraph_Viewer::Type() )
1058   {
1059     viewMgr = new SUPERVGraph_ViewManager( activeStudy(), desktop() );
1060     SUPERVGraph_Viewer* vm = new SUPERVGraph_Viewer();
1061     SUPERVGraph_ViewFrame* view = dynamic_cast<SUPERVGraph_ViewFrame*>( vm->getViewManager()->getActiveView() );
1062     if( view )
1063       view->setBackgroundColor( resMgr->colorValue( "SUPERVGraph", "Background", view->backgroundColor() ) );
1064   }
1065   else if( vmType == OCCViewer_Viewer::Type() )
1066   {
1067     viewMgr = new OCCViewer_ViewManager( activeStudy(), desktop() );
1068     SOCC_Viewer* vm = new SOCC_Viewer();
1069     vm->setBackgroundColor( resMgr->colorValue( "OCCViewer", "background", vm->backgroundColor() ) );
1070     vm->setTrihedronSize( resMgr->integerValue( "OCCViewer", "trihedron_size", vm->trihedronSize() ) );
1071     int u( 1 ), v( 1 );
1072     vm->isos( u, v );
1073     u = resMgr->integerValue( "OCCViewer", "iso_number_u", u );
1074     v = resMgr->integerValue( "OCCViewer", "iso_number_v", v );
1075     vm->setIsos( u, v );
1076     viewMgr->setViewModel( vm );// custom view model, which extends SALOME_View interface
1077     new LightApp_OCCSelector( (OCCViewer_Viewer*)viewMgr->getViewModel(), mySelMgr );
1078   }
1079   else if ( vmType == SVTK_Viewer::Type() )
1080   {
1081     viewMgr = new SVTK_ViewManager( activeStudy(), desktop() );
1082     SVTK_Viewer* vm = dynamic_cast<SVTK_Viewer*>( viewMgr->getViewModel() );
1083     if( vm )
1084     {
1085       vm->setBackgroundColor( resMgr->colorValue( "VTKViewer", "background", vm->backgroundColor() ) );
1086       vm->setTrihedronSize( resMgr->integerValue( "VTKViewer", "trihedron_size", vm->trihedronSize() ) );
1087       new LightApp_VTKSelector( vm, mySelMgr );
1088     }
1089   }
1090
1091   if ( !viewMgr )
1092     return 0;
1093
1094   addViewManager( viewMgr );
1095   SUIT_ViewWindow* viewWin = viewMgr->createViewWindow();
1096
1097   if ( viewWin && desktop() )
1098     viewWin->resize( (int)( desktop()->width() * 0.6 ), (int)( desktop()->height() * 0.6 ) );
1099
1100   connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
1101            this, SLOT( onCloseView( SUIT_ViewManager* ) ) );
1102
1103   return viewMgr;
1104 }
1105
1106 //=======================================================================
1107 // name    : onCloseView
1108 /*! Purpose : SLOT. Remove view manager from application*/
1109 //=======================================================================
1110 void LightApp_Application::onCloseView( SUIT_ViewManager* theVM )
1111 {
1112   removeViewManager( theVM );
1113 }
1114
1115 /*!Protected SLOT. On study created.*/
1116 void LightApp_Application::onStudyCreated( SUIT_Study* theStudy )
1117 {
1118   SUIT_DataObject* aRoot = 0;
1119   if ( theStudy && theStudy->root() )
1120   {
1121     aRoot = theStudy->root();
1122     //aRoot->setName( tr( "DATA_MODELS" ) );
1123   }
1124   if ( objectBrowser() != 0 )
1125     objectBrowser()->setRootObject( aRoot );
1126
1127   activateModule( defaultModule() );
1128
1129   activateWindows();
1130 }
1131
1132 /*!Protected SLOT. On study opened.*/
1133 void LightApp_Application::onStudyOpened( SUIT_Study* theStudy )
1134 {
1135   SUIT_DataObject* aRoot = 0;
1136   if ( theStudy && theStudy->root() )
1137   {
1138     aRoot = theStudy->root();
1139     //aRoot->dump();
1140   }
1141   if ( objectBrowser() != 0 ) {
1142     objectBrowser()->setRootObject( aRoot );
1143   }
1144
1145   activateModule( defaultModule() );
1146
1147   activateWindows();
1148
1149   emit studyOpened();
1150 }
1151
1152 /*!Protected SLOT. On study saved.*/
1153 void LightApp_Application::onStudySaved( SUIT_Study* )
1154 {
1155   emit studySaved();
1156 }
1157
1158 /*!Protected SLOT. On study closed.*/
1159 void LightApp_Application::onStudyClosed( SUIT_Study* )
1160 {
1161   emit studyClosed();
1162
1163   // Bug 10396: clear selection
1164   mySelMgr->clearSelected();
1165
1166   activateModule( "" );
1167
1168   saveWindowsGeometry();
1169 }
1170
1171 /*!Protected SLOT.On desktop activated.*/
1172 void LightApp_Application::onDesktopActivated()
1173 {
1174   CAM_Application::onDesktopActivated();
1175   LightApp_Module* aModule = dynamic_cast<LightApp_Module*>(activeModule());
1176   if(aModule)
1177     aModule->studyActivated();
1178 }
1179
1180 /*!Gets file filter.
1181  *\retval QString "(*.bin)"
1182  */
1183 QString LightApp_Application::getFileFilter() const
1184 {
1185   return "(*.bin)";
1186 }
1187
1188 /*! Gets file name*/
1189 QString LightApp_Application::getFileName( bool open, const QString& initial, const QString& filters, 
1190                                            const QString& caption, QWidget* parent )
1191 {
1192   if ( !parent )
1193     parent = desktop();
1194   QStringList fls = QStringList::split( ";;", filters, false );
1195   return SUIT_FileDlg::getFileName( parent, initial, fls, caption, open, true );
1196 }
1197
1198 /*! Gets directory*/
1199 QString LightApp_Application::getDirectory( const QString& initial, const QString& caption, QWidget* parent )
1200 {
1201   if ( !parent )
1202     parent = desktop();
1203   return SUIT_FileDlg::getExistingDirectory( parent, initial, caption, true );
1204 }
1205
1206 /*! Get open file names*/
1207 QStringList LightApp_Application::getOpenFileNames( const QString& initial, const QString& filters, 
1208                                                     const QString& caption, QWidget* parent )
1209 {
1210   if ( !parent )
1211     parent = desktop();
1212   QStringList fls = QStringList::split( ";;", filters, false );
1213   return SUIT_FileDlg::getOpenFileNames( parent, initial, fls, caption, true );
1214 }
1215
1216 /*!Private SLOT. Update object browser.*/
1217 void LightApp_Application::onRefresh()
1218 {
1219   updateObjectBrowser( true );
1220 }
1221
1222 /*!Private SLOT. On preferences.*/
1223 void LightApp_Application::onPreferences()
1224 {
1225   QApplication::setOverrideCursor( Qt::waitCursor );
1226
1227   LightApp_PreferencesDlg* prefDlg = new LightApp_PreferencesDlg( preferences( true ), desktop());
1228
1229   QApplication::restoreOverrideCursor();
1230
1231   if ( !prefDlg )
1232     return;
1233
1234   prefDlg->exec();
1235
1236   delete prefDlg;
1237 }
1238
1239 /*!Protected SLOT. On preferences changed.*/
1240 void LightApp_Application::onPreferenceChanged( QString& modName, QString& section, QString& param )
1241 {
1242   LightApp_Module* sMod = 0;
1243   CAM_Module* mod = module( modName );
1244   if ( mod && mod->inherits( "LightApp_Module" ) )
1245     sMod = (LightApp_Module*)mod;
1246
1247   if ( sMod )
1248     sMod->preferencesChanged( section, param );
1249   else
1250     preferencesChanged( section, param );
1251 }
1252
1253 /*!Private SLOT. On open document with name \a aName.*/
1254 void LightApp_Application::onMRUActivated( QString aName )
1255 {
1256   onOpenDoc( aName );
1257 }
1258
1259 /*!Remove all windows from study.*/
1260 void LightApp_Application::beforeCloseDoc( SUIT_Study* s )
1261 {
1262   CAM_Application::beforeCloseDoc( s );
1263
1264   for ( WindowMap::ConstIterator itr = myWindows.begin(); s && itr != myWindows.end(); ++itr )
1265     removeWindow( itr.key(), s->id() );
1266 }
1267
1268 /*!Update actions.*/
1269 void LightApp_Application::updateActions()
1270 {
1271   updateCommandsStatus();
1272 }
1273
1274 //=======================================================================
1275 // name    : createNewStudy
1276 /*! Purpose : Create new study*/
1277 //=======================================================================
1278 SUIT_Study* LightApp_Application::createNewStudy()
1279 {
1280   LightApp_Study* aStudy = new LightApp_Study( this );
1281
1282   // Set up processing of major study-related events
1283   connect( aStudy, SIGNAL( created( SUIT_Study* ) ), this, SLOT( onStudyCreated( SUIT_Study* ) ) );
1284   connect( aStudy, SIGNAL( opened ( SUIT_Study* ) ), this, SLOT( onStudyOpened ( SUIT_Study* ) ) );
1285   connect( aStudy, SIGNAL( saved  ( SUIT_Study* ) ), this, SLOT( onStudySaved  ( SUIT_Study* ) ) );
1286   connect( aStudy, SIGNAL( closed ( SUIT_Study* ) ), this, SLOT( onStudyClosed ( SUIT_Study* ) ) );
1287
1288   return aStudy;
1289 }
1290
1291 /*!Create window.*/
1292 QWidget* LightApp_Application::createWindow( const int flag )
1293 {
1294   QWidget* wid = 0;
1295   if ( flag == WT_ObjectBrowser )
1296   {
1297     OB_Browser* ob = new OB_Browser( desktop() );
1298     ob->setAutoUpdate( true );
1299     ob->setAutoOpenLevel( 1 );
1300     ob->setCaption( tr( "OBJECT_BROWSER" ) );
1301     ob->listView()->setColumnWidth( 0, OBJECT_COLUMN_WIDTH );
1302     ob->resize( OBJECT_BROWSER_WIDTH, ob->height() );
1303     ob->setFilter( new LightApp_OBFilter( selectionMgr() ) );
1304
1305     ob->setNameTitle( tr( "OBJ_BROWSER_NAME" ) );
1306
1307     // Create OBSelector
1308     new LightApp_OBSelector( ob, mySelMgr );
1309
1310     wid = ob;
1311
1312     ob->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
1313   }
1314   else  if ( flag == WT_PyConsole )
1315   {
1316     PythonConsole* pyCons = new PythonConsole( desktop() );
1317     pyCons->setCaption( tr( "PYTHON_CONSOLE" ) );
1318     wid = pyCons;
1319     //    pyCons->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
1320   }
1321   else if ( flag == WT_LogWindow )
1322   {
1323     LogWindow* logWin = new LogWindow( desktop() );
1324     logWin->setCaption( tr( "LOG_WINDOW" ) );
1325     wid = logWin;
1326     logWin->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
1327   }
1328   return wid;
1329 }
1330
1331 /*!Default windows(Object Browser, Python Console).
1332  * Adds to map \a aMap.
1333  */
1334 void LightApp_Application::defaultWindows( QMap<int, int>& aMap ) const
1335 {  
1336   aMap.insert( WT_ObjectBrowser, Qt::DockLeft );
1337   aMap.insert( WT_PyConsole, Qt::DockBottom );
1338   //  aMap.insert( WT_LogWindow, Qt::DockBottom );
1339 }
1340
1341 /*!Default view manager.*/
1342 void LightApp_Application::defaultViewManagers( QStringList& ) const
1343 {
1344   /*!Do nothing.*/
1345 }
1346
1347 /*!Gets preferences.
1348  * Create preferences, if \a crt = true.
1349  */
1350 LightApp_Preferences* LightApp_Application::preferences( const bool crt ) const
1351 {
1352   if ( myPrefs )
1353     return myPrefs;
1354
1355   LightApp_Application* that = (LightApp_Application*)this;
1356
1357   if ( !_prefs_ && crt )
1358   {
1359     _prefs_ = new LightApp_Preferences( resourceMgr() );
1360     that->createPreferences( _prefs_ );
1361   }
1362
1363   that->myPrefs = _prefs_;
1364
1365   QPtrList<SUIT_Application> appList = SUIT_Session::session()->applications();
1366   for ( QPtrListIterator<SUIT_Application> appIt ( appList ); appIt.current(); ++appIt )
1367   {
1368     if ( !appIt.current()->inherits( "LightApp_Application" ) )
1369       continue;
1370
1371     LightApp_Application* app = (LightApp_Application*)appIt.current();
1372
1373     QStringList modNameList;
1374     app->modules( modNameList, false );
1375     for ( QStringList::const_iterator it = modNameList.begin(); it != modNameList.end(); ++it )
1376     {
1377       int id = _prefs_->addPreference( *it );
1378       _prefs_->setItemProperty( id, "info", tr( "PREFERENCES_NOT_LOADED" ).arg( *it ) );
1379     }
1380
1381     ModuleList modList;
1382     app->modules( modList );
1383     for ( ModuleListIterator itr( modList ); itr.current(); ++itr )
1384     {
1385       LightApp_Module* mod = 0;
1386       if ( itr.current()->inherits( "LightApp_Module" ) )
1387         mod = (LightApp_Module*)itr.current();
1388
1389       if ( mod && !_prefs_->hasModule( mod->moduleName() ) )
1390       {
1391         int modCat = _prefs_->addPreference( mod->moduleName() );
1392         _prefs_->setItemProperty( modCat, "info", QString::null );
1393         mod->createPreferences();
1394       }
1395     }
1396   }
1397
1398   connect( myPrefs, SIGNAL( preferenceChanged( QString&, QString&, QString& ) ),
1399            this, SLOT( onPreferenceChanged( QString&, QString&, QString& ) ) );
1400
1401   return myPrefs;
1402 }
1403
1404 /*!Add new module to application.*/
1405 void LightApp_Application::moduleAdded( CAM_Module* mod )
1406 {
1407   CAM_Application::moduleAdded( mod );
1408
1409   LightApp_Module* lightMod = 0;
1410   if ( mod && mod->inherits( "LightApp_Module" ) )
1411     lightMod = (LightApp_Module*)mod;
1412
1413   if ( myPrefs && lightMod && !myPrefs->hasModule( lightMod->moduleName() ))
1414   {
1415     int modCat = myPrefs->addPreference( mod->moduleName() );
1416     myPrefs->setItemProperty( modCat, "info", QString::null );
1417     lightMod->createPreferences();
1418   }
1419 }
1420
1421 /*!Create preferences.*/
1422 void LightApp_Application::createPreferences( LightApp_Preferences* pref )
1423 {
1424   if ( !pref )
1425     return;
1426
1427   int salomeCat = pref->addPreference( tr( "PREF_CATEGORY_SALOME" ) );
1428
1429   int genTab = pref->addPreference( tr( "PREF_TAB_GENERAL" ), salomeCat );
1430   int studyGroup = pref->addPreference( tr( "PREF_GROUP_STUDY" ), genTab );
1431   pref->setItemProperty( studyGroup, "columns", 1 );
1432
1433   pref->addPreference( tr( "PREF_MULTI_FILE" ), studyGroup, LightApp_Preferences::Bool, "Study", "multi_file" );
1434   pref->addPreference( tr( "PREF_ASCII_FILE" ), studyGroup, LightApp_Preferences::Bool, "Study", "ascii_file" );
1435   int undoPref = pref->addPreference( tr( "PREF_UNDO_LEVEL" ), studyGroup, LightApp_Preferences::IntSpin, "Study", "undo_level" );
1436   pref->setItemProperty( undoPref, "min", 1 );
1437   pref->setItemProperty( undoPref, "max", 100 );
1438
1439   int extgroup = pref->addPreference( tr( "PREF_GROUP_EXT_BROWSER" ), genTab );
1440   pref->setItemProperty( extgroup, "columns", 1 );
1441   int apppref = pref->addPreference( tr( "PREF_APP" ), extgroup, LightApp_Preferences::File, "ExternalBrowser", "application" );
1442   pref->setItemProperty( apppref, "existing", true );
1443   pref->setItemProperty( apppref, "flags", QFileInfo::ExeUser );
1444
1445   pref->addPreference( tr( "PREF_PARAM" ), extgroup, LightApp_Preferences::String, "ExternalBrowser", "parameters" );
1446
1447   int pythonConsoleGroup = pref->addPreference( tr( "PREF_GROUP_PY_CONSOLE" ), genTab );
1448   pref->setItemProperty( pythonConsoleGroup, "columns", 1 );
1449   pref->addPreference( tr( "PREF_FONT" ), pythonConsoleGroup, LightApp_Preferences::Font, "PyConsole", "font" );
1450
1451   int viewTab = pref->addPreference( tr( "PREF_TAB_VIEWERS" ), salomeCat );
1452
1453   int occGroup = pref->addPreference( tr( "PREF_GROUP_OCCVIEWER" ), viewTab );
1454
1455   int vtkGroup = pref->addPreference( tr( "PREF_GROUP_VTKVIEWER" ), viewTab );
1456
1457   int plot2dGroup = pref->addPreference( tr( "PREF_GROUP_PLOT2DVIEWER" ), viewTab );
1458
1459   int supervGroup = pref->addPreference( tr( "PREF_GROUP_SUPERV" ), viewTab );
1460
1461   pref->setItemProperty( occGroup, "columns", 1 );
1462   pref->setItemProperty( vtkGroup, "columns", 1 );
1463   pref->setItemProperty( plot2dGroup, "columns", 1 );
1464
1465   int occTS = pref->addPreference( tr( "PREF_TRIHEDRON_SIZE" ), occGroup,
1466                                    LightApp_Preferences::IntSpin, "OCCViewer", "trihedron_size" );
1467   pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), occGroup,
1468                        LightApp_Preferences::Color, "OCCViewer", "background" );
1469
1470   pref->setItemProperty( occTS, "min", 1 );
1471   pref->setItemProperty( occTS, "max", 150 );
1472
1473   int isoU = pref->addPreference( tr( "PREF_ISOS_U" ), occGroup,
1474                                   LightApp_Preferences::IntSpin, "OCCViewer", "iso_number_u" );
1475   int isoV = pref->addPreference( tr( "PREF_ISOS_V" ), occGroup,
1476                                   LightApp_Preferences::IntSpin, "OCCViewer", "iso_number_v" );
1477
1478   pref->setItemProperty( isoU, "min", 0 );
1479   pref->setItemProperty( isoU, "max", 100000 );
1480
1481   pref->setItemProperty( isoV, "min", 0 );
1482   pref->setItemProperty( isoV, "max", 100000 );
1483
1484   int vtkTS = pref->addPreference( tr( "PREF_TRIHEDRON_SIZE" ), vtkGroup,
1485                                    LightApp_Preferences::IntSpin, "VTKViewer", "trihedron_size" );
1486   pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), vtkGroup,
1487                        LightApp_Preferences::Color, "VTKViewer", "background" );
1488
1489   pref->setItemProperty( vtkTS, "min", 1 );
1490   pref->setItemProperty( vtkTS, "max", 150 );
1491
1492   pref->addPreference( tr( "PREF_SHOW_LEGEND" ), plot2dGroup,
1493                        LightApp_Preferences::Bool, "Plot2d", "ShowLegend" );
1494
1495   int legendPosition = pref->addPreference( tr( "PREF_LEGEND_POSITION" ), plot2dGroup,
1496                                             LightApp_Preferences::Selector, "Plot2d", "LegendPos" );
1497   QStringList aLegendPosList;
1498   aLegendPosList.append( tr("PREF_LEFT") );
1499   aLegendPosList.append( tr("PREF_RIGHT") );
1500   aLegendPosList.append( tr("PREF_TOP") );
1501   aLegendPosList.append( tr("PREF_BOTTOM") );
1502
1503   QValueList<QVariant> anIndexesList;
1504   anIndexesList.append(0);
1505   anIndexesList.append(1);
1506   anIndexesList.append(2);
1507   anIndexesList.append(3);
1508
1509   pref->setItemProperty( legendPosition, "strings", aLegendPosList );
1510   pref->setItemProperty( legendPosition, "indexes", anIndexesList );
1511
1512   int curveType = pref->addPreference( tr( "PREF_CURVE_TYPE" ), plot2dGroup,
1513                                        LightApp_Preferences::Selector, "Plot2d", "CurveType" );
1514   QStringList aCurveTypesList;
1515   aCurveTypesList.append( tr("PREF_POINTS") );
1516   aCurveTypesList.append( tr("PREF_LINES") );
1517   aCurveTypesList.append( tr("PREF_SPLINE") );
1518
1519   anIndexesList.clear();
1520   anIndexesList.append(0);
1521   anIndexesList.append(1);
1522   anIndexesList.append(2);
1523   
1524   pref->setItemProperty( curveType, "strings", aCurveTypesList );
1525   pref->setItemProperty( curveType, "indexes", anIndexesList );
1526
1527   int markerSize = pref->addPreference( tr( "PREF_MARKER_SIZE" ), plot2dGroup,
1528                                         LightApp_Preferences::IntSpin, "Plot2d", "MarkerSize" );
1529
1530   pref->setItemProperty( markerSize, "min", 0 );
1531   pref->setItemProperty( markerSize, "max", 100 );
1532   
1533   QStringList aScaleModesList;
1534   aScaleModesList.append( tr("PREF_LINEAR") );
1535   aScaleModesList.append( tr("PREF_LOGARITHMIC") );
1536   
1537   anIndexesList.clear();
1538   anIndexesList.append(0);
1539   anIndexesList.append(1);
1540
1541   int horScale = pref->addPreference( tr( "PREF_HOR_AXIS_SCALE" ), plot2dGroup,
1542                                       LightApp_Preferences::Selector, "Plot2d", "HorScaleMode" );
1543
1544   pref->setItemProperty( horScale, "strings", aScaleModesList );
1545   pref->setItemProperty( horScale, "indexes", anIndexesList );
1546
1547   int verScale = pref->addPreference( tr( "PREF_VERT_AXIS_SCALE" ), plot2dGroup,
1548                                       LightApp_Preferences::Selector, "Plot2d", "VerScaleMode" );
1549
1550   pref->setItemProperty( verScale, "strings", aScaleModesList );
1551   pref->setItemProperty( verScale, "indexes", anIndexesList );
1552
1553   pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), plot2dGroup,
1554                        LightApp_Preferences::Color, "Plot2d", "Background" );
1555
1556   int dirTab = pref->addPreference( tr( "PREF_TAB_DIRECTORIES" ), salomeCat );
1557   int dirGroup = pref->addPreference( tr( "PREF_GROUP_DIRECTORIES" ), dirTab );
1558   pref->setItemProperty( dirGroup, "columns", 1 );
1559   pref->addPreference( tr( "" ), dirGroup,
1560                        LightApp_Preferences::DirList, "FileDlg", "QuickDirList" );
1561
1562   pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), supervGroup,
1563                        LightApp_Preferences::Color, "SUPERVGraph", "Background" );
1564   pref->addPreference( tr( "PREF_SUPERV_TITLE_COLOR" ), supervGroup,
1565                        LightApp_Preferences::Color, "SUPERVGraph", "Title" );
1566 //  pref->addPreference( tr( "PREF_SUPERV_CTRL_COLOR" ), supervGroup,
1567 //                     LightApp_Preferences::Color, "SUPERVGraph", "Ctrl" );
1568 }
1569
1570 /*!Changed preferences */
1571 void LightApp_Application::preferencesChanged( const QString& sec, const QString& param )
1572 {
1573   SUIT_ResourceMgr* resMgr = resourceMgr();
1574   if ( !resMgr )
1575     return;
1576
1577   if ( sec == QString( "OCCViewer" ) && param == QString( "trihedron_size" ) )
1578   {
1579     int sz = resMgr->integerValue( sec, param, -1 );
1580     QPtrList<SUIT_ViewManager> lst;
1581     viewManagers( OCCViewer_Viewer::Type(), lst );
1582     for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current() && sz >= 0; ++it )
1583     {
1584       SUIT_ViewModel* vm = it.current()->getViewModel();
1585       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
1586         continue;
1587
1588       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
1589       occVM->setTrihedronSize( sz );
1590       occVM->getAISContext()->UpdateCurrentViewer();
1591     }
1592   }
1593
1594   if ( sec == QString( "VTKViewer" ) && param == QString( "trihedron_size" ) )
1595   {
1596     int sz = resMgr->integerValue( sec, param, -1 );
1597     QPtrList<SUIT_ViewManager> lst;
1598     viewManagers( SVTK_Viewer::Type(), lst );
1599     for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current() && sz >= 0; ++it )
1600     {
1601       SUIT_ViewModel* vm = it.current()->getViewModel();
1602       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
1603         continue;
1604
1605       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
1606       if( vtkVM )
1607       {
1608         vtkVM->setTrihedronSize( sz );
1609         vtkVM->Repaint();
1610       }
1611     }
1612   }
1613
1614   if ( sec == QString( "OCCViewer" ) && ( param == QString( "iso_number_u" ) || param == QString( "iso_number_v" ) ) )
1615   {
1616     QPtrList<SUIT_ViewManager> lst;
1617     viewManagers( OCCViewer_Viewer::Type(), lst );
1618     int u = resMgr->integerValue( sec, "iso_number_u" );
1619     int v = resMgr->integerValue( sec, "iso_number_v" );
1620     for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current(); ++it )
1621     {
1622       OCCViewer_ViewManager* mgr = dynamic_cast<OCCViewer_ViewManager*>( it.current() );
1623       if( mgr && mgr->getOCCViewer() )
1624         mgr->getOCCViewer()->setIsos( u, v );
1625     }
1626   }
1627
1628   if( sec=="ObjectBrowser" )
1629   {
1630     if( param=="auto_size" )
1631     {
1632       OB_Browser* ob = objectBrowser();
1633       if( !ob )
1634         return;
1635
1636       bool autoSize = resMgr->booleanValue( "ObjectBrowser", "auto_size", false );
1637       ob->setWidthMode( autoSize ? QListView::Maximum : QListView::Manual );
1638
1639       updateObjectBrowser( false );
1640     }
1641   }
1642
1643   if( sec=="PyConsole" )
1644   {
1645     if( param=="font" )
1646       if( pythonConsole() )
1647         pythonConsole()->setFont( resMgr->fontValue( "PyConsole", "font" ) );
1648   }
1649 }
1650
1651 /*!Update desktop title.*/
1652 void LightApp_Application::updateDesktopTitle() {
1653   QString aTitle = applicationName();
1654   QString aVer = applicationVersion();
1655   if ( !aVer.isEmpty() )
1656     aTitle += QString( " " ) + aVer;
1657
1658   desktop()->setCaption( aTitle );
1659 }
1660
1661 /*!Update windows after close document.*/
1662 void LightApp_Application::afterCloseDoc()
1663 {
1664   updateWindows();
1665
1666   CAM_Application::afterCloseDoc();
1667 }
1668
1669 /*!Update module action.*/
1670 void LightApp_Application::updateModuleActions()
1671 {
1672   QString modName;
1673   if ( activeModule() )
1674     modName = activeModule()->moduleName();
1675
1676   if ( myActions.contains( modName ) )
1677     myActions[modName]->setOn( true );
1678 }
1679
1680 /*!Gets current windows.
1681  *\param winMap - output current windows map.
1682  */
1683 void LightApp_Application::currentWindows( QMap<int, int>& winMap ) const
1684 {
1685   winMap.clear();
1686   if ( !activeStudy() )
1687     return;
1688
1689   if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) )
1690     ((LightApp_Module*)activeModule())->windows( winMap );
1691   else
1692     defaultWindows( winMap );
1693 }
1694
1695 /*!Gets current view managers.
1696  *\param lst - output current view managers list.
1697  */
1698 void LightApp_Application::currentViewManagers( QStringList& lst ) const
1699 {
1700   lst.clear();
1701   if ( !activeStudy() )
1702     return;
1703
1704   if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) )
1705     ((LightApp_Module*)activeModule())->viewManagers( lst );
1706   else
1707     defaultViewManagers( lst );
1708 }
1709
1710 /*!Update windows.*/
1711 void LightApp_Application::updateWindows()
1712 {
1713   QMap<int, int> winMap;
1714   currentWindows( winMap );
1715
1716   for ( QMap<int, int>::ConstIterator it = winMap.begin(); it != winMap.end(); ++it )
1717     getWindow( it.key() );
1718
1719   loadWindowsGeometry();
1720
1721   for ( WindowMap::ConstIterator itr = myWindows.begin(); itr != myWindows.end(); ++itr )
1722     setWindowShown( itr.key(), !itr.data()->isEmpty() && winMap.contains( itr.key() ) );
1723 }
1724
1725 /*!Update view managers.*/
1726 void LightApp_Application::updateViewManagers()
1727 {
1728   QStringList lst;
1729   currentViewManagers( lst );
1730
1731   for ( QStringList::const_iterator it = lst.begin(); it != lst.end(); ++it )
1732     getViewManager( *it, true );
1733 }
1734
1735 /*!Load windows geometry.*/
1736 void LightApp_Application::loadWindowsGeometry()
1737 {
1738   QtxDockAction* dockMgr = 0;
1739
1740   QAction* a = action( ViewWindowsId );
1741   if ( a && a->inherits( "QtxDockAction" ) )
1742     dockMgr = (QtxDockAction*)a;
1743
1744   if ( !dockMgr )
1745     return;
1746
1747   QString modName;
1748   if ( activeModule() )
1749     modName = activeModule()->name("");
1750
1751   QString section = QString( "windows_geometry" );
1752   if ( !modName.isEmpty() )
1753     section += QString( "." ) + modName;
1754
1755   dockMgr->loadGeometry( resourceMgr(), section, false );
1756   dockMgr->restoreGeometry();
1757 }
1758
1759 /*!Save windows geometry.*/
1760 void LightApp_Application::saveWindowsGeometry()
1761 {
1762   QtxDockAction* dockMgr = 0;
1763
1764   QAction* a = action( ViewWindowsId );
1765   if ( a && a->inherits( "QtxDockAction" ) )
1766     dockMgr = (QtxDockAction*)a;
1767
1768   if ( !dockMgr )
1769     return;
1770
1771   QString modName;
1772   if ( activeModule() )
1773     modName = activeModule()->name("");
1774
1775   QString section = QString( "windows_geometry" );
1776   if ( !modName.isEmpty() )
1777     section += QString( "." ) + modName;
1778
1779   dockMgr->storeGeometry();
1780   dockMgr->saveGeometry( resourceMgr(), section, false );
1781 }
1782
1783 /*!Activate windows.*/
1784 void LightApp_Application::activateWindows()
1785 {
1786   if ( activeStudy() )
1787   {
1788     for ( WindowMap::Iterator itr = myWindows.begin(); itr != myWindows.end(); ++itr )
1789       itr.data()->activate( activeStudy()->id() );
1790   }
1791 }
1792
1793 /*!Adds icon names for modules.*/
1794 void LightApp_Application::moduleIconNames( QMap<QString, QString>& iconMap ) const
1795 {
1796   iconMap.clear();
1797
1798   SUIT_ResourceMgr* resMgr = resourceMgr();
1799   if ( !resMgr )
1800     return;
1801
1802   QStringList modList;
1803   modules( modList, false );
1804
1805   for ( QStringList::const_iterator it = modList.begin(); it != modList.end(); ++it )
1806   {
1807     QString modName = *it;
1808     QString modIntr = moduleName( modName );
1809     QString modIcon = resMgr->stringValue( modIntr, "icon", QString::null );
1810
1811     if ( modIcon.isEmpty() )
1812       continue;
1813
1814     if ( SUIT_Tools::extension( modIcon ).isEmpty() )
1815       modIcon += QString( ".png" );
1816
1817     iconMap.insert( modName, modIcon );
1818   }
1819 }
1820
1821 /*!Insert items in popup, which necessary for current application*/
1822 void LightApp_Application::contextMenuPopup( const QString& type, QPopupMenu* thePopup, QString& title )
1823 {
1824   CAM_Application::contextMenuPopup( type, thePopup, title );
1825
1826   OB_Browser* ob = objectBrowser();
1827   if ( !ob || type != ob->popupClientType() )
1828     return;
1829
1830   thePopup->insertSeparator();
1831   thePopup->insertItem( tr( "MEN_REFRESH" ), this, SLOT( onRefresh() ) );
1832 }
1833
1834 /*!Create empty study.*/
1835 void LightApp_Application::createEmptyStudy()
1836 {
1837   CAM_Application::createEmptyStudy();
1838   if ( objectBrowser() )
1839     objectBrowser()->updateTree();
1840 }
1841
1842 /*!Activate module \a mod.*/
1843 bool LightApp_Application::activateModule( CAM_Module* mod )
1844 {
1845   bool res = CAM_Application::activateModule( mod );
1846   if ( objectBrowser() )
1847     objectBrowser()->updateTree();
1848   return res;
1849 }
1850
1851 /*!return keyborad accelerators manager object */
1852 SUIT_Accel* LightApp_Application::accel() const
1853 {
1854   return myAccel;
1855 }
1856
1857 /*! remove dead widget container from map */
1858 void LightApp_Application::onWCDestroyed( QObject* ob )
1859 {
1860   // remove destroyed widget container from windows map
1861   for ( WindowMap::ConstIterator itr = myWindows.begin(); itr != myWindows.end(); ++itr )
1862   {
1863     if ( itr.data() != ob )
1864       continue;
1865
1866     int key = itr.key();
1867     myWindows.remove( key );
1868     break;
1869   }
1870 }
1871
1872 /*! redefined to remove view manager from memory */
1873 void LightApp_Application::removeViewManager( SUIT_ViewManager* vm )
1874 {
1875   disconnect( vm, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
1876            this, SLOT( onCloseView( SUIT_ViewManager* ) ) );
1877   STD_Application::removeViewManager( vm );
1878   delete vm;
1879 }