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