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