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