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