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