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