Salome HOME
Copyright update 2020
[modules/gui.git] / src / LightApp / LightApp_Application.cxx
1 // Copyright (C) 2007-2020  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 ( !wid )
4119       continue;
4120     if ( winMap.contains( it.key() ) )
4121       wid->setVisible( true );
4122     else if ( !activeStudy() )
4123       delete wid;
4124     else
4125       wid->setVisible( false );
4126   }
4127
4128   loadDockWindowsState();
4129 }
4130
4131 /*!
4132   Updates view managers
4133 */
4134 void LightApp_Application::updateViewManagers()
4135 {
4136   QStringList lst;
4137   currentViewManagers( lst );
4138
4139   for ( QStringList::const_iterator it = lst.begin(); it != lst.end(); ++it )
4140     getViewManager( *it, true );
4141 }
4142
4143 /*!
4144   Loads windows geometry
4145 */
4146 void LightApp_Application::loadDockWindowsState()
4147 {
4148   if ( !desktop() )
4149     return;
4150   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
4151   bool storeWin = aResMgr->booleanValue( "Study", "store_positions", true );
4152   bool storeTb = aResMgr->booleanValue( "Study", "store_tool_positions", true );
4153
4154   QString modName;
4155   if ( activeModule() )
4156     modName = activeModule()->name();
4157   else if ( activeStudy() )
4158     modName = "nomodule";
4159
4160   QtxResourceMgr::WorkingMode prevMode = aResMgr->setWorkingMode( QtxResourceMgr::IgnoreUserValues );
4161   QByteArray aDefaultState;
4162   aResMgr->value( "windows_geometry", modName, aDefaultState );
4163   QByteArray aDefaultVisibility;
4164   aResMgr->value( "windows_visibility", modName, aDefaultVisibility );
4165   bool hasDefaultVisibility = !aDefaultVisibility.isEmpty();
4166   aResMgr->setWorkingMode( prevMode );
4167   
4168   if( !storeWin && !storeTb && aDefaultState.isEmpty() && !hasDefaultVisibility)
4169     return;
4170
4171   if ( aResMgr->hasValue("windows_geometry" ,modName ) ) {
4172     long version = Qtx::versionToId( aResMgr->stringValue( "windows_geometry_version", modName, "" ) );
4173     QByteArray arr;
4174     if ( version > Qtx::versionToId( "7.4.1" ) )
4175       aResMgr->value( "windows_geometry", modName , arr );
4176     else
4177       arr = aDefaultState;
4178     QByteArray aTargetArray = processState(arr, storeWin, storeTb, true, aDefaultState);
4179     desktop()->restoreState( aTargetArray );
4180   }
4181
4182   QStringList mainToolbarsNames;
4183   mainToolbarsNames << "SalomeStandard" << "SalomeModules";
4184   QList<QToolBar*> mainToolbars = findToolBars( mainToolbarsNames );
4185   foreach( QToolBar* tb, mainToolbars ) tb->setVisible( true );
4186   /*
4187   if ( !myWinVis.contains( modName ) && aDefaultVisibility.isEmpty())
4188     return;
4189
4190   QMap<QString, bool> *tbMap = 0;
4191   QMap<QString, bool> *dwMap = 0;
4192   
4193   QMap<QString, bool> userTbMap, userDwMap;
4194   dockWindowsState( myWinVis[modName], userTbMap, userDwMap );
4195
4196   QMap<QString, bool> defaultTbMap, defaultDwMap;
4197   if(hasDefaultVisibility) {
4198     dockWindowsState( aDefaultVisibility, defaultTbMap, defaultDwMap);    
4199   }
4200
4201   if(storeTb) {
4202     tbMap =  &userTbMap;
4203   } else {
4204     if(hasDefaultVisibility){
4205       tbMap =  &defaultTbMap;
4206     }
4207   }
4208
4209   if(storeWin) {
4210     dwMap =  &userDwMap;
4211   } else {
4212     if(hasDefaultVisibility){
4213       dwMap =  &defaultDwMap;
4214     }
4215   }
4216
4217   if(tbMap) {
4218     QList<QToolBar*> tbList = findToolBars();
4219     for ( QList<QToolBar*>::iterator tit = tbList.begin(); tit != tbList.end(); ++tit )
4220       { 
4221         QToolBar* tb = *tit;
4222         if ( tbMap->contains( tb->objectName() ) ) {      
4223           tb->setVisible( (*tbMap)[tb->objectName()] );
4224         }
4225       }
4226   }
4227
4228   if(dwMap) {
4229     QList<QDockWidget*> dwList = desktop()->findChildren<QDockWidget*>();
4230     for ( QList<QDockWidget*>::iterator dit = dwList.begin(); dit != dwList.end(); ++dit )
4231       {
4232         QDockWidget* dw = *dit;
4233         
4234         QObject* po = Qtx::findParent( dw, "QMainWindow" );
4235         if ( po != desktop() )
4236           continue;
4237         
4238         if ( dwMap->contains( dw->objectName() ) )
4239           dw->setVisible( (*dwMap)[dw->objectName()] );
4240       }
4241   }
4242   */
4243 }
4244
4245
4246 /*!
4247   Saves windows geometry
4248 */
4249 void LightApp_Application::saveDockWindowsState()
4250 {
4251   if ( !desktop() )
4252     return;
4253
4254   bool storeWin = resourceMgr()->booleanValue( "Study", "store_positions", true );
4255   bool storeTb = resourceMgr()->booleanValue( "Study", "store_tool_positions", true );
4256
4257   if( !storeWin && !storeTb )
4258     return;
4259
4260   QString modName;
4261   if ( activeModule() )
4262     modName = activeModule()->name();
4263   else if ( activeStudy() )
4264     modName = "nomodule";
4265
4266   QString versionId = GUI_VERSION_STR;
4267 #if GUI_DEVELOPMENT > 0
4268   versionId += "dev";
4269 #endif
4270
4271   QByteArray arr = desktop()->saveState();
4272   resourceMgr()->setValue( "windows_geometry", modName, processState(arr, storeWin, storeTb, false) );
4273   resourceMgr()->setValue( "windows_geometry_version", modName, versionId );
4274
4275   QByteArray visArr;
4276   if ( myWinVis.contains( modName ) )
4277     visArr = myWinVis[modName];
4278
4279   QMap<QString, bool> tbMap, dwMap;
4280   dockWindowsState( visArr, tbMap, dwMap );
4281
4282   QList<QToolBar*> tbList = desktop()->findChildren<QToolBar*>();
4283   for ( QList<QToolBar*>::iterator it = tbList.begin(); it != tbList.end(); ++it )
4284   {
4285     QToolBar* tb = *it;
4286     tbMap.insert( tb->objectName(), tb->toggleViewAction()->isChecked() );
4287   }
4288
4289   QList<QDockWidget*> dwList = desktop()->findChildren<QDockWidget*>();
4290   for ( QList<QDockWidget*>::iterator it = dwList.begin(); it != dwList.end(); ++it )
4291   {
4292     QDockWidget* wid = *it;
4293     dwMap.insert( wid->objectName(), wid->toggleViewAction()->isChecked() );
4294   }
4295
4296   visArr = dockWindowsState( tbMap, dwMap );
4297
4298   myWinVis.insert( modName, visArr );
4299 }
4300
4301 QByteArray LightApp_Application::dockWindowsState( const QMap<QString, bool>& tb, const QMap<QString, bool>& dw ) const
4302 {
4303   QByteArray visArr;
4304   QDataStream stream( &visArr, QIODevice::WriteOnly );
4305
4306   stream << (uchar)ToolBarMarker;
4307   stream << tb.size();
4308   for ( QMap<QString, bool>::const_iterator tit = tb.begin(); tit != tb.end(); ++tit )
4309   {
4310     stream << tit.key();
4311     stream << (uchar)( tit.value() ? 1 : 0 );
4312   }
4313
4314   stream << (uchar)DockWidgetMarker;
4315   stream << dw.size();
4316   for ( QMap<QString, bool>::const_iterator wit = dw.begin(); wit != dw.end(); ++wit )
4317   {
4318     stream << wit.key();
4319     stream << (uchar)( wit.value() ? 1 : 0 );
4320   }
4321
4322   return visArr;
4323 }
4324
4325 void LightApp_Application::dockWindowsState( const QByteArray& arr, QMap<QString, bool>& tb, QMap<QString, bool>& dw ) const
4326 {
4327   tb.clear();
4328   dw.clear();
4329
4330   QByteArray visArr = arr;
4331   QDataStream stream( &visArr, QIODevice::ReadOnly );
4332
4333   uchar marker;
4334   stream >> marker;
4335   if ( marker != ToolBarMarker )
4336     return;
4337
4338   int lines;
4339   stream >> lines;
4340   for ( int i = 0; i < lines; ++i )
4341   {
4342     QString objectName;
4343     stream >> objectName;
4344     uchar shown;
4345     stream >> shown;
4346     tb.insert( objectName, shown );
4347   }
4348
4349   stream >> marker;
4350   if ( marker != DockWidgetMarker )
4351     return;
4352
4353   stream >> lines;
4354   for ( int j = 0; j < lines; ++j )
4355   {
4356     QString objectName;
4357     stream >> objectName;
4358     uchar shown;
4359     stream >> shown;
4360     dw.insert( objectName, shown );
4361   }
4362 }
4363
4364 /*!
4365   Adds icon names for modules
4366 */
4367 void LightApp_Application::moduleIconNames( QMap<QString, QString>& iconMap ) const
4368 {
4369   iconMap.clear();
4370
4371   SUIT_ResourceMgr* resMgr = resourceMgr();
4372   if ( !resMgr )
4373     return;
4374
4375   QStringList modList;
4376   modules( modList, false );
4377
4378   for ( QStringList::const_iterator it = modList.begin(); it != modList.end(); ++it )
4379   {
4380     QString modName = *it;
4381     QString modIntr = moduleName( modName );
4382     QString modIcon = resMgr->stringValue( modIntr, "icon", QString() );
4383
4384     if ( modIcon.isEmpty() )
4385       continue;
4386
4387     if ( SUIT_Tools::extension( modIcon ).isEmpty() )
4388       modIcon += QString( ".png" );
4389
4390     iconMap.insert( modName, modIcon );
4391   }
4392 }
4393
4394 /*!
4395   Inserts items in popup, which necessary for current application
4396 */
4397 void LightApp_Application::contextMenuPopup( const QString& type, QMenu* thePopup, QString& title )
4398 {
4399   //Add "Rename" item
4400   LightApp_SelectionMgr* selMgr = LightApp_Application::selectionMgr();
4401   bool cacheIsOn = selMgr->isSelectionCacheEnabled();
4402   selMgr->setSelectionCacheEnabled( true );
4403
4404   SUIT_DataBrowser* ob = objectBrowser();
4405
4406   CAM_Application::contextMenuPopup( type, thePopup, title );
4407
4408   if ( ob && type == ob->popupClientType() ) {
4409     thePopup->addSeparator();
4410     QAction* a = thePopup->addAction( tr( "MEN_REFRESH" ), this, SLOT( onRefresh() ) );
4411     if ( ob->shortcutKey(SUIT_DataBrowser::UpdateShortcut) )
4412       a->setShortcut( ob->shortcutKey(SUIT_DataBrowser::UpdateShortcut) );
4413   }
4414
4415 #ifndef DISABLE_SALOMEOBJECT
4416   if ( selMgr && ob ) {
4417     SALOME_ListIO selected;
4418     selMgr->selectedObjects( selected );
4419     if(selected.Extent() == 1){
4420       Handle(SALOME_InteractiveObject) anIObject = selected.First();
4421       SUIT_DataObject* obj = findObject(anIObject->getEntry());
4422       if(obj && obj->renameAllowed()) {
4423         QAction* a = new QAction(tr("MEN_RENAME_OBJ"), thePopup);
4424         connect( a, SIGNAL( triggered(bool) ), ob, SLOT( onStartEditing() ) );
4425         if ( ob->shortcutKey(SUIT_DataBrowser::RenameShortcut) )
4426           a->setShortcut( ob->shortcutKey(SUIT_DataBrowser::RenameShortcut) );
4427
4428         QList<QAction*> acts = thePopup->actions();
4429         QAction* firstAction = acts.count() > 0 ? acts.first() : 0;
4430         thePopup->insertAction(firstAction,a);
4431       }
4432     }
4433   }
4434 #endif
4435
4436   selMgr->setSelectionCacheEnabled( cacheIsOn );
4437 }
4438
4439 /*!
4440   Create empty study
4441 */
4442 void LightApp_Application::createEmptyStudy()
4443 {
4444   CAM_Application::createEmptyStudy();
4445
4446   if ( objectBrowser() )
4447     objectBrowser()->updateTree();
4448
4449   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
4450   if ( aResMgr && activeStudy() ) {
4451     int autoSaveInterval = aResMgr->integerValue( "Study", "auto_save_interval", 0 );
4452     if ( autoSaveInterval > 0 ) myAutoSaveTimer->start( autoSaveInterval*60000 );
4453   }
4454 }
4455
4456 /*!Set desktop:*/
4457 void LightApp_Application::setDesktop( SUIT_Desktop* desk )
4458 {
4459   CAM_Application::setDesktop( desk );
4460
4461   if ( desk ) {
4462     connect( desk, SIGNAL( message( const QString& ) ),
4463              this, SLOT( onDesktopMessage( const QString& ) ), Qt::UniqueConnection );
4464     connect( desk, SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
4465              this, SLOT( onWindowActivated( SUIT_ViewWindow* ) ), Qt::UniqueConnection );
4466     /* connect( desk, SIGNAL( windowMoved( SUIT_ViewWindow* ) ),
4467              this, SLOT( onWindowMoved( SUIT_ViewWindow* ) ), Qt::UniqueConnection ); */
4468   }
4469 }
4470
4471 /*!
4472   Activates module
4473   \param mod - module to be activated
4474 */
4475 bool LightApp_Application::activateModule( CAM_Module* mod )
4476 {
4477   bool res = CAM_Application::activateModule( mod );
4478
4479   if ( objectBrowser() )
4480     objectBrowser()->updateTree();
4481
4482   return res;
4483 }
4484
4485 /*!
4486   \return keyborad accelerators manager object
4487 */
4488 SUIT_Accel* LightApp_Application::accel() const
4489 {
4490   return myAccel;
4491 }
4492
4493 /*!
4494   Removes dead widget container from map
4495 */
4496 void LightApp_Application::onWCDestroyed( QObject* ob )
4497 {
4498   // remove destroyed widget container from windows map
4499   for ( WinMap::ConstIterator itr = myWin.begin(); itr != myWin.end(); ++itr )
4500   {
4501     if ( itr.value() != ob )
4502       continue;
4503
4504     int key = itr.key();
4505     myWin.remove( key );
4506     break;
4507   }
4508 }
4509
4510 void LightApp_Application::onMRUActivated( const QString& name )
4511 {
4512   SUIT_Session* s = SUIT_Session::session();
4513   if ( s && s->activeApplication() == this )
4514     onOpenDoc( name );
4515 }
4516
4517 void LightApp_Application::onStylePreferences()
4518 {
4519 #ifdef USE_SALOME_STYLE
4520   Style_PrefDlg dlg( desktop() );
4521   dlg.exec();
4522
4523   resourceMgr()->setValue( "Style", "use_salome_style", Style_Salome::isActive() );
4524 #endif // USE_SALOME_STYLE
4525 }
4526
4527 void LightApp_Application::onFullScreen(){
4528   if(myScreenHelper) {
4529     if(desktop()->isFullScreen())
4530       myScreenHelper->switchToNormalScreen();
4531     else
4532       myScreenHelper->switchToFullScreen();
4533   }
4534 }
4535
4536 /*!
4537   Connects just added view manager
4538 */
4539 void LightApp_Application::addViewManager( SUIT_ViewManager* vm )
4540 {
4541   connect( vm, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
4542            this, SLOT( onCloseView( SUIT_ViewManager* ) ) );
4543   CAM_Application::addViewManager( vm );
4544 }
4545
4546 /*!
4547   Remove view manager from memory
4548 */
4549 void LightApp_Application::removeViewManager( SUIT_ViewManager* vm )
4550 {
4551   disconnect( vm, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
4552            this, SLOT( onCloseView( SUIT_ViewManager* ) ) );
4553   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>(activeStudy());
4554   if (aStudy )
4555     aStudy->removeObjectProperties( vm->getGlobalId() );
4556
4557   CAM_Application::removeViewManager( vm );
4558
4559   LightApp_SelectionMgr* selMgr = selectionMgr();
4560   QList<SUIT_Selector*> selectors;
4561   selMgr->selectors( selectors );
4562   foreach( SUIT_Selector* selector, selectors ) {
4563     if ( selector->owner() == vm->getViewModel() ) {
4564       delete selector;
4565     }
4566   }
4567
4568   // IPAL22894: Crash on closing OCC view
4569   //delete vm;
4570   vm->deleteLater();
4571 }
4572
4573 /*!
4574   Renames active window of desktop
4575 */
4576 void LightApp_Application::onRenameWindow()
4577 {
4578   if( !desktop() )
4579     return;
4580
4581   QWidget* w = desktop()->activeWindow();
4582   if( !w )
4583     return;
4584
4585   bool ok;
4586   QString name = QInputDialog::getText( w, tr( "TOT_RENAME" ), tr( "PRP_RENAME" ), QLineEdit::Normal, w->windowTitle(), &ok );
4587   if( ok && !name.isEmpty() )
4588     w->setWindowTitle( name );
4589 }
4590
4591 /*!
4592   Closes active window of desktop
4593 */
4594 void LightApp_Application::onCloseWindow()
4595 {
4596   if( !desktop() )
4597     return;
4598
4599   QWidget* w = desktop()->activeWindow();
4600   if( !w )
4601     return;
4602
4603   w->close();
4604 }
4605
4606 /*!
4607   Closes all windows of desktop
4608 */
4609 void LightApp_Application::onCloseAllWindow()
4610 {
4611   STD_TabDesktop* desk = dynamic_cast<STD_TabDesktop*>( desktop() );
4612   if( !desk )
4613     return;
4614
4615   QList<SUIT_ViewWindow*> wndList = desk->windows();
4616   SUIT_ViewWindow* wnd;
4617   foreach( wnd, wndList )
4618   {
4619     if ( wnd )
4620       wnd->close();
4621   }
4622 }
4623
4624 /*!
4625   Groups all windows of desktop
4626 */
4627 void LightApp_Application::onGroupAllWindow()
4628 {
4629   STD_TabDesktop* desk = dynamic_cast<STD_TabDesktop*>( desktop() );
4630   if( !desk )
4631     return;
4632
4633   QtxWorkstack* wgStack = desk->workstack();
4634   if ( wgStack )
4635     wgStack->stack();
4636 }
4637
4638 /*!
4639   \return default name for an active study
4640 */
4641 void LightApp_Application::setDefaultStudyName( const QString& theName )
4642 {
4643   QStringList anInfoList;
4644   modules( anInfoList, false );
4645
4646   LightApp_Study* aStudy = (LightApp_Study*)activeStudy();
4647   if( anInfoList.count() == 1 && // to avoid a conflict between different modules
4648       !aStudy->isSaved() )
4649   {
4650     aStudy->setStudyName( theName );
4651     updateDesktopTitle();
4652   }
4653 }
4654
4655 /*!
4656   Custom event handler
4657 */
4658 bool LightApp_Application::event( QEvent* e )
4659 {
4660   if( e && e->type()==2000 )
4661   {
4662     SALOME_CustomEvent* ce = ( SALOME_CustomEvent* )e;
4663     QString* d = ( QString* )ce->data();
4664     if( SUIT_MessageBox::question(0, tr("WRN_WARNING"),
4665                                   d ? *d : "",
4666                                   SUIT_MessageBox::Yes | SUIT_MessageBox::No,
4667                                   SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes )
4668     {
4669       QStringList path;
4670       path << tr( "PREF_CATEGORY_SALOME" ) << tr( "PREF_TAB_GENERAL" )
4671            << tr( "PREF_GROUP_EXT_BROWSER" ) << tr( "PREF_APP" );
4672       showPreferences( path );
4673     }
4674     if( d )
4675       delete d;
4676     return true;
4677   }
4678   return CAM_Application::event( e );
4679 }
4680
4681 /*! Check data object */
4682 bool LightApp_Application::checkDataObject(LightApp_DataObject* theObj)
4683 {
4684   if (theObj)
4685     {
4686       bool isSuitable = !theObj->entry().isEmpty() &&
4687                         !theObj->componentDataType().isEmpty() &&
4688                         !theObj->name().isEmpty();
4689       return isSuitable;
4690     }
4691
4692   return false;
4693 }
4694
4695 int LightApp_Application::openChoice( const QString& aName )
4696 {
4697   int choice = CAM_Application::openChoice( aName );
4698
4699   if ( choice == OpenExist ) // The document is already open.
4700   {
4701     // Do you want to reload it?
4702     if ( SUIT_MessageBox::question( desktop(), tr( "WRN_WARNING" ), tr( "QUE_DOC_ALREADYOPEN" ).arg( aName ),
4703                                     SUIT_MessageBox::Yes | SUIT_MessageBox::No, SUIT_MessageBox::No ) == SUIT_MessageBox::Yes )
4704       choice = OpenReload;
4705   }
4706
4707   return choice;
4708 }
4709
4710 bool LightApp_Application::openAction( const int choice, const QString& aName )
4711 {
4712   bool res = false;
4713   switch ( choice )
4714   {
4715   case OpenReload:
4716     {
4717       STD_Application* app = 0;
4718       SUIT_Session* session = SUIT_Session::session();
4719       QList<SUIT_Application*> appList = session->applications();
4720       for ( QList<SUIT_Application*>::iterator it = appList.begin(); it != appList.end() && !app; ++it )
4721       {
4722         if ( (*it)->activeStudy() && (*it)->activeStudy()->studyName() == aName )
4723           app = ::qobject_cast<STD_Application*>( *it );
4724       }
4725
4726       if ( app )
4727       {
4728         app->onCloseDoc( false );
4729         appList = session->applications();
4730         STD_Application* other = 0;
4731         for ( QList<SUIT_Application*>::iterator it = appList.begin(); it != appList.end() && !other; ++it )
4732           other = ::qobject_cast<STD_Application*>( *it );
4733
4734         if ( other )
4735           res = other->onOpenDoc( aName );
4736       }
4737     }
4738     break;
4739   default:
4740     res = CAM_Application::openAction( choice, aName );
4741     break;
4742   }
4743
4744   return res;
4745 }
4746
4747 QStringList LightApp_Application::viewManagersTypes() const
4748 {
4749   QStringList aTypesList;
4750   aTypesList += myUserWmTypes;
4751 #ifndef DISABLE_GLVIEWER
4752   aTypesList<<GLViewer_Viewer::Type();
4753 #endif
4754 #ifndef DISABLE_PLOT2DVIEWER
4755   aTypesList<<Plot2d_Viewer::Type();
4756 #endif
4757 #ifndef DISABLE_QXGRAPHVIEWER
4758   aTypesList<<QxScene_Viewer::Type();
4759 #endif
4760 #ifndef DISABLE_PVVIEWER
4761   aTypesList<<PVViewer_Viewer::Type();
4762 #endif
4763 #ifndef DISABLE_PYVIEWER
4764   aTypesList<<PyViewer_Viewer::Type();
4765 #endif
4766 #ifndef DISABLE_OCCVIEWER
4767   aTypesList<<OCCViewer_Viewer::Type();
4768 #endif
4769 #ifndef DISABLE_VTKVIEWER
4770  #ifndef DISABLE_SALOMEOBJECT
4771   aTypesList<<SVTK_Viewer::Type();
4772  #else
4773   aTypesList<<VTKViewer_Viewer::Type();
4774  #endif
4775 #endif
4776   return aTypesList;
4777 }
4778 /*!
4779  * Removes all view managers of known types
4780  * Other view managers are ignored
4781  */
4782 void LightApp_Application::clearKnownViewManagers()
4783 {
4784   QStringList aTypesList = viewManagersTypes();
4785   QList<SUIT_ViewManager*> aMgrList;
4786   viewManagers( aMgrList );
4787   foreach (SUIT_ViewManager* aMgr, aMgrList) {
4788     if (aTypesList.contains(aMgr->getType()))
4789       removeViewManager(aMgr);
4790   }
4791 }
4792
4793 /*!
4794   Copy of current selection
4795  */
4796 void LightApp_Application::onCopy()
4797 {
4798   LightApp_Module* m = dynamic_cast<LightApp_Module*>( activeModule() );
4799   if( m )
4800     m->copy();
4801 }
4802
4803 /*!
4804   Paste of current data in clipboard
4805  */
4806 void LightApp_Application::onPaste()
4807 {
4808   LightApp_Module* m = dynamic_cast<LightApp_Module*>( activeModule() );
4809   if( m )
4810     m->paste();
4811 }
4812
4813 /*!
4814   Browse (i.e. set focus on) the published objects
4815   \param theIsApplyAndClose - flag indicating that the dialog for creating objects
4816                               has been accepted by Ok (or Apply & Close) button
4817   \param theIsOptimizedBrowsing - flag switching to optimized browsing mode
4818                                   (to select the first published object only)
4819   \return entry of the selected object
4820  */
4821 QString LightApp_Application::browseObjects( const QStringList& theEntryList,
4822                                              const bool theIsApplyAndClose,
4823                                              const bool theIsOptimizedBrowsing )
4824 {
4825   QString aResult;
4826   if( SUIT_ResourceMgr* aResourceMgr = resourceMgr() )
4827   {
4828     int aBrowsePolicy = aResourceMgr->integerValue( "ObjectBrowser", "browse_published_object", (int)BP_Never );
4829     switch( aBrowsePolicy )
4830     {
4831       case BP_Never:
4832         return aResult;
4833       case BP_ApplyAndClose:
4834         if( !theIsApplyAndClose )
4835           return aResult;
4836       case BP_Always:
4837       default:
4838         break;
4839     }
4840   }
4841
4842   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( activeStudy() );
4843   if( !aStudy )
4844     return aResult;
4845
4846   SUIT_DataBrowser* anOB = objectBrowser();
4847   if( !anOB )
4848     return aResult;
4849
4850   SUIT_AbstractModel* aModel = dynamic_cast<SUIT_AbstractModel*>( anOB->model() );
4851   if( !aModel )
4852     return aResult;
4853
4854   QStringListIterator anIter( theEntryList );
4855   if( theIsOptimizedBrowsing )
4856   {
4857     // go to the last entry
4858     anIter.toBack();
4859     if( anIter.hasPrevious() )
4860       anIter.previous();
4861   }
4862
4863   // scroll to each entry in the list
4864   // (in optimized mode - to the last entry only)
4865   QString anEntry;
4866   LightApp_DataObject* anObject = 0;
4867   while( anIter.hasNext() )
4868   {
4869     anEntry = anIter.next();
4870     if( !anEntry.isEmpty() )
4871     {
4872       anObject = aStudy->findObjectByEntry( anEntry );
4873       if( anObject )
4874       {
4875         QModelIndex anIndex = aModel->index( anObject );
4876         anOB->treeView()->scrollTo( anIndex );
4877       }
4878     }
4879   }
4880
4881   // always select the last object
4882   if( anObject && !anEntry.isEmpty() )
4883   {
4884     QList<SUIT_Selector*> aSelectorList;
4885     selectionMgr()->selectors( "ObjectBrowser", aSelectorList );
4886     if( !aSelectorList.isEmpty() )
4887     {
4888       if( LightApp_OBSelector* aSelector = dynamic_cast<LightApp_OBSelector*>( aSelectorList.first() ) )
4889       {
4890         bool anIsAutoBlock = aSelector->autoBlock();
4891
4892         // temporarily disable auto block, to emit LightApp_SelectionMgr::currentSelectionChanged() signal
4893         aSelector->setAutoBlock( false );
4894
4895         SUIT_DataOwnerPtrList aList;
4896 #ifndef DISABLE_SALOMEOBJECT
4897         Handle(SALOME_InteractiveObject) aSObj = new SALOME_InteractiveObject
4898           ( anObject->entry().toUtf8().constData(),
4899             anObject->componentDataType().toLatin1().constData(),
4900             anObject->name().toUtf8().constData() );
4901         LightApp_DataOwner* owner = new LightApp_DataOwner( aSObj  );
4902 #else
4903         LightApp_DataOwner* owner = new LightApp_DataOwner( anEntry );
4904 #endif
4905
4906         aList.append( owner );
4907         selectionMgr()->setSelected( aList );
4908         aResult = anEntry;
4909
4910         // restore auto block flag
4911         aSelector->setAutoBlock( anIsAutoBlock );
4912       }
4913     }
4914   }
4915
4916   return aResult;
4917 }
4918
4919 SUIT_DataObject* LightApp_Application::findObject( const QString& id ) const
4920 {
4921   LightApp_Study* study = dynamic_cast<LightApp_Study*>( activeStudy() );
4922   return study ? study->findObjectByEntry( id ) : 0;
4923 }
4924
4925 /*!
4926   Checks that an object can be renamed.
4927   \param entry entry of the object
4928   \brief Return \c true if object can be renamed
4929 */
4930 bool LightApp_Application::renameAllowed( const QString& /*entry*/) const {
4931   return false;
4932 }
4933
4934 /*!
4935   Rename object by entry.
4936   \param entry entry of the object
4937   \param name new name of the object
4938   \brief Return \c true if rename operation finished successfully, \c false otherwise.
4939 */
4940 bool LightApp_Application::renameObject( const QString& entry, const QString& ) {
4941   return false;
4942 }
4943
4944 /*! Process standard messages from desktop */
4945 void LightApp_Application::onDesktopMessage( const QString& message )
4946 {
4947   const QString sectionSeparator = "/";
4948
4949   if ( message.toLower() == "updateobjectbrowser" ||
4950        message.toLower() == "updateobjbrowser" ) {
4951     // update object browser
4952     updateObjectBrowser();
4953   }
4954   else if ( message.toLower().startsWith( "activate_viewer" ) ) {
4955     QString vtype = message.split( sectionSeparator ).last();
4956     if ( !vtype.isEmpty() )
4957       getViewManager( vtype, true );
4958   }
4959   else {
4960     QStringList data = message.split( sectionSeparator );
4961     if ( data.count() > 1 ) {
4962       QString msgType = data[0].trimmed();
4963       LightApp_Module* sMod = 0;
4964       CAM_Module* mod = module( msgType );
4965       if ( !mod )
4966         mod = module( moduleTitle( msgType ) );
4967       if ( mod && mod->inherits( "LightApp_Module" ) )
4968         sMod = (LightApp_Module*)mod;
4969
4970       if ( msgType.toLower() == "preferences" ) {
4971         // requested preferences change: should be given as "preferences/<section>/<name>/<value>"
4972         // for example "preferences/Study/multi_file_dump/true"
4973         if ( data.count() > 3 ) {
4974           QString section = data[1].trimmed();
4975           QString param   = data[2].trimmed();
4976           QString value   = QStringList( data.mid(3) ).join( sectionSeparator );
4977           resourceMgr()->setValue( section, param, value );
4978         }
4979       }
4980       else if ( sMod ) {
4981         // received message for the module
4982         QString msg = QStringList( data.mid(1) ).join( sectionSeparator );
4983         sMod->message( msg );
4984       }
4985     }
4986   }
4987 }
4988
4989 /*!
4990   Internal method. 
4991   Returns all top level toolbars.
4992   Note : Result list contains only main window toolbars, not including toolbars from viewers.
4993 */
4994 QList<QToolBar*> LightApp_Application::findToolBars( const QStringList& names )
4995 {
4996   QList<QToolBar*> aResult;
4997   QList<QToolBar*> tbList = desktop()->findChildren<QToolBar*>();
4998   for ( QList<QToolBar*>::iterator tit = tbList.begin(); tit != tbList.end(); ++tit ) {
4999     QToolBar* tb = *tit;
5000     QObject* po = Qtx::findParent( tb, "QMainWindow" );
5001     if ( po != desktop() )
5002       continue;
5003     if ( names.isEmpty() || names.contains( tb->objectName() ) )
5004       aResult.append(tb);
5005   }
5006   return aResult;
5007 }
5008
5009 /*!
5010   Internal method to parse toolbars and dockable windows state.
5011 */
5012 QByteArray LightApp_Application::processState(QByteArray& input,
5013                                               const bool processWin,
5014                                               const bool processTb,
5015                                               const bool isRestoring,
5016                                               QByteArray defaultState) {
5017
5018   QByteArray aRes;
5019   bool hasDefaultState  = !defaultState.isEmpty();
5020   bool isDockWinWriten = false;
5021   int nbDocWin = -1;
5022   //Write date from users settings
5023   if(isRestoring){
5024     QDataStream tmpInputData(&input, QIODevice::ReadOnly);
5025     int marker, version;
5026     uchar dockmarker;
5027     tmpInputData >> marker;
5028     tmpInputData >> version;
5029     tmpInputData >> dockmarker;
5030     tmpInputData >> nbDocWin;
5031   }
5032   if(processWin && processTb && !isRestoring) {
5033     aRes = input;
5034   } else if(!processWin && !processTb ) {
5035     if(hasDefaultState)
5036       aRes = defaultState;
5037   } else {
5038     QDataStream aData(&aRes, QIODevice::WriteOnly);
5039     QList<QToolBar*> aToolBars = findToolBars();
5040
5041     QStringList aNames;
5042     for ( QList<QToolBar*>::iterator tit = aToolBars.begin(); tit != aToolBars.end(); ++tit ) {
5043       QToolBar* tb = *tit;
5044       aNames.append(tb->objectName());
5045     }
5046
5047     int toolBarMarkerIndex = getToolbarMarkerIndex(input,aNames);
5048     if(toolBarMarkerIndex < 0)
5049       return aRes;
5050     QDataStream anInputData(&input, QIODevice::ReadOnly);
5051
5052     int toolBarMarkerIndexDef;
5053     if(hasDefaultState) {
5054       toolBarMarkerIndexDef = getToolbarMarkerIndex(defaultState, aNames);
5055       if(toolBarMarkerIndexDef < 0)
5056         return aRes;
5057     }
5058     QDataStream anInputDataDef(&defaultState, QIODevice::ReadOnly);
5059
5060     QDataStream* aTargetData = 0;
5061     int          aTargetIndex = -1;
5062
5063     QByteArray currentArr = desktop()->saveState();
5064     QDataStream anInputDataCur(&currentArr, QIODevice::ReadOnly);
5065     bool useInputData = !isRestoring || (isRestoring && nbDocWin > 0);
5066     if(processWin && useInputData) {
5067       aTargetData = &anInputData;
5068       aTargetIndex = toolBarMarkerIndex;
5069     } else {
5070       //Write date from default settings
5071       if(hasDefaultState) {
5072         aTargetData = &anInputDataDef;
5073         aTargetIndex = toolBarMarkerIndexDef;
5074       } else {
5075         //If no default state, write current snapshot of the dockable windows
5076         if(isRestoring) {
5077           aTargetData = &anInputDataCur;
5078           int toolBarMarkerIndexCur = getToolbarMarkerIndex(currentArr, aNames);
5079           aTargetIndex = toolBarMarkerIndexCur;
5080         }
5081       }
5082     }
5083
5084     if(aTargetData && aTargetIndex >= 0 ) {
5085       aTargetData->device()->seek(0);
5086       while( aTargetData->device()->pos() < aTargetIndex ) {
5087         uchar ch;
5088         *aTargetData >> ch;
5089         aData<<ch;
5090       }
5091       isDockWinWriten = true;
5092     }
5093
5094     aTargetData = 0;
5095     aTargetIndex = -1;
5096
5097     if(processTb) {
5098       aTargetData = &anInputData;
5099       aTargetIndex = toolBarMarkerIndex;
5100     } else {
5101       if(hasDefaultState) {
5102         aTargetData = &anInputDataDef;
5103         aTargetIndex = toolBarMarkerIndexDef;
5104       }
5105     }
5106
5107     if(aTargetData && aTargetIndex >= 0) {
5108       int index;
5109       if(!isDockWinWriten ) {
5110         //Write version marker
5111         int marker, version;
5112         aTargetData->device()->seek(0);
5113         *aTargetData >> marker;
5114         *aTargetData >> version;
5115         aData << marker;
5116         aData << version;
5117         aData << (uchar) QDockWidgetMarker;
5118         aData << (int) 0;
5119         int shift = 4*sizeof(int) + sizeof(QSize);
5120         index = aTargetIndex - shift;
5121       } else {
5122         index = aTargetIndex;
5123       }
5124
5125       aTargetData->device()->seek(index);
5126       while(!aTargetData->atEnd()) {
5127         uchar ch;
5128         *aTargetData >> ch;
5129         aData << ch;
5130       }
5131     } else { // Not treat toolbars
5132       aData << (uchar) QToolBarMarker;
5133       aData << (int) 0; //Nb toolbars = 0
5134     }
5135   }
5136   return aRes;
5137 }
5138
5139 /*!
5140   \brief Emits operationFinished signal.
5141   \param theModuleName the name of the module which perfomed the operation
5142   \param theOperationName the operation name
5143   \param theEntryList the list of the created objects entries
5144 */
5145 void LightApp_Application::emitOperationFinished( const QString& theModuleName,
5146                                                   const QString& theOperationName,
5147                                                   const QStringList& theEntryList )
5148 {
5149   emit operationFinished( theModuleName, theOperationName, theEntryList );
5150 }
5151
5152 /*!
5153   Update visibility state of given objects
5154 */
5155 void LightApp_Application::updateVisibilityState( DataObjectList& theList,
5156                                                   SUIT_ViewModel*  theViewModel )
5157 {
5158   if ( !theViewModel || theList.isEmpty() ) return;
5159
5160   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>(activeStudy());
5161   if ( !aStudy ) return;
5162
5163   SALOME_View* aView = dynamic_cast<SALOME_View*>( theViewModel );
5164
5165   for ( DataObjectList::iterator itr = theList.begin(); itr != theList.end(); ++itr ) {
5166     LightApp_DataObject* obj = dynamic_cast<LightApp_DataObject*>(*itr);
5167
5168     if ( !obj || aStudy->isComponent( obj->entry() ) )
5169       continue;
5170
5171     LightApp_Module* anObjModule = dynamic_cast<LightApp_Module*>(obj->module());
5172     if ( anObjModule ) {
5173       LightApp_Displayer* aDisplayer = anObjModule->displayer();
5174       if ( aDisplayer ) {
5175         Qtx::VisibilityState anObjState = Qtx::UnpresentableState;
5176         if ( aDisplayer->canBeDisplayed( obj->entry(), theViewModel->getType() ) ) {
5177           if ( aView && aDisplayer->IsDisplayed( obj->entry(), aView ) )
5178             anObjState = Qtx::ShownState;
5179           else
5180             anObjState = Qtx::HiddenState;
5181         }
5182         aStudy->setVisibilityState( obj->entry(), anObjState );
5183       }
5184     }
5185   }
5186 }
5187
5188 /*!
5189  * Called when window activated
5190  */
5191 void LightApp_Application::onWindowActivated( SUIT_ViewWindow* theViewWindow )
5192 {
5193   SUIT_DataBrowser* anOB = objectBrowser();
5194   if ( !anOB )
5195     return;
5196   SUIT_DataObject* rootObj = anOB->root();
5197   if ( !rootObj )
5198     return;
5199
5200   DataObjectList listObj = rootObj->children( true );
5201
5202   SUIT_ViewModel* vmod = 0;
5203   if ( SUIT_ViewManager* vman = theViewWindow->getViewManager() )
5204     vmod = vman->getViewModel();
5205   updateVisibilityState( listObj, vmod );
5206 }
5207
5208 /*!
5209   Called then view manager removed
5210 */
5211 void LightApp_Application::onViewManagerRemoved( SUIT_ViewManager* )
5212 {
5213   ViewManagerList lst;
5214   viewManagers( lst );
5215   if ( lst.count() == 1) { // in case if closed last view window
5216     LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( activeStudy() );
5217     if ( aStudy )
5218       aStudy->setVisibilityStateForAll( Qtx::UnpresentableState );
5219   }
5220 }
5221
5222 /*!
5223   Check existing document.
5224 */
5225 bool LightApp_Application::checkExistingDoc( bool closeExistingDoc )
5226 {
5227   bool result = true;
5228   if( activeStudy() ) {
5229     int answer = !activeStudy()->isModified() ? 1 :
5230                  SUIT_MessageBox::question( desktop(),
5231                                             tr( "APPCLOSE_CAPTION" ),
5232                                             tr( "STUDYCLOSE_DESCRIPTION" ),
5233                                             tr( "APPCLOSE_SAVE" ),
5234                                             tr( "APPCLOSE_CLOSE" ),
5235                                             tr( "APPCLOSE_CANCEL" ), 0 );
5236     if(answer == 0) {
5237       if ( activeStudy()->isSaved() ) {
5238         onSaveDoc();
5239                 if (closeExistingDoc) {
5240                         closeDoc(false);
5241                 }
5242       } else if ( onSaveAsDoc() ) {
5243          if (closeExistingDoc) {
5244            if( !closeDoc( false ) ) {
5245              result = false;
5246            }
5247         }
5248       } else {
5249         result = false;
5250       }
5251     }
5252     else if( answer == 1 ) {
5253       if (closeExistingDoc) {
5254         closeDoc( false );
5255       }
5256     } else if( answer == 2 ) {
5257       result = false;
5258     }
5259   }
5260   return result;
5261 }
5262
5263 #ifndef DISABLE_PYCONSOLE
5264
5265 PyConsole_Interp* LightApp_Application::getPyInterp()
5266 {
5267   static PyConsole_Interp* myInterp = 0;
5268   if ( !myInterp ) {
5269     myInterp = createPyInterp();
5270     myInterp->initialize();
5271   }
5272   return myInterp;
5273 }
5274
5275 PyConsole_Interp* LightApp_Application::createPyInterp()
5276 {
5277   return new PyConsole_Interp();
5278 }
5279
5280 #endif // DISABLE_PYCONSOLE