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