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