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