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