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