Salome HOME
[bos #29467] [EDF] (2022-T1) Logging of SALOME usage: specific log in SALOME
[modules/gui.git] / src / LightApp / LightApp_Application.cxx
1 // Copyright (C) 2007-2023  CEA, EDF, 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, or (at your option) any later version.
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 #ifdef WIN32
27 // E.A. : On windows with python 2.6, there is a conflict
28 // E.A. : between pymath.h and Standard_math.h which define
29 // E.A. : some same symbols : acosh, asinh, ...
30   #include <Standard_math.hxx>
31   #ifndef DISABLE_PYCONSOLE
32     #include <pymath.h>
33   #endif
34 #endif
35
36 #ifndef DISABLE_PYCONSOLE
37   #include "PyConsole_Interp.h"
38   #include "LightApp_PyEditor.h"
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_DataOwner.h"
46 #include "LightApp_Displayer.h"
47 #include "LightApp_Study.h"
48 #include "LightApp_Preferences.h"
49 #include "LightApp_PreferencesDlg.h"
50 #include "LightApp_ModuleDlg.h"
51 #include "LightApp_AboutDlg.h"
52 #include "LightApp_ExtInfoDlg.h"
53 #include "LightApp_ModuleAction.h"
54 // temporary commented
55 #include "LightApp_EventFilter.h"
56 #include "LightApp_OBSelector.h"
57 #include "LightApp_SelectionMgr.h"
58 #include "LightApp_DataObject.h"
59 #include "LightApp_WgViewModel.h"
60 #include "LightApp_FullScreenHelper.h"
61
62 #include <GUI_version.h>
63
64 #include <SALOME_Event.h>
65
66 #ifdef USE_SALOME_STYLE
67 #include <Style_Salome.h>
68 #include <Style_PrefDlg.h>
69 #endif // USE_SALOME_STYLE
70
71 #include <CAM_Module.h>
72 #include <CAM_DataModel.h>
73 #include <CAM_Study.h>
74 #include <STD_TabDesktop.h>
75
76 #include <SUIT_DataBrowser.h>
77 #include <SUIT_Session.h>
78 #include <SUIT_Study.h>
79 #include <SUIT_FileDlg.h>
80 #include <SUIT_ResourceMgr.h>
81 #include <SUIT_ShortcutMgr.h>
82 #include <SUIT_Tools.h>
83 #include <SUIT_Accel.h>
84 #include <SUIT_MessageBox.h>
85 #include <SUIT_ViewWindow.h>
86
87 #include <Qtx.h>
88 #include <QtxFontEdit.h>
89 #include <QtxToolBar.h>
90 #include <QtxTreeView.h>
91 #include <QtxInfoPanel.h>
92 #include <QtxMRUAction.h>
93 #include <QtxDockAction.h>
94 #include <QtxDockWidget.h>
95 #include <QtxActionToolMgr.h>
96 #include <QtxSearchTool.h>
97 #include <QtxWorkstack.h>
98 #include <QtxMap.h>
99
100 #include <LogWindow.h>
101
102 #ifndef DISABLE_GLVIEWER
103   #include <GLViewer_Viewer.h>
104   #include <GLViewer_ViewManager.h>
105   #include "LightApp_GLSelector.h"
106 #endif
107
108 #ifndef DISABLE_PLOT2DVIEWER
109   #include <Plot2d_ViewManager.h>
110   #include <Plot2d_ViewModel.h>
111   #include <Plot2d_ViewWindow.h>
112   #include <Plot2d_ViewFrame.h>
113   #include "LightApp_Plot2dSelector.h"
114 #ifndef DISABLE_SALOMEOBJECT
115   #include <SPlot2d_ViewModel.h>
116 #else
117   #include <Plot2d_ViewModel.h>
118 #endif
119 #endif
120
121 #ifndef DISABLE_OCCVIEWER
122   #include <OCCViewer_ViewManager.h>
123   #include <OCCViewer_ViewFrame.h>
124   #include <OCCViewer_ViewPort3d.h>
125 #ifndef DISABLE_SALOMEOBJECT
126   #include <SOCC_ViewModel.h>
127 #else
128   #include <OCCViewer_ViewModel.h>
129 #endif
130   #include "LightApp_OCCSelector.h"
131 #endif
132
133 #ifndef DISABLE_VTKVIEWER
134 #ifndef DISABLE_SALOMEOBJECT
135   #include <SVTK_ViewModel.h>
136   #include <SVTK_ViewManager.h>
137   #include "LightApp_VTKSelector.h"
138 #else
139   #include <VTKViewer_ViewModel.h>
140   #include <VTKViewer_ViewManager.h>
141 #endif
142   #include <VTKViewer_ViewModel.h>
143 #endif
144
145 #ifndef DISABLE_QXGRAPHVIEWER
146   #include <QxScene_ViewManager.h>
147   #include <QxScene_ViewModel.h>
148   #include <QxScene_ViewWindow.h>
149 #endif
150
151 #ifndef DISABLE_GRAPHICSVIEW
152   #include "GraphicsView_Viewer.h"
153   #include "GraphicsView_ViewManager.h"
154   #include "LightApp_GVSelector.h"
155 #endif
156
157 #ifndef DISABLE_PVVIEWER
158   #include "PVViewer_ViewManager.h"
159   #include "PVViewer_ViewWindow.h"
160   #include "PVViewer_ViewModel.h"
161 #endif
162
163 #ifndef DISABLE_PYVIEWER
164   #include <PyViewer_ViewManager.h>
165   #include <PyViewer_ViewModel.h>
166   #include <PyViewer_ViewWindow.h>
167 #endif
168
169 #ifndef DISABLE_PV3DVIEWER
170 #ifndef DISABLE_SALOMEOBJECT
171   #include <SPV3D_ViewModel.h>
172   #include <SPV3D_ViewManager.h>
173   #include "LightApp_PV3DSelector.h"
174 #else
175   #include <PV3DViewer_ViewModel.h>
176   #include <PV3DViewer_ViewManager.h>
177 #endif
178   #include <PV3DViewer_ViewManager.h>
179   #include <PV3DViewer_ViewModel.h>
180   #include "PV3DViewer_ViewWindow.h"
181 #endif
182
183
184 #define VISIBILITY_COLUMN_WIDTH 25
185
186 #include <QDir>
187 #include <QImage>
188 #include <QString>
189 #include <QWidget>
190 #include <QStringList>
191 #include <QFile>
192 #include <QApplication>
193 #include <QMap>
194 #include <QStatusBar>
195 #include <QThread>
196 #include <QObjectList>
197 #include <QComboBox>
198 #include <QInputDialog>
199 #include <QFontDatabase>
200 #include <QIcon>
201 #include <QByteArray>
202 #include <QMenu>
203 #include <QProcess>
204 #include <QTimer>
205 #include <QHeaderView>
206 #include <QTreeView>
207 #include <QMimeData>
208 #include <QShortcut>
209 #include <QRegExp>
210 #include <QMutex>
211 #include <QMutexLocker>
212
213 #include <utilities.h>
214
215 #define FIRST_HELP_ID 1000000
216 #define HAS_WWW_URL true
217 #define HAS_FORUM_URL true
218 #define HAS_YOUTUBE_URL true
219 #define HAS_TUTORIAL_URL false
220
221 #ifndef DISABLE_SALOMEOBJECT
222   #include <SALOME_InteractiveObject.hxx>
223   #include <SALOME_ListIO.hxx>
224 #endif
225
226 #include <Standard_Version.hxx>
227
228 #define ToolBarMarker    0
229 #define DockWidgetMarker 1
230
231 static const char* imageEmptyIcon[] = {
232 "20 20 1 1",
233 ".      c None",
234 "....................",
235 "....................",
236 "....................",
237 "....................",
238 "....................",
239 "....................",
240 "....................",
241 "....................",
242 "....................",
243 "....................",
244 "....................",
245 "....................",
246 "....................",
247 "....................",
248 "....................",
249 "....................",
250 "....................",
251 "....................",
252 "....................",
253 "...................."};
254
255 // Markers used to parse array with dockable windows and toolbars state.
256 // For more details please see the qdockarealayout.cpp && qtoolbararealayout.cpp
257 // in the Qt source code.
258
259 #define QDockWidgetMarker 0xfd // = DockWidgetStateMarker
260 #define QToolBarMarker 0xfc    // = ToolBarStateMarkerEx
261
262 // Format of the Byte array with the windows and toolbar state is:
263 // VersionMarker|version|DockWidgetStateMarker|nbDockWidgetLines|...DocWidgetData...|ToolBarStateMarkerEx|nbToolBarLines|...ToolBarData...
264
265 //Find toolbar marker position in the array in the following way:
266 //since the 'toolbar marker' is not unique, find index of first occurrence of the
267 //'toolbar marker' in the array and check that next string is name of the toolbar
268
269 namespace
270 {
271   const char* salomeAppDir = "SALOME_APPLICATION_DIR";
272 }
273
274 void LightAppCleanUpAppResources()
275 {
276   if ( LightApp_Application::_prefs_ ) {
277     delete LightApp_Application::_prefs_;
278     LightApp_Application::_prefs_ = 0;
279   }
280 }
281
282 namespace
283 {
284   int getToolbarMarkerIndex( QByteArray input, const QStringList& aFlags ) {
285     int aResult = -1,tmp = 0;
286     int inputLen = input.length();
287     QDataStream anInputData( &input, QIODevice::ReadOnly );
288     while ( tmp < inputLen ) {
289       tmp = input.indexOf( (uchar)QToolBarMarker, tmp + 1 );
290       if ( tmp < 0 )
291         break;
292       anInputData.device()->seek( tmp );
293       uchar mark;
294       anInputData >> mark;
295       int lines;
296       anInputData >> lines;
297
298       if ( lines == 0 && anInputData.atEnd() ) {
299         //Case then array doesn't contain information about toolbars,
300         aResult = tmp;
301         break;
302       }
303
304       int pos;
305       anInputData >> pos;
306       int cnt;
307       anInputData >> cnt;
308       QString str;
309       anInputData >> str;
310       if ( aFlags.contains( str ) ) {
311         aResult = tmp;
312         break;
313       }
314     }
315     return aResult;
316   }
317
318   QString langToName( const QString& lang )
319   {
320     // special processing for English language to avoid such result as "American English"
321     // as Qt cannot just say "English"
322     QString result;
323     if ( lang == "en" )
324       result = "English";
325     else
326       result = QLocale( lang ).nativeLanguageName();
327     return result;
328   }
329
330   QString getHelpItem( const QString& section, const QString& parameter, const QString& root = QString() )
331   {
332     SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
333     foreach( QString item, resMgr->stringValue( section, parameter ).split( ";;", QString::SkipEmptyParts ) )
334     {
335       if ( item.startsWith( "http", Qt::CaseInsensitive ) )
336         return item;
337       QString path = item;
338       path.remove( QRegExp( "#.*$" ) );
339       QFileInfo fi( path );
340       if ( fi.isRelative() && !root.isEmpty() )
341         path = Qtx::addSlash( root ) + path;
342       if ( QFile::exists( path ) )
343         return item;
344     }
345     return QString();
346   }
347
348   const bool HAS_SALOME_ON_DEMAND =
349 #if defined(WITH_SALOME_ON_DEMAND)
350     true;
351 #else
352     false;
353 #endif
354 }
355
356 /*!Create new instance of LightApp_Application.*/
357 extern "C" LIGHTAPP_EXPORT SUIT_Application* createApplication()
358 {
359   return new LightApp_Application();
360 }
361
362 /*! \var global preferences of LightApp */
363 LightApp_Preferences* LightApp_Application::_prefs_ = 0;
364
365
366 /*!
367   \class LightApp_Application
368   Application containing LightApp module
369 */
370
371 /*!Constructor.*/
372 LightApp_Application::LightApp_Application()
373 : CAM_Application( false ),
374   myPrefs( 0 ),
375   myScreenHelper(new LightApp_FullScreenHelper())
376 {
377   Q_INIT_RESOURCE( LightApp );
378
379   STD_TabDesktop* desk = new STD_TabDesktop();
380   desk->setFullScreenAllowed(false);
381   desk->setMinimizeAllowed(false);
382
383   setDesktop( desk );
384
385   // initialize auto save timer
386   myAutoSaveTimer = new QTimer( this );
387   myAutoSaveTimer->setSingleShot( true );
388   connect( myAutoSaveTimer, SIGNAL( timeout() ), this, SLOT( onSaveDoc() ) );
389
390   //connect( this, SIGNAL( moving() ), this, SLOT( onMoved() ) );
391
392   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
393   QPixmap aLogo = aResMgr->loadPixmap( "LightApp", tr( "APP_DEFAULT_ICO" ), false );
394
395   desktop()->setWindowIcon( aLogo );
396   desktop()->setDockableMenuBar( false );
397   desktop()->setDockableStatusBar( false );
398
399   // base logo (salome itself)
400   desktop()->logoInsert( "_app_base",  aResMgr->loadPixmap( "LightApp", tr( "APP_BASE_LOGO" ), false ) );
401   // extra logo (salome-based application)
402   desktop()->logoInsert( "_app_extra", aResMgr->loadPixmap( "LightApp", tr( "APP_EXTRA_LOGO" ), false ) );
403
404   clearViewManagers();
405
406   mySelMgr = new LightApp_SelectionMgr( this );
407
408   myAccel = SUIT_Accel::getAccel();
409
410 #ifndef DISABLE_OCCVIEWER
411   myAccel->setActionKey( SUIT_Accel::PanLeft,     Qt::CTRL+Qt::Key_Left,     OCCViewer_Viewer::Type() );
412   myAccel->setActionKey( SUIT_Accel::PanRight,    Qt::CTRL+Qt::Key_Right,    OCCViewer_Viewer::Type() );
413   myAccel->setActionKey( SUIT_Accel::PanUp,       Qt::CTRL+Qt::Key_Up,       OCCViewer_Viewer::Type() );
414   myAccel->setActionKey( SUIT_Accel::PanDown,     Qt::CTRL+Qt::Key_Down,     OCCViewer_Viewer::Type() );
415   myAccel->setActionKey( SUIT_Accel::ZoomIn,      Qt::CTRL+Qt::Key_Plus,     OCCViewer_Viewer::Type() );
416   myAccel->setActionKey( SUIT_Accel::ZoomOut,     Qt::CTRL+Qt::Key_Minus,    OCCViewer_Viewer::Type() );
417   myAccel->setActionKey( SUIT_Accel::ZoomFit,     Qt::CTRL+Qt::Key_Asterisk, OCCViewer_Viewer::Type() );
418   myAccel->setActionKey( SUIT_Accel::ZoomFit,     Qt::Key_Space,             OCCViewer_Viewer::Type() );
419   myAccel->setActionKey( SUIT_Accel::RotateLeft,  Qt::ALT+Qt::Key_Left,      OCCViewer_Viewer::Type() );
420   myAccel->setActionKey( SUIT_Accel::RotateRight, Qt::ALT+Qt::Key_Right,     OCCViewer_Viewer::Type() );
421   myAccel->setActionKey( SUIT_Accel::RotateUp,    Qt::ALT+Qt::Key_Up,        OCCViewer_Viewer::Type() );
422   myAccel->setActionKey( SUIT_Accel::RotateDown,  Qt::ALT+Qt::Key_Down,      OCCViewer_Viewer::Type() );
423 #endif
424 #ifndef DISABLE_VTKVIEWER
425   myAccel->setActionKey( SUIT_Accel::PanLeft,     Qt::CTRL+Qt::Key_Left,     VTKViewer_Viewer::Type() );
426   myAccel->setActionKey( SUIT_Accel::PanRight,    Qt::CTRL+Qt::Key_Right,    VTKViewer_Viewer::Type() );
427   myAccel->setActionKey( SUIT_Accel::PanUp,       Qt::CTRL+Qt::Key_Up,       VTKViewer_Viewer::Type() );
428   myAccel->setActionKey( SUIT_Accel::PanDown,     Qt::CTRL+Qt::Key_Down,     VTKViewer_Viewer::Type() );
429   myAccel->setActionKey( SUIT_Accel::ZoomIn,      Qt::CTRL+Qt::Key_Plus,     VTKViewer_Viewer::Type() );
430   myAccel->setActionKey( SUIT_Accel::ZoomOut,     Qt::CTRL+Qt::Key_Minus,    VTKViewer_Viewer::Type() );
431   myAccel->setActionKey( SUIT_Accel::ZoomFit,     Qt::CTRL+Qt::Key_Asterisk, VTKViewer_Viewer::Type() );
432   myAccel->setActionKey( SUIT_Accel::ZoomFit,     Qt::Key_Space,             VTKViewer_Viewer::Type() );
433   myAccel->setActionKey( SUIT_Accel::RotateLeft,  Qt::ALT+Qt::Key_Left,      VTKViewer_Viewer::Type() );
434   myAccel->setActionKey( SUIT_Accel::RotateRight, Qt::ALT+Qt::Key_Right,     VTKViewer_Viewer::Type() );
435   myAccel->setActionKey( SUIT_Accel::RotateUp,    Qt::ALT+Qt::Key_Up,        VTKViewer_Viewer::Type() );
436   myAccel->setActionKey( SUIT_Accel::RotateDown,  Qt::ALT+Qt::Key_Down,      VTKViewer_Viewer::Type() );
437 #endif
438 #ifndef DISABLE_PLOT2DVIEWER
439   myAccel->setActionKey( SUIT_Accel::PanLeft,     Qt::CTRL+Qt::Key_Left,     Plot2d_Viewer::Type() );
440   myAccel->setActionKey( SUIT_Accel::PanRight,    Qt::CTRL+Qt::Key_Right,    Plot2d_Viewer::Type() );
441   myAccel->setActionKey( SUIT_Accel::PanUp,       Qt::CTRL+Qt::Key_Up,       Plot2d_Viewer::Type() );
442   myAccel->setActionKey( SUIT_Accel::PanDown,     Qt::CTRL+Qt::Key_Down,     Plot2d_Viewer::Type() );
443   myAccel->setActionKey( SUIT_Accel::ZoomIn,      Qt::CTRL+Qt::Key_Plus,     Plot2d_Viewer::Type() );
444   myAccel->setActionKey( SUIT_Accel::ZoomOut,     Qt::CTRL+Qt::Key_Minus,    Plot2d_Viewer::Type() );
445   myAccel->setActionKey( SUIT_Accel::ZoomFit,     Qt::CTRL+Qt::Key_Asterisk, Plot2d_Viewer::Type() );
446   myAccel->setActionKey( SUIT_Accel::ZoomFit,     Qt::Key_Space,             Plot2d_Viewer::Type() );
447 #endif
448
449   connect( mySelMgr, SIGNAL( selectionChanged() ), this, SLOT( onSelection() ) );
450   connect( desktop(), SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
451            this,      SLOT( onWindowActivated( SUIT_ViewWindow* ) ), Qt::UniqueConnection );
452   connect( this, SIGNAL( viewManagerRemoved( SUIT_ViewManager* ) ),
453            this, SLOT( onViewManagerRemoved( SUIT_ViewManager* ) ), Qt::UniqueConnection );
454
455
456   // Set existing font for the python console in resources
457   if( !aResMgr->hasValue( "PyConsole", "font" ) )
458     return;
459
460   QFont f = aResMgr->fontValue( "PyConsole", "font" );
461   QFontDatabase fdb;
462   QStringList famdb = fdb.families();
463
464   if ( famdb.contains(f.family()) || !aResMgr->hasValue( "PyConsole", "additional_families" ) )
465     return;
466
467   QStringList anAddFamilies = aResMgr->stringValue( "PyConsole", "additional_families" ).split( ";", QString::SkipEmptyParts );
468   QString aFamily;
469   for ( QStringList::Iterator it = anAddFamilies.begin(); it != anAddFamilies.end(); ++it )
470   {
471     aFamily = *it;
472     if ( famdb.contains(aFamily) )
473     {
474       f.setFamily( aFamily );
475       aResMgr->setValue( "PyConsole", "font", f );
476       break;
477     }
478   }
479 }
480
481 /*!Destructor.
482  *\li Save window geometry.
483  *\li Save desktop geometry.
484  *\li Save resource maneger.
485  *\li Delete selection manager.
486  */
487 LightApp_Application::~LightApp_Application()
488 {
489   savePreferences();
490   delete mySelMgr;
491   delete myScreenHelper;
492   myPrefs = 0;
493 }
494
495 /*!Start application.*/
496 void LightApp_Application::start()
497 {
498   CAM_Application::start();
499
500   updateWindows();
501   updateViewManagers();
502   updateCommandsStatus();
503
504   putInfo( "" );
505   desktop()->statusBar()->showMessage( "" );
506
507   LightApp_EventFilter::Init();
508
509   onNewDoc();
510 }
511
512 /*!Closeapplication.*/
513 void LightApp_Application::closeApplication()
514 {
515 #ifndef DISABLE_QTXWEBBROWSER
516   QProcess::startDetached( "HelpBrowser",
517                            QStringList() << QString( "--remove=%1" ).arg( QApplication::instance()->applicationPid() ) );
518 #endif
519   CAM_Application::closeApplication();
520 }
521
522 /*!Gets application name.*/
523 QString LightApp_Application::applicationName() const
524 {
525   static QString _app_name;
526   if ( _app_name.isEmpty() )
527     _app_name = tr( "APP_NAME" );
528   return _app_name;
529 }
530
531 /*!Gets application version.*/
532 QString LightApp_Application::applicationVersion() const
533 {
534   static QString _app_version;
535
536   if ( _app_version.isEmpty() )
537   {
538     QString resVersion = tr( "APP_VERSION" );
539     if ( resVersion != "APP_VERSION" )
540     {
541       _app_version = resVersion;
542     }
543     else
544     {
545       _app_version = GUI_VERSION_STR;
546     }
547   }
548   return _app_version;
549 }
550
551 /*!Load module by \a name.*/
552 CAM_Module* LightApp_Application::loadModule( const QString& name, const bool showMsg )
553 {
554   CAM_Module* mod = CAM_Application::loadModule( name, showMsg );
555   if ( mod )
556   {
557     connect( this, SIGNAL( studyOpened() ), mod, SLOT( onModelOpened() ) );
558     connect( this, SIGNAL( studySaved() ),  mod, SLOT( onModelSaved() ) );
559     connect( this, SIGNAL( studyClosed() ), mod, SLOT( onModelClosed() ) );
560   }
561   return mod;
562 }
563
564 /*!Activate module by \a modName*/
565 bool LightApp_Application::activateModule( const QString& modName )
566 {
567   QString actName;
568   CAM_Module* prevMod = activeModule();
569
570   if ( prevMod )
571     actName = prevMod->moduleName();
572
573   QString name = modName;
574   if ( !name.isEmpty() && !moduleTitle( modName ).isEmpty() )
575     name = moduleTitle( modName );
576
577   if ( actName == name )
578     return true;
579
580   putInfo( tr( "ACTIVATING_MODULE" ).arg( name ) );
581
582   saveDockWindowsState();
583
584   if ( infoPanel() )
585     infoPanel()->clear();
586
587   bool status = CAM_Application::activateModule( name );
588
589   updateModuleActions();
590
591   putInfo( "" );
592
593   if ( !status )
594     return false;
595
596   updateWindows();
597   updateViewManagers();
598
599   if ( activeStudy() && activeStudy()->root() && objectBrowser() ) {
600     if ( objectBrowser()->root() != activeStudy()->root() )
601       objectBrowser()->setRoot( activeStudy()->root() );
602     updateObjectBrowser( true );
603   }
604
605   if ( activeModule() ) activeModule()->updateModuleVisibilityState();
606
607   updateActions();
608   return true;
609 }
610
611 /*!Gets selection manager.*/
612 LightApp_SelectionMgr* LightApp_Application::selectionMgr() const
613 {
614   return mySelMgr;
615 }
616
617 /*!Creat action "New window" for certain type of viewer:*/
618 void LightApp_Application::createActionForViewer( const int id,
619                                                   const int parentId,
620                                                   const QString& suffix,
621                                                   const int accel )
622 {
623   QString vtlt = tr( QString( "NEW_WINDOW_%1" ).arg( suffix ).toLatin1().constData() );
624   QString tip = tr( "CREATING_NEW_WINDOW" ).arg( vtlt.remove( "&" ) );
625   QAction* a = createAction( id,                      // menu action id
626                              tip,                     // status tip
627                              QIcon(),                 // icon
628                              vtlt,                    // menu text
629                              tip,                     // tooltip
630                              accel,                   // shortcut
631                              desktop(),               // parent
632                              false,                   // toggle flag
633                              this,                    // receiver
634                              SLOT( onNewWindow() ) ); // slot
635   createMenu( a, parentId, -1 );
636 }
637
638 /*!Create actions:*/
639
640 void LightApp_Application::createActions()
641 {
642   CAM_Application::createActions();
643
644   SUIT_Desktop* desk = desktop();
645   SUIT_ResourceMgr* resMgr = resourceMgr();
646
647   // Preferences
648   createAction( PreferencesId, tr( "TOT_DESK_PREFERENCES" ), QIcon(),
649                 tr( "MEN_DESK_PREFERENCES" ), tr( "PRP_DESK_PREFERENCES" ),
650                 Qt::CTRL+Qt::Key_P, desk, false, this, SLOT( onPreferences() ) );
651
652   // Help menu
653
654   int helpMenu = createMenu( tr( "MEN_DESK_HELP" ), -1, -1, 1000 );
655
656   QString url;
657
658   // a) Link to web site
659   if ( HAS_WWW_URL ) {
660     url = resMgr->stringValue("GUI", "site_url");
661     if ( !url.isEmpty() ) {
662       QString title = tr ( "SALOME_SITE" );
663       QAction* as = createAction( WebSiteId, title,
664                                   resMgr->loadPixmap( "LightApp", tr( "ICON_WWW" ), false ),
665                                   title, title,
666                                   0, desk, false, this, SLOT( onHelpContentsModule() ) );
667       as->setData( url );
668       createMenu( as, helpMenu, -1, 0 );
669     }
670   }
671
672   // b) Link to Forum
673   if ( HAS_FORUM_URL ) {
674     url = resMgr->stringValue("GUI", "forum_url");
675     if ( !url.isEmpty() ) {
676       QString title = tr ( "SALOME_FORUM" );
677       QAction* af = createAction( ForumId, title,
678                                   resMgr->loadPixmap( "LightApp", tr( "ICON_WWW" ), false ),
679                                   title, title,
680                                   0, desk, false, this, SLOT( onHelpContentsModule() ) );
681       af->setData( url );
682       createMenu( af, helpMenu, -1, 0 );
683     }
684   }
685
686   // c) Link to YouTube channel
687   if ( HAS_YOUTUBE_URL ) {
688     url = resMgr->stringValue("GUI", "channel_url");
689     if ( !url.isEmpty() ) {
690       createMenu( separator(), helpMenu, -1, 0 );
691       QString title = tr ( "SALOME_VIDEO_TUTORIALS" );
692       QAction* av = createAction( VideosId, title,
693                                   resMgr->loadPixmap( "LightApp", tr( "ICON_LIFE_RIGN" ), false ),
694                                   title, tr( "PRP_SALOME_VIDEO_TUTORIALS" ),
695                                   0, desk, false, this, SLOT( onHelpContentsModule() ) );
696       av->setData( url );
697       createMenu( av, helpMenu, -1, 0 );
698     }
699   }
700
701   // d) Link to Tutorials
702   if ( HAS_TUTORIAL_URL ) {
703     url = resMgr->stringValue("GUI", "tutorials_url");
704     if ( !url.isEmpty() ) {
705       QString title = tr ( "SALOME_TUTORIALS" );
706       QAction* as = createAction( TutorialsId, title,
707                                   resMgr->loadPixmap( "LightApp", tr( "ICON_WWW" ), false ),
708                                   title, tr( "PRP_SALOME_TUTORIALS" ),
709                                   0, desk, false, this, SLOT( onHelpContentsModule() ) );
710       as->setData( url );
711       createMenu( as, helpMenu, -1, 0 );
712     }
713   }
714
715   // e) Help for modules
716
717   QStringList aModuleList;
718   modules( aModuleList, false );
719   aModuleList.prepend( "GUI" );
720   aModuleList.prepend( "KERNEL" );
721
722   foreach( QString aModule, aModuleList )
723     createHelpItems( aModule );
724
725   // f) Additional help items
726
727   int id = LightApp_Application::UserID + FIRST_HELP_ID + 1000;
728   createMenu( separator(), helpMenu, -1, 10 );
729
730   QStringList addHelpItems = resMgr->parameters( "add_help" );
731   foreach ( QString paramName, addHelpItems ) {
732     QString helpItem = getHelpItem( "add_help", paramName );
733     if ( !helpItem.isEmpty() )
734     {
735       QPixmap helpIcon = helpItem.startsWith( "http", Qt::CaseInsensitive ) ?
736         resMgr->loadPixmap( "STD", tr( "ICON_WWW" ), false ) : resMgr->loadPixmap( "STD", tr( "ICON_HELP" ), false );
737       QAction* a = createAction( id++, paramName, helpIcon, paramName, paramName,
738                                  0, desk, false, this, SLOT( onHelpContentsModule() ) );
739       a->setData( helpItem );
740       createMenu( a, helpMenu, -1, 10 );
741     }
742   }
743
744   //! MRU
745   static QtxMRUAction* mru = new QtxMRUAction( tr( "TOT_DESK_MRU" ), tr( "MEN_DESK_MRU" ), 0 );
746   connect( mru, SIGNAL( activated( const QString& ) ), this, SLOT( onMRUActivated( const QString& ) ) );
747   registerAction( MRUId, mru );
748
749   // List of modules
750   LightApp_ModuleAction* moduleAction = new LightApp_ModuleAction( resMgr, desk );
751   registerAction( ModulesListId, moduleAction );
752   // a. here we add regular modules (specified to GUI via --modules cmd line option, or default list from configuration)
753   // b. custom modules are added in customize() method
754   QStringList modList;
755   modules( modList, false );
756   foreach ( QString aModule, modList )
757     moduleAction->insertModule( aModule, moduleIcon( aModule, 20 ) ); // scale icon to 20x20 pix
758
759   connect( this, SIGNAL( moduleActivated( QString ) ),
760            moduleAction, SLOT( setActiveModule( QString ) ) );
761   connect( moduleAction, SIGNAL( moduleActivated( const QString& ) ),
762            this, SLOT( onModuleActivation( const QString& ) ) );
763   connect( moduleAction, SIGNAL( adding() ),
764            this, SLOT( onExtAdding() ) );
765   connect( moduleAction, SIGNAL( removing( QString ) ),
766            this, SLOT( onExtRemoving( QString ) ) );
767   connect( moduleAction, SIGNAL(showExtInfo()),
768            this, SLOT(onShowExtInfo()));
769
770   addExtensionsActions(moduleAction);
771
772   // New window
773   int windowMenu = createMenu( tr( "MEN_DESK_WINDOW" ), -1, MenuWindowId, 100 );
774   int newWinMenu = createMenu( tr( "MEN_DESK_NEWWINDOW" ), windowMenu, -1, 0 );
775
776   createAction( CloseId, tr( "TOT_CLOSE" ), QIcon(), tr( "MEN_DESK_CLOSE" ), tr( "PRP_CLOSE" ),
777                 Qt::CTRL+Qt::Key_F4, desk, false, this, SLOT( onCloseWindow() ) );
778   createAction( CloseAllId, tr( "TOT_CLOSE_ALL" ), QIcon(), tr( "MEN_DESK_CLOSE_ALL" ), tr( "PRP_CLOSE_ALL" ),
779                 0, desk, false, this, SLOT( onCloseAllWindow() ) );
780   createAction( GroupAllId, tr( "TOT_GROUP_ALL" ), QIcon(), tr( "MEN_DESK_GROUP_ALL" ), tr( "PRP_GROUP_ALL" ),
781                 0, desk, false, this, SLOT( onGroupAllWindow() ) );
782
783   createMenu( CloseId,     windowMenu, 0, -1 );
784   createMenu( CloseAllId,  windowMenu, 0, -1 );
785   createMenu( GroupAllId,  windowMenu, 0, -1 );
786   createMenu( separator(), windowMenu, -1, 0 );
787
788 #ifndef DISABLE_GLVIEWER
789   createActionForViewer( NewGLViewId, newWinMenu, QString::number( 0 ), Qt::ALT+Qt::Key_G );
790 #endif
791 #ifndef DISABLE_PLOT2DVIEWER
792   createActionForViewer( NewPlot2dId, newWinMenu, QString::number( 1 ), Qt::ALT+Qt::Key_P );
793 #endif
794 #ifndef DISABLE_OCCVIEWER
795   createActionForViewer( NewOCCViewId, newWinMenu, QString::number( 2 ), Qt::ALT+Qt::Key_O );
796 #endif
797 #ifndef DISABLE_VTKVIEWER
798   createActionForViewer( NewVTKViewId, newWinMenu, QString::number( 3 ), Qt::ALT+Qt::Key_K );
799 #endif
800 #ifndef DISABLE_QXGRAPHVIEWER
801   createActionForViewer( NewQxSceneViewId, newWinMenu, QString::number( 4 ), Qt::ALT+Qt::Key_S );
802 #endif
803 #ifndef DISABLE_GRAPHICSVIEW
804   createActionForViewer( NewGraphicsViewId, newWinMenu, QString::number( 5 ), Qt::ALT+Qt::Key_C );
805 #endif
806 #ifndef DISABLE_PVVIEWER
807   createActionForViewer( NewPVViewId, newWinMenu, QString::number( 6 ), Qt::ALT+Qt::Key_A );
808 #endif
809 #ifndef DISABLE_PYVIEWER
810   createActionForViewer( NewPyViewerId, newWinMenu, QString::number( 7 ), Qt::ALT+Qt::Key_Y );
811 #endif
812 #ifndef DISABLE_PV3DVIEWER
813   createActionForViewer( NewPV3DViewId, newWinMenu, QString::number( 8 ), Qt::ALT+Qt::Key_3 );
814 #endif
815
816   createAction( RenameId, tr( "TOT_RENAME" ), QIcon(), tr( "MEN_DESK_RENAME" ), tr( "PRP_RENAME" ),
817                 Qt::ALT+Qt::SHIFT+Qt::Key_R, desk, false, this, SLOT( onRenameWindow() ) );
818   createMenu( RenameId, windowMenu, -1 );
819
820   int fileMenu = createMenu( tr( "MEN_DESK_FILE" ), -1 );
821   createMenu( PreferencesId, fileMenu, 50, -1 );
822   createMenu( separator(), fileMenu, -1, 50, -1 );
823
824   createMenu( separator(), fileMenu, -1, 100, -1 );
825   createMenu( MRUId, fileMenu, 100, -1 );
826   createMenu( separator(), fileMenu, -1, 100, -1 );
827
828 #ifdef USE_SALOME_STYLE
829   createAction( StyleId, tr( "TOT_THEME" ), QIcon(), tr( "MEN_DESK_THEME" ), tr( "PRP_THEME" ),
830                 0, desk, false, this, SLOT( onStylePreferences() ) );
831 #endif // USE_SALOME_STYLE
832
833   createAction( FullScreenId, tr( "TOT_FULLSCREEN" ), QIcon(), tr( "MEN_DESK_FULLSCREEN" ), tr( "PRP_FULLSCREEN" ),
834                 Qt::Key_F11, desk, false, this, SLOT( onFullScreen() ) );
835
836
837   int viewMenu = createMenu( tr( "MEN_DESK_VIEW" ), -1 );
838   createMenu( separator(), viewMenu, -1, 20, -1 );
839 #ifdef USE_SALOME_STYLE
840   createMenu( StyleId, viewMenu, 20, -1 );
841 #endif // USE_SALOME_STYLE
842   createMenu( FullScreenId, viewMenu, 20, -1 );
843   createMenu( separator(), viewMenu, -1, 20, -1 );
844   createMenu( ModulesListId, viewMenu );
845
846   int modTBar = createTool( tr( "INF_TOOLBAR_MODULES" ),    // title (language-dependant)
847                             QString( "SalomeModules" ) );   // name (language-independant)
848   createTool( ModulesListId, modTBar );
849 }
850
851 /*!Create actions for installed extensions:*/
852 void LightApp_Application::addExtensionsActions(LightApp_ModuleAction* moduleAction)
853 {
854   if (!moduleAction)
855   {
856     MESSAGE("Couldn't get a moduleAction! Return.");
857     return;
858   }
859
860   // It should be set on the app start if we use an --on_demand 1 command line option
861   auto extRootDir = getenv(salomeAppDir);
862   if (!extRootDir)
863   {
864     // It's ok if we don't use --on_demand
865     return;
866   }
867   SCRUTE(extRootDir);
868
869    // Import Python module that manages SALOME extensions.
870   PyLockWrapper lck; // acquire GIL
871   PyObjWrapper extensionQuery = PyImport_ImportModule((char*)"SalomeOnDemandTK.extension_query");
872   PyObjWrapper installedExtensions = PyObject_CallMethod(
873       extensionQuery, (char*)"ext_by_name", (char*)"s", extRootDir);
874   if (!installedExtensions)
875   {
876     return;
877   }
878
879   // Iterate installed extensions
880   for (Py_ssize_t pos = 0; pos < PyList_Size(installedExtensions); ++pos)
881   {
882     // Get the current ext name
883     auto extNameItem = PyList_GetItem(installedExtensions, pos);
884     QString extName(PyUnicode_AsUTF8(extNameItem));
885     SCRUTE(extName.toStdString());
886
887     moduleAction->insertExtension(extName);
888   }
889
890   // Udate actions only once after all of them were already inserted
891   moduleAction->updateExtActions();
892 }
893
894 /*!
895   Customize actions.
896 */
897 void LightApp_Application::customize()
898 {
899   // List of modules
900   LightApp_ModuleAction* moduleAction = qobject_cast<LightApp_ModuleAction*>( action( ModulesListId ) );
901   // a. regular modules were added in createActions() method
902   // b. here we add custom modules (manually added by the user)
903   if ( HAS_SALOME_ON_DEMAND )
904   {
905     QStringList modList = resourceMgr()->stringValue( "launch", "user_modules" ).split( ";", QString::SkipEmptyParts );
906     foreach ( QString aModule, modList )
907       addUserModule(  aModule, resourceMgr()->stringValue( "user_modules", aModule ) );
908   }
909   else
910   {
911     moduleAction->setModeEnabled( LightApp_ModuleAction::AddRemove, false );
912   }
913 }
914
915 /*!On module activation action.*/
916 void LightApp_Application::onModuleActivation( const QString& modTitle )
917 {
918   // Force user to create/open a study before module activation
919   QPixmap icon = moduleIcon( modTitle );
920   bool cancelled = false;
921
922   while ( !modTitle.isEmpty() && !activeStudy() && !cancelled ){
923     LightApp_ModuleDlg aDlg( desktop(), modTitle, icon );
924     QMap<int, QString> opmap = activateModuleActions();
925     for ( QMap<int, QString>::ConstIterator it = opmap.begin(); it != opmap.end(); ++it )
926       aDlg.addButton( it.value(), it.key() );
927
928     int res = aDlg.exec();
929     if ( res ) {
930       // some operation is selected
931       moduleActionSelected( res );
932     }
933     else {
934       // cancelled
935       putInfo( tr("INF_CANCELLED") );
936       emit moduleActivated( QString() );
937       cancelled = true;
938     }
939   }
940
941   if ( !cancelled )
942     activateModule( modTitle );
943 }
944
945 /*!On extension adding action.*/
946 void LightApp_Application::onExtAdding()
947 {
948   // Show dialog to browse a salome extension file
949   QStringList filters = (QStringList() << tr("Salome extension files") + " (*.salomex)" << tr("All files") + " (*)");
950   QStringList paths = getOpenFileNames(QString(), filters.join(";;"), QString(), desktop());
951   if (paths.isEmpty())
952   {
953     MESSAGE("Adding an extension was cancelled.");
954     return;
955   }
956
957   LightApp_ModuleAction* moduleAction = qobject_cast<LightApp_ModuleAction*>(action(ModulesListId));
958   if (!moduleAction)
959   {
960     MESSAGE("Couldn't get a moduleAction! Return.");
961     return;
962   }
963
964   // It should be set on the app start
965   auto extRootDir = getenv(salomeAppDir);
966   if (!extRootDir)
967   {
968     SUIT_MessageBox::warning(desktop(), tr("WRN_WARNING"), tr("WRN_SALOME_APPLICATION_DIR"));
969     return;
970   }
971   SCRUTE(extRootDir);
972
973   // We'll load all the extensions modules from this path
974   auto SalomeExtDir = QDir::cleanPath(QString(extRootDir) + QDir::separator() + "__SALOME_EXT__");
975   SCRUTE(SalomeExtDir.toStdString());
976
977   // Import Python module that manages SALOME extensions.
978   // It seems to be faster to lock and unlock once than on each iteration,
979   // but I didn't compare the performance for each case.
980   PyLockWrapper lck; // acquire GIL
981   PyObjWrapper extensionUnpacker = PyImport_ImportModule((char*)"SalomeOnDemandTK.extension_unpacker");
982
983   // Loop via selected extensions files
984   foreach(QString path, paths)
985   {
986     std::string extPath = path.toStdString();
987     SCRUTE(extPath);
988
989     PyObjWrapper unpackedModules = PyObject_CallMethod(
990       extensionUnpacker, (char*)"install_salomex", (char*)"s", extPath.c_str());
991     if (!unpackedModules || unpackedModules == Py_None)
992     {
993       SUIT_MessageBox::warning(desktop(), tr("WRN_WARNING"), tr("WRN_FAILED_UNPACK_EXTENSION").arg(path) );
994       continue;
995     }
996
997     // Iterate all the components (modules) for this extension
998     for (Py_ssize_t pos = 0; pos < PyList_Size(unpackedModules); ++pos)
999     {
1000       auto moduleNameItem = PyList_GetItem(unpackedModules, pos);
1001       QString moduleName(PyUnicode_AsUTF8(moduleNameItem));
1002       SCRUTE(moduleName.toStdString());
1003
1004       addUserModule(moduleName, SalomeExtDir, true);
1005     }
1006
1007     // Add an extension to GUI
1008     if (moduleAction)
1009     {
1010       QFileInfo extFileInfo(path);
1011       QString extName = extFileInfo.baseName();
1012       moduleAction->insertExtension(extName);
1013     }
1014   }
1015
1016   // Udate actions only once after all of them were already inserted
1017   moduleAction->updateExtActions();
1018 }
1019
1020 /*Add user module.*/
1021 bool LightApp_Application::addUserModule( const QString& name, const QString& root, bool interactive )
1022 {
1023   if ( name.isEmpty() || root.isEmpty() )
1024     return false;
1025
1026   if ( !moduleTitle( name ).isEmpty() ) // module alread in current session
1027   {
1028     if ( interactive )
1029       SUIT_MessageBox::warning( desktop(), tr( "WRN_WARNING" ), tr( "WRN_MODULE_DUPLICATED" ).arg( name ) );
1030     return false;
1031   }
1032   if ( !QFileInfo( root ).exists() ) // root directory does not exist
1033   {
1034     if ( interactive )
1035       SUIT_MessageBox::warning( desktop(), tr( "WRN_WARNING" ), tr( "WRN_MODULE_ROOT_DOES_NOT_EXIST" ).arg( root ) );
1036     return false;
1037   }
1038   // resources directory
1039   QString resDir = Qtx::joinPath( QStringList() << root << "share" << "salome" << "resources" << name.toLower() );
1040   if ( !QFileInfo( resDir ).exists() ) // resources directory does not exist
1041   {
1042     if ( interactive )
1043       SUIT_MessageBox::warning( desktop(), tr( "WRN_WARNING" ), tr( "WRN_MODULE_BAD_RESDIR" ).arg( resDir ) );
1044     return false;
1045   }
1046
1047   SUIT_ResourceMgr* resMgr = resourceMgr();
1048
1049   // read XML configuration file
1050   resMgr->setConstant(QString("%1_ROOT_DIR").arg(name), root);
1051   if (!resMgr->addResource(resDir)) // cannot read configuration
1052   {
1053     if ( interactive )
1054       SUIT_MessageBox::warning( desktop(), tr( "WRN_WARNING" ), tr( "WRN_MODULE_CANNOT_READ_CFG" ).arg( resDir ) );
1055     return false;
1056   }
1057   // fill in information about module
1058   if ( !appendModuleInfo( name ) ) // cannot append module information to internal table
1059   {
1060     if ( interactive )
1061       SUIT_MessageBox::warning( desktop(), tr( "WRN_WARNING" ), tr( "WRN_MODULE_BAD_CFG_FILE" ).arg( name ) );
1062     return false;
1063   }
1064
1065   // load translations
1066   resMgr->loadLanguage(name);
1067
1068   // Do all the GUI related stuff only if the module supports that.
1069   // We already did check for GUI inside CAM_Application::appendModuleInfo, but
1070   // need to do that again.
1071   // TODO: Maybe it's better to return ModuleInfo from appendModuleInfo() and check status.
1072   const QString title = resMgr->stringValue(name, "name", QString()).trimmed();
1073   if (resMgr->booleanValue(name, "gui", false) || !title.isEmpty())
1074   {
1075     // Append module to the menu / toolbar
1076     LightApp_ModuleAction* moduleAction = qobject_cast<LightApp_ModuleAction*>(action(ModulesListId));
1077     if (moduleAction)
1078     {
1079       // Scale icon to 20x20 pix
1080       moduleAction->insertModule(moduleTitle(name), moduleIcon(moduleTitle(name), 20), true);
1081     }
1082   }
1083
1084   // add empty page to Preferences dialog
1085   LightApp_Preferences* prefs = preferences();
1086   if ( prefs && !prefs->hasModule( moduleTitle( name ) ) )
1087   {
1088     int prefId = prefs->addPreference( moduleTitle( name ) );
1089     prefs->setItemIcon( prefId, moduleIcon( moduleTitle( name ), 20 ) ); // scale icon to 20x20 pix
1090     LightApp_Module* m = qobject_cast<LightApp_Module*>( module( moduleTitle( name ) ) );
1091     if ( m )
1092     {
1093       m->createPreferences();
1094       emptyPreferences( moduleTitle( name ) );
1095     }
1096   }
1097   // add Help items
1098   createHelpItems( moduleTitle( name ) );
1099   // extend module catalog
1100   QString catalogue = QDir( resDir ).filePath( QString( "%1Catalog.xml" ).arg( name ) );
1101   addCatalogue( name, catalogue );
1102   // update windows (in particular, Info panel)
1103   updateWindows();
1104   // save module in the resource manager
1105   if ( interactive )
1106   {
1107     QStringList customModules = resMgr->stringValue("launch", "user_modules").split(";", QString::SkipEmptyParts);
1108     customModules << name;
1109     customModules.removeDuplicates();
1110     resMgr->setValue( "launch", "user_modules", customModules.join( ";" ) );
1111     resMgr->setValue( "user_modules", name, root );
1112   }
1113   return true;
1114 }
1115
1116 /*!Remove user module from UI.*/
1117 void LightApp_Application::removeUserModule(const QString& moduleInnerName, LightApp_ModuleAction* moduleAction)
1118 {
1119   MESSAGE("Remove a module from UI...");
1120   SCRUTE(moduleInnerName.toStdString());
1121
1122   // There is a some confusion point, because now we have a module's 'inner' name
1123   // from the extension's salomexd file.
1124   // But, in the next GUI methods we need to use a module title (user name).
1125   // For example, PYHELLO (inner name) and PyHello (user name to display in GUI).
1126   // Then, from the inner module's name we need to get a user one.
1127   QString moduleUserName = moduleTitle(moduleInnerName);
1128   SCRUTE(moduleUserName.toStdString());
1129
1130   // Set current state in modules combo box
1131   // Don't confuse again, because activeModule()->moduleName() returns a module title, not an inner one!
1132   if (activeModule() && activeModule()->moduleName() == moduleUserName)
1133     activateModule("");
1134
1135   // Remove from "Modules" menu and toolbar
1136   if (moduleAction)
1137   {
1138     moduleAction->removeModule(moduleUserName);
1139   }
1140
1141   // Remove Help menu items
1142   removeHelpItems(moduleUserName);
1143
1144   // Remove Preferences
1145   LightApp_Preferences* prefs = preferences();
1146   if (prefs)
1147     prefs->removeModule(moduleUserName);
1148
1149   // Remove settings
1150   // Here we use an inner module name!
1151   QStringList customModules = resourceMgr()->stringValue("launch", "user_modules").split(";", QString::SkipEmptyParts);
1152   customModules.removeAll(moduleInnerName);
1153   resourceMgr()->setValue("launch", "user_modules", customModules.join(";"));
1154   removeModuleInfo(moduleInnerName);
1155 }
1156
1157 /*!On module removing action.*/
1158 void LightApp_Application::onExtRemoving(const QString& title)
1159 {
1160   MESSAGE("Remove an extension...");
1161   std::string extName = title.toStdString();
1162   SCRUTE(extName);
1163
1164   // Ask user if he's ready to completely remove an extension and all its modules.
1165   int answer = SUIT_MessageBox::question(
1166     desktop(),
1167     tr("TLT_REMOVE_EXTENSION"),
1168     tr("QUE_REMOVE_EXTENSION").arg(title),
1169     SUIT_MessageBox::Ok | SUIT_MessageBox::Cancel,
1170     SUIT_MessageBox::Ok
1171   );
1172
1173   if (answer == SUIT_MessageBox::Cancel)
1174   {
1175     MESSAGE("Removing of an extension was cancelled");
1176     return; // cancelled
1177   }
1178   
1179   if (activeStudy() && activeStudy()->isModified() && !onSaveDoc())
1180   {
1181     // doc is not saved, or saving cancelled
1182     SUIT_MessageBox::warning(
1183       desktop(),
1184       tr("WRN_WARNING"), tr("WRN_CANCEL_REMOVE_EXTENSION_UNSAVE").arg(title)
1185     );
1186
1187     return;
1188   }
1189
1190   // It should be set on the app start
1191   auto extRootDir = getenv(salomeAppDir);
1192   if (!extRootDir)
1193   {
1194     SUIT_MessageBox::warning(desktop(), tr("WRN_WARNING"), tr("WRN_SALOME_APPLICATION_DIR"));
1195     return;
1196   }
1197   SCRUTE(extRootDir);
1198
1199   // Import Python module that manages SALOME extensions.
1200   PyLockWrapper lck; // acquire GIL
1201   PyObjWrapper extensionRemover = PyImport_ImportModule((char*)"SalomeOnDemandTK.extension_remover");
1202   PyObjWrapper removedModules = PyObject_CallMethod(
1203       extensionRemover, (char*)"remove_salomex", (char*)"ss", extRootDir, extName.c_str());
1204   if (!removedModules || removedModules == Py_None)
1205   {
1206     SUIT_MessageBox::warning(desktop(), tr("WRN_WARNING"), tr("WRN_FAILED_REMOVE_EXTENSION").arg(title));
1207     return;
1208   }
1209
1210   // We need it to remove ext and modules from UI
1211   LightApp_ModuleAction* moduleAction = qobject_cast<LightApp_ModuleAction*>(action(ModulesListId));
1212   if (!moduleAction)
1213   {
1214     MESSAGE("Cannot get a pointer to LightApp_ModuleAction! Removing from menue and toolbars will skipped.");
1215   }
1216
1217   // Module's content was already removed on python remove_salomex call,
1218   // then all we do next - just remove UI items.
1219   for (Py_ssize_t pos = 0; pos < PyList_Size(removedModules); ++pos)
1220   {
1221     // Get the current module's name
1222     auto moduleNameItem = PyList_GetItem(removedModules, pos);
1223     const QString moduleInnerName(PyUnicode_AsUTF8(moduleNameItem));
1224
1225     removeUserModule(moduleInnerName, moduleAction);
1226   }
1227
1228   // Remove an ext from UI
1229   if (moduleAction)
1230   {
1231     moduleAction->removeExtension(title);
1232   }
1233
1234   // Update windows (in particular, Info panel)
1235   updateWindows();
1236 }
1237
1238 /*!On show extension info action.*/
1239 void LightApp_Application::onShowExtInfo()
1240 {
1241   // Show dialog with information about loaded salome extensions
1242   LightApp_ExtInfoDlg dlg(desktop());
1243   dlg.exec();
1244 }
1245
1246 /*!Default module activation.*/
1247 QString LightApp_Application::defaultModule() const
1248 {
1249   QStringList aModuleNames;
1250   modules( aModuleNames, false ); // obtain a complete list of module names for the current configuration
1251   //! If there's the one and only module --> activate it automatically
1252   //! TODO: Possible improvement - default module can be taken from preferences
1253   return aModuleNames.count() > 1 ? "" : ( aModuleNames.count() ? aModuleNames.first() : "" );
1254 }
1255
1256 /*!On new window slot.*/
1257 void LightApp_Application::onNewWindow()
1258 {
1259   const QObject* obj = sender();
1260   if ( !obj || !obj->inherits( "QAction" ) )
1261     return;
1262
1263   QString type;
1264   int id = actionId( (QAction*)obj );
1265   switch ( id )
1266   {
1267 #ifndef DISABLE_GLVIEWER
1268   case NewGLViewId:
1269     type = GLViewer_Viewer::Type();
1270     break;
1271 #endif
1272 #ifndef DISABLE_PLOT2DVIEWER
1273   case NewPlot2dId:
1274     type = Plot2d_Viewer::Type();
1275     break;
1276 #endif
1277 #ifndef DISABLE_OCCVIEWER
1278   case NewOCCViewId:
1279     type = OCCViewer_Viewer::Type();
1280     break;
1281 #endif
1282 #ifndef DISABLE_VTKVIEWER
1283   case NewVTKViewId:
1284     type = VTKViewer_Viewer::Type();
1285     break;
1286 #endif
1287 #ifndef DISABLE_QXGRAPHVIEWER
1288   case NewQxSceneViewId:
1289     type = QxScene_Viewer::Type();
1290     break;
1291 #endif
1292 #ifndef DISABLE_GRAPHICSVIEW
1293   case NewGraphicsViewId:
1294     type = GraphicsView_Viewer::Type();
1295     break;
1296 #endif
1297 #ifndef DISABLE_PVVIEWER
1298   case NewPVViewId:
1299     type = PVViewer_Viewer::Type();
1300     break;
1301 #endif
1302 #ifndef DISABLE_PYVIEWER
1303   case NewPyViewerId:
1304     type = PyViewer_Viewer::Type();
1305     break;
1306 #endif
1307 #ifndef DISABLE_PV3DVIEWER
1308   case NewPV3DViewId:
1309     type = PV3DViewer_ViewModel::Type();
1310     break;
1311 #endif
1312   }
1313
1314   if ( !type.isEmpty() )
1315     createViewManager( type );
1316 }
1317
1318 /*!
1319   SLOT: Creates new document
1320 */
1321 void LightApp_Application::onNewDoc()
1322 {
1323   if ( !checkExistingDoc() )
1324     return;
1325
1326   //asl: fix for 0020515
1327   saveDockWindowsState();
1328
1329   CAM_Application::onNewDoc();
1330 }
1331
1332 /*!
1333   SLOT: Opens new document
1334 */
1335 void LightApp_Application::onOpenDoc()
1336 {
1337   SUIT_Study* study = activeStudy();
1338
1339   if ( !checkExistingDoc( false ) )
1340     return;
1341
1342   QString aName = getFileName( true, QString(), getFileFilter( true ), QString(), 0 );
1343   if ( aName.isNull() ) //Cancel
1344     return;
1345
1346   onOpenDoc( aName );
1347
1348   if ( !study ) // new study will be create in THIS application
1349   {
1350     updateWindows();
1351     updateViewManagers();
1352   }
1353 }
1354
1355 bool LightApp_Application::canOpenDoc( const QString& )
1356 {
1357   return true;
1358 }
1359
1360 /*!
1361   SLOT: Opens new document.
1362   \param aName - name of file
1363 */
1364 bool LightApp_Application::onOpenDoc( const QString& aName )
1365 {
1366   if ( !canOpenDoc(aName)) {
1367     bool showError = !property("open_study_from_command_line").isValid() ||
1368       !property("open_study_from_command_line").toBool();
1369
1370     putInfo( tr("OPEN_DOCUMENT_PROBLEM") );
1371     if ( showError )
1372       SUIT_MessageBox::critical( desktop(), tr("ERR_ERROR"), tr("OPEN_DOCUMENT_PROBLEM"));
1373
1374     return false;
1375   }
1376
1377   closeDoc(false);
1378
1379   if ( !checkExistingDoc() )
1380     return false;
1381
1382   saveDockWindowsState();
1383
1384   // We should take mru action first because this application instance can be deleted later.
1385   QtxMRUAction* mru = ::qobject_cast<QtxMRUAction*>( action( MRUId ) );
1386
1387   bool res = CAM_Application::onOpenDoc( aName );
1388
1389   if ( mru )
1390   {
1391     if ( res )
1392       mru->insert( aName );
1393     else
1394       mru->remove( aName );
1395   }
1396   return res;
1397 }
1398
1399 /*!
1400   SLOT: Displays "About" message box
1401 */
1402 void LightApp_Application::onHelpAbout()
1403 {
1404   LightApp_AboutDlg dlg( applicationName(), applicationVersion(), desktop() );
1405   dlg.exec();
1406 }
1407
1408 /*!
1409   Private SLOT: Called on selection is changed
1410   Dispatchs active module that selection is changed
1411 */
1412 void LightApp_Application::onSelection()
1413 {
1414   //MESSAGE("onSelection")
1415   onSelectionChanged();
1416
1417   if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) )
1418     ((LightApp_Module*)activeModule())->selectionChanged();
1419 }
1420
1421 /*!
1422   Sets active study.
1423  \param study - SUIT_Study.
1424 */
1425 void LightApp_Application::setActiveStudy( SUIT_Study* study )
1426 {
1427   CAM_Application::setActiveStudy( study );
1428 }
1429
1430 /*!
1431   Enables/Disables menu items and toolbar buttons. Rebuild menu
1432 */
1433 void LightApp_Application::updateCommandsStatus()
1434 {
1435   CAM_Application::updateCommandsStatus();
1436   QAction* a = 0;
1437
1438 #ifndef DISABLE_GLVIEWER
1439   a = action( NewGLViewId );
1440   if( a )
1441     a->setEnabled( activeStudy() );
1442 #endif
1443
1444 #ifndef DISABLE_PLOT2DVIEWER
1445   a = action( NewPlot2dId );
1446   if( a )
1447     a->setEnabled( activeStudy() );
1448 #endif
1449
1450 #ifndef DISABLE_OCCVIEWER
1451   a = action( NewOCCViewId );
1452   if( a )
1453     a->setEnabled( activeStudy() );
1454 #endif
1455
1456 #ifndef DISABLE_VTKVIEWER
1457   a = action( NewVTKViewId );
1458   if( a )
1459     a->setEnabled( activeStudy() );
1460 #endif
1461
1462 #ifndef DISABLE_QXGRAPHVIEWER
1463   a = action( NewQxSceneViewId );
1464   if( a )
1465     a->setEnabled( activeStudy() );
1466 #endif
1467
1468 #ifndef DISABLE_GRAPHICSVIEW
1469   a = action( NewGraphicsViewId );
1470   if( a )
1471     a->setEnabled( activeStudy() );
1472 #endif
1473
1474 #ifndef DISABLE_PVVIEWER
1475   a = action( NewPVViewId );
1476   if( a )
1477     a->setEnabled( activeStudy() );
1478 #endif
1479
1480 #ifndef DISABLE_PYVIEWER
1481   a = action( NewPyViewerId );
1482   if( a )
1483     a->setEnabled( activeStudy() );
1484 #endif
1485
1486 #ifndef DISABLE_PV3DVIEWER
1487   a = action( NewPV3DViewId );
1488   if( a )
1489     a->setEnabled( activeStudy() );
1490 #endif
1491 }
1492
1493 /*!
1494   \class RunBrowser
1495   Runs system command in separate thread
1496 */
1497 class RunBrowser: public QThread
1498 {
1499 public:
1500   static void execute( LightApp_Application* application,
1501                        const QString& browser,
1502                        const QString& parameters,
1503                        const QString& url )
1504   {
1505     (new RunBrowser( application, browser, parameters, url ))->start();
1506   }
1507
1508 protected:
1509   RunBrowser( LightApp_Application* application,
1510               const QString&        browser,
1511               const QString&        parameters,
1512               const QString&        url)
1513     : myApplication( application ),
1514       myBrowser( browser ),
1515       myParameters( parameters ),
1516       myUrl( url )
1517   {
1518     if ( !myUrl.startsWith( "http", Qt::CaseInsensitive ) )
1519     {
1520       // normalize path
1521       if ( myUrl.startsWith( "file://", Qt::CaseInsensitive ) )
1522         myUrl = myUrl.remove( 0, QString( "file://" ).count() );
1523       // For the external browser we always specify 'file://' protocol,
1524       // because some web browsers (e.g. Mozilla Firefox) can't open local file without protocol.
1525       myUrl = myUrl.prepend( "file://" );
1526     }
1527     connect(this, SIGNAL(finished()), SLOT(deleteLater()));
1528   }
1529
1530   virtual void run()
1531   {
1532     if ( !myBrowser.isEmpty() && !myUrl.isEmpty() )
1533     {
1534       QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
1535 #ifdef WIN32
1536       QString cmdLine = QString( "\"%1\" %2 \"%3\"" ).arg( myBrowser, myParameters, myUrl );
1537 #else
1538       QString cmdLine = QString( "%1 %2 \"%3\"" ).arg( myBrowser, myParameters, myUrl );
1539       // remove LD_LIBRARY_PATH from the environement before starting launcher to avoid bad interactions.
1540       // (especially in the case of universal binaries)
1541       env.remove("LD_LIBRARY_PATH");
1542 #endif
1543       QProcess* proc = new QProcess();
1544       proc->setProcessEnvironment(env);
1545       proc->start( cmdLine );
1546       if ( !proc->waitForStarted() )
1547       {
1548         SALOME_CustomEvent* ce2000 = new SALOME_CustomEvent( 2000 );
1549         QString* msg = new QString( QObject::tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ).arg( myBrowser, myUrl ) );
1550         ce2000->setData( msg );
1551         QApplication::postEvent( myApplication, ce2000 );
1552       }
1553     }
1554   }
1555
1556 private:
1557   LightApp_Application* myApplication;
1558   QString               myBrowser;
1559   QString               myParameters;
1560   QString               myUrl;
1561 };
1562
1563 void LightApp_Application::showHelp( const QString& path )
1564 {
1565   SUIT_ResourceMgr* resMgr = resourceMgr();
1566
1567 #if DISABLE_QTXWEBBROWSER
1568   bool useExternalBrowser = true;
1569 #else
1570   bool useExternalBrowser = resMgr->booleanValue("ExternalBrowser", "use_external_browser", false );
1571 #endif
1572
1573   if ( useExternalBrowser )
1574   {
1575 #ifdef WIN32
1576     QString browser = resMgr->stringValue( "ExternalBrowser", "winapplication" ) ;
1577 #else
1578     QString browser = resMgr->stringValue( "ExternalBrowser", "application" );
1579 #endif
1580     QString parameters = resMgr->stringValue("ExternalBrowser", "parameters");
1581
1582     if ( !browser.isEmpty() )
1583     {
1584       RunBrowser::execute( this, browser, parameters, path );
1585     }
1586     else
1587     {
1588       if ( SUIT_MessageBox::question( desktop(), tr( "WRN_WARNING" ), tr( "DEFINE_EXTERNAL_BROWSER" ),
1589                                       SUIT_MessageBox::Yes | SUIT_MessageBox::No,
1590                                       SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes )
1591       {
1592         QStringList path;
1593         path << tr( "PREF_CATEGORY_SALOME" ) << tr( "PREF_TAB_GENERAL" )
1594              << tr( "PREF_GROUP_EXT_BROWSER" ) << tr( "PREF_APP" );
1595         showPreferences( path );
1596       }
1597     }
1598   }
1599   else
1600   {
1601     QStringList cmdLine;
1602     cmdLine << QString( "--language=%1" ).arg( resMgr->stringValue( "language", "language" ) );
1603     cmdLine << QString( "--add=%1" ).arg( QApplication::instance()->applicationPid() );
1604     cmdLine << path;
1605     QProcess::startDetached( "HelpBrowser", cmdLine );
1606   }
1607 }
1608
1609 /*!
1610   SLOT: Displays help contents for choosen module
1611 */
1612 void LightApp_Application::onHelpContentsModule()
1613 {
1614   const QAction* a = (QAction*) sender();
1615   QString helpFile = a->data().toString();
1616   if ( !helpFile.isEmpty() )
1617     showHelp( helpFile );
1618 }
1619
1620 /*!
1621   SLOT: Displays contextual help (e.g. for choosen dialog)
1622 */
1623 void LightApp_Application::onHelpContextModule( const QString& component,
1624                                                 const QString& url,
1625                                                 const QString& context )
1626 {
1627   QString path = url;
1628   if ( !url.startsWith( "http", Qt::CaseInsensitive ) )
1629   {
1630     // local file path
1631     QFileInfo fi( url );
1632     if ( fi.isRelative() && !component.isEmpty() )
1633     {
1634       QString rootDir = Qtx::getenv( (component + "_ROOT_DIR").toLatin1().constData() );
1635       if ( !rootDir.isEmpty() )
1636       {
1637         path = (QStringList() << rootDir << "share" << "doc" << "salome" << "gui" << component << url).join( QDir::separator() );
1638       }
1639     }
1640   }
1641   if ( !context.isEmpty() )
1642   {
1643     path += QString( "#%1" ).arg( context );
1644   }
1645   showHelp( path );
1646 }
1647
1648 /*!
1649   Sets enable or disable some actions on selection changed.
1650 */
1651 void LightApp_Application::onSelectionChanged()
1652 {
1653   LightApp_Module* m = dynamic_cast<LightApp_Module*>( activeModule() );
1654   bool canCopy  = m ? m->canCopy() : false;
1655   bool canPaste = m ? m->canPaste() : false;
1656
1657   action( EditCopyId )->setEnabled(canCopy);
1658   action( EditPasteId )->setEnabled(canPaste);
1659 }
1660
1661 /*!
1662   SLOT: Performs some actions when dockable windows are triggered
1663 */
1664 void LightApp_Application::onDockWindowVisibilityChanged( bool )
1665 {
1666 }
1667
1668 QWidget* LightApp_Application::dockWindow( const int id ) const
1669 {
1670   QWidget* wid = 0;
1671   if ( myWin.contains( id ) )
1672     wid = myWin[id];
1673   return wid;
1674 }
1675
1676 QDockWidget* LightApp_Application::windowDock( QWidget* wid ) const
1677 {
1678   if ( !wid )
1679     return 0;
1680
1681   QDockWidget* dock = 0;
1682   QWidget* w = wid->parentWidget();
1683   while ( w && !dock )
1684   {
1685     dock = ::qobject_cast<QDockWidget*>( w );
1686     w = w->parentWidget();
1687   }
1688   return dock;
1689 }
1690
1691 void LightApp_Application::insertDockWindow( const int id, QWidget* wid )
1692 {
1693   if ( !wid )
1694     return;
1695
1696   if ( wid != dockWindow( id ) )
1697     removeDockWindow( id );
1698
1699   myWin.insert( id, wid );
1700
1701   QtxDockWidget* dock = new QtxDockWidget( true, desktop() );
1702   if ( id == WT_InfoPanel ) {
1703     // Info panel's position is strongly limited to the right area;
1704     // It is not movable and not floatable.
1705     dock->setAllowedAreas( Qt::RightDockWidgetArea );
1706     dock->setFeatures( QDockWidget::DockWidgetClosable );
1707     connect( dock, SIGNAL( aboutToShow()), this, SLOT( onInfoPanelShown() ) );
1708   }
1709   else {
1710     dock->setFeatures( QDockWidget::AllDockWidgetFeatures );
1711   }
1712   connect( dock, SIGNAL(  destroyed( QObject* ) ), this, SLOT( onWCDestroyed( QObject* ) ) );
1713
1714   dock->setObjectName( wid->objectName().isEmpty() ? QString( "window_%1" ).arg( id ) :
1715                        QString( "%1Dock" ).arg( wid->objectName() ) );
1716   dock->setWidget( wid );
1717   dock->toggleViewAction()->setData( QVariant( wid->objectName() ) );
1718   connect( dock->toggleViewAction(), SIGNAL( triggered( bool ) ),
1719            this, SLOT( onDockWindowVisibilityChanged( bool ) ) );
1720
1721   QKeySequence accel = wid->property( "shortcut" ).value<QKeySequence>();
1722   if ( !accel.isEmpty() )
1723     dock->toggleViewAction()->setShortcut( accel );
1724
1725   dock->show();
1726 }
1727
1728 void LightApp_Application::removeDockWindow( const int id )
1729 {
1730   QWidget* wid = dockWindow( id );
1731   if ( !wid )
1732     return;
1733
1734   myWin.remove( id );
1735
1736   QDockWidget* dock = windowDock( wid );
1737   if ( !dock )
1738     return;
1739
1740   dock->setWidget( 0 );
1741   wid->setParent( 0 );
1742   wid->setVisible( false );
1743   delete dock;
1744 }
1745
1746 void LightApp_Application::placeDockWindow( const int id, Qt::DockWidgetArea place )
1747 {
1748   QDockWidget* dock = windowDock( dockWindow( id ) );
1749   if ( dock && desktop() ) {
1750     desktop()->addDockWidget( place, dock );
1751     QtxDockAction* a = qobject_cast<QtxDockAction*>( action( ViewWindowsId ) );
1752     if ( a ) a->update();
1753   }
1754 }
1755
1756 /*!
1757   Gets window.
1758   \param flag - key for window
1759   Flag used how identificator of window in windows list.
1760 */
1761 QWidget* LightApp_Application::getWindow( const int flag)
1762 {
1763   QWidget* wid = dockWindow( flag );
1764   if ( !wid )
1765     insertDockWindow( flag, wid = createWindow( flag ) );
1766
1767   QMap<int, int> winMap;
1768   currentWindows( winMap );
1769   if ( winMap.contains( flag ) )
1770     placeDockWindow( flag, (Qt::DockWidgetArea)winMap[flag] );
1771
1772   return wid;
1773 }
1774
1775 /*!
1776   \return Object Browser
1777 */
1778 SUIT_DataBrowser* LightApp_Application::objectBrowser()
1779 {
1780   return qobject_cast<SUIT_DataBrowser*>( dockWindow( WT_ObjectBrowser ) );
1781 }
1782
1783 QtxInfoPanel* LightApp_Application::infoPanel()
1784 {
1785   return qobject_cast<QtxInfoPanel *>( dockWindow( WT_InfoPanel ));
1786 }
1787
1788 /*!
1789   \return Log Window
1790 */
1791 LogWindow* LightApp_Application::logWindow()
1792 {
1793   return qobject_cast<LogWindow*>( dockWindow( WT_LogWindow ) );
1794 }
1795
1796 #ifndef DISABLE_PYCONSOLE
1797 /*!
1798   This returns the python console integrated to the GUI. Depending
1799   when you request the python console, this function could return
1800   null. Then the optional parameter force (default to false) can be
1801   set to force the creation of the python console if it is not done
1802   already.
1803   \param force - if true, the pythonConsole is created if it does not exist yet
1804   \return Python Console
1805 */
1806 PyConsole_Console* LightApp_Application::pythonConsole(const bool force)
1807 {
1808   QWidget* wid = dockWindow( WT_PyConsole );
1809   if ( !wid && force==true) {
1810     wid = getWindow(WT_PyConsole);
1811   }
1812   return qobject_cast<PyConsole_Console*>( wid );
1813 }
1814 #endif
1815
1816 /*!
1817   Updates object browser and maybe data models
1818   \param updateModels - if it is true, then data models are updated
1819 */
1820 void LightApp_Application::updateObjectBrowser( const bool updateModels )
1821 {
1822   // update existing data models
1823   if ( updateModels )
1824   {
1825     const bool isAutoUpdate = objectBrowser() ? objectBrowser()->autoUpdate() : true;
1826     if ( objectBrowser() )
1827       objectBrowser()->setAutoUpdate( false );
1828
1829     LightApp_Study* study = dynamic_cast<LightApp_Study*>(activeStudy());
1830     if ( study ) {
1831       CAM_Study::ModelList dm_list;
1832       study->dataModels( dm_list );
1833       QListIterator<CAM_DataModel*> it( dm_list );
1834       while ( it.hasNext() ) {
1835         CAM_DataModel* camDM = it.next();
1836         if ( camDM && camDM->inherits( "LightApp_DataModel" ) )
1837           ((LightApp_DataModel*)camDM)->update();
1838       }
1839     }
1840
1841     if( objectBrowser() )
1842       objectBrowser()->setAutoUpdate( isAutoUpdate );
1843   }
1844
1845   if ( objectBrowser() ) {
1846     objectBrowser()->updateGeometry();
1847     objectBrowser()->updateTree( 0, false );
1848   }
1849 }
1850
1851 /*!
1852   \return preferences
1853 */
1854 LightApp_Preferences* LightApp_Application::preferences() const
1855 {
1856   return preferences( false );
1857 }
1858
1859 /*!
1860   \return first view manager of some type
1861   \param vmType - type of view manager
1862   \param create - is it necessary to create view manager in case, when there is no manager of such type
1863 */
1864 SUIT_ViewManager* LightApp_Application::getViewManager( const QString& vmType, const bool create )
1865 {
1866   SUIT_ViewManager* aVM = viewManager( vmType );
1867   SUIT_ViewManager* anActiveVM = CAM_Application::activeViewManager();
1868   MESSAGE("vmType: " << vmType.toStdString() << " aVM: " << aVM << " anActiveVM: " << anActiveVM );
1869   if ( anActiveVM && anActiveVM->getType() == vmType )
1870     {
1871       MESSAGE("aVM = anActiveVM");
1872       aVM = anActiveVM;
1873     }
1874
1875   bool keepDetached = property("keep_detached").toBool();
1876   if ( aVM && (!aVM->getDetached() || keepDetached) && create )
1877   {
1878     if ( !aVM->getActiveView() )
1879       {
1880         MESSAGE("aVM->createView()");
1881         aVM->createView();
1882       }
1883     else
1884       {
1885         MESSAGE("desktop()->setActiveWindow: " << aVM->getActiveView());
1886         desktop()->setActiveWindow( aVM->getActiveView() );
1887       }
1888   }
1889   else if ( create )
1890     {
1891       MESSAGE("aVM = createViewManager( vmType )");
1892       aVM = createViewManager( vmType );
1893     }
1894
1895   return aVM;
1896 }
1897
1898 /*!
1899   Creates view manager of some type
1900   \param vmType - type of view manager
1901 */
1902 SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType, bool detached )
1903 {
1904   SUIT_ResourceMgr* resMgr = resourceMgr();
1905
1906   SUIT_ViewManager* viewMgr = 0;
1907 #ifndef DISABLE_GLVIEWER
1908   if( vmType == GLViewer_Viewer::Type() )
1909   {
1910     viewMgr = new GLViewer_ViewManager( activeStudy(), desktop() );
1911     new LightApp_GLSelector( (GLViewer_Viewer2d*)viewMgr->getViewModel(), mySelMgr );
1912   }
1913 #endif
1914 #ifndef DISABLE_PLOT2DVIEWER
1915   if( vmType == Plot2d_Viewer::Type() )
1916   {
1917     viewMgr = new Plot2d_ViewManager( activeStudy(), desktop() );
1918     Plot2d_Viewer* vm;
1919 #ifndef DISABLE_SALOMEOBJECT
1920     SPlot2d_Viewer* v = new SPlot2d_Viewer();
1921     vm = v;
1922     new LightApp_Plot2dSelector( v, mySelMgr );
1923 #else
1924     vm = new Plot2d_Viewer();
1925 #endif
1926     viewMgr->setViewModel( vm  );// custom view model, which extends SALOME_View interface
1927     Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( viewMgr->getActiveView() );
1928     if( wnd )
1929     {
1930       Plot2d_ViewFrame* frame = wnd->getViewFrame();
1931       frame->setBackgroundColor( resMgr->colorValue( "Plot2d", "Background", frame->backgroundColor() ) );
1932     }
1933   }
1934 #endif
1935 #ifndef DISABLE_QXGRAPHVIEWER
1936   if( vmType == QxScene_Viewer::Type() )
1937   {
1938     viewMgr = new QxScene_ViewManager( activeStudy(), desktop() );
1939     QxScene_Viewer* vm = new QxScene_Viewer();
1940     viewMgr->setViewModel( vm  );
1941     //QxScene_ViewWindow* wnd = dynamic_cast<QxScene_ViewWindow*>( viewMgr->getActiveView() );
1942   }
1943 #endif
1944 #ifndef DISABLE_GRAPHICSVIEW
1945   if( vmType == GraphicsView_Viewer::Type() )
1946   {
1947     viewMgr = new GraphicsView_ViewManager( activeStudy(), desktop() );
1948     new LightApp_GVSelector( (GraphicsView_Viewer*)viewMgr->getViewModel(), mySelMgr );
1949   }
1950 #endif
1951 #ifndef DISABLE_PVVIEWER
1952   if( vmType == PVViewer_Viewer::Type() )
1953   {
1954     if (( viewMgr = dynamic_cast<PVViewer_ViewManager*>( getViewManager( vmType, false )))) {
1955       viewMgr->getActiveView()->setFocus();
1956       return 0;
1957     } else {
1958       viewMgr = new PVViewer_ViewManager( activeStudy(), desktop() );
1959     }
1960   }
1961 #endif
1962 #ifndef DISABLE_PYVIEWER
1963   if( vmType == PyViewer_Viewer::Type() )
1964   {
1965     viewMgr = new PyViewer_ViewManager( activeStudy(), desktop() );
1966   }
1967 #endif
1968 #ifndef DISABLE_OCCVIEWER
1969   if( vmType == OCCViewer_Viewer::Type() )
1970   {
1971     viewMgr = new OCCViewer_ViewManager( activeStudy(), desktop() );
1972     OCCViewer_Viewer* vm;
1973 #ifndef DISABLE_SALOMEOBJECT
1974     vm = new SOCC_Viewer();
1975 #else
1976     vm = new OCCViewer_Viewer( true );
1977 #endif
1978     vm->setBackground( OCCViewer_ViewFrame::TOP_LEFT,
1979                        resMgr->backgroundValue( "OCCViewer", "xz_background", vm->background(OCCViewer_ViewFrame::TOP_LEFT) ) );
1980     vm->setBackground( OCCViewer_ViewFrame::TOP_RIGHT,
1981                        resMgr->backgroundValue( "OCCViewer", "yz_background", vm->background(OCCViewer_ViewFrame::TOP_RIGHT) ) );
1982     vm->setBackground( OCCViewer_ViewFrame::BOTTOM_LEFT,
1983                        resMgr->backgroundValue( "OCCViewer", "xy_background", vm->background(OCCViewer_ViewFrame::BOTTOM_LEFT) ) );
1984     vm->setBackground( OCCViewer_ViewFrame::BOTTOM_RIGHT,
1985                        resMgr->backgroundValue( "OCCViewer", "background", vm->background(OCCViewer_ViewFrame::MAIN_VIEW) ) );
1986
1987     vm->setTrihedronSize(  resMgr->doubleValue( "3DViewer", "trihedron_size", vm->trihedronSize() ),
1988                            resMgr->booleanValue( "3DViewer", "relative_size", vm->trihedronRelative() ));
1989     vm->setInteractionStyle( resMgr->integerValue( "3DViewer", "navigation_mode", vm->interactionStyle() ) );
1990     vm->setProjectionType( resMgr->integerValue( "OCCViewer", "projection_mode", vm->projectionType() ) );
1991     vm->setStereoType( resMgr->integerValue( "OCCViewer", "stereo_type", vm->stereoType() ) );
1992     vm->setAnaglyphFilter( resMgr->integerValue( "OCCViewer", "anaglyph_filter", vm->anaglyphFilter() ) );
1993     vm->setStereographicFocus( resMgr->integerValue( "OCCViewer", "focus_type", vm->stereographicFocusType() ),
1994                                resMgr->doubleValue( "OCCViewer", "focus_value", vm->stereographicFocusValue() ));
1995     vm->setInterocularDistance( resMgr->integerValue( "OCCViewer", "iod_type", vm->interocularDistanceType() ),
1996                                 resMgr->doubleValue( "OCCViewer", "iod_value", vm->interocularDistanceValue() ));
1997     vm->setSelectionStyle((OCCViewer_ViewWindow::SelectionStyle) resMgr->integerValue( "OCCViewer", "adv_selection_mode", vm->selectionStyle() ) );
1998
1999     vm->setReverseStereo( resMgr->booleanValue( "OCCViewer", "reverse_stereo", vm->isReverseStereo() ) );
2000     vm->setVSync( resMgr->booleanValue( "OCCViewer", "enable_vsync", vm->isVSync() ) );
2001     vm->setQuadBufferSupport( resMgr->booleanValue( "OCCViewer", "enable_quad_buffer_support", vm->isQuadBufferSupport() ) );
2002     vm->setZoomingStyle( resMgr->integerValue( "3DViewer", "zooming_mode", vm->zoomingStyle() ) );
2003     vm->enablePreselection( resMgr->booleanValue( "OCCViewer", "enable_preselection", vm->isPreselectionEnabled() ) );
2004     vm->enableSelection(    resMgr->booleanValue( "OCCViewer", "enable_selection",    vm->isSelectionEnabled() ) );
2005     vm->setClippingColor( resMgr->colorValue( "OCCViewer", "clipping_color", vm->clippingColor() ) );
2006     vm->setClippingTextureParams( resMgr->booleanValue( "OCCViewer", "clipping_use_default_texture", vm->isDefaultTextureUsed() ),
2007                                   resMgr->stringValue( "OCCViewer", "clipping_texture", vm->clippingTexture() ),
2008                                   resMgr->booleanValue( "OCCViewer", "clipping_modulate", vm->isTextureModulated() ),
2009                                   resMgr->doubleValue( "OCCViewer", "clipping_scale", vm->clippingTextureScale() ) );
2010
2011
2012     viewMgr->setViewModel( vm );// custom view model, which extends SALOME_View interface
2013     new LightApp_OCCSelector( (OCCViewer_Viewer*)viewMgr->getViewModel(), mySelMgr );
2014   }
2015 #endif
2016 #ifndef DISABLE_VTKVIEWER
2017 #ifndef DISABLE_SALOMEOBJECT
2018   if ( vmType == SVTK_Viewer::Type() )
2019 #else
2020   if ( vmType == VTKViewer_Viewer::Type() )
2021 #endif
2022   {
2023 #ifndef DISABLE_SALOMEOBJECT
2024     viewMgr = new SVTK_ViewManager( activeStudy(), desktop() );
2025     SVTK_Viewer* vm = dynamic_cast<SVTK_Viewer*>( viewMgr->getViewModel() );
2026     if( vm )
2027     {
2028       vm->setProjectionMode( resMgr->integerValue( "VTKViewer", "projection_mode", vm->projectionMode() ) );
2029       vm->setStereoType( resMgr->integerValue( "VTKViewer", "stereo_type", vm->stereoType() ) );
2030       vm->setAnaglyphFilter( resMgr->integerValue( "VTKViewer", "anaglyph_filter", vm->anaglyphFilter() ) );
2031       vm->setQuadBufferSupport( resMgr->booleanValue( "VTKViewer", "enable_quad_buffer_support", vm->isQuadBufferSupport() ) );
2032       vm->setBackground( resMgr->backgroundValue( "VTKViewer", "background", vm->background() ) );
2033       vm->setTrihedronSize( resMgr->doubleValue( "3DViewer", "trihedron_size", vm->trihedronSize() ),
2034                             resMgr->booleanValue( "3DViewer", "relative_size", vm->trihedronRelative() ) );
2035       vm->setStaticTrihedronVisible( resMgr->booleanValue( "3DViewer", "show_static_trihedron", vm->isStaticTrihedronVisible() ) );
2036       vm->setInteractionStyle( resMgr->integerValue( "3DViewer", "navigation_mode", vm->interactionStyle() ) );
2037       vm->setZoomingStyle( resMgr->integerValue( "3DViewer", "zooming_mode", vm->zoomingStyle() ) );
2038       vm->setPreSelectionMode(resMgr->integerValue( "VTKViewer", "preselection", vm->preSelectionMode() ) );
2039       vm->enableSelection( resMgr->booleanValue( "VTKViewer", "enable_selection", vm->isSelectionEnabled() ) );
2040       vm->setIncrementalSpeed( resMgr->integerValue( "VTKViewer", "speed_value", vm->incrementalSpeed() ),
2041                                resMgr->integerValue( "VTKViewer", "speed_mode", vm->incrementalSpeedMode() ) );
2042       vm->setSpacemouseButtons( resMgr->integerValue( "VTKViewer", "spacemouse_func1_btn", vm->spacemouseBtn(1) ),
2043                                 resMgr->integerValue( "VTKViewer", "spacemouse_func2_btn", vm->spacemouseBtn(2) ),
2044                                 resMgr->integerValue( "VTKViewer", "spacemouse_func5_btn", vm->spacemouseBtn(3) ) );
2045       new LightApp_VTKSelector( vm, mySelMgr );
2046     }
2047 #else
2048     viewMgr = new VTKViewer_ViewManager( activeStudy(), desktop() );
2049     VTKViewer_Viewer* vm = dynamic_cast<VTKViewer_Viewer*>( viewMgr->getViewModel() );
2050     if ( vm )
2051       vm->setBackground( resMgr->backgroundValue( "VTKViewer", "background", vm->background() ) );
2052 #endif
2053   }
2054 #endif
2055
2056 #ifndef DISABLE_PV3DVIEWER
2057 # ifndef DISABLE_SALOMEOBJECT
2058   if ( vmType == SPV3D_ViewModel::Type() )
2059 # else
2060   if ( vmType == PV3DViewer_ViewModel::Type() )
2061 # endif
2062   {
2063     viewMgr = new SPV3D_ViewManager( activeStudy(), desktop() );
2064     SPV3D_ViewModel* vm = dynamic_cast<SPV3D_ViewModel*>( viewMgr->getViewModel() );
2065     if ( vm )
2066     {
2067       // vm->setBackground(...); //NYI
2068       // vm->...
2069
2070       new LightApp_PV3DSelector( vm, mySelMgr );
2071     }
2072 #else
2073     viewMgr = new PV3DViewer_ViewManager( activeStudy(), desktop() );
2074     PV3DViewer_ViewModel* vm = dynamic_cast<PV3DViewer_ViewModel*>( viewMgr->getViewModel() );
2075     if ( vm )
2076     {
2077       // vm->setBackground(...); //NYI
2078     }
2079 #endif
2080   }
2081
2082   if ( !viewMgr )
2083     return 0;
2084
2085   viewMgr->setDetached(detached);
2086   addViewManager( viewMgr );
2087   SUIT_ViewWindow* viewWin = viewMgr->createViewWindow();
2088
2089   if ( viewWin && desktop() ) {
2090     viewWin->resize( (int)( desktop()->width() * 0.6 ), (int)( desktop()->height() * 0.6 ) );
2091     viewWin->setDropDownButtons( resMgr->booleanValue( "viewers", "drop_down_buttons", true ) );
2092   }
2093
2094   return viewMgr;
2095 }
2096
2097 SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType, QWidget* w )
2098 {
2099   SUIT_ResourceMgr* resMgr = resourceMgr();
2100
2101   SUIT_ViewManager* vm = new SUIT_ViewManager( activeStudy(),
2102                                                desktop(),
2103                                                new LightApp_WgViewModel( vmType, w ) );
2104   vm->setTitle( QString( "%1: %M - viewer %V" ).arg( vmType ) );
2105
2106   addViewManager( vm );
2107   SUIT_ViewWindow* vw = vm->createViewWindow();
2108   if ( vw && desktop() ) {
2109     vw->resize( (int)( desktop()->width() * 0.6 ), (int)( desktop()->height() * 0.6 ) );
2110     vw->setDropDownButtons( resMgr->booleanValue( "viewers", "drop_down_buttons", true ) );
2111   }
2112
2113   if ( !vmType.isEmpty() && !myUserWmTypes.contains( vmType ) )
2114     myUserWmTypes << vmType;
2115
2116   return vm;
2117 }
2118
2119 SUIT_ViewManager* LightApp_Application::createViewManager( SUIT_ViewModel* theModel )
2120 {
2121   SUIT_ResourceMgr* resMgr = resourceMgr();
2122
2123   SUIT_ViewManager* vm = new SUIT_ViewManager( activeStudy(),
2124                                                desktop(),
2125                                                theModel );
2126
2127   QString vmType = vm->getType();
2128
2129   vm->setTitle( QString( "%1: %M - viewer %V" ).arg( vmType ) );
2130
2131   addViewManager( vm );
2132   SUIT_ViewWindow* vw = vm->createViewWindow();
2133   if ( vw && desktop() ) {
2134     vw->resize( (int)( desktop()->width() * 0.6 ), (int)( desktop()->height() * 0.6 ) );
2135     vw->setDropDownButtons( resMgr->booleanValue( "viewers", "drop_down_buttons", true ) );
2136   }
2137
2138   if ( !vmType.isEmpty() && !myUserWmTypes.contains( vmType ) )
2139     myUserWmTypes << vmType;
2140
2141   return vm;
2142 }
2143
2144 /*!
2145   SLOT: Removes view manager from application
2146 */
2147 void LightApp_Application::onCloseView( SUIT_ViewManager* theVM )
2148 {
2149   removeViewManager( theVM );
2150 }
2151
2152 /*!
2153   Protected SLOT: On study created.
2154   \param theStudy - just created study
2155 */
2156 void LightApp_Application::onStudyCreated( SUIT_Study* theStudy )
2157 {
2158   SUIT_DataObject* aRoot = 0;
2159   if ( theStudy && theStudy->root() )
2160   {
2161     aRoot = theStudy->root();
2162     //aRoot->setName( tr( "DATA_MODELS" ) );
2163   }
2164
2165   getWindow( WT_ObjectBrowser );
2166   getWindow( WT_InfoPanel );
2167
2168   loadDockWindowsState();
2169
2170   if ( objectBrowser() )
2171     objectBrowser()->setRoot( aRoot );
2172
2173   activateModule( defaultModule() );
2174
2175   if ( objectBrowser() )
2176     objectBrowser()->openLevels();
2177
2178 #ifndef DISABLE_PYCONSOLE
2179   if( pythonConsole() )
2180     getPyInterp()->initStudy();
2181 #endif
2182 }
2183
2184 /*!
2185   Protected SLOT: On study opened.
2186   \param theStudy - just opened  study
2187 */
2188 void LightApp_Application::onStudyOpened( SUIT_Study* theStudy )
2189 {
2190   SUIT_DataObject* aRoot = 0;
2191   if ( theStudy && theStudy->root() )
2192   {
2193     aRoot = theStudy->root();
2194     //aRoot->dump();
2195   }
2196
2197   getWindow( WT_ObjectBrowser );
2198   getWindow( WT_InfoPanel );
2199
2200   loadDockWindowsState();
2201
2202   if ( objectBrowser() )
2203     objectBrowser()->setRoot( aRoot );
2204
2205   activateModule( defaultModule() );
2206
2207   if ( objectBrowser() )
2208     objectBrowser()->openLevels();
2209
2210 #ifndef DISABLE_PYCONSOLE
2211   if( pythonConsole() )
2212     getPyInterp()->initStudy();
2213 #endif
2214
2215   emit studyOpened();
2216 }
2217
2218 /*!Protected SLOT. On study saved.*/
2219 void LightApp_Application::onStudySaved( SUIT_Study* s )
2220 {
2221   QtxMRUAction* mru = ::qobject_cast<QtxMRUAction*>( action( MRUId ) );
2222   if ( mru && s )
2223     mru->insert( s->studyName() );
2224
2225   emit studySaved();
2226 }
2227
2228 /*!Protected SLOT. On study closed.*/
2229 void LightApp_Application::onStudyClosed( SUIT_Study* /*s*/ )
2230 {
2231   /*
2232   disconnect( this, SIGNAL( viewManagerRemoved( SUIT_ViewManager* ) ),
2233               this, SLOT( onViewManagerRemoved( SUIT_ViewManager* ) ) );
2234   */
2235
2236   // stop auto-save timer
2237   myAutoSaveTimer->stop();
2238
2239   // Bug 10396: clear selection
2240   mySelMgr->clearSelected();
2241
2242   // Bug 12944: emit signal only after clear selection
2243   emit studyClosed();
2244
2245   activateModule( "" );
2246 }
2247
2248 /*!Protected SLOT.On desktop activated.*/
2249 void LightApp_Application::onDesktopActivated()
2250 {
2251   CAM_Application::onDesktopActivated();
2252   LightApp_Module* aModule = dynamic_cast<LightApp_Module*>(activeModule());
2253   if(aModule)
2254     aModule->studyActivated();
2255 }
2256
2257 void LightApp_Application::studyOpened( SUIT_Study* s )
2258 {
2259   CAM_Application::studyOpened( s );
2260
2261   updateWindows();
2262   updateViewManagers();
2263 }
2264
2265 void LightApp_Application::studySaved( SUIT_Study* s )
2266 {
2267   CAM_Application::studyOpened( s );
2268   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
2269   if ( aResMgr && activeStudy() ) {
2270     int autoSaveInterval = aResMgr->integerValue( "Study", "auto_save_interval", 0 );
2271     if ( autoSaveInterval > 0 ) myAutoSaveTimer->start( autoSaveInterval*60000 );
2272   }
2273 }
2274
2275 void LightApp_Application::studyCreated( SUIT_Study* s )
2276 {
2277   CAM_Application::studyCreated( s );
2278
2279   updateWindows();
2280   updateViewManagers();
2281 }
2282
2283 /*!Gets file filter.
2284  *\retval QString "(*.hdf)"
2285  */
2286 QString LightApp_Application::getFileFilter( bool /*open*/) const
2287 {
2288   return "(*.hdf)";
2289 }
2290
2291 /*!
2292   Shows file dialog and return user selected file name
2293 */
2294 QString LightApp_Application::getFileName( bool open, const QString& initial, const QString& filters,
2295                                            const QString& caption, QWidget* parent )
2296 {
2297   if ( !parent )
2298     parent = desktop();
2299   QStringList fls = filters.split( ";;", QString::SkipEmptyParts );
2300   return SUIT_FileDlg::getFileName( parent, initial, fls, caption, open, true );
2301 }
2302
2303 /*! Gets directory*/
2304 QString LightApp_Application::getDirectory( const QString& initial, const QString& caption, QWidget* parent )
2305 {
2306   if ( !parent )
2307     parent = desktop();
2308   return SUIT_FileDlg::getExistingDirectory( parent, initial, caption, true );
2309 }
2310
2311 /*! Get open file names*/
2312 QStringList LightApp_Application::getOpenFileNames( const QString& initial, const QString& filters,
2313                                                     const QString& caption, QWidget* parent )
2314 {
2315   if ( !parent )
2316     parent = desktop();
2317   QStringList fls = filters.split( ";;", QString::SkipEmptyParts );
2318   return SUIT_FileDlg::getOpenFileNames( parent, initial, fls, caption, true );
2319 }
2320
2321 /*!Private SLOT. Update object browser.*/
2322 void LightApp_Application::onRefresh()
2323 {
2324   updateObjectBrowser( true );
2325 }
2326
2327 /*!Private SLOT. Update actions after rename object.*/
2328 void LightApp_Application::onRenamed()
2329 {
2330   activeStudy()->Modified();
2331   updateActions();
2332 }
2333
2334 // IMN 08.07.2015 : issue 002556: Some stereo outputs are affected by window position.
2335 // To prevent reversion the window should be either aligned during movement and resize.
2336 /*!Private SLOT. Update actions after rename object.*/
2337 /*void LightApp_Application::onMoved()
2338 {
2339   OCCViewer_ViewManager* viewMgr = 0;
2340   viewMgr = dynamic_cast<OCCViewer_ViewManager*>( getViewManager( OCCViewer_Viewer::Type(), false ) );
2341   if (viewMgr) {
2342     OCCViewer_ViewWindow* view = 0;
2343     view = dynamic_cast<OCCViewer_ViewWindow*>( viewMgr->getActiveView() );
2344     if (view) {
2345       view->getViewPort()->repaintViewAfterMove();
2346     }
2347   }
2348 }
2349 */
2350 /*!Private SLOT. Support drag-and-drop operation.*/
2351 void LightApp_Application::onDropped( const QList<SUIT_DataObject*>& objects, SUIT_DataObject* parent, int row, Qt::DropAction action )
2352 {
2353   LightApp_DataObject* parentObj = dynamic_cast<LightApp_DataObject*>( parent );
2354   if ( !parentObj )
2355     return;
2356
2357   LightApp_Module* aModule = dynamic_cast<LightApp_Module*>( parentObj->module() );
2358   if ( aModule )
2359     aModule->dropObjects( objects, parentObj, row, action );
2360 }
2361
2362 /*!Private SLOT. On preferences.*/
2363 void LightApp_Application::onPreferences()
2364 {
2365   showPreferences( activeModule() ? activeModule()->moduleName() : tr( "PREF_CATEGORY_SALOME" ) );
2366 }
2367
2368 /*!Private SLOT. On preferences.*/
2369 void LightApp_Application::showPreferences( const QString& path )
2370 {
2371   showPreferences( QStringList() << path );
2372 }
2373
2374 void LightApp_Application::showPreferences( const QStringList& path )
2375 {
2376   QApplication::setOverrideCursor( Qt::WaitCursor );
2377
2378   LightApp_PreferencesDlg* prefDlg = new LightApp_PreferencesDlg( preferences( true ), desktop());
2379
2380   QApplication::restoreOverrideCursor();
2381
2382   if ( !prefDlg )
2383     return;
2384
2385   preferences()->activateItem( path );
2386
2387   if ( ( prefDlg->exec() == QDialog::Accepted || prefDlg->isSaved() ) &&  resourceMgr() )
2388   {
2389     if ( desktop() )
2390       resourceMgr()->setValue( "desktop", "geometry", desktop()->storeGeometry() );
2391     resourceMgr()->save();
2392
2393     // Update shortcuts
2394     shortcutMgr()->updateShortcuts();
2395   }
2396
2397   delete prefDlg;
2398 }
2399
2400 /*!Protected SLOT. On preferences changed.*/
2401 void LightApp_Application::onPreferenceChanged( QString& modName, QString& section, QString& param )
2402 {
2403   LightApp_Module* sMod = 0;
2404   CAM_Module* mod = module( modName );
2405   if ( mod && mod->inherits( "LightApp_Module" ) )
2406     sMod = (LightApp_Module*)mod;
2407
2408   if ( sMod )
2409     sMod->preferencesChanged( section, param );
2410   else
2411     preferencesChanged( section, param );
2412   // emit signal to allow additional preferences changing processing
2413   emit preferenceChanged( modName, section, param );
2414 }
2415
2416 /*!Remove all windows from study.*/
2417 void LightApp_Application::beforeCloseDoc( SUIT_Study* s )
2418 {
2419   saveDockWindowsState();
2420
2421   if ( SUIT_DataBrowser* ob = objectBrowser() )
2422     ob->setModel(0);
2423
2424   CAM_Application::beforeCloseDoc( s );
2425 }
2426
2427 /*!Update actions.*/
2428 void LightApp_Application::updateActions()
2429 {
2430   updateCommandsStatus();
2431 }
2432
2433 /*!
2434   Creates new study
2435 */
2436 SUIT_Study* LightApp_Application::createNewStudy()
2437 {
2438   LightApp_Study* aStudy = new LightApp_Study( this );
2439
2440   // Set up processing of major study-related events
2441   connect( aStudy, SIGNAL( created( SUIT_Study* ) ), this, SLOT( onStudyCreated( SUIT_Study* ) ) );
2442   connect( aStudy, SIGNAL( opened ( SUIT_Study* ) ), this, SLOT( onStudyOpened ( SUIT_Study* ) ) );
2443   connect( aStudy, SIGNAL( saved  ( SUIT_Study* ) ), this, SLOT( onStudySaved  ( SUIT_Study* ) ) );
2444   connect( aStudy, SIGNAL( closed ( SUIT_Study* ) ), this, SLOT( onStudyClosed ( SUIT_Study* ) ) );
2445
2446   return aStudy;
2447 }
2448
2449 /*!
2450   Creates window by flag.
2451   \param flag - identificator of window type
2452 */
2453 QWidget* LightApp_Application::createWindow( const int flag )
2454 {
2455   QWidget* wid = 0;
2456
2457   SUIT_ResourceMgr* resMgr = resourceMgr();
2458
2459   if ( flag == WT_ObjectBrowser )
2460   {
2461     SUIT_DataBrowser* ob = new SUIT_DataBrowser( new LightApp_DataObject(), desktop() );
2462     ob->setObjectName( "objectBrowser" );
2463     ob->setSortMenuEnabled( true );
2464     ob->setAutoUpdate( true );
2465     if ( resMgr->hasValue( "ObjectBrowser", "auto_hide_search_tool" ) )
2466       ob->searchTool()->enableAutoHide( resMgr->booleanValue( "ObjectBrowser", "auto_hide_search_tool" ) );
2467
2468     //ob->setAutoOpenLevel( 1 ); // commented by ASV as a fix to bug IPAL10107
2469     ob->setWindowTitle( tr( "OBJECT_BROWSER" ) );
2470     connect( ob, SIGNAL( requestUpdate() ), this, SLOT( onRefresh() ) );
2471
2472     QString EntryCol = QObject::tr( "ENTRY_COLUMN" );
2473     SUIT_AbstractModel* treeModel = dynamic_cast<SUIT_AbstractModel*>( ob->model() );
2474     treeModel->setSearcher( this );
2475     treeModel->registerColumn( 0, EntryCol, LightApp_DataObject::EntryId );
2476     treeModel->setAppropriate( EntryCol, Qtx::Toggled );
2477
2478     // Mantis issue 0020136: Drag&Drop in OB
2479     SUIT_ProxyModel* proxyModel = dynamic_cast<SUIT_ProxyModel*>(treeModel);
2480     if ( proxyModel ) {
2481       connect( proxyModel, SIGNAL( dropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ),
2482                this,       SLOT( onDropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ) );
2483       connect( proxyModel, SIGNAL( renamed( SUIT_DataObject* ) ),
2484                this,       SLOT( onRenamed( ) ) );
2485
2486     }
2487
2488     // temporary commented
2489     /*
2490     OB_ListView* ob_list = dynamic_cast<OB_ListView*>( const_cast<QListView*>( ob->listView() ) );
2491     if( ob_list )
2492       ob_list->setColumnMaxWidth( 0, desktop()->width()/4 );
2493     */
2494
2495     // Create OBSelector
2496     new LightApp_OBSelector( ob, mySelMgr );
2497     ob->treeView()->header()->setSectionResizeMode(SUIT_DataObject::VisibilityId, QHeaderView::Fixed);
2498     ob->treeView()->header()->moveSection(SUIT_DataObject::NameId,SUIT_DataObject::VisibilityId);
2499     ob->treeView()->setColumnWidth(SUIT_DataObject::VisibilityId, VISIBILITY_COLUMN_WIDTH);
2500     ob->setProperty( "shortcut", QKeySequence( "Alt+Shift+O" ) );
2501     wid = ob;
2502     ob->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
2503   }
2504   else if ( flag == WT_InfoPanel)
2505   {
2506     QtxInfoPanel* ipanel = new QtxInfoPanel( desktop() );
2507     ipanel->setObjectName( "infoPanel" );
2508     ipanel->setWindowTitle( tr( "INFO_PANEL" ) );
2509     wid = ipanel;
2510   }
2511 #ifndef DISABLE_PYCONSOLE
2512   else  if ( flag == WT_PyConsole )
2513   {
2514     PyConsole_Console* pyCons = new PyConsole_Console( desktop(), new LightApp_PyEditor( getPyInterp() ) );
2515     pyCons->setObjectName( "pythonConsole" );
2516     pyCons->setWindowTitle( tr( "PYTHON_CONSOLE" ) );
2517     pyCons->setFont( resMgr->fontValue( "PyConsole", "font" ) );
2518     pyCons->setIsShowBanner( resMgr->booleanValue( "PyConsole", "show_banner", true ) );
2519     pyCons->setAutoCompletion( resMgr->booleanValue( "PyConsole", "auto_completion", true ) );
2520     pyCons->setProperty( "shortcut", QKeySequence( "Alt+Shift+P" ) );
2521     wid = pyCons;
2522   }
2523 #endif
2524   else if ( flag == WT_LogWindow )
2525   {
2526     LogWindow* logWin = new LogWindow( desktop() );
2527     logWin->handleQtMessages( true );
2528     logWin->setObjectName( "logWindow" );
2529     logWin->setWindowTitle( tr( "LOG_WINDOW" ) );
2530     logWin->setProperty( "shortcut", QKeySequence( "Alt+Shift+L" ) );
2531     wid = logWin;
2532     logWin->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
2533   }
2534   return wid;
2535 }
2536
2537 /*!
2538   \return default windows( Object Browser, Python Console )
2539   Adds to map \a aMap.
2540  */
2541 void LightApp_Application::defaultWindows( QMap<int, int>& aMap ) const
2542 {
2543 #ifndef DISABLE_PYCONSOLE
2544   aMap.insert( WT_PyConsole, Qt::BottomDockWidgetArea );
2545 #endif
2546   if ( activeStudy() ) {
2547     aMap.insert( WT_ObjectBrowser, Qt::LeftDockWidgetArea );
2548     aMap.insert( WT_InfoPanel, Qt::RightDockWidgetArea );
2549     //  aMap.insert( WT_LogWindow, Qt::DockBottom );
2550   }
2551 }
2552
2553 /*!Default view managers*/
2554 void LightApp_Application::defaultViewManagers( QStringList& ) const
2555 {
2556   /*!Do nothing.*/
2557 }
2558
2559 /*!
2560   \return preferences.
2561   Create preferences, if \a crt = true.
2562 */
2563 LightApp_Preferences* LightApp_Application::preferences( const bool crt ) const
2564 {
2565   if ( myPrefs )
2566     return myPrefs;
2567
2568   LightApp_Application* that = (LightApp_Application*)this;
2569
2570   bool toCreate = !_prefs_ && crt;
2571   if ( toCreate )
2572   {
2573     _prefs_ = new LightApp_Preferences( resourceMgr() );
2574     that->createPreferences( _prefs_ );
2575     qAddPostRoutine( LightAppCleanUpAppResources );
2576   }
2577
2578   that->myPrefs = _prefs_;
2579
2580   connect( myPrefs, SIGNAL( preferenceChanged( QString&, QString&, QString& ) ),
2581            this, SLOT( onPreferenceChanged( QString&, QString&, QString& ) ), Qt::UniqueConnection );
2582   connect( myPrefs, SIGNAL( resetToDefaults() ),
2583            this, SIGNAL( preferenceResetToDefaults() ), Qt::UniqueConnection );
2584
2585   if ( !crt )
2586     return myPrefs;
2587
2588   QList<SUIT_Application*> appList = SUIT_Session::session()->applications();
2589   for ( QList<SUIT_Application*>::iterator appIt = appList.begin(); appIt != appList.end(); ++appIt )
2590   {
2591     LightApp_Application* app = ::qobject_cast<LightApp_Application*>( *appIt );
2592     if ( !app )
2593       continue;
2594
2595     // all modules available in current session
2596     QStringList names;
2597     app->modules( names, false );
2598
2599     // step 1: iterate through list of all available modules
2600     // and add empty preferences page
2601     for ( QStringList::const_iterator it = names.begin(); it != names.end(); ++it )
2602     {
2603       if ( !_prefs_->hasModule( *it ) ) // prevent possible duplications
2604       {
2605         int modId = _prefs_->addPreference( *it ); // add empty page
2606         _prefs_->setItemIcon( modId, moduleIcon( *it, 20 ) ); // scale icon to 20x20 pix
2607       }
2608     }
2609
2610     // step 2: iterate through list of all loaded modules
2611     // and initialize their preferences
2612     ModuleList loadedModules;
2613     app->modules( loadedModules );
2614     QListIterator<CAM_Module*> itr( loadedModules );
2615     while ( itr.hasNext() )
2616     {
2617       LightApp_Module* module = 0;
2618       CAM_Module* m = itr.next();
2619       if ( m->inherits( "LightApp_Module" ) )
2620         module = (LightApp_Module*)m;
2621
2622       if ( module && !_prefs_->hasModule( module->moduleName() ) )
2623       {
2624         _prefs_->addPreference( module->moduleName() ); // add page (for sure, had to be done at step 1)
2625         module->createPreferences();                    // initialize preferences
2626         that->emptyPreferences( module->moduleName() ); // show dummy page if module does not export any preferences
2627       }
2628     }
2629   }
2630   _prefs_->setItemProperty( "info", tr( "PREFERENCES_NOT_LOADED" ) ); // dummy page for modules which are not loaded yet
2631
2632   return myPrefs;
2633 }
2634
2635 /*!
2636   Adds new module to application
2637 */
2638 void LightApp_Application::moduleAdded( CAM_Module* mod )
2639 {
2640   CAM_Application::moduleAdded( mod );
2641
2642   LightApp_Module* lightMod = 0;
2643   if ( mod && mod->inherits( "LightApp_Module" ) )
2644     lightMod = (LightApp_Module*)mod;
2645
2646   if ( myPrefs && lightMod && !myPrefs->hasModule( lightMod->moduleName() ))
2647   {
2648     myPrefs->addPreference( mod->moduleName() );
2649     lightMod->createPreferences();
2650     emptyPreferences( mod->moduleName() );
2651   }
2652 }
2653
2654 void LightApp_Application::moduleDeactivated( CAM_Module* /*mod*/ )
2655 {
2656   if ( infoPanel() )
2657     infoPanel()->clear();
2658 }
2659
2660 void LightApp_Application::emptyPreferences( const QString& modName )
2661 {
2662   QtxPreferenceItem* item = myPrefs->findItem( modName, true );
2663   if ( !item || !item->isEmpty() )
2664     return;
2665
2666   QtxPagePrefFrameItem* frm = new QtxPagePrefFrameItem( item->title(), item->parentItem() );
2667   frm->setIcon( item->icon() );
2668   frm->setStretch( false );
2669   item->parentItem()->insertItem( frm, item );
2670   new QtxPagePrefLabelItem( Qt::AlignCenter, tr( "PREFERENCES_NOT_SUPPORTED" ).arg( modName ), frm );
2671   delete item;
2672 }
2673
2674 /*!
2675   Create preferences
2676 */
2677 void LightApp_Application::createPreferences( LightApp_Preferences* pref )
2678 {
2679   if ( !pref )
2680     return;
2681
2682   QStringList     aValuesList;
2683   QList<QVariant> anIndicesList;
2684   QIntList        idList;
2685   QIntList        txtList;
2686
2687   // . Top-level "SALOME" preferences group <<start>>
2688   int salomeCat = pref->addPreference( tr( "PREF_CATEGORY_SALOME" ) );
2689   pref->setItemIcon( salomeCat, Qtx::scaleIcon( resourceMgr()->loadPixmap( "LightApp", tr( "APP_DEFAULT_ICO" ), false ), 20 ) );
2690
2691   // .. "General" preferences tab <<start>>
2692   int genTab = pref->addPreference( tr( "PREF_TAB_GENERAL" ), salomeCat );
2693
2694   // ... "Language" group <<start>>
2695   int langGroup = pref->addPreference( tr( "PREF_GROUP_LANGUAGE" ), genTab );
2696   pref->setItemProperty( "columns", 2, langGroup );
2697   // .... -> application language
2698   int curLang = pref->addPreference( tr( "PREF_CURRENT_LANGUAGE" ), langGroup,
2699                                           LightApp_Preferences::Selector, "language", "language" );
2700   QStringList aLangs = SUIT_Session::session()->resourceMgr()->stringValue( "language", "languages", "en" ).split( "," );
2701   QList<QVariant> aIcons;
2702   QList<QVariant> aNumbers;
2703   QStringList aTitles;
2704   foreach ( QString aLang, aLangs ) {
2705     aIcons << QPixmap( QString( ":/images/%1" ).arg( aLang ) );
2706     aNumbers << aLang;
2707     aTitles << langToName( aLang );
2708   }
2709   pref->setItemProperty( "strings", aTitles, curLang );
2710   pref->setItemProperty( "ids",     aNumbers, curLang );
2711   pref->setItemProperty( "icons",   aIcons, curLang );
2712   pref->setItemProperty( "restart",  true, curLang );
2713
2714   int curLocale = pref->addPreference( tr( "PREF_CURRENT_LOCALE" ), langGroup,
2715                                           LightApp_Preferences::Bool, "language", "locale" );
2716   pref->setItemProperty( "restart",  true, curLocale );
2717   // ... "Language" group <<end>>
2718
2719   // ... "Look and feel" group <<start>>
2720   int lookGroup = pref->addPreference( tr( "PREF_GROUP_LOOK_AND_FEEL" ), genTab );
2721   pref->setItemProperty( "columns", 2, lookGroup );
2722   // .... -> show splash-screen
2723   pref->addPreference( tr( "PREF_SHOW_SPLASH" ), lookGroup, LightApp_Preferences::Bool, "launch", "splash" );
2724   // .... -> opaque resize
2725   pref->addPreference( tr( "PREF_OPAQUE_RESIZE" ), lookGroup, LightApp_Preferences::Bool, "desktop", "opaque_resize" );
2726   // .... -> drop-down buttons
2727   pref->addPreference( tr( "PREF_DROP_DOWN_BUTTONS" ), lookGroup, LightApp_Preferences::Bool, "viewers", "drop_down_buttons" );
2728   // .... -> Notification timeout
2729   int delay = pref->addPreference( tr( "PREF_NOTIFY_TIMEOUT" ), lookGroup, LightApp_Preferences::IntSpin, "notification", "timeout" );
2730   pref->setItemProperty( "special", tr("PREF_NOTIFY_TIMEOUT_NONE"), delay );
2731   pref->setItemProperty( "min", 0, delay );
2732   pref->setItemProperty( "max", 100, delay );
2733   pref->setItemProperty( "suffix", " sec", delay );
2734   // ... "Look and feel" group <<end>>
2735
2736   // ... "Study properties" group <<start>>
2737   int studyGroup = pref->addPreference( tr( "PREF_GROUP_STUDY" ), genTab );
2738   pref->setItemProperty( "columns", 2, studyGroup );
2739   // .... -> multi-file save
2740   pref->addPreference( tr( "PREF_MULTI_FILE" ), studyGroup, LightApp_Preferences::Bool, "Study", "multi_file" );
2741   // .... -> ascii save mode
2742   pref->addPreference( tr( "PREF_ASCII_FILE" ), studyGroup, LightApp_Preferences::Bool, "Study", "ascii_file" );
2743   // .... -> store windows geometry
2744   pref->addPreference( tr( "PREF_LOAD_LIGHT" ), studyGroup, LightApp_Preferences::Bool, "Study", "autoload_light_modules" );
2745   pref->addPreference( tr( "PREF_STORE_POS" ),  studyGroup, LightApp_Preferences::Bool, "Study", "store_positions" );
2746   pref->addPreference( "", studyGroup, LightApp_Preferences::Space );
2747   pref->addPreference( tr( "PREF_STORE_TOOL_POS" ),  studyGroup, LightApp_Preferences::Bool, "Study", "store_tool_positions" );
2748   // .... -> auto-save
2749   int autoSaveInterval = pref->addPreference( tr( "PREF_AUTO_SAVE" ),  studyGroup,
2750                                               LightApp_Preferences::IntSpin, "Study", "auto_save_interval" );
2751   pref->setItemProperty( "min",        0, autoSaveInterval );
2752   pref->setItemProperty( "max",     1440, autoSaveInterval );
2753   pref->setItemProperty( "special", tr( "PREF_AUTO_SAVE_DISABLED" ), autoSaveInterval );
2754   // ... "Study properties" group <<end>>
2755
2756   // ... "Help browser" group <<start>>
2757 #ifndef DISABLE_QTXWEBBROWSER
2758   int extgroup = pref->addPreference( tr( "PREF_GROUP_EXT_BROWSER" ), genTab, LightApp_Preferences::Auto, "ExternalBrowser", "use_external_browser");
2759 #else
2760   int extgroup = pref->addPreference( tr( "PREF_GROUP_EXT_BROWSER" ), genTab );
2761 #endif
2762
2763 #ifdef WIN32
2764   QString platform = "winapplication";
2765 #else
2766   QString platform = "application";
2767 #endif
2768   // .... -> browser application
2769   int apppref = pref->addPreference( tr( "PREF_APP" ), extgroup, LightApp_Preferences::File, "ExternalBrowser", platform );
2770   pref->setItemProperty( "mode", Qtx::PT_OpenFile, apppref );
2771   // .... -> browser parameters
2772   pref->addPreference( tr( "PREF_PARAM" ), extgroup, LightApp_Preferences::String, "ExternalBrowser", "parameters" );
2773   // ... "Help browser" group <<end>>
2774
2775   // ... "Python console properties" group <<start>>
2776   int pythonConsoleGroup = pref->addPreference( tr( "PREF_GROUP_PY_CONSOLE" ), genTab );
2777   pref->setItemProperty( "columns", 2, pythonConsoleGroup );
2778   // .... -> font
2779   pref->addPreference( tr( "PREF_FONT" ), pythonConsoleGroup, LightApp_Preferences::Font, "PyConsole", "font" );
2780   // .... -> show banner
2781   pref->addPreference( tr( "PREF_SHOW_BANNER" ), pythonConsoleGroup, LightApp_Preferences::Bool, "PyConsole", "show_banner" );
2782   // .... -> auto-completion
2783   pref->addPreference( tr( "PREF_AUTO_COMPLETION" ), pythonConsoleGroup, LightApp_Preferences::Bool, "PyConsole", "auto_completion" );
2784   // ... "Python console properties" group <<end>>
2785
2786   // ... "MRU" preferences group <<start>>
2787   int mruGroup = pref->addPreference( tr( "PREF_GROUP_MRU" ), genTab, LightApp_Preferences::Auto, "MRU", "show_mru" );
2788   pref->setItemProperty( "columns", 4, mruGroup );
2789   // number of MRU items
2790   int mruVisCount = pref->addPreference( tr( "PREF_MRU_VISIBLE_COUNT" ), mruGroup, LightApp_Preferences::IntSpin,
2791                                          "MRU", "visible_count" );
2792   pref->setItemProperty( "min", 0,   mruVisCount );
2793   pref->setItemProperty( "max", 100, mruVisCount );
2794   // MRU links type
2795   int mruLinkType = pref->addPreference( tr( "PREF_MRU_LINK_TYPE" ), mruGroup, LightApp_Preferences::Selector,
2796                                          "MRU", "link_type" );
2797   aValuesList.clear();
2798   anIndicesList.clear();
2799   aValuesList   << tr("PREF_MRU_LINK_AUTO") << tr("PREF_MRU_LINK_SHORT") << tr("PREF_MRU_LINK_FULL");
2800   anIndicesList << 0                        << 1                         << 2                       ;
2801   pref->setItemProperty( "strings", aValuesList,   mruLinkType );
2802   pref->setItemProperty( "indexes", anIndicesList, mruLinkType );
2803   // ... "MRU" preferences group <<end>>
2804
2805   // ... "Full-screen" group <<start>>
2806   int fullScreenGroup = pref->addPreference( tr( "PREF_GROUP_FULL_SCREEN" ), genTab );
2807   pref->setItemProperty( "columns", 2, fullScreenGroup );
2808   // .... -> automatic hiding toolbars
2809   pref->addPreference( tr( "PREF_FULL_SCREEN_AUTO" ), fullScreenGroup,
2810                        LightApp_Preferences::Bool, "OCCViewer", "automatic_hiding" );
2811   // ... "Full-screen" group <<end>>
2812
2813   // .. "General" preferences tab <<end>>
2814
2815   // .. "3D viewer" group <<start>>
2816   int Viewer3DGroup = pref->addPreference( tr( "PREF_GROUP_3DVIEWER" ), salomeCat );
2817   // ... -> navigation mode
2818   int vtkStyleMode = pref->addPreference( tr( "PREF_NAVIGATION" ), Viewer3DGroup,
2819                                           LightApp_Preferences::Selector, "3DViewer", "navigation_mode" );
2820   aValuesList.clear();
2821   anIndicesList.clear();
2822   aValuesList   << tr("PREF_STANDARD_STYLE") << tr("PREF_KEYFREE_STYLE");
2823   anIndicesList << 0                         << 1;
2824   pref->setItemProperty( "strings", aValuesList,   vtkStyleMode );
2825   pref->setItemProperty( "indexes", anIndicesList, vtkStyleMode );
2826   // ... -> zooming mode
2827   int occZoomingStyleMode = pref->addPreference( tr( "PREF_ZOOMING" ), Viewer3DGroup,
2828                                                  LightApp_Preferences::Selector, "3DViewer", "zooming_mode" );
2829   aValuesList.clear();
2830   anIndicesList.clear();
2831   aValuesList   << tr("PREF_ZOOMING_AT_CENTER") << tr("PREF_ZOOMING_AT_CURSOR");
2832   anIndicesList << 0                            << 1;
2833   pref->setItemProperty( "strings", aValuesList,   occZoomingStyleMode );
2834   pref->setItemProperty( "indexes", anIndicesList, occZoomingStyleMode );
2835   // ... "Trihedron" group <<start>>
2836   int occTriGroup = pref->addPreference( tr( "PREF_TRIHEDRON" ), Viewer3DGroup );
2837   pref->setItemProperty( "columns", 2, occTriGroup );
2838   // .... -> trihedron size
2839   int occTS = pref->addPreference( tr( "PREF_TRIHEDRON_SIZE" ), occTriGroup,
2840                                    LightApp_Preferences::DblSpin, "3DViewer", "trihedron_size" );
2841   pref->setItemProperty( "min", 1.0E-06, occTS );
2842   pref->setItemProperty( "max", 1000, occTS );
2843   // .... -> relative size of trihedron
2844   pref->addPreference( tr( "PREF_RELATIVE_SIZE" ), occTriGroup, LightApp_Preferences::Bool, "3DViewer", "relative_size" );
2845   // .... -> show static trihedron
2846   pref->addPreference( tr( "PREF_SHOW_STATIC_TRIHEDRON" ), occTriGroup, LightApp_Preferences::Bool, "3DViewer", "show_static_trihedron" );
2847   // ... "Trihedron" group <<end>>
2848   // .. "3D viewer" group <<end>>
2849
2850   QString formats;
2851   int bgId;
2852 #ifndef DISABLE_OCCVIEWER
2853   // .. "OCC viewer" group <<start>>
2854   int occGroup = pref->addPreference( tr( "PREF_GROUP_OCCVIEWER" ), salomeCat );
2855
2856   // .... -> Projection mode
2857   int occProjMode = pref->addPreference( tr( "PREF_PROJECTION_MODE" ), occGroup,
2858                                          LightApp_Preferences::Selector, "OCCViewer", "projection_mode" );
2859   aValuesList.clear();
2860   anIndicesList.clear();
2861   aValuesList   << tr("PREF_ORTHOGRAPHIC") << tr("PREF_PERSPECTIVE");
2862   anIndicesList << 0                       << 1;
2863   pref->setItemProperty( "strings", aValuesList,   occProjMode );
2864   pref->setItemProperty( "indexes", anIndicesList, occProjMode );
2865
2866   // .... -> Stereo group
2867   int stereoGroup = pref->addPreference( tr( "PREF_GROUP_STEREO" ), occGroup);
2868   pref->setItemProperty( "columns", 2, stereoGroup );
2869   // .... -> Stereo type
2870   int stereoType = pref->addPreference( tr( "PREF_STEREO_TYPE" ), stereoGroup,
2871                                             LightApp_Preferences::Selector, "OCCViewer", "stereo_type" );
2872   aValuesList.clear();
2873   anIndicesList.clear();
2874   idList.clear();
2875   OCCViewer_Viewer::stereoData( aValuesList, idList);
2876   foreach( int gid, idList ) anIndicesList << gid;
2877   pref->setItemProperty( "strings", aValuesList,   stereoType );
2878   pref->setItemProperty( "indexes", anIndicesList, stereoType );
2879
2880   // .... -> Anaglyph filter
2881   int anaglyphFilter = pref->addPreference( tr( "PREF_ANAGLYPH_FILTER" ), stereoGroup,
2882                                             LightApp_Preferences::Selector, "OCCViewer", "anaglyph_filter" );
2883   aValuesList.clear();
2884   anIndicesList.clear();
2885   aValuesList   << tr("PREF_ANAGLYPH_RED_CYAN") << tr("PREF_ANAGLYPH_YELLOW_BLUE") << tr("PREF_ANAGLYPH_GREEN_MAGENTA");
2886   anIndicesList << 0                            << 1                               << 2;
2887
2888   pref->setItemProperty( "strings", aValuesList,   anaglyphFilter );
2889   pref->setItemProperty( "indexes", anIndicesList, anaglyphFilter );
2890
2891   // .... -> Convergence distance type
2892   int occFocusType = pref->addPreference( tr( "PREF_FOCUS_TYPE" ), stereoGroup,
2893                                            LightApp_Preferences::Selector, "OCCViewer", "focus_type" );
2894   aValuesList.clear();
2895   anIndicesList.clear();
2896   aValuesList   << tr("PREF_ABSOLUTE") << tr("PREF_RELATIVE");
2897   anIndicesList << 0                   << 1;
2898   pref->setItemProperty( "strings", aValuesList,   occFocusType );
2899   pref->setItemProperty( "indexes", anIndicesList, occFocusType );
2900
2901   // .... -> Stereographic focus value
2902   int focusValue = pref->addPreference( tr( "PREF_FOCUS_VALUE" ), stereoGroup,
2903                LightApp_Preferences::DblSpin, "OCCViewer", "focus_value" );
2904   pref->setItemProperty( "precision", 3, focusValue );
2905   pref->setItemProperty( "min", 1.0E-03, focusValue );
2906   pref->setItemProperty( "max", 1.0E03, focusValue );
2907   pref->setItemProperty( "step", 0.05, focusValue );
2908
2909   // .... -> IOD type
2910   int occIODType = pref->addPreference( tr( "PREF_IOD_TYPE" ), stereoGroup,
2911                                            LightApp_Preferences::Selector, "OCCViewer", "iod_type" );
2912   aValuesList.clear();
2913   anIndicesList.clear();
2914   aValuesList   << tr("PREF_ABSOLUTE") << tr("PREF_RELATIVE");
2915   anIndicesList << 0                   << 1;
2916   pref->setItemProperty( "strings", aValuesList,   occIODType );
2917   pref->setItemProperty( "indexes", anIndicesList, occIODType );
2918
2919   // .... -> Interocular distance (IOD) value
2920   int IODValue = pref->addPreference( tr( "PREF_IOD_VALUE" ), stereoGroup,
2921                                       LightApp_Preferences::DblSpin, "OCCViewer", "iod_value" );
2922   pref->setItemProperty( "precision", 3, IODValue );
2923   pref->setItemProperty( "min", 1.0E-03, IODValue );
2924   pref->setItemProperty( "max", 1.0E03, IODValue );
2925   pref->setItemProperty( "step", 0.05, IODValue );
2926
2927   // .... -> Reverse stereo
2928   pref->addPreference( tr( "PREF_REVERSE_STEREO" ), stereoGroup,
2929                        LightApp_Preferences::Bool, "OCCViewer", "reverse_stereo" );
2930   // .... -> Enable V-Sync
2931   pref->addPreference( tr( "PREF_ENABLE_VSYNC" ), stereoGroup,
2932                        LightApp_Preferences::Bool, "OCCViewer", "enable_vsync" );
2933   // .... -> Enable quad-buffer support
2934   pref->addPreference( tr( "PREF_ENABLE_QUAD_BUFFER_SUPPORT" ), stereoGroup,
2935                        LightApp_Preferences::Bool, "OCCViewer", "enable_quad_buffer_support" );
2936
2937   // ... "Background" group <<start>>
2938   int bgGroup = pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), occGroup );
2939   //  pref->setItemProperty( "columns", 2, bgGroup );
2940   aValuesList.clear();
2941   anIndicesList.clear();
2942   txtList.clear();
2943   idList.clear();
2944   formats = OCCViewer_Viewer::backgroundData( aValuesList, idList, txtList );
2945   foreach( int gid, idList ) anIndicesList << gid;
2946   // .... -> 3D viewer background
2947   bgId = pref->addPreference( tr( "PREF_3DVIEWER_BACKGROUND" ), bgGroup,
2948                                   LightApp_Preferences::Background, "OCCViewer", "background" );
2949   pref->setItemProperty( "gradient_names", aValuesList, bgId );
2950   pref->setItemProperty( "gradient_ids", anIndicesList, bgId );
2951   pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId );
2952   pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId );
2953   pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId );
2954   pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId );
2955   pref->setItemProperty( "custom_enabled", false, bgId );
2956   pref->setItemProperty( "image_formats", formats, bgId );
2957   // .... -> XZ viewer background
2958   bgId = pref->addPreference( tr( "PREF_XZVIEWER_BACKGROUND" ), bgGroup,
2959                               LightApp_Preferences::Background, "OCCViewer", "xz_background" );
2960   pref->setItemProperty( "gradient_names", aValuesList, bgId );
2961   pref->setItemProperty( "gradient_ids", anIndicesList, bgId );
2962   pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId );
2963   pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId );
2964   pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId );
2965   pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId );
2966   pref->setItemProperty( "custom_enabled", false, bgId );
2967   pref->setItemProperty( "image_formats", formats, bgId );
2968   // .... -> YZ viewer background
2969   bgId = pref->addPreference( tr( "PREF_YZVIEWER_BACKGROUND" ), bgGroup,
2970                               LightApp_Preferences::Background, "OCCViewer", "yz_background" );
2971   pref->setItemProperty( "gradient_names", aValuesList, bgId );
2972   pref->setItemProperty( "gradient_ids", anIndicesList, bgId );
2973   pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId );
2974   pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId );
2975   pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId );
2976   pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId );
2977   pref->setItemProperty( "custom_enabled", false, bgId );
2978   pref->setItemProperty( "image_formats", formats, bgId );
2979   // .... -> XY viewer background
2980   bgId = pref->addPreference( tr( "PREF_XYVIEWER_BACKGROUND" ), bgGroup,
2981                               LightApp_Preferences::Background, "OCCViewer", "xy_background" );
2982   pref->setItemProperty( "gradient_names", aValuesList, bgId );
2983   pref->setItemProperty( "gradient_ids", anIndicesList, bgId );
2984   pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId );
2985   pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId );
2986   pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId );
2987   pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId );
2988   pref->setItemProperty( "custom_enabled", false, bgId );
2989   pref->setItemProperty( "image_formats", formats, bgId );
2990   // ... "Background" group <<end>>
2991
2992
2993   // ... "Selection" group <<start>>
2994   int occSelectionGroup = pref->addPreference( tr( "PREF_GROUP_SELECTION" ), occGroup );
2995   pref->setItemProperty( "columns", 3, occSelectionGroup );
2996   // .... -> enable preselection
2997   pref->addPreference( tr( "PREF_ENABLE_PRESELECTION" ), occSelectionGroup,
2998                        LightApp_Preferences::Bool, "OCCViewer", "enable_preselection" );
2999   // .... -> enable selection
3000   pref->addPreference( tr( "PREF_ENABLE_SELECTION" ), occSelectionGroup,
3001                        LightApp_Preferences::Bool, "OCCViewer", "enable_selection" );
3002   // .... -> selection style
3003   int aSeleStyle = pref->addPreference( tr( "PREF_SELECTION_STYLE" ), occSelectionGroup,
3004                        LightApp_Preferences::Selector, "OCCViewer", "adv_selection_mode" );
3005   aValuesList.clear();
3006   anIndicesList.clear();
3007   aValuesList   << tr("PREF_POLYGON_SELECTION") << tr("PREF_CIRCLE_SELECTION");
3008   anIndicesList << 0 << 1;
3009   pref->setItemProperty( "strings", aValuesList, aSeleStyle);
3010   pref->setItemProperty( "indexes", anIndicesList, aSeleStyle);
3011   // ... "Selection" group <<end>>
3012
3013   // ... "Clipping" group <<start>>
3014   int occClippingGroup = pref->addPreference( tr( "PREF_GROUP_CLIPPING" ), occGroup );
3015   // .... -> clipping color
3016   pref->addPreference( tr( "PREF_CLIPPING_COLOR" ), occClippingGroup,
3017                        LightApp_Preferences::Color, "OCCViewer", "clipping_color" );
3018   int texturePref = pref->addPreference( "", occClippingGroup, LightApp_Preferences::Frame );
3019   pref->setItemProperty( "columns", 2, texturePref );
3020   // .... -> use default texture
3021   pref->addPreference( tr( "PREF_CLIPPING_DEFAULT_TEXTURE" ), texturePref,
3022                LightApp_Preferences::Bool, "OCCViewer", "clipping_use_default_texture" );
3023   // .... -> clipping texture
3024   int filePref = pref->addPreference( tr( "PREF_CLIPPING_TEXTURE" ), texturePref,
3025                LightApp_Preferences::File, "OCCViewer", "clipping_texture" );
3026   pref->setItemProperty( "path_filter", tr( "OCC_TEXTURE_FILES" ), filePref );
3027   // .... -> modulate
3028   pref->addPreference( tr( "PREF_CLIPPING_MODULATE" ), texturePref,
3029                LightApp_Preferences::Bool, "OCCViewer", "clipping_modulate" );
3030   // .... -> scale factor
3031   int scaleFactor = pref->addPreference( tr( "PREF_CLIPPING_SCALE" ), texturePref,
3032                LightApp_Preferences::DblSpin, "OCCViewer", "clipping_scale" );
3033   pref->setItemProperty( "precision", 3, scaleFactor );
3034   pref->setItemProperty( "min", 1.0E-03, scaleFactor );
3035   pref->setItemProperty( "max", 1.0E03, scaleFactor );
3036   pref->setItemProperty( "step", 0.1, scaleFactor );
3037   // ... "Clipping" group <<end>>
3038
3039   // ... "Ray tracing" group <<start>>
3040   int occRayTracingGroup = pref->addPreference( tr( "PREF_GROUP_RAY_TRACING" ), occGroup );
3041   int rtPref = pref->addPreference( "", occRayTracingGroup, LightApp_Preferences::Frame );
3042   pref->setItemProperty( "columns", 2, rtPref );
3043   // .... -> depth
3044   int rt_depth = pref->addPreference( tr( "PREF_RAY_TRACING_DEPTH" ), rtPref,
3045                LightApp_Preferences::IntSpin, "OCCViewer", "rt_depth" );
3046   pref->setItemProperty( "min", 1, rt_depth );
3047   pref->setItemProperty( "max", 10, rt_depth );
3048   pref->setItemProperty( "step", 1, rt_depth );
3049   pref->addPreference( "", rtPref, LightApp_Preferences::Frame );
3050   // .... -> specular reflections
3051   pref->addPreference( tr( "PREF_RAY_TRACING_REFLECTION" ), rtPref,
3052                LightApp_Preferences::Bool, "OCCViewer", "rt_reflection" );
3053   // .... -> adaptive anti-aliasing
3054   pref->addPreference( tr( "PREF_RAY_TRACING_ANTIALIASING" ), rtPref,
3055                LightApp_Preferences::Bool, "OCCViewer", "rt_antialiasing" );
3056   // .... -> shadows rendering
3057   pref->addPreference( tr( "PREF_RAY_TRACING_SHADOW" ), rtPref,
3058                LightApp_Preferences::Bool, "OCCViewer", "rt_shadow" );
3059   // .... -> transparent shadow
3060   pref->addPreference( tr( "PREF_RAY_TRACING_TRANS_SHADOW" ), rtPref,
3061                LightApp_Preferences::Bool, "OCCViewer", "rt_trans_shadow" );
3062   // ... "Ray tracing" group <<end>>
3063
3064   // ... "Light source" group <<start>>
3065   int occLightGroup = pref->addPreference( tr( "PREF_GROUP_LIGHT" ), occGroup );
3066   // .... -> light color
3067   pref->addPreference( tr( "PREF_LIGHT_COLOR" ), occLightGroup,
3068                LightApp_Preferences::Color, "OCCViewer", "light_color" );
3069   int directionPref = pref->addPreference( "", occLightGroup, LightApp_Preferences::Frame );
3070   pref->setItemProperty( "columns", 3, directionPref );
3071   // .... -> light direction (dx component)
3072   int light_dx = pref->addPreference( tr( "Dx" ), directionPref,
3073                LightApp_Preferences::DblSpin, "OCCViewer", "light_dx" );
3074   pref->setItemProperty( "precision", 2, light_dx );
3075   pref->setItemProperty( "min", -1.0E03, light_dx );
3076   pref->setItemProperty( "max", 1.0E03, light_dx );
3077   pref->setItemProperty( "step", 0.1, light_dx );
3078   // .... -> light direction (dy component)
3079   int light_dy = pref->addPreference( tr( "Dy" ), directionPref,
3080                LightApp_Preferences::DblSpin, "OCCViewer", "light_dy" );
3081   pref->setItemProperty( "precision", 2, light_dy );
3082   pref->setItemProperty( "min", -1.0E03, light_dy );
3083   pref->setItemProperty( "max", 1.0E03, light_dy );
3084   pref->setItemProperty( "step", 0.1, light_dy );
3085   // .... -> light direction (dz component)
3086   int light_dz = pref->addPreference( tr( "Dz" ), directionPref,
3087                LightApp_Preferences::DblSpin, "OCCViewer", "light_dz" );
3088   pref->setItemProperty( "precision", 2, light_dz );
3089   pref->setItemProperty( "min", -1.0E03, light_dz );
3090   pref->setItemProperty( "max", 1.0E03, light_dz );
3091   pref->setItemProperty( "step", 0.1, light_dz );
3092   // ... "Light source" group <<end>>
3093
3094   // ... "View cube" group <<start>>
3095   int occViewCubeGroup = pref->addPreference( tr( "PREF_GROUP_VIEWCUBE" ), occGroup );
3096   pref->setItemProperty( "columns", 2, occViewCubeGroup );
3097   // .... -> show view cube on viewer start
3098   pref->addPreference( tr( "PREF_VIEWCUBE_SHOW" ), occViewCubeGroup,
3099                LightApp_Preferences::Bool, "OCCViewer", "viewcube_show" );
3100   // .... -> view cube duration of animation (sec)
3101   int viewcube_dur = pref->addPreference( tr( "PREF_VIEWCUBE_DURATION" ), occViewCubeGroup,
3102                LightApp_Preferences::DblSpin, "OCCViewer", "viewcube_duration" );
3103   pref->setItemProperty( "min", 0.1, viewcube_dur );
3104   pref->setItemProperty( "max", 10.0, viewcube_dur );
3105   pref->setItemProperty( "step", 0.1, viewcube_dur );
3106   // .... -> show view cube axes
3107   pref->addPreference( tr( "PREF_VIEWCUBE_AXES" ), occViewCubeGroup,
3108                LightApp_Preferences::Bool, "OCCViewer", "viewcube_axes" );
3109   // ... "View cube" group <<end>>
3110
3111   // ... "View cube default (OCCT) attributes" group <<start>>
3112   int occViewCubeAttrsGroup = pref->addPreference( tr( "PREF_VIEWCUBE_CUSTOM" ), occGroup,
3113                LightApp_Preferences::Auto, "OCCViewer", "viewcube_custom" );
3114   pref->setItemProperty( "columns", 2, occViewCubeAttrsGroup );
3115   // .... -> box color
3116   pref->addPreference( tr( "PREF_VIEWCUBE_COLOR" ), occViewCubeAttrsGroup,
3117                LightApp_Preferences::Color, "OCCViewer", "viewcube_color" );
3118   // .... -> view cube size
3119   int viewcube_size = pref->addPreference( tr( "PREF_VIEWCUBE_SIZE" ), occViewCubeAttrsGroup,
3120                LightApp_Preferences::DblSpin, "OCCViewer", "viewcube_size" );
3121   pref->setItemProperty( "min",  30.0, viewcube_size );
3122   pref->setItemProperty( "max", 100.0, viewcube_size );
3123   pref->setItemProperty( "step", 10.0, viewcube_size );
3124   // .... -> text color
3125   pref->addPreference( tr( "PREF_VIEWCUBE_TEXTCOLOR" ), occViewCubeAttrsGroup,
3126                LightApp_Preferences::Color, "OCCViewer", "viewcube_text_color" );
3127   // ... "View cube" group <<end>>
3128
3129   // ... -> empty frame (for layout) <<start>>
3130   int occGen = pref->addPreference( "", occGroup, LightApp_Preferences::Frame );
3131   pref->setItemProperty( "margin",  0, occGen );
3132   pref->setItemProperty( "columns", 2, occGen );
3133   // ... -> empty frame (for layout) <<end>>
3134
3135   // .. "OCC viewer" group <<end>>
3136 #endif
3137
3138 #ifndef DISABLE_VTKVIEWER
3139   // .. "VTK viewer" group <<start>>
3140   int vtkGroup = pref->addPreference( tr( "PREF_GROUP_VTKVIEWER" ), salomeCat ); //viewTab
3141
3142   // ... -> empty frame (for layout) <<start>>
3143   int vtkGen = pref->addPreference( "", vtkGroup, LightApp_Preferences::Frame );
3144   //pref->setItemProperty( "columns", 2, vtkGen );
3145   // .... -> projection mode
3146   int vtkProjMode = pref->addPreference( tr( "PREF_PROJECTION_MODE" ), vtkGen,
3147                                          LightApp_Preferences::Selector, "VTKViewer", "projection_mode" );
3148   aValuesList.clear();
3149   anIndicesList.clear();
3150   aValuesList   << tr("PREF_ORTHOGRAPHIC") << tr("PREF_PERSPECTIVE");
3151   anIndicesList << 0                       << 1;
3152   pref->setItemProperty( "strings", aValuesList,   vtkProjMode );
3153   pref->setItemProperty( "indexes", anIndicesList, vtkProjMode );
3154
3155   // .... -> Stereo group
3156   int vtkStereoGroup = pref->addPreference( tr( "PREF_GROUP_STEREO" ), vtkGroup);
3157   pref->setItemProperty( "columns", 2, vtkStereoGroup );
3158   // .... -> Stereo type
3159   int vtkStereoType = pref->addPreference( tr( "PREF_STEREO_TYPE" ), vtkStereoGroup,
3160                                            LightApp_Preferences::Selector, "VTKViewer", "stereo_type" );
3161   aValuesList.clear();
3162   anIndicesList.clear();
3163   idList.clear();
3164   SVTK_Viewer::stereoData( aValuesList, idList);
3165   foreach( int gid, idList ) anIndicesList << gid;
3166   pref->setItemProperty( "strings", aValuesList,   vtkStereoType );
3167   pref->setItemProperty( "indexes", anIndicesList, vtkStereoType );
3168   // .... -> Anaglyph filter
3169   int vtkAnaglyphFilter = pref->addPreference( tr( "PREF_ANAGLYPH_FILTER" ), vtkStereoGroup,
3170                                                LightApp_Preferences::Selector, "VTKViewer", "anaglyph_filter" );
3171   aValuesList.clear();
3172   anIndicesList.clear();
3173   aValuesList   << tr("PREF_ANAGLYPH_RED_CYAN") << tr("PREF_ANAGLYPH_YELLOW_BLUE") << tr("PREF_ANAGLYPH_GREEN_MAGENTA");
3174   anIndicesList << 0                            << 1                               << 2;
3175
3176   pref->setItemProperty( "strings", aValuesList,   vtkAnaglyphFilter );
3177   pref->setItemProperty( "indexes", anIndicesList, vtkAnaglyphFilter );
3178
3179   // .... -> Enable quad-buffer support
3180   pref->addPreference( tr( "PREF_ENABLE_QUAD_BUFFER_SUPPORT" ), vtkStereoGroup,
3181                        LightApp_Preferences::Bool, "VTKViewer", "enable_quad_buffer_support" );
3182
3183   // .... -> background
3184   aValuesList.clear();
3185   anIndicesList.clear();
3186   txtList.clear();
3187   idList.clear();
3188 #ifndef DISABLE_SALOMEOBJECT
3189   formats = SVTK_Viewer::backgroundData( aValuesList, idList, txtList );
3190 #endif
3191   foreach( int gid, idList ) anIndicesList << gid;
3192   bgId = pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), vtkGen,
3193                               LightApp_Preferences::Background, "VTKViewer", "background" );
3194   pref->setItemProperty( "gradient_names", aValuesList, bgId );
3195   pref->setItemProperty( "gradient_ids", anIndicesList, bgId );
3196   pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId );
3197   pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId );
3198   pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId );
3199   pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId );
3200   pref->setItemProperty( "custom_enabled", false, bgId );
3201 #ifndef DISABLE_SALOMEOBJECT
3202   pref->setItemProperty( "image_formats", formats, bgId );
3203 #endif
3204   // .... -> speed increment
3205   int vtkSpeed = pref->addPreference( tr( "PREF_INCREMENTAL_SPEED" ), vtkGen,
3206                                       LightApp_Preferences::IntSpin, "VTKViewer", "speed_value" );
3207   pref->setItemProperty( "min", 1, vtkSpeed );
3208   pref->setItemProperty( "max", 1000, vtkSpeed );
3209   // .... -> speed mode
3210   int vtkSpeedMode = pref->addPreference( tr( "PREF_INCREMENTAL_SPEED_MODE" ), vtkGen,
3211                                           LightApp_Preferences::Selector, "VTKViewer", "speed_mode" );
3212   aValuesList.clear();
3213   anIndicesList.clear();
3214   aValuesList   << tr("PREF_ARITHMETIC") << tr("PREF_GEOMETRICAL");
3215   anIndicesList << 0                     << 1;
3216   pref->setItemProperty( "strings", aValuesList,   vtkSpeedMode );
3217   pref->setItemProperty( "indexes", anIndicesList, vtkSpeedMode );
3218
3219   // ... "Selection" group <<start>>
3220   int vtkSelectionGroup = pref->addPreference( tr( "PREF_GROUP_SELECTION" ), vtkGroup );
3221   pref->setItemProperty( "columns", 2, vtkSelectionGroup );
3222   // .... -> preselection
3223   int vtkPreselection = pref->addPreference( tr( "PREF_PRESELECTION" ),  vtkSelectionGroup,
3224                                              LightApp_Preferences::Selector, "VTKViewer", "preselection" );
3225   aValuesList.clear();
3226   anIndicesList.clear();
3227   aValuesList   << tr("PREF_PRESELECTION_STANDARD") << tr("PREF_PRESELECTION_DYNAMIC") << tr("PREF_PRESELECTION_DISABLED");
3228   anIndicesList << 0 << 1 << 2;
3229   pref->setItemProperty( "strings", aValuesList,   vtkPreselection );
3230   pref->setItemProperty( "indexes", anIndicesList, vtkPreselection );
3231   // .... -> enable selection
3232   pref->addPreference( tr( "PREF_ENABLE_SELECTION" ), vtkSelectionGroup, LightApp_Preferences::Bool, "VTKViewer", "enable_selection" );
3233   // ... "Selection" group <<end>>
3234
3235   // ... -> empty frame (for layout) <<end>>
3236
3237   // ... space mouse sub-group <<start>>
3238   int vtkSM = pref->addPreference( tr( "PREF_FRAME_SPACEMOUSE" ), vtkGroup, LightApp_Preferences::GroupBox );
3239   //pref->setItemProperty( "columns", 2, vtkSM );
3240   // .... -> decrease speed increment
3241   int spacemousePref1 = pref->addPreference( tr( "PREF_SPACEMOUSE_FUNC_1" ), vtkSM,
3242                                              LightApp_Preferences::Selector, "VTKViewer",
3243                                              "spacemouse_func1_btn" );
3244   // .... -> increase speed increment
3245   int spacemousePref2 = pref->addPreference( tr( "PREF_SPACEMOUSE_FUNC_2" ), vtkSM,
3246                                              LightApp_Preferences::Selector, "VTKViewer",
3247                                              "spacemouse_func2_btn" );
3248   // .... -> dominant / combined switch
3249   int spacemousePref3 = pref->addPreference( tr( "PREF_SPACEMOUSE_FUNC_3" ), vtkSM,
3250                                              LightApp_Preferences::Selector, "VTKViewer",
3251                                              "spacemouse_func5_btn" ); //
3252   aValuesList.clear();
3253   anIndicesList.clear();
3254   aValuesList << tr( "PREF_SPACEMOUSE_BTN_1" )  << tr( "PREF_SPACEMOUSE_BTN_2" ) << tr( "PREF_SPACEMOUSE_BTN_3" );
3255   aValuesList << tr( "PREF_SPACEMOUSE_BTN_4" )  << tr( "PREF_SPACEMOUSE_BTN_5" ) << tr( "PREF_SPACEMOUSE_BTN_6" );
3256   aValuesList << tr( "PREF_SPACEMOUSE_BTN_7" )  << tr( "PREF_SPACEMOUSE_BTN_8" ) << tr( "PREF_SPACEMOUSE_BTN_*" );
3257   aValuesList << tr( "PREF_SPACEMOUSE_BTN_10" ) << tr( "PREF_SPACEMOUSE_BTN_11" );
3258   anIndicesList << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10 << 11;
3259   pref->setItemProperty( "strings", aValuesList,   spacemousePref1 );
3260   pref->setItemProperty( "indexes", anIndicesList, spacemousePref1 );
3261   pref->setItemProperty( "strings", aValuesList,   spacemousePref2 );
3262   pref->setItemProperty( "indexes", anIndicesList, spacemousePref2 );
3263   pref->setItemProperty( "strings", aValuesList,   spacemousePref3 );
3264   pref->setItemProperty( "indexes", anIndicesList, spacemousePref3 );
3265   // ... space mouse sub-group <<end>>
3266
3267   // ... avi recording sub-group <<start>>
3268   int vtkRec = pref->addPreference( tr( "PREF_FRAME_RECORDING" ), vtkGroup, LightApp_Preferences::GroupBox );
3269   pref->setItemProperty( "columns", 2, vtkRec );
3270   // .... -> recording mode
3271   int modePref = pref->addPreference( tr( "PREF_RECORDING_MODE" ), vtkRec,
3272                                       LightApp_Preferences::Selector, "VTKViewer", "recorder_mode" );
3273   aValuesList.clear();
3274   anIndicesList.clear();
3275   aValuesList   << tr( "PREF_SKIPPED_FRAMES" ) << tr( "PREF_ALL_DISLPAYED_FRAMES" );
3276   anIndicesList << 0                           << 1;
3277   pref->setItemProperty( "strings", aValuesList,   modePref );
3278   pref->setItemProperty( "indexes", anIndicesList, modePref );
3279   // .... -> fps
3280   int fpsPref = pref->addPreference( tr( "PREF_FPS" ), vtkRec,
3281                                      LightApp_Preferences::DblSpin, "VTKViewer", "recorder_fps" );
3282   pref->setItemProperty( "min", 0.1, fpsPref );
3283   pref->setItemProperty( "max", 100, fpsPref );
3284   // .... -> quality
3285   int qualityPref = pref->addPreference( tr( "PREF_QUALITY" ), vtkRec,
3286                                          LightApp_Preferences::IntSpin, "VTKViewer", "recorder_quality" );
3287   pref->setItemProperty( "min", 1, qualityPref );
3288   pref->setItemProperty( "max", 100, qualityPref );
3289   // .... -> progressive mode
3290   pref->addPreference( tr( "PREF_PROGRESSIVE" ), vtkRec,
3291                        LightApp_Preferences::Bool, "VTKViewer", "recorder_progressive" );
3292   // ... avi recording sub-group <<end>>
3293
3294   // ... group names sub-group <<start>>
3295   int vtkGN = pref->addPreference( tr( "PREF_FRAME_GROUP_NAMES" ), vtkGroup,
3296                                    LightApp_Preferences::GroupBox, "VTKViewer", "show_group_names" );
3297   pref->setItemProperty( "columns", 2, vtkGN );
3298   // .... -> text color
3299   pref->addPreference( tr(  "PREF_GROUP_NAMES_TEXT_COLOR" ), vtkGN,
3300                        LightApp_Preferences::Color, "VTKViewer", "group_names_text_color" );
3301   // .... -> transparency
3302   int transPref = pref->addPreference( tr( "PREF_GROUP_NAMES_TRANSPARENCY" ), vtkGN,
3303                                        LightApp_Preferences::DblSpin, "VTKViewer", "group_names_transparency" );
3304   pref->setItemProperty( "min", 0.0, transPref );
3305   pref->setItemProperty( "max", 1.0, transPref );
3306   pref->setItemProperty( "step", 0.1, transPref );
3307   // ... -> group names sub-group <<end>>
3308   // .. "VTK viewer" group <<end>>
3309 #endif
3310
3311   // .. "Plot2d viewer" group <<start>>
3312   int plot2dGroup = pref->addPreference( tr( "PREF_GROUP_PLOT2DVIEWER" ), salomeCat ); //viewTab
3313   //pref->setItemProperty( "columns", 2, plot2dGroup );
3314
3315   // ... -> background
3316   pref->addPreference( tr( "PREF_VIEWER_BACKGROUND_COLOR" ), plot2dGroup,
3317                        LightApp_Preferences::Color, "Plot2d", "Background" );
3318   // ... -> selection color
3319   pref->addPreference( tr( "PREF_VIEWER_SELECTION" ), plot2dGroup,
3320                        LightApp_Preferences::Color, "Plot2d", "SelectionColor" );
3321
3322   // ... "Viewer" group <<start>>
3323   int plot2dViewerGroup = pref->addPreference( tr( "PREF_GROUP_VIEWER" ), plot2dGroup );
3324
3325   // .... -> curve type
3326   int curveType = pref->addPreference( tr( "PREF_CURVE_TYPE" ), plot2dViewerGroup,
3327                                        LightApp_Preferences::Selector, "Plot2d", "CurveType" );
3328   aValuesList.clear();
3329   anIndicesList.clear();
3330   aValuesList   << tr("PREF_POINTS") << tr("PREF_LINES") << tr("PREF_SPLINE");
3331   anIndicesList << 0                 << 1                << 2                ;
3332   pref->setItemProperty( "strings", aValuesList,   curveType );
3333   pref->setItemProperty( "indexes", anIndicesList, curveType );
3334   // .... -> marker size
3335   int markerSize = pref->addPreference( tr( "PREF_MARKER_SIZE" ), plot2dViewerGroup,
3336                                         LightApp_Preferences::IntSpin, "Plot2d", "MarkerSize" );
3337   pref->setItemProperty( "min", 0, markerSize );
3338   pref->setItemProperty( "max", 100, markerSize );
3339   // .... -> horizontal scaling mode
3340   int horScale = pref->addPreference( tr( "PREF_HOR_AXIS_SCALE" ), plot2dViewerGroup,
3341                                       LightApp_Preferences::Selector, "Plot2d", "HorScaleMode" );
3342   aValuesList.clear();
3343   anIndicesList.clear();
3344   aValuesList   << tr("PREF_LINEAR") << tr("PREF_LOGARITHMIC");
3345   anIndicesList << 0                 << 1                     ;
3346   pref->setItemProperty( "strings", aValuesList,   horScale );
3347   pref->setItemProperty( "indexes", anIndicesList, horScale );
3348   // .... -> vertical scaling mode
3349   int verScale = pref->addPreference( tr( "PREF_VERT_AXIS_SCALE" ), plot2dViewerGroup,
3350                                       LightApp_Preferences::Selector, "Plot2d", "VerScaleMode" );
3351   pref->setItemProperty( "strings", aValuesList,   verScale );
3352   pref->setItemProperty( "indexes", anIndicesList, verScale );
3353
3354   // .... -> errors/deviation colot
3355   pref->addPreference( tr( "PREF_DEVIATION_COLOR" ), plot2dViewerGroup,
3356                        LightApp_Preferences::Color, "Plot2d", "DeviationMarkerColor" );
3357   // .... -> deviation markers line size
3358   int deviationMarkerLw = pref->addPreference( tr( "PREF_DEVIATION_MARKER_LW" ), plot2dViewerGroup,
3359                                         LightApp_Preferences::IntSpin, "Plot2d", "DeviationMarkerLineWidth" );
3360   pref->setItemProperty( "min", 1, deviationMarkerLw );
3361   pref->setItemProperty( "max", 5, deviationMarkerLw );
3362   // .... -> deviation markers tick mark size
3363   int deviationMarkerTs = pref->addPreference( tr( "PREF_DEVIATION_MARKER_TS" ), plot2dViewerGroup,
3364                                         LightApp_Preferences::IntSpin, "Plot2d", "DeviationMarkerTickSize" );
3365   pref->setItemProperty( "min", 1, deviationMarkerTs );
3366   pref->setItemProperty( "max", 5, deviationMarkerTs );
3367   // .... "Viewer" group <<end>>
3368
3369   // ... "Legend" group <<start>>
3370   int plot2dLegendGroup = pref->addPreference( tr( "PREF_GROUP_LEGEND" ), plot2dGroup );
3371
3372   // .... -> show legend
3373   pref->addPreference( tr( "PREF_SHOW_LEGEND" ), plot2dLegendGroup,
3374                        LightApp_Preferences::Bool, "Plot2d", "ShowLegend" );
3375   // .... -> legend position
3376   int legendPosition = pref->addPreference( tr( "PREF_LEGEND_POSITION" ), plot2dLegendGroup,
3377                                             LightApp_Preferences::Selector, "Plot2d", "LegendPos" );
3378   aValuesList.clear();
3379   anIndicesList.clear();
3380   aValuesList   << tr("PREF_LEFT") << tr("PREF_RIGHT") << tr("PREF_TOP") << tr("PREF_BOTTOM");
3381   anIndicesList << 0               << 1                << 2              << 3                ;
3382   pref->setItemProperty( "strings", aValuesList,   legendPosition );
3383   pref->setItemProperty( "indexes", anIndicesList, legendPosition );
3384   // .... -> Symbol type
3385   int legendSymbolType = pref->addPreference( tr( "PREF_LEGEND_SYMBOL_TYPE" ), plot2dLegendGroup,
3386                                             LightApp_Preferences::Selector, "Plot2d", "LegendSymbolType" );
3387   aValuesList.clear();
3388   anIndicesList.clear();
3389   aValuesList   << tr("PREF_MARKER_ON_LINE") << tr("PREF_MARKER_ABOVE_LINE");
3390   anIndicesList << 0                            << 1                        ;
3391   pref->setItemProperty( "strings", aValuesList,   legendSymbolType );
3392   pref->setItemProperty( "indexes", anIndicesList, legendSymbolType );
3393   // .... -> legend font
3394   pref->addPreference( tr( "PREF_LEGEND_FONT" ), plot2dLegendGroup, LightApp_Preferences::Font, "Plot2d", "LegendFont" );
3395   // ... -> font color
3396   pref->addPreference( tr( "PREF_FONT_COLOR" ), plot2dLegendGroup, LightApp_Preferences::Color, "Plot2d", "LegendFontColor" );
3397   // ... -> selection font color
3398   pref->addPreference( tr( "PREF_SELECTED_FONT_COLOR" ), plot2dLegendGroup, LightApp_Preferences::Color, "Plot2d", "SelectedLegendFontColor" );
3399   // ... "Legend" group <<end>>
3400
3401   // .. "Plot2d viewer" group <<end>>
3402
3403   // .. "PyViewer" preferences tab <<start>>
3404   int pyeditTab = pref->addPreference( tr( "PREF_TAB_PYEDITOR" ), salomeCat );
3405   // ... "Font settings" group <<start>>
3406   int pyFontGroup = pref->addPreference( tr( "PREF_GROUP_PY_FONT" ), pyeditTab );
3407   int pyFont = pref->addPreference( tr( "PREF_PY_FONT" ), pyFontGroup,
3408                                     LightApp_Preferences::Font, "PyEditor", "Font" );
3409   pref->setItemProperty( "features", QtxFontEdit::Family | QtxFontEdit::Size | QtxFontEdit::UserSize, pyFont );
3410   // ... "Font settings" group <<end>>
3411   // ... "Display settings" group <<start>>
3412   int pyDispGroup = pref->addPreference( tr( "PREF_GROUP_PY_DISPLAY" ), pyeditTab );
3413   pref->setItemProperty( "columns", 2, pyDispGroup );
3414   // ... -> current line highlight
3415   pref->addPreference( tr( "PREF_PY_CURRLINE_HIGHLIGHT" ), pyDispGroup,
3416     LightApp_Preferences::Bool, "PyEditor", "HighlightCurrentLine" );
3417   // ... -> text wrapping
3418   pref->addPreference( tr( "PREF_PY_TEXT_WRAP" ), pyDispGroup,
3419     LightApp_Preferences::Bool, "PyEditor", "TextWrapping" );
3420   // ... -> center cursor on scroll
3421   pref->addPreference( tr( "PREF_PY_CURSON_ON_SCROLL" ), pyDispGroup,
3422     LightApp_Preferences::Bool, "PyEditor", "CenterCursorOnScroll" );
3423   // ... -> line numbers area
3424   pref->addPreference( tr( "PREF_PY_LINE_NUMBS_AREA" ), pyDispGroup,
3425     LightApp_Preferences::Bool, "PyEditor", "LineNumberArea" );
3426   // ... "Display settings" group <<end>>
3427
3428   // ... "Editor settings" group <<start>>
3429   int pyEditGroup = pref->addPreference( tr( "PREF_GROUP_PY_EDITOR" ), pyeditTab );
3430   // ... -> navigation mode
3431   int pyCompletion = pref->addPreference( tr( "PREF_PY_COMPLETION_MODE" ), pyEditGroup,
3432                                           LightApp_Preferences::Selector, "PyEditor", "CompletionPolicy" );
3433   aValuesList.clear();
3434   anIndicesList.clear();
3435   aValuesList   << tr("PREF_PY_NONE") << tr("PREF_PY_AUTO") << tr("PREF_PY_MANUAL") << tr("PREF_PY_ALWAYS");
3436   anIndicesList << 0                  << 1                  << 2                    << 3                   ;
3437   pref->setItemProperty( "strings", aValuesList, pyCompletion );
3438   pref->setItemProperty( "indexes", anIndicesList, pyCompletion );
3439   // ... "Editor settings" group <<end>>
3440
3441   // ... "Tab settings" group <<start>>
3442   int pyTabGroup = pref->addPreference( tr( "PREF_GROUP_PY_TAB" ), pyeditTab );
3443   pref->setItemProperty( "columns", 2, pyTabGroup );
3444   // ... -> tab whitespaces
3445   pref->addPreference( tr( "PREF_PY_TAB_WHITESPACES" ), pyTabGroup,
3446     LightApp_Preferences::Bool, "PyEditor", "TabSpaceVisible" );
3447   // ... -> tab size
3448   pref->addPreference( tr( "PREF_PY_TAB_SIZE" ), pyTabGroup,
3449     LightApp_Preferences::IntSpin, "PyEditor", "TabSize" );
3450   // ... "Tab settings" group <<end>>
3451   // ... "Vertical edge settings" group <<start>>
3452   int pyVertEdgeGroup = pref->addPreference( tr( "PREF_GROUP_VERT_EDGE" ), pyeditTab );
3453   pref->setItemProperty( "columns", 2, pyVertEdgeGroup );
3454   // ... -> vertical edge
3455   pref->addPreference( tr( "PREF_PY_VERT_EDGE" ), pyVertEdgeGroup,
3456     LightApp_Preferences::Bool, "PyEditor", "VerticalEdge" );
3457   // ... -> number of columns
3458   pref->addPreference( tr( "PREF_PY_NUM_COLUMNS" ), pyVertEdgeGroup,
3459     LightApp_Preferences::IntSpin, "PyEditor", "NumberColumns" );
3460   // ... "Vertical edge settings" group <<end>>
3461   // .. "PyEditor" preferences tab <<end>>
3462
3463   // .. "Directories" preferences tab <<start>>
3464   int dirTab = pref->addPreference( tr( "PREF_TAB_DIRECTORIES" ), salomeCat );
3465   // ... --> quick directories list
3466   int dirGroup = pref->addPreference( tr( "PREF_GROUP_DIRECTORIES" ), dirTab );
3467   pref->addPreference( tr( "" ), dirGroup,
3468                        LightApp_Preferences::DirList, "FileDlg", "QuickDirList" );
3469   // .. "Directories" preferences tab <<end>>
3470
3471   // .. "Object browser" preferences tab <<start>>
3472   int obTab = pref->addPreference( tr( "PREF_TAB_OBJBROWSER" ), salomeCat );
3473
3474   // ... "Search tool" group <<start>>
3475   int stGroup = pref->addPreference( tr( "PREF_OBJ_BROWSER_SEARCH_TOOL" ), obTab );
3476   // .... --> auto-hide
3477   pref->addPreference( tr( "PREF_AUTO_HIDE_SEARCH_TOOL" ), stGroup, LightApp_Preferences::Bool,
3478                        "ObjectBrowser", "auto_hide_search_tool" );
3479   // ... "Search tool" group <<end>>
3480
3481   // ... "Object browser settings" group <<start>>
3482   int objSetGroup = pref->addPreference( tr( "PREF_GROUP_LOOK_AND_FEEL" ), obTab );
3483   pref->setItemProperty( "columns", 2, objSetGroup );
3484   // .... -> auto size first column
3485   pref->addPreference( tr( "PREF_AUTO_SIZE_FIRST" ), objSetGroup, LightApp_Preferences::Bool,
3486                        "ObjectBrowser", "auto_size_first" );
3487   // .... -> auto size other columns
3488   pref->addPreference( tr( "PREF_AUTO_SIZE" ), objSetGroup, LightApp_Preferences::Bool,
3489                        "ObjectBrowser", "auto_size" );
3490   // .... -> resize columns on expand item
3491   pref->addPreference( tr( "PREF_RESIZE_ON_EXPAND_ITEM" ), objSetGroup, LightApp_Preferences::Bool,
3492                        "ObjectBrowser", "resize_on_expand_item" );
3493   // .... -> browse to published object
3494   int browsePublished = pref->addPreference( tr( "PREF_BROWSE_TO_THE_PUBLISHED_OBJECT" ), objSetGroup, LightApp_Preferences::Selector,
3495                                              "ObjectBrowser", "browse_published_object" );
3496   aValuesList.clear();
3497   anIndicesList.clear();
3498   aValuesList << tr( "PREF_BROWSE_NEVER" ) << tr( "PREF_BROWSE_AFTER_APPLY_AND_CLOSE_ONLY" ) << tr( "PREF_BROWSE_ALWAYS" );
3499   anIndicesList << BP_Never << BP_ApplyAndClose << BP_Always;
3500   pref->setItemProperty( "strings", aValuesList,   browsePublished );
3501   pref->setItemProperty( "indexes", anIndicesList, browsePublished );
3502   // ... "Object browser settings" group <<end>>
3503   // .. "Object browser" preferences tab <<end>>
3504
3505   // .. "Shortcuts" preferences tab <<start>>
3506   int shortcutTab = pref->addPreference( tr( "PREF_TAB_SHORTCUTS" ), salomeCat );
3507   // ... "Shortcuts settings" group <<start>>
3508   int shortcutGroup = pref->addPreference( tr( "PREF_GROUP_SHORTCUTS" ), shortcutTab );
3509   pref->addPreference( tr( "" ), shortcutGroup,
3510                        LightApp_Preferences::ShortcutTree, "shortcuts" );
3511   // ... "Shortcuts settings" group <<end>>
3512   // .. "Shortcuts" preferences tab <<end>>
3513   // . Top-level "SALOME" preferences group <<end>>
3514
3515   pref->retrieve();
3516 }
3517
3518 /*!
3519   Changes appearance of application according to changed preferences
3520   \param sec - section
3521   \param param - name of changed parameter
3522 */
3523 void LightApp_Application::preferencesChanged( const QString& sec, const QString& param )
3524 {
3525   SUIT_ResourceMgr* resMgr = resourceMgr();
3526   if ( !resMgr )
3527     return;
3528
3529   if ( sec == "viewers" && param == "drop_down_buttons" )
3530   {
3531     ViewManagerList vmlist = viewManagers();
3532     foreach( SUIT_ViewManager* vm, vmlist )
3533     {
3534       QVector<SUIT_ViewWindow*> vwlist = vm->getViews();
3535       foreach( SUIT_ViewWindow* vw, vwlist )
3536         if ( vw ) vw->setDropDownButtons( resMgr->booleanValue( "viewers", "drop_down_buttons", true ) );
3537     }
3538   }
3539
3540   if ( sec == QString( "3DViewer" ) && (param == QString( "trihedron_size" ) || param == QString( "relative_size" )))
3541   {
3542     double sz = resMgr->doubleValue( sec, "trihedron_size", -1 );
3543     bool relative = resMgr->booleanValue( sec, "relative_size", true );
3544     QList<SUIT_ViewManager*> lst;
3545 #ifndef DISABLE_OCCVIEWER
3546     viewManagers( OCCViewer_Viewer::Type(), lst );
3547     QListIterator<SUIT_ViewManager*> itOCC( lst );
3548     while ( itOCC.hasNext() && sz >= 0 )
3549     {
3550       SUIT_ViewModel* vm = itOCC.next()->getViewModel();
3551       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
3552         continue;
3553
3554       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
3555       occVM->setTrihedronSize( sz, relative );
3556       occVM->getAISContext()->UpdateCurrentViewer();
3557     }
3558 #endif
3559 #ifndef DISABLE_VTKVIEWER
3560 #ifndef DISABLE_SALOMEOBJECT
3561     viewManagers( SVTK_Viewer::Type(), lst );
3562     QListIterator<SUIT_ViewManager*> itVTK( lst );
3563     while ( itVTK.hasNext() && sz >= 0 )
3564     {
3565       SUIT_ViewModel* vm = itVTK.next()->getViewModel();
3566       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
3567         continue;
3568
3569       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
3570       if( vtkVM )
3571       {
3572         vtkVM->setTrihedronSize( sz, relative );
3573         vtkVM->Repaint();
3574       }
3575     }
3576 #endif
3577 #endif
3578   }
3579
3580   if ( sec == QString( "3DViewer" ) && param == QString( "show_static_trihedron" ) )
3581   {
3582     bool isVisible = resMgr->booleanValue( "3DViewer", "show_static_trihedron", true );
3583     QList<SUIT_ViewManager*> lst;
3584 #ifndef DISABLE_OCCVIEWER
3585     viewManagers( OCCViewer_Viewer::Type(), lst );
3586     QListIterator<SUIT_ViewManager*> itOCC( lst );
3587     while ( itOCC.hasNext() )
3588     {
3589       SUIT_ViewModel* vm = itOCC.next()->getViewModel();
3590       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
3591         continue;
3592
3593       OCCViewer_Viewer* occVM = dynamic_cast<OCCViewer_Viewer*>( vm );
3594       if( occVM )
3595       {
3596         occVM->setStaticTrihedronDisplayed( isVisible );
3597       }
3598     }
3599 #endif
3600 #ifndef DISABLE_VTKVIEWER
3601 #ifndef DISABLE_SALOMEOBJECT
3602     viewManagers( SVTK_Viewer::Type(), lst );
3603     QListIterator<SUIT_ViewManager*> itVTK( lst );
3604     while ( itVTK.hasNext() )
3605     {
3606       SUIT_ViewModel* vm = itVTK.next()->getViewModel();
3607       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
3608         continue;
3609
3610       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
3611       if( vtkVM )
3612       {
3613         vtkVM->setStaticTrihedronVisible( isVisible );
3614         vtkVM->Repaint();
3615       }
3616     }
3617 #endif
3618 #endif
3619   }
3620
3621   if ( sec == QString( "3DViewer" ) && param == QString( "navigation_mode" ) )
3622   {
3623     int mode = resMgr->integerValue( "3DViewer", "navigation_mode", 0 );
3624     QList<SUIT_ViewManager*> lst;
3625 #ifndef DISABLE_OCCVIEWER
3626     viewManagers( OCCViewer_Viewer::Type(), lst );
3627     QListIterator<SUIT_ViewManager*> itOCC( lst );
3628     while ( itOCC.hasNext() )
3629     {
3630       SUIT_ViewModel* vm = itOCC.next()->getViewModel();
3631       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
3632         continue;
3633
3634       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
3635       occVM->setInteractionStyle( mode );
3636     }
3637 #endif
3638 #ifndef DISABLE_VTKVIEWER
3639 #ifndef DISABLE_SALOMEOBJECT
3640     viewManagers( SVTK_Viewer::Type(), lst );
3641     QListIterator<SUIT_ViewManager*> itVTK( lst );
3642     while ( itVTK.hasNext() )
3643     {
3644       SUIT_ViewModel* vm = itVTK.next()->getViewModel();
3645       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
3646         continue;
3647
3648       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
3649       if( vtkVM ) vtkVM->setInteractionStyle( mode );
3650     }
3651 #endif
3652 #endif
3653   }
3654
3655 #ifndef DISABLE_OCCVIEWER
3656   if ( sec == QString( "OCCViewer" ) && param == QString( "enable_preselection" ) )
3657   {
3658     bool isToEnablePreselection = resMgr->booleanValue( "OCCViewer", "enable_preselection", true );
3659     QList<SUIT_ViewManager*> lst;
3660     viewManagers( OCCViewer_Viewer::Type(), lst );
3661     QListIterator<SUIT_ViewManager*> it( lst );
3662     while ( it.hasNext() )
3663     {
3664       SUIT_ViewModel* vm = it.next()->getViewModel();
3665       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
3666         continue;
3667
3668       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
3669       occVM->enablePreselection( isToEnablePreselection );
3670     }
3671   }
3672 #endif
3673
3674 #ifndef DISABLE_OCCVIEWER
3675   if ( sec == QString( "OCCViewer" ) && param == QString( "enable_selection" ) )
3676   {
3677     bool isToEnableSelection = resMgr->booleanValue( "OCCViewer", "enable_selection", true );
3678     QList<SUIT_ViewManager*> lst;
3679     viewManagers( OCCViewer_Viewer::Type(), lst );
3680     QListIterator<SUIT_ViewManager*> it( lst );
3681     while ( it.hasNext() )
3682     {
3683       SUIT_ViewModel* vm = it.next()->getViewModel();
3684       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
3685         continue;
3686
3687       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
3688       occVM->enableSelection( isToEnableSelection );
3689     }
3690   }
3691 #endif
3692
3693 #ifndef DISABLE_OCCVIEWER
3694   if ( sec == QString( "OCCViewer" ) && param == QString( "clipping_color" ) )
3695   {
3696     QColor aColor = resMgr->colorValue( "OCCViewer", "clipping_color", QColor( 50, 50, 50 ) );
3697     QList<SUIT_ViewManager*> lst;
3698     viewManagers( OCCViewer_Viewer::Type(), lst );
3699     QListIterator<SUIT_ViewManager*> it( lst );
3700     while ( it.hasNext() )
3701     {
3702       SUIT_ViewModel* vm = it.next()->getViewModel();
3703       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
3704         continue;
3705
3706       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
3707       occVM->setClippingColor( aColor );
3708     }
3709   }
3710 #endif
3711
3712 #ifndef DISABLE_OCCVIEWER
3713   if ( sec == QString( "OCCViewer" ) && ( param == QString( "clipping_use_default_texture" ) ||
3714                                           param == QString( "clipping_texture" ) ||
3715                                           param == QString( "clipping_modulate" ) ||
3716                                           param == QString( "clipping_scale" ) ) )
3717   {
3718     bool isDefaultTextureUsed = resMgr->booleanValue( "OCCViewer", "clipping_use_default_texture" );
3719     QString aTexture = resMgr->stringValue( "OCCViewer", "clipping_texture" );
3720     bool isModulated = resMgr->booleanValue( "OCCViewer", "clipping_modulate" );
3721     double aScale = resMgr->doubleValue( "OCCViewer", "clipping_scale" );
3722     QList<SUIT_ViewManager*> lst;
3723     viewManagers( OCCViewer_Viewer::Type(), lst );
3724     QListIterator<SUIT_ViewManager*> it( lst );
3725     while ( it.hasNext() )
3726     {
3727       SUIT_ViewModel* vm = it.next()->getViewModel();
3728       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
3729         continue;
3730
3731       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
3732       occVM->setClippingTextureParams( isDefaultTextureUsed, aTexture, isModulated, aScale );
3733     }
3734   }
3735 #endif
3736
3737 #ifndef DISABLE_OCCVIEWER
3738   if ( sec == QString( "OCCViewer" ) && param == QString( "projection_mode" ) )
3739   {
3740     int mode = resMgr->integerValue( "OCCViewer", "projection_mode", 0 );
3741     QList<SUIT_ViewManager*> lst;
3742     viewManagers( OCCViewer_Viewer::Type(), lst );
3743     QListIterator<SUIT_ViewManager*> it( lst );
3744     while ( it.hasNext() )
3745     {
3746       SUIT_ViewModel* vm = it.next()->getViewModel();
3747       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
3748         continue;
3749
3750       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
3751       occVM->setProjectionType( mode );
3752     }
3753   }
3754 #endif
3755
3756
3757 #ifndef DISABLE_OCCVIEWER
3758   if (sec == QString("OCCViewer") && param == QString("adv_selection_mode"))
3759   {
3760     int mode = resMgr->integerValue("OCCViewer", "adv_selection_mode", 0);
3761     QList<SUIT_ViewManager*> lst;
3762     viewManagers(OCCViewer_Viewer::Type(), lst);
3763     QListIterator<SUIT_ViewManager*> it(lst);
3764     while (it.hasNext())
3765     {
3766       SUIT_ViewModel* vm = it.next()->getViewModel();
3767       if (!vm || !vm->inherits("OCCViewer_Viewer"))
3768         continue;
3769
3770       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
3771       occVM->setSelectionStyle((OCCViewer_ViewWindow::SelectionStyle)mode);
3772     }
3773   }
3774 #endif
3775
3776
3777 #ifndef DISABLE_OCCVIEWER
3778   if ( sec == QString( "OCCViewer" ) && param == QString( "stereo_type" ) )
3779   {
3780     int mode = resMgr->integerValue( "OCCViewer", "stereo_type", 0 );
3781     QList<SUIT_ViewManager*> lst;
3782     viewManagers( OCCViewer_Viewer::Type(), lst );
3783     QListIterator<SUIT_ViewManager*> it( lst );
3784     while ( it.hasNext() )
3785     {
3786       SUIT_ViewModel* vm = it.next()->getViewModel();
3787       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
3788         continue;
3789
3790       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
3791       occVM->setStereoType( mode );
3792     }
3793   }
3794 #endif
3795
3796 #ifndef DISABLE_OCCVIEWER
3797   if ( sec == QString( "OCCViewer" ) && param == QString( "anaglyph_filter" ) )
3798   {
3799     int mode = resMgr->integerValue( "OCCViewer", "anaglyph_filter", 0 );
3800     QList<SUIT_ViewManager*> lst;
3801     viewManagers( OCCViewer_Viewer::Type(), lst );
3802     QListIterator<SUIT_ViewManager*> it( lst );
3803     while ( it.hasNext() )
3804     {
3805       SUIT_ViewModel* vm = it.next()->getViewModel();
3806       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
3807         continue;
3808
3809       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
3810       occVM->setAnaglyphFilter( mode );
3811     }
3812   }
3813 #endif
3814
3815 #ifndef DISABLE_OCCVIEWER
3816   if ( sec == QString( "OCCViewer" ) && ( param == QString( "focus_type" ) ||
3817                                           param == QString( "focus_value" ) ) )
3818   {
3819     int aType = resMgr->integerValue( "OCCViewer", "focus_type" );
3820     double aValue = resMgr->doubleValue( "OCCViewer", "focus_value" );
3821     QList<SUIT_ViewManager*> lst;
3822     viewManagers( OCCViewer_Viewer::Type(), lst );
3823     QListIterator<SUIT_ViewManager*> it( lst );
3824     while ( it.hasNext() )
3825     {
3826       SUIT_ViewModel* vm = it.next()->getViewModel();
3827       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
3828         continue;
3829
3830       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
3831       occVM->setStereographicFocus( aType, aValue );
3832     }
3833   }
3834 #endif
3835
3836 #ifndef DISABLE_OCCVIEWER
3837   if ( sec == QString( "OCCViewer" ) && ( param == QString( "iod_type" ) ||
3838                                           param == QString( "iod_value" ) ) )
3839   {
3840     int aType = resMgr->integerValue( "OCCViewer", "iod_type" );
3841     double aValue = resMgr->doubleValue( "OCCViewer", "iod_value" );
3842     QList<SUIT_ViewManager*> lst;
3843     viewManagers( OCCViewer_Viewer::Type(), lst );
3844     QListIterator<SUIT_ViewManager*> it( lst );
3845     while ( it.hasNext() )
3846     {
3847       SUIT_ViewModel* vm = it.next()->getViewModel();
3848       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
3849         continue;
3850
3851       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
3852       occVM->setInterocularDistance( aType, aValue );
3853     }
3854   }
3855 #endif
3856
3857 #ifndef DISABLE_OCCVIEWER
3858   if ( sec == QString( "OCCViewer" ) && param == QString( "reverse_stereo" ) )
3859   {
3860     bool reverse = resMgr->booleanValue( "OCCViewer", "reverse_stereo", false );
3861     QList<SUIT_ViewManager*> lst;
3862     viewManagers( OCCViewer_Viewer::Type(), lst );
3863     QListIterator<SUIT_ViewManager*> it( lst );
3864     while ( it.hasNext() )
3865     {
3866       SUIT_ViewModel* vm = it.next()->getViewModel();
3867       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
3868         continue;
3869
3870       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
3871       occVM->setReverseStereo( reverse );
3872     }
3873   }
3874 #endif
3875
3876 #ifndef DISABLE_OCCVIEWER
3877   if ( sec == QString( "OCCViewer" ) && param == QString( "enable_vsync" ) )
3878   {
3879     bool enable = resMgr->booleanValue( "OCCViewer", "enable_vsync", true );
3880     QList<SUIT_ViewManager*> lst;
3881     viewManagers( OCCViewer_Viewer::Type(), lst );
3882     QListIterator<SUIT_ViewManager*> it( lst );
3883     while ( it.hasNext() )
3884     {
3885       SUIT_ViewModel* vm = it.next()->getViewModel();
3886       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
3887         continue;
3888
3889       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
3890       occVM->setVSync( enable );
3891     }
3892   }
3893 #endif
3894
3895 #ifndef DISABLE_OCCVIEWER
3896   if ( sec == QString( "OCCViewer" ) && param == QString( "enable_quad_buffer_support" ) )
3897   {
3898     bool enable = resMgr->booleanValue( "OCCViewer", "enable_quad_buffer_support", false );
3899     QList<SUIT_ViewManager*> lst;
3900     viewManagers( OCCViewer_Viewer::Type(), lst );
3901     QListIterator<SUIT_ViewManager*> it( lst );
3902     while ( it.hasNext() )
3903     {
3904       SUIT_ViewModel* vm = it.next()->getViewModel();
3905       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
3906         continue;
3907
3908       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
3909       occVM->setQuadBufferSupport( enable );
3910     }
3911   }
3912 #endif
3913
3914 #ifndef DISABLE_OCCVIEWER
3915   if ( sec == QString( "OCCViewer" ) && param.contains( "viewcube" ) )
3916   {
3917     QList<SUIT_ViewManager*> lst;
3918     viewManagers( OCCViewer_Viewer::Type(), lst );
3919     QListIterator<SUIT_ViewManager*> it( lst );
3920     while ( it.hasNext() )
3921     {
3922       SUIT_ViewModel* vm = it.next()->getViewModel();
3923       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
3924         continue;
3925
3926       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
3927       occVM->setViewCubeParamsFromPreferences();
3928     }
3929   }
3930 #endif
3931
3932   if ( sec == QString( "3DViewer" ) && param == QString( "zooming_mode" ) )
3933   {
3934     int mode = resMgr->integerValue( "3DViewer", "zooming_mode", 0 );
3935     QList<SUIT_ViewManager*> lst;
3936 #ifndef DISABLE_OCCVIEWER
3937     viewManagers( OCCViewer_Viewer::Type(), lst );
3938     QListIterator<SUIT_ViewManager*> itOCC( lst );
3939     while ( itOCC.hasNext() )
3940     {
3941       SUIT_ViewModel* vm = itOCC.next()->getViewModel();
3942       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
3943         continue;
3944
3945       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
3946       occVM->setZoomingStyle( mode );
3947     }
3948 #endif
3949 #ifndef DISABLE_VTKVIEWER
3950 #ifndef DISABLE_SALOMEOBJECT
3951     viewManagers( SVTK_Viewer::Type(), lst );
3952     QListIterator<SUIT_ViewManager*> itVTK( lst );
3953     while ( itVTK.hasNext() )
3954     {
3955       SUIT_ViewModel* vm = itVTK.next()->getViewModel();
3956       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
3957         continue;
3958
3959       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
3960       if( vtkVM ) vtkVM->setZoomingStyle( mode );
3961     }
3962 #endif
3963 #endif
3964   }
3965
3966 #ifndef DISABLE_VTKVIEWER
3967   if ( sec == QString( "VTKViewer" ) && (param == QString( "speed_value" ) || param == QString( "speed_mode" )) )
3968   {
3969     int speed = resMgr->integerValue( "VTKViewer", "speed_value", 10 );
3970     int mode = resMgr->integerValue( "VTKViewer", "speed_mode", 0 );
3971     QList<SUIT_ViewManager*> lst;
3972 #ifndef DISABLE_SALOMEOBJECT
3973     viewManagers( SVTK_Viewer::Type(), lst );
3974     QListIterator<SUIT_ViewManager*> it( lst );
3975     while ( it.hasNext() )
3976     {
3977       SUIT_ViewModel* vm = it.next()->getViewModel();
3978       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
3979         continue;
3980
3981       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
3982       if( vtkVM ) vtkVM->setIncrementalSpeed( speed, mode );
3983     }
3984 #endif
3985   }
3986 #endif
3987
3988 #ifndef DISABLE_VTKVIEWER
3989   if ( sec == QString( "VTKViewer" ) && param == QString( "projection_mode" ) )
3990   {
3991     int mode = resMgr->integerValue( "VTKViewer", "projection_mode", 0 );
3992     QList<SUIT_ViewManager*> lst;
3993 #ifndef DISABLE_SALOMEOBJECT
3994     viewManagers( SVTK_Viewer::Type(), lst );
3995     QListIterator<SUIT_ViewManager*> it( lst );
3996     while ( it.hasNext() )
3997     {
3998       SUIT_ViewModel* vm = it.next()->getViewModel();
3999       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
4000         continue;
4001
4002       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
4003       if( vtkVM ) vtkVM->setProjectionMode( mode );
4004     }
4005 #endif
4006   }
4007 #endif
4008
4009 #ifndef DISABLE_VTKVIEWER
4010   if ( sec == QString( "VTKViewer" ) && param == QString( "stereo_type" ) )
4011   {
4012     int mode = resMgr->integerValue( "VTKViewer", "stereo_type", 0 );
4013     QList<SUIT_ViewManager*> lst;
4014 #ifndef DISABLE_SALOMEOBJECT
4015     viewManagers( SVTK_Viewer::Type(), lst );
4016     QListIterator<SUIT_ViewManager*> it( lst );
4017     while ( it.hasNext() )
4018     {
4019       SUIT_ViewModel* vm = it.next()->getViewModel();
4020       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
4021         continue;
4022
4023       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
4024       if( vtkVM ) vtkVM->setStereoType( mode );
4025     }
4026 #endif
4027   }
4028 #endif
4029
4030 #ifndef DISABLE_VTKVIEWER
4031   if ( sec == QString( "VTKViewer" ) && param == QString( "anaglyph_filter" ) )
4032   {
4033     int mode = resMgr->integerValue( "VTKViewer", "anaglyph_filter", 0 );
4034     QList<SUIT_ViewManager*> lst;
4035 #ifndef DISABLE_SALOMEOBJECT
4036     viewManagers( SVTK_Viewer::Type(), lst );
4037     QListIterator<SUIT_ViewManager*> it( lst );
4038     while ( it.hasNext() )
4039     {
4040       SUIT_ViewModel* vm = it.next()->getViewModel();
4041       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
4042         continue;
4043
4044       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
4045       if( vtkVM ) vtkVM->setAnaglyphFilter( mode );
4046     }
4047 #endif
4048   }
4049 #endif
4050
4051 #ifndef DISABLE_VTKVIEWER
4052   if ( sec == QString( "VTKViewer" ) && param == QString( "enable_quad_buffer_support" ) )
4053   {
4054     int enable = resMgr->booleanValue( "VTKViewer", "enable_quad_buffer_support", false );
4055     QList<SUIT_ViewManager*> lst;
4056 #ifndef DISABLE_SALOMEOBJECT
4057     viewManagers( SVTK_Viewer::Type(), lst );
4058     QListIterator<SUIT_ViewManager*> it( lst );
4059     while ( it.hasNext() )
4060     {
4061       SUIT_ViewModel* vm = it.next()->getViewModel();
4062       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
4063         continue;
4064
4065       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
4066       if( vtkVM ) vtkVM->setQuadBufferSupport( enable );
4067     }
4068 #endif
4069   }
4070 #endif
4071
4072 #ifndef DISABLE_VTKVIEWER
4073   if ( sec == QString( "VTKViewer" ) && param == QString( "preselection" ) )
4074   {
4075     int mode = resMgr->integerValue( "VTKViewer", "preselection", 0 );
4076     QList<SUIT_ViewManager*> lst;
4077 #ifndef DISABLE_SALOMEOBJECT
4078     viewManagers( SVTK_Viewer::Type(), lst );
4079     QListIterator<SUIT_ViewManager*> it( lst );
4080     while ( it.hasNext() )
4081     {
4082       SUIT_ViewModel* vm = it.next()->getViewModel();
4083       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
4084         continue;
4085
4086       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
4087       if( vtkVM ) vtkVM->setPreSelectionMode( mode );
4088     }
4089 #endif
4090   }
4091 #endif
4092
4093 #ifndef DISABLE_VTKVIEWER
4094   if ( sec == QString( "VTKViewer" ) && param == QString( "enable_selection" ) )
4095   {
4096     bool isToEnableSelection = resMgr->booleanValue( "VTKViewer", "enable_selection", true );
4097     QList<SUIT_ViewManager*> lst;
4098 #ifndef DISABLE_SALOMEOBJECT
4099     viewManagers( SVTK_Viewer::Type(), lst );
4100     QListIterator<SUIT_ViewManager*> it( lst );
4101     while ( it.hasNext() )
4102     {
4103       SUIT_ViewModel* vm = it.next()->getViewModel();
4104       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
4105         continue;
4106
4107       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
4108       if( vtkVM ) vtkVM->enableSelection( isToEnableSelection );
4109     }
4110 #endif
4111   }
4112 #endif
4113
4114 #ifndef DISABLE_VTKVIEWER
4115   if ( sec == QString( "VTKViewer" ) && (param == QString( "spacemouse_func1_btn" ) ||
4116                                          param == QString( "spacemouse_func2_btn" ) ||
4117                                          param == QString( "spacemouse_func5_btn" ) ) )
4118   {
4119     int btn1 = resMgr->integerValue( "VTKViewer", "spacemouse_func1_btn", 1 );
4120     int btn2 = resMgr->integerValue( "VTKViewer", "spacemouse_func2_btn", 2 );
4121     int btn3 = resMgr->integerValue( "VTKViewer", "spacemouse_func5_btn", 9 );
4122     QList<SUIT_ViewManager*> lst;
4123 #ifndef DISABLE_SALOMEOBJECT
4124     viewManagers( SVTK_Viewer::Type(), lst );
4125     QListIterator<SUIT_ViewManager*> it( lst );
4126     while ( it.hasNext() )
4127     {
4128       SUIT_ViewModel* vm = it.next()->getViewModel();
4129       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
4130         continue;
4131
4132       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
4133       if( vtkVM ) vtkVM->setSpacemouseButtons( btn1, btn2, btn3 );
4134     }
4135 #endif
4136   }
4137 #endif
4138   if( sec=="ObjectBrowser" )
4139   {
4140     SUIT_DataBrowser* ob = objectBrowser();
4141     if ( !ob )
4142       return;
4143
4144     if ( param=="auto_size_first" )
4145     {
4146       bool autoSizeFirst = resMgr->booleanValue( "ObjectBrowser", "auto_size_first", true );
4147       ob->setAutoSizeFirstColumn( autoSizeFirst );
4148       if ( autoSizeFirst )
4149         ob->adjustFirstColumnWidth();
4150     }
4151     else if ( param=="auto_size" ) {
4152       bool autoSize = resMgr->booleanValue( "ObjectBrowser", "auto_size", false );
4153       ob->setAutoSizeColumns(autoSize);
4154       if ( autoSize )
4155         ob->adjustColumnsWidth();
4156     }
4157     else if ( param=="resize_on_expand_item" ) {
4158       bool resizeOnExpandItem = resMgr->booleanValue( "ObjectBrowser", "resize_on_expand_item", false );
4159       ob->setResizeOnExpandItem(resizeOnExpandItem);
4160     }
4161     else if ( param == "auto_hide_search_tool" ) {
4162       ob->searchTool()->enableAutoHide( resMgr->booleanValue( "ObjectBrowser", "auto_hide_search_tool" ) );
4163     }
4164   }
4165
4166   if( sec=="Study" )
4167   {
4168     if( param=="auto_save_interval" ) {
4169       myAutoSaveTimer->stop();
4170       int autoSaveInterval = resMgr->integerValue( "Study", "auto_save_interval", 0 );
4171       if ( activeStudy() && autoSaveInterval > 0 ) myAutoSaveTimer->start( autoSaveInterval*60000 );
4172     }
4173   }
4174
4175 #ifndef DISABLE_PYCONSOLE
4176   if( sec=="PyConsole" && pythonConsole() )
4177   {
4178     if ( param=="font" ) {
4179       pythonConsole()->setFont( resMgr->fontValue( "PyConsole", "font" ) );
4180     }
4181     else if ( param=="show_banner" ) {
4182       pythonConsole()->setIsShowBanner( resMgr->booleanValue( "PyConsole", "show_banner", true ) );
4183     }
4184     else if ( param=="auto_completion" ) {
4185       pythonConsole()->setAutoCompletion( resMgr->booleanValue( "PyConsole", "auto_completion", true ) );
4186     }
4187   }
4188 #endif
4189
4190   if( sec=="MRU" )
4191   {
4192     QtxMRUAction* mru = ::qobject_cast<QtxMRUAction*>( action( MRUId ) );
4193     if ( mru ) {
4194       if ( param == "visible_count" )
4195         mru->setVisibleCount( resMgr->integerValue( "MRU", "visible_count", 5 ) );    // 5 MRU items by default
4196       else if ( param == "max_count" )
4197         mru->setHistoryCount( resMgr->integerValue( "MRU", "max_count", -1 ) );       // unlimited history by default
4198       else if ( param == "insert_mode" )
4199         mru->setInsertMode( resMgr->integerValue( "MRU", "insert_mode", 0 ) );        // QtxMRUAction::MoveFirst by default
4200       else if ( param == "link_type" )
4201         mru->setLinkType( resMgr->integerValue( "MRU", "link_type", 0 ) );            // QtxMRUAction::LinkAuto by default
4202       else if ( param == "show_clear" )
4203         mru->setClearPossible( resMgr->booleanValue( "MRU", "show_clear", false ) );  // do not show "Clear" item by default
4204       else if ( param == "show_mru" )
4205         mru->setVisible( resMgr->booleanValue( "MRU", "show_mru", false ) );          // do not show MRU menu item by default
4206     }
4207   }
4208   if ( sec == "language" && param == "language" )
4209   {
4210     // VSR 18.06.2015 : commented out : single warning dialog box is now shown by the LightApp_PreferencesDlg
4211     //SUIT_MessageBox::information( desktop(), tr( "WRN_WARNING" ), tr( "LANG_CHANGED" ) );
4212   }
4213   if ( sec == "language" && param == "locale")
4214   {
4215     // VSR 18.06.2015: commented out : single warning dialog box is now shown by the LightApp_PreferencesDlg
4216     //SUIT_MessageBox::information( desktop(), tr( "WRN_WARNING" ), tr( "LOCALE_CHANGED" ) );
4217   }
4218   if ( sec == "desktop" && param == "opaque_resize" ) {
4219     bool opaqueResize = resMgr->booleanValue( "desktop", "opaque_resize", false );
4220     // RNV: This code has been commented, because clearing of the QMainWindow::AnimatedDocks option
4221     //      leads to strange behaviour of the dockable windows (at least at qt-5.6.1):
4222     //      any dockable window can't be docked to the another area, except initial area.
4223     //      It is possible to move window to another area, but it always returns to the initial area.
4224     //
4225     //    QMainWindow::DockOptions dopts = desktop()->dockOptions();
4226     //    if ( opaqueResize ) dopts |= QMainWindow::AnimatedDocks;
4227     //     else                dopts &= ~QMainWindow::AnimatedDocks;
4228     //    desktop()->setDockOptions( dopts );
4229     desktop()->setOpaqueResize( opaqueResize );
4230     if ( dynamic_cast<STD_TabDesktop*>( desktop() ) )
4231       dynamic_cast<STD_TabDesktop*>( desktop() )->workstack()->setOpaqueResize( opaqueResize );
4232   }
4233
4234 #ifndef DISABLE_PLOT2DVIEWER
4235   QList<SUIT_ViewManager*> lst;
4236   viewManagers( Plot2d_Viewer::Type(), lst );
4237   QListIterator<SUIT_ViewManager*> itPlot2d( lst );
4238   while ( itPlot2d.hasNext() ) {
4239     SUIT_ViewManager* viewMgr = itPlot2d.next();
4240     SUIT_ViewModel* vm = viewMgr->getViewModel();
4241     if ( !vm || !vm->inherits( "Plot2d_Viewer" ) )
4242       continue;
4243
4244     //Plot2d_Viewer* Plot2dVM = dynamic_cast<Plot2d_Viewer*>( vm );
4245
4246     viewMgr->setViewModel( vm  );
4247     Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( viewMgr->getActiveView() );
4248     if( wnd ) {
4249       Plot2d_ViewFrame* frame = wnd->getViewFrame();
4250       frame->SetPreference();
4251     }
4252   }
4253 #endif
4254 }
4255
4256 /*!
4257   Loads preferences
4258 */
4259 void LightApp_Application::loadPreferences()
4260 {
4261   CAM_Application::loadPreferences();
4262
4263   SUIT_ResourceMgr* aResMgr = resourceMgr();
4264
4265   if ( !aResMgr )
4266     return;
4267
4268   static bool mru_load = true;
4269   if ( mru_load )
4270   {
4271     QtxMRUAction* mru = ::qobject_cast<QtxMRUAction*>( action( MRUId ) );
4272     if ( mru ) {
4273       mru->setVisible( aResMgr->booleanValue( "MRU", "show_mru", false ) );         // do not show MRU menu item by default
4274       mru->setVisibleCount( aResMgr->integerValue( "MRU", "visible_count", 5 ) );   // 5 MRU items by default
4275       mru->setHistoryCount( aResMgr->integerValue( "MRU", "max_count", -1 ) );      // unlimited history by default
4276       mru->setInsertMode( aResMgr->integerValue( "MRU", "insert_mode", 0 ) );       // QtxMRUAction::MoveFirst by default
4277       mru->setLinkType( aResMgr->integerValue( "MRU", "link_type", 0 ) );           // QtxMRUAction::LinkAuto by default
4278       mru->setClearPossible( aResMgr->booleanValue( "MRU", "show_clear", false ) ); // do not show "Clear" item by default
4279       mru->loadLinks( aResMgr, "MRU" );
4280     }
4281     mru_load = false;
4282   }
4283
4284   myWinVis.clear();
4285   QStringList mods = aResMgr->parameters( "windows_visibility" );
4286   for ( QStringList::const_iterator itr = mods.begin(); itr != mods.end(); ++itr )
4287   {
4288     QByteArray arr;
4289     if ( aResMgr->value( "windows_visibility", *itr, arr ) )
4290       myWinVis.insert( *itr, arr );
4291   }
4292
4293   if ( desktop() ) {
4294     desktop()->retrieveGeometry( aResMgr->stringValue( "desktop", "geometry" ) );
4295     bool opaqueResize = aResMgr->booleanValue( "desktop", "opaque_resize", false );
4296     //    QMainWindow::DockOptions dopts = desktop()->dockOptions();
4297     //    if ( opaqueResize ) dopts |= QMainWindow::AnimatedDocks;
4298     //    else                dopts &= ~QMainWindow::AnimatedDocks;
4299     //    desktop()->setDockOptions( dopts );
4300     desktop()->setOpaqueResize( opaqueResize );
4301     if ( dynamic_cast<STD_TabDesktop*>( desktop() ) )
4302       dynamic_cast<STD_TabDesktop*>( desktop() )->workstack()->setOpaqueResize( opaqueResize );
4303   }
4304 }
4305
4306 /*!
4307   Saves preferences
4308 */
4309 void LightApp_Application::savePreferences()
4310 {
4311   CAM_Application::savePreferences();
4312
4313   saveDockWindowsState();
4314
4315   SUIT_ResourceMgr* aResMgr = resourceMgr();
4316
4317   if ( !aResMgr )
4318     return;
4319
4320   QtxMRUAction* mru = ::qobject_cast<QtxMRUAction*>( action( MRUId ) );
4321   if ( mru )
4322     mru->saveLinks( aResMgr, "MRU" );
4323
4324   for ( WinVis::const_iterator itr = myWinVis.begin(); itr != myWinVis.end(); ++itr )
4325     aResMgr->setValue( "windows_visibility", itr.key(), itr.value() );
4326
4327   if ( desktop() )
4328     aResMgr->setValue( "desktop", "geometry", desktop()->storeGeometry() );
4329
4330 #if GUI_DEVELOPMENT > 0
4331   aResMgr->setValue( "salome", "version", QString(GUI_VERSION_STR)+"dev" );
4332 #else
4333   aResMgr->setValue( "salome", "version", QString(GUI_VERSION_STR) );
4334 #endif
4335
4336   aResMgr->save();
4337 }
4338
4339 /*!
4340   Updates desktop title
4341 */
4342 void LightApp_Application::updateDesktopTitle()
4343 {
4344   QString aTitle = applicationName();
4345   QString aVer = applicationVersion();
4346   if ( !aVer.isEmpty() )
4347     aTitle += QString( " " ) + aVer;
4348
4349   if ( activeStudy() ) {
4350     QString sName = SUIT_Tools::file( activeStudy()->studyName().trimmed(), false );
4351     aTitle += QString( " - [%1]" ).arg( sName );
4352   }
4353
4354   desktop()->setWindowTitle( aTitle );
4355 }
4356
4357 /*!
4358   \brief Get map of the operations which can be performed
4359   on the module activation.
4360
4361   The method should return the map of the kind \c {<id>:<name>}
4362   where \c <id> is an integer identifier of the operation and
4363   \c <name> is a title for the button to be added to the
4364   dialog box. After user selects the required operation by the
4365   clicking the corresponding button in the dialog box, its identifier
4366   is passed to the moduleActionSelected() method to process
4367   the made choice.
4368
4369   \return map of the operations
4370   \sa moduleActionSelected()
4371 */
4372 QMap<int, QString> LightApp_Application::activateModuleActions() const
4373 {
4374   QMap<int, QString> opmap;
4375   opmap.insert( NewStudyId,  tr( "ACTIVATE_MODULE_OP_NEW" ) );
4376   opmap.insert( OpenStudyId, tr( "ACTIVATE_MODULE_OP_OPEN" ) );
4377   return opmap;
4378 }
4379
4380 /*!
4381   \brief Called when the used selectes required operation chosen
4382   from "Activate module" dialog box.
4383
4384   Performs the required operation according to the user choice.
4385
4386   \param id operation identifier
4387   \sa activateModuleActions()
4388 */
4389 void LightApp_Application::moduleActionSelected( const int id )
4390 {
4391   switch ( id ) {
4392   case NewStudyId:
4393     onNewDoc();
4394     break;
4395   case OpenStudyId:
4396     onOpenDoc();
4397     break;
4398   default:
4399     break;
4400   }
4401 }
4402
4403 /*!
4404   Updates windows after close document
4405 */
4406 void LightApp_Application::afterCloseDoc()
4407 {
4408   updateWindows();
4409
4410   CAM_Application::afterCloseDoc();
4411 }
4412
4413 /*!
4414   Updates actions of active module
4415 */
4416 void LightApp_Application::updateModuleActions()
4417 {
4418   emit moduleActivated( activeModule() ? activeModule()->moduleName() : QString() );
4419 }
4420
4421 bool LightApp_Application::checkModule( const QString& title )
4422 {
4423   if ( title.isEmpty() )
4424     return false;
4425
4426   QString library = moduleLibrary( title, true );
4427   if ( library.isEmpty() )
4428     return false;
4429
4430   QString name = moduleName( title );
4431
4432   bool isPyModule = library.contains( "SalomePyQtGUI" ) || library.contains( "SalomePyQtGUILight" );
4433
4434   QStringList paths;
4435 #if defined(WIN32)
4436   paths = QString( Qtx::getenv( "PATH" ) ).split( ";", QString::SkipEmptyParts );
4437 #elif defined(__APPLE__)
4438   paths = QString( Qtx::getenv( "DYLD_LIBRARY_PATH" ) ).split( ":", QString::SkipEmptyParts );
4439 #else
4440   paths = QString( Qtx::getenv( "LD_LIBRARY_PATH" ) ).split( ":", QString::SkipEmptyParts );
4441 #endif
4442
4443   bool isFound = false;
4444   QStringList::const_iterator it;
4445   for ( it = paths.begin(); it != paths.end() && !isFound; ++it )
4446   {
4447     isFound = QFileInfo( Qtx::addSlash( *it ) + library ).exists();
4448   }
4449
4450   if ( !isFound )
4451   {
4452     INFOS( std::endl <<
4453            "****************************************************************" << std::endl <<
4454            "     Warning: library " << qPrintable( library ) << " is not found!" << std::endl <<
4455            "     Module " << qPrintable( title ) << " will not be available in GUI mode!" << std::endl <<
4456            "****************************************************************" << std::endl);
4457     return false;
4458   }
4459
4460   if ( isPyModule )
4461   {
4462     QString pyModule = QString( "%1GUI.py" ).arg( name );
4463 #if defined(WIN32)
4464     paths = QString( Qtx::getenv( "PYTHONPATH" ) ).split( ";", QString::SkipEmptyParts );
4465 #else
4466     paths = QString( Qtx::getenv( "PYTHONPATH" ) ).split( ":", QString::SkipEmptyParts );
4467 #endif
4468     isFound = false;
4469     for ( it = paths.begin(); it != paths.end() && !isFound; ++it )
4470     {
4471       isFound = QFileInfo( Qtx::addSlash( *it ) + pyModule ).exists();
4472     }
4473
4474     if ( !isFound )
4475     {
4476       INFOS( std::endl <<
4477              "****************************************************************" << std::endl <<
4478              "     Warning: Python module " << qPrintable( pyModule ) << " is not found!" << std::endl <<
4479              "     Module " << qPrintable( title ) << " will not be available in GUI mode!" << std::endl <<
4480              "****************************************************************" << std::endl);
4481       return false;
4482     }
4483   }
4484
4485   return true;
4486 }
4487
4488 /*!
4489   Gets current windows.
4490   \param winMap - output current windows map.
4491 */
4492 void LightApp_Application::currentWindows( QMap<int, int>& winMap ) const
4493 {
4494   winMap.clear();
4495   if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) )
4496     ((LightApp_Module*)activeModule())->windows( winMap );
4497   else
4498     defaultWindows( winMap );
4499 }
4500
4501 /*!
4502   Gets current view managers.
4503   \param lst - output current view managers list.
4504 */
4505 void LightApp_Application::currentViewManagers( QStringList& lst ) const
4506 {
4507   lst.clear();
4508   if ( !activeStudy() )
4509     return;
4510
4511   if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) )
4512     ((LightApp_Module*)activeModule())->viewManagers( lst );
4513   else
4514     defaultViewManagers( lst );
4515 }
4516
4517 /*!
4518   Updates windows
4519 */
4520 void LightApp_Application::updateWindows()
4521 {
4522   QMap<int, int> winMap;
4523   currentWindows( winMap );
4524
4525   for ( QMap<int, int>::ConstIterator it = winMap.begin(); it != winMap.end(); ++it )
4526   {
4527     if ( !dockWindow( it.key() ) )
4528       getWindow( it.key() );
4529   }
4530
4531   for ( WinMap::ConstIterator it = myWin.begin(); it != myWin.end(); ++it )
4532   {
4533     QWidget* wid = it.value();
4534     if ( !wid )
4535       continue;
4536     if ( winMap.contains( it.key() ) )
4537       wid->setVisible( true );
4538     else if ( !activeStudy() )
4539       delete wid;
4540     else
4541       wid->setVisible( false );
4542   }
4543
4544   loadDockWindowsState();
4545
4546   if ( !activeModule() && infoPanel() )
4547   {
4548     infoPanel()->clear();
4549     infoPanel()->setTitle( tr( "INFO_WELCOME_TO_SALOME" ) );
4550
4551     int grp = infoPanel()->addGroup( tr( "INFO_GETTING_STARTED" ) );
4552     infoPanel()->addAction( action( FileNewId ), grp );
4553     infoPanel()->addLabel( action( FileNewId )->statusTip(), grp );
4554     infoPanel()->addAction( action( FileOpenId ), grp );
4555     infoPanel()->addLabel( action( FileOpenId )->statusTip(), grp );
4556     if ( HAS_TUTORIAL_URL ) {
4557       infoPanel()->addAction( action( TutorialsId ), grp );
4558       infoPanel()->addLabel( action( TutorialsId )->statusTip(), grp );
4559     }
4560     infoPanel()->addAction( action( VideosId ), grp );
4561     infoPanel()->addLabel( action( VideosId )->statusTip(), grp );
4562
4563     LightApp_ModuleAction* ma = qobject_cast<LightApp_ModuleAction*>(action(ModulesListId));
4564     if ( ma && ma->count() > 0 )
4565     {
4566       grp = infoPanel()->addGroup( tr( "INFO_AVAILABLE_MODULES" ) );
4567       foreach ( QString mname, ma->modules() )
4568       {
4569         infoPanel()->addAction( ma->moduleAction( mname ), grp );
4570         if ( !moduleDescription( mname ).isEmpty() )
4571           infoPanel()->addLabel( moduleDescription( mname ), grp );
4572       }
4573     }
4574   }
4575 }
4576
4577 /*!
4578   Updates view managers
4579 */
4580 void LightApp_Application::updateViewManagers()
4581 {
4582   QStringList lst;
4583   currentViewManagers( lst );
4584
4585   for ( QStringList::const_iterator it = lst.begin(); it != lst.end(); ++it )
4586     getViewManager( *it, true );
4587 }
4588
4589 /*!
4590   Loads windows geometry
4591 */
4592 void LightApp_Application::loadDockWindowsState()
4593 {
4594   if ( !desktop() )
4595     return;
4596   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
4597   bool storeWin = aResMgr->booleanValue( "Study", "store_positions", true );
4598   bool storeTb = aResMgr->booleanValue( "Study", "store_tool_positions", true );
4599
4600   QString modName;
4601   if ( activeModule() )
4602     modName = activeModule()->name();
4603   else if ( activeStudy() )
4604     modName = "nomodule";
4605
4606   QtxResourceMgr::WorkingMode prevMode = aResMgr->setWorkingMode( QtxResourceMgr::IgnoreUserValues );
4607   QByteArray aDefaultState;
4608   aResMgr->value( "windows_geometry", modName, aDefaultState );
4609   QByteArray aDefaultVisibility;
4610   aResMgr->value( "windows_visibility", modName, aDefaultVisibility );
4611   bool hasDefaultVisibility = !aDefaultVisibility.isEmpty();
4612   aResMgr->setWorkingMode( prevMode );
4613
4614   if( !storeWin && !storeTb && aDefaultState.isEmpty() && !hasDefaultVisibility)
4615     return;
4616
4617   if ( aResMgr->hasValue("windows_geometry" ,modName ) ) {
4618     long version = Qtx::versionToId( aResMgr->stringValue( "windows_geometry_version", modName, "" ) );
4619     QByteArray arr;
4620     if ( version > Qtx::versionToId( "7.4.1" ) )
4621       aResMgr->value( "windows_geometry", modName , arr );
4622     else
4623       arr = aDefaultState;
4624     QByteArray aTargetArray = processState(arr, storeWin, storeTb, true, aDefaultState);
4625     desktop()->restoreState( aTargetArray );
4626   }
4627
4628   QStringList mainToolbarsNames;
4629   mainToolbarsNames << "SalomeStandard" << "SalomeModules";
4630   QList<QToolBar*> mainToolbars = findToolBars( mainToolbarsNames );
4631   foreach( QToolBar* tb, mainToolbars ) tb->setVisible( true );
4632   /*
4633   if ( !myWinVis.contains( modName ) && aDefaultVisibility.isEmpty())
4634     return;
4635
4636   QMap<QString, bool> *tbMap = 0;
4637   QMap<QString, bool> *dwMap = 0;
4638
4639   QMap<QString, bool> userTbMap, userDwMap;
4640   dockWindowsState( myWinVis[modName], userTbMap, userDwMap );
4641
4642   QMap<QString, bool> defaultTbMap, defaultDwMap;
4643   if(hasDefaultVisibility) {
4644     dockWindowsState( aDefaultVisibility, defaultTbMap, defaultDwMap);
4645   }
4646
4647   if(storeTb) {
4648     tbMap =  &userTbMap;
4649   } else {
4650     if(hasDefaultVisibility){
4651       tbMap =  &defaultTbMap;
4652     }
4653   }
4654
4655   if(storeWin) {
4656     dwMap =  &userDwMap;
4657   } else {
4658     if(hasDefaultVisibility){
4659       dwMap =  &defaultDwMap;
4660     }
4661   }
4662
4663   if(tbMap) {
4664     QList<QToolBar*> tbList = findToolBars();
4665     for ( QList<QToolBar*>::iterator tit = tbList.begin(); tit != tbList.end(); ++tit )
4666       {
4667         QToolBar* tb = *tit;
4668         if ( tbMap->contains( tb->objectName() ) ) {
4669           tb->setVisible( (*tbMap)[tb->objectName()] );
4670         }
4671       }
4672   }
4673
4674   if(dwMap) {
4675     QList<QDockWidget*> dwList = desktop()->findChildren<QDockWidget*>();
4676     for ( QList<QDockWidget*>::iterator dit = dwList.begin(); dit != dwList.end(); ++dit )
4677       {
4678         QDockWidget* dw = *dit;
4679
4680         QObject* po = Qtx::findParent( dw, "QMainWindow" );
4681         if ( po != desktop() )
4682           continue;
4683
4684         if ( dwMap->contains( dw->objectName() ) )
4685           dw->setVisible( (*dwMap)[dw->objectName()] );
4686       }
4687   }
4688   */
4689 }
4690
4691
4692 /*!
4693   Saves windows geometry
4694 */
4695 void LightApp_Application::saveDockWindowsState()
4696 {
4697   if ( !desktop() )
4698     return;
4699
4700   bool storeWin = resourceMgr()->booleanValue( "Study", "store_positions", true );
4701   bool storeTb = resourceMgr()->booleanValue( "Study", "store_tool_positions", true );
4702
4703   if( !storeWin && !storeTb )
4704     return;
4705
4706   QString modName;
4707   if ( activeModule() )
4708     modName = activeModule()->name();
4709   else if ( activeStudy() )
4710     modName = "nomodule";
4711
4712   QString versionId = GUI_VERSION_STR;
4713 #if GUI_DEVELOPMENT > 0
4714   versionId += "dev";
4715 #endif
4716
4717   QByteArray arr = desktop()->saveState();
4718   resourceMgr()->setValue( "windows_geometry", modName, processState(arr, storeWin, storeTb, false) );
4719   resourceMgr()->setValue( "windows_geometry_version", modName, versionId );
4720
4721   QByteArray visArr;
4722   if ( myWinVis.contains( modName ) )
4723     visArr = myWinVis[modName];
4724
4725   QMap<QString, bool> tbMap, dwMap;
4726   dockWindowsState( visArr, tbMap, dwMap );
4727
4728   QList<QToolBar*> tbList = desktop()->findChildren<QToolBar*>();
4729   for ( QList<QToolBar*>::iterator it = tbList.begin(); it != tbList.end(); ++it )
4730   {
4731     QToolBar* tb = *it;
4732     tbMap.insert( tb->objectName(), tb->toggleViewAction()->isChecked() );
4733   }
4734
4735   QList<QDockWidget*> dwList = desktop()->findChildren<QDockWidget*>();
4736   for ( QList<QDockWidget*>::iterator it = dwList.begin(); it != dwList.end(); ++it )
4737   {
4738     QDockWidget* wid = *it;
4739     dwMap.insert( wid->objectName(), wid->toggleViewAction()->isChecked() );
4740   }
4741
4742   visArr = dockWindowsState( tbMap, dwMap );
4743
4744   myWinVis.insert( modName, visArr );
4745 }
4746
4747 QByteArray LightApp_Application::dockWindowsState( const QMap<QString, bool>& tb, const QMap<QString, bool>& dw ) const
4748 {
4749   QByteArray visArr;
4750   QDataStream stream( &visArr, QIODevice::WriteOnly );
4751
4752   stream << (uchar)ToolBarMarker;
4753   stream << tb.size();
4754   for ( QMap<QString, bool>::const_iterator tit = tb.begin(); tit != tb.end(); ++tit )
4755   {
4756     stream << tit.key();
4757     stream << (uchar)( tit.value() ? 1 : 0 );
4758   }
4759
4760   stream << (uchar)DockWidgetMarker;
4761   stream << dw.size();
4762   for ( QMap<QString, bool>::const_iterator wit = dw.begin(); wit != dw.end(); ++wit )
4763   {
4764     stream << wit.key();
4765     stream << (uchar)( wit.value() ? 1 : 0 );
4766   }
4767
4768   return visArr;
4769 }
4770
4771 void LightApp_Application::dockWindowsState( const QByteArray& arr, QMap<QString, bool>& tb, QMap<QString, bool>& dw ) const
4772 {
4773   tb.clear();
4774   dw.clear();
4775
4776   QByteArray visArr = arr;
4777   QDataStream stream( &visArr, QIODevice::ReadOnly );
4778
4779   uchar marker;
4780   stream >> marker;
4781   if ( marker != ToolBarMarker )
4782     return;
4783
4784   int lines;
4785   stream >> lines;
4786   for ( int i = 0; i < lines; ++i )
4787   {
4788     QString objectName;
4789     stream >> objectName;
4790     uchar shown;
4791     stream >> shown;
4792     tb.insert( objectName, shown );
4793   }
4794
4795   stream >> marker;
4796   if ( marker != DockWidgetMarker )
4797     return;
4798
4799   stream >> lines;
4800   for ( int j = 0; j < lines; ++j )
4801   {
4802     QString objectName;
4803     stream >> objectName;
4804     uchar shown;
4805     stream >> shown;
4806     dw.insert( objectName, shown );
4807   }
4808 }
4809
4810 QPixmap LightApp_Application::moduleIcon( const QString& moduleTitle, const int size ) const
4811 {
4812   QPixmap icon;
4813   if ( resourceMgr() )
4814   {
4815     QPixmap defaultIcon = resourceMgr()->loadPixmap( "LightApp", tr( "APP_MODULE_ICO" ), QPixmap( imageEmptyIcon ) );
4816     QString iconName = resourceMgr()->stringValue( moduleName( moduleTitle ), "icon", QString() );
4817     icon = resourceMgr()->loadPixmap( moduleName( moduleTitle ), iconName, defaultIcon );
4818     if ( size > 0 )
4819       icon = Qtx::scaleIcon( icon, size );
4820   }
4821   return icon;
4822 }
4823
4824 /*!
4825   Inserts items in popup, which necessary for current application
4826 */
4827 void LightApp_Application::contextMenuPopup( const QString& type, QMenu* thePopup, QString& title )
4828 {
4829   //Add "Rename" item
4830   LightApp_SelectionMgr* selMgr = LightApp_Application::selectionMgr();
4831   bool cacheIsOn = selMgr->isSelectionCacheEnabled();
4832   selMgr->setSelectionCacheEnabled( true );
4833
4834   SUIT_DataBrowser* ob = objectBrowser();
4835
4836   CAM_Application::contextMenuPopup( type, thePopup, title );
4837
4838   if ( ob && type == ob->popupClientType() ) {
4839     thePopup->addSeparator();
4840     QAction* a = thePopup->addAction( tr( "MEN_REFRESH" ), this, SLOT( onRefresh() ) );
4841     if ( ob->shortcutKey(SUIT_DataBrowser::UpdateShortcut) )
4842       a->setShortcut( ob->shortcutKey(SUIT_DataBrowser::UpdateShortcut) );
4843   }
4844
4845 #ifndef DISABLE_SALOMEOBJECT
4846   if ( selMgr && ob ) {
4847     SALOME_ListIO selected;
4848     selMgr->selectedObjects( selected );
4849     if(selected.Extent() == 1){
4850       Handle(SALOME_InteractiveObject) anIObject = selected.First();
4851       SUIT_DataObject* obj = findObject(anIObject->getEntry());
4852       if(obj && obj->renameAllowed()) {
4853         QAction* a = new QAction(tr("MEN_RENAME_OBJ"), thePopup);
4854         connect( a, SIGNAL( triggered(bool) ), ob, SLOT( onStartEditing() ) );
4855         if ( ob->shortcutKey(SUIT_DataBrowser::RenameShortcut) )
4856           a->setShortcut( ob->shortcutKey(SUIT_DataBrowser::RenameShortcut) );
4857
4858         QList<QAction*> acts = thePopup->actions();
4859         QAction* firstAction = acts.count() > 0 ? acts.first() : 0;
4860         thePopup->insertAction(firstAction,a);
4861       }
4862     }
4863   }
4864 #endif
4865
4866   selMgr->setSelectionCacheEnabled( cacheIsOn );
4867 }
4868
4869 /*!
4870   Create empty study
4871 */
4872 void LightApp_Application::createEmptyStudy()
4873 {
4874   CAM_Application::createEmptyStudy();
4875
4876   if ( objectBrowser() )
4877     objectBrowser()->updateTree();
4878
4879   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
4880   if ( aResMgr && activeStudy() ) {
4881     int autoSaveInterval = aResMgr->integerValue( "Study", "auto_save_interval", 0 );
4882     if ( autoSaveInterval > 0 ) myAutoSaveTimer->start( autoSaveInterval*60000 );
4883   }
4884 }
4885
4886 /*!Set desktop:*/
4887 void LightApp_Application::setDesktop( SUIT_Desktop* desk )
4888 {
4889   CAM_Application::setDesktop( desk );
4890
4891   if ( desk ) {
4892     connect( desk, SIGNAL( message( const QString& ) ),
4893              this, SLOT( onDesktopMessage( const QString& ) ), Qt::UniqueConnection );
4894     connect( desk, SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
4895              this, SLOT( onWindowActivated( SUIT_ViewWindow* ) ), Qt::UniqueConnection );
4896     /* connect( desk, SIGNAL( windowMoved( SUIT_ViewWindow* ) ),
4897              this, SLOT( onWindowMoved( SUIT_ViewWindow* ) ), Qt::UniqueConnection ); */
4898   }
4899 }
4900
4901 /*!
4902   Activates module
4903   \param mod - module to be activated
4904 */
4905 bool LightApp_Application::activateModule( CAM_Module* mod )
4906 {
4907   bool res = CAM_Application::activateModule( mod );
4908
4909   if ( objectBrowser() )
4910     objectBrowser()->updateTree();
4911
4912   return res;
4913 }
4914
4915 /*!
4916   \return keyborad accelerators manager object
4917 */
4918 SUIT_Accel* LightApp_Application::accel() const
4919 {
4920   return myAccel;
4921 }
4922
4923 /*!
4924   Removes dead widget container from map
4925 */
4926 void LightApp_Application::onWCDestroyed( QObject* ob )
4927 {
4928   // remove destroyed widget container from windows map
4929   for ( WinMap::ConstIterator itr = myWin.begin(); itr != myWin.end(); ++itr )
4930   {
4931     if ( itr.value() != ob )
4932       continue;
4933
4934     int key = itr.key();
4935     myWin.remove( key );
4936     break;
4937   }
4938 }
4939
4940 void LightApp_Application::onMRUActivated( const QString& name )
4941 {
4942   SUIT_Session* s = SUIT_Session::session();
4943   if ( s && s->activeApplication() == this )
4944     onOpenDoc( name );
4945 }
4946
4947 void LightApp_Application::onStylePreferences()
4948 {
4949 #ifdef USE_SALOME_STYLE
4950   Style_PrefDlg dlg( desktop() );
4951   dlg.exec();
4952
4953   resourceMgr()->setValue( "Style", "use_salome_style", Style_Salome::isActive() );
4954 #endif // USE_SALOME_STYLE
4955 }
4956
4957 void LightApp_Application::onFullScreen(){
4958   if(myScreenHelper) {
4959     if(desktop()->isFullScreen())
4960       myScreenHelper->switchToNormalScreen();
4961     else
4962       myScreenHelper->switchToFullScreen();
4963   }
4964 }
4965
4966 /*!
4967   Connects just added view manager
4968 */
4969 void LightApp_Application::addViewManager( SUIT_ViewManager* vm )
4970 {
4971   connect( vm, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
4972            this, SLOT( onCloseView( SUIT_ViewManager* ) ) );
4973   CAM_Application::addViewManager( vm );
4974 }
4975
4976 /*!
4977   Remove view manager from memory
4978 */
4979 void LightApp_Application::removeViewManager( SUIT_ViewManager* vm )
4980 {
4981   disconnect( vm, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
4982            this, SLOT( onCloseView( SUIT_ViewManager* ) ) );
4983   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>(activeStudy());
4984   if (aStudy )
4985     aStudy->removeObjectProperties( vm->getGlobalId() );
4986
4987   CAM_Application::removeViewManager( vm );
4988
4989   LightApp_SelectionMgr* selMgr = selectionMgr();
4990   QList<SUIT_Selector*> selectors;
4991   selMgr->selectors( selectors );
4992   foreach( SUIT_Selector* selector, selectors ) {
4993     if ( selector->owner() == vm->getViewModel() ) {
4994       delete selector;
4995     }
4996   }
4997
4998   // IPAL22894: Crash on closing OCC view
4999   //delete vm;
5000   vm->deleteLater();
5001 }
5002
5003 /*!
5004   Renames active window of desktop
5005 */
5006 void LightApp_Application::onRenameWindow()
5007 {
5008   if( !desktop() )
5009     return;
5010
5011   QWidget* w = desktop()->activeWindow();
5012   if( !w )
5013     return;
5014
5015   bool ok;
5016   QString name = QInputDialog::getText( w, tr( "TOT_RENAME" ), tr( "PRP_RENAME" ), QLineEdit::Normal, w->windowTitle(), &ok );
5017   if( ok && !name.isEmpty() )
5018     w->setWindowTitle( name );
5019 }
5020
5021 /*!
5022   Closes active window of desktop
5023 */
5024 void LightApp_Application::onCloseWindow()
5025 {
5026   if( !desktop() )
5027     return;
5028
5029   QWidget* w = desktop()->activeWindow();
5030   if( !w )
5031     return;
5032
5033   w->close();
5034 }
5035
5036 /*!
5037   Closes all windows of desktop
5038 */
5039 void LightApp_Application::onCloseAllWindow()
5040 {
5041   STD_TabDesktop* desk = dynamic_cast<STD_TabDesktop*>( desktop() );
5042   if( !desk )
5043     return;
5044
5045   QList<SUIT_ViewWindow*> wndList = desk->windows();
5046   SUIT_ViewWindow* wnd;
5047   foreach( wnd, wndList )
5048   {
5049     if ( wnd )
5050       wnd->close();
5051   }
5052 }
5053
5054 /*!
5055   Groups all windows of desktop
5056 */
5057 void LightApp_Application::onGroupAllWindow()
5058 {
5059   STD_TabDesktop* desk = dynamic_cast<STD_TabDesktop*>( desktop() );
5060   if( !desk )
5061     return;
5062
5063   QtxWorkstack* wgStack = desk->workstack();
5064   if ( wgStack )
5065     wgStack->stack();
5066 }
5067
5068 /*!
5069   \return default name for an active study
5070 */
5071 void LightApp_Application::setDefaultStudyName( const QString& theName )
5072 {
5073   QStringList anInfoList;
5074   modules( anInfoList, false );
5075
5076   LightApp_Study* aStudy = (LightApp_Study*)activeStudy();
5077   if( anInfoList.count() == 1 && // to avoid a conflict between different modules
5078       !aStudy->isSaved() )
5079   {
5080     aStudy->setStudyName( theName );
5081     updateDesktopTitle();
5082   }
5083 }
5084
5085 /*!
5086   Custom event handler
5087 */
5088 bool LightApp_Application::event( QEvent* e )
5089 {
5090   if( e && e->type()==2000 )
5091   {
5092     SALOME_CustomEvent* ce = ( SALOME_CustomEvent* )e;
5093     QString* d = ( QString* )ce->data();
5094     if( SUIT_MessageBox::question(0, tr("WRN_WARNING"),
5095                                   d ? *d : "",
5096                                   SUIT_MessageBox::Yes | SUIT_MessageBox::No,
5097                                   SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes )
5098     {
5099       QStringList path;
5100       path << tr( "PREF_CATEGORY_SALOME" ) << tr( "PREF_TAB_GENERAL" )
5101            << tr( "PREF_GROUP_EXT_BROWSER" ) << tr( "PREF_APP" );
5102       showPreferences( path );
5103     }
5104     if( d )
5105       delete d;
5106     return true;
5107   }
5108   return CAM_Application::event( e );
5109 }
5110
5111 /*! Check data object */
5112 bool LightApp_Application::checkDataObject(LightApp_DataObject* theObj)
5113 {
5114   if (theObj)
5115     {
5116       bool isSuitable = !theObj->entry().isEmpty() &&
5117                         !theObj->componentDataType().isEmpty() &&
5118                         !theObj->name().isEmpty();
5119       return isSuitable;
5120     }
5121
5122   return false;
5123 }
5124
5125 int LightApp_Application::openChoice( const QString& aName )
5126 {
5127   int choice = CAM_Application::openChoice( aName );
5128
5129   if ( choice == OpenExist ) // The document is already open.
5130   {
5131     // Do you want to reload it?
5132     if ( SUIT_MessageBox::question( desktop(), tr( "WRN_WARNING" ), tr( "QUE_DOC_ALREADYOPEN" ).arg( aName ),
5133                                     SUIT_MessageBox::Yes | SUIT_MessageBox::No, SUIT_MessageBox::No ) == SUIT_MessageBox::Yes )
5134       choice = OpenReload;
5135   }
5136
5137   return choice;
5138 }
5139
5140 bool LightApp_Application::openAction( const int choice, const QString& aName )
5141 {
5142   bool res = false;
5143   switch ( choice )
5144   {
5145   case OpenReload:
5146     {
5147       STD_Application* app = 0;
5148       SUIT_Session* session = SUIT_Session::session();
5149       QList<SUIT_Application*> appList = session->applications();
5150       for ( QList<SUIT_Application*>::iterator it = appList.begin(); it != appList.end() && !app; ++it )
5151       {
5152         if ( (*it)->activeStudy() && (*it)->activeStudy()->studyName() == aName )
5153           app = ::qobject_cast<STD_Application*>( *it );
5154       }
5155
5156       if ( app )
5157       {
5158         app->onCloseDoc( false );
5159         appList = session->applications();
5160         STD_Application* other = 0;
5161         for ( QList<SUIT_Application*>::iterator it = appList.begin(); it != appList.end() && !other; ++it )
5162           other = ::qobject_cast<STD_Application*>( *it );
5163
5164         if ( other )
5165           res = other->onOpenDoc( aName );
5166       }
5167     }
5168     break;
5169   default:
5170     res = CAM_Application::openAction( choice, aName );
5171     break;
5172   }
5173
5174   return res;
5175 }
5176
5177 QStringList LightApp_Application::viewManagersTypes() const
5178 {
5179   QStringList aTypesList;
5180   aTypesList += myUserWmTypes;
5181 #ifndef DISABLE_GLVIEWER
5182   aTypesList<<GLViewer_Viewer::Type();
5183 #endif
5184 #ifndef DISABLE_PLOT2DVIEWER
5185   aTypesList<<Plot2d_Viewer::Type();
5186 #endif
5187 #ifndef DISABLE_QXGRAPHVIEWER
5188   aTypesList<<QxScene_Viewer::Type();
5189 #endif
5190 #ifndef DISABLE_PVVIEWER
5191   aTypesList<<PVViewer_Viewer::Type();
5192 #endif
5193 #ifndef DISABLE_PYVIEWER
5194   aTypesList<<PyViewer_Viewer::Type();
5195 #endif
5196 #ifndef DISABLE_OCCVIEWER
5197   aTypesList<<OCCViewer_Viewer::Type();
5198 #endif
5199 #ifndef DISABLE_VTKVIEWER
5200  #ifndef DISABLE_SALOMEOBJECT
5201   aTypesList<<SVTK_Viewer::Type();
5202  #else
5203   aTypesList<<VTKViewer_Viewer::Type();
5204  #endif
5205 #endif
5206 #ifndef DISABLE_PV3DVIEWER
5207   aTypesList<<PV3DViewer_ViewModel::Type();
5208 #endif
5209   return aTypesList;
5210 }
5211 /*!
5212  * Removes all view managers of known types
5213  * Other view managers are ignored
5214  */
5215 void LightApp_Application::clearKnownViewManagers()
5216 {
5217   QStringList aTypesList = viewManagersTypes();
5218   QList<SUIT_ViewManager*> aMgrList;
5219   viewManagers( aMgrList );
5220   foreach (SUIT_ViewManager* aMgr, aMgrList) {
5221     if (aTypesList.contains(aMgr->getType()))
5222       removeViewManager(aMgr);
5223   }
5224 }
5225
5226 /*!
5227   Copy of current selection
5228  */
5229 void LightApp_Application::onCopy()
5230 {
5231   LightApp_Module* m = dynamic_cast<LightApp_Module*>( activeModule() );
5232   if( m )
5233     m->copy();
5234 }
5235
5236 /*!
5237   Paste of current data in clipboard
5238  */
5239 void LightApp_Application::onPaste()
5240 {
5241   LightApp_Module* m = dynamic_cast<LightApp_Module*>( activeModule() );
5242   if( m )
5243     m->paste();
5244 }
5245
5246 /*!
5247   Browse (i.e. set focus on) the published objects
5248   \param theIsApplyAndClose - flag indicating that the dialog for creating objects
5249                               has been accepted by Ok (or Apply & Close) button
5250   \param theIsOptimizedBrowsing - flag switching to optimized browsing mode
5251                                   (to select the first published object only)
5252   \return entry of the selected object
5253  */
5254 QString LightApp_Application::browseObjects( const QStringList& theEntryList,
5255                                              const bool theIsApplyAndClose,
5256                                              const bool theIsOptimizedBrowsing )
5257 {
5258   QString aResult;
5259   if( SUIT_ResourceMgr* aResourceMgr = resourceMgr() )
5260   {
5261     int aBrowsePolicy = aResourceMgr->integerValue( "ObjectBrowser", "browse_published_object", (int)BP_Never );
5262     switch( aBrowsePolicy )
5263     {
5264       case BP_Never:
5265         return aResult;
5266       case BP_ApplyAndClose:
5267         if( !theIsApplyAndClose )
5268           return aResult;
5269       case BP_Always:
5270       default:
5271         break;
5272     }
5273   }
5274
5275   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( activeStudy() );
5276   if( !aStudy )
5277     return aResult;
5278
5279   SUIT_DataBrowser* anOB = objectBrowser();
5280   if( !anOB )
5281     return aResult;
5282
5283   SUIT_AbstractModel* aModel = dynamic_cast<SUIT_AbstractModel*>( anOB->model() );
5284   if( !aModel )
5285     return aResult;
5286
5287   QStringListIterator anIter( theEntryList );
5288   if( theIsOptimizedBrowsing )
5289   {
5290     // go to the last entry
5291     anIter.toBack();
5292     if( anIter.hasPrevious() )
5293       anIter.previous();
5294   }
5295
5296   // scroll to each entry in the list
5297   // (in optimized mode - to the last entry only)
5298   QString anEntry;
5299   LightApp_DataObject* anObject = 0;
5300   while( anIter.hasNext() )
5301   {
5302     anEntry = anIter.next();
5303     if( !anEntry.isEmpty() )
5304     {
5305       anObject = aStudy->findObjectByEntry( anEntry );
5306       if( anObject )
5307       {
5308         QModelIndex anIndex = aModel->index( anObject );
5309         anOB->treeView()->scrollTo( anIndex );
5310       }
5311     }
5312   }
5313
5314   // always select the last object
5315   if( anObject && !anEntry.isEmpty() )
5316   {
5317     QList<SUIT_Selector*> aSelectorList;
5318     selectionMgr()->selectors( "ObjectBrowser", aSelectorList );
5319     if( !aSelectorList.isEmpty() )
5320     {
5321       if( LightApp_OBSelector* aSelector = dynamic_cast<LightApp_OBSelector*>( aSelectorList.first() ) )
5322       {
5323         bool anIsAutoBlock = aSelector->autoBlock();
5324
5325         // temporarily disable auto block, to emit LightApp_SelectionMgr::currentSelectionChanged() signal
5326         aSelector->setAutoBlock( false );
5327
5328         SUIT_DataOwnerPtrList aList;
5329 #ifndef DISABLE_SALOMEOBJECT
5330         Handle(SALOME_InteractiveObject) aSObj = new SALOME_InteractiveObject
5331           ( anObject->entry().toUtf8().constData(),
5332             anObject->componentDataType().toLatin1().constData(),
5333             anObject->name().toUtf8().constData() );
5334         LightApp_DataOwner* owner = new LightApp_DataOwner( aSObj  );
5335 #else
5336         LightApp_DataOwner* owner = new LightApp_DataOwner( anEntry );
5337 #endif
5338
5339         aList.append( owner );
5340         selectionMgr()->setSelected( aList );
5341         aResult = anEntry;
5342
5343         // restore auto block flag
5344         aSelector->setAutoBlock( anIsAutoBlock );
5345       }
5346     }
5347   }
5348
5349   return aResult;
5350 }
5351
5352 SUIT_DataObject* LightApp_Application::findObject( const QString& id ) const
5353 {
5354   LightApp_Study* study = dynamic_cast<LightApp_Study*>( activeStudy() );
5355   return study ? study->findObjectByEntry( id ) : 0;
5356 }
5357
5358 /*!
5359   Checks that an object can be renamed.
5360   \param entry entry of the object
5361   \brief Return \c true if object can be renamed
5362 */
5363 bool LightApp_Application::renameAllowed( const QString& /*entry*/) const {
5364   return false;
5365 }
5366
5367 /*!
5368   Rename object by entry.
5369   \param entry entry of the object
5370   \param name new name of the object
5371   \brief Return \c true if rename operation finished successfully, \c false otherwise.
5372 */
5373 bool LightApp_Application::renameObject( const QString& /*entry*/, const QString& /*name*/ ) {
5374   return false;
5375 }
5376
5377 /*! Process standard messages from desktop */
5378 void LightApp_Application::onDesktopMessage( const QString& message )
5379 {
5380   const QString sectionSeparator = "/";
5381
5382   if ( message.toLower() == "updateobjectbrowser" ||
5383        message.toLower() == "updateobjbrowser" ) {
5384     // update object browser
5385     updateObjectBrowser();
5386   }
5387   else if ( message.toLower().startsWith( "activate_viewer" ) ) {
5388     QString vtype = message.split( sectionSeparator ).last();
5389     if ( !vtype.isEmpty() )
5390       getViewManager( vtype, true );
5391   }
5392   else if ( message.toLower().startsWith("register_module_in_study" ) ) {
5393     QString moduleName = message.split( sectionSeparator ).last();
5394     // Check name of current activating module name in order to avoid ciclik
5395     // call because of messages
5396     if (!property("activateModule").toBool()) {
5397       CAM_Module* mod = module(moduleName);
5398       if (!mod)
5399         mod = module(moduleTitle(moduleName));
5400       if (!mod) {
5401         mod = loadModule(moduleName);
5402         if (!mod)
5403           mod = loadModule(moduleTitle(moduleName));
5404         if (mod) {
5405           addModule(mod);
5406         }
5407       }
5408       if (mod) {
5409         CAM_Study* anActiveStudy = dynamic_cast<CAM_Study*>(activeStudy());
5410         if (anActiveStudy) {
5411           mod->connectToStudy(anActiveStudy);
5412           LightApp_DataModel* aDM = dynamic_cast<LightApp_DataModel*>(mod->dataModel());
5413           if(aDM) {
5414             aDM->initRootObject();
5415           }
5416         }
5417       }
5418     }
5419   }
5420   else {
5421     QStringList data = message.split( sectionSeparator );
5422     if ( data.count() > 1 ) {
5423       QString msgType = data[0].trimmed();
5424       LightApp_Module* sMod = 0;
5425       CAM_Module* mod = module( msgType );
5426       if ( !mod )
5427         mod = module( moduleTitle( msgType ) );
5428       if ( mod && mod->inherits( "LightApp_Module" ) )
5429         sMod = (LightApp_Module*)mod;
5430
5431       if ( msgType.toLower() == "preferences" ) {
5432         // requested preferences change: should be given as "preferences/<section>/<name>/<value>"
5433         // for example "preferences/Study/multi_file_dump/true"
5434         if ( data.count() > 3 ) {
5435           QString section = data[1].trimmed();
5436           QString param   = data[2].trimmed();
5437           QString value   = QStringList( data.mid(3) ).join( sectionSeparator );
5438           resourceMgr()->setValue( section, param, value );
5439         }
5440       }
5441       else if ( sMod ) {
5442         // received message for the module
5443         QString msg = QStringList( data.mid(1) ).join( sectionSeparator );
5444         sMod->message( msg );
5445       }
5446     }
5447   }
5448 }
5449
5450 void LightApp_Application::onInfoPanelShown()
5451 {
5452   if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) )
5453     ((LightApp_Module*)activeModule())->updateInfoPanel();
5454 }
5455
5456 /*!
5457   Internal method.
5458   Returns all top level toolbars.
5459   Note : Result list contains only main window toolbars, not including toolbars from viewers.
5460 */
5461 QList<QToolBar*> LightApp_Application::findToolBars( const QStringList& names )
5462 {
5463   QList<QToolBar*> aResult;
5464   QList<QToolBar*> tbList = desktop()->findChildren<QToolBar*>();
5465   for ( QList<QToolBar*>::iterator tit = tbList.begin(); tit != tbList.end(); ++tit ) {
5466     QToolBar* tb = *tit;
5467     QObject* po = Qtx::findParent( tb, "QMainWindow" );
5468     if ( po != desktop() )
5469       continue;
5470     if ( names.isEmpty() || names.contains( tb->objectName() ) )
5471       aResult.append(tb);
5472   }
5473   return aResult;
5474 }
5475
5476 /*!
5477   Internal method to parse toolbars and dockable windows state.
5478 */
5479 QByteArray LightApp_Application::processState(QByteArray& input,
5480                                               const bool processWin,
5481                                               const bool processTb,
5482                                               const bool isRestoring,
5483                                               QByteArray defaultState) {
5484
5485   QByteArray aRes;
5486   bool hasDefaultState  = !defaultState.isEmpty();
5487   bool isDockWinWriten = false;
5488   int nbDocWin = -1;
5489   //Write date from users settings
5490   if(isRestoring){
5491     QDataStream tmpInputData(&input, QIODevice::ReadOnly);
5492     int marker, version;
5493     uchar dockmarker;
5494     tmpInputData >> marker;
5495     tmpInputData >> version;
5496     tmpInputData >> dockmarker;
5497     tmpInputData >> nbDocWin;
5498   }
5499   if(processWin && processTb && !isRestoring) {
5500     aRes = input;
5501   } else if(!processWin && !processTb ) {
5502     if(hasDefaultState)
5503       aRes = defaultState;
5504   } else {
5505     QDataStream aData(&aRes, QIODevice::WriteOnly);
5506     QList<QToolBar*> aToolBars = findToolBars();
5507
5508     QStringList aNames;
5509     for ( QList<QToolBar*>::iterator tit = aToolBars.begin(); tit != aToolBars.end(); ++tit ) {
5510       QToolBar* tb = *tit;
5511       aNames.append(tb->objectName());
5512     }
5513
5514     int toolBarMarkerIndex = getToolbarMarkerIndex(input,aNames);
5515     if(toolBarMarkerIndex < 0)
5516       return aRes;
5517     QDataStream anInputData(&input, QIODevice::ReadOnly);
5518
5519     int toolBarMarkerIndexDef = 0;
5520     if(hasDefaultState) {
5521       toolBarMarkerIndexDef = getToolbarMarkerIndex(defaultState, aNames);
5522       if(toolBarMarkerIndexDef < 0)
5523         return aRes;
5524     }
5525     QDataStream anInputDataDef(&defaultState, QIODevice::ReadOnly);
5526
5527     QDataStream* aTargetData = 0;
5528     int          aTargetIndex = -1;
5529
5530     QByteArray currentArr = desktop()->saveState();
5531     QDataStream anInputDataCur(&currentArr, QIODevice::ReadOnly);
5532     bool useInputData = !isRestoring || (isRestoring && nbDocWin > 0);
5533     if(processWin && useInputData) {
5534       aTargetData = &anInputData;
5535       aTargetIndex = toolBarMarkerIndex;
5536     } else {
5537       //Write date from default settings
5538       if(hasDefaultState) {
5539         aTargetData = &anInputDataDef;
5540         aTargetIndex = toolBarMarkerIndexDef;
5541       } else {
5542         //If no default state, write current snapshot of the dockable windows
5543         if(isRestoring) {
5544           aTargetData = &anInputDataCur;
5545           int toolBarMarkerIndexCur = getToolbarMarkerIndex(currentArr, aNames);
5546           aTargetIndex = toolBarMarkerIndexCur;
5547         }
5548       }
5549     }
5550
5551     if(aTargetData && aTargetIndex >= 0 ) {
5552       aTargetData->device()->seek(0);
5553       while( aTargetData->device()->pos() < aTargetIndex ) {
5554         uchar ch;
5555         *aTargetData >> ch;
5556         aData<<ch;
5557       }
5558       isDockWinWriten = true;
5559     }
5560
5561     aTargetData = 0;
5562     aTargetIndex = -1;
5563
5564     if(processTb) {
5565       aTargetData = &anInputData;
5566       aTargetIndex = toolBarMarkerIndex;
5567     } else {
5568       if(hasDefaultState) {
5569         aTargetData = &anInputDataDef;
5570         aTargetIndex = toolBarMarkerIndexDef;
5571       }
5572     }
5573
5574     if(aTargetData && aTargetIndex >= 0) {
5575       int index;
5576       if(!isDockWinWriten ) {
5577         //Write version marker
5578         int marker, version;
5579         aTargetData->device()->seek(0);
5580         *aTargetData >> marker;
5581         *aTargetData >> version;
5582         aData << marker;
5583         aData << version;
5584         aData << (uchar) QDockWidgetMarker;
5585         aData << (int) 0;
5586         int shift = 4*sizeof(int) + sizeof(QSize);
5587         index = aTargetIndex - shift;
5588       } else {
5589         index = aTargetIndex;
5590       }
5591
5592       aTargetData->device()->seek(index);
5593       while(!aTargetData->atEnd()) {
5594         uchar ch;
5595         *aTargetData >> ch;
5596         aData << ch;
5597       }
5598     } else { // Not treat toolbars
5599       aData << (uchar) QToolBarMarker;
5600       aData << (int) 0; //Nb toolbars = 0
5601     }
5602   }
5603   return aRes;
5604 }
5605
5606 /*!
5607   \brief Emits operationFinished signal.
5608   \param theModuleName the name of the module which perfomed the operation
5609   \param theOperationName the operation name
5610   \param theEntryList the list of the created objects entries
5611 */
5612 void LightApp_Application::emitOperationFinished( const QString& theModuleName,
5613                                                   const QString& theOperationName,
5614                                                   const QStringList& theEntryList )
5615 {
5616   emit operationFinished( theModuleName, theOperationName, theEntryList );
5617 }
5618
5619 /*!
5620   Update visibility state of given objects
5621 */
5622 void LightApp_Application::updateVisibilityState( DataObjectList& theList,
5623                                                   SUIT_ViewModel* theViewModel )
5624 {
5625   if ( !theViewModel || theList.isEmpty() ) return;
5626
5627   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>(activeStudy());
5628   if ( !aStudy ) return;
5629
5630   SALOME_View* aView = dynamic_cast<SALOME_View*>( theViewModel );
5631
5632   for ( DataObjectList::iterator itr = theList.begin(); itr != theList.end(); ++itr ) {
5633     LightApp_DataObject* obj = dynamic_cast<LightApp_DataObject*>(*itr);
5634
5635     if ( !obj || aStudy->isComponent( obj->entry() ) )
5636       continue;
5637
5638     QString mname = aStudy->componentDataType(obj->entry());
5639     LightApp_Displayer* aDisplayer = LightApp_Displayer::FindDisplayer(mname, false);
5640     if ( aDisplayer ) {
5641       Qtx::VisibilityState anObjState = Qtx::UnpresentableState;
5642       if ( aDisplayer->canBeDisplayed( obj->entry(), theViewModel->getType() ) ) {
5643         if ( aDisplayer->IsDisplayed( obj->entry(), aView ) )
5644           anObjState = Qtx::ShownState;
5645         else
5646           anObjState = Qtx::HiddenState;
5647       }
5648       aStudy->setVisibilityState( obj->entry(), anObjState );
5649     }
5650   }
5651 }
5652
5653 /*!
5654   Update presentations of all displayed objects of theComponent in specified viewers
5655 */
5656 void LightApp_Application::updatePresentations( const QString& theComponent,
5657                                                 const QStringList& theViewManagerTypes )
5658 {
5659   LightApp_Displayer* aDisplayer = LightApp_Displayer::FindDisplayer(theComponent, false);
5660   if ( aDisplayer ) {
5661     LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>(activeStudy());
5662     DataObjectList aComps;
5663     bool isFound = false;
5664     aStudy->root()->children( aComps );
5665     DataObjectList::const_iterator aCompsIt = aComps.begin();
5666     for ( ; aCompsIt != aComps.end() && !isFound; aCompsIt++ ) {
5667       LightApp_DataObject* aComp = dynamic_cast<LightApp_DataObject*>( *aCompsIt );
5668       if ( aComp && aComp->componentDataType() ==  theComponent) {
5669         isFound = true;
5670         DataObjectList anObjs;
5671         aComp->children(anObjs, true);
5672
5673         QList<SUIT_ViewManager*> aViewMgrs;
5674         QStringList::const_iterator itVMTypes = theViewManagerTypes.begin();
5675         for ( ; itVMTypes != theViewManagerTypes.end(); ++itVMTypes )
5676           viewManagers( *itVMTypes, aViewMgrs );
5677
5678         DataObjectList::const_iterator itObjs = anObjs.begin();
5679         for ( ; itObjs != anObjs.end(); itObjs++ ) {
5680           LightApp_DataObject* anObj = dynamic_cast<LightApp_DataObject*>( *itObjs );
5681           QString anEntry = anObj->entry();
5682
5683           QListIterator<SUIT_ViewManager*> itViewMgrs( aViewMgrs );
5684           while ( itViewMgrs.hasNext()) {
5685             SUIT_ViewModel* aVM = itViewMgrs.next()->getViewModel();
5686             if ( aVM ) {
5687               SALOME_View* aView = dynamic_cast<SALOME_View*>(aVM);
5688               if ( aView ) {
5689                 bool isDisp = aDisplayer->IsDisplayed( anEntry, aView );
5690                 aDisplayer->Erase( anEntry, true, false, aView );
5691                 if ( isDisp ) {
5692                   aDisplayer->Display( anEntry, false, aView );
5693                 }
5694               }
5695             }
5696           }
5697         }
5698       }
5699     }
5700   }
5701 }
5702
5703 /*!
5704  * Called when window activated
5705  */
5706 void LightApp_Application::onWindowActivated( SUIT_ViewWindow* theViewWindow )
5707 {
5708   SUIT_DataBrowser* anOB = objectBrowser();
5709   if ( !anOB )
5710     return;
5711   SUIT_DataObject* rootObj = anOB->root();
5712   if ( !rootObj )
5713     return;
5714
5715   DataObjectList listObj = rootObj->children( true );
5716
5717   SUIT_ViewModel* vmod = 0;
5718   if ( SUIT_ViewManager* vman = theViewWindow->getViewManager() )
5719     vmod = vman->getViewModel();
5720   updateVisibilityState( listObj, vmod );
5721 }
5722
5723 /*!
5724   Called then view manager removed
5725 */
5726 void LightApp_Application::onViewManagerRemoved( SUIT_ViewManager* )
5727 {
5728   ViewManagerList lst;
5729   viewManagers( lst );
5730   if ( lst.count() == 1) { // in case if closed last view window
5731     LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( activeStudy() );
5732     if ( aStudy )
5733       aStudy->setVisibilityStateForAll( Qtx::UnpresentableState );
5734   }
5735 }
5736
5737 /*!
5738   Check existing document.
5739 */
5740 bool LightApp_Application::checkExistingDoc( bool closeExistingDoc )
5741 {
5742   bool result = true;
5743   if( activeStudy() ) {
5744     int answer = !activeStudy()->isModified() ? 1 :
5745                  SUIT_MessageBox::question( desktop(),
5746                                             tr( "APPCLOSE_CAPTION" ),
5747                                             tr( "STUDYCLOSE_DESCRIPTION" ),
5748                                             tr( "APPCLOSE_SAVE" ),
5749                                             tr( "APPCLOSE_CLOSE" ),
5750                                             tr( "APPCLOSE_CANCEL" ), 0 );
5751     if(answer == 0) {
5752       if ( activeStudy()->isSaved() ) {
5753         onSaveDoc();
5754                 if (closeExistingDoc) {
5755                         closeDoc(false);
5756                 }
5757       } else if ( onSaveAsDoc() ) {
5758          if (closeExistingDoc) {
5759            if( !closeDoc( false ) ) {
5760              result = false;
5761            }
5762         }
5763       } else {
5764         result = false;
5765       }
5766     }
5767     else if( answer == 1 ) {
5768       if (closeExistingDoc) {
5769         closeDoc( false );
5770       }
5771     } else if( answer == 2 ) {
5772       result = false;
5773     }
5774   }
5775   return result;
5776 }
5777
5778 /*!
5779   Log GUI action
5780 */
5781 void LightApp_Application::logUserEvent(const QString& eventDescription)
5782 {
5783   static QString _gui_log_file_ = "Not initialized";
5784   static QMutex aGUILogMutex;
5785   if (_gui_log_file_ == "Not initialized") {
5786     std::cout << "!!!***aaajfa***!!! _gui_log_file_ initialization" << std::endl;
5787     _gui_log_file_ = "";
5788     QStringList args = QApplication::arguments();
5789     for (int i = 1; i < args.count(); i++) {
5790       QRegExp rxs ("--gui-log-file=(.+)");
5791       if (rxs.indexIn( args[i] ) >= 0 && rxs.capturedTexts().count() > 1) {
5792         QString file = rxs.capturedTexts()[1];
5793         QFileInfo fi ( file );
5794         if (!fi.isDir()) {
5795           if (fi.dir().exists()) {
5796             _gui_log_file_ = fi.absoluteFilePath();
5797             if (fi.exists()) {
5798               QFile file (_gui_log_file_);
5799               file.remove();
5800             }
5801           }
5802         }
5803         break;
5804       }
5805     }
5806   }
5807   if (_gui_log_file_ != "") {
5808     std::cout << "!!!***aaajfa***!!! log User Event: " << eventDescription.toStdString() << std::endl;
5809     QMutexLocker aLocker (&aGUILogMutex);
5810     QFile file (_gui_log_file_);
5811     if (file.open(QFile::Append)) {
5812       QTextStream stream( &file );
5813       stream << eventDescription << endl;
5814       file.close();
5815     }
5816   }
5817 }
5818
5819 #ifndef DISABLE_PYCONSOLE
5820
5821 PyConsole_Interp* LightApp_Application::getPyInterp()
5822 {
5823   static PyConsole_Interp* myInterp = 0;
5824   if ( !myInterp ) {
5825     myInterp = createPyInterp();
5826     myInterp->initialize();
5827   }
5828   return myInterp;
5829 }
5830
5831 PyConsole_Interp* LightApp_Application::createPyInterp()
5832 {
5833   return new PyConsole_Interp();
5834 }
5835
5836 #endif // DISABLE_PYCONSOLE
5837
5838 void LightApp_Application::createHelpItems( const QString& modTitle )
5839 {
5840   if ( modTitle.isEmpty() )
5841     return;
5842
5843   QString userGuide = "User's Guide";
5844   QString devGuide = "Developer's Guide";
5845
5846   int helpMenu = createMenu( tr( "MEN_DESK_HELP" ), -1, -1, 1000 );
5847
5848   createMenu( userGuide, helpMenu, -1, 5 );
5849   createMenu( devGuide, helpMenu, -1, 5 );
5850
5851   IMap <QString, QString> helpData;                                 // list of help files for the module
5852   QString helpSubMenu;                                              // help submenu name (empty if not needed)
5853   QString modName = moduleName( modTitle );                         // module name
5854   if ( modName.isEmpty() ) modName = modTitle;                      // for KERNEL and GUI
5855   QString rootDir = QString( "%1_ROOT_DIR" ).arg( modName );        // module root dir env variable
5856   QString modDir = Qtx::getenv( rootDir.toUtf8().constData() );     // module root dir path
5857   QString docSection;
5858   if ( resourceMgr()->hasValue( modName, "documentation" ) )
5859     docSection = resourceMgr()->stringValue( modName, "documentation" );
5860   else if ( resourceMgr()->hasSection( modName + "_documentation" ) )
5861     docSection = modName + "_documentation";
5862   if ( !docSection.isEmpty() )
5863   {
5864     helpSubMenu = resourceMgr()->stringValue( docSection, "sub_menu", "" );
5865     if ( helpSubMenu.contains( "%1" ) )
5866       helpSubMenu = helpSubMenu.arg( modTitle );
5867     foreach( QString paramName, resourceMgr()->parameters( docSection ) )
5868     {
5869       QString key = paramName.contains( "%1" ) ? paramName.arg( modTitle ) : paramName;
5870       QString helpItem = getHelpItem( docSection, paramName );
5871       if ( !helpItem.isEmpty() )
5872         helpData.insert( key, helpItem );
5873     }
5874   }
5875
5876   if ( helpData.isEmpty() && !modDir.isEmpty() )
5877   {
5878     QStringList idxLst = QStringList() << modDir << "share" << "doc" << "salome" << "gui" << modName << "index.html";
5879     QString indexFile = idxLst.join( QDir::separator() );          // index file
5880     if ( QFile::exists( indexFile ) )
5881       helpData.insert( tr( "%1 module Users's Guide" ).arg( modTitle ), indexFile );
5882   }
5883
5884   IMapConstIterator<QString, QString > fileIt;
5885   for ( fileIt = helpData.begin(); fileIt != helpData.end(); fileIt++ )
5886   {
5887     QString helpItemPath = fileIt.key();
5888     // remove all '//' occurances
5889     while ( helpItemPath.contains( "//" ) )
5890       helpItemPath.replace( "//", "" );
5891     // obtain submenus hierarchy if given
5892     QStringList smenus = helpItemPath.split( "/" );
5893     helpItemPath = smenus.takeLast();
5894     // workaround for User's Guide and Developer's Guide to avoid having single item in module's submenu.
5895     if ( helpItemPath == userGuide || helpItemPath == devGuide )
5896     {
5897       QString menuPath = smenus.join( "/" );
5898       QStringList allKeys = helpData.keys();
5899       QStringList total = allKeys.filter( QRegExp( QString( "^%1" ).arg( menuPath ) ) );
5900       if ( total.count() == 1 && smenus.count() > 0 )
5901         helpItemPath = smenus.takeLast();
5902     }
5903     QPixmap helpIcon = fileIt.value().startsWith( "http", Qt::CaseInsensitive ) ?
5904       resourceMgr()->loadPixmap( "STD", tr( "ICON_WWW" ), false ) :
5905       resourceMgr()->loadPixmap( "STD", tr( "ICON_HELP" ), false );
5906     QAction* a = createAction( -1, helpItemPath, helpIcon, helpItemPath, helpItemPath,
5907                                0, desktop(), false, this, SLOT( onHelpContentsModule() ) );
5908     a->setData( fileIt.value() );
5909     if ( !helpSubMenu.isEmpty() )
5910       smenus.prepend( helpSubMenu );
5911     // create sub-menus hierarchy
5912     int menuId = helpMenu;
5913     foreach ( QString subMenu, smenus )
5914       menuId = createMenu( subMenu, menuId, -1, 5 );
5915     createMenu( a, menuId, -1, ( menuId != helpMenu && ( helpItemPath == userGuide || helpItemPath == devGuide ) ) ? 0 : 5 );
5916     if ( !myHelpItems.contains( modName ) )
5917       myHelpItems[modName] = IdList();
5918     myHelpItems[modName].append( actionId( a ) );
5919   }
5920 }
5921
5922 void LightApp_Application::removeHelpItems( const QString& modTitle )
5923 {
5924   QString modName = moduleName( modTitle );
5925   if ( myHelpItems.contains( modName ) )
5926   {
5927     foreach( int id, myHelpItems[modName] )
5928       setMenuShown( id, false );
5929     myHelpItems.remove( modName );
5930   }
5931 }