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