]> SALOME platform Git repositories - modules/gui.git/blob - src/LightApp/LightApp_Application.cxx
Salome HOME
0022256: [CEA 866] Add item "Developers" in menu "Help"
[modules/gui.git] / src / LightApp / LightApp_Application.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // File:      LightApp_Application.cxx
24 // Created:   6/20/2005 18:39:45 PM
25 // Author:    Natalia Donis
26
27 #ifdef WNT
28 // E.A. : On windows with python 2.6, there is a conflict
29 // E.A. : between pymath.h and Standard_math.h which define
30 // E.A. : some same symbols : acosh, asinh, ...
31   #include <Standard_math.hxx>
32   #ifndef DISABLE_PYCONSOLE
33     #include <pymath.h>
34   #endif
35 #endif
36
37 #ifndef DISABLE_PYCONSOLE
38   #include "LightApp_PyInterp.h" // WARNING! This include must be the first!
39   #include <PyConsole_Console.h>
40 #endif
41
42 #include "LightApp_Application.h"
43 #include "LightApp_Module.h"
44 #include "LightApp_DataModel.h"
45 #include "LightApp_Study.h"
46 #include "LightApp_Preferences.h"
47 #include "LightApp_PreferencesDlg.h"
48 #include "LightApp_ModuleDlg.h"
49 #include "LightApp_AboutDlg.h"
50 #include "LightApp_ModuleAction.h"
51 // temporary commented
52 //#include "LightApp_OBFilter.h"
53 #include "LightApp_EventFilter.h"
54 #include "LightApp_OBSelector.h"
55 #include "LightApp_SelectionMgr.h"
56 #include "LightApp_DataObject.h"
57 #include "LightApp_WgViewModel.h"
58 #include "LightApp_FullScreenHelper.h"
59
60
61 #include <GUI_version.h>
62 #include <Basics_OCCTVersion.hxx>
63
64 #include <SALOME_Event.h>
65
66 #include <Style_Salome.h>
67 #include <Style_PrefDlg.h>
68
69 #include <CAM_Module.h>
70 #include <CAM_DataModel.h>
71 #include <CAM_Study.h>
72 #include <STD_TabDesktop.h>
73
74 #include <SUIT_DataBrowser.h>
75 #include <SUIT_Session.h>
76 #include <SUIT_Study.h>
77 #include <SUIT_FileDlg.h>
78 #include <SUIT_ResourceMgr.h>
79 #include <SUIT_ShortcutMgr.h>
80 #include <SUIT_Tools.h>
81 #include <SUIT_Accel.h>
82 #include <SUIT_MessageBox.h>
83 #include <SUIT_ViewWindow.h>
84
85 #include <Qtx.h>
86 #include <QtxToolBar.h>
87 #include <QtxTreeView.h>
88 #include <QtxMRUAction.h>
89 #include <QtxDockAction.h>
90 #include <QtxDockWidget.h>
91 #include <QtxActionToolMgr.h>
92 #include <QtxSearchTool.h>
93 #include <QtxWorkstack.h>
94 #include <QtxMap.h>
95 #include <QtxWebBrowser.h>
96
97 #include <LogWindow.h>
98
99 #ifndef DISABLE_GLVIEWER
100   #include <GLViewer_Viewer.h>
101   #include <GLViewer_ViewManager.h>
102   #include "LightApp_GLSelector.h"
103 #endif
104
105 #ifndef DISABLE_PLOT2DVIEWER
106   #include <Plot2d_ViewManager.h>
107   #include <Plot2d_ViewModel.h>
108   #include <Plot2d_ViewWindow.h>
109   #include <Plot2d_ViewFrame.h>
110   #include "LightApp_Plot2dSelector.h"
111 #ifndef DISABLE_SALOMEOBJECT
112   #include <SPlot2d_ViewModel.h>
113 #else
114   #include <Plot2d_ViewModel.h>
115 #endif
116 #endif
117
118 #ifndef DISABLE_OCCVIEWER
119   #include <OCCViewer_ViewManager.h>
120   #include <OCCViewer_ViewFrame.h>
121 #ifndef DISABLE_SALOMEOBJECT
122   #include <SOCC_ViewModel.h>
123 #else
124   #include <OCCViewer_ViewModel.h>
125 #endif
126   #include "LightApp_OCCSelector.h"
127 #endif
128
129 #ifndef DISABLE_VTKVIEWER
130 #ifndef DISABLE_SALOMEOBJECT
131   #include <SVTK_ViewModel.h>
132   #include <SVTK_ViewManager.h>
133   #include "LightApp_VTKSelector.h"
134 #else
135   #include <VTKViewer_ViewModel.h>
136   #include <VTKViewer_ViewManager.h>
137 #endif
138   #include <VTKViewer_ViewModel.h>
139 #endif
140
141 //#ifndef DISABLE_SUPERVGRAPHVIEWER
142 //  #include <SUPERVGraph_ViewModel.h>
143 //  #include <SUPERVGraph_ViewFrame.h>
144 //  #include <SUPERVGraph_ViewManager.h>
145 //#endif
146
147 #ifndef DISABLE_QXGRAPHVIEWER
148 //VSR: QxGraph has been replaced by QxScene
149 //  #include <QxGraph_ViewModel.h>
150 //  #include <QxGraph_ViewWindow.h>
151 //  #include <QxGraph_ViewManager.h>
152   #include <QxScene_ViewManager.h>
153   #include <QxScene_ViewModel.h>
154   #include <QxScene_ViewWindow.h>
155 #endif
156
157
158 #define VISIBILITY_COLUMN_WIDTH 25
159
160 #include <QDir>
161 #include <QImage>
162 #include <QString>
163 #include <QWidget>
164 #include <QStringList>
165 #include <QFile>
166 #include <QApplication>
167 #include <QMap>
168 #include <QStatusBar>
169 #include <QThread>
170 #include <QObjectList>
171 #include <QComboBox>
172 #include <QInputDialog>
173 #include <QFontDatabase>
174 #include <QIcon>
175 #include <QByteArray>
176 #include <QMenu>
177 #include <QProcess>
178 #include <QTimer>
179 #include <QHeaderView>
180 #include <QTreeView>
181 #include <QMimeData>
182 #include <QShortcut>
183
184 #include <utilities.h>
185
186 #define FIRST_HELP_ID 1000000
187
188 #ifndef DISABLE_SALOMEOBJECT
189   #include <SALOME_InteractiveObject.hxx>
190   #include <SALOME_ListIO.hxx>
191 #endif
192
193 #include <Standard_Version.hxx>
194
195 #define ToolBarMarker    0
196 #define DockWidgetMarker 1
197
198 static const char* imageEmptyIcon[] = {
199 "20 20 1 1",
200 ".      c None",
201 "....................",
202 "....................",
203 "....................",
204 "....................",
205 "....................",
206 "....................",
207 "....................",
208 "....................",
209 "....................",
210 "....................",
211 "....................",
212 "....................",
213 "....................",
214 "....................",
215 "....................",
216 "....................",
217 "....................",
218 "....................",
219 "....................",
220 "...................."};
221
222 int LightApp_Application::lastStudyId = 0;
223
224 /*!
225   \return last global id of study
226 */
227 int LightApp_Application::studyId()
228 {
229   return LightApp_Application::lastStudyId;
230 }
231
232 /*!Create new instance of LightApp_Application.*/
233 extern "C" LIGHTAPP_EXPORT SUIT_Application* createApplication()
234 {
235   return new LightApp_Application();
236 }
237
238 /*! \var global preferences of LightApp */
239 LightApp_Preferences* LightApp_Application::_prefs_ = 0;
240
241
242 /*!
243   \class LightApp_Application
244   Application containing LightApp module
245 */
246
247 /*!Constructor.*/
248 LightApp_Application::LightApp_Application()
249 : CAM_Application( false ),
250   myPrefs( 0 ),
251   myScreenHelper(new LightApp_FullScreenHelper())
252 {
253   Q_INIT_RESOURCE( LightApp );
254
255   STD_TabDesktop* desk = new STD_TabDesktop();
256   desk->setFullScreenAllowed(false);
257   desk->setMinimizeAllowed(false);
258
259   setDesktop( desk );
260
261   // initialize auto save timer
262   myAutoSaveTimer = new QTimer( this );
263   myAutoSaveTimer->setSingleShot( true );
264   connect( myAutoSaveTimer, SIGNAL( timeout() ), this, SLOT( onSaveDoc() ) );
265
266   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
267   QPixmap aLogo = aResMgr->loadPixmap( "LightApp", tr( "APP_DEFAULT_ICO" ), false );
268
269   QtxWebBrowser::setData("browser:icon",          aResMgr->loadPixmap( "LightApp", tr( "BROWSER_ICON" ) ) );
270   QtxWebBrowser::setData("browser:title",         tr( "BROWSER_TITLE" ) );
271   QtxWebBrowser::setData("toolbar:title",         tr( "BROWSER_TOOLBAR_TITLE" ) );
272   QtxWebBrowser::setData("menu:file:title",       tr( "BROWSER_FILEMENU" ) );
273   QtxWebBrowser::setData("action:close:title",    tr( "BROWSER_CLOSE" ) );
274   QtxWebBrowser::setData("action:close:icon",     aResMgr->loadPixmap( "LightApp", tr( "BROWSER_CLOSE_ICON" ) ) );
275   QtxWebBrowser::setData("action:back:title",     tr( "BROWSER_BACK" ) );
276   QtxWebBrowser::setData("action:forward:title",  tr( "BROWSER_FORWARD" ) );
277   QtxWebBrowser::setData("action:find:title",     tr( "BROWSER_FIND" ) );
278   QtxWebBrowser::setData("action:findnext:title", tr( "BROWSER_FINDNEXT" ) );
279   QtxWebBrowser::setData("action:findprev:title", tr( "BROWSER_FINDPREV" ) );
280
281   desktop()->setWindowIcon( aLogo );
282   desktop()->setDockableMenuBar( false );
283   desktop()->setDockableStatusBar( false );
284
285   // base logo (salome itself)
286   desktop()->logoInsert( "_app_base",  aResMgr->loadPixmap( "LightApp", tr( "APP_BASE_LOGO" ), false ) );
287   // extra logo (salome-based application)
288   desktop()->logoInsert( "_app_extra", aResMgr->loadPixmap( "LightApp", tr( "APP_EXTRA_LOGO" ), false ) );
289
290   clearViewManagers();
291
292   mySelMgr = new LightApp_SelectionMgr( this );
293
294   myAccel = SUIT_Accel::getAccel();
295
296 #ifndef DISABLE_OCCVIEWER
297   myAccel->setActionKey( SUIT_Accel::PanLeft,     Qt::CTRL+Qt::Key_Left,     OCCViewer_Viewer::Type() );
298   myAccel->setActionKey( SUIT_Accel::PanRight,    Qt::CTRL+Qt::Key_Right,    OCCViewer_Viewer::Type() );
299   myAccel->setActionKey( SUIT_Accel::PanUp,       Qt::CTRL+Qt::Key_Up,       OCCViewer_Viewer::Type() );
300   myAccel->setActionKey( SUIT_Accel::PanDown,     Qt::CTRL+Qt::Key_Down,     OCCViewer_Viewer::Type() );
301   myAccel->setActionKey( SUIT_Accel::ZoomIn,      Qt::CTRL+Qt::Key_Plus,     OCCViewer_Viewer::Type() );
302   myAccel->setActionKey( SUIT_Accel::ZoomOut,     Qt::CTRL+Qt::Key_Minus,    OCCViewer_Viewer::Type() );
303   myAccel->setActionKey( SUIT_Accel::ZoomFit,     Qt::CTRL+Qt::Key_Asterisk, OCCViewer_Viewer::Type() );
304   myAccel->setActionKey( SUIT_Accel::RotateLeft,  Qt::ALT+Qt::Key_Left,      OCCViewer_Viewer::Type() );
305   myAccel->setActionKey( SUIT_Accel::RotateRight, Qt::ALT+Qt::Key_Right,     OCCViewer_Viewer::Type() );
306   myAccel->setActionKey( SUIT_Accel::RotateUp,    Qt::ALT+Qt::Key_Up,        OCCViewer_Viewer::Type() );
307   myAccel->setActionKey( SUIT_Accel::RotateDown,  Qt::ALT+Qt::Key_Down,      OCCViewer_Viewer::Type() );
308 #endif
309 #ifndef DISABLE_VTKVIEWER
310   myAccel->setActionKey( SUIT_Accel::PanLeft,     Qt::CTRL+Qt::Key_Left,     VTKViewer_Viewer::Type() );
311   myAccel->setActionKey( SUIT_Accel::PanRight,    Qt::CTRL+Qt::Key_Right,    VTKViewer_Viewer::Type() );
312   myAccel->setActionKey( SUIT_Accel::PanUp,       Qt::CTRL+Qt::Key_Up,       VTKViewer_Viewer::Type() );
313   myAccel->setActionKey( SUIT_Accel::PanDown,     Qt::CTRL+Qt::Key_Down,     VTKViewer_Viewer::Type() );
314   myAccel->setActionKey( SUIT_Accel::ZoomIn,      Qt::CTRL+Qt::Key_Plus,     VTKViewer_Viewer::Type() );
315   myAccel->setActionKey( SUIT_Accel::ZoomOut,     Qt::CTRL+Qt::Key_Minus,    VTKViewer_Viewer::Type() );
316   myAccel->setActionKey( SUIT_Accel::ZoomFit,     Qt::CTRL+Qt::Key_Asterisk, VTKViewer_Viewer::Type() );
317   myAccel->setActionKey( SUIT_Accel::RotateLeft,  Qt::ALT+Qt::Key_Left,      VTKViewer_Viewer::Type() );
318   myAccel->setActionKey( SUIT_Accel::RotateRight, Qt::ALT+Qt::Key_Right,     VTKViewer_Viewer::Type() );
319   myAccel->setActionKey( SUIT_Accel::RotateUp,    Qt::ALT+Qt::Key_Up,        VTKViewer_Viewer::Type() );
320   myAccel->setActionKey( SUIT_Accel::RotateDown,  Qt::ALT+Qt::Key_Down,      VTKViewer_Viewer::Type() );
321 #endif
322 #ifndef DISABLE_PLOT2DVIEWER
323   myAccel->setActionKey( SUIT_Accel::PanLeft,     Qt::CTRL+Qt::Key_Left,     Plot2d_Viewer::Type() );
324   myAccel->setActionKey( SUIT_Accel::PanRight,    Qt::CTRL+Qt::Key_Right,    Plot2d_Viewer::Type() );
325   myAccel->setActionKey( SUIT_Accel::PanUp,       Qt::CTRL+Qt::Key_Up,       Plot2d_Viewer::Type() );
326   myAccel->setActionKey( SUIT_Accel::PanDown,     Qt::CTRL+Qt::Key_Down,     Plot2d_Viewer::Type() );
327   myAccel->setActionKey( SUIT_Accel::ZoomIn,      Qt::CTRL+Qt::Key_Plus,     Plot2d_Viewer::Type() );
328   myAccel->setActionKey( SUIT_Accel::ZoomOut,     Qt::CTRL+Qt::Key_Minus,    Plot2d_Viewer::Type() );
329   myAccel->setActionKey( SUIT_Accel::ZoomFit,     Qt::CTRL+Qt::Key_Asterisk, Plot2d_Viewer::Type() );
330 #endif
331
332   connect( mySelMgr, SIGNAL( selectionChanged() ), this, SLOT( onSelection() ) );
333
334   // Set existing font for the python console in resources
335   if( !aResMgr->hasValue( "PyConsole", "font" ) )
336     return;
337
338   QFont f = aResMgr->fontValue( "PyConsole", "font" );
339   QFontDatabase fdb;
340   QStringList famdb = fdb.families();
341
342   if ( famdb.contains(f.family()) || !aResMgr->hasValue( "PyConsole", "additional_families" ) )
343     return;
344
345   QStringList anAddFamilies = aResMgr->stringValue( "PyConsole", "additional_families" ).split( ";", QString::SkipEmptyParts );
346   QString aFamily;
347   for ( QStringList::Iterator it = anAddFamilies.begin(); it != anAddFamilies.end(); ++it )
348   {
349     aFamily = *it;
350     if ( famdb.contains(aFamily) )
351     {
352       f.setFamily( aFamily );
353       aResMgr->setValue( "PyConsole", "font", f );
354       break;
355     }
356   }
357 }
358
359 /*!Destructor.
360  *\li Save window geometry.
361  *\li Save desktop geometry.
362  *\li Save resource maneger.
363  *\li Delete selection manager.
364  */
365 LightApp_Application::~LightApp_Application()
366 {
367   delete mySelMgr;
368   delete myScreenHelper;
369 }
370
371 /*!Start application.*/
372 void LightApp_Application::start()
373 {
374   CAM_Application::start();
375
376   updateWindows();
377   updateViewManagers();
378
379   putInfo( "" );
380   desktop()->statusBar()->showMessage( "" );
381
382   LightApp_EventFilter::Init();
383 }
384
385 /*!Gets application name.*/
386 QString LightApp_Application::applicationName() const
387 {
388   static QString _app_name;
389   if ( _app_name.isEmpty() )
390     _app_name = tr( "APP_NAME" );
391   return _app_name;
392 }
393
394 /*!Gets application version.*/
395 QString LightApp_Application::applicationVersion() const
396 {
397   static QString _app_version;
398
399   if ( _app_version.isEmpty() )
400   {
401     QString resVersion = tr( "APP_VERSION" );
402     if ( resVersion != "APP_VERSION" )
403     {
404       _app_version = resVersion;
405     }
406     else
407     {
408       _app_version = GUI_VERSION_STR;
409     }
410   }
411   return _app_version;
412 }
413
414 /*!Load module by \a name.*/
415 CAM_Module* LightApp_Application::loadModule( const QString& name, const bool showMsg )
416 {
417   CAM_Module* mod = CAM_Application::loadModule( name, showMsg );
418   if ( mod )
419   {
420     connect( this, SIGNAL( studyOpened() ), mod, SLOT( onModelOpened() ) );
421     connect( this, SIGNAL( studySaved() ),  mod, SLOT( onModelSaved() ) );
422     connect( this, SIGNAL( studyClosed() ), mod, SLOT( onModelClosed() ) );
423   }
424   return mod;
425 }
426
427 /*!Activate module by \a modName*/
428 bool LightApp_Application::activateModule( const QString& modName )
429 {
430   QString actName;
431   CAM_Module* prevMod = activeModule();
432
433   if ( prevMod )
434     actName = prevMod->moduleName();
435
436   if ( actName == modName )
437     return true;
438
439   putInfo( tr( "ACTIVATING_MODULE" ).arg( modName ) );
440
441   saveDockWindowsState();
442
443   bool status = CAM_Application::activateModule( modName );
444
445   updateModuleActions();
446
447   putInfo( "" );
448
449   if ( !status )
450     return false;
451
452   updateWindows();
453   updateViewManagers();
454
455   return true;
456 }
457
458 /*!Gets selection manager.*/
459 LightApp_SelectionMgr* LightApp_Application::selectionMgr() const
460 {
461   return mySelMgr;
462 }
463
464 /*!Creat action "New window" for certain type of viewer:*/
465 void LightApp_Application::createActionForViewer( const int id,
466                                                   const int parentId,
467                                                   const QString& suffix,
468                                                   const int accel )
469 {
470   QString vtlt = tr( QString( "NEW_WINDOW_%1" ).arg( suffix ).toLatin1().constData() );
471   QString tip = tr( "CREATING_NEW_WINDOW" ).arg( vtlt.remove( "&" ) );
472   QAction* a = createAction( id,                      // menu action id
473                              tip,                     // status tip
474                              QIcon(),                 // icon
475                              vtlt,                    // menu text
476                              tip,                     // tooltip
477                              accel,                   // shortcut
478                              desktop(),               // parent
479                              false,                   // toggle flag
480                              this,                    // receiver
481                              SLOT( onNewWindow() ) ); // slot
482   createMenu( a, parentId, -1 );
483 }
484
485 /*!Create actions:*/
486
487 void LightApp_Application::createActions()
488 {
489   CAM_Application::createActions();
490
491   SUIT_Desktop* desk = desktop();
492   SUIT_ResourceMgr* resMgr = resourceMgr();
493
494   // Preferences
495   createAction( PreferencesId, tr( "TOT_DESK_PREFERENCES" ), QIcon(),
496                 tr( "MEN_DESK_PREFERENCES" ), tr( "PRP_DESK_PREFERENCES" ),
497                 Qt::CTRL+Qt::Key_R, desk, false, this, SLOT( onPreferences() ) );
498
499   // Help menu:
500
501   // - Help for modules
502
503   int helpMenu = createMenu( tr( "MEN_DESK_HELP" ), -1, -1, 1000 );
504   createMenu( separator(), helpMenu, -1, 10 );
505   QStringList aModuleList;
506   modules( aModuleList, false );
507   aModuleList.prepend( "GUI" );
508   aModuleList.prepend( "KERNEL" );
509
510   int id = LightApp_Application::UserID + FIRST_HELP_ID;
511
512   QString aModule;
513   foreach( aModule, aModuleList ) {
514     if ( aModule.isEmpty() )                                         // module title (user name)
515       continue;
516     IMap <QString, QString> helpData;                                // list of help files for the module
517     QString helpSubMenu;                                             // help submenu name (empty if not needed)
518     QString modName = moduleName( aModule );                         // module name
519     if ( modName.isEmpty() ) modName = aModule;                      // for KERNEL and GUI
520     QString rootDir = QString( "%1_ROOT_DIR" ).arg( modName );       // module root dir variable
521     QString modDir  = getenv( rootDir.toLatin1().constData() );      // module root dir
522     QString docSection;
523     if (resMgr->hasValue( modName, "documentation" ) )
524       docSection = resMgr->stringValue(modName, "documentation");
525     else if ( resMgr->hasSection( modName + "_documentation" ) )
526       docSection = modName + "_documentation";
527     if ( !docSection.isEmpty() ) {
528       helpSubMenu = resMgr->stringValue( docSection, "sub_menu", "" ).arg( aModule );
529       QStringList listOfParam = resMgr->parameters( docSection );
530       foreach( QString paramName, listOfParam ) {
531         QString valueStr = resMgr->stringValue( docSection, paramName );
532         if ( !valueStr.isEmpty() ) {
533           QFileInfo fi( valueStr );
534           if ( fi.isRelative() && !modDir.isEmpty() )
535             valueStr = Qtx::addSlash( modDir ) + valueStr;
536           if ( QFile::exists( valueStr ) )
537             helpData.insert( paramName.arg( aModule ), valueStr );
538         }
539       }
540     }
541
542     if ( helpData.isEmpty() && !modDir.isEmpty() ) {
543       QStringList idxLst = QStringList() << modDir << "share" << "doc" << "salome" << "gui" << modName << "index.html";
544       QString indexFile = idxLst.join( QDir::separator() );          // index file
545       if ( QFile::exists( indexFile ) )
546         helpData.insert( tr( "%1 module Users's Guide" ).arg( aModule ), indexFile );
547     }
548
549     IMapConstIterator<QString, QString > fileIt;
550     for ( fileIt = helpData.begin(); fileIt != helpData.end(); fileIt++ ) {
551       QString helpFileName = fileIt.key();
552       // remove all '//' occurances 
553       while ( helpFileName.contains( "//" ) )
554         helpFileName.replace( "//", "" );
555       // obtain submenus hierarchy if given
556       QStringList smenus = helpFileName.split( "/" );
557       helpFileName = smenus.last();
558       smenus.removeLast();
559       QAction* a = createAction( id, helpFileName,
560                                  resMgr->loadPixmap( "STD", tr( "ICON_HELP" ), false ),
561                                  helpFileName, helpFileName,
562                                  0, desk, false, this, SLOT( onHelpContentsModule() ) );
563       a->setData( fileIt.value() );
564       if ( !helpSubMenu.isEmpty() ) {
565         smenus.prepend( helpSubMenu );
566       }
567       // create sub-menus hierarchy
568       int menuId = helpMenu;
569       foreach ( QString subMenu, smenus ) {
570         menuId = createMenu( subMenu, menuId, -1, 0 );
571       }
572       createMenu( a, menuId, -1, 0 );
573       id++;
574     }
575   }
576
577   // - Additional help items
578
579   QStringList addHelpItems = resMgr->parameters( "add_help" );
580   foreach ( QString addHelpItem, addHelpItems ) {
581     QString valueStr = resMgr->stringValue( "add_help", addHelpItem );
582     printf("-----%s\n", qPrintable(valueStr));
583     if ( !valueStr.isEmpty() && QFile::exists( valueStr ) ) {
584       QAction* a = createAction( id, addHelpItem,
585                                  resMgr->loadPixmap( "STD", tr( "ICON_HELP" ), false ),
586                                  addHelpItem, addHelpItem,
587                                  0, desk, false, this, SLOT( onHelpContentsModule() ) );
588       a->setData( valueStr );
589       createMenu( a, helpMenu, -1, 5 );
590       id++;
591     }
592   }
593   createMenu( separator(), helpMenu, -1, 5 );
594
595   //! MRU
596   static QtxMRUAction* mru = new QtxMRUAction( tr( "TOT_DESK_MRU" ), tr( "MEN_DESK_MRU" ), 0 );
597   connect( mru, SIGNAL( activated( const QString& ) ), this, SLOT( onMRUActivated( const QString& ) ) );
598   registerAction( MRUId, mru );
599
600   // default icon for neutral point ('SALOME' module)
601   QPixmap defIcon = resMgr->loadPixmap( "LightApp", tr( "APP_DEFAULT_ICO" ), false );
602   if ( defIcon.isNull() )
603     defIcon = QPixmap( imageEmptyIcon );
604
605   //! default icon for any module
606   QPixmap modIcon = resMgr->loadPixmap( "LightApp", tr( "APP_MODULE_ICO" ), false );
607   if ( modIcon.isNull() )
608     modIcon = QPixmap( imageEmptyIcon );
609
610   QStringList modList;
611   modules( modList, false );
612
613   if ( modList.count() > 1 )
614   {
615     LightApp_ModuleAction* moduleAction =
616       new LightApp_ModuleAction( tr( "APP_NAME" ), defIcon, desk );
617
618     QMap<QString, QString> iconMap;
619     moduleIconNames( iconMap );
620
621     const int iconSize = 20;
622
623     QStringList::Iterator it;
624     for ( it = modList.begin(); it != modList.end(); ++it )
625     {
626       if ( !isLibExists( *it ) )
627         continue;
628
629       QString modName = moduleName( *it );
630
631       if ( !isModuleAccessible( *it ) )
632         continue;
633
634       QString iconName;
635       if ( iconMap.contains( *it ) )
636         iconName = iconMap[*it];
637
638       QPixmap icon = resMgr->loadPixmap( modName, iconName, false );
639       if ( icon.isNull() )
640       {
641         icon = modIcon;
642         INFOS ( "****************************************************************" << std::endl
643                 <<  "*    Icon for " << (*it).toLatin1().constData()
644                 << " not found. Using the default one." << std::endl
645                 << "****************************************************************" << std::endl );
646       }
647
648       icon = Qtx::scaleIcon( icon, iconSize );
649
650       moduleAction->insertModule( *it, icon );
651     }
652
653     connect( moduleAction, SIGNAL( moduleActivated( const QString& ) ),
654              this, SLOT( onModuleActivation( const QString& ) ) );
655     registerAction( ModulesListId, moduleAction );
656   }
657
658   // New window
659   int windowMenu = createMenu( tr( "MEN_DESK_WINDOW" ), -1, MenuWindowId, 100 );
660   int newWinMenu = createMenu( tr( "MEN_DESK_NEWWINDOW" ), windowMenu, -1, 0 );
661
662   createAction( CloseId, tr( "TOT_CLOSE" ), QIcon(), tr( "MEN_DESK_CLOSE" ), tr( "PRP_CLOSE" ),
663                 Qt::CTRL+Qt::Key_F4, desk, false, this, SLOT( onCloseWindow() ) );
664   createAction( CloseAllId, tr( "TOT_CLOSE_ALL" ), QIcon(), tr( "MEN_DESK_CLOSE_ALL" ), tr( "PRP_CLOSE_ALL" ),
665                 0, desk, false, this, SLOT( onCloseAllWindow() ) );
666   createAction( GroupAllId, tr( "TOT_GROUP_ALL" ), QIcon(), tr( "MEN_DESK_GROUP_ALL" ), tr( "PRP_GROUP_ALL" ),
667                 0, desk, false, this, SLOT( onGroupAllWindow() ) );
668
669   createMenu( CloseId,     windowMenu, 0, -1 );
670   createMenu( CloseAllId,  windowMenu, 0, -1 );
671   createMenu( GroupAllId,  windowMenu, 0, -1 );
672   createMenu( separator(), windowMenu, -1, 0 );
673
674 #ifndef DISABLE_GLVIEWER
675   createActionForViewer( NewGLViewId, newWinMenu, QString::number( 0 ), Qt::ALT+Qt::Key_G );
676 #endif
677 #ifndef DISABLE_PLOT2DVIEWER
678   createActionForViewer( NewPlot2dId, newWinMenu, QString::number( 1 ), Qt::ALT+Qt::Key_P );
679 #endif
680 #ifndef DISABLE_OCCVIEWER
681   createActionForViewer( NewOCCViewId, newWinMenu, QString::number( 2 ), Qt::ALT+Qt::Key_O );
682 #endif
683 #ifndef DISABLE_VTKVIEWER
684   createActionForViewer( NewVTKViewId, newWinMenu, QString::number( 3 ), Qt::ALT+Qt::Key_K );
685 #endif
686 #ifndef DISABLE_QXGRAPHVIEWER
687 //VSR: QxGraph has been replaced by QxScene
688 //  createActionForViewer( NewQxGraphViewId, newWinMenu, QString::number( 4 ), Qt::ALT+Qt::Key_C );
689   createActionForViewer( NewQxSceneViewId, newWinMenu, QString::number( 4 ), Qt::ALT+Qt::Key_S );
690 #endif
691
692   createAction( RenameId, tr( "TOT_RENAME" ), QIcon(), tr( "MEN_DESK_RENAME" ), tr( "PRP_RENAME" ),
693                 Qt::ALT+Qt::SHIFT+Qt::Key_R, desk, false, this, SLOT( onRenameWindow() ) );
694   createMenu( RenameId, windowMenu, -1 );
695
696   int fileMenu = createMenu( tr( "MEN_DESK_FILE" ), -1 );
697   createMenu( PreferencesId, fileMenu, 50, -1 );
698   createMenu( separator(), fileMenu, -1, 50, -1 );
699
700   createMenu( separator(), fileMenu, -1, 100, -1 );
701   createMenu( MRUId, fileMenu, 100, -1 );
702   createMenu( separator(), fileMenu, -1, 100, -1 );
703
704   createAction( StyleId, tr( "TOT_THEME" ), QIcon(), tr( "MEN_DESK_THEME" ), tr( "PRP_THEME" ),
705                 0, desk, false, this, SLOT( onStylePreferences() ) );
706
707   createAction( FullScreenId, tr( "TOT_FULLSCREEN" ), QIcon(), tr( "MEN_DESK_FULLSCREEN" ), tr( "PRP_FULLSCREEN" ),
708                 Qt::Key_F11, desk, false, this, SLOT( onFullScreen() ) );
709
710
711   int viewMenu = createMenu( tr( "MEN_DESK_VIEW" ), -1 );
712   createMenu( separator(), viewMenu, -1, 20, -1 );
713   createMenu( StyleId, viewMenu, 20, -1 );
714   createMenu( FullScreenId, viewMenu, 20, -1 );
715
716   int modTBar = createTool( tr( "INF_TOOLBAR_MODULES" ) );
717   createTool( ModulesListId, modTBar );
718 }
719
720 /*!On module activation action.*/
721 void LightApp_Application::onModuleActivation( const QString& modName )
722 {
723   // Force user to create/open a study before module activation
724   QMap<QString, QString> iconMap;
725   moduleIconNames( iconMap );
726   QPixmap icon = resourceMgr()->loadPixmap( moduleName( modName ), iconMap[ modName ], false );
727   if ( icon.isNull() )
728     icon = resourceMgr()->loadPixmap( "LightApp", tr( "APP_MODULE_BIG_ICO" ), false ); // default icon for any module
729
730   bool cancelled = false;
731
732   while ( !modName.isEmpty() && !activeStudy() && !cancelled ){
733     LightApp_ModuleDlg aDlg( desktop(), modName, icon );
734     QMap<int, QString> opmap = activateModuleActions();
735     for ( QMap<int, QString>::ConstIterator it = opmap.begin(); it != opmap.end(); ++it )
736       aDlg.addButton( it.value(), it.key() );
737
738     int res = aDlg.exec();
739     if ( res ) {
740       // some operation is selected
741       moduleActionSelected( res );
742     }
743     else {
744       // cancelled
745       putInfo( tr("INF_CANCELLED") );
746
747       LightApp_ModuleAction* moduleAction =
748         qobject_cast<LightApp_ModuleAction*>( action( ModulesListId ) );
749       if ( moduleAction )
750         moduleAction->setActiveModule( QString() );
751       cancelled = true;
752     }
753   }
754
755   if ( !cancelled )
756     activateModule( modName );
757 }
758
759 /*!Default module activation.*/
760 QString LightApp_Application::defaultModule() const
761 {
762   QStringList aModuleNames;
763   modules( aModuleNames, false ); // obtain a complete list of module names for the current configuration
764   //! If there's the one and only module --> activate it automatically
765   //! TODO: Possible improvement - default module can be taken from preferences
766   return aModuleNames.count() > 1 ? "" : ( aModuleNames.count() ? aModuleNames.first() : "" );
767 }
768
769 /*!On new window slot.*/
770 void LightApp_Application::onNewWindow()
771 {
772   const QObject* obj = sender();
773   if ( !obj || !obj->inherits( "QAction" ) )
774     return;
775
776   QString type;
777   int id = actionId( (QAction*)obj );
778   switch ( id )
779   {
780 #ifndef DISABLE_GLVIEWER
781   case NewGLViewId:
782     type = GLViewer_Viewer::Type();
783     break;
784 #endif
785 #ifndef DISABLE_PLOT2DVIEWER
786   case NewPlot2dId:
787     type = Plot2d_Viewer::Type();
788     break;
789 #endif
790 #ifndef DISABLE_OCCVIEWER
791   case NewOCCViewId:
792     type = OCCViewer_Viewer::Type();
793     break;
794 #endif
795 #ifndef DISABLE_VTKVIEWER
796   case NewVTKViewId:
797     type = VTKViewer_Viewer::Type();
798     break;
799 #endif
800 #ifndef DISABLE_QXGRAPHVIEWER
801 //VSR: QxGraph has been replaced by QxScene
802 //  case NewQxGraphViewId:
803 //    type = QxGraph_Viewer::Type();
804 //    break;
805   case NewQxSceneViewId:
806     type = QxScene_Viewer::Type();
807     break;
808 #endif
809   }
810
811   if ( !type.isEmpty() )
812     createViewManager( type );
813 }
814
815 /*!
816   SLOT: Creates new document
817 */
818 void LightApp_Application::onNewDoc()
819 {
820   //asl: fix for 0020515
821   if ( activeStudy() )
822     saveDockWindowsState();
823
824   CAM_Application::onNewDoc();
825 }
826
827 /*!
828   SLOT: Opens new document
829 */
830 void LightApp_Application::onOpenDoc()
831 {
832   SUIT_Study* study = activeStudy();
833   saveDockWindowsState();
834
835   CAM_Application::onOpenDoc();
836
837   if ( !study ) // new study will be create in THIS application
838   {
839     updateWindows();
840     updateViewManagers();
841   }
842 }
843
844 /*!
845   SLOT: Opens new document.
846   \param aName - name of file
847 */
848 bool LightApp_Application::onOpenDoc( const QString& aName )
849 {
850   // We should take mru action first because this application instance can be deleted later.
851   QtxMRUAction* mru = ::qobject_cast<QtxMRUAction*>( action( MRUId ) );
852
853   bool res = CAM_Application::onOpenDoc( aName );
854
855   if ( mru )
856   {
857     if ( res )
858       mru->insert( aName );
859     else
860       mru->remove( aName );
861   }
862   return res;
863 }
864
865 /*!
866   SLOT: Displays "About" message box
867 */
868 void LightApp_Application::onHelpAbout()
869 {
870   LightApp_AboutDlg dlg( applicationName(), applicationVersion(), desktop() );
871   dlg.exec();
872 }
873
874 /*!
875   Private SLOT: Called on selection is changed
876   Dispatchs active module that selection is changed
877 */
878 void LightApp_Application::onSelection()
879 {
880   onSelectionChanged();
881
882   if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) )
883     ((LightApp_Module*)activeModule())->selectionChanged();
884 }
885
886 /*!
887   Sets active study.
888  \param study - SUIT_Study.
889 */
890 void LightApp_Application::setActiveStudy( SUIT_Study* study )
891 {
892   CAM_Application::setActiveStudy( study );
893 }
894
895 /*!
896   Enables/Disables menu items and toolbar buttons. Rebuild menu
897 */
898 void LightApp_Application::updateCommandsStatus()
899 {
900   CAM_Application::updateCommandsStatus();
901   QAction* a = 0;
902
903 #ifndef DISABLE_GLVIEWER
904   a = action( NewGLViewId );
905   if( a )
906     a->setEnabled( activeStudy() );
907 #endif
908
909 #ifndef DISABLE_PLOT2DVIEWER
910   a = action( NewPlot2dId );
911   if( a )
912     a->setEnabled( activeStudy() );
913 #endif
914
915 #ifndef DISABLE_OCCVIEWER
916   a = action( NewOCCViewId );
917   if( a )
918     a->setEnabled( activeStudy() );
919 #endif
920
921 #ifndef DISABLE_VTKVIEWER
922   a = action( NewVTKViewId );
923   if( a )
924     a->setEnabled( activeStudy() );
925 #endif
926
927 #ifndef DISABLE_QXGRAPHVIEWER
928 //VSR: QxGraph has been replaced by QxScene
929 //  a = action( NewQxGraphViewId );
930   a = action( NewQxSceneViewId );
931   if( a )
932     a->setEnabled( activeStudy() );
933 #endif
934 }
935
936 /*!
937   \class RunBrowser
938   Runs system command in separate thread
939 */
940 class RunBrowser: public QThread
941 {
942 public:
943   RunBrowser( LightApp_Application* app,
944               const QString&        theApp,
945               const QString&        theParams,
946               const QString&        theHelpFile,
947               const QString&        theContext = QString() )
948     : myApp( theApp ),
949       myParams( theParams ),
950       myContext( theContext ),
951       myStatus(0),
952       myLApp( app )
953   {
954     //For the external browser always specify 'file://' protocol,
955     //because some WEB browsers (for example Mozilla Firefox) can't open local file without protocol.
956     myHelpFile = QString("file://%1").arg( QFileInfo( theHelpFile ).canonicalFilePath() );
957   }
958
959   virtual void run()
960   {
961     if ( !myApp.isEmpty() && !myHelpFile.isEmpty()) {
962       QString aCommand = QString( "%1 %2 \"%3%4\"" ).arg( myApp, myParams, myHelpFile, myContext.isEmpty() ? QString("") : QString( "#%1" ).arg( myContext ) );
963
964       QProcess* proc = new QProcess();
965
966       proc->start( aCommand );
967       if ( !proc->waitForStarted() ) {
968         SALOME_CustomEvent* ce2000 = new SALOME_CustomEvent( 2000 );
969         QString* msg = new QString( QObject::tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ).arg( myApp, myHelpFile ) );
970         ce2000->setData( msg );
971         QApplication::postEvent( myLApp, ce2000 );
972       }
973     }
974   }
975
976 private:
977   QString               myApp;
978   QString               myParams;
979   QString               myHelpFile;
980   QString               myContext;
981   int                   myStatus;
982   LightApp_Application* myLApp;
983 };
984
985 /*!
986   SLOT: Displays help contents for choosen module
987 */
988 void LightApp_Application::onHelpContentsModule()
989 {
990   const QAction* a = (QAction*) sender();
991   QString helpFile = a->data().toString();
992   if ( helpFile.isEmpty() ) return;
993
994   SUIT_ResourceMgr* resMgr = resourceMgr();
995   QString platform;
996 #ifdef WIN32
997   platform = "winapplication";
998 #else
999   platform = "application";
1000 #endif
1001   QString anApp = resMgr->stringValue("ExternalBrowser", platform);
1002 #ifdef WIN32
1003   QString quote("\"");
1004   anApp.prepend( quote );
1005   anApp.append( quote );
1006 #endif
1007   QString aParams = resMgr->stringValue("ExternalBrowser", "parameters");
1008   bool useExtBrowser = resMgr->booleanValue("ExternalBrowser", "use_external_browser", false );
1009
1010   if( useExtBrowser ) {
1011     if ( !anApp.isEmpty() ) {
1012       RunBrowser* rs = new RunBrowser( this, anApp, aParams, helpFile );
1013       rs->start();
1014     }
1015     else {
1016       if ( SUIT_MessageBox::question( desktop(), tr( "WRN_WARNING" ), tr( "DEFINE_EXTERNAL_BROWSER" ),
1017                                       SUIT_MessageBox::Yes | SUIT_MessageBox::No,
1018                                       SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes )
1019
1020         showPreferences( tr( "PREF_APP" ) );
1021     }
1022   }
1023   else {
1024 #ifdef WIN32
1025     // On Win32 platform QWebKit of the Qt 4.6.3 hang up in case 'file://' protocol 
1026     // is defined. On Linux platform QWebKit doesn't work correctly without 'file://' protocol.
1027     QtxWebBrowser::loadUrl(helpFile);
1028 #else
1029         QtxWebBrowser::loadUrl(QString("file://%1").arg(helpFile));
1030 #endif
1031   }
1032 }
1033
1034 /*!
1035   SLOT: Displays help contents for choosen dialog
1036 */
1037 void LightApp_Application::onHelpContextModule( const QString& theComponentName,
1038                                                 const QString& theFileName,
1039                                                 const QString& theContext )
1040 {
1041   QString fileName = theFileName;
1042   QString context  = theContext;
1043   if ( !QFile::exists( fileName ) && theContext.isEmpty() ) {
1044     // context might be passed within theFileName argument
1045     QStringList comps = fileName.split("#");
1046     if ( comps.count() > 1 ) {
1047       context = comps.last();
1048       comps.removeLast();
1049       fileName = comps.join("#");
1050     }
1051   }
1052
1053   QString homeDir = "";
1054   if ( !theComponentName.isEmpty() ) {
1055     QString dir = getenv( ( theComponentName + "_ROOT_DIR" ).toLatin1().constData() );
1056     if ( !dir.isEmpty() )
1057       homeDir = Qtx::addSlash( Qtx::addSlash( dir )      +
1058                                Qtx::addSlash( "share" )  +
1059                                Qtx::addSlash( "doc" )    +
1060                                Qtx::addSlash( "salome" ) +
1061                                Qtx::addSlash( "gui" )    +
1062                                Qtx::addSlash( theComponentName ) );
1063   }
1064
1065   QString helpFile = QFileInfo( homeDir + fileName ).absoluteFilePath();
1066   SUIT_ResourceMgr* resMgr = resourceMgr();
1067         QString platform;
1068 #ifdef WIN32
1069         platform = "winapplication";
1070 #else
1071         platform = "application";
1072 #endif
1073         QString anApp = resMgr->stringValue("ExternalBrowser", platform);
1074 #ifdef WIN32
1075         QString quote("\"");
1076         anApp.prepend( quote );
1077         anApp.append( quote );
1078 #endif
1079
1080   bool useExtBrowser = resMgr->booleanValue("ExternalBrowser", "use_external_browser", false );
1081
1082   if(useExtBrowser) {
1083     QString aParams = resMgr->stringValue("ExternalBrowser", "parameters");
1084
1085     if ( !anApp.isEmpty() ) {
1086       RunBrowser* rs = new RunBrowser( this, anApp, aParams, helpFile, context );
1087       rs->start();
1088     }
1089     else {
1090       if ( SUIT_MessageBox::question( desktop(), tr( "WRN_WARNING" ), tr( "DEFINE_EXTERNAL_BROWSER" ),
1091                                       SUIT_MessageBox::Yes | SUIT_MessageBox::No,
1092                                       SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes )
1093         showPreferences( tr( "PREF_APP" ) );
1094     }
1095   }
1096   else {
1097 #ifdef WIN32
1098     // On Win32 platform QWebKit of the Qt 4.6.3 hang up in case 'file://' protocol 
1099     // is defined. On Linux platform QWebKit doesn't work correctly without 'file://' protocol.
1100         QtxWebBrowser::loadUrl(helpFile, context);
1101 #else
1102         QtxWebBrowser::loadUrl(QString("file://%1").arg(helpFile),context);
1103 #endif
1104     
1105   }
1106 }
1107
1108 /*!
1109   Sets enable or disable some actions on selection changed.
1110 */
1111 void LightApp_Application::onSelectionChanged()
1112 {
1113   LightApp_Module* m = dynamic_cast<LightApp_Module*>( activeModule() );
1114   bool canCopy  = m ? m->canCopy() : false;
1115   bool canPaste = m ? m->canPaste() : false;
1116
1117   action( EditCopyId )->setEnabled(canCopy);
1118   action( EditPasteId )->setEnabled(canPaste);
1119 }
1120
1121 /*!
1122   Adds window to application.
1123   \param wid - QWidget
1124   \param flag - key for window
1125   \param studyId - study id
1126   Flag used how identificator of window in windows list.
1127 */
1128 /*
1129 void LightApp_Application::addWindow( QWidget* wid, const int flag, const int studyId )
1130 {
1131   if ( !wid )
1132     return;
1133
1134   int sId = studyId;
1135   if ( sId < 0 )
1136   {
1137     if ( !activeStudy() )
1138       return;
1139     else
1140       sId = activeStudy()->id();
1141   }
1142
1143   if ( !myWindows.contains( flag ) )
1144   {
1145     QMap<int, int> winMap;
1146     currentWindows( winMap );
1147
1148     LightApp_WidgetContainer* newWC = new LightApp_WidgetContainer( flag, desktop() );
1149     connect( newWC, SIGNAL(  destroyed ( QObject* ) ), this, SLOT( onWCDestroyed( QObject* ) ) );
1150     // asv: connecting a slot for storing visibility flag of a window
1151     connect( newWC, SIGNAL( visibilityChanged ( bool ) ), SLOT( onVisibilityChanged( bool ) ) );
1152     myWindows.insert( flag, newWC );
1153     if ( winMap.contains( flag ) ) {
1154       //desktop()->removeDockWidget( myWindows[flag] );
1155       desktop()->addDockWidget( (Qt::DockWidgetArea)winMap[flag], myWindows[flag] );
1156     }
1157
1158     //myWindows[flag]->setResizeEnabled( true );
1159     myWindows[flag]->setFeatures( QDockWidget::AllDockWidgetFeatures );
1160     myWindows[flag]->setObjectName( QString( "dock_window_%1" ).arg( flag ) );
1161     //myWindows[flag]->setFixedExtentWidth( wid->width() );
1162     //myWindows[flag]->setFixedExtentHeight( wid->height() );
1163     myWindows[flag]->resize( wid->width(), wid->height() );
1164   }
1165
1166   QFont f;
1167 #ifndef DISABLE_PYCONSOLE
1168   if( wid->inherits( "PyConsole_Console" ) )
1169   {
1170     if( resourceMgr()->hasValue( "PyConsole", "font" ) )
1171       f = resourceMgr()->fontValue( "PyConsole", "font" );
1172     else
1173       {
1174         f = ( ( PyConsole_Console* )wid )->font();
1175         resourceMgr()->setValue( "PyConsole", "font", f );
1176       }
1177   }
1178   else
1179 #endif
1180     f = wid->font();
1181
1182   myWindows[flag]->insert( sId, wid );
1183   wid->setFont( f );
1184
1185   setWindowShown( flag, !myWindows[flag]->isEmpty() );
1186 }
1187 */
1188
1189 QWidget* LightApp_Application::dockWindow( const int id ) const
1190 {
1191   QWidget* wid = 0;
1192   if ( myWin.contains( id ) )
1193     wid = myWin[id];
1194   return wid;
1195 }
1196
1197 QDockWidget* LightApp_Application::windowDock( QWidget* wid ) const
1198 {
1199   if ( !wid )
1200     return 0;
1201
1202   QDockWidget* dock = 0;
1203   QWidget* w = wid->parentWidget();
1204   while ( w && !dock )
1205   {
1206     dock = ::qobject_cast<QDockWidget*>( w );
1207     w = w->parentWidget();
1208   }
1209   return dock;
1210 }
1211
1212 void LightApp_Application::insertDockWindow( const int id, QWidget* wid )
1213 {
1214   if ( !wid )
1215     return;
1216
1217   if ( wid != dockWindow( id ) )
1218     removeDockWindow( id );
1219
1220   myWin.insert( id, wid );
1221
1222   QtxDockWidget* dock = new QtxDockWidget( true, desktop() );
1223   connect( dock, SIGNAL(  destroyed( QObject* ) ), this, SLOT( onWCDestroyed( QObject* ) ) );
1224
1225   dock->setFeatures( QDockWidget::AllDockWidgetFeatures );
1226   dock->setObjectName( QString( "window_%1" ).arg( id ) );
1227   dock->setWidget( wid );
1228
1229   QKeySequence accel = wid->property( "shortcut" ).value<QKeySequence>();
1230   if ( !accel.isEmpty() )
1231     dock->toggleViewAction()->setShortcut( accel );
1232
1233   dock->show();
1234 }
1235
1236 void LightApp_Application::removeDockWindow( const int id )
1237 {
1238   QWidget* wid = dockWindow( id );
1239   if ( !wid )
1240     return;
1241
1242   myWin.remove( id );
1243
1244   QDockWidget* dock = windowDock( wid );
1245   if ( !dock )
1246     return;
1247
1248   dock->setWidget( 0 );
1249   wid->setParent( 0 );
1250   wid->setVisible( false );
1251   delete dock;
1252 }
1253
1254 void LightApp_Application::placeDockWindow( const int id, Qt::DockWidgetArea place )
1255 {
1256   QDockWidget* dock = windowDock( dockWindow( id ) );
1257   if ( dock && desktop() ) {
1258     desktop()->addDockWidget( place, dock );
1259     QtxDockAction* a = qobject_cast<QtxDockAction*>( action( ViewWindowsId ) );
1260     if ( a ) a->update();
1261   }
1262 }
1263
1264 /*!
1265   Gets window.
1266   \param flag - key for window
1267   \param studyId - study id
1268   Flag used how identificator of window in windows list.
1269 */
1270 QWidget* LightApp_Application::getWindow( const int flag, const int )
1271 {
1272   QWidget* wid = dockWindow( flag );
1273   if ( !wid )
1274     insertDockWindow( flag, wid = createWindow( flag ) );
1275
1276   QMap<int, int> winMap;
1277   currentWindows( winMap );
1278   if ( winMap.contains( flag ) )
1279     placeDockWindow( flag, (Qt::DockWidgetArea)winMap[flag] );
1280
1281   return wid;
1282 }
1283
1284 /*!
1285   \return Object Browser
1286 */
1287 SUIT_DataBrowser* LightApp_Application::objectBrowser()
1288 {
1289   return qobject_cast<SUIT_DataBrowser*>( dockWindow( WT_ObjectBrowser ) );
1290 }
1291
1292 /*!
1293   \return Log Window
1294 */
1295 LogWindow* LightApp_Application::logWindow()
1296 {
1297   return qobject_cast<LogWindow*>( dockWindow( WT_LogWindow ) );
1298 }
1299
1300 #ifndef DISABLE_PYCONSOLE
1301 /*!
1302   This returns the python console integrated to the GUI. Depending
1303   when you request the python console, this function could return
1304   null. Then the optional parameter force (default to false) can be
1305   set to force the creation of the python console if it is not done
1306   already. 
1307   \param force - if true, the pythonConsole is created if it does not exist yet
1308   \return Python Console
1309 */
1310 PyConsole_Console* LightApp_Application::pythonConsole(const bool force)
1311 {
1312   QWidget* wid = dockWindow( WT_PyConsole );
1313   if ( !wid && force==true) {
1314     wid = getWindow(WT_PyConsole);
1315   }
1316   return qobject_cast<PyConsole_Console*>( wid );
1317 }
1318 #endif
1319
1320 /*!
1321   Updates object browser and maybe data models
1322   \param updateModels - if it is true, then data models are updated
1323 */
1324 void LightApp_Application::updateObjectBrowser( const bool updateModels )
1325 {
1326   // update existing data models
1327   if ( updateModels )
1328   {
1329     const bool isAutoUpdate = objectBrowser() ? objectBrowser()->autoUpdate() : true;
1330     if ( objectBrowser() )
1331       objectBrowser()->setAutoUpdate( false );
1332
1333     LightApp_Study* study = dynamic_cast<LightApp_Study*>(activeStudy());
1334     if ( study ) {
1335       CAM_Study::ModelList dm_list;
1336       study->dataModels( dm_list );
1337       QListIterator<CAM_DataModel*> it( dm_list );
1338       while ( it.hasNext() ) {
1339         CAM_DataModel* camDM = it.next();
1340         if ( camDM && camDM->inherits( "LightApp_DataModel" ) )
1341           ((LightApp_DataModel*)camDM)->update();
1342       }
1343     }
1344
1345     if( objectBrowser() )
1346       objectBrowser()->setAutoUpdate( isAutoUpdate );
1347   }
1348
1349   if ( objectBrowser() ) {
1350     objectBrowser()->updateGeometry();
1351     objectBrowser()->updateTree( 0, false );
1352   }
1353 }
1354
1355 /*!
1356   \return preferences
1357 */
1358 LightApp_Preferences* LightApp_Application::preferences() const
1359 {
1360   return preferences( false );
1361 }
1362
1363 /*!
1364   \return first view manager of some type
1365   \param vmType - type of view manager
1366   \param create - is it necessary to create view manager in case, when there is no manager of such type
1367 */
1368 SUIT_ViewManager* LightApp_Application::getViewManager( const QString& vmType, const bool create )
1369 {
1370   SUIT_ViewManager* aVM = viewManager( vmType );
1371   SUIT_ViewManager* anActiveVM = CAM_Application::activeViewManager();
1372
1373   if ( anActiveVM && anActiveVM->getType() == vmType )
1374     aVM = anActiveVM;
1375
1376   if ( aVM && create )
1377   {
1378     if ( !aVM->getActiveView() )
1379       aVM->createView();
1380     else
1381       aVM->getActiveView()->setFocus();
1382   }
1383   else if ( create )
1384     aVM = createViewManager( vmType );
1385
1386   return aVM;
1387 }
1388
1389 /*!
1390   Creates view manager of some type
1391   \param vmType - type of view manager
1392 */
1393 SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType )
1394 {
1395   SUIT_ResourceMgr* resMgr = resourceMgr();
1396
1397   SUIT_ViewManager* viewMgr = 0;
1398 #ifndef DISABLE_GLVIEWER
1399   if( vmType == GLViewer_Viewer::Type() )
1400   {
1401     viewMgr = new GLViewer_ViewManager( activeStudy(), desktop() );
1402     new LightApp_GLSelector( (GLViewer_Viewer2d*)viewMgr->getViewModel(), mySelMgr );
1403   }
1404 #endif
1405 #ifndef DISABLE_PLOT2DVIEWER
1406   if( vmType == Plot2d_Viewer::Type() )
1407   {
1408     viewMgr = new Plot2d_ViewManager( activeStudy(), desktop() );
1409     Plot2d_Viewer* vm;
1410 #ifndef DISABLE_SALOMEOBJECT
1411     SPlot2d_Viewer* v = new SPlot2d_Viewer();
1412     vm = v;
1413     new LightApp_Plot2dSelector( v, mySelMgr );
1414 #else
1415     vm = new Plot2d_Viewer();
1416 #endif
1417     viewMgr->setViewModel( vm  );// custom view model, which extends SALOME_View interface
1418     Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( viewMgr->getActiveView() );
1419     if( wnd )
1420     {
1421       Plot2d_ViewFrame* frame = wnd->getViewFrame();
1422       frame->setBackgroundColor( resMgr->colorValue( "Plot2d", "Background", frame->backgroundColor() ) );
1423     }
1424   }
1425 #endif
1426   //#ifndef DISABLE_SUPERVGRAPHVIEWER
1427   //  if( vmType == SUPERVGraph_Viewer::Type() )
1428   //  {
1429   //    viewMgr = new SUPERVGraph_ViewManager( activeStudy(), desktop(), new SUPERVGraph_Viewer() );
1430   //  }
1431   //#endif
1432 #ifndef DISABLE_QXGRAPHVIEWER
1433 //VSR: QxGraph has been replaced by QxScene
1434 //  if( vmType == QxGraph_Viewer::Type() )
1435 //    {
1436 //      viewMgr = new QxGraph_ViewManager( activeStudy(), desktop(), new QxGraph_Viewer() );
1437 //    }
1438   if( vmType == QxScene_Viewer::Type() )
1439   {
1440     viewMgr = new QxScene_ViewManager( activeStudy(), desktop() );
1441     QxScene_Viewer* vm = new QxScene_Viewer();
1442     viewMgr->setViewModel( vm  );
1443     //QxScene_ViewWindow* wnd = dynamic_cast<QxScene_ViewWindow*>( viewMgr->getActiveView() );
1444   }
1445 #endif
1446 #ifndef DISABLE_OCCVIEWER
1447   if( vmType == OCCViewer_Viewer::Type() )
1448   {
1449     viewMgr = new OCCViewer_ViewManager( activeStudy(), desktop() );
1450     OCCViewer_Viewer* vm;
1451 #ifndef DISABLE_SALOMEOBJECT
1452     vm = new SOCC_Viewer();
1453 #else
1454     vm = new OCCViewer_Viewer( true );
1455 #endif
1456     vm->setBackground( OCCViewer_ViewFrame::TOP_LEFT,
1457                        resMgr->backgroundValue( "OCCViewer", "xz_background", vm->background(OCCViewer_ViewFrame::TOP_LEFT) ) );
1458     vm->setBackground( OCCViewer_ViewFrame::TOP_RIGHT,
1459                        resMgr->backgroundValue( "OCCViewer", "yz_background", vm->background(OCCViewer_ViewFrame::TOP_RIGHT) ) );
1460     vm->setBackground( OCCViewer_ViewFrame::BOTTOM_LEFT,
1461                        resMgr->backgroundValue( "OCCViewer", "xy_background", vm->background(OCCViewer_ViewFrame::BOTTOM_LEFT) ) );
1462     vm->setBackground( OCCViewer_ViewFrame::BOTTOM_RIGHT,
1463                        resMgr->backgroundValue( "OCCViewer", "background", vm->background(OCCViewer_ViewFrame::MAIN_VIEW) ) );
1464
1465     vm->setTrihedronSize(  resMgr->doubleValue( "3DViewer", "trihedron_size", vm->trihedronSize() ),
1466                            resMgr->booleanValue( "3DViewer", "relative_size", vm->trihedronRelative() ));
1467     vm->setInteractionStyle( resMgr->integerValue( "3DViewer", "navigation_mode", vm->interactionStyle() ) );
1468     vm->setZoomingStyle( resMgr->integerValue( "3DViewer", "zooming_mode", vm->zoomingStyle() ) );
1469     viewMgr->setViewModel( vm );// custom view model, which extends SALOME_View interface
1470     new LightApp_OCCSelector( (OCCViewer_Viewer*)viewMgr->getViewModel(), mySelMgr );
1471   }
1472 #endif
1473 #ifndef DISABLE_VTKVIEWER
1474 #ifndef DISABLE_SALOMEOBJECT
1475   if ( vmType == SVTK_Viewer::Type() )
1476 #else
1477   if ( vmType == VTKViewer_Viewer::Type() )
1478 #endif
1479   {
1480 #ifndef DISABLE_SALOMEOBJECT
1481     viewMgr = new SVTK_ViewManager( activeStudy(), desktop() );
1482     SVTK_Viewer* vm = dynamic_cast<SVTK_Viewer*>( viewMgr->getViewModel() );
1483     if( vm )
1484     {
1485       vm->setProjectionMode( resMgr->integerValue( "VTKViewer", "projection_mode", vm->projectionMode() ) );
1486       vm->setBackground( resMgr->backgroundValue( "VTKViewer", "background", vm->background() ) );
1487       vm->setTrihedronSize( resMgr->doubleValue( "3DViewer", "trihedron_size", vm->trihedronSize() ),
1488                             resMgr->booleanValue( "3DViewer", "relative_size", vm->trihedronRelative() ) );
1489       vm->setStaticTrihedronVisible( resMgr->booleanValue( "3DViewer", "show_static_trihedron", vm->isStaticTrihedronVisible() ) );
1490       vm->setInteractionStyle( resMgr->integerValue( "3DViewer", "navigation_mode", vm->interactionStyle() ) );
1491       vm->setZoomingStyle( resMgr->integerValue( "3DViewer", "zooming_mode", vm->zoomingStyle() ) );
1492       vm->setDynamicPreSelection( resMgr->booleanValue( "VTKViewer", "dynamic_preselection", vm->dynamicPreSelection() ) );
1493       vm->setIncrementalSpeed( resMgr->integerValue( "VTKViewer", "speed_value", vm->incrementalSpeed() ),
1494                                resMgr->integerValue( "VTKViewer", "speed_mode", vm->incrementalSpeedMode() ) );
1495       vm->setSpacemouseButtons( resMgr->integerValue( "VTKViewer", "spacemouse_func1_btn", vm->spacemouseBtn(1) ),
1496                                 resMgr->integerValue( "VTKViewer", "spacemouse_func2_btn", vm->spacemouseBtn(2) ),
1497                                 resMgr->integerValue( "VTKViewer", "spacemouse_func5_btn", vm->spacemouseBtn(3) ) );
1498       new LightApp_VTKSelector( vm, mySelMgr );
1499     }
1500 #else
1501     viewMgr = new VTKViewer_ViewManager( activeStudy(), desktop() );
1502     VTKViewer_Viewer* vm = dynamic_cast<VTKViewer_Viewer*>( viewMgr->getViewModel() );
1503     if ( vm )
1504       vm->setBackground( resMgr->backgroundValue( "VTKViewer", "background", vm->background() ) );
1505 #endif
1506   }
1507 #endif
1508
1509   if ( !viewMgr )
1510     return 0;
1511
1512   addViewManager( viewMgr );
1513   SUIT_ViewWindow* viewWin = viewMgr->createViewWindow();
1514
1515   if ( viewWin && desktop() ) {
1516     viewWin->resize( (int)( desktop()->width() * 0.6 ), (int)( desktop()->height() * 0.6 ) );
1517     viewWin->setDropDownButtons( resMgr->booleanValue( "viewers", "drop_down_buttons", true ) );
1518   }
1519
1520   return viewMgr;
1521 }
1522
1523 SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType, QWidget* w )
1524 {
1525   SUIT_ResourceMgr* resMgr = resourceMgr();
1526
1527   SUIT_ViewManager* vm = new SUIT_ViewManager( activeStudy(),
1528                                                desktop(),
1529                                                new LightApp_WgViewModel( vmType, w ) );
1530   vm->setTitle( QString( "%1: %M - viewer %V" ).arg( vmType ) );
1531
1532   addViewManager( vm );
1533   SUIT_ViewWindow* vw = vm->createViewWindow();
1534   if ( vw && desktop() ) {
1535     vw->resize( (int)( desktop()->width() * 0.6 ), (int)( desktop()->height() * 0.6 ) );
1536     vw->setDropDownButtons( resMgr->booleanValue( "viewers", "drop_down_buttons", true ) );
1537   }
1538
1539   if ( !vmType.isEmpty() && !myUserWmTypes.contains( vmType ) )
1540     myUserWmTypes << vmType;
1541
1542   return vm;
1543 }
1544
1545 /*!
1546   SLOT: Removes view manager from application
1547 */
1548 void LightApp_Application::onCloseView( SUIT_ViewManager* theVM )
1549 {
1550   removeViewManager( theVM );
1551 }
1552
1553 /*!
1554   Protected SLOT: On study created.
1555   \param theStudy - just created study
1556 */
1557 void LightApp_Application::onStudyCreated( SUIT_Study* theStudy )
1558 {
1559   SUIT_DataObject* aRoot = 0;
1560   if ( theStudy && theStudy->root() )
1561   {
1562     aRoot = theStudy->root();
1563     //aRoot->setName( tr( "DATA_MODELS" ) );
1564   }
1565
1566   getWindow( WT_ObjectBrowser );
1567
1568   loadDockWindowsState();
1569
1570   if ( objectBrowser() )
1571     objectBrowser()->setRoot( aRoot );
1572
1573   activateModule( defaultModule() );
1574
1575   if ( objectBrowser() )
1576     objectBrowser()->openLevels();
1577 }
1578
1579 /*!
1580   Protected SLOT: On study opened.
1581   \param theStudy - just opened  study
1582 */
1583 void LightApp_Application::onStudyOpened( SUIT_Study* theStudy )
1584 {
1585   SUIT_DataObject* aRoot = 0;
1586   if ( theStudy && theStudy->root() )
1587   {
1588     aRoot = theStudy->root();
1589     //aRoot->dump();
1590   }
1591
1592   getWindow( WT_ObjectBrowser );
1593
1594   loadDockWindowsState();
1595
1596   if ( objectBrowser() )
1597     objectBrowser()->setRoot( aRoot );
1598
1599   activateModule( defaultModule() );
1600
1601   if ( objectBrowser() )
1602     objectBrowser()->openLevels();
1603
1604   emit studyOpened();
1605 }
1606
1607 /*!Protected SLOT. On study saved.*/
1608 void LightApp_Application::onStudySaved( SUIT_Study* s )
1609 {
1610   QtxMRUAction* mru = ::qobject_cast<QtxMRUAction*>( action( MRUId ) );
1611   if ( mru && s )
1612       mru->insert( s->studyName() );
1613
1614   emit studySaved();
1615 }
1616
1617 /*!Protected SLOT. On study closed.*/
1618 void LightApp_Application::onStudyClosed( SUIT_Study* s )
1619 {
1620   // stop auto-save timer
1621   myAutoSaveTimer->stop();
1622
1623   // Bug 10396: clear selection
1624   mySelMgr->clearSelected();
1625
1626   // Bug 12944: emit signal only after clear selection
1627   emit studyClosed();
1628
1629   activateModule( "" );
1630 }
1631
1632 /*!Protected SLOT.On desktop activated.*/
1633 void LightApp_Application::onDesktopActivated()
1634 {
1635   CAM_Application::onDesktopActivated();
1636   LightApp_Module* aModule = dynamic_cast<LightApp_Module*>(activeModule());
1637   if(aModule)
1638     aModule->studyActivated();
1639 }
1640
1641 void LightApp_Application::studyOpened( SUIT_Study* s )
1642 {
1643   CAM_Application::studyOpened( s );
1644
1645   updateWindows();
1646   updateViewManagers();
1647 }
1648
1649 void LightApp_Application::studySaved( SUIT_Study* s )
1650 {
1651   CAM_Application::studyOpened( s );
1652   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
1653   if ( aResMgr && activeStudy() ) {
1654     int autoSaveInterval = aResMgr->integerValue( "Study", "auto_save_interval", 0 );
1655     if ( autoSaveInterval > 0 ) myAutoSaveTimer->start( autoSaveInterval*60000 );
1656   }
1657 }
1658
1659 void LightApp_Application::studyCreated( SUIT_Study* s )
1660 {
1661   CAM_Application::studyCreated( s );
1662
1663   updateWindows();
1664   updateViewManagers();
1665 }
1666
1667 /*!Gets file filter.
1668  *\retval QString "(*.bin)"
1669  */
1670 QString LightApp_Application::getFileFilter() const
1671 {
1672   //return "(*.bin)";
1673   // HDF persistence
1674   return "(*.hdf)";
1675 }
1676
1677 /*!
1678   Shows file dialog and return user selected file name
1679 */
1680 QString LightApp_Application::getFileName( bool open, const QString& initial, const QString& filters,
1681                                            const QString& caption, QWidget* parent )
1682 {
1683   if ( !parent )
1684     parent = desktop();
1685   QStringList fls = filters.split( ";;", QString::SkipEmptyParts );
1686   return SUIT_FileDlg::getFileName( parent, initial, fls, caption, open, true );
1687 }
1688
1689 /*! Gets directory*/
1690 QString LightApp_Application::getDirectory( const QString& initial, const QString& caption, QWidget* parent )
1691 {
1692   if ( !parent )
1693     parent = desktop();
1694   return SUIT_FileDlg::getExistingDirectory( parent, initial, caption, true );
1695 }
1696
1697 /*! Get open file names*/
1698 QStringList LightApp_Application::getOpenFileNames( const QString& initial, const QString& filters,
1699                                                     const QString& caption, QWidget* parent )
1700 {
1701   if ( !parent )
1702     parent = desktop();
1703   QStringList fls = filters.split( ";;", QString::SkipEmptyParts );
1704   return SUIT_FileDlg::getOpenFileNames( parent, initial, fls, caption, true );
1705 }
1706
1707 /*!Private SLOT. Update object browser.*/
1708 void LightApp_Application::onRefresh()
1709 {
1710   updateObjectBrowser( true );
1711 }
1712
1713 /*!Private SLOT. Support drag-and-drop operation.*/
1714 void LightApp_Application::onDropped( const QList<SUIT_DataObject*>& objects, SUIT_DataObject* parent, int row, Qt::DropAction action )
1715 {
1716   LightApp_DataObject* parentObj = dynamic_cast<LightApp_DataObject*>( parent );
1717   if ( !parentObj )
1718     return;
1719
1720   LightApp_Module* aModule = dynamic_cast<LightApp_Module*>( parentObj->module() );
1721   if ( aModule )
1722     aModule->dropObjects( objects, parentObj, row, action );
1723 }
1724
1725 /*!Private SLOT. On preferences.*/
1726 void LightApp_Application::onPreferences()
1727 {
1728   showPreferences( activeModule() ? activeModule()->moduleName() : tr( "PREF_CATEGORY_SALOME" ) );
1729 }
1730
1731 /*!Private SLOT. On preferences.*/
1732 void LightApp_Application::showPreferences( const QString& itemText )
1733 {
1734   QApplication::setOverrideCursor( Qt::WaitCursor );
1735
1736   LightApp_PreferencesDlg* prefDlg = new LightApp_PreferencesDlg( preferences( true ), desktop());
1737
1738   QApplication::restoreOverrideCursor();
1739
1740   if ( !prefDlg )
1741     return;
1742
1743   preferences()->activateItem( itemText );
1744
1745   if ( ( prefDlg->exec() == QDialog::Accepted || prefDlg->isSaved() ) &&  resourceMgr() )
1746   {
1747     if ( desktop() )
1748       resourceMgr()->setValue( "desktop", "geometry", desktop()->storeGeometry() );
1749     resourceMgr()->save();
1750
1751     // Update shortcuts
1752     shortcutMgr()->updateShortcuts();
1753   }
1754
1755   delete prefDlg;
1756 }
1757
1758 /*!Protected SLOT. On preferences changed.*/
1759 void LightApp_Application::onPreferenceChanged( QString& modName, QString& section, QString& param )
1760 {
1761   LightApp_Module* sMod = 0;
1762   CAM_Module* mod = module( modName );
1763   if ( mod && mod->inherits( "LightApp_Module" ) )
1764     sMod = (LightApp_Module*)mod;
1765
1766   if ( sMod )
1767     sMod->preferencesChanged( section, param );
1768   else
1769     preferencesChanged( section, param );
1770   // emit signal to allow additional preferences changing processing
1771   emit preferenceChanged( modName, section, param );
1772 }
1773
1774 /*!Remove all windows from study.*/
1775 void LightApp_Application::beforeCloseDoc( SUIT_Study* s )
1776 {
1777   CAM_Application::beforeCloseDoc( s );
1778 }
1779
1780 /*!Update actions.*/
1781 void LightApp_Application::updateActions()
1782 {
1783   updateCommandsStatus();
1784 }
1785
1786 /*!
1787   Creates new study
1788 */
1789 SUIT_Study* LightApp_Application::createNewStudy()
1790 {
1791   LightApp_Application::lastStudyId++;
1792
1793   LightApp_Study* aStudy = new LightApp_Study( this );
1794
1795   // Set up processing of major study-related events
1796   connect( aStudy, SIGNAL( created( SUIT_Study* ) ), this, SLOT( onStudyCreated( SUIT_Study* ) ) );
1797   connect( aStudy, SIGNAL( opened ( SUIT_Study* ) ), this, SLOT( onStudyOpened ( SUIT_Study* ) ) );
1798   connect( aStudy, SIGNAL( saved  ( SUIT_Study* ) ), this, SLOT( onStudySaved  ( SUIT_Study* ) ) );
1799   connect( aStudy, SIGNAL( closed ( SUIT_Study* ) ), this, SLOT( onStudyClosed ( SUIT_Study* ) ) );
1800
1801   return aStudy;
1802 }
1803
1804 /*!
1805   Creates window by flag.
1806   \param flag - identificator of window type
1807 */
1808 QWidget* LightApp_Application::createWindow( const int flag )
1809 {
1810   QWidget* wid = 0;
1811
1812   SUIT_ResourceMgr* resMgr = resourceMgr();
1813
1814   if ( flag == WT_ObjectBrowser )
1815   {
1816     SUIT_DataBrowser* ob = new SUIT_DataBrowser( new LightApp_DataObject(), desktop() );
1817     ob->setSortMenuEnabled( true );
1818     ob->setAutoUpdate( true );
1819     if ( resMgr->hasValue( "ObjectBrowser", "auto_hide_search_tool" ) )
1820       ob->searchTool()->enableAutoHide( resMgr->booleanValue( "ObjectBrowser", "auto_hide_search_tool" ) );
1821
1822     //ob->setAutoOpenLevel( 1 ); // commented by ASV as a fix to bug IPAL10107
1823     ob->setWindowTitle( tr( "OBJECT_BROWSER" ) );
1824     connect( ob, SIGNAL( requestUpdate() ), this, SLOT( onRefresh() ) );
1825
1826     QString EntryCol = QObject::tr( "ENTRY_COLUMN" );
1827     SUIT_AbstractModel* treeModel = dynamic_cast<SUIT_AbstractModel*>( ob->model() );
1828     treeModel->setSearcher( this );
1829     treeModel->registerColumn( 0, EntryCol, LightApp_DataObject::EntryId );
1830     treeModel->setAppropriate( EntryCol, Qtx::Toggled );
1831
1832     // Mantis issue 0020136: Drag&Drop in OB
1833     SUIT_ProxyModel* proxyModel = dynamic_cast<SUIT_ProxyModel*>(treeModel);
1834     if ( proxyModel ) {
1835       connect( proxyModel, SIGNAL( dropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ),
1836                this,       SLOT( onDropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ) );
1837     }
1838
1839     // temporary commented
1840     /*
1841     OB_ListView* ob_list = dynamic_cast<OB_ListView*>( const_cast<QListView*>( ob->listView() ) );
1842     if( ob_list )
1843       ob_list->setColumnMaxWidth( 0, desktop()->width()/4 );
1844
1845     ob->setFilter( new LightApp_OBFilter( selectionMgr() ) );
1846     */
1847
1848     // Create OBSelector
1849     new LightApp_OBSelector( ob, mySelMgr );
1850
1851     ob->treeView()->header()->setResizeMode(SUIT_DataObject::VisibilityId, QHeaderView::Fixed);
1852     ob->treeView()->header()->moveSection(SUIT_DataObject::NameId,SUIT_DataObject::VisibilityId);
1853     ob->treeView()->setColumnWidth(SUIT_DataObject::VisibilityId, VISIBILITY_COLUMN_WIDTH);
1854     ob->setProperty( "shortcut", QKeySequence( "Alt+Shift+O" ) );
1855     wid = ob;
1856     ob->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
1857   }
1858 #ifndef DISABLE_PYCONSOLE
1859   else  if ( flag == WT_PyConsole )
1860   {
1861     PyConsole_Console* pyCons = new PyConsole_EnhConsole( desktop(),new LightApp_PyInterp());
1862     pyCons->setWindowTitle( tr( "PYTHON_CONSOLE" ) );
1863     pyCons->setFont(resourceMgr()->fontValue( "PyConsole", "font" ));
1864     pyCons->setIsShowBanner(resourceMgr()->booleanValue( "PyConsole", "show_banner", true ));
1865     pyCons->setProperty( "shortcut", QKeySequence( "Alt+Shift+P" ) );
1866
1867     wid = pyCons;
1868     pyCons->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
1869   }
1870 #endif
1871   else if ( flag == WT_LogWindow )
1872   {
1873     LogWindow* logWin = new LogWindow( desktop() );
1874     logWin->setWindowTitle( tr( "LOG_WINDOW" ) );
1875     logWin->setProperty( "shortcut", QKeySequence( "Alt+Shift+L" ) );
1876     wid = logWin;
1877     logWin->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
1878   }
1879   return wid;
1880 }
1881
1882 /*!
1883   \return default windows( Object Browser, Python Console )
1884   Adds to map \a aMap.
1885  */
1886 void LightApp_Application::defaultWindows( QMap<int, int>& aMap ) const
1887 {
1888   aMap.insert( WT_ObjectBrowser, Qt::LeftDockWidgetArea );
1889 #ifndef DISABLE_PYCONSOLE
1890   aMap.insert( WT_PyConsole, Qt::BottomDockWidgetArea );
1891 #endif
1892   //  aMap.insert( WT_LogWindow, Qt::DockBottom );
1893 }
1894
1895 /*!Default view managers*/
1896 void LightApp_Application::defaultViewManagers( QStringList& ) const
1897 {
1898   /*!Do nothing.*/
1899 }
1900
1901 /*!
1902   \return preferences.
1903   Create preferences, if \a crt = true.
1904 */
1905 LightApp_Preferences* LightApp_Application::preferences( const bool crt ) const
1906 {
1907   if ( myPrefs )
1908     return myPrefs;
1909
1910   LightApp_Application* that = (LightApp_Application*)this;
1911
1912   bool toCreate = !_prefs_ && crt;
1913   if ( toCreate )
1914   {
1915     _prefs_ = new LightApp_Preferences( resourceMgr() );
1916     that->createPreferences( _prefs_ );
1917   }
1918
1919   that->myPrefs = _prefs_;
1920
1921   connect( myPrefs, SIGNAL( preferenceChanged( QString&, QString&, QString& ) ),
1922            this, SLOT( onPreferenceChanged( QString&, QString&, QString& ) ) );
1923
1924   if ( !crt )
1925     return myPrefs;
1926
1927   SUIT_ResourceMgr* resMgr = resourceMgr();
1928
1929   QList<SUIT_Application*> appList = SUIT_Session::session()->applications();
1930   for ( QList<SUIT_Application*>::iterator appIt = appList.begin(); appIt != appList.end(); ++appIt )
1931   {
1932     LightApp_Application* app = ::qobject_cast<LightApp_Application*>( *appIt );
1933     if ( !app )
1934       continue;
1935
1936     QStringList modNameList;
1937     app->modules( modNameList, false );
1938
1939     QMap<QString, QString> iconMap;
1940     app->moduleIconNames( iconMap );
1941
1942     for ( QStringList::const_iterator it = modNameList.begin(); it != modNameList.end(); ++it )
1943     {
1944       if ( !app->isLibExists( *it ) || _prefs_->hasModule( *it ) )
1945         continue;
1946
1947       int modId = _prefs_->addPreference( *it );
1948       if ( iconMap.contains( *it ) )
1949         _prefs_->setItemIcon( modId, Qtx::scaleIcon( resMgr->loadPixmap( moduleName( *it ), iconMap[*it], false ), 20 ) );
1950     }
1951
1952     ModuleList modList;
1953     app->modules( modList );
1954     QListIterator<CAM_Module*> itr( modList );
1955     while ( itr.hasNext() )
1956     {
1957       LightApp_Module* mod = 0;
1958
1959       CAM_Module* anItem = itr.next();
1960       if ( anItem->inherits( "LightApp_Module" ) )
1961         mod = (LightApp_Module*)anItem;
1962
1963       if ( mod && !_prefs_->hasModule( mod->moduleName() ) )
1964       {
1965         _prefs_->addPreference( mod->moduleName() );
1966         mod->createPreferences();
1967         that->emptyPreferences( mod->moduleName() );
1968       }
1969     }
1970   }
1971   _prefs_->setItemProperty( "info", tr( "PREFERENCES_NOT_LOADED" ) );
1972
1973   return myPrefs;
1974 }
1975
1976 /*!
1977   Adds new module to application
1978 */
1979 void LightApp_Application::moduleAdded( CAM_Module* mod )
1980 {
1981   CAM_Application::moduleAdded( mod );
1982
1983   LightApp_Module* lightMod = 0;
1984   if ( mod && mod->inherits( "LightApp_Module" ) )
1985     lightMod = (LightApp_Module*)mod;
1986
1987   if ( myPrefs && lightMod && !myPrefs->hasModule( lightMod->moduleName() ))
1988   {
1989     myPrefs->addPreference( mod->moduleName() );
1990     lightMod->createPreferences();
1991     emptyPreferences( mod->moduleName() );
1992   }
1993 }
1994
1995 void LightApp_Application::emptyPreferences( const QString& modName )
1996 {
1997   QtxPreferenceItem* item = myPrefs->findItem( modName, true );
1998   if ( !item || !item->isEmpty() )
1999     return;
2000
2001   //  printf( "---------------------> Modify for empty module.\n" );
2002
2003   QtxPagePrefFrameItem* frm = new QtxPagePrefFrameItem( item->title(), item->parentItem() );
2004   frm->setIcon( item->icon() );
2005   frm->setStretch( false );
2006   item->parentItem()->insertItem( frm, item );
2007   new QtxPagePrefLabelItem( Qt::AlignCenter, tr( "PREFERENCES_NOT_SUPPORTED" ).arg( modName ), frm );
2008   delete item;
2009 }
2010
2011 /*!
2012   Create preferences
2013 */
2014 void LightApp_Application::createPreferences( LightApp_Preferences* pref )
2015 {
2016   if ( !pref )
2017     return;
2018
2019   QStringList     aValuesList;
2020   QList<QVariant> anIndicesList;
2021   QIntList        idList;
2022   QIntList        txtList;
2023
2024   // . Top-level "SALOME" preferences group <<start>>
2025   int salomeCat = pref->addPreference( tr( "PREF_CATEGORY_SALOME" ) );
2026   pref->setItemIcon( salomeCat, Qtx::scaleIcon( resourceMgr()->loadPixmap( "LightApp", tr( "APP_DEFAULT_ICO" ), false ), 20 ) );
2027
2028   // .. "General" preferences tab <<start>>
2029   int genTab = pref->addPreference( tr( "PREF_TAB_GENERAL" ), salomeCat );
2030
2031   // ... "Language" group <<start>>
2032   int langGroup = pref->addPreference( tr( "PREF_GROUP_LANGUAGE" ), genTab );
2033   pref->setItemProperty( "columns", 2, langGroup );
2034   // .... -> application language
2035   int curLang = pref->addPreference( tr( "PREF_CURRENT_LANGUAGE" ), langGroup,
2036                                           LightApp_Preferences::Selector, "language", "language" );
2037   QStringList aLangs = SUIT_Session::session()->resourceMgr()->stringValue( "language", "languages", "en" ).split( "," );
2038   QList<QVariant> aIcons;
2039   foreach ( QString aLang, aLangs ) {
2040     aIcons << QPixmap( QString( ":/images/%1" ).arg( aLang ) );
2041   }
2042   pref->setItemProperty( "strings", aLangs, curLang );
2043   pref->setItemProperty( "icons",   aIcons, curLang );
2044   // ... "Language" group <<end>>
2045
2046   // ... "Look and feel" group <<start>>
2047   int lookGroup = pref->addPreference( tr( "PREF_GROUP_LOOK_AND_FEEL" ), genTab );
2048   pref->setItemProperty( "columns", 2, lookGroup );
2049   // .... -> show splash-screen
2050   pref->addPreference( tr( "PREF_SHOW_SPLASH" ), lookGroup, LightApp_Preferences::Bool, "launch", "splash" );
2051   // .... -> opaque resize
2052   pref->addPreference( tr( "PREF_OPAQUE_RESIZE" ), lookGroup, LightApp_Preferences::Bool, "desktop", "opaque_resize" );
2053   // .... -> drop-down buttons 
2054   pref->addPreference( tr( "PREF_DROP_DOWN_BUTTONS" ), lookGroup, LightApp_Preferences::Bool, "viewers", "drop_down_buttons" );
2055   // ... "Look and feel" group <<end>>
2056
2057   // ... "Study properties" group <<start>>
2058   int studyGroup = pref->addPreference( tr( "PREF_GROUP_STUDY" ), genTab );
2059   pref->setItemProperty( "columns", 2, studyGroup );
2060   // .... -> multi-file save
2061   pref->addPreference( tr( "PREF_MULTI_FILE" ), studyGroup, LightApp_Preferences::Bool, "Study", "multi_file" );
2062   // .... -> ascii save mode
2063   pref->addPreference( tr( "PREF_ASCII_FILE" ), studyGroup, LightApp_Preferences::Bool, "Study", "ascii_file" );
2064   // .... -> store windows geometry
2065   pref->addPreference( tr( "PREF_STORE_POS" ),  studyGroup, LightApp_Preferences::Bool, "Study", "store_positions" );
2066   // .... -> auto-save
2067   int autoSaveInterval = pref->addPreference( tr( "PREF_AUTO_SAVE" ),  studyGroup,
2068                                               LightApp_Preferences::IntSpin, "Study", "auto_save_interval" );
2069   pref->setItemProperty( "min",        0, autoSaveInterval );
2070   pref->setItemProperty( "max",     1440, autoSaveInterval );
2071   pref->setItemProperty( "special", tr( "PREF_AUTO_SAVE_DISABLED" ), autoSaveInterval );
2072   // ... "Study properties" group <<end>>
2073
2074   // ... "Help browser" group <<start>>
2075   int extgroup = pref->addPreference( tr( "PREF_GROUP_EXT_BROWSER" ), genTab, LightApp_Preferences::Auto, "ExternalBrowser", "use_external_browser");
2076 #ifdef WIN32
2077   QString platform = "winapplication";
2078 #else
2079   QString platform = "application";
2080 #endif
2081   // .... -> browser application
2082   int apppref = pref->addPreference( tr( "PREF_APP" ), extgroup, LightApp_Preferences::File, "ExternalBrowser", platform );
2083   pref->setItemProperty( "mode", Qtx::PT_OpenFile, apppref );
2084   // .... -> browser parameters
2085   pref->addPreference( tr( "PREF_PARAM" ), extgroup, LightApp_Preferences::String, "ExternalBrowser", "parameters" );
2086   // ... "Help browser" group <<end>>
2087
2088   // ... "Python console properties" group <<start>>
2089   int pythonConsoleGroup = pref->addPreference( tr( "PREF_GROUP_PY_CONSOLE" ), genTab );
2090   // .... -> font
2091   pref->addPreference( tr( "PREF_FONT" ), pythonConsoleGroup, LightApp_Preferences::Font, "PyConsole", "font" );
2092   // .... -> show banner
2093   pref->addPreference( tr( "PREF_SHOW_BANNER" ), pythonConsoleGroup, LightApp_Preferences::Bool, "PyConsole", "show_banner" );
2094   // ... "Python console properties" group <<end>>
2095
2096   // ... "MRU" preferences group <<start>>
2097   int mruGroup = pref->addPreference( tr( "PREF_GROUP_MRU" ), genTab, LightApp_Preferences::Auto, "MRU", "show_mru" );
2098   pref->setItemProperty( "columns", 4, mruGroup );
2099   // number of MRU items
2100   int mruVisCount = pref->addPreference( tr( "PREF_MRU_VISIBLE_COUNT" ), mruGroup, LightApp_Preferences::IntSpin,
2101                                          "MRU", "visible_count" );
2102   pref->setItemProperty( "min", 0,   mruVisCount );
2103   pref->setItemProperty( "max", 100, mruVisCount );
2104   // MRU links type
2105   int mruLinkType = pref->addPreference( tr( "PREF_MRU_LINK_TYPE" ), mruGroup, LightApp_Preferences::Selector,
2106                                          "MRU", "link_type" );
2107   aValuesList.clear();
2108   anIndicesList.clear();
2109   aValuesList   << tr("PREF_MRU_LINK_AUTO") << tr("PREF_MRU_LINK_SHORT") << tr("PREF_MRU_LINK_FULL");
2110   anIndicesList << 0                        << 1                         << 2                       ;
2111   pref->setItemProperty( "strings", aValuesList,   mruLinkType );
2112   pref->setItemProperty( "indexes", anIndicesList, mruLinkType );
2113   // ... "MRU" preferences group <<end>>
2114   // .. "General" preferences tab <<end>>
2115
2116   // .. "3D viewer" group <<start>>
2117   int Viewer3DGroup = pref->addPreference( tr( "PREF_GROUP_3DVIEWER" ), salomeCat );
2118   // ... -> navigation mode
2119   int vtkStyleMode = pref->addPreference( tr( "PREF_NAVIGATION" ), Viewer3DGroup,
2120                                           LightApp_Preferences::Selector, "3DViewer", "navigation_mode" );
2121   aValuesList.clear();
2122   anIndicesList.clear();
2123   aValuesList   << tr("PREF_STANDARD_STYLE") << tr("PREF_KEYFREE_STYLE");
2124   anIndicesList << 0                         << 1;
2125   pref->setItemProperty( "strings", aValuesList,   vtkStyleMode );
2126   pref->setItemProperty( "indexes", anIndicesList, vtkStyleMode );
2127   // ... -> zooming mode
2128   #if OCC_VERSION_LARGE > 0x0603000A // available only with OCC-6.3-sp11 and higher version
2129     int occZoomingStyleMode = pref->addPreference( tr( "PREF_ZOOMING" ), Viewer3DGroup,
2130                                                    LightApp_Preferences::Selector, "3DViewer", "zooming_mode" );
2131     aValuesList.clear();
2132     anIndicesList.clear();
2133     aValuesList   << tr("PREF_ZOOMING_AT_CENTER") << tr("PREF_ZOOMING_AT_CURSOR");
2134     anIndicesList << 0                            << 1;
2135     pref->setItemProperty( "strings", aValuesList,   occZoomingStyleMode );
2136     pref->setItemProperty( "indexes", anIndicesList, occZoomingStyleMode );
2137   #endif
2138   // ... "Trihedron" group <<start>>
2139   int occTriGroup = pref->addPreference( tr( "PREF_TRIHEDRON" ), Viewer3DGroup );
2140   pref->setItemProperty( "columns", 2, occTriGroup );
2141   // .... -> trihedron size
2142   int occTS = pref->addPreference( tr( "PREF_TRIHEDRON_SIZE" ), occTriGroup,
2143                                    LightApp_Preferences::DblSpin, "3DViewer", "trihedron_size" );
2144   pref->setItemProperty( "min", 1.0E-06, occTS );
2145   pref->setItemProperty( "max", 1000, occTS );
2146   // .... -> relative size of trihedron
2147   pref->addPreference( tr( "PREF_RELATIVE_SIZE" ), occTriGroup, LightApp_Preferences::Bool, "3DViewer", "relative_size" );
2148   // .... -> show static trihedron
2149   pref->addPreference( tr( "PREF_SHOW_STATIC_TRIHEDRON" ), occTriGroup, LightApp_Preferences::Bool, "3DViewer", "show_static_trihedron" );
2150   // ... "Trihedron" group <<end>>
2151   // .. "3D viewer" group <<end>>
2152
2153   // .. "OCC viewer" group <<start>>
2154   int occGroup = pref->addPreference( tr( "PREF_GROUP_OCCVIEWER" ), salomeCat );
2155
2156   // ... "Background" group <<start>>
2157   int bgGroup = pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), occGroup );
2158   //  pref->setItemProperty( "columns", 2, bgGroup );
2159   aValuesList.clear();
2160   anIndicesList.clear();
2161   txtList.clear();
2162   QString formats = OCCViewer_Viewer::backgroundData( aValuesList, idList, txtList );
2163   foreach( int gid, idList ) anIndicesList << gid;
2164   // .... -> 3D viewer background
2165   int bgId = pref->addPreference( tr( "PREF_3DVIEWER_BACKGROUND" ), bgGroup,
2166                                   LightApp_Preferences::Background, "OCCViewer", "background" );
2167   pref->setItemProperty( "gradient_names", aValuesList, bgId );
2168   pref->setItemProperty( "gradient_ids", anIndicesList, bgId );
2169   pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId );
2170   pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId );
2171   pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId );
2172   pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId );
2173   pref->setItemProperty( "custom_enabled", false, bgId );
2174   pref->setItemProperty( "image_formats", formats, bgId );
2175   // .... -> XZ viewer background
2176   bgId = pref->addPreference( tr( "PREF_XZVIEWER_BACKGROUND" ), bgGroup,
2177                               LightApp_Preferences::Background, "OCCViewer", "xz_background" );
2178   pref->setItemProperty( "gradient_names", aValuesList, bgId );
2179   pref->setItemProperty( "gradient_ids", anIndicesList, bgId );
2180   pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId );
2181   pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId );
2182   pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId );
2183   pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId );
2184   pref->setItemProperty( "custom_enabled", false, bgId );
2185   pref->setItemProperty( "image_formats", formats, bgId );
2186   // .... -> YZ viewer background
2187   bgId = pref->addPreference( tr( "PREF_YZVIEWER_BACKGROUND" ), bgGroup,
2188                               LightApp_Preferences::Background, "OCCViewer", "yz_background" );
2189   pref->setItemProperty( "gradient_names", aValuesList, bgId );
2190   pref->setItemProperty( "gradient_ids", anIndicesList, bgId );
2191   pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId );
2192   pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId );
2193   pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId );
2194   pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId );
2195   pref->setItemProperty( "custom_enabled", false, bgId );
2196   pref->setItemProperty( "image_formats", formats, bgId );
2197   // .... -> XY viewer background
2198   bgId = pref->addPreference( tr( "PREF_XYVIEWER_BACKGROUND" ), bgGroup,
2199                               LightApp_Preferences::Background, "OCCViewer", "xy_background" );
2200   pref->setItemProperty( "gradient_names", aValuesList, bgId );
2201   pref->setItemProperty( "gradient_ids", anIndicesList, bgId );
2202   pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId );
2203   pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId );
2204   pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId );
2205   pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId );
2206   pref->setItemProperty( "custom_enabled", false, bgId );
2207   pref->setItemProperty( "image_formats", formats, bgId );
2208   // ... "Background" group <<end>>
2209
2210   // ... -> empty frame (for layout) <<start>>
2211   int occGen = pref->addPreference( "", occGroup, LightApp_Preferences::Frame );
2212   pref->setItemProperty( "margin",  0, occGen );
2213   pref->setItemProperty( "columns", 2, occGen );
2214   // ... -> empty frame (for layout) <<end>>
2215   // .. "OCC viewer" group <<end>>
2216
2217   // .. "VTK viewer" group <<start>>
2218   int vtkGroup = pref->addPreference( tr( "PREF_GROUP_VTKVIEWER" ), salomeCat ); //viewTab
2219
2220   // ... -> empty frame (for layout) <<start>>
2221   int vtkGen = pref->addPreference( "", vtkGroup, LightApp_Preferences::Frame );
2222   //pref->setItemProperty( "columns", 2, vtkGen );
2223   // .... -> projection mode
2224   int vtkProjMode = pref->addPreference( tr( "PREF_PROJECTION_MODE" ), vtkGen,
2225                                          LightApp_Preferences::Selector, "VTKViewer", "projection_mode" );
2226   aValuesList.clear();
2227   anIndicesList.clear();
2228   aValuesList   << tr("PREF_ORTHOGRAPHIC") << tr("PREF_PERSPECTIVE");
2229   anIndicesList << 0                       << 1;
2230   pref->setItemProperty( "strings", aValuesList,   vtkProjMode );
2231   pref->setItemProperty( "indexes", anIndicesList, vtkProjMode );
2232   // .... -> background
2233   aValuesList.clear();
2234   anIndicesList.clear();
2235   txtList.clear();
2236   formats = SVTK_Viewer::backgroundData( aValuesList, idList, txtList );
2237   foreach( int gid, idList ) anIndicesList << gid;
2238   bgId = pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), vtkGen,
2239                               LightApp_Preferences::Background, "VTKViewer", "background" );
2240   pref->setItemProperty( "gradient_names", aValuesList, bgId );
2241   pref->setItemProperty( "gradient_ids", anIndicesList, bgId );
2242   pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId );
2243   pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId );
2244   pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId );
2245   pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId );
2246   pref->setItemProperty( "custom_enabled", false, bgId );
2247   pref->setItemProperty( "image_formats", formats, bgId );
2248   // .... -> speed increment
2249   int vtkSpeed = pref->addPreference( tr( "PREF_INCREMENTAL_SPEED" ), vtkGen,
2250                                       LightApp_Preferences::IntSpin, "VTKViewer", "speed_value" );
2251   pref->setItemProperty( "min", 1, vtkSpeed );
2252   pref->setItemProperty( "max", 1000, vtkSpeed );
2253   // .... -> speed mode
2254   int vtkSpeedMode = pref->addPreference( tr( "PREF_INCREMENTAL_SPEED_MODE" ), vtkGen,
2255                                           LightApp_Preferences::Selector, "VTKViewer", "speed_mode" );
2256   aValuesList.clear();
2257   anIndicesList.clear();
2258   aValuesList   << tr("PREF_ARITHMETIC") << tr("PREF_GEOMETRICAL");
2259   anIndicesList << 0                     << 1;
2260   pref->setItemProperty( "strings", aValuesList,   vtkSpeedMode );
2261   pref->setItemProperty( "indexes", anIndicesList, vtkSpeedMode );
2262   // .... -> dynamic pre-selection
2263   pref->addPreference( tr( "PREF_DYNAMIC_PRESELECTION" ),  vtkGen, LightApp_Preferences::Bool, "VTKViewer", "dynamic_preselection" );
2264   // ... -> empty frame (for layout) <<end>>
2265
2266   // ... space mouse sub-group <<start>>
2267   int vtkSM = pref->addPreference( tr( "PREF_FRAME_SPACEMOUSE" ), vtkGroup, LightApp_Preferences::GroupBox );
2268   //pref->setItemProperty( "columns", 2, vtkSM );
2269   // .... -> decrease speed increment
2270   int spacemousePref1 = pref->addPreference( tr( "PREF_SPACEMOUSE_FUNC_1" ), vtkSM,
2271                                              LightApp_Preferences::Selector, "VTKViewer",
2272                                              "spacemouse_func1_btn" );
2273   // .... -> increase speed increment
2274   int spacemousePref2 = pref->addPreference( tr( "PREF_SPACEMOUSE_FUNC_2" ), vtkSM,
2275                                              LightApp_Preferences::Selector, "VTKViewer",
2276                                              "spacemouse_func2_btn" );
2277   // .... -> dominant / combined switch  
2278   int spacemousePref3 = pref->addPreference( tr( "PREF_SPACEMOUSE_FUNC_3" ), vtkSM,
2279                                              LightApp_Preferences::Selector, "VTKViewer",
2280                                              "spacemouse_func5_btn" ); //
2281   aValuesList.clear();
2282   anIndicesList.clear();
2283   aValuesList << tr( "PREF_SPACEMOUSE_BTN_1" )  << tr( "PREF_SPACEMOUSE_BTN_2" ) << tr( "PREF_SPACEMOUSE_BTN_3" );
2284   aValuesList << tr( "PREF_SPACEMOUSE_BTN_4" )  << tr( "PREF_SPACEMOUSE_BTN_5" ) << tr( "PREF_SPACEMOUSE_BTN_6" );
2285   aValuesList << tr( "PREF_SPACEMOUSE_BTN_7" )  << tr( "PREF_SPACEMOUSE_BTN_8" ) << tr( "PREF_SPACEMOUSE_BTN_*" );
2286   aValuesList << tr( "PREF_SPACEMOUSE_BTN_10" ) << tr( "PREF_SPACEMOUSE_BTN_11" );
2287   anIndicesList << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10 << 11;
2288   pref->setItemProperty( "strings", aValuesList,   spacemousePref1 );
2289   pref->setItemProperty( "indexes", anIndicesList, spacemousePref1 );
2290   pref->setItemProperty( "strings", aValuesList,   spacemousePref2 );
2291   pref->setItemProperty( "indexes", anIndicesList, spacemousePref2 );
2292   pref->setItemProperty( "strings", aValuesList,   spacemousePref3 );
2293   pref->setItemProperty( "indexes", anIndicesList, spacemousePref3 );
2294   // ... space mouse sub-group <<end>>
2295
2296   // ... avi recording sub-group <<start>>
2297   int vtkRec = pref->addPreference( tr( "PREF_FRAME_RECORDING" ), vtkGroup, LightApp_Preferences::GroupBox );
2298   pref->setItemProperty( "columns", 2, vtkRec );
2299   // .... -> recording mode
2300   int modePref = pref->addPreference( tr( "PREF_RECORDING_MODE" ), vtkRec,
2301                                       LightApp_Preferences::Selector, "VTKViewer", "recorder_mode" );
2302   aValuesList.clear();
2303   anIndicesList.clear();
2304   aValuesList   << tr( "PREF_SKIPPED_FRAMES" ) << tr( "PREF_ALL_DISLPAYED_FRAMES" );
2305   anIndicesList << 0                           << 1;
2306   pref->setItemProperty( "strings", aValuesList,   modePref );
2307   pref->setItemProperty( "indexes", anIndicesList, modePref );
2308   // .... -> fps
2309   int fpsPref = pref->addPreference( tr( "PREF_FPS" ), vtkRec,
2310                                      LightApp_Preferences::DblSpin, "VTKViewer", "recorder_fps" );
2311   pref->setItemProperty( "min", 0.1, fpsPref );
2312   pref->setItemProperty( "max", 100, fpsPref );
2313   // .... -> quality
2314   int qualityPref = pref->addPreference( tr( "PREF_QUALITY" ), vtkRec,
2315                                          LightApp_Preferences::IntSpin, "VTKViewer", "recorder_quality" );
2316   pref->setItemProperty( "min", 1, qualityPref );
2317   pref->setItemProperty( "max", 100, qualityPref );
2318   // .... -> progressive mode
2319   pref->addPreference( tr( "PREF_PROGRESSIVE" ), vtkRec,
2320                        LightApp_Preferences::Bool, "VTKViewer", "recorder_progressive" );
2321   // ... avi recording sub-group <<end>>
2322
2323   // ... group names sub-group <<start>>
2324   int vtkGN = pref->addPreference( tr( "PREF_FRAME_GROUP_NAMES" ), vtkGroup,
2325                                    LightApp_Preferences::GroupBox, "VTKViewer", "show_group_names" );
2326   pref->setItemProperty( "columns", 2, vtkGN );
2327   // .... -> text color
2328   pref->addPreference( tr(  "PREF_GROUP_NAMES_TEXT_COLOR" ), vtkGN,
2329                        LightApp_Preferences::Color, "VTKViewer", "group_names_text_color" );
2330   // .... -> transparency
2331   int transPref = pref->addPreference( tr( "PREF_GROUP_NAMES_TRANSPARENCY" ), vtkGN,
2332                                        LightApp_Preferences::DblSpin, "VTKViewer", "group_names_transparency" );
2333   pref->setItemProperty( "min", 0.0, transPref );
2334   pref->setItemProperty( "max", 1.0, transPref );
2335   pref->setItemProperty( "step", 0.1, transPref );
2336   // ... -> group names sub-group <<end>>
2337   // .. "VTK viewer" group <<end>>
2338
2339   // .. "Plot2d viewer" group <<start>>
2340   int plot2dGroup = pref->addPreference( tr( "PREF_GROUP_PLOT2DVIEWER" ), salomeCat ); //viewTab
2341   //pref->setItemProperty( "columns", 2, plot2dGroup );
2342
2343   // ... -> show legend
2344   pref->addPreference( tr( "PREF_SHOW_LEGEND" ), plot2dGroup,
2345                        LightApp_Preferences::Bool, "Plot2d", "ShowLegend" );
2346   // ... -> legend position
2347   int legendPosition = pref->addPreference( tr( "PREF_LEGEND_POSITION" ), plot2dGroup,
2348                                             LightApp_Preferences::Selector, "Plot2d", "LegendPos" );
2349   aValuesList.clear();
2350   anIndicesList.clear();
2351   aValuesList   << tr("PREF_LEFT") << tr("PREF_RIGHT") << tr("PREF_TOP") << tr("PREF_BOTTOM");
2352   anIndicesList << 0               << 1                << 2              << 3                ;
2353   pref->setItemProperty( "strings", aValuesList,   legendPosition );
2354   pref->setItemProperty( "indexes", anIndicesList, legendPosition );
2355   // ... -> legend font
2356   pref->addPreference( tr( "PREF_LEGEND_FONT" ), plot2dGroup, LightApp_Preferences::Font, "Plot2d", "LegendFont" );
2357   // ... -> curve type
2358   int curveType = pref->addPreference( tr( "PREF_CURVE_TYPE" ), plot2dGroup,
2359                                        LightApp_Preferences::Selector, "Plot2d", "CurveType" );
2360   aValuesList.clear();
2361   anIndicesList.clear();
2362   aValuesList   << tr("PREF_POINTS") << tr("PREF_LINES") << tr("PREF_SPLINE");
2363   anIndicesList << 0                 << 1                << 2                ;
2364   pref->setItemProperty( "strings", aValuesList,   curveType );
2365   pref->setItemProperty( "indexes", anIndicesList, curveType );
2366   // ... -> marker size
2367   int markerSize = pref->addPreference( tr( "PREF_MARKER_SIZE" ), plot2dGroup,
2368                                         LightApp_Preferences::IntSpin, "Plot2d", "MarkerSize" );
2369   pref->setItemProperty( "min", 0, markerSize );
2370   pref->setItemProperty( "max", 100, markerSize );
2371   // ... -> horizontal scaling mode
2372   int horScale = pref->addPreference( tr( "PREF_HOR_AXIS_SCALE" ), plot2dGroup,
2373                                       LightApp_Preferences::Selector, "Plot2d", "HorScaleMode" );
2374   aValuesList.clear();
2375   anIndicesList.clear();
2376   aValuesList   << tr("PREF_LINEAR") << tr("PREF_LOGARITHMIC");
2377   anIndicesList << 0                 << 1                     ;
2378   pref->setItemProperty( "strings", aValuesList,   horScale );
2379   pref->setItemProperty( "indexes", anIndicesList, horScale );
2380   // ... -> vertical scaling mode
2381   int verScale = pref->addPreference( tr( "PREF_VERT_AXIS_SCALE" ), plot2dGroup,
2382                                       LightApp_Preferences::Selector, "Plot2d", "VerScaleMode" );
2383   pref->setItemProperty( "strings", aValuesList,   verScale );
2384   pref->setItemProperty( "indexes", anIndicesList, verScale );
2385   // ... -> background
2386   pref->addPreference( tr( "PREF_VIEWER_BACKGROUND_COLOR" ), plot2dGroup,
2387                        LightApp_Preferences::Color, "Plot2d", "Background" );
2388   // ... -> font color
2389   pref->addPreference( tr( "PREF_FONT_COLOR" ), plot2dGroup, LightApp_Preferences::Color, "Plot2d", "LegendFontColor" );
2390   // ... -> selection font color
2391   pref->addPreference( tr( "PREF_SELECTED_FONT_COLOR" ), plot2dGroup, LightApp_Preferences::Color, "Plot2d", "SelectedLegendFontColor" );
2392   // ... -> selection color
2393   pref->addPreference( tr( "PREF_VIEWER_SELECTION" ), plot2dGroup,
2394                        LightApp_Preferences::Color, "Plot2d", "SelectionColor" );
2395   // ... -> errors/deviation colot
2396   pref->addPreference( tr( "PREF_DEVIATION_COLOR" ), plot2dGroup,
2397                        LightApp_Preferences::Color, "Plot2d", "DeviationMarkerColor" );
2398   // ... -> deviation markers line size
2399   int deviationMarkerLw = pref->addPreference( tr( "PREF_DEVIATION_MARKER_LW" ), plot2dGroup,
2400                                         LightApp_Preferences::IntSpin, "Plot2d", "DeviationMarkerLineWidth" );
2401   pref->setItemProperty( "min", 1, deviationMarkerLw );
2402   pref->setItemProperty( "max", 5, deviationMarkerLw );
2403   // ... -> deviation markers tick mark size
2404   int deviationMarkerTs = pref->addPreference( tr( "PREF_DEVIATION_MARKER_TS" ), plot2dGroup,
2405                                         LightApp_Preferences::IntSpin, "Plot2d", "DeviationMarkerTickSize" );
2406   pref->setItemProperty( "min", 1, deviationMarkerTs );
2407   pref->setItemProperty( "max", 5, deviationMarkerTs );
2408   // .. "Plot2d viewer" group <<end>>
2409
2410   // .. "Directories" preferences tab <<start>>
2411   int dirTab = pref->addPreference( tr( "PREF_TAB_DIRECTORIES" ), salomeCat );
2412   // ... --> quick directories list
2413   int dirGroup = pref->addPreference( tr( "PREF_GROUP_DIRECTORIES" ), dirTab );
2414   pref->addPreference( tr( "" ), dirGroup,
2415                        LightApp_Preferences::DirList, "FileDlg", "QuickDirList" );
2416   // .. "Directories" preferences tab <<end>>
2417
2418   // .. "Object browser" preferences tab <<start>>
2419   int obTab = pref->addPreference( tr( "PREF_TAB_OBJBROWSER" ), salomeCat );
2420
2421   // ... "Search tool" group <<start>>
2422   int stGroup = pref->addPreference( tr( "PREF_OBJ_BROWSER_SEARCH_TOOL" ), obTab );
2423   // .... --> auto-hide
2424   pref->addPreference( tr( "PREF_AUTO_HIDE_SEARCH_TOOL" ), stGroup, LightApp_Preferences::Bool,
2425                        "ObjectBrowser", "auto_hide_search_tool" );
2426   // ... "Search tool" group <<end>>
2427
2428   // ... "Object browser settings" group <<start>>
2429   int objSetGroup = pref->addPreference( tr( "PREF_GROUP_LOOK_AND_FEEL" ), obTab );
2430   pref->setItemProperty( "columns", 2, objSetGroup );
2431   // .... -> auto size first column
2432   pref->addPreference( tr( "PREF_AUTO_SIZE_FIRST" ), objSetGroup, LightApp_Preferences::Bool,
2433                        "ObjectBrowser", "auto_size_first" );
2434   // .... -> auto size other columns
2435   pref->addPreference( tr( "PREF_AUTO_SIZE" ), objSetGroup, LightApp_Preferences::Bool,
2436                        "ObjectBrowser", "auto_size" );
2437   // .... -> resize columns on expand item
2438   pref->addPreference( tr( "PREF_RESIZE_ON_EXPAND_ITEM" ), objSetGroup, LightApp_Preferences::Bool,
2439                        "ObjectBrowser", "resize_on_expand_item" );
2440   // .... -> browse to published object
2441   int browsePublished = pref->addPreference( tr( "PREF_BROWSE_TO_THE_PUBLISHED_OBJECT" ), objSetGroup, LightApp_Preferences::Selector,
2442                                              "ObjectBrowser", "browse_published_object" );
2443   aValuesList.clear();
2444   anIndicesList.clear();
2445   aValuesList << tr( "PREF_BROWSE_NEVER" ) << tr( "PREF_BROWSE_AFTER_APPLY_AND_CLOSE_ONLY" ) << tr( "PREF_BROWSE_ALWAYS" );
2446   anIndicesList << BP_Never << BP_ApplyAndClose << BP_Always;
2447   pref->setItemProperty( "strings", aValuesList,   browsePublished );
2448   pref->setItemProperty( "indexes", anIndicesList, browsePublished );
2449   // ... "Object browser settings" group <<end>>
2450   // .. "Object browser" preferences tab <<end>>
2451
2452   // .. "Shortcuts" preferences tab <<start>>
2453   int shortcutTab = pref->addPreference( tr( "PREF_TAB_SHORTCUTS" ), salomeCat );
2454   // ... "Shortcuts settings" group <<start>>
2455   int shortcutGroup = pref->addPreference( tr( "PREF_GROUP_SHORTCUTS" ), shortcutTab );
2456   pref->addPreference( tr( "" ), shortcutGroup,
2457                        LightApp_Preferences::ShortcutTree, "shortcuts" );
2458   // ... "Shortcuts settings" group <<end>>
2459   // .. "Shortcuts" preferences tab <<end>>
2460   // . Top-level "SALOME" preferences group <<end>>
2461
2462   pref->retrieve();
2463 }
2464
2465 /*!
2466   Changes appearance of application according to changed preferences
2467   \param sec - section
2468   \param param - name of changed parameter
2469 */
2470 void LightApp_Application::preferencesChanged( const QString& sec, const QString& param )
2471 {
2472   SUIT_ResourceMgr* resMgr = resourceMgr();
2473   if ( !resMgr )
2474     return;
2475
2476   if ( sec == "viewers" && param == "drop_down_buttons" )
2477   {
2478     ViewManagerList vmlist = viewManagers();
2479     foreach( SUIT_ViewManager* vm, vmlist )
2480     {
2481       QVector<SUIT_ViewWindow*> vwlist = vm->getViews();
2482       foreach( SUIT_ViewWindow* vw, vwlist )
2483         if ( vw ) vw->setDropDownButtons( resMgr->booleanValue( "viewers", "drop_down_buttons", true ) );
2484     }
2485   }
2486
2487   if ( sec == QString( "3DViewer" ) && (param == QString( "trihedron_size" ) || param == QString( "relative_size" )))
2488   {
2489     double sz = resMgr->doubleValue( sec, "trihedron_size", -1 );
2490     bool relative = resMgr->booleanValue( sec, "relative_size", true );
2491     QList<SUIT_ViewManager*> lst;
2492 #ifndef DISABLE_OCCVIEWER
2493     viewManagers( OCCViewer_Viewer::Type(), lst );
2494     QListIterator<SUIT_ViewManager*> itOCC( lst );
2495     while ( itOCC.hasNext() && sz >= 0 )
2496     {
2497       SUIT_ViewModel* vm = itOCC.next()->getViewModel();
2498       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
2499         continue;
2500
2501       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
2502       occVM->setTrihedronSize( sz, relative );
2503       occVM->getAISContext()->UpdateCurrentViewer();
2504     }
2505 #endif
2506 #ifndef DISABLE_VTKVIEWER
2507 #ifndef DISABLE_SALOMEOBJECT
2508     viewManagers( SVTK_Viewer::Type(), lst );
2509     QListIterator<SUIT_ViewManager*> itVTK( lst );
2510     while ( itVTK.hasNext() && sz >= 0 )
2511     {
2512       SUIT_ViewModel* vm = itVTK.next()->getViewModel();
2513       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
2514         continue;
2515
2516       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
2517       if( vtkVM )
2518       {
2519         vtkVM->setTrihedronSize( sz, relative );
2520         vtkVM->Repaint();
2521       }
2522     }
2523 #endif
2524 #endif
2525   }
2526
2527   if ( sec == QString( "3DViewer" ) && param == QString( "show_static_trihedron" ) )
2528   {
2529     bool isVisible = resMgr->booleanValue( "3DViewer", "show_static_trihedron", true );
2530     QList<SUIT_ViewManager*> lst;
2531 #ifndef DISABLE_OCCVIEWER
2532     viewManagers( OCCViewer_Viewer::Type(), lst );
2533     QListIterator<SUIT_ViewManager*> itOCC( lst );
2534     while ( itOCC.hasNext() )
2535     {
2536       SUIT_ViewModel* vm = itOCC.next()->getViewModel();
2537       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
2538         continue;
2539
2540       OCCViewer_Viewer* occVM = dynamic_cast<OCCViewer_Viewer*>( vm );
2541       if( occVM )
2542       {
2543         occVM->setStaticTrihedronDisplayed( isVisible );
2544       }
2545     }
2546 #endif
2547 #ifndef DISABLE_VTKVIEWER
2548 #ifndef DISABLE_SALOMEOBJECT
2549     viewManagers( SVTK_Viewer::Type(), lst );
2550     QListIterator<SUIT_ViewManager*> itVTK( lst );
2551     while ( itVTK.hasNext() )
2552     {
2553       SUIT_ViewModel* vm = itVTK.next()->getViewModel();
2554       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
2555         continue;
2556
2557       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
2558       if( vtkVM )
2559       {
2560         vtkVM->setStaticTrihedronVisible( isVisible );
2561         vtkVM->Repaint();
2562       }
2563     }
2564 #endif
2565 #endif
2566   }
2567
2568   if ( sec == QString( "3DViewer" ) && param == QString( "navigation_mode" ) )
2569   {
2570     int mode = resMgr->integerValue( "3DViewer", "navigation_mode", 0 );
2571     QList<SUIT_ViewManager*> lst;
2572 #ifndef DISABLE_OCCVIEWER
2573     viewManagers( OCCViewer_Viewer::Type(), lst );
2574     QListIterator<SUIT_ViewManager*> itOCC( lst );
2575     while ( itOCC.hasNext() )
2576     {
2577       SUIT_ViewModel* vm = itOCC.next()->getViewModel();
2578       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
2579         continue;
2580
2581       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
2582       occVM->setInteractionStyle( mode );
2583     }
2584 #endif
2585 #ifndef DISABLE_VTKVIEWER
2586 #ifndef DISABLE_SALOMEOBJECT
2587     viewManagers( SVTK_Viewer::Type(), lst );
2588     QListIterator<SUIT_ViewManager*> itVTK( lst );
2589     while ( itVTK.hasNext() )
2590     {
2591       SUIT_ViewModel* vm = itVTK.next()->getViewModel();
2592       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
2593         continue;
2594
2595       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
2596       if( vtkVM ) vtkVM->setInteractionStyle( mode );
2597     }
2598 #endif
2599 #endif
2600   }
2601
2602   if ( sec == QString( "3DViewer" ) && param == QString( "zooming_mode" ) )
2603   {
2604     int mode = resMgr->integerValue( "3DViewer", "zooming_mode", 0 );
2605     QList<SUIT_ViewManager*> lst;
2606 #ifndef DISABLE_OCCVIEWER
2607     viewManagers( OCCViewer_Viewer::Type(), lst );
2608     QListIterator<SUIT_ViewManager*> itOCC( lst );
2609     while ( itOCC.hasNext() )
2610     {
2611       SUIT_ViewModel* vm = itOCC.next()->getViewModel();
2612       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
2613         continue;
2614
2615       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
2616       occVM->setZoomingStyle( mode );
2617     }
2618 #endif
2619 #ifndef DISABLE_VTKVIEWER
2620 #ifndef DISABLE_SALOMEOBJECT
2621     viewManagers( SVTK_Viewer::Type(), lst );
2622     QListIterator<SUIT_ViewManager*> itVTK( lst );
2623     while ( itVTK.hasNext() )
2624     {
2625       SUIT_ViewModel* vm = itVTK.next()->getViewModel();
2626       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
2627         continue;
2628
2629       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
2630       if( vtkVM ) vtkVM->setZoomingStyle( mode );
2631     }
2632 #endif
2633 #endif
2634   }
2635
2636 #ifndef DISABLE_VTKVIEWER
2637   if ( sec == QString( "VTKViewer" ) && (param == QString( "speed_value" ) || param == QString( "speed_mode" )) )
2638   {
2639     int speed = resMgr->integerValue( "VTKViewer", "speed_value", 10 );
2640     int mode = resMgr->integerValue( "VTKViewer", "speed_mode", 0 );
2641     QList<SUIT_ViewManager*> lst;
2642 #ifndef DISABLE_SALOMEOBJECT
2643     viewManagers( SVTK_Viewer::Type(), lst );
2644     QListIterator<SUIT_ViewManager*> it( lst );
2645     while ( it.hasNext() )
2646     {
2647       SUIT_ViewModel* vm = it.next()->getViewModel();
2648       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
2649         continue;
2650
2651       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
2652       if( vtkVM ) vtkVM->setIncrementalSpeed( speed, mode );
2653     }
2654 #endif
2655   }
2656 #endif
2657
2658 #ifndef DISABLE_VTKVIEWER
2659   if ( sec == QString( "VTKViewer" ) && param == QString( "projection_mode" ) )
2660   {
2661     int mode = resMgr->integerValue( "VTKViewer", "projection_mode", 0 );
2662     QList<SUIT_ViewManager*> lst;
2663 #ifndef DISABLE_SALOMEOBJECT
2664     viewManagers( SVTK_Viewer::Type(), lst );
2665     QListIterator<SUIT_ViewManager*> it( lst );
2666     while ( it.hasNext() )
2667     {
2668       SUIT_ViewModel* vm = it.next()->getViewModel();
2669       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
2670         continue;
2671
2672       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
2673       if( vtkVM ) vtkVM->setProjectionMode( mode );
2674     }
2675 #endif
2676   }
2677 #endif
2678
2679 #ifndef DISABLE_VTKVIEWER
2680   if ( sec == QString( "VTKViewer" ) && param == QString( "dynamic_preselection" ) )
2681   {
2682     bool mode = resMgr->booleanValue( "VTKViewer", "dynamic_preselection", true );
2683     QList<SUIT_ViewManager*> lst;
2684 #ifndef DISABLE_SALOMEOBJECT
2685     viewManagers( SVTK_Viewer::Type(), lst );
2686     QListIterator<SUIT_ViewManager*> it( lst );
2687     while ( it.hasNext() )
2688     {
2689       SUIT_ViewModel* vm = it.next()->getViewModel();
2690       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
2691         continue;
2692
2693       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
2694       if( vtkVM ) vtkVM->setDynamicPreSelection( mode );
2695     }
2696 #endif
2697   }
2698 #endif
2699
2700 #ifndef DISABLE_VTKVIEWER
2701   if ( sec == QString( "VTKViewer" ) && (param == QString( "spacemouse_func1_btn" ) ||
2702                                          param == QString( "spacemouse_func2_btn" ) ||
2703                                          param == QString( "spacemouse_func5_btn" ) ) )
2704   {
2705     int btn1 = resMgr->integerValue( "VTKViewer", "spacemouse_func1_btn", 1 );
2706     int btn2 = resMgr->integerValue( "VTKViewer", "spacemouse_func2_btn", 2 );
2707     int btn3 = resMgr->integerValue( "VTKViewer", "spacemouse_func5_btn", 9 );
2708     QList<SUIT_ViewManager*> lst;
2709 #ifndef DISABLE_SALOMEOBJECT
2710     viewManagers( SVTK_Viewer::Type(), lst );
2711     QListIterator<SUIT_ViewManager*> it( lst );
2712     while ( it.hasNext() )
2713     {
2714       SUIT_ViewModel* vm = it.next()->getViewModel();
2715       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
2716         continue;
2717
2718       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
2719       if( vtkVM ) vtkVM->setSpacemouseButtons( btn1, btn2, btn3 );
2720     }
2721 #endif
2722   }
2723 #endif
2724   if( sec=="ObjectBrowser" )
2725   {
2726     SUIT_DataBrowser* ob = objectBrowser();
2727     if ( !ob )
2728       return;
2729
2730     if ( param=="auto_size_first" )
2731     {
2732       bool autoSizeFirst = resMgr->booleanValue( "ObjectBrowser", "auto_size_first", true );
2733       ob->setAutoSizeFirstColumn( autoSizeFirst );
2734       if ( autoSizeFirst )
2735         ob->adjustFirstColumnWidth();
2736     }
2737     else if ( param=="auto_size" ) {
2738       bool autoSize = resMgr->booleanValue( "ObjectBrowser", "auto_size", false );
2739       ob->setAutoSizeColumns(autoSize);
2740       if ( autoSize )
2741         ob->adjustColumnsWidth();
2742     }
2743     else if ( param=="resize_on_expand_item" ) {
2744       bool resizeOnExpandItem = resMgr->booleanValue( "ObjectBrowser", "resize_on_expand_item", false );
2745       ob->setResizeOnExpandItem(resizeOnExpandItem);
2746     }
2747     else if ( param == "auto_hide_search_tool" ) {
2748       ob->searchTool()->enableAutoHide( resMgr->booleanValue( "ObjectBrowser", "auto_hide_search_tool" ) );
2749     }
2750   }
2751
2752   if( sec=="Study" )
2753   {
2754     if( param=="store_positions" )
2755       updateWindows();
2756     if( param=="auto_save_interval" ) {
2757       myAutoSaveTimer->stop();
2758       int autoSaveInterval = resMgr->integerValue( "Study", "auto_save_interval", 0 );
2759       if ( activeStudy() && autoSaveInterval > 0 ) myAutoSaveTimer->start( autoSaveInterval*60000 );
2760     }
2761   }
2762
2763 #ifndef DISABLE_PYCONSOLE
2764   if( sec=="PyConsole" && pythonConsole() )
2765   {
2766     if ( param=="font" ) {
2767       pythonConsole()->setFont( resMgr->fontValue( "PyConsole", "font" ) );
2768     }
2769     else if ( param=="show_banner" ) {
2770       pythonConsole()->setIsShowBanner( resMgr->booleanValue( "PyConsole", "show_banner", true ) );
2771     }
2772   }
2773 #endif
2774
2775   if( sec=="MRU" )
2776   {
2777     QtxMRUAction* mru = ::qobject_cast<QtxMRUAction*>( action( MRUId ) );
2778     if ( mru ) {
2779       if ( param == "visible_count" )
2780         mru->setVisibleCount( resMgr->integerValue( "MRU", "visible_count", 5 ) );    // 5 MRU items by default
2781       else if ( param == "max_count" )
2782         mru->setHistoryCount( resMgr->integerValue( "MRU", "max_count", -1 ) );       // unlimited history by default
2783       else if ( param == "insert_mode" )
2784         mru->setInsertMode( resMgr->integerValue( "MRU", "insert_mode", 0 ) );        // QtxMRUAction::MoveFirst by default
2785       else if ( param == "link_type" )
2786         mru->setLinkType( resMgr->integerValue( "MRU", "link_type", 0 ) );            // QtxMRUAction::LinkAuto by default
2787       else if ( param == "show_clear" )
2788         mru->setClearPossible( resMgr->booleanValue( "MRU", "show_clear", false ) );  // do not show "Clear" item by default
2789       else if ( param == "show_mru" )
2790         mru->setVisible( resMgr->booleanValue( "MRU", "show_mru", false ) );          // do not show MRU menu item by default
2791     }
2792   }
2793   if ( sec == "language" && param == "language" )
2794   {
2795     SUIT_MessageBox::information( desktop(), tr( "WRN_WARNING" ), tr( "LANG_CHANGED" ) );
2796   }
2797   if ( sec == "desktop" && param == "opaque_resize" ) {
2798     bool opaqueResize = resMgr->booleanValue( "desktop", "opaque_resize", false );
2799     QMainWindow::DockOptions dopts = desktop()->dockOptions();
2800     if ( opaqueResize ) dopts |= QMainWindow::AnimatedDocks;
2801     else                dopts &= ~QMainWindow::AnimatedDocks;
2802     desktop()->setDockOptions( dopts );
2803     desktop()->setOpaqueResize( opaqueResize );
2804     if ( dynamic_cast<STD_TabDesktop*>( desktop() ) )
2805       dynamic_cast<STD_TabDesktop*>( desktop() )->workstack()->setOpaqueResize( opaqueResize );
2806   }
2807
2808   if ( sec == "ExternalBrowser" && param == "use_external_browser" ) {
2809     if ( resMgr->booleanValue("ExternalBrowser", "use_external_browser", false ) )
2810       {
2811         if(QtxWebBrowser::webBrowser())
2812           QtxWebBrowser::webBrowser()->close();
2813       }
2814   }
2815
2816 #ifndef DISABLE_PLOT2DVIEWER
2817   if ( sec == "Plot2d" ) {
2818     if( param == "SelectionColor" ) {
2819       QColor c = resMgr->colorValue( sec, param );
2820       Plot2d_Object::setSelectionColor(c);
2821     }
2822     else if (param == "SelectedLegendFontColor") {
2823       QColor c = resMgr->colorValue( sec, param );      
2824       Plot2d_Object::setHighlightedLegendTextColor(c);
2825     }
2826   }
2827 #endif
2828 }
2829
2830 /*!
2831   Loads preferences
2832 */
2833 void LightApp_Application::loadPreferences()
2834 {
2835   CAM_Application::loadPreferences();
2836
2837   SUIT_ResourceMgr* aResMgr = resourceMgr();
2838
2839   if ( !aResMgr )
2840     return;
2841
2842   static bool mru_load = true;
2843   if ( mru_load )
2844   {
2845     QtxMRUAction* mru = ::qobject_cast<QtxMRUAction*>( action( MRUId ) );
2846     if ( mru ) {
2847       mru->setVisible( aResMgr->booleanValue( "MRU", "show_mru", false ) );         // do not show MRU menu item by default
2848       mru->setVisibleCount( aResMgr->integerValue( "MRU", "visible_count", 5 ) );   // 5 MRU items by default
2849       mru->setHistoryCount( aResMgr->integerValue( "MRU", "max_count", -1 ) );      // unlimited history by default
2850       mru->setInsertMode( aResMgr->integerValue( "MRU", "insert_mode", 0 ) );       // QtxMRUAction::MoveFirst by default
2851       mru->setLinkType( aResMgr->integerValue( "MRU", "link_type", 0 ) );           // QtxMRUAction::LinkAuto by default
2852       mru->setClearPossible( aResMgr->booleanValue( "MRU", "show_clear", false ) ); // do not show "Clear" item by default
2853       mru->loadLinks( aResMgr, "MRU" );
2854     }
2855     mru_load = false;
2856   }
2857
2858   myWinGeom.clear();
2859   QStringList mods = aResMgr->parameters( "windows_geometry" );
2860   for ( QStringList::const_iterator it = mods.begin(); it != mods.end(); ++it )
2861   {
2862     QByteArray arr;
2863     if ( aResMgr->value( "windows_geometry", *it, arr ) )
2864       myWinGeom.insert( *it, arr );
2865   }
2866
2867   myWinVis.clear();
2868   mods = aResMgr->parameters( "windows_visibility" );
2869   for ( QStringList::const_iterator itr = mods.begin(); itr != mods.end(); ++itr )
2870   {
2871     QByteArray arr;
2872     if ( aResMgr->value( "windows_visibility", *itr, arr ) )
2873       myWinVis.insert( *itr, arr );
2874   }
2875
2876   if ( desktop() ) {
2877     desktop()->retrieveGeometry( aResMgr->stringValue( "desktop", "geometry" ) );
2878     bool opaqueResize = aResMgr->booleanValue( "desktop", "opaque_resize", false );
2879     QMainWindow::DockOptions dopts = desktop()->dockOptions();
2880     if ( opaqueResize ) dopts |= QMainWindow::AnimatedDocks;
2881     else                dopts &= ~QMainWindow::AnimatedDocks;
2882     desktop()->setDockOptions( dopts );
2883     desktop()->setOpaqueResize( opaqueResize );
2884     if ( dynamic_cast<STD_TabDesktop*>( desktop() ) )
2885       dynamic_cast<STD_TabDesktop*>( desktop() )->workstack()->setOpaqueResize( opaqueResize );
2886   }
2887 }
2888
2889 /*!
2890   Saves preferences
2891 */
2892 void LightApp_Application::savePreferences()
2893 {
2894   CAM_Application::savePreferences();
2895
2896   saveDockWindowsState();
2897
2898   SUIT_ResourceMgr* aResMgr = resourceMgr();
2899
2900   if ( !aResMgr )
2901     return;
2902
2903   QtxMRUAction* mru = ::qobject_cast<QtxMRUAction*>( action( MRUId ) );
2904   if ( mru )
2905     mru->saveLinks( aResMgr, "MRU" );
2906
2907   for ( WinGeom::const_iterator it = myWinGeom.begin(); it != myWinGeom.end(); ++it )
2908     aResMgr->setValue( "windows_geometry", it.key(), it.value() );
2909
2910   for ( WinVis::const_iterator itr = myWinVis.begin(); itr != myWinVis.end(); ++itr )
2911     aResMgr->setValue( "windows_visibility", itr.key(), itr.value() );
2912
2913   if ( desktop() )
2914     aResMgr->setValue( "desktop", "geometry", desktop()->storeGeometry() );
2915
2916   aResMgr->save();
2917 }
2918
2919 /*!
2920   Updates desktop title
2921 */
2922 void LightApp_Application::updateDesktopTitle()
2923 {
2924   QString aTitle = applicationName();
2925   QString aVer = applicationVersion();
2926   if ( !aVer.isEmpty() )
2927     aTitle += QString( " " ) + aVer;
2928
2929   if ( activeStudy() ) {
2930     QString sName = SUIT_Tools::file( activeStudy()->studyName().trimmed(), false );
2931     aTitle += QString( " - [%1]" ).arg( sName );
2932   }
2933
2934   desktop()->setWindowTitle( aTitle );
2935 }
2936
2937 /*!
2938   \brief Get map of the operations which can be performed
2939   on the module activation.
2940
2941   The method should return the map of the kind \c {<id>:<name>}
2942   where \c <id> is an integer identifier of the operation and
2943   \c <name> is a title for the button to be added to the
2944   dialog box. After user selects the required operation by the
2945   clicking the corresponding button in the dialog box, its identifier
2946   is passed to the moduleActionSelected() method to process
2947   the made choice.
2948
2949   \return map of the operations
2950   \sa moduleActionSelected()
2951 */
2952 QMap<int, QString> LightApp_Application::activateModuleActions() const
2953 {
2954   QMap<int, QString> opmap;
2955   opmap.insert( NewStudyId,  tr( "ACTIVATE_MODULE_OP_NEW" ) );
2956   opmap.insert( OpenStudyId, tr( "ACTIVATE_MODULE_OP_OPEN" ) );
2957   return opmap;
2958 }
2959
2960 /*!
2961   \brief Called when the used selectes required operation chosen
2962   from "Activate module" dialog box.
2963
2964   Performs the required operation according to the user choice.
2965
2966   \param id operation identifier
2967   \sa activateModuleActions()
2968 */
2969 void LightApp_Application::moduleActionSelected( const int id )
2970 {
2971   switch ( id ) {
2972   case NewStudyId:
2973     onNewDoc();
2974     break;
2975   case OpenStudyId:
2976     onOpenDoc();
2977     break;
2978   default:
2979     break;
2980   }
2981 }
2982
2983 /*!
2984   Updates windows after close document
2985 */
2986 void LightApp_Application::afterCloseDoc()
2987 {
2988   updateWindows();
2989
2990   CAM_Application::afterCloseDoc();
2991 }
2992
2993 /*!
2994   Updates actions of active module
2995 */
2996 void LightApp_Application::updateModuleActions()
2997 {
2998   QString modName;
2999   if ( activeModule() ) {
3000     modName = activeModule()->moduleName();
3001     if ( !isModuleAccessible( modName ) ) {
3002       QList<SUIT_Application*> apps = SUIT_Session::session()->applications();
3003       foreach( SUIT_Application* app, apps ) {
3004         LightApp_Application* lapp = dynamic_cast<LightApp_Application*>( app );
3005         if ( lapp && lapp != this )
3006           lapp->removeModuleAction( modName );
3007       }
3008     }
3009   }
3010
3011   LightApp_ModuleAction* moduleAction =
3012     qobject_cast<LightApp_ModuleAction*>( action( ModulesListId ) );
3013   if ( moduleAction )
3014     moduleAction->setActiveModule( modName );
3015 }
3016
3017 void LightApp_Application::removeModuleAction( const QString& modName )
3018 {
3019   LightApp_ModuleAction* moduleAction =
3020     qobject_cast<LightApp_ModuleAction*>( action( ModulesListId ) );
3021   if ( moduleAction )
3022     moduleAction->removeModule( modName );
3023 }
3024
3025 /*!
3026   Gets current windows.
3027   \param winMap - output current windows map.
3028 */
3029 void LightApp_Application::currentWindows( QMap<int, int>& winMap ) const
3030 {
3031   winMap.clear();
3032   if ( !activeStudy() )
3033     return;
3034
3035   if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) )
3036     ((LightApp_Module*)activeModule())->windows( winMap );
3037   else
3038     defaultWindows( winMap );
3039 }
3040
3041 /*!
3042   Gets current view managers.
3043   \param lst - output current view managers list.
3044 */
3045 void LightApp_Application::currentViewManagers( QStringList& lst ) const
3046 {
3047   lst.clear();
3048   if ( !activeStudy() )
3049     return;
3050
3051   if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) )
3052     ((LightApp_Module*)activeModule())->viewManagers( lst );
3053   else
3054     defaultViewManagers( lst );
3055 }
3056
3057 /*!
3058   Updates windows
3059 */
3060 void LightApp_Application::updateWindows()
3061 {
3062   QMap<int, int> winMap;
3063   currentWindows( winMap );
3064
3065   if ( activeStudy() )
3066   {
3067     for ( QMap<int, int>::ConstIterator it = winMap.begin(); it != winMap.end(); ++it )
3068     {
3069       if ( !dockWindow( it.key() ) )
3070         getWindow( it.key() );
3071     }
3072   }
3073
3074   for ( WinMap::ConstIterator it = myWin.begin(); it != myWin.end(); ++it )
3075   {
3076     QWidget* wid = it.value();
3077     if ( activeStudy() )
3078       wid->setVisible( winMap.contains( it.key() ) );
3079     else
3080       delete wid;
3081   }
3082
3083   if ( activeStudy() )
3084     loadDockWindowsState();
3085   else
3086     myWin.clear();
3087 }
3088
3089 /*!
3090   Updates view managers
3091 */
3092 void LightApp_Application::updateViewManagers()
3093 {
3094   QStringList lst;
3095   currentViewManagers( lst );
3096
3097   for ( QStringList::const_iterator it = lst.begin(); it != lst.end(); ++it )
3098     getViewManager( *it, true );
3099 }
3100
3101 /*!
3102   Loads windows geometry
3103 */
3104 void LightApp_Application::loadDockWindowsState()
3105 {
3106   if ( !desktop() )
3107     return;
3108
3109   bool store = resourceMgr()->booleanValue( "Study", "store_positions", true );
3110   if( !store )
3111     return;
3112
3113   QString modName;
3114   if ( activeModule() )
3115     modName = activeModule()->name();
3116
3117   if ( myWinGeom.contains( modName ) )
3118     desktop()->restoreState( myWinGeom[modName] );
3119
3120   if ( !myWinVis.contains( modName ) )
3121     return;
3122
3123   QMap<QString, bool> tbMap, dwMap;
3124   dockWindowsState( myWinVis[modName], tbMap, dwMap );
3125
3126   QList<QToolBar*> tbList = qFindChildren<QToolBar*>( desktop() );
3127   for ( QList<QToolBar*>::iterator tit = tbList.begin(); tit != tbList.end(); ++tit )
3128   {
3129     QToolBar* tb = *tit;
3130
3131     QObject* po = Qtx::findParent( tb, "QMainWindow" );
3132     if ( po != desktop() )
3133       continue;
3134
3135     if ( tbMap.contains( tb->objectName() ) )
3136       tb->setVisible( tbMap[tb->objectName()] );
3137   }
3138
3139   QList<QDockWidget*> dwList = qFindChildren<QDockWidget*>( desktop() );
3140   for ( QList<QDockWidget*>::iterator dit = dwList.begin(); dit != dwList.end(); ++dit )
3141   {
3142     QDockWidget* dw = *dit;
3143
3144     QObject* po = Qtx::findParent( dw, "QMainWindow" );
3145     if ( po != desktop() )
3146       continue;
3147
3148     if ( dwMap.contains( dw->objectName() ) )
3149       dw->setVisible( dwMap[dw->objectName()] );
3150   }
3151 }
3152
3153 /*!
3154   Saves windows geometry
3155 */
3156 void LightApp_Application::saveDockWindowsState()
3157 {
3158   if ( !desktop() )
3159     return;
3160
3161   bool store = resourceMgr()->booleanValue( "Study", "store_positions", true );
3162   if( !store )
3163     return;
3164
3165   QString modName;
3166   if ( activeModule() )
3167     modName = activeModule()->name();
3168
3169   myWinGeom.insert( modName, desktop()->saveState() );
3170
3171   QByteArray visArr;
3172   if ( myWinVis.contains( modName ) )
3173     visArr = myWinVis[modName];
3174
3175   QMap<QString, bool> tbMap, dwMap;
3176   dockWindowsState( visArr, tbMap, dwMap );
3177
3178   QList<QToolBar*> tbList = qFindChildren<QToolBar*>( desktop() );
3179   for ( QList<QToolBar*>::iterator it = tbList.begin(); it != tbList.end(); ++it )
3180   {
3181     QToolBar* tb = *it;
3182     tbMap.insert( tb->objectName(), tb->toggleViewAction()->isChecked() );
3183   }
3184
3185   QList<QDockWidget*> dwList = qFindChildren<QDockWidget*>( desktop() );
3186   for ( QList<QDockWidget*>::iterator it = dwList.begin(); it != dwList.end(); ++it )
3187   {
3188     QDockWidget* wid = *it;
3189     dwMap.insert( wid->objectName(), wid->toggleViewAction()->isChecked() );
3190   }
3191
3192   visArr = dockWindowsState( tbMap, dwMap );
3193
3194   myWinVis.insert( modName, visArr );
3195 }
3196
3197 QByteArray LightApp_Application::dockWindowsState( const QMap<QString, bool>& tb, const QMap<QString, bool>& dw ) const
3198 {
3199   QByteArray visArr;
3200   QDataStream stream( &visArr, QIODevice::WriteOnly );
3201
3202   stream << (uchar)ToolBarMarker;
3203   stream << tb.size();
3204   for ( QMap<QString, bool>::const_iterator tit = tb.begin(); tit != tb.end(); ++tit )
3205   {
3206     stream << tit.key();
3207     stream << (uchar)( tit.value() ? 1 : 0 );
3208   }
3209
3210   stream << (uchar)DockWidgetMarker;
3211   stream << dw.size();
3212   for ( QMap<QString, bool>::const_iterator wit = dw.begin(); wit != dw.end(); ++wit )
3213   {
3214     stream << wit.key();
3215     stream << (uchar)( wit.value() ? 1 : 0 );
3216   }
3217
3218   return visArr;
3219 }
3220
3221 void LightApp_Application::dockWindowsState( const QByteArray& arr, QMap<QString, bool>& tb, QMap<QString, bool>& dw ) const
3222 {
3223   tb.clear();
3224   dw.clear();
3225
3226   QByteArray visArr = arr;
3227   QDataStream stream( &visArr, QIODevice::ReadOnly );
3228
3229   uchar marker;
3230   stream >> marker;
3231   if ( marker != ToolBarMarker )
3232     return;
3233
3234   int lines;
3235   stream >> lines;
3236   for ( int i = 0; i < lines; ++i )
3237   {
3238     QString objectName;
3239     stream >> objectName;
3240     uchar shown;
3241     stream >> shown;
3242     tb.insert( objectName, shown );
3243   }
3244
3245   stream >> marker;
3246   if ( marker != DockWidgetMarker )
3247     return;
3248
3249   stream >> lines;
3250   for ( int j = 0; j < lines; ++j )
3251   {
3252     QString objectName;
3253     stream >> objectName;
3254     uchar shown;
3255     stream >> shown;
3256     dw.insert( objectName, shown );
3257   }
3258 }
3259
3260 /*!
3261   Adds icon names for modules
3262 */
3263 void LightApp_Application::moduleIconNames( QMap<QString, QString>& iconMap ) const
3264 {
3265   iconMap.clear();
3266
3267   SUIT_ResourceMgr* resMgr = resourceMgr();
3268   if ( !resMgr )
3269     return;
3270
3271   QStringList modList;
3272   modules( modList, false );
3273
3274   for ( QStringList::const_iterator it = modList.begin(); it != modList.end(); ++it )
3275   {
3276     QString modName = *it;
3277     QString modIntr = moduleName( modName );
3278     QString modIcon = resMgr->stringValue( modIntr, "icon", QString() );
3279
3280     if ( modIcon.isEmpty() )
3281       continue;
3282
3283     if ( SUIT_Tools::extension( modIcon ).isEmpty() )
3284       modIcon += QString( ".png" );
3285
3286     iconMap.insert( modName, modIcon );
3287   }
3288 }
3289
3290 /*!
3291   Inserts items in popup, which necessary for current application
3292 */
3293 void LightApp_Application::contextMenuPopup( const QString& type, QMenu* thePopup, QString& title )
3294 {
3295   //Add "Rename" item
3296   LightApp_SelectionMgr* selMgr = LightApp_Application::selectionMgr();
3297   bool cacheIsOn = selMgr->isSelectionCacheEnabled();
3298   selMgr->setSelectionCacheEnabled( true );
3299
3300   SUIT_DataBrowser* ob = objectBrowser();
3301
3302   CAM_Application::contextMenuPopup( type, thePopup, title );
3303
3304   if ( ob && type == ob->popupClientType() ) {
3305     thePopup->addSeparator();
3306     QAction* a = thePopup->addAction( tr( "MEN_REFRESH" ), this, SLOT( onRefresh() ) );
3307     if ( ob->shortcutKey(SUIT_DataBrowser::UpdateShortcut) )
3308       a->setShortcut( ob->shortcutKey(SUIT_DataBrowser::UpdateShortcut) );
3309   }
3310
3311   if ( selMgr && ob ) {
3312     SALOME_ListIO selected;
3313     selMgr->selectedObjects( selected );
3314     if(selected.Extent() == 1){
3315       Handle(SALOME_InteractiveObject) anIObject = selected.First();
3316       SUIT_DataObject* obj = findObject(anIObject->getEntry());
3317       if(obj && obj->renameAllowed()) {
3318         QAction* a = new QAction(tr("MEN_RENAME_OBJ"), thePopup);
3319         connect( a, SIGNAL( triggered(bool) ), ob, SLOT( onStartEditing() ) );
3320         if ( ob->shortcutKey(SUIT_DataBrowser::RenameShortcut) )
3321           a->setShortcut( ob->shortcutKey(SUIT_DataBrowser::RenameShortcut) );
3322
3323         QList<QAction*> acts = thePopup->actions();
3324         QAction* firstAction = acts.count() > 0 ? acts.first() : 0;
3325         thePopup->insertAction(firstAction,a);
3326       }
3327     }
3328   }
3329
3330   selMgr->setSelectionCacheEnabled( cacheIsOn );
3331 }
3332
3333 /*!
3334   Create empty study
3335 */
3336 void LightApp_Application::createEmptyStudy()
3337 {
3338   CAM_Application::createEmptyStudy();
3339
3340   if ( objectBrowser() )
3341     objectBrowser()->updateTree();
3342
3343   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3344   if ( aResMgr && activeStudy() ) {
3345     int autoSaveInterval = aResMgr->integerValue( "Study", "auto_save_interval", 0 );
3346     if ( autoSaveInterval > 0 ) myAutoSaveTimer->start( autoSaveInterval*60000 );
3347   }
3348 }
3349
3350 /*!Set desktop:*/
3351 void LightApp_Application::setDesktop( SUIT_Desktop* desk )
3352 {
3353   CAM_Application::setDesktop( desk );
3354
3355   if ( desk ) {
3356     connect( desk, SIGNAL( message( const QString& ) ),
3357              this, SLOT( onDesktopMessage( const QString& ) ), Qt::UniqueConnection );
3358   }
3359 }
3360
3361 /*!
3362   Activates module
3363   \param mod - module to be activated
3364 */
3365 bool LightApp_Application::activateModule( CAM_Module* mod )
3366 {
3367   bool res = CAM_Application::activateModule( mod );
3368
3369   if ( objectBrowser() )
3370     objectBrowser()->updateTree();
3371
3372   return res;
3373 }
3374
3375 /*!
3376   \return keyborad accelerators manager object
3377 */
3378 SUIT_Accel* LightApp_Application::accel() const
3379 {
3380   return myAccel;
3381 }
3382
3383 /*!
3384   Removes dead widget container from map
3385 */
3386 void LightApp_Application::onWCDestroyed( QObject* ob )
3387 {
3388   // remove destroyed widget container from windows map
3389   for ( WinMap::ConstIterator itr = myWin.begin(); itr != myWin.end(); ++itr )
3390   {
3391     if ( itr.value() != ob )
3392       continue;
3393
3394     int key = itr.key();
3395     myWin.remove( key );
3396     break;
3397   }
3398 }
3399
3400 void LightApp_Application::onMRUActivated( const QString& name )
3401 {
3402   SUIT_Session* s = SUIT_Session::session();
3403   if ( s && s->activeApplication() == this )
3404     onOpenDoc( name );
3405 }
3406
3407 void LightApp_Application::onStylePreferences()
3408 {
3409   Style_PrefDlg dlg( desktop() );
3410   dlg.exec();
3411
3412   resourceMgr()->setValue( "Style", "use_salome_style", Style_Salome::isActive() );
3413 }
3414
3415 void LightApp_Application::onFullScreen(){
3416   if(myScreenHelper) {
3417     if(desktop()->isFullScreen())
3418       myScreenHelper->switchToNormalScreen();
3419     else
3420       myScreenHelper->switchToFullScreen();
3421   }
3422 }
3423
3424 /*!
3425   Connects just added view manager
3426 */
3427 void LightApp_Application::addViewManager( SUIT_ViewManager* vm )
3428 {
3429   connect( vm, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
3430            this, SLOT( onCloseView( SUIT_ViewManager* ) ) );
3431   CAM_Application::addViewManager( vm );
3432 }
3433
3434 /*!
3435   Remove view manager from memory
3436 */
3437 void LightApp_Application::removeViewManager( SUIT_ViewManager* vm )
3438 {
3439   disconnect( vm, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
3440            this, SLOT( onCloseView( SUIT_ViewManager* ) ) );
3441   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>(activeStudy());
3442   if (aStudy )
3443     aStudy->removeViewMgr(vm->getGlobalId());
3444
3445   CAM_Application::removeViewManager( vm );
3446
3447   LightApp_SelectionMgr* selMgr = selectionMgr();
3448   QList<SUIT_Selector*> selectors;
3449   selMgr->selectors( selectors );
3450   foreach( SUIT_Selector* selector, selectors ) {
3451     if ( selector->owner() == vm->getViewModel() ) {
3452       delete selector;
3453     }
3454   }
3455
3456   // IPAL22894: Crash on closing OCC view
3457   //delete vm;
3458   vm->deleteLater();
3459 }
3460
3461 /*!
3462   Renames active window of desktop
3463 */
3464 void LightApp_Application::onRenameWindow()
3465 {
3466   if( !desktop() )
3467     return;
3468
3469   QWidget* w = desktop()->activeWindow();
3470   if( !w )
3471     return;
3472
3473   bool ok;
3474   QString name = QInputDialog::getText( w, tr( "TOT_RENAME" ), tr( "PRP_RENAME" ), QLineEdit::Normal, w->windowTitle(), &ok );
3475   if( ok && !name.isEmpty() )
3476     w->setWindowTitle( name );
3477 }
3478
3479 /*!
3480   Closes active window of desktop
3481 */
3482 void LightApp_Application::onCloseWindow()
3483 {
3484   if( !desktop() )
3485     return;
3486
3487   QWidget* w = desktop()->activeWindow();
3488   if( !w )
3489     return;
3490
3491   w->close();
3492 }
3493
3494 /*!
3495   Closes all windows of desktop
3496 */
3497 void LightApp_Application::onCloseAllWindow()
3498 {
3499   STD_TabDesktop* desk = dynamic_cast<STD_TabDesktop*>( desktop() );
3500   if( !desk )
3501     return;
3502
3503   QList<SUIT_ViewWindow*> wndList = desk->windows();
3504   SUIT_ViewWindow* wnd;
3505   foreach( wnd, wndList )
3506   {
3507     if ( wnd )
3508       wnd->close();
3509   }
3510 }
3511
3512 /*!
3513   Groups all windows of desktop
3514 */
3515 void LightApp_Application::onGroupAllWindow()
3516 {
3517   STD_TabDesktop* desk = dynamic_cast<STD_TabDesktop*>( desktop() );
3518   if( !desk )
3519     return;
3520
3521   QtxWorkstack* wgStack = desk->workstack();
3522   if ( wgStack )
3523     wgStack->stack();
3524 }
3525
3526 /*!
3527   \return if the library of module exists
3528   \param moduleTitle - title of module
3529 */
3530 bool LightApp_Application::isLibExists( const QString& moduleTitle ) const
3531 {
3532   if( moduleTitle.isEmpty() )
3533     return false;
3534
3535   QString lib = moduleLibrary( moduleTitle );
3536
3537   //abd: changed libSalomePyQtGUI to SalomePyQtGUI for WIN32
3538   bool isPythonModule = lib.contains("SalomePyQtGUI");
3539   bool isPythonLightModule = lib.contains("SalomePyQtGUILight");
3540
3541   QStringList paths;
3542 #ifdef WIN32
3543   paths = QString(::getenv( "PATH" )).split( ";", QString::SkipEmptyParts );
3544 #else
3545   paths = QString(::getenv( "LD_LIBRARY_PATH" )).split( ":", QString::SkipEmptyParts );
3546 #endif
3547
3548   bool isLibFound = false;
3549   QStringList::const_iterator anIt = paths.begin(), aLast = paths.end();
3550   for( ; anIt!=aLast; anIt++ )
3551   {
3552     QFileInfo inf( Qtx::addSlash( *anIt ) + lib );
3553
3554     if( inf.exists() )
3555       {
3556         isLibFound = true;
3557         break;
3558       }
3559   }
3560
3561   if ( !isLibFound )
3562     {
3563       INFOS( "****************************************************************" << std::endl
3564           << "*    Warning: library " << lib.toLatin1().constData() << " cannot be found" << std::endl
3565           << "*    Module " << moduleTitle.toLatin1().constData() << " will not be available in GUI mode" << std::endl
3566           << "****************************************************************" << std::endl );
3567     }
3568   else if ( !isPythonModule && !isPythonLightModule)
3569     return true;
3570
3571   if ( isPythonModule || isPythonLightModule)
3572     {
3573       QString pylib = moduleName( moduleTitle ) + QString(".py");
3574       QString pylibgui = moduleName( moduleTitle ) + QString("GUI.py");
3575
3576       // Check the python library
3577 // #ifdef WIN32
3578 //       paths = QString(::getenv( "PATH" )).split( ";", QString::SkipEmptyParts );
3579 // #else
3580       paths = QString(::getenv( "PYTHONPATH" )).split( ":", QString::SkipEmptyParts );
3581 // #endif
3582       bool isPyLib = false, isPyGuiLib = false;
3583       QStringList::const_iterator anIt = paths.begin(), aLast = paths.end();
3584       for( ; anIt!=aLast; anIt++ )
3585         {
3586           QFileInfo inf( Qtx::addSlash( *anIt ) + pylib );
3587           QFileInfo infgui( Qtx::addSlash( *anIt ) + pylibgui );
3588
3589           if(!isPythonLightModule)
3590             if( !isPyLib && inf.exists() )
3591               isPyLib = true;
3592
3593           if( !isPyGuiLib && infgui.exists() )
3594             isPyGuiLib = true;
3595
3596           if ((isPyLib || isPythonLightModule ) && isPyGuiLib && isLibFound)
3597             return true;
3598         }
3599
3600       printf( "****************************************************************\n" );
3601       printf( "*    Warning: python library for %s cannot be found:\n", moduleTitle.toLatin1().constData() );
3602       if (!isPyLib)
3603         printf( "*    No module named %s\n", moduleName( moduleTitle ).toLatin1().constData() );
3604       if (!isPyGuiLib)
3605         printf( "*    No module named %s\n", (moduleName( moduleTitle ) + QString("GUI")).toLatin1().constData() );
3606       printf( "****************************************************************\n" );
3607       return true;
3608   }
3609   return false;
3610 }
3611
3612 /*!
3613   \return default name for an active study
3614 */
3615 void LightApp_Application::setDefaultStudyName( const QString& theName )
3616 {
3617   QStringList anInfoList;
3618   modules( anInfoList, false );
3619
3620   LightApp_Study* aStudy = (LightApp_Study*)activeStudy();
3621   if( anInfoList.count() == 1 && // to avoid a conflict between different modules
3622       !aStudy->isSaved() )
3623   {
3624     aStudy->setStudyName( theName );
3625     updateDesktopTitle();
3626   }
3627 }
3628
3629 /*!
3630   Custom event handler
3631 */
3632 bool LightApp_Application::event( QEvent* e )
3633 {
3634   if( e && e->type()==2000 )
3635   {
3636     SALOME_CustomEvent* ce = ( SALOME_CustomEvent* )e;
3637     QString* d = ( QString* )ce->data();
3638     if( SUIT_MessageBox::question(0, tr("WRN_WARNING"),
3639                                   d ? *d : "",
3640                                   SUIT_MessageBox::Yes | SUIT_MessageBox::No,
3641                                   SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes )
3642       showPreferences( tr( "PREF_APP" ) );
3643     if( d )
3644       delete d;
3645     return true;
3646   }
3647   return CAM_Application::event( e );
3648 }
3649
3650 /*! Check data object */
3651 bool LightApp_Application::checkDataObject(LightApp_DataObject* theObj)
3652 {
3653   if (theObj)
3654     {
3655       bool isSuitable = !theObj->entry().isEmpty() &&
3656                         !theObj->componentDataType().isEmpty() &&
3657                         !theObj->name().isEmpty();
3658       return isSuitable;
3659     }
3660
3661   return false;
3662 }
3663
3664 int LightApp_Application::openChoice( const QString& aName )
3665 {
3666   int choice = CAM_Application::openChoice( aName );
3667
3668   if ( choice == OpenExist ) // The document is already open.
3669   {
3670     // Do you want to reload it?
3671     if ( SUIT_MessageBox::question( desktop(), tr( "WRN_WARNING" ), tr( "QUE_DOC_ALREADYOPEN" ).arg( aName ),
3672                                     SUIT_MessageBox::Yes | SUIT_MessageBox::No, SUIT_MessageBox::No ) == SUIT_MessageBox::Yes )
3673       choice = OpenReload;
3674   }
3675
3676   return choice;
3677 }
3678
3679 bool LightApp_Application::openAction( const int choice, const QString& aName )
3680 {
3681   bool res = false;
3682   switch ( choice )
3683   {
3684   case OpenReload:
3685     {
3686       STD_Application* app = 0;
3687       SUIT_Session* session = SUIT_Session::session();
3688       QList<SUIT_Application*> appList = session->applications();
3689       for ( QList<SUIT_Application*>::iterator it = appList.begin(); it != appList.end() && !app; ++it )
3690       {
3691         if ( (*it)->activeStudy() && (*it)->activeStudy()->studyName() == aName )
3692           app = ::qobject_cast<STD_Application*>( *it );
3693       }
3694
3695       if ( app )
3696       {
3697         app->onCloseDoc( false );
3698         appList = session->applications();
3699         STD_Application* other = 0;
3700         for ( QList<SUIT_Application*>::iterator it = appList.begin(); it != appList.end() && !other; ++it )
3701           other = ::qobject_cast<STD_Application*>( *it );
3702
3703         if ( other )
3704           res = other->onOpenDoc( aName );
3705       }
3706     }
3707     break;
3708   default:
3709     res = CAM_Application::openAction( choice, aName );
3710     break;
3711   }
3712
3713   return res;
3714 }
3715
3716 QStringList LightApp_Application::viewManagersTypes() const
3717 {
3718   QStringList aTypesList;
3719   aTypesList += myUserWmTypes;
3720 #ifndef DISABLE_GLVIEWER
3721   aTypesList<<GLViewer_Viewer::Type();
3722 #endif
3723 #ifndef DISABLE_PLOT2DVIEWER
3724   aTypesList<<Plot2d_Viewer::Type();
3725 #endif
3726 #ifndef DISABLE_QXGRAPHVIEWER
3727   aTypesList<<QxScene_Viewer::Type();
3728 #endif
3729 #ifndef DISABLE_OCCVIEWER
3730   aTypesList<<OCCViewer_Viewer::Type();
3731 #endif
3732 #ifndef DISABLE_VTKVIEWER
3733  #ifndef DISABLE_SALOMEOBJECT
3734   aTypesList<<SVTK_Viewer::Type();
3735  #else
3736   aTypesList<<VTKViewer_Viewer::Type();
3737  #endif
3738 #endif
3739   return aTypesList;
3740 }
3741 /*!
3742  * Removes all view managers of known types
3743  * Other view managers are ignored
3744  */
3745 void LightApp_Application::clearKnownViewManagers()
3746 {
3747   QStringList aTypesList = viewManagersTypes();
3748   QList<SUIT_ViewManager*> aMgrList;
3749   viewManagers( aMgrList );
3750   foreach (SUIT_ViewManager* aMgr, aMgrList) {
3751     if (aTypesList.contains(aMgr->getType()))
3752       removeViewManager(aMgr);
3753   }
3754 }
3755
3756 /*!
3757   Copy of current selection
3758  */
3759 void LightApp_Application::onCopy()
3760 {
3761   LightApp_Module* m = dynamic_cast<LightApp_Module*>( activeModule() );
3762   if( m )
3763     m->copy();
3764 }
3765
3766 /*!
3767   Paste of current data in clipboard
3768  */
3769 void LightApp_Application::onPaste()
3770 {
3771   LightApp_Module* m = dynamic_cast<LightApp_Module*>( activeModule() );
3772   if( m )
3773     m->paste();
3774 }
3775
3776 /*!
3777   Browse (i.e. set focus on) the published objects
3778   \param theIsApplyAndClose - flag indicating that the dialog for creating objects
3779                               has been accepted by Ok (or Apply & Close) button
3780   \param theIsOptimizedBrowsing - flag switching to optimized browsing mode
3781                                   (to select the first published object only)
3782   \return entry of the selected object
3783  */
3784 QString LightApp_Application::browseObjects( const QStringList& theEntryList,
3785                                              const bool theIsApplyAndClose,
3786                                              const bool theIsOptimizedBrowsing )
3787 {
3788   QString aResult;
3789   if( SUIT_ResourceMgr* aResourceMgr = resourceMgr() )
3790   {
3791     int aBrowsePolicy = aResourceMgr->integerValue( "ObjectBrowser", "browse_published_object", (int)BP_Never );
3792     switch( aBrowsePolicy )
3793     {
3794       case BP_Never:
3795         return aResult;
3796       case BP_ApplyAndClose:
3797         if( !theIsApplyAndClose )
3798           return aResult;
3799       case BP_Always:
3800       default:
3801         break;
3802     }
3803   }
3804
3805   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( activeStudy() );
3806   if( !aStudy )
3807     return aResult;
3808
3809   SUIT_DataBrowser* anOB = objectBrowser();
3810   if( !anOB )
3811     return aResult;
3812
3813   SUIT_AbstractModel* aModel = dynamic_cast<SUIT_AbstractModel*>( anOB->model() );
3814   if( !aModel )
3815     return aResult;
3816
3817   QStringListIterator anIter( theEntryList );
3818   if( theIsOptimizedBrowsing )
3819   {
3820     // go to the last entry
3821     anIter.toBack();
3822     if( anIter.hasPrevious() )
3823       anIter.previous();
3824   }
3825
3826   // scroll to each entry in the list
3827   // (in optimized mode - to the last entry only)
3828   QString anEntry;
3829   LightApp_DataObject* anObject = 0;
3830   while( anIter.hasNext() )
3831   {
3832     anEntry = anIter.next();
3833     if( !anEntry.isEmpty() )
3834     {
3835       anObject = aStudy->findObjectByEntry( anEntry );
3836       if( anObject )
3837       {
3838         QModelIndex anIndex = aModel->index( anObject );
3839         anOB->treeView()->scrollTo( anIndex );
3840       }
3841     }
3842   }
3843
3844   // always select the last object
3845   if( anObject && !anEntry.isEmpty() )
3846   {
3847     QList<SUIT_Selector*> aSelectorList;
3848     selectionMgr()->selectors( "ObjectBrowser", aSelectorList );
3849     if( !aSelectorList.isEmpty() )
3850     {
3851       if( LightApp_OBSelector* aSelector = dynamic_cast<LightApp_OBSelector*>( aSelectorList.first() ) )
3852       {
3853         bool anIsAutoBlock = aSelector->autoBlock();
3854
3855         // temporarily disable auto block, to emit LightApp_SelectionMgr::currentSelectionChanged() signal
3856         aSelector->setAutoBlock( false );
3857
3858         SUIT_DataOwnerPtrList aList;
3859 #ifndef DISABLE_SALOMEOBJECT
3860         Handle(SALOME_InteractiveObject) aSObj = new SALOME_InteractiveObject
3861           ( anObject->entry().toLatin1().constData(),
3862             anObject->componentDataType().toLatin1().constData(),
3863             anObject->name().toLatin1().constData() );
3864         LightApp_DataOwner* owner = new LightApp_DataOwner( aSObj  );
3865 #else
3866         LightApp_DataOwner* owner = new LightApp_DataOwner( anEntry );
3867 #endif
3868
3869         aList.append( owner );
3870         selectionMgr()->setSelected( aList );
3871         aResult = anEntry;
3872
3873         // restore auto block flag
3874         aSelector->setAutoBlock( anIsAutoBlock );
3875       }
3876     }
3877   }
3878
3879   return aResult;
3880 }
3881
3882 SUIT_DataObject* LightApp_Application::findObject( const QString& id ) const
3883 {
3884   LightApp_Study* study = dynamic_cast<LightApp_Study*>( activeStudy() );
3885   return study ? study->findObjectByEntry( id ) : 0;
3886 }
3887
3888 /*!
3889   Checks that an object can be renamed.
3890   \param entry entry of the object
3891   \brief Return \c true if object can be renamed
3892 */
3893 bool LightApp_Application::renameAllowed( const QString& /*entry*/) const {
3894   return false;
3895 }
3896
3897 /*!
3898   Rename object by entry.
3899   \param entry entry of the object
3900   \param name new name of the object
3901   \brief Return \c true if rename operation finished successfully, \c false otherwise.
3902 */
3903 bool LightApp_Application::renameObject( const QString& entry, const QString& ) {
3904   return false;
3905 }
3906
3907 /*! Process standard messages from desktop */
3908 void LightApp_Application::onDesktopMessage( const QString& message )
3909 {
3910   const QString sectionSeparator = "/";
3911
3912   if ( message.toLower() == "updateobjectbrowser" ||
3913        message.toLower() == "updateobjbrowser" ) {
3914     // update object browser
3915     updateObjectBrowser();
3916   }
3917   else {
3918     QStringList data = message.split( sectionSeparator );
3919     if ( data.count() > 1 ) {
3920       QString msgType = data[0].trimmed();
3921       LightApp_Module* sMod = 0;
3922       CAM_Module* mod = module( msgType );
3923       if ( !mod )
3924         mod = module( moduleTitle( msgType ) );
3925       if ( mod && mod->inherits( "LightApp_Module" ) )
3926         sMod = (LightApp_Module*)mod;
3927
3928       if ( msgType.toLower() == "preferences" ) {
3929         // requested preferences change: should be given as "preferences/<section>/<name>/<value>"
3930         // for example "preferences/Study/multi_file_dump/true"
3931         if ( data.count() > 3 ) {
3932           QString section = data[1].trimmed();
3933           QString param   = data[2].trimmed();
3934           QString value   = QStringList( data.mid(3) ).join( sectionSeparator );
3935           resourceMgr()->setValue( section, param, value );
3936         }
3937       }
3938       else if ( sMod ) {
3939         // received message for the module
3940         QString msg = QStringList( data.mid(1) ).join( sectionSeparator );
3941         sMod->message( msg );
3942       }
3943     }
3944   }
3945 }