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