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