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