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