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