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