Salome HOME
Merge from branch mpa/qwt6_porting
[modules/gui.git] / src / LightApp / LightApp_Application.cxx
1 // Copyright (C) 2007-2013  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.
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 "LightApp_PyInterp.h" // WARNING! This include must be the first!
39   #include <PyConsole_Console.h>
40 #endif
41
42 #include "LightApp_Application.h"
43 #include "LightApp_Module.h"
44 #include "LightApp_DataModel.h"
45 #include "LightApp_Study.h"
46 #include "LightApp_Preferences.h"
47 #include "LightApp_PreferencesDlg.h"
48 #include "LightApp_ModuleDlg.h"
49 #include "LightApp_AboutDlg.h"
50 #include "LightApp_ModuleAction.h"
51 // temporary commented
52 #include "LightApp_EventFilter.h"
53 #include "LightApp_OBSelector.h"
54 #include "LightApp_SelectionMgr.h"
55 #include "LightApp_DataObject.h"
56 #include "LightApp_WgViewModel.h"
57 #include "LightApp_FullScreenHelper.h"
58
59
60 #include <GUI_version.h>
61 #include <Basics_OCCTVersion.hxx>
62
63 #include <SALOME_Event.h>
64
65 #include <Style_Salome.h>
66 #include <Style_PrefDlg.h>
67
68 #include <CAM_Module.h>
69 #include <CAM_DataModel.h>
70 #include <CAM_Study.h>
71 #include <STD_TabDesktop.h>
72
73 #include <SUIT_DataBrowser.h>
74 #include <SUIT_Session.h>
75 #include <SUIT_Study.h>
76 #include <SUIT_FileDlg.h>
77 #include <SUIT_ResourceMgr.h>
78 #include <SUIT_ShortcutMgr.h>
79 #include <SUIT_Tools.h>
80 #include <SUIT_Accel.h>
81 #include <SUIT_MessageBox.h>
82 #include <SUIT_ViewWindow.h>
83
84 #include <Qtx.h>
85 #include <QtxToolBar.h>
86 #include <QtxTreeView.h>
87 #include <QtxMRUAction.h>
88 #include <QtxDockAction.h>
89 #include <QtxDockWidget.h>
90 #include <QtxActionToolMgr.h>
91 #include <QtxSearchTool.h>
92 #include <QtxWorkstack.h>
93 #include <QtxMap.h>
94 #include <QtxWebBrowser.h>
95
96 #include <LogWindow.h>
97
98 #ifndef DISABLE_GLVIEWER
99   #include <GLViewer_Viewer.h>
100   #include <GLViewer_ViewManager.h>
101   #include "LightApp_GLSelector.h"
102 #endif
103
104 #ifndef DISABLE_PLOT2DVIEWER
105   #include <Plot2d_ViewManager.h>
106   #include <Plot2d_ViewModel.h>
107   #include <Plot2d_ViewWindow.h>
108   #include <Plot2d_ViewFrame.h>
109   #include "LightApp_Plot2dSelector.h"
110 #ifndef DISABLE_SALOMEOBJECT
111   #include <SPlot2d_ViewModel.h>
112 #else
113   #include <Plot2d_ViewModel.h>
114 #endif
115 #endif
116
117 #ifndef DISABLE_OCCVIEWER
118   #include <OCCViewer_ViewManager.h>
119   #include <OCCViewer_ViewFrame.h>
120 #ifndef DISABLE_SALOMEOBJECT
121   #include <SOCC_ViewModel.h>
122 #else
123   #include <OCCViewer_ViewModel.h>
124 #endif
125   #include "LightApp_OCCSelector.h"
126 #endif
127
128 #ifndef DISABLE_VTKVIEWER
129 #ifndef DISABLE_SALOMEOBJECT
130   #include <SVTK_ViewModel.h>
131   #include <SVTK_ViewManager.h>
132   #include "LightApp_VTKSelector.h"
133 #else
134   #include <VTKViewer_ViewModel.h>
135   #include <VTKViewer_ViewManager.h>
136 #endif
137   #include <VTKViewer_ViewModel.h>
138 #endif
139
140 #ifndef DISABLE_QXGRAPHVIEWER
141   #include <QxScene_ViewManager.h>
142   #include <QxScene_ViewModel.h>
143   #include <QxScene_ViewWindow.h>
144 #endif
145
146 #ifndef DISABLE_GRAPHICSVIEW
147   #include "GraphicsView_Viewer.h"
148   #include "GraphicsView_ViewManager.h"
149   #include "LightApp_GVSelector.h"
150 #endif
151
152 #define VISIBILITY_COLUMN_WIDTH 25
153
154 #include <QDir>
155 #include <QImage>
156 #include <QString>
157 #include <QWidget>
158 #include <QStringList>
159 #include <QFile>
160 #include <QApplication>
161 #include <QMap>
162 #include <QStatusBar>
163 #include <QThread>
164 #include <QObjectList>
165 #include <QComboBox>
166 #include <QInputDialog>
167 #include <QFontDatabase>
168 #include <QIcon>
169 #include <QByteArray>
170 #include <QMenu>
171 #include <QProcess>
172 #include <QTimer>
173 #include <QHeaderView>
174 #include <QTreeView>
175 #include <QMimeData>
176 #include <QShortcut>
177
178 #include <utilities.h>
179
180 #define FIRST_HELP_ID 1000000
181
182 #ifndef DISABLE_SALOMEOBJECT
183   #include <SALOME_InteractiveObject.hxx>
184   #include <SALOME_ListIO.hxx>
185 #endif
186
187 #include <Standard_Version.hxx>
188
189 #define ToolBarMarker    0
190 #define DockWidgetMarker 1
191
192 static const char* imageEmptyIcon[] = {
193 "20 20 1 1",
194 ".      c None",
195 "....................",
196 "....................",
197 "....................",
198 "....................",
199 "....................",
200 "....................",
201 "....................",
202 "....................",
203 "....................",
204 "....................",
205 "....................",
206 "....................",
207 "....................",
208 "....................",
209 "....................",
210 "....................",
211 "....................",
212 "....................",
213 "....................",
214 "...................."};
215
216 int LightApp_Application::lastStudyId = 0;
217
218
219 // Markers used to parse array with dockable windows and toolbars state.
220 // For more details please see the qdockarealayout.cpp && qtoolbararealayout.cpp
221 // in the Qt source code.
222
223 #define QDockWidgetMarker 0xfd // = DockWidgetStateMarker
224 #define QToolBarMarker 0xfc    // = ToolBarStateMarkerEx
225
226 // Format of the Byte array with the windows and toolbar state is:
227 // VersionMarker|version|DockWidgetStateMarker|nbDockWidgetLines|...DocWidgetData...|ToolBarStateMarkerEx|nbToolBarLines|...ToolBarData...
228
229 //Find toolbar marker position in the array in the following way:
230 //since the 'toolbar marker' is not unique, find index of first occurrence of the
231 //'toolbar marker' in the array and check that next string is name of the toolbar
232
233 int getToolbarMarkerIndex(QByteArray input, const QStringList& aFlags) {
234   int aResult = -1,tmp = 0;
235   int inputLen = input.length();
236   QDataStream anInputData(&input, QIODevice::ReadOnly);
237   while(tmp < inputLen) {
238       tmp = input.indexOf(QToolBarMarker, tmp + 1);
239       if(tmp < 0 )
240         break;
241       anInputData.device()->seek(tmp);
242       uchar mark;
243       anInputData>>mark;
244       int lines;
245       anInputData >> lines;
246
247       if(lines == 0 && anInputData.atEnd()){
248         //Case then array doesn't contain information about toolbars,
249         aResult = tmp;
250         break;
251       }
252
253       int pos;
254       anInputData >> pos;
255       int cnt;
256       anInputData >> cnt;
257       QString str;
258       anInputData>>str;
259       if(aFlags.contains(str)) {
260         aResult = tmp;
261         break;
262       }
263     }        
264   return aResult;
265 }
266
267 /*!
268   \return last global id of study
269 */
270 int LightApp_Application::studyId()
271 {
272   return LightApp_Application::lastStudyId;
273 }
274
275 /*!Create new instance of LightApp_Application.*/
276 extern "C" LIGHTAPP_EXPORT SUIT_Application* createApplication()
277 {
278   return new LightApp_Application();
279 }
280
281 /*! \var global preferences of LightApp */
282 LightApp_Preferences* LightApp_Application::_prefs_ = 0;
283
284
285 /*!
286   \class LightApp_Application
287   Application containing LightApp module
288 */
289
290 /*!Constructor.*/
291 LightApp_Application::LightApp_Application()
292 : CAM_Application( false ),
293   myPrefs( 0 ),
294   myScreenHelper(new LightApp_FullScreenHelper())
295 {
296   Q_INIT_RESOURCE( LightApp );
297
298   STD_TabDesktop* desk = new STD_TabDesktop();
299   desk->setFullScreenAllowed(false);
300   desk->setMinimizeAllowed(false);
301
302   setDesktop( desk );
303
304   // initialize auto save timer
305   myAutoSaveTimer = new QTimer( this );
306   myAutoSaveTimer->setSingleShot( true );
307   connect( myAutoSaveTimer, SIGNAL( timeout() ), this, SLOT( onSaveDoc() ) );
308
309   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
310   QPixmap aLogo = aResMgr->loadPixmap( "LightApp", tr( "APP_DEFAULT_ICO" ), false );
311
312   QtxWebBrowser::setResourceManager( aResMgr );
313   QtxWebBrowser::setData("browser:icon",          aResMgr->loadPixmap( "LightApp", tr( "BROWSER_ICON" ) ) );
314   QtxWebBrowser::setData("browser:title",         tr( "BROWSER_TITLE" ) );
315   QtxWebBrowser::setData("toolbar:title",         tr( "BROWSER_TOOLBAR_TITLE" ) );
316   QtxWebBrowser::setData("menu:file:title",       tr( "BROWSER_FILEMENU" ) );
317   QtxWebBrowser::setData("action:close:title",    tr( "BROWSER_CLOSE" ) );
318   QtxWebBrowser::setData("action:close:icon",     aResMgr->loadPixmap( "LightApp", tr( "BROWSER_CLOSE_ICON" ) ) );
319   QtxWebBrowser::setData("action:back:title",     tr( "BROWSER_BACK" ) );
320   QtxWebBrowser::setData("action:forward:title",  tr( "BROWSER_FORWARD" ) );
321   QtxWebBrowser::setData("action:find:title",     tr( "BROWSER_FIND" ) );
322   QtxWebBrowser::setData("action:findnext:title", tr( "BROWSER_FINDNEXT" ) );
323   QtxWebBrowser::setData("action:findprev:title", tr( "BROWSER_FINDPREV" ) );
324
325   desktop()->setWindowIcon( aLogo );
326   desktop()->setDockableMenuBar( false );
327   desktop()->setDockableStatusBar( false );
328
329   // base logo (salome itself)
330   desktop()->logoInsert( "_app_base",  aResMgr->loadPixmap( "LightApp", tr( "APP_BASE_LOGO" ), false ) );
331   // extra logo (salome-based application)
332   desktop()->logoInsert( "_app_extra", aResMgr->loadPixmap( "LightApp", tr( "APP_EXTRA_LOGO" ), false ) );
333
334   clearViewManagers();
335
336   mySelMgr = new LightApp_SelectionMgr( this );
337
338   myAccel = SUIT_Accel::getAccel();
339
340 #ifndef DISABLE_OCCVIEWER
341   myAccel->setActionKey( SUIT_Accel::PanLeft,     Qt::CTRL+Qt::Key_Left,     OCCViewer_Viewer::Type() );
342   myAccel->setActionKey( SUIT_Accel::PanRight,    Qt::CTRL+Qt::Key_Right,    OCCViewer_Viewer::Type() );
343   myAccel->setActionKey( SUIT_Accel::PanUp,       Qt::CTRL+Qt::Key_Up,       OCCViewer_Viewer::Type() );
344   myAccel->setActionKey( SUIT_Accel::PanDown,     Qt::CTRL+Qt::Key_Down,     OCCViewer_Viewer::Type() );
345   myAccel->setActionKey( SUIT_Accel::ZoomIn,      Qt::CTRL+Qt::Key_Plus,     OCCViewer_Viewer::Type() );
346   myAccel->setActionKey( SUIT_Accel::ZoomOut,     Qt::CTRL+Qt::Key_Minus,    OCCViewer_Viewer::Type() );
347   myAccel->setActionKey( SUIT_Accel::ZoomFit,     Qt::CTRL+Qt::Key_Asterisk, OCCViewer_Viewer::Type() );
348   myAccel->setActionKey( SUIT_Accel::ZoomFit,     Qt::Key_Space,             OCCViewer_Viewer::Type() );
349   myAccel->setActionKey( SUIT_Accel::RotateLeft,  Qt::ALT+Qt::Key_Left,      OCCViewer_Viewer::Type() );
350   myAccel->setActionKey( SUIT_Accel::RotateRight, Qt::ALT+Qt::Key_Right,     OCCViewer_Viewer::Type() );
351   myAccel->setActionKey( SUIT_Accel::RotateUp,    Qt::ALT+Qt::Key_Up,        OCCViewer_Viewer::Type() );
352   myAccel->setActionKey( SUIT_Accel::RotateDown,  Qt::ALT+Qt::Key_Down,      OCCViewer_Viewer::Type() );
353 #endif
354 #ifndef DISABLE_VTKVIEWER
355   myAccel->setActionKey( SUIT_Accel::PanLeft,     Qt::CTRL+Qt::Key_Left,     VTKViewer_Viewer::Type() );
356   myAccel->setActionKey( SUIT_Accel::PanRight,    Qt::CTRL+Qt::Key_Right,    VTKViewer_Viewer::Type() );
357   myAccel->setActionKey( SUIT_Accel::PanUp,       Qt::CTRL+Qt::Key_Up,       VTKViewer_Viewer::Type() );
358   myAccel->setActionKey( SUIT_Accel::PanDown,     Qt::CTRL+Qt::Key_Down,     VTKViewer_Viewer::Type() );
359   myAccel->setActionKey( SUIT_Accel::ZoomIn,      Qt::CTRL+Qt::Key_Plus,     VTKViewer_Viewer::Type() );
360   myAccel->setActionKey( SUIT_Accel::ZoomOut,     Qt::CTRL+Qt::Key_Minus,    VTKViewer_Viewer::Type() );
361   myAccel->setActionKey( SUIT_Accel::ZoomFit,     Qt::CTRL+Qt::Key_Asterisk, VTKViewer_Viewer::Type() );
362   myAccel->setActionKey( SUIT_Accel::ZoomFit,     Qt::Key_Space,             VTKViewer_Viewer::Type() );
363   myAccel->setActionKey( SUIT_Accel::RotateLeft,  Qt::ALT+Qt::Key_Left,      VTKViewer_Viewer::Type() );
364   myAccel->setActionKey( SUIT_Accel::RotateRight, Qt::ALT+Qt::Key_Right,     VTKViewer_Viewer::Type() );
365   myAccel->setActionKey( SUIT_Accel::RotateUp,    Qt::ALT+Qt::Key_Up,        VTKViewer_Viewer::Type() );
366   myAccel->setActionKey( SUIT_Accel::RotateDown,  Qt::ALT+Qt::Key_Down,      VTKViewer_Viewer::Type() );
367 #endif
368 #ifndef DISABLE_PLOT2DVIEWER
369   myAccel->setActionKey( SUIT_Accel::PanLeft,     Qt::CTRL+Qt::Key_Left,     Plot2d_Viewer::Type() );
370   myAccel->setActionKey( SUIT_Accel::PanRight,    Qt::CTRL+Qt::Key_Right,    Plot2d_Viewer::Type() );
371   myAccel->setActionKey( SUIT_Accel::PanUp,       Qt::CTRL+Qt::Key_Up,       Plot2d_Viewer::Type() );
372   myAccel->setActionKey( SUIT_Accel::PanDown,     Qt::CTRL+Qt::Key_Down,     Plot2d_Viewer::Type() );
373   myAccel->setActionKey( SUIT_Accel::ZoomIn,      Qt::CTRL+Qt::Key_Plus,     Plot2d_Viewer::Type() );
374   myAccel->setActionKey( SUIT_Accel::ZoomOut,     Qt::CTRL+Qt::Key_Minus,    Plot2d_Viewer::Type() );
375   myAccel->setActionKey( SUIT_Accel::ZoomFit,     Qt::CTRL+Qt::Key_Asterisk, Plot2d_Viewer::Type() );
376   myAccel->setActionKey( SUIT_Accel::ZoomFit,     Qt::Key_Space,             Plot2d_Viewer::Type() );
377 #endif
378
379   connect( mySelMgr, SIGNAL( selectionChanged() ), this, SLOT( onSelection() ) );
380
381   // Set existing font for the python console in resources
382   if( !aResMgr->hasValue( "PyConsole", "font" ) )
383     return;
384
385   QFont f = aResMgr->fontValue( "PyConsole", "font" );
386   QFontDatabase fdb;
387   QStringList famdb = fdb.families();
388
389   if ( famdb.contains(f.family()) || !aResMgr->hasValue( "PyConsole", "additional_families" ) )
390     return;
391
392   QStringList anAddFamilies = aResMgr->stringValue( "PyConsole", "additional_families" ).split( ";", QString::SkipEmptyParts );
393   QString aFamily;
394   for ( QStringList::Iterator it = anAddFamilies.begin(); it != anAddFamilies.end(); ++it )
395   {
396     aFamily = *it;
397     if ( famdb.contains(aFamily) )
398     {
399       f.setFamily( aFamily );
400       aResMgr->setValue( "PyConsole", "font", f );
401       break;
402     }
403   }
404 }
405
406 /*!Destructor.
407  *\li Save window geometry.
408  *\li Save desktop geometry.
409  *\li Save resource maneger.
410  *\li Delete selection manager.
411  */
412 LightApp_Application::~LightApp_Application()
413 {
414   delete mySelMgr;
415   delete myScreenHelper;
416 }
417
418 /*!Start application.*/
419 void LightApp_Application::start()
420 {
421   CAM_Application::start();
422
423   updateWindows();
424   updateViewManagers();
425
426   putInfo( "" );
427   desktop()->statusBar()->showMessage( "" );
428
429   LightApp_EventFilter::Init();
430 }
431
432 /*!Gets application name.*/
433 QString LightApp_Application::applicationName() const
434 {
435   static QString _app_name;
436   if ( _app_name.isEmpty() )
437     _app_name = tr( "APP_NAME" );
438   return _app_name;
439 }
440
441 /*!Gets application version.*/
442 QString LightApp_Application::applicationVersion() const
443 {
444   static QString _app_version;
445
446   if ( _app_version.isEmpty() )
447   {
448     QString resVersion = tr( "APP_VERSION" );
449     if ( resVersion != "APP_VERSION" )
450     {
451       _app_version = resVersion;
452     }
453     else
454     {
455       _app_version = GUI_VERSION_STR;
456     }
457   }
458   return _app_version;
459 }
460
461 /*!Load module by \a name.*/
462 CAM_Module* LightApp_Application::loadModule( const QString& name, const bool showMsg )
463 {
464   CAM_Module* mod = CAM_Application::loadModule( name, showMsg );
465   if ( mod )
466   {
467     connect( this, SIGNAL( studyOpened() ), mod, SLOT( onModelOpened() ) );
468     connect( this, SIGNAL( studySaved() ),  mod, SLOT( onModelSaved() ) );
469     connect( this, SIGNAL( studyClosed() ), mod, SLOT( onModelClosed() ) );
470   }
471   return mod;
472 }
473
474 /*!Activate module by \a modName*/
475 bool LightApp_Application::activateModule( const QString& modName )
476 {
477   QString actName;
478   CAM_Module* prevMod = activeModule();
479
480   if ( prevMod )
481     actName = prevMod->moduleName();
482
483   if ( actName == modName )
484     return true;
485
486   putInfo( tr( "ACTIVATING_MODULE" ).arg( modName ) );
487
488   saveDockWindowsState();
489
490   bool status = CAM_Application::activateModule( modName );
491
492   updateModuleActions();
493
494   putInfo( "" );
495
496   if ( !status )
497     return false;
498
499   updateWindows();
500   updateViewManagers();
501
502   return true;
503 }
504
505 /*!Gets selection manager.*/
506 LightApp_SelectionMgr* LightApp_Application::selectionMgr() const
507 {
508   return mySelMgr;
509 }
510
511 /*!Creat action "New window" for certain type of viewer:*/
512 void LightApp_Application::createActionForViewer( const int id,
513                                                   const int parentId,
514                                                   const QString& suffix,
515                                                   const int accel )
516 {
517   QString vtlt = tr( QString( "NEW_WINDOW_%1" ).arg( suffix ).toLatin1().constData() );
518   QString tip = tr( "CREATING_NEW_WINDOW" ).arg( vtlt.remove( "&" ) );
519   QAction* a = createAction( id,                      // menu action id
520                              tip,                     // status tip
521                              QIcon(),                 // icon
522                              vtlt,                    // menu text
523                              tip,                     // tooltip
524                              accel,                   // shortcut
525                              desktop(),               // parent
526                              false,                   // toggle flag
527                              this,                    // receiver
528                              SLOT( onNewWindow() ) ); // slot
529   createMenu( a, parentId, -1 );
530 }
531
532 /*!Create actions:*/
533
534 void LightApp_Application::createActions()
535 {
536   CAM_Application::createActions();
537
538   SUIT_Desktop* desk = desktop();
539   SUIT_ResourceMgr* resMgr = resourceMgr();
540
541   // Preferences
542   createAction( PreferencesId, tr( "TOT_DESK_PREFERENCES" ), QIcon(),
543                 tr( "MEN_DESK_PREFERENCES" ), tr( "PRP_DESK_PREFERENCES" ),
544                 Qt::CTRL+Qt::Key_R, desk, false, this, SLOT( onPreferences() ) );
545
546   // Help menu:
547
548   // - Help for modules
549
550   int helpMenu = createMenu( tr( "MEN_DESK_HELP" ), -1, -1, 1000 );
551   createMenu( separator(), helpMenu, -1, 10 );
552   QStringList aModuleList;
553   modules( aModuleList, false );
554   aModuleList.prepend( "GUI" );
555   aModuleList.prepend( "KERNEL" );
556
557   int id = LightApp_Application::UserID + FIRST_HELP_ID;
558
559   QString aModule;
560   foreach( aModule, aModuleList ) {
561     if ( aModule.isEmpty() )                                         // module title (user name)
562       continue;
563     IMap <QString, QString> helpData;                                // list of help files for the module
564     QString helpSubMenu;                                             // help submenu name (empty if not needed)
565     QString modName = moduleName( aModule );                         // module name
566     if ( modName.isEmpty() ) modName = aModule;                      // for KERNEL and GUI
567     QString rootDir = QString( "%1_ROOT_DIR" ).arg( modName );       // module root dir variable
568     QString modDir  = getenv( rootDir.toLatin1().constData() );      // module root dir
569     QString docSection;
570     if (resMgr->hasValue( modName, "documentation" ) )
571       docSection = resMgr->stringValue(modName, "documentation");
572     else if ( resMgr->hasSection( modName + "_documentation" ) )
573       docSection = modName + "_documentation";
574     if ( !docSection.isEmpty() ) {
575       helpSubMenu = resMgr->stringValue( docSection, "sub_menu", "" ).arg( aModule );
576       QStringList listOfParam = resMgr->parameters( docSection );
577       foreach( QString paramName, listOfParam ) {
578         QString valueStr = resMgr->stringValue( docSection, paramName );
579         if ( !valueStr.isEmpty() ) {
580           QFileInfo fi( valueStr );
581           if ( fi.isRelative() && !modDir.isEmpty() )
582             valueStr = Qtx::addSlash( modDir ) + valueStr;
583           if ( QFile::exists( valueStr ) )
584             helpData.insert( paramName.arg( aModule ), valueStr );
585         }
586       }
587     }
588
589     if ( helpData.isEmpty() && !modDir.isEmpty() ) {
590       QStringList idxLst = QStringList() << modDir << "share" << "doc" << "salome" << "gui" << modName << "index.html";
591       QString indexFile = idxLst.join( QDir::separator() );          // index file
592       if ( QFile::exists( indexFile ) )
593         helpData.insert( tr( "%1 module Users's Guide" ).arg( aModule ), indexFile );
594     }
595
596     IMapConstIterator<QString, QString > fileIt;
597     for ( fileIt = helpData.begin(); fileIt != helpData.end(); fileIt++ ) {
598       QString helpFileName = fileIt.key();
599       // remove all '//' occurances 
600       while ( helpFileName.contains( "//" ) )
601         helpFileName.replace( "//", "" );
602       // obtain submenus hierarchy if given
603       QStringList smenus = helpFileName.split( "/" );
604       helpFileName = smenus.last();
605       smenus.removeLast();
606       QAction* a = createAction( id, helpFileName,
607                                  resMgr->loadPixmap( "STD", tr( "ICON_HELP" ), false ),
608                                  helpFileName, helpFileName,
609                                  0, desk, false, this, SLOT( onHelpContentsModule() ) );
610       a->setData( fileIt.value() );
611       if ( !helpSubMenu.isEmpty() ) {
612         smenus.prepend( helpSubMenu );
613       }
614       // create sub-menus hierarchy
615       int menuId = helpMenu;
616       foreach ( QString subMenu, smenus ) {
617         menuId = createMenu( subMenu, menuId, -1, 0 );
618       }
619       createMenu( a, menuId, -1, 0 );
620       id++;
621     }
622   }
623
624   // - Additional help items
625
626   createMenu( separator(), helpMenu, -1, 5 );
627
628   QStringList addHelpItems = resMgr->parameters( "add_help" );
629   foreach ( QString addHelpItem, addHelpItems ) {
630     QString valueStr = resMgr->stringValue( "add_help", addHelpItem );
631     if ( !valueStr.isEmpty() && QFile::exists( valueStr ) ) {
632       QAction* a = createAction( id, addHelpItem,
633                                  resMgr->loadPixmap( "STD", tr( "ICON_HELP" ), false ),
634                                  addHelpItem, addHelpItem,
635                                  0, desk, false, this, SLOT( onHelpContentsModule() ) );
636       a->setData( valueStr );
637       createMenu( a, helpMenu, -1, 5 );
638       id++;
639     }
640   }
641
642   //! MRU
643   static QtxMRUAction* mru = new QtxMRUAction( tr( "TOT_DESK_MRU" ), tr( "MEN_DESK_MRU" ), 0 );
644   connect( mru, SIGNAL( activated( const QString& ) ), this, SLOT( onMRUActivated( const QString& ) ) );
645   registerAction( MRUId, mru );
646
647   // default icon for neutral point ('SALOME' module)
648   QPixmap defIcon = resMgr->loadPixmap( "LightApp", tr( "APP_DEFAULT_ICO" ), false );
649   if ( defIcon.isNull() )
650     defIcon = QPixmap( imageEmptyIcon );
651
652   //! default icon for any module
653   QPixmap modIcon = resMgr->loadPixmap( "LightApp", tr( "APP_MODULE_ICO" ), false );
654   if ( modIcon.isNull() )
655     modIcon = QPixmap( imageEmptyIcon );
656
657   QStringList modList;
658   modules( modList, false );
659
660   if ( modList.count() > 1 )
661   {
662     LightApp_ModuleAction* moduleAction =
663       new LightApp_ModuleAction( tr( "APP_NAME" ), defIcon, desk );
664
665     QMap<QString, QString> iconMap;
666     moduleIconNames( iconMap );
667
668     const int iconSize = 20;
669
670     QStringList::Iterator it;
671     for ( it = modList.begin(); it != modList.end(); ++it )
672     {
673       if ( !isLibExists( *it ) )
674         continue;
675
676       QString modName = moduleName( *it );
677
678       if ( !isModuleAccessible( *it ) )
679         continue;
680
681       QString iconName;
682       if ( iconMap.contains( *it ) )
683         iconName = iconMap[*it];
684
685       QPixmap icon = resMgr->loadPixmap( modName, iconName, false );
686       if ( icon.isNull() )
687       {
688         icon = modIcon;
689         INFOS ( "\n****************************************************************" << std::endl
690                 <<  "*    Icon for " << (*it).toLatin1().constData()
691                 << " not found. Using the default one." << std::endl
692                 << "****************************************************************" << std::endl );
693       }
694
695       icon = Qtx::scaleIcon( icon, iconSize );
696
697       moduleAction->insertModule( *it, icon );
698     }
699
700     connect( moduleAction, SIGNAL( moduleActivated( const QString& ) ),
701              this, SLOT( onModuleActivation( const QString& ) ) );
702     registerAction( ModulesListId, moduleAction );
703   }
704
705   // New window
706   int windowMenu = createMenu( tr( "MEN_DESK_WINDOW" ), -1, MenuWindowId, 100 );
707   int newWinMenu = createMenu( tr( "MEN_DESK_NEWWINDOW" ), windowMenu, -1, 0 );
708
709   createAction( CloseId, tr( "TOT_CLOSE" ), QIcon(), tr( "MEN_DESK_CLOSE" ), tr( "PRP_CLOSE" ),
710                 Qt::CTRL+Qt::Key_F4, desk, false, this, SLOT( onCloseWindow() ) );
711   createAction( CloseAllId, tr( "TOT_CLOSE_ALL" ), QIcon(), tr( "MEN_DESK_CLOSE_ALL" ), tr( "PRP_CLOSE_ALL" ),
712                 0, desk, false, this, SLOT( onCloseAllWindow() ) );
713   createAction( GroupAllId, tr( "TOT_GROUP_ALL" ), QIcon(), tr( "MEN_DESK_GROUP_ALL" ), tr( "PRP_GROUP_ALL" ),
714                 0, desk, false, this, SLOT( onGroupAllWindow() ) );
715
716   createMenu( CloseId,     windowMenu, 0, -1 );
717   createMenu( CloseAllId,  windowMenu, 0, -1 );
718   createMenu( GroupAllId,  windowMenu, 0, -1 );
719   createMenu( separator(), windowMenu, -1, 0 );
720
721 #ifndef DISABLE_GLVIEWER
722   createActionForViewer( NewGLViewId, newWinMenu, QString::number( 0 ), Qt::ALT+Qt::Key_G );
723 #endif
724 #ifndef DISABLE_PLOT2DVIEWER
725   createActionForViewer( NewPlot2dId, newWinMenu, QString::number( 1 ), Qt::ALT+Qt::Key_P );
726 #endif
727 #ifndef DISABLE_OCCVIEWER
728   createActionForViewer( NewOCCViewId, newWinMenu, QString::number( 2 ), Qt::ALT+Qt::Key_O );
729 #endif
730 #ifndef DISABLE_VTKVIEWER
731   createActionForViewer( NewVTKViewId, newWinMenu, QString::number( 3 ), Qt::ALT+Qt::Key_K );
732 #endif
733 #ifndef DISABLE_QXGRAPHVIEWER
734   createActionForViewer( NewQxSceneViewId, newWinMenu, QString::number( 4 ), Qt::ALT+Qt::Key_S );
735 #endif
736 #ifndef DISABLE_GRAPHICSVIEW
737   createActionForViewer( NewGraphicsViewId, newWinMenu, QString::number( 5 ), Qt::ALT+Qt::Key_R );
738 #endif
739
740   createAction( RenameId, tr( "TOT_RENAME" ), QIcon(), tr( "MEN_DESK_RENAME" ), tr( "PRP_RENAME" ),
741                 Qt::ALT+Qt::SHIFT+Qt::Key_R, desk, false, this, SLOT( onRenameWindow() ) );
742   createMenu( RenameId, windowMenu, -1 );
743
744   int fileMenu = createMenu( tr( "MEN_DESK_FILE" ), -1 );
745   createMenu( PreferencesId, fileMenu, 50, -1 );
746   createMenu( separator(), fileMenu, -1, 50, -1 );
747
748   createMenu( separator(), fileMenu, -1, 100, -1 );
749   createMenu( MRUId, fileMenu, 100, -1 );
750   createMenu( separator(), fileMenu, -1, 100, -1 );
751
752   createAction( StyleId, tr( "TOT_THEME" ), QIcon(), tr( "MEN_DESK_THEME" ), tr( "PRP_THEME" ),
753                 0, desk, false, this, SLOT( onStylePreferences() ) );
754
755   createAction( FullScreenId, tr( "TOT_FULLSCREEN" ), QIcon(), tr( "MEN_DESK_FULLSCREEN" ), tr( "PRP_FULLSCREEN" ),
756                 Qt::Key_F11, desk, false, this, SLOT( onFullScreen() ) );
757
758
759   int viewMenu = createMenu( tr( "MEN_DESK_VIEW" ), -1 );
760   createMenu( separator(), viewMenu, -1, 20, -1 );
761   createMenu( StyleId, viewMenu, 20, -1 );
762   createMenu( FullScreenId, viewMenu, 20, -1 );
763
764   int modTBar = createTool( tr( "INF_TOOLBAR_MODULES" ) );
765   createTool( ModulesListId, modTBar );
766 }
767
768 /*!On module activation action.*/
769 void LightApp_Application::onModuleActivation( const QString& modName )
770 {
771   // Force user to create/open a study before module activation
772   QMap<QString, QString> iconMap;
773   moduleIconNames( iconMap );
774   QPixmap icon = resourceMgr()->loadPixmap( moduleName( modName ), iconMap[ modName ], false );
775   if ( icon.isNull() )
776     icon = resourceMgr()->loadPixmap( "LightApp", tr( "APP_MODULE_BIG_ICO" ), false ); // default icon for any module
777
778   bool cancelled = false;
779
780   while ( !modName.isEmpty() && !activeStudy() && !cancelled ){
781     LightApp_ModuleDlg aDlg( desktop(), modName, icon );
782     QMap<int, QString> opmap = activateModuleActions();
783     for ( QMap<int, QString>::ConstIterator it = opmap.begin(); it != opmap.end(); ++it )
784       aDlg.addButton( it.value(), it.key() );
785
786     int res = aDlg.exec();
787     if ( res ) {
788       // some operation is selected
789       moduleActionSelected( res );
790     }
791     else {
792       // cancelled
793       putInfo( tr("INF_CANCELLED") );
794
795       LightApp_ModuleAction* moduleAction =
796         qobject_cast<LightApp_ModuleAction*>( action( ModulesListId ) );
797       if ( moduleAction )
798         moduleAction->setActiveModule( QString() );
799       cancelled = true;
800     }
801   }
802
803   if ( !cancelled )
804     activateModule( modName );
805 }
806
807 /*!Default module activation.*/
808 QString LightApp_Application::defaultModule() const
809 {
810   QStringList aModuleNames;
811   modules( aModuleNames, false ); // obtain a complete list of module names for the current configuration
812   //! If there's the one and only module --> activate it automatically
813   //! TODO: Possible improvement - default module can be taken from preferences
814   return aModuleNames.count() > 1 ? "" : ( aModuleNames.count() ? aModuleNames.first() : "" );
815 }
816
817 /*!On new window slot.*/
818 void LightApp_Application::onNewWindow()
819 {
820   const QObject* obj = sender();
821   if ( !obj || !obj->inherits( "QAction" ) )
822     return;
823
824   QString type;
825   int id = actionId( (QAction*)obj );
826   switch ( id )
827   {
828 #ifndef DISABLE_GLVIEWER
829   case NewGLViewId:
830     type = GLViewer_Viewer::Type();
831     break;
832 #endif
833 #ifndef DISABLE_PLOT2DVIEWER
834   case NewPlot2dId:
835     type = Plot2d_Viewer::Type();
836     break;
837 #endif
838 #ifndef DISABLE_OCCVIEWER
839   case NewOCCViewId:
840     type = OCCViewer_Viewer::Type();
841     break;
842 #endif
843 #ifndef DISABLE_VTKVIEWER
844   case NewVTKViewId:
845     type = VTKViewer_Viewer::Type();
846     break;
847 #endif
848 #ifndef DISABLE_QXGRAPHVIEWER
849   case NewQxSceneViewId:
850     type = QxScene_Viewer::Type();
851     break;
852 #endif
853 #ifndef DISABLE_GRAPHICSVIEW
854   case NewGraphicsViewId:
855     type = GraphicsView_Viewer::Type();
856     break;
857 #endif
858   }
859
860   if ( !type.isEmpty() )
861     createViewManager( type );
862 }
863
864 /*!
865   SLOT: Creates new document
866 */
867 void LightApp_Application::onNewDoc()
868 {
869   //asl: fix for 0020515
870   if ( activeStudy() )
871     saveDockWindowsState();
872
873   CAM_Application::onNewDoc();
874 }
875
876 /*!
877   SLOT: Opens new document
878 */
879 void LightApp_Application::onOpenDoc()
880 {
881   SUIT_Study* study = activeStudy();
882   saveDockWindowsState();
883
884   CAM_Application::onOpenDoc();
885
886   if ( !study ) // new study will be create in THIS application
887   {
888     updateWindows();
889     updateViewManagers();
890   }
891 }
892
893 /*!
894   SLOT: Opens new document.
895   \param aName - name of file
896 */
897 bool LightApp_Application::onOpenDoc( const QString& aName )
898 {
899   // We should take mru action first because this application instance can be deleted later.
900   QtxMRUAction* mru = ::qobject_cast<QtxMRUAction*>( action( MRUId ) );
901
902   bool res = CAM_Application::onOpenDoc( aName );
903
904   if ( mru )
905   {
906     if ( res )
907       mru->insert( aName );
908     else
909       mru->remove( aName );
910   }
911   return res;
912 }
913
914 /*!
915   SLOT: Displays "About" message box
916 */
917 void LightApp_Application::onHelpAbout()
918 {
919   LightApp_AboutDlg dlg( applicationName(), applicationVersion(), desktop() );
920   dlg.exec();
921 }
922
923 /*!
924   Private SLOT: Called on selection is changed
925   Dispatchs active module that selection is changed
926 */
927 void LightApp_Application::onSelection()
928 {
929   onSelectionChanged();
930
931   if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) )
932     ((LightApp_Module*)activeModule())->selectionChanged();
933 }
934
935 /*!
936   Sets active study.
937  \param study - SUIT_Study.
938 */
939 void LightApp_Application::setActiveStudy( SUIT_Study* study )
940 {
941   CAM_Application::setActiveStudy( study );
942 }
943
944 /*!
945   Enables/Disables menu items and toolbar buttons. Rebuild menu
946 */
947 void LightApp_Application::updateCommandsStatus()
948 {
949   CAM_Application::updateCommandsStatus();
950   QAction* a = 0;
951
952 #ifndef DISABLE_GLVIEWER
953   a = action( NewGLViewId );
954   if( a )
955     a->setEnabled( activeStudy() );
956 #endif
957
958 #ifndef DISABLE_PLOT2DVIEWER
959   a = action( NewPlot2dId );
960   if( a )
961     a->setEnabled( activeStudy() );
962 #endif
963
964 #ifndef DISABLE_OCCVIEWER
965   a = action( NewOCCViewId );
966   if( a )
967     a->setEnabled( activeStudy() );
968 #endif
969
970 #ifndef DISABLE_VTKVIEWER
971   a = action( NewVTKViewId );
972   if( a )
973     a->setEnabled( activeStudy() );
974 #endif
975
976 #ifndef DISABLE_QXGRAPHVIEWER
977   a = action( NewQxSceneViewId );
978   if( a )
979     a->setEnabled( activeStudy() );
980 #endif
981
982 #ifndef DISABLE_GRAPHICSVIEW
983   a = action( NewGraphicsViewId );
984   if( a )
985     a->setEnabled( activeStudy() );
986 #endif
987 }
988
989 /*!
990   \class RunBrowser
991   Runs system command in separate thread
992 */
993 class RunBrowser: public QThread
994 {
995 public:
996   RunBrowser( LightApp_Application* app,
997               const QString&        theApp,
998               const QString&        theParams,
999               const QString&        theHelpFile,
1000               const QString&        theContext = QString() )
1001     : myApp( theApp ),
1002       myParams( theParams ),
1003       myContext( theContext ),
1004       myStatus(0),
1005       myLApp( app )
1006   {
1007     //For the external browser always specify 'file://' protocol,
1008     //because some WEB browsers (for example Mozilla Firefox) can't open local file without protocol.
1009     myHelpFile = QString("file://%1").arg( QFileInfo( theHelpFile ).canonicalFilePath() );
1010   }
1011
1012   virtual void run()
1013   {
1014     if ( !myApp.isEmpty() && !myHelpFile.isEmpty()) {
1015       QString aCommand = QString( "%1 %2 \"%3%4\"" ).arg( myApp, myParams, myHelpFile, myContext.isEmpty() ? QString("") : QString( "#%1" ).arg( myContext ) );
1016
1017       QProcess* proc = new QProcess();
1018
1019       proc->start( aCommand );
1020       if ( !proc->waitForStarted() ) {
1021         SALOME_CustomEvent* ce2000 = new SALOME_CustomEvent( 2000 );
1022         QString* msg = new QString( QObject::tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ).arg( myApp, myHelpFile ) );
1023         ce2000->setData( msg );
1024         QApplication::postEvent( myLApp, ce2000 );
1025       }
1026     }
1027   }
1028
1029 private:
1030   QString               myApp;
1031   QString               myParams;
1032   QString               myHelpFile;
1033   QString               myContext;
1034   int                   myStatus;
1035   LightApp_Application* myLApp;
1036 };
1037
1038 /*!
1039   SLOT: Displays help contents for choosen module
1040 */
1041 void LightApp_Application::onHelpContentsModule()
1042 {
1043   const QAction* a = (QAction*) sender();
1044   QString helpFile = a->data().toString();
1045   if ( helpFile.isEmpty() ) return;
1046
1047   SUIT_ResourceMgr* resMgr = resourceMgr();
1048   QString platform;
1049 #ifdef WIN32
1050   platform = "winapplication";
1051 #else
1052   platform = "application";
1053 #endif
1054   QString anApp = resMgr->stringValue("ExternalBrowser", platform);
1055 #ifdef WIN32
1056   QString quote("\"");
1057   anApp.prepend( quote );
1058   anApp.append( quote );
1059 #endif
1060   QString aParams = resMgr->stringValue("ExternalBrowser", "parameters");
1061   bool useExtBrowser = resMgr->booleanValue("ExternalBrowser", "use_external_browser", false );
1062
1063   if( useExtBrowser ) {
1064     if ( !anApp.isEmpty() ) {
1065       RunBrowser* rs = new RunBrowser( this, anApp, aParams, helpFile );
1066       rs->start();
1067     }
1068     else {
1069       if ( SUIT_MessageBox::question( desktop(), tr( "WRN_WARNING" ), tr( "DEFINE_EXTERNAL_BROWSER" ),
1070                                       SUIT_MessageBox::Yes | SUIT_MessageBox::No,
1071                                       SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes )
1072
1073         showPreferences( tr( "PREF_APP" ) );
1074     }
1075   }
1076   else {
1077 #ifdef WIN32
1078     // On Win32 platform QWebKit of the Qt 4.6.3 hang up in case 'file://' protocol 
1079     // is defined. On Linux platform QWebKit doesn't work correctly without 'file://' protocol.
1080     QtxWebBrowser::loadUrl(helpFile);
1081 #else
1082     QtxWebBrowser::loadUrl(QString("file://%1").arg(helpFile));
1083 #endif
1084   }
1085 }
1086
1087 /*!
1088   SLOT: Displays help contents for choosen dialog
1089 */
1090 void LightApp_Application::onHelpContextModule( const QString& theComponentName,
1091                                                 const QString& theFileName,
1092                                                 const QString& theContext )
1093 {
1094   QString fileName = theFileName;
1095   QString context  = theContext;
1096   if ( !QFile::exists( fileName ) && theContext.isEmpty() ) {
1097     // context might be passed within theFileName argument
1098     QStringList comps = fileName.split("#");
1099     if ( comps.count() > 1 ) {
1100       context = comps.last();
1101       comps.removeLast();
1102       fileName = comps.join("#");
1103     }
1104   }
1105
1106   QString homeDir = "";
1107   if ( !theComponentName.isEmpty() ) {
1108     QString dir = getenv( ( theComponentName + "_ROOT_DIR" ).toLatin1().constData() );
1109     if ( !dir.isEmpty() )
1110       homeDir = Qtx::addSlash( Qtx::addSlash( dir )      +
1111                                Qtx::addSlash( "share" )  +
1112                                Qtx::addSlash( "doc" )    +
1113                                Qtx::addSlash( "salome" ) +
1114                                Qtx::addSlash( "gui" )    +
1115                                Qtx::addSlash( theComponentName ) );
1116   }
1117
1118   QString helpFile = QFileInfo( homeDir + fileName ).absoluteFilePath();
1119   SUIT_ResourceMgr* resMgr = resourceMgr();
1120         QString platform;
1121 #ifdef WIN32
1122         platform = "winapplication";
1123 #else
1124         platform = "application";
1125 #endif
1126         QString anApp = resMgr->stringValue("ExternalBrowser", platform);
1127 #ifdef WIN32
1128         QString quote("\"");
1129         anApp.prepend( quote );
1130         anApp.append( quote );
1131 #endif
1132
1133   bool useExtBrowser = resMgr->booleanValue("ExternalBrowser", "use_external_browser", false );
1134
1135   if(useExtBrowser) {
1136     QString aParams = resMgr->stringValue("ExternalBrowser", "parameters");
1137
1138     if ( !anApp.isEmpty() ) {
1139       RunBrowser* rs = new RunBrowser( this, anApp, aParams, helpFile, context );
1140       rs->start();
1141     }
1142     else {
1143       if ( SUIT_MessageBox::question( desktop(), tr( "WRN_WARNING" ), tr( "DEFINE_EXTERNAL_BROWSER" ),
1144                                       SUIT_MessageBox::Yes | SUIT_MessageBox::No,
1145                                       SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes )
1146         showPreferences( tr( "PREF_APP" ) );
1147     }
1148   }
1149   else {
1150 #ifdef WIN32
1151     // On Win32 platform QWebKit of the Qt 4.6.3 hang up in case 'file://' protocol 
1152     // is defined. On Linux platform QWebKit doesn't work correctly without 'file://' protocol.
1153     QtxWebBrowser::loadUrl(helpFile, context);
1154 #else
1155     QtxWebBrowser::loadUrl(QString("file://%1").arg(helpFile), context);
1156 #endif
1157     
1158   }
1159 }
1160
1161 /*!
1162   Sets enable or disable some actions on selection changed.
1163 */
1164 void LightApp_Application::onSelectionChanged()
1165 {
1166   LightApp_Module* m = dynamic_cast<LightApp_Module*>( activeModule() );
1167   bool canCopy  = m ? m->canCopy() : false;
1168   bool canPaste = m ? m->canPaste() : false;
1169
1170   action( EditCopyId )->setEnabled(canCopy);
1171   action( EditPasteId )->setEnabled(canPaste);
1172 }
1173
1174 /*!
1175   Adds window to application.
1176   \param wid - QWidget
1177   \param flag - key for window
1178   \param studyId - study id
1179   Flag used how identificator of window in windows list.
1180 */
1181 /*
1182 void LightApp_Application::addWindow( QWidget* wid, const int flag, const int studyId )
1183 {
1184   if ( !wid )
1185     return;
1186
1187   int sId = studyId;
1188   if ( sId < 0 )
1189   {
1190     if ( !activeStudy() )
1191       return;
1192     else
1193       sId = activeStudy()->id();
1194   }
1195
1196   if ( !myWindows.contains( flag ) )
1197   {
1198     QMap<int, int> winMap;
1199     currentWindows( winMap );
1200
1201     LightApp_WidgetContainer* newWC = new LightApp_WidgetContainer( flag, desktop() );
1202     connect( newWC, SIGNAL(  destroyed ( QObject* ) ), this, SLOT( onWCDestroyed( QObject* ) ) );
1203     // asv: connecting a slot for storing visibility flag of a window
1204     connect( newWC, SIGNAL( visibilityChanged ( bool ) ), SLOT( onVisibilityChanged( bool ) ) );
1205     myWindows.insert( flag, newWC );
1206     if ( winMap.contains( flag ) ) {
1207       //desktop()->removeDockWidget( myWindows[flag] );
1208       desktop()->addDockWidget( (Qt::DockWidgetArea)winMap[flag], myWindows[flag] );
1209     }
1210
1211     //myWindows[flag]->setResizeEnabled( true );
1212     myWindows[flag]->setFeatures( QDockWidget::AllDockWidgetFeatures );
1213     myWindows[flag]->setObjectName( QString( "dock_window_%1" ).arg( flag ) );
1214     //myWindows[flag]->setFixedExtentWidth( wid->width() );
1215     //myWindows[flag]->setFixedExtentHeight( wid->height() );
1216     myWindows[flag]->resize( wid->width(), wid->height() );
1217   }
1218
1219   QFont f;
1220 #ifndef DISABLE_PYCONSOLE
1221   if( wid->inherits( "PyConsole_Console" ) )
1222   {
1223     if( resourceMgr()->hasValue( "PyConsole", "font" ) )
1224       f = resourceMgr()->fontValue( "PyConsole", "font" );
1225     else
1226       {
1227         f = ( ( PyConsole_Console* )wid )->font();
1228         resourceMgr()->setValue( "PyConsole", "font", f );
1229       }
1230   }
1231   else
1232 #endif
1233     f = wid->font();
1234
1235   myWindows[flag]->insert( sId, wid );
1236   wid->setFont( f );
1237
1238   setWindowShown( flag, !myWindows[flag]->isEmpty() );
1239 }
1240 */
1241
1242 QWidget* LightApp_Application::dockWindow( const int id ) const
1243 {
1244   QWidget* wid = 0;
1245   if ( myWin.contains( id ) )
1246     wid = myWin[id];
1247   return wid;
1248 }
1249
1250 QDockWidget* LightApp_Application::windowDock( QWidget* wid ) const
1251 {
1252   if ( !wid )
1253     return 0;
1254
1255   QDockWidget* dock = 0;
1256   QWidget* w = wid->parentWidget();
1257   while ( w && !dock )
1258   {
1259     dock = ::qobject_cast<QDockWidget*>( w );
1260     w = w->parentWidget();
1261   }
1262   return dock;
1263 }
1264
1265 void LightApp_Application::insertDockWindow( const int id, QWidget* wid )
1266 {
1267   if ( !wid )
1268     return;
1269
1270   if ( wid != dockWindow( id ) )
1271     removeDockWindow( id );
1272
1273   myWin.insert( id, wid );
1274
1275   QtxDockWidget* dock = new QtxDockWidget( true, desktop() );
1276   connect( dock, SIGNAL(  destroyed( QObject* ) ), this, SLOT( onWCDestroyed( QObject* ) ) );
1277
1278   dock->setFeatures( QDockWidget::AllDockWidgetFeatures );
1279   dock->setObjectName( QString( "window_%1" ).arg( id ) );
1280   dock->setWidget( wid );
1281
1282   QKeySequence accel = wid->property( "shortcut" ).value<QKeySequence>();
1283   if ( !accel.isEmpty() )
1284     dock->toggleViewAction()->setShortcut( accel );
1285
1286   dock->show();
1287 }
1288
1289 void LightApp_Application::removeDockWindow( const int id )
1290 {
1291   QWidget* wid = dockWindow( id );
1292   if ( !wid )
1293     return;
1294
1295   myWin.remove( id );
1296
1297   QDockWidget* dock = windowDock( wid );
1298   if ( !dock )
1299     return;
1300
1301   dock->setWidget( 0 );
1302   wid->setParent( 0 );
1303   wid->setVisible( false );
1304   delete dock;
1305 }
1306
1307 void LightApp_Application::placeDockWindow( const int id, Qt::DockWidgetArea place )
1308 {
1309   QDockWidget* dock = windowDock( dockWindow( id ) );
1310   if ( dock && desktop() ) {
1311     desktop()->addDockWidget( place, dock );
1312     QtxDockAction* a = qobject_cast<QtxDockAction*>( action( ViewWindowsId ) );
1313     if ( a ) a->update();
1314   }
1315 }
1316
1317 /*!
1318   Gets window.
1319   \param flag - key for window
1320   \param studyId - study id
1321   Flag used how identificator of window in windows list.
1322 */
1323 QWidget* LightApp_Application::getWindow( const int flag, const int )
1324 {
1325   QWidget* wid = dockWindow( flag );
1326   if ( !wid )
1327     insertDockWindow( flag, wid = createWindow( flag ) );
1328
1329   QMap<int, int> winMap;
1330   currentWindows( winMap );
1331   if ( winMap.contains( flag ) )
1332     placeDockWindow( flag, (Qt::DockWidgetArea)winMap[flag] );
1333
1334   return wid;
1335 }
1336
1337 /*!
1338   \return Object Browser
1339 */
1340 SUIT_DataBrowser* LightApp_Application::objectBrowser()
1341 {
1342   return qobject_cast<SUIT_DataBrowser*>( dockWindow( WT_ObjectBrowser ) );
1343 }
1344
1345 /*!
1346   \return Log Window
1347 */
1348 LogWindow* LightApp_Application::logWindow()
1349 {
1350   return qobject_cast<LogWindow*>( dockWindow( WT_LogWindow ) );
1351 }
1352
1353 #ifndef DISABLE_PYCONSOLE
1354 /*!
1355   This returns the python console integrated to the GUI. Depending
1356   when you request the python console, this function could return
1357   null. Then the optional parameter force (default to false) can be
1358   set to force the creation of the python console if it is not done
1359   already. 
1360   \param force - if true, the pythonConsole is created if it does not exist yet
1361   \return Python Console
1362 */
1363 PyConsole_Console* LightApp_Application::pythonConsole(const bool force)
1364 {
1365   QWidget* wid = dockWindow( WT_PyConsole );
1366   if ( !wid && force==true) {
1367     wid = getWindow(WT_PyConsole);
1368   }
1369   return qobject_cast<PyConsole_Console*>( wid );
1370 }
1371 #endif
1372
1373 /*!
1374   Updates object browser and maybe data models
1375   \param updateModels - if it is true, then data models are updated
1376 */
1377 void LightApp_Application::updateObjectBrowser( const bool updateModels )
1378 {
1379   // update existing data models
1380   if ( updateModels )
1381   {
1382     const bool isAutoUpdate = objectBrowser() ? objectBrowser()->autoUpdate() : true;
1383     if ( objectBrowser() )
1384       objectBrowser()->setAutoUpdate( false );
1385
1386     LightApp_Study* study = dynamic_cast<LightApp_Study*>(activeStudy());
1387     if ( study ) {
1388       CAM_Study::ModelList dm_list;
1389       study->dataModels( dm_list );
1390       QListIterator<CAM_DataModel*> it( dm_list );
1391       while ( it.hasNext() ) {
1392         CAM_DataModel* camDM = it.next();
1393         if ( camDM && camDM->inherits( "LightApp_DataModel" ) )
1394           ((LightApp_DataModel*)camDM)->update();
1395       }
1396     }
1397
1398     if( objectBrowser() )
1399       objectBrowser()->setAutoUpdate( isAutoUpdate );
1400   }
1401
1402   if ( objectBrowser() ) {
1403     objectBrowser()->updateGeometry();
1404     objectBrowser()->updateTree( 0, false );
1405   }
1406 }
1407
1408 /*!
1409   \return preferences
1410 */
1411 LightApp_Preferences* LightApp_Application::preferences() const
1412 {
1413   return preferences( false );
1414 }
1415
1416 /*!
1417   \return first view manager of some type
1418   \param vmType - type of view manager
1419   \param create - is it necessary to create view manager in case, when there is no manager of such type
1420 */
1421 SUIT_ViewManager* LightApp_Application::getViewManager( const QString& vmType, const bool create )
1422 {
1423   SUIT_ViewManager* aVM = viewManager( vmType );
1424   SUIT_ViewManager* anActiveVM = CAM_Application::activeViewManager();
1425
1426   if ( anActiveVM && anActiveVM->getType() == vmType )
1427     aVM = anActiveVM;
1428
1429   if ( aVM && create )
1430   {
1431     if ( !aVM->getActiveView() )
1432       aVM->createView();
1433     else
1434       aVM->getActiveView()->setFocus();
1435   }
1436   else if ( create )
1437     aVM = createViewManager( vmType );
1438
1439   return aVM;
1440 }
1441
1442 /*!
1443   Creates view manager of some type
1444   \param vmType - type of view manager
1445 */
1446 SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType )
1447 {
1448   SUIT_ResourceMgr* resMgr = resourceMgr();
1449
1450   SUIT_ViewManager* viewMgr = 0;
1451 #ifndef DISABLE_GLVIEWER
1452   if( vmType == GLViewer_Viewer::Type() )
1453   {
1454     viewMgr = new GLViewer_ViewManager( activeStudy(), desktop() );
1455     new LightApp_GLSelector( (GLViewer_Viewer2d*)viewMgr->getViewModel(), mySelMgr );
1456   }
1457 #endif
1458 #ifndef DISABLE_PLOT2DVIEWER
1459   if( vmType == Plot2d_Viewer::Type() )
1460   {
1461     viewMgr = new Plot2d_ViewManager( activeStudy(), desktop() );
1462     Plot2d_Viewer* vm;
1463 #ifndef DISABLE_SALOMEOBJECT
1464     SPlot2d_Viewer* v = new SPlot2d_Viewer();
1465     vm = v;
1466     new LightApp_Plot2dSelector( v, mySelMgr );
1467 #else
1468     vm = new Plot2d_Viewer();
1469 #endif
1470     viewMgr->setViewModel( vm  );// custom view model, which extends SALOME_View interface
1471     Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( viewMgr->getActiveView() );
1472     if( wnd )
1473     {
1474       Plot2d_ViewFrame* frame = wnd->getViewFrame();
1475       frame->setBackgroundColor( resMgr->colorValue( "Plot2d", "Background", frame->backgroundColor() ) );
1476     }
1477   }
1478 #endif
1479 #ifndef DISABLE_QXGRAPHVIEWER
1480   if( vmType == QxScene_Viewer::Type() )
1481   {
1482     viewMgr = new QxScene_ViewManager( activeStudy(), desktop() );
1483     QxScene_Viewer* vm = new QxScene_Viewer();
1484     viewMgr->setViewModel( vm  );
1485     //QxScene_ViewWindow* wnd = dynamic_cast<QxScene_ViewWindow*>( viewMgr->getActiveView() );
1486   }
1487 #endif
1488 #ifndef DISABLE_GRAPHICSVIEW
1489   if( vmType == GraphicsView_Viewer::Type() )
1490   {
1491     viewMgr = new GraphicsView_ViewManager( activeStudy(), desktop() );
1492     new LightApp_GVSelector( (GraphicsView_Viewer*)viewMgr->getViewModel(), mySelMgr );
1493   }
1494 #endif
1495 #ifndef DISABLE_OCCVIEWER
1496   if( vmType == OCCViewer_Viewer::Type() )
1497   {
1498     viewMgr = new OCCViewer_ViewManager( activeStudy(), desktop() );
1499     OCCViewer_Viewer* vm;
1500 #ifndef DISABLE_SALOMEOBJECT
1501     vm = new SOCC_Viewer();
1502 #else
1503     vm = new OCCViewer_Viewer( true );
1504 #endif
1505     vm->setBackground( OCCViewer_ViewFrame::TOP_LEFT,
1506                        resMgr->backgroundValue( "OCCViewer", "xz_background", vm->background(OCCViewer_ViewFrame::TOP_LEFT) ) );
1507     vm->setBackground( OCCViewer_ViewFrame::TOP_RIGHT,
1508                        resMgr->backgroundValue( "OCCViewer", "yz_background", vm->background(OCCViewer_ViewFrame::TOP_RIGHT) ) );
1509     vm->setBackground( OCCViewer_ViewFrame::BOTTOM_LEFT,
1510                        resMgr->backgroundValue( "OCCViewer", "xy_background", vm->background(OCCViewer_ViewFrame::BOTTOM_LEFT) ) );
1511     vm->setBackground( OCCViewer_ViewFrame::BOTTOM_RIGHT,
1512                        resMgr->backgroundValue( "OCCViewer", "background", vm->background(OCCViewer_ViewFrame::MAIN_VIEW) ) );
1513
1514     vm->setTrihedronSize(  resMgr->doubleValue( "3DViewer", "trihedron_size", vm->trihedronSize() ),
1515                            resMgr->booleanValue( "3DViewer", "relative_size", vm->trihedronRelative() ));
1516     vm->setInteractionStyle( resMgr->integerValue( "3DViewer", "navigation_mode", vm->interactionStyle() ) );
1517     vm->setZoomingStyle( resMgr->integerValue( "3DViewer", "zooming_mode", vm->zoomingStyle() ) );
1518     vm->enablePreselection( resMgr->booleanValue( "OCCViewer", "enable_preselection", vm->isPreselectionEnabled() ) );
1519     vm->enableSelection(    resMgr->booleanValue( "OCCViewer", "enable_selection",    vm->isSelectionEnabled() ) );
1520
1521     viewMgr->setViewModel( vm );// custom view model, which extends SALOME_View interface
1522     new LightApp_OCCSelector( (OCCViewer_Viewer*)viewMgr->getViewModel(), mySelMgr );
1523   }
1524 #endif
1525 #ifndef DISABLE_VTKVIEWER
1526 #ifndef DISABLE_SALOMEOBJECT
1527   if ( vmType == SVTK_Viewer::Type() )
1528 #else
1529   if ( vmType == VTKViewer_Viewer::Type() )
1530 #endif
1531   {
1532 #ifndef DISABLE_SALOMEOBJECT
1533     viewMgr = new SVTK_ViewManager( activeStudy(), desktop() );
1534     SVTK_Viewer* vm = dynamic_cast<SVTK_Viewer*>( viewMgr->getViewModel() );
1535     if( vm )
1536     {
1537       vm->setProjectionMode( resMgr->integerValue( "VTKViewer", "projection_mode", vm->projectionMode() ) );
1538       vm->setBackground( resMgr->backgroundValue( "VTKViewer", "background", vm->background() ) );
1539       vm->setTrihedronSize( resMgr->doubleValue( "3DViewer", "trihedron_size", vm->trihedronSize() ),
1540                             resMgr->booleanValue( "3DViewer", "relative_size", vm->trihedronRelative() ) );
1541       vm->setStaticTrihedronVisible( resMgr->booleanValue( "3DViewer", "show_static_trihedron", vm->isStaticTrihedronVisible() ) );
1542       vm->setInteractionStyle( resMgr->integerValue( "3DViewer", "navigation_mode", vm->interactionStyle() ) );
1543       vm->setZoomingStyle( resMgr->integerValue( "3DViewer", "zooming_mode", vm->zoomingStyle() ) );
1544       vm->setPreSelectionMode(resMgr->integerValue( "VTKViewer", "preselection", vm->preSelectionMode() ) );
1545       vm->enableSelection( resMgr->booleanValue( "VTKViewer", "enable_selection", vm->isSelectionEnabled() ) );
1546       vm->setIncrementalSpeed( resMgr->integerValue( "VTKViewer", "speed_value", vm->incrementalSpeed() ),
1547                                resMgr->integerValue( "VTKViewer", "speed_mode", vm->incrementalSpeedMode() ) );
1548       vm->setSpacemouseButtons( resMgr->integerValue( "VTKViewer", "spacemouse_func1_btn", vm->spacemouseBtn(1) ),
1549                                 resMgr->integerValue( "VTKViewer", "spacemouse_func2_btn", vm->spacemouseBtn(2) ),
1550                                 resMgr->integerValue( "VTKViewer", "spacemouse_func5_btn", vm->spacemouseBtn(3) ) );
1551       new LightApp_VTKSelector( vm, mySelMgr );
1552     }
1553 #else
1554     viewMgr = new VTKViewer_ViewManager( activeStudy(), desktop() );
1555     VTKViewer_Viewer* vm = dynamic_cast<VTKViewer_Viewer*>( viewMgr->getViewModel() );
1556     if ( vm )
1557       vm->setBackground( resMgr->backgroundValue( "VTKViewer", "background", vm->background() ) );
1558 #endif
1559   }
1560 #endif
1561
1562   if ( !viewMgr )
1563     return 0;
1564
1565   addViewManager( viewMgr );
1566   SUIT_ViewWindow* viewWin = viewMgr->createViewWindow();
1567
1568   if ( viewWin && desktop() ) {
1569     viewWin->resize( (int)( desktop()->width() * 0.6 ), (int)( desktop()->height() * 0.6 ) );
1570     viewWin->setDropDownButtons( resMgr->booleanValue( "viewers", "drop_down_buttons", true ) );
1571   }
1572
1573   return viewMgr;
1574 }
1575
1576 SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType, QWidget* w )
1577 {
1578   SUIT_ResourceMgr* resMgr = resourceMgr();
1579
1580   SUIT_ViewManager* vm = new SUIT_ViewManager( activeStudy(),
1581                                                desktop(),
1582                                                new LightApp_WgViewModel( vmType, w ) );
1583   vm->setTitle( QString( "%1: %M - viewer %V" ).arg( vmType ) );
1584
1585   addViewManager( vm );
1586   SUIT_ViewWindow* vw = vm->createViewWindow();
1587   if ( vw && desktop() ) {
1588     vw->resize( (int)( desktop()->width() * 0.6 ), (int)( desktop()->height() * 0.6 ) );
1589     vw->setDropDownButtons( resMgr->booleanValue( "viewers", "drop_down_buttons", true ) );
1590   }
1591
1592   if ( !vmType.isEmpty() && !myUserWmTypes.contains( vmType ) )
1593     myUserWmTypes << vmType;
1594
1595   return vm;
1596 }
1597
1598 /*!
1599   SLOT: Removes view manager from application
1600 */
1601 void LightApp_Application::onCloseView( SUIT_ViewManager* theVM )
1602 {
1603   removeViewManager( theVM );
1604 }
1605
1606 /*!
1607   Protected SLOT: On study created.
1608   \param theStudy - just created study
1609 */
1610 void LightApp_Application::onStudyCreated( SUIT_Study* theStudy )
1611 {
1612   SUIT_DataObject* aRoot = 0;
1613   if ( theStudy && theStudy->root() )
1614   {
1615     aRoot = theStudy->root();
1616     //aRoot->setName( tr( "DATA_MODELS" ) );
1617   }
1618
1619   getWindow( WT_ObjectBrowser );
1620
1621   loadDockWindowsState();
1622
1623   if ( objectBrowser() )
1624     objectBrowser()->setRoot( aRoot );
1625
1626   activateModule( defaultModule() );
1627
1628   if ( objectBrowser() )
1629     objectBrowser()->openLevels();
1630 }
1631
1632 /*!
1633   Protected SLOT: On study opened.
1634   \param theStudy - just opened  study
1635 */
1636 void LightApp_Application::onStudyOpened( SUIT_Study* theStudy )
1637 {
1638   SUIT_DataObject* aRoot = 0;
1639   if ( theStudy && theStudy->root() )
1640   {
1641     aRoot = theStudy->root();
1642     //aRoot->dump();
1643   }
1644
1645   getWindow( WT_ObjectBrowser );
1646
1647   loadDockWindowsState();
1648
1649   if ( objectBrowser() )
1650     objectBrowser()->setRoot( aRoot );
1651
1652   activateModule( defaultModule() );
1653
1654   if ( objectBrowser() )
1655     objectBrowser()->openLevels();
1656
1657   emit studyOpened();
1658 }
1659
1660 /*!Protected SLOT. On study saved.*/
1661 void LightApp_Application::onStudySaved( SUIT_Study* s )
1662 {
1663   QtxMRUAction* mru = ::qobject_cast<QtxMRUAction*>( action( MRUId ) );
1664   if ( mru && s )
1665       mru->insert( s->studyName() );
1666
1667   emit studySaved();
1668 }
1669
1670 /*!Protected SLOT. On study closed.*/
1671 void LightApp_Application::onStudyClosed( SUIT_Study* s )
1672 {
1673   // stop auto-save timer
1674   myAutoSaveTimer->stop();
1675
1676   // Bug 10396: clear selection
1677   mySelMgr->clearSelected();
1678
1679   // Bug 12944: emit signal only after clear selection
1680   emit studyClosed();
1681
1682   activateModule( "" );
1683 }
1684
1685 /*!Protected SLOT.On desktop activated.*/
1686 void LightApp_Application::onDesktopActivated()
1687 {
1688   CAM_Application::onDesktopActivated();
1689   LightApp_Module* aModule = dynamic_cast<LightApp_Module*>(activeModule());
1690   if(aModule)
1691     aModule->studyActivated();
1692 }
1693
1694 void LightApp_Application::studyOpened( SUIT_Study* s )
1695 {
1696   CAM_Application::studyOpened( s );
1697
1698   updateWindows();
1699   updateViewManagers();
1700 }
1701
1702 void LightApp_Application::studySaved( SUIT_Study* s )
1703 {
1704   CAM_Application::studyOpened( s );
1705   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
1706   if ( aResMgr && activeStudy() ) {
1707     int autoSaveInterval = aResMgr->integerValue( "Study", "auto_save_interval", 0 );
1708     if ( autoSaveInterval > 0 ) myAutoSaveTimer->start( autoSaveInterval*60000 );
1709   }
1710 }
1711
1712 void LightApp_Application::studyCreated( SUIT_Study* s )
1713 {
1714   CAM_Application::studyCreated( s );
1715
1716   updateWindows();
1717   updateViewManagers();
1718 }
1719
1720 /*!Gets file filter.
1721  *\retval QString "(*.bin)"
1722  */
1723 QString LightApp_Application::getFileFilter() const
1724 {
1725   //return "(*.bin)";
1726   // HDF persistence
1727   return "(*.hdf)";
1728 }
1729
1730 /*!
1731   Shows file dialog and return user selected file name
1732 */
1733 QString LightApp_Application::getFileName( bool open, const QString& initial, const QString& filters,
1734                                            const QString& caption, QWidget* parent )
1735 {
1736   if ( !parent )
1737     parent = desktop();
1738   QStringList fls = filters.split( ";;", QString::SkipEmptyParts );
1739   return SUIT_FileDlg::getFileName( parent, initial, fls, caption, open, true );
1740 }
1741
1742 /*! Gets directory*/
1743 QString LightApp_Application::getDirectory( const QString& initial, const QString& caption, QWidget* parent )
1744 {
1745   if ( !parent )
1746     parent = desktop();
1747   return SUIT_FileDlg::getExistingDirectory( parent, initial, caption, true );
1748 }
1749
1750 /*! Get open file names*/
1751 QStringList LightApp_Application::getOpenFileNames( const QString& initial, const QString& filters,
1752                                                     const QString& caption, QWidget* parent )
1753 {
1754   if ( !parent )
1755     parent = desktop();
1756   QStringList fls = filters.split( ";;", QString::SkipEmptyParts );
1757   return SUIT_FileDlg::getOpenFileNames( parent, initial, fls, caption, true );
1758 }
1759
1760 /*!Private SLOT. Update object browser.*/
1761 void LightApp_Application::onRefresh()
1762 {
1763   updateObjectBrowser( true );
1764 }
1765
1766 /*!Private SLOT. Support drag-and-drop operation.*/
1767 void LightApp_Application::onDropped( const QList<SUIT_DataObject*>& objects, SUIT_DataObject* parent, int row, Qt::DropAction action )
1768 {
1769   LightApp_DataObject* parentObj = dynamic_cast<LightApp_DataObject*>( parent );
1770   if ( !parentObj )
1771     return;
1772
1773   LightApp_Module* aModule = dynamic_cast<LightApp_Module*>( parentObj->module() );
1774   if ( aModule )
1775     aModule->dropObjects( objects, parentObj, row, action );
1776 }
1777
1778 /*!Private SLOT. On preferences.*/
1779 void LightApp_Application::onPreferences()
1780 {
1781   showPreferences( activeModule() ? activeModule()->moduleName() : tr( "PREF_CATEGORY_SALOME" ) );
1782 }
1783
1784 /*!Private SLOT. On preferences.*/
1785 void LightApp_Application::showPreferences( const QString& itemText )
1786 {
1787   QApplication::setOverrideCursor( Qt::WaitCursor );
1788
1789   LightApp_PreferencesDlg* prefDlg = new LightApp_PreferencesDlg( preferences( true ), desktop());
1790
1791   QApplication::restoreOverrideCursor();
1792
1793   if ( !prefDlg )
1794     return;
1795
1796   preferences()->activateItem( itemText );
1797
1798   if ( ( prefDlg->exec() == QDialog::Accepted || prefDlg->isSaved() ) &&  resourceMgr() )
1799   {
1800     if ( desktop() )
1801       resourceMgr()->setValue( "desktop", "geometry", desktop()->storeGeometry() );
1802     resourceMgr()->save();
1803
1804     // Update shortcuts
1805     shortcutMgr()->updateShortcuts();
1806   }
1807
1808   delete prefDlg;
1809 }
1810
1811 /*!Protected SLOT. On preferences changed.*/
1812 void LightApp_Application::onPreferenceChanged( QString& modName, QString& section, QString& param )
1813 {
1814   LightApp_Module* sMod = 0;
1815   CAM_Module* mod = module( modName );
1816   if ( mod && mod->inherits( "LightApp_Module" ) )
1817     sMod = (LightApp_Module*)mod;
1818
1819   if ( sMod )
1820     sMod->preferencesChanged( section, param );
1821   else
1822     preferencesChanged( section, param );
1823   // emit signal to allow additional preferences changing processing
1824   emit preferenceChanged( modName, section, param );
1825 }
1826
1827 /*!Remove all windows from study.*/
1828 void LightApp_Application::beforeCloseDoc( SUIT_Study* s )
1829 {
1830   if ( SUIT_DataBrowser* ob = objectBrowser() )
1831     ob->setModel(0);
1832
1833   CAM_Application::beforeCloseDoc( s );
1834 }
1835
1836 /*!Update actions.*/
1837 void LightApp_Application::updateActions()
1838 {
1839   updateCommandsStatus();
1840 }
1841
1842 /*!
1843   Creates new study
1844 */
1845 SUIT_Study* LightApp_Application::createNewStudy()
1846 {
1847   LightApp_Application::lastStudyId++;
1848
1849   LightApp_Study* aStudy = new LightApp_Study( this );
1850
1851   // Set up processing of major study-related events
1852   connect( aStudy, SIGNAL( created( SUIT_Study* ) ), this, SLOT( onStudyCreated( SUIT_Study* ) ) );
1853   connect( aStudy, SIGNAL( opened ( SUIT_Study* ) ), this, SLOT( onStudyOpened ( SUIT_Study* ) ) );
1854   connect( aStudy, SIGNAL( saved  ( SUIT_Study* ) ), this, SLOT( onStudySaved  ( SUIT_Study* ) ) );
1855   connect( aStudy, SIGNAL( closed ( SUIT_Study* ) ), this, SLOT( onStudyClosed ( SUIT_Study* ) ) );
1856
1857   return aStudy;
1858 }
1859
1860 /*!
1861   Creates window by flag.
1862   \param flag - identificator of window type
1863 */
1864 QWidget* LightApp_Application::createWindow( const int flag )
1865 {
1866   QWidget* wid = 0;
1867
1868   SUIT_ResourceMgr* resMgr = resourceMgr();
1869
1870   if ( flag == WT_ObjectBrowser )
1871   {
1872     SUIT_DataBrowser* ob = new SUIT_DataBrowser( new LightApp_DataObject(), desktop() );
1873     ob->setSortMenuEnabled( true );
1874     ob->setAutoUpdate( true );
1875     if ( resMgr->hasValue( "ObjectBrowser", "auto_hide_search_tool" ) )
1876       ob->searchTool()->enableAutoHide( resMgr->booleanValue( "ObjectBrowser", "auto_hide_search_tool" ) );
1877
1878     //ob->setAutoOpenLevel( 1 ); // commented by ASV as a fix to bug IPAL10107
1879     ob->setWindowTitle( tr( "OBJECT_BROWSER" ) );
1880     connect( ob, SIGNAL( requestUpdate() ), this, SLOT( onRefresh() ) );
1881
1882     QString EntryCol = QObject::tr( "ENTRY_COLUMN" );
1883     SUIT_AbstractModel* treeModel = dynamic_cast<SUIT_AbstractModel*>( ob->model() );
1884     treeModel->setSearcher( this );
1885     treeModel->registerColumn( 0, EntryCol, LightApp_DataObject::EntryId );
1886     treeModel->setAppropriate( EntryCol, Qtx::Toggled );
1887
1888     // Mantis issue 0020136: Drag&Drop in OB
1889     SUIT_ProxyModel* proxyModel = dynamic_cast<SUIT_ProxyModel*>(treeModel);
1890     if ( proxyModel ) {
1891       connect( proxyModel, SIGNAL( dropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ),
1892                this,       SLOT( onDropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ) );
1893     }
1894
1895     // temporary commented
1896     /*
1897     OB_ListView* ob_list = dynamic_cast<OB_ListView*>( const_cast<QListView*>( ob->listView() ) );
1898     if( ob_list )
1899       ob_list->setColumnMaxWidth( 0, desktop()->width()/4 );
1900     */
1901
1902     // Create OBSelector
1903     new LightApp_OBSelector( ob, mySelMgr );
1904
1905     ob->treeView()->header()->setResizeMode(SUIT_DataObject::VisibilityId, QHeaderView::Fixed);
1906     ob->treeView()->header()->moveSection(SUIT_DataObject::NameId,SUIT_DataObject::VisibilityId);
1907     ob->treeView()->setColumnWidth(SUIT_DataObject::VisibilityId, VISIBILITY_COLUMN_WIDTH);
1908     ob->setProperty( "shortcut", QKeySequence( "Alt+Shift+O" ) );
1909     wid = ob;
1910     ob->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
1911   }
1912 #ifndef DISABLE_PYCONSOLE
1913   else  if ( flag == WT_PyConsole )
1914   {
1915     PyConsole_Console* pyCons = new PyConsole_EnhConsole( desktop(),new LightApp_PyInterp());
1916     pyCons->setWindowTitle( tr( "PYTHON_CONSOLE" ) );
1917     pyCons->setFont(resourceMgr()->fontValue( "PyConsole", "font" ));
1918     pyCons->setIsShowBanner(resourceMgr()->booleanValue( "PyConsole", "show_banner", true ));
1919     pyCons->setProperty( "shortcut", QKeySequence( "Alt+Shift+P" ) );
1920
1921     wid = pyCons;
1922     pyCons->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
1923   }
1924 #endif
1925   else if ( flag == WT_LogWindow )
1926   {
1927     LogWindow* logWin = new LogWindow( desktop() );
1928     logWin->setWindowTitle( tr( "LOG_WINDOW" ) );
1929     logWin->setProperty( "shortcut", QKeySequence( "Alt+Shift+L" ) );
1930     wid = logWin;
1931     logWin->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
1932   }
1933   return wid;
1934 }
1935
1936 /*!
1937   \return default windows( Object Browser, Python Console )
1938   Adds to map \a aMap.
1939  */
1940 void LightApp_Application::defaultWindows( QMap<int, int>& aMap ) const
1941 {
1942   aMap.insert( WT_ObjectBrowser, Qt::LeftDockWidgetArea );
1943 #ifndef DISABLE_PYCONSOLE
1944   aMap.insert( WT_PyConsole, Qt::BottomDockWidgetArea );
1945 #endif
1946   //  aMap.insert( WT_LogWindow, Qt::DockBottom );
1947 }
1948
1949 /*!Default view managers*/
1950 void LightApp_Application::defaultViewManagers( QStringList& ) const
1951 {
1952   /*!Do nothing.*/
1953 }
1954
1955 /*!
1956   \return preferences.
1957   Create preferences, if \a crt = true.
1958 */
1959 LightApp_Preferences* LightApp_Application::preferences( const bool crt ) const
1960 {
1961   if ( myPrefs )
1962     return myPrefs;
1963
1964   LightApp_Application* that = (LightApp_Application*)this;
1965
1966   bool toCreate = !_prefs_ && crt;
1967   if ( toCreate )
1968   {
1969     _prefs_ = new LightApp_Preferences( resourceMgr() );
1970     that->createPreferences( _prefs_ );
1971   }
1972
1973   that->myPrefs = _prefs_;
1974
1975   connect( myPrefs, SIGNAL( preferenceChanged( QString&, QString&, QString& ) ),
1976            this, SLOT( onPreferenceChanged( QString&, QString&, QString& ) ) );
1977
1978   if ( !crt )
1979     return myPrefs;
1980
1981   SUIT_ResourceMgr* resMgr = resourceMgr();
1982
1983   QList<SUIT_Application*> appList = SUIT_Session::session()->applications();
1984   for ( QList<SUIT_Application*>::iterator appIt = appList.begin(); appIt != appList.end(); ++appIt )
1985   {
1986     LightApp_Application* app = ::qobject_cast<LightApp_Application*>( *appIt );
1987     if ( !app )
1988       continue;
1989
1990     QStringList modNameList;
1991     app->modules( modNameList, false );
1992
1993     QMap<QString, QString> iconMap;
1994     app->moduleIconNames( iconMap );
1995
1996     for ( QStringList::const_iterator it = modNameList.begin(); it != modNameList.end(); ++it )
1997     {
1998       if ( !app->isLibExists( *it ) || _prefs_->hasModule( *it ) )
1999         continue;
2000
2001       int modId = _prefs_->addPreference( *it );
2002       if ( iconMap.contains( *it ) )
2003         _prefs_->setItemIcon( modId, Qtx::scaleIcon( resMgr->loadPixmap( moduleName( *it ), iconMap[*it], false ), 20 ) );
2004     }
2005
2006     ModuleList modList;
2007     app->modules( modList );
2008     QListIterator<CAM_Module*> itr( modList );
2009     while ( itr.hasNext() )
2010     {
2011       LightApp_Module* mod = 0;
2012
2013       CAM_Module* anItem = itr.next();
2014       if ( anItem->inherits( "LightApp_Module" ) )
2015         mod = (LightApp_Module*)anItem;
2016
2017       if ( mod && !_prefs_->hasModule( mod->moduleName() ) )
2018       {
2019         _prefs_->addPreference( mod->moduleName() );
2020         mod->createPreferences();
2021         that->emptyPreferences( mod->moduleName() );
2022       }
2023     }
2024   }
2025   _prefs_->setItemProperty( "info", tr( "PREFERENCES_NOT_LOADED" ) );
2026
2027   return myPrefs;
2028 }
2029
2030 /*!
2031   Adds new module to application
2032 */
2033 void LightApp_Application::moduleAdded( CAM_Module* mod )
2034 {
2035   CAM_Application::moduleAdded( mod );
2036
2037   LightApp_Module* lightMod = 0;
2038   if ( mod && mod->inherits( "LightApp_Module" ) )
2039     lightMod = (LightApp_Module*)mod;
2040
2041   if ( myPrefs && lightMod && !myPrefs->hasModule( lightMod->moduleName() ))
2042   {
2043     myPrefs->addPreference( mod->moduleName() );
2044     lightMod->createPreferences();
2045     emptyPreferences( mod->moduleName() );
2046   }
2047 }
2048
2049 void LightApp_Application::emptyPreferences( const QString& modName )
2050 {
2051   QtxPreferenceItem* item = myPrefs->findItem( modName, true );
2052   if ( !item || !item->isEmpty() )
2053     return;
2054
2055   //  printf( "---------------------> Modify for empty module.\n" );
2056
2057   QtxPagePrefFrameItem* frm = new QtxPagePrefFrameItem( item->title(), item->parentItem() );
2058   frm->setIcon( item->icon() );
2059   frm->setStretch( false );
2060   item->parentItem()->insertItem( frm, item );
2061   new QtxPagePrefLabelItem( Qt::AlignCenter, tr( "PREFERENCES_NOT_SUPPORTED" ).arg( modName ), frm );
2062   delete item;
2063 }
2064
2065 /*!
2066   Create preferences
2067 */
2068 void LightApp_Application::createPreferences( LightApp_Preferences* pref )
2069 {
2070   if ( !pref )
2071     return;
2072
2073   QStringList     aValuesList;
2074   QList<QVariant> anIndicesList;
2075   QIntList        idList;
2076   QIntList        txtList;
2077
2078   // . Top-level "SALOME" preferences group <<start>>
2079   int salomeCat = pref->addPreference( tr( "PREF_CATEGORY_SALOME" ) );
2080   pref->setItemIcon( salomeCat, Qtx::scaleIcon( resourceMgr()->loadPixmap( "LightApp", tr( "APP_DEFAULT_ICO" ), false ), 20 ) );
2081
2082   // .. "General" preferences tab <<start>>
2083   int genTab = pref->addPreference( tr( "PREF_TAB_GENERAL" ), salomeCat );
2084
2085   // ... "Language" group <<start>>
2086   int langGroup = pref->addPreference( tr( "PREF_GROUP_LANGUAGE" ), genTab );
2087   pref->setItemProperty( "columns", 2, langGroup );
2088   // .... -> application language
2089   int curLang = pref->addPreference( tr( "PREF_CURRENT_LANGUAGE" ), langGroup,
2090                                           LightApp_Preferences::Selector, "language", "language" );
2091   QStringList aLangs = SUIT_Session::session()->resourceMgr()->stringValue( "language", "languages", "en" ).split( "," );
2092   QList<QVariant> aIcons;
2093   foreach ( QString aLang, aLangs ) {
2094     aIcons << QPixmap( QString( ":/images/%1" ).arg( aLang ) );
2095   }
2096   pref->setItemProperty( "strings", aLangs, curLang );
2097   pref->setItemProperty( "icons",   aIcons, curLang );
2098   // ... "Language" group <<end>>
2099
2100   // ... "Look and feel" group <<start>>
2101   int lookGroup = pref->addPreference( tr( "PREF_GROUP_LOOK_AND_FEEL" ), genTab );
2102   pref->setItemProperty( "columns", 2, lookGroup );
2103   // .... -> show splash-screen
2104   pref->addPreference( tr( "PREF_SHOW_SPLASH" ), lookGroup, LightApp_Preferences::Bool, "launch", "splash" );
2105   // .... -> opaque resize
2106   pref->addPreference( tr( "PREF_OPAQUE_RESIZE" ), lookGroup, LightApp_Preferences::Bool, "desktop", "opaque_resize" );
2107   // .... -> drop-down buttons 
2108   pref->addPreference( tr( "PREF_DROP_DOWN_BUTTONS" ), lookGroup, LightApp_Preferences::Bool, "viewers", "drop_down_buttons" );
2109   // ... "Look and feel" group <<end>>
2110
2111   // ... "Study properties" group <<start>>
2112   int studyGroup = pref->addPreference( tr( "PREF_GROUP_STUDY" ), genTab );
2113   pref->setItemProperty( "columns", 2, studyGroup );
2114   // .... -> multi-file save
2115   pref->addPreference( tr( "PREF_MULTI_FILE" ), studyGroup, LightApp_Preferences::Bool, "Study", "multi_file" );
2116   // .... -> ascii save mode
2117   pref->addPreference( tr( "PREF_ASCII_FILE" ), studyGroup, LightApp_Preferences::Bool, "Study", "ascii_file" );
2118   // .... -> store windows geometry
2119   pref->addPreference( tr( "PREF_STORE_POS" ),  studyGroup, LightApp_Preferences::Bool, "Study", "store_positions" );
2120   pref->addPreference( "", studyGroup, LightApp_Preferences::Space );
2121   pref->addPreference( tr( "PREF_STORE_TOOL_POS" ),  studyGroup, LightApp_Preferences::Bool, "Study", "store_tool_positions" );
2122   // .... -> auto-save
2123   int autoSaveInterval = pref->addPreference( tr( "PREF_AUTO_SAVE" ),  studyGroup,
2124                                               LightApp_Preferences::IntSpin, "Study", "auto_save_interval" );
2125   pref->setItemProperty( "min",        0, autoSaveInterval );
2126   pref->setItemProperty( "max",     1440, autoSaveInterval );
2127   pref->setItemProperty( "special", tr( "PREF_AUTO_SAVE_DISABLED" ), autoSaveInterval );
2128   // ... "Study properties" group <<end>>
2129
2130   // ... "Help browser" group <<start>>
2131   int extgroup = pref->addPreference( tr( "PREF_GROUP_EXT_BROWSER" ), genTab, LightApp_Preferences::Auto, "ExternalBrowser", "use_external_browser");
2132 #ifdef WIN32
2133   QString platform = "winapplication";
2134 #else
2135   QString platform = "application";
2136 #endif
2137   // .... -> browser application
2138   int apppref = pref->addPreference( tr( "PREF_APP" ), extgroup, LightApp_Preferences::File, "ExternalBrowser", platform );
2139   pref->setItemProperty( "mode", Qtx::PT_OpenFile, apppref );
2140   // .... -> browser parameters
2141   pref->addPreference( tr( "PREF_PARAM" ), extgroup, LightApp_Preferences::String, "ExternalBrowser", "parameters" );
2142   // ... "Help browser" group <<end>>
2143
2144   // ... "Python console properties" group <<start>>
2145   int pythonConsoleGroup = pref->addPreference( tr( "PREF_GROUP_PY_CONSOLE" ), genTab );
2146   // .... -> font
2147   pref->addPreference( tr( "PREF_FONT" ), pythonConsoleGroup, LightApp_Preferences::Font, "PyConsole", "font" );
2148   // .... -> show banner
2149   pref->addPreference( tr( "PREF_SHOW_BANNER" ), pythonConsoleGroup, LightApp_Preferences::Bool, "PyConsole", "show_banner" );
2150   // ... "Python console properties" group <<end>>
2151
2152   // ... "MRU" preferences group <<start>>
2153   int mruGroup = pref->addPreference( tr( "PREF_GROUP_MRU" ), genTab, LightApp_Preferences::Auto, "MRU", "show_mru" );
2154   pref->setItemProperty( "columns", 4, mruGroup );
2155   // number of MRU items
2156   int mruVisCount = pref->addPreference( tr( "PREF_MRU_VISIBLE_COUNT" ), mruGroup, LightApp_Preferences::IntSpin,
2157                                          "MRU", "visible_count" );
2158   pref->setItemProperty( "min", 0,   mruVisCount );
2159   pref->setItemProperty( "max", 100, mruVisCount );
2160   // MRU links type
2161   int mruLinkType = pref->addPreference( tr( "PREF_MRU_LINK_TYPE" ), mruGroup, LightApp_Preferences::Selector,
2162                                          "MRU", "link_type" );
2163   aValuesList.clear();
2164   anIndicesList.clear();
2165   aValuesList   << tr("PREF_MRU_LINK_AUTO") << tr("PREF_MRU_LINK_SHORT") << tr("PREF_MRU_LINK_FULL");
2166   anIndicesList << 0                        << 1                         << 2                       ;
2167   pref->setItemProperty( "strings", aValuesList,   mruLinkType );
2168   pref->setItemProperty( "indexes", anIndicesList, mruLinkType );
2169   // ... "MRU" preferences group <<end>>
2170   // .. "General" preferences tab <<end>>
2171
2172   // .. "3D viewer" group <<start>>
2173   int Viewer3DGroup = pref->addPreference( tr( "PREF_GROUP_3DVIEWER" ), salomeCat );
2174   // ... -> navigation mode
2175   int vtkStyleMode = pref->addPreference( tr( "PREF_NAVIGATION" ), Viewer3DGroup,
2176                                           LightApp_Preferences::Selector, "3DViewer", "navigation_mode" );
2177   aValuesList.clear();
2178   anIndicesList.clear();
2179   aValuesList   << tr("PREF_STANDARD_STYLE") << tr("PREF_KEYFREE_STYLE");
2180   anIndicesList << 0                         << 1;
2181   pref->setItemProperty( "strings", aValuesList,   vtkStyleMode );
2182   pref->setItemProperty( "indexes", anIndicesList, vtkStyleMode );
2183   // ... -> zooming mode
2184   #if OCC_VERSION_LARGE > 0x0603000A // available only with OCC-6.3-sp11 and higher version
2185     int occZoomingStyleMode = pref->addPreference( tr( "PREF_ZOOMING" ), Viewer3DGroup,
2186                                                    LightApp_Preferences::Selector, "3DViewer", "zooming_mode" );
2187     aValuesList.clear();
2188     anIndicesList.clear();
2189     aValuesList   << tr("PREF_ZOOMING_AT_CENTER") << tr("PREF_ZOOMING_AT_CURSOR");
2190     anIndicesList << 0                            << 1;
2191     pref->setItemProperty( "strings", aValuesList,   occZoomingStyleMode );
2192     pref->setItemProperty( "indexes", anIndicesList, occZoomingStyleMode );
2193   #endif
2194   // ... "Trihedron" group <<start>>
2195   int occTriGroup = pref->addPreference( tr( "PREF_TRIHEDRON" ), Viewer3DGroup );
2196   pref->setItemProperty( "columns", 2, occTriGroup );
2197   // .... -> trihedron size
2198   int occTS = pref->addPreference( tr( "PREF_TRIHEDRON_SIZE" ), occTriGroup,
2199                                    LightApp_Preferences::DblSpin, "3DViewer", "trihedron_size" );
2200   pref->setItemProperty( "min", 1.0E-06, occTS );
2201   pref->setItemProperty( "max", 1000, occTS );
2202   // .... -> relative size of trihedron
2203   pref->addPreference( tr( "PREF_RELATIVE_SIZE" ), occTriGroup, LightApp_Preferences::Bool, "3DViewer", "relative_size" );
2204   // .... -> show static trihedron
2205   pref->addPreference( tr( "PREF_SHOW_STATIC_TRIHEDRON" ), occTriGroup, LightApp_Preferences::Bool, "3DViewer", "show_static_trihedron" );
2206   // ... "Trihedron" group <<end>>
2207   // .. "3D viewer" group <<end>>
2208
2209   // .. "OCC viewer" group <<start>>
2210   int occGroup = pref->addPreference( tr( "PREF_GROUP_OCCVIEWER" ), salomeCat );
2211
2212   // ... "Background" group <<start>>
2213   int bgGroup = pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), occGroup );
2214   //  pref->setItemProperty( "columns", 2, bgGroup );
2215   aValuesList.clear();
2216   anIndicesList.clear();
2217   txtList.clear();
2218   QString formats = OCCViewer_Viewer::backgroundData( aValuesList, idList, txtList );
2219   foreach( int gid, idList ) anIndicesList << gid;
2220   // .... -> 3D viewer background
2221   int bgId = pref->addPreference( tr( "PREF_3DVIEWER_BACKGROUND" ), bgGroup,
2222                                   LightApp_Preferences::Background, "OCCViewer", "background" );
2223   pref->setItemProperty( "gradient_names", aValuesList, bgId );
2224   pref->setItemProperty( "gradient_ids", anIndicesList, bgId );
2225   pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId );
2226   pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId );
2227   pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId );
2228   pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId );
2229   pref->setItemProperty( "custom_enabled", false, bgId );
2230   pref->setItemProperty( "image_formats", formats, bgId );
2231   // .... -> XZ viewer background
2232   bgId = pref->addPreference( tr( "PREF_XZVIEWER_BACKGROUND" ), bgGroup,
2233                               LightApp_Preferences::Background, "OCCViewer", "xz_background" );
2234   pref->setItemProperty( "gradient_names", aValuesList, bgId );
2235   pref->setItemProperty( "gradient_ids", anIndicesList, bgId );
2236   pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId );
2237   pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId );
2238   pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId );
2239   pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId );
2240   pref->setItemProperty( "custom_enabled", false, bgId );
2241   pref->setItemProperty( "image_formats", formats, bgId );
2242   // .... -> YZ viewer background
2243   bgId = pref->addPreference( tr( "PREF_YZVIEWER_BACKGROUND" ), bgGroup,
2244                               LightApp_Preferences::Background, "OCCViewer", "yz_background" );
2245   pref->setItemProperty( "gradient_names", aValuesList, bgId );
2246   pref->setItemProperty( "gradient_ids", anIndicesList, bgId );
2247   pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId );
2248   pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId );
2249   pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId );
2250   pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId );
2251   pref->setItemProperty( "custom_enabled", false, bgId );
2252   pref->setItemProperty( "image_formats", formats, bgId );
2253   // .... -> XY viewer background
2254   bgId = pref->addPreference( tr( "PREF_XYVIEWER_BACKGROUND" ), bgGroup,
2255                               LightApp_Preferences::Background, "OCCViewer", "xy_background" );
2256   pref->setItemProperty( "gradient_names", aValuesList, bgId );
2257   pref->setItemProperty( "gradient_ids", anIndicesList, bgId );
2258   pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId );
2259   pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId );
2260   pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId );
2261   pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId );
2262   pref->setItemProperty( "custom_enabled", false, bgId );
2263   pref->setItemProperty( "image_formats", formats, bgId );
2264   // ... "Background" group <<end>>
2265
2266
2267   // ... "Selection" group <<start>>
2268   int occSelectionGroup = pref->addPreference( tr( "PREF_GROUP_SELECTION" ), occGroup );
2269   pref->setItemProperty( "columns", 2, occSelectionGroup );
2270   // .... -> enable preselection
2271   pref->addPreference( tr( "PREF_ENABLE_PRESELECTION" ), occSelectionGroup, 
2272                        LightApp_Preferences::Bool, "OCCViewer", "enable_preselection" );
2273   // .... -> enable selection
2274   pref->addPreference( tr( "PREF_ENABLE_SELECTION" ), occSelectionGroup, 
2275                        LightApp_Preferences::Bool, "OCCViewer", "enable_selection" );
2276   // ... "Selection" group <<end>>
2277
2278   // ... -> empty frame (for layout) <<start>>
2279   int occGen = pref->addPreference( "", occGroup, LightApp_Preferences::Frame );
2280   pref->setItemProperty( "margin",  0, occGen );
2281   pref->setItemProperty( "columns", 2, occGen );
2282   // ... -> empty frame (for layout) <<end>>
2283   // .. "OCC viewer" group <<end>>
2284
2285   // .. "VTK viewer" group <<start>>
2286   int vtkGroup = pref->addPreference( tr( "PREF_GROUP_VTKVIEWER" ), salomeCat ); //viewTab
2287
2288   // ... -> empty frame (for layout) <<start>>
2289   int vtkGen = pref->addPreference( "", vtkGroup, LightApp_Preferences::Frame );
2290   //pref->setItemProperty( "columns", 2, vtkGen );
2291   // .... -> projection mode
2292   int vtkProjMode = pref->addPreference( tr( "PREF_PROJECTION_MODE" ), vtkGen,
2293                                          LightApp_Preferences::Selector, "VTKViewer", "projection_mode" );
2294   aValuesList.clear();
2295   anIndicesList.clear();
2296   aValuesList   << tr("PREF_ORTHOGRAPHIC") << tr("PREF_PERSPECTIVE");
2297   anIndicesList << 0                       << 1;
2298   pref->setItemProperty( "strings", aValuesList,   vtkProjMode );
2299   pref->setItemProperty( "indexes", anIndicesList, vtkProjMode );
2300   // .... -> background
2301   aValuesList.clear();
2302   anIndicesList.clear();
2303   txtList.clear();
2304   formats = SVTK_Viewer::backgroundData( aValuesList, idList, txtList );
2305   foreach( int gid, idList ) anIndicesList << gid;
2306   bgId = pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), vtkGen,
2307                               LightApp_Preferences::Background, "VTKViewer", "background" );
2308   pref->setItemProperty( "gradient_names", aValuesList, bgId );
2309   pref->setItemProperty( "gradient_ids", anIndicesList, bgId );
2310   pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId );
2311   pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId );
2312   pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId );
2313   pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId );
2314   pref->setItemProperty( "custom_enabled", false, bgId );
2315   pref->setItemProperty( "image_formats", formats, bgId );
2316   // .... -> speed increment
2317   int vtkSpeed = pref->addPreference( tr( "PREF_INCREMENTAL_SPEED" ), vtkGen,
2318                                       LightApp_Preferences::IntSpin, "VTKViewer", "speed_value" );
2319   pref->setItemProperty( "min", 1, vtkSpeed );
2320   pref->setItemProperty( "max", 1000, vtkSpeed );
2321   // .... -> speed mode
2322   int vtkSpeedMode = pref->addPreference( tr( "PREF_INCREMENTAL_SPEED_MODE" ), vtkGen,
2323                                           LightApp_Preferences::Selector, "VTKViewer", "speed_mode" );
2324   aValuesList.clear();
2325   anIndicesList.clear();
2326   aValuesList   << tr("PREF_ARITHMETIC") << tr("PREF_GEOMETRICAL");
2327   anIndicesList << 0                     << 1;
2328   pref->setItemProperty( "strings", aValuesList,   vtkSpeedMode );
2329   pref->setItemProperty( "indexes", anIndicesList, vtkSpeedMode );
2330
2331   // ... "Selection" group <<start>>
2332   int vtkSelectionGroup = pref->addPreference( tr( "PREF_GROUP_SELECTION" ), vtkGroup );
2333   pref->setItemProperty( "columns", 2, vtkSelectionGroup );
2334   // .... -> preselection
2335   int vtkPreselection = pref->addPreference( tr( "PREF_PRESELECTION" ),  vtkSelectionGroup, 
2336                                              LightApp_Preferences::Selector, "VTKViewer", "preselection" );
2337   aValuesList.clear();
2338   anIndicesList.clear();
2339   aValuesList   << tr("PREF_PRESELECTION_STANDARD") << tr("PREF_PRESELECTION_DYNAMIC") << tr("PREF_PRESELECTION_DISABLED");
2340   anIndicesList << 0 << 1 << 2;
2341   pref->setItemProperty( "strings", aValuesList,   vtkPreselection );
2342   pref->setItemProperty( "indexes", anIndicesList, vtkPreselection );
2343   // .... -> enable selection
2344   pref->addPreference( tr( "PREF_ENABLE_SELECTION" ), vtkSelectionGroup, LightApp_Preferences::Bool, "VTKViewer", "enable_selection" );
2345   // ... "Selection" group <<end>>
2346
2347   // ... -> empty frame (for layout) <<end>>
2348
2349   // ... space mouse sub-group <<start>>
2350   int vtkSM = pref->addPreference( tr( "PREF_FRAME_SPACEMOUSE" ), vtkGroup, LightApp_Preferences::GroupBox );
2351   //pref->setItemProperty( "columns", 2, vtkSM );
2352   // .... -> decrease speed increment
2353   int spacemousePref1 = pref->addPreference( tr( "PREF_SPACEMOUSE_FUNC_1" ), vtkSM,
2354                                              LightApp_Preferences::Selector, "VTKViewer",
2355                                              "spacemouse_func1_btn" );
2356   // .... -> increase speed increment
2357   int spacemousePref2 = pref->addPreference( tr( "PREF_SPACEMOUSE_FUNC_2" ), vtkSM,
2358                                              LightApp_Preferences::Selector, "VTKViewer",
2359                                              "spacemouse_func2_btn" );
2360   // .... -> dominant / combined switch  
2361   int spacemousePref3 = pref->addPreference( tr( "PREF_SPACEMOUSE_FUNC_3" ), vtkSM,
2362                                              LightApp_Preferences::Selector, "VTKViewer",
2363                                              "spacemouse_func5_btn" ); //
2364   aValuesList.clear();
2365   anIndicesList.clear();
2366   aValuesList << tr( "PREF_SPACEMOUSE_BTN_1" )  << tr( "PREF_SPACEMOUSE_BTN_2" ) << tr( "PREF_SPACEMOUSE_BTN_3" );
2367   aValuesList << tr( "PREF_SPACEMOUSE_BTN_4" )  << tr( "PREF_SPACEMOUSE_BTN_5" ) << tr( "PREF_SPACEMOUSE_BTN_6" );
2368   aValuesList << tr( "PREF_SPACEMOUSE_BTN_7" )  << tr( "PREF_SPACEMOUSE_BTN_8" ) << tr( "PREF_SPACEMOUSE_BTN_*" );
2369   aValuesList << tr( "PREF_SPACEMOUSE_BTN_10" ) << tr( "PREF_SPACEMOUSE_BTN_11" );
2370   anIndicesList << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10 << 11;
2371   pref->setItemProperty( "strings", aValuesList,   spacemousePref1 );
2372   pref->setItemProperty( "indexes", anIndicesList, spacemousePref1 );
2373   pref->setItemProperty( "strings", aValuesList,   spacemousePref2 );
2374   pref->setItemProperty( "indexes", anIndicesList, spacemousePref2 );
2375   pref->setItemProperty( "strings", aValuesList,   spacemousePref3 );
2376   pref->setItemProperty( "indexes", anIndicesList, spacemousePref3 );
2377   // ... space mouse sub-group <<end>>
2378
2379   // ... avi recording sub-group <<start>>
2380   int vtkRec = pref->addPreference( tr( "PREF_FRAME_RECORDING" ), vtkGroup, LightApp_Preferences::GroupBox );
2381   pref->setItemProperty( "columns", 2, vtkRec );
2382   // .... -> recording mode
2383   int modePref = pref->addPreference( tr( "PREF_RECORDING_MODE" ), vtkRec,
2384                                       LightApp_Preferences::Selector, "VTKViewer", "recorder_mode" );
2385   aValuesList.clear();
2386   anIndicesList.clear();
2387   aValuesList   << tr( "PREF_SKIPPED_FRAMES" ) << tr( "PREF_ALL_DISLPAYED_FRAMES" );
2388   anIndicesList << 0                           << 1;
2389   pref->setItemProperty( "strings", aValuesList,   modePref );
2390   pref->setItemProperty( "indexes", anIndicesList, modePref );
2391   // .... -> fps
2392   int fpsPref = pref->addPreference( tr( "PREF_FPS" ), vtkRec,
2393                                      LightApp_Preferences::DblSpin, "VTKViewer", "recorder_fps" );
2394   pref->setItemProperty( "min", 0.1, fpsPref );
2395   pref->setItemProperty( "max", 100, fpsPref );
2396   // .... -> quality
2397   int qualityPref = pref->addPreference( tr( "PREF_QUALITY" ), vtkRec,
2398                                          LightApp_Preferences::IntSpin, "VTKViewer", "recorder_quality" );
2399   pref->setItemProperty( "min", 1, qualityPref );
2400   pref->setItemProperty( "max", 100, qualityPref );
2401   // .... -> progressive mode
2402   pref->addPreference( tr( "PREF_PROGRESSIVE" ), vtkRec,
2403                        LightApp_Preferences::Bool, "VTKViewer", "recorder_progressive" );
2404   // ... avi recording sub-group <<end>>
2405
2406   // ... group names sub-group <<start>>
2407   int vtkGN = pref->addPreference( tr( "PREF_FRAME_GROUP_NAMES" ), vtkGroup,
2408                                    LightApp_Preferences::GroupBox, "VTKViewer", "show_group_names" );
2409   pref->setItemProperty( "columns", 2, vtkGN );
2410   // .... -> text color
2411   pref->addPreference( tr(  "PREF_GROUP_NAMES_TEXT_COLOR" ), vtkGN,
2412                        LightApp_Preferences::Color, "VTKViewer", "group_names_text_color" );
2413   // .... -> transparency
2414   int transPref = pref->addPreference( tr( "PREF_GROUP_NAMES_TRANSPARENCY" ), vtkGN,
2415                                        LightApp_Preferences::DblSpin, "VTKViewer", "group_names_transparency" );
2416   pref->setItemProperty( "min", 0.0, transPref );
2417   pref->setItemProperty( "max", 1.0, transPref );
2418   pref->setItemProperty( "step", 0.1, transPref );
2419   // ... -> group names sub-group <<end>>
2420   // .. "VTK viewer" group <<end>>
2421
2422   // .. "Plot2d viewer" group <<start>>
2423   int plot2dGroup = pref->addPreference( tr( "PREF_GROUP_PLOT2DVIEWER" ), salomeCat ); //viewTab
2424   //pref->setItemProperty( "columns", 2, plot2dGroup );
2425
2426   // ... -> background
2427   pref->addPreference( tr( "PREF_VIEWER_BACKGROUND_COLOR" ), plot2dGroup,
2428                        LightApp_Preferences::Color, "Plot2d", "Background" );
2429   // ... -> selection color
2430   pref->addPreference( tr( "PREF_VIEWER_SELECTION" ), plot2dGroup,
2431                        LightApp_Preferences::Color, "Plot2d", "SelectionColor" );
2432
2433   // ... "Viewer" group <<start>>
2434   int plot2dViewerGroup = pref->addPreference( tr( "PREF_GROUP_VIEWER" ), plot2dGroup );
2435
2436   // .... -> curve type
2437   int curveType = pref->addPreference( tr( "PREF_CURVE_TYPE" ), plot2dViewerGroup,
2438                                        LightApp_Preferences::Selector, "Plot2d", "CurveType" );
2439   aValuesList.clear();
2440   anIndicesList.clear();
2441   aValuesList   << tr("PREF_POINTS") << tr("PREF_LINES") << tr("PREF_SPLINE");
2442   anIndicesList << 0                 << 1                << 2                ;
2443   pref->setItemProperty( "strings", aValuesList,   curveType );
2444   pref->setItemProperty( "indexes", anIndicesList, curveType );
2445   // .... -> marker size
2446   int markerSize = pref->addPreference( tr( "PREF_MARKER_SIZE" ), plot2dViewerGroup,
2447                                         LightApp_Preferences::IntSpin, "Plot2d", "MarkerSize" );
2448   pref->setItemProperty( "min", 0, markerSize );
2449   pref->setItemProperty( "max", 100, markerSize );
2450   // .... -> horizontal scaling mode
2451   int horScale = pref->addPreference( tr( "PREF_HOR_AXIS_SCALE" ), plot2dViewerGroup,
2452                                       LightApp_Preferences::Selector, "Plot2d", "HorScaleMode" );
2453   aValuesList.clear();
2454   anIndicesList.clear();
2455   aValuesList   << tr("PREF_LINEAR") << tr("PREF_LOGARITHMIC");
2456   anIndicesList << 0                 << 1                     ;
2457   pref->setItemProperty( "strings", aValuesList,   horScale );
2458   pref->setItemProperty( "indexes", anIndicesList, horScale );
2459   // .... -> vertical scaling mode
2460   int verScale = pref->addPreference( tr( "PREF_VERT_AXIS_SCALE" ), plot2dViewerGroup,
2461                                       LightApp_Preferences::Selector, "Plot2d", "VerScaleMode" );
2462   pref->setItemProperty( "strings", aValuesList,   verScale );
2463   pref->setItemProperty( "indexes", anIndicesList, verScale );
2464
2465   // .... -> errors/deviation colot
2466   pref->addPreference( tr( "PREF_DEVIATION_COLOR" ), plot2dViewerGroup,
2467                        LightApp_Preferences::Color, "Plot2d", "DeviationMarkerColor" );
2468   // .... -> deviation markers line size
2469   int deviationMarkerLw = pref->addPreference( tr( "PREF_DEVIATION_MARKER_LW" ), plot2dViewerGroup,
2470                                         LightApp_Preferences::IntSpin, "Plot2d", "DeviationMarkerLineWidth" );
2471   pref->setItemProperty( "min", 1, deviationMarkerLw );
2472   pref->setItemProperty( "max", 5, deviationMarkerLw );
2473   // .... -> deviation markers tick mark size
2474   int deviationMarkerTs = pref->addPreference( tr( "PREF_DEVIATION_MARKER_TS" ), plot2dViewerGroup,
2475                                         LightApp_Preferences::IntSpin, "Plot2d", "DeviationMarkerTickSize" );
2476   pref->setItemProperty( "min", 1, deviationMarkerTs );
2477   pref->setItemProperty( "max", 5, deviationMarkerTs );
2478   // .... "Viewer" group <<end>>
2479
2480   // ... "Legend" group <<start>>
2481   int plot2dLegendGroup = pref->addPreference( tr( "PREF_GROUP_LEGEND" ), plot2dGroup );
2482
2483   // .... -> show legend
2484   pref->addPreference( tr( "PREF_SHOW_LEGEND" ), plot2dLegendGroup,
2485                        LightApp_Preferences::Bool, "Plot2d", "ShowLegend" );
2486   // .... -> legend position
2487   int legendPosition = pref->addPreference( tr( "PREF_LEGEND_POSITION" ), plot2dLegendGroup,
2488                                             LightApp_Preferences::Selector, "Plot2d", "LegendPos" );
2489   aValuesList.clear();
2490   anIndicesList.clear();
2491   aValuesList   << tr("PREF_LEFT") << tr("PREF_RIGHT") << tr("PREF_TOP") << tr("PREF_BOTTOM");
2492   anIndicesList << 0               << 1                << 2              << 3                ;
2493   pref->setItemProperty( "strings", aValuesList,   legendPosition );
2494   pref->setItemProperty( "indexes", anIndicesList, legendPosition );
2495   // .... -> Symbol type
2496   int legendSymbolType = pref->addPreference( tr( "PREF_LEGEND_SYMBOL_TYPE" ), plot2dLegendGroup,
2497                                             LightApp_Preferences::Selector, "Plot2d", "LegendSymbolType" );
2498   aValuesList.clear();
2499   anIndicesList.clear();
2500   aValuesList   << tr("PREF_MARKER_ON_LINE") << tr("PREF_MARKER_ABOVE_LINE");
2501   anIndicesList << 0                            << 1                        ;
2502   pref->setItemProperty( "strings", aValuesList,   legendSymbolType );
2503   pref->setItemProperty( "indexes", anIndicesList, legendSymbolType );
2504   // .... -> legend font
2505   pref->addPreference( tr( "PREF_LEGEND_FONT" ), plot2dLegendGroup, LightApp_Preferences::Font, "Plot2d", "LegendFont" );
2506   // ... -> font color
2507   pref->addPreference( tr( "PREF_FONT_COLOR" ), plot2dLegendGroup, LightApp_Preferences::Color, "Plot2d", "LegendFontColor" );
2508   // ... -> selection font color
2509   pref->addPreference( tr( "PREF_SELECTED_FONT_COLOR" ), plot2dLegendGroup, LightApp_Preferences::Color, "Plot2d", "SelectedLegendFontColor" );
2510   // ... "Legend" group <<end>>
2511
2512   // .. "Plot2d viewer" group <<end>>
2513
2514   // .. "Directories" preferences tab <<start>>
2515   int dirTab = pref->addPreference( tr( "PREF_TAB_DIRECTORIES" ), salomeCat );
2516   // ... --> quick directories list
2517   int dirGroup = pref->addPreference( tr( "PREF_GROUP_DIRECTORIES" ), dirTab );
2518   pref->addPreference( tr( "" ), dirGroup,
2519                        LightApp_Preferences::DirList, "FileDlg", "QuickDirList" );
2520   // .. "Directories" preferences tab <<end>>
2521
2522   // .. "Object browser" preferences tab <<start>>
2523   int obTab = pref->addPreference( tr( "PREF_TAB_OBJBROWSER" ), salomeCat );
2524
2525   // ... "Search tool" group <<start>>
2526   int stGroup = pref->addPreference( tr( "PREF_OBJ_BROWSER_SEARCH_TOOL" ), obTab );
2527   // .... --> auto-hide
2528   pref->addPreference( tr( "PREF_AUTO_HIDE_SEARCH_TOOL" ), stGroup, LightApp_Preferences::Bool,
2529                        "ObjectBrowser", "auto_hide_search_tool" );
2530   // ... "Search tool" group <<end>>
2531
2532   // ... "Object browser settings" group <<start>>
2533   int objSetGroup = pref->addPreference( tr( "PREF_GROUP_LOOK_AND_FEEL" ), obTab );
2534   pref->setItemProperty( "columns", 2, objSetGroup );
2535   // .... -> auto size first column
2536   pref->addPreference( tr( "PREF_AUTO_SIZE_FIRST" ), objSetGroup, LightApp_Preferences::Bool,
2537                        "ObjectBrowser", "auto_size_first" );
2538   // .... -> auto size other columns
2539   pref->addPreference( tr( "PREF_AUTO_SIZE" ), objSetGroup, LightApp_Preferences::Bool,
2540                        "ObjectBrowser", "auto_size" );
2541   // .... -> resize columns on expand item
2542   pref->addPreference( tr( "PREF_RESIZE_ON_EXPAND_ITEM" ), objSetGroup, LightApp_Preferences::Bool,
2543                        "ObjectBrowser", "resize_on_expand_item" );
2544   // .... -> browse to published object
2545   int browsePublished = pref->addPreference( tr( "PREF_BROWSE_TO_THE_PUBLISHED_OBJECT" ), objSetGroup, LightApp_Preferences::Selector,
2546                                              "ObjectBrowser", "browse_published_object" );
2547   aValuesList.clear();
2548   anIndicesList.clear();
2549   aValuesList << tr( "PREF_BROWSE_NEVER" ) << tr( "PREF_BROWSE_AFTER_APPLY_AND_CLOSE_ONLY" ) << tr( "PREF_BROWSE_ALWAYS" );
2550   anIndicesList << BP_Never << BP_ApplyAndClose << BP_Always;
2551   pref->setItemProperty( "strings", aValuesList,   browsePublished );
2552   pref->setItemProperty( "indexes", anIndicesList, browsePublished );
2553   // ... "Object browser settings" group <<end>>
2554   // .. "Object browser" preferences tab <<end>>
2555
2556   // .. "Shortcuts" preferences tab <<start>>
2557   int shortcutTab = pref->addPreference( tr( "PREF_TAB_SHORTCUTS" ), salomeCat );
2558   // ... "Shortcuts settings" group <<start>>
2559   int shortcutGroup = pref->addPreference( tr( "PREF_GROUP_SHORTCUTS" ), shortcutTab );
2560   pref->addPreference( tr( "" ), shortcutGroup,
2561                        LightApp_Preferences::ShortcutTree, "shortcuts" );
2562   // ... "Shortcuts settings" group <<end>>
2563   // .. "Shortcuts" preferences tab <<end>>
2564   // . Top-level "SALOME" preferences group <<end>>
2565
2566   pref->retrieve();
2567 }
2568
2569 /*!
2570   Changes appearance of application according to changed preferences
2571   \param sec - section
2572   \param param - name of changed parameter
2573 */
2574 void LightApp_Application::preferencesChanged( const QString& sec, const QString& param )
2575 {
2576   SUIT_ResourceMgr* resMgr = resourceMgr();
2577   if ( !resMgr )
2578     return;
2579
2580   if ( sec == "viewers" && param == "drop_down_buttons" )
2581   {
2582     ViewManagerList vmlist = viewManagers();
2583     foreach( SUIT_ViewManager* vm, vmlist )
2584     {
2585       QVector<SUIT_ViewWindow*> vwlist = vm->getViews();
2586       foreach( SUIT_ViewWindow* vw, vwlist )
2587         if ( vw ) vw->setDropDownButtons( resMgr->booleanValue( "viewers", "drop_down_buttons", true ) );
2588     }
2589   }
2590
2591   if ( sec == QString( "3DViewer" ) && (param == QString( "trihedron_size" ) || param == QString( "relative_size" )))
2592   {
2593     double sz = resMgr->doubleValue( sec, "trihedron_size", -1 );
2594     bool relative = resMgr->booleanValue( sec, "relative_size", true );
2595     QList<SUIT_ViewManager*> lst;
2596 #ifndef DISABLE_OCCVIEWER
2597     viewManagers( OCCViewer_Viewer::Type(), lst );
2598     QListIterator<SUIT_ViewManager*> itOCC( lst );
2599     while ( itOCC.hasNext() && sz >= 0 )
2600     {
2601       SUIT_ViewModel* vm = itOCC.next()->getViewModel();
2602       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
2603         continue;
2604
2605       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
2606       occVM->setTrihedronSize( sz, relative );
2607       occVM->getAISContext()->UpdateCurrentViewer();
2608     }
2609 #endif
2610 #ifndef DISABLE_VTKVIEWER
2611 #ifndef DISABLE_SALOMEOBJECT
2612     viewManagers( SVTK_Viewer::Type(), lst );
2613     QListIterator<SUIT_ViewManager*> itVTK( lst );
2614     while ( itVTK.hasNext() && sz >= 0 )
2615     {
2616       SUIT_ViewModel* vm = itVTK.next()->getViewModel();
2617       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
2618         continue;
2619
2620       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
2621       if( vtkVM )
2622       {
2623         vtkVM->setTrihedronSize( sz, relative );
2624         vtkVM->Repaint();
2625       }
2626     }
2627 #endif
2628 #endif
2629   }
2630
2631   if ( sec == QString( "3DViewer" ) && param == QString( "show_static_trihedron" ) )
2632   {
2633     bool isVisible = resMgr->booleanValue( "3DViewer", "show_static_trihedron", true );
2634     QList<SUIT_ViewManager*> lst;
2635 #ifndef DISABLE_OCCVIEWER
2636     viewManagers( OCCViewer_Viewer::Type(), lst );
2637     QListIterator<SUIT_ViewManager*> itOCC( lst );
2638     while ( itOCC.hasNext() )
2639     {
2640       SUIT_ViewModel* vm = itOCC.next()->getViewModel();
2641       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
2642         continue;
2643
2644       OCCViewer_Viewer* occVM = dynamic_cast<OCCViewer_Viewer*>( vm );
2645       if( occVM )
2646       {
2647         occVM->setStaticTrihedronDisplayed( isVisible );
2648       }
2649     }
2650 #endif
2651 #ifndef DISABLE_VTKVIEWER
2652 #ifndef DISABLE_SALOMEOBJECT
2653     viewManagers( SVTK_Viewer::Type(), lst );
2654     QListIterator<SUIT_ViewManager*> itVTK( lst );
2655     while ( itVTK.hasNext() )
2656     {
2657       SUIT_ViewModel* vm = itVTK.next()->getViewModel();
2658       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
2659         continue;
2660
2661       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
2662       if( vtkVM )
2663       {
2664         vtkVM->setStaticTrihedronVisible( isVisible );
2665         vtkVM->Repaint();
2666       }
2667     }
2668 #endif
2669 #endif
2670   }
2671
2672   if ( sec == QString( "3DViewer" ) && param == QString( "navigation_mode" ) )
2673   {
2674     int mode = resMgr->integerValue( "3DViewer", "navigation_mode", 0 );
2675     QList<SUIT_ViewManager*> lst;
2676 #ifndef DISABLE_OCCVIEWER
2677     viewManagers( OCCViewer_Viewer::Type(), lst );
2678     QListIterator<SUIT_ViewManager*> itOCC( lst );
2679     while ( itOCC.hasNext() )
2680     {
2681       SUIT_ViewModel* vm = itOCC.next()->getViewModel();
2682       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
2683         continue;
2684
2685       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
2686       occVM->setInteractionStyle( mode );
2687     }
2688 #endif
2689 #ifndef DISABLE_VTKVIEWER
2690 #ifndef DISABLE_SALOMEOBJECT
2691     viewManagers( SVTK_Viewer::Type(), lst );
2692     QListIterator<SUIT_ViewManager*> itVTK( lst );
2693     while ( itVTK.hasNext() )
2694     {
2695       SUIT_ViewModel* vm = itVTK.next()->getViewModel();
2696       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
2697         continue;
2698
2699       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
2700       if( vtkVM ) vtkVM->setInteractionStyle( mode );
2701     }
2702 #endif
2703 #endif
2704   }
2705
2706 #ifndef DISABLE_OCCVIEWER
2707   if ( sec == QString( "OCCViewer" ) && param == QString( "enable_preselection" ) )
2708   {
2709     bool isToEnablePreselection = resMgr->booleanValue( "OCCViewer", "enable_preselection", true );
2710     QList<SUIT_ViewManager*> lst;
2711     viewManagers( OCCViewer_Viewer::Type(), lst );
2712     QListIterator<SUIT_ViewManager*> it( lst );
2713     while ( it.hasNext() )
2714     {
2715       SUIT_ViewModel* vm = it.next()->getViewModel();
2716       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
2717         continue;
2718
2719       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
2720       occVM->enablePreselection( isToEnablePreselection );
2721     }
2722   }
2723 #endif
2724
2725 #ifndef DISABLE_OCCVIEWER
2726   if ( sec == QString( "OCCViewer" ) && param == QString( "enable_selection" ) )
2727   {
2728     bool isToEnableSelection = resMgr->booleanValue( "OCCViewer", "enable_selection", true );
2729     QList<SUIT_ViewManager*> lst;
2730     viewManagers( OCCViewer_Viewer::Type(), lst );
2731     QListIterator<SUIT_ViewManager*> it( lst );
2732     while ( it.hasNext() )
2733     {
2734       SUIT_ViewModel* vm = it.next()->getViewModel();
2735       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
2736         continue;
2737
2738       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
2739       occVM->enableSelection( isToEnableSelection );
2740     }
2741   }
2742 #endif
2743
2744   if ( sec == QString( "3DViewer" ) && param == QString( "zooming_mode" ) )
2745   {
2746     int mode = resMgr->integerValue( "3DViewer", "zooming_mode", 0 );
2747     QList<SUIT_ViewManager*> lst;
2748 #ifndef DISABLE_OCCVIEWER
2749     viewManagers( OCCViewer_Viewer::Type(), lst );
2750     QListIterator<SUIT_ViewManager*> itOCC( lst );
2751     while ( itOCC.hasNext() )
2752     {
2753       SUIT_ViewModel* vm = itOCC.next()->getViewModel();
2754       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
2755         continue;
2756
2757       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
2758       occVM->setZoomingStyle( mode );
2759     }
2760 #endif
2761 #ifndef DISABLE_VTKVIEWER
2762 #ifndef DISABLE_SALOMEOBJECT
2763     viewManagers( SVTK_Viewer::Type(), lst );
2764     QListIterator<SUIT_ViewManager*> itVTK( lst );
2765     while ( itVTK.hasNext() )
2766     {
2767       SUIT_ViewModel* vm = itVTK.next()->getViewModel();
2768       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
2769         continue;
2770
2771       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
2772       if( vtkVM ) vtkVM->setZoomingStyle( mode );
2773     }
2774 #endif
2775 #endif
2776   }
2777
2778 #ifndef DISABLE_VTKVIEWER
2779   if ( sec == QString( "VTKViewer" ) && (param == QString( "speed_value" ) || param == QString( "speed_mode" )) )
2780   {
2781     int speed = resMgr->integerValue( "VTKViewer", "speed_value", 10 );
2782     int mode = resMgr->integerValue( "VTKViewer", "speed_mode", 0 );
2783     QList<SUIT_ViewManager*> lst;
2784 #ifndef DISABLE_SALOMEOBJECT
2785     viewManagers( SVTK_Viewer::Type(), lst );
2786     QListIterator<SUIT_ViewManager*> it( lst );
2787     while ( it.hasNext() )
2788     {
2789       SUIT_ViewModel* vm = it.next()->getViewModel();
2790       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
2791         continue;
2792
2793       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
2794       if( vtkVM ) vtkVM->setIncrementalSpeed( speed, mode );
2795     }
2796 #endif
2797   }
2798 #endif
2799
2800 #ifndef DISABLE_VTKVIEWER
2801   if ( sec == QString( "VTKViewer" ) && param == QString( "projection_mode" ) )
2802   {
2803     int mode = resMgr->integerValue( "VTKViewer", "projection_mode", 0 );
2804     QList<SUIT_ViewManager*> lst;
2805 #ifndef DISABLE_SALOMEOBJECT
2806     viewManagers( SVTK_Viewer::Type(), lst );
2807     QListIterator<SUIT_ViewManager*> it( lst );
2808     while ( it.hasNext() )
2809     {
2810       SUIT_ViewModel* vm = it.next()->getViewModel();
2811       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
2812         continue;
2813
2814       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
2815       if( vtkVM ) vtkVM->setProjectionMode( mode );
2816     }
2817 #endif
2818   }
2819 #endif
2820
2821 #ifndef DISABLE_VTKVIEWER
2822   if ( sec == QString( "VTKViewer" ) && param == QString( "preselection" ) )
2823   {
2824     int mode = resMgr->integerValue( "VTKViewer", "preselection", 0 );
2825     QList<SUIT_ViewManager*> lst;
2826 #ifndef DISABLE_SALOMEOBJECT
2827     viewManagers( SVTK_Viewer::Type(), lst );
2828     QListIterator<SUIT_ViewManager*> it( lst );
2829     while ( it.hasNext() )
2830     {
2831       SUIT_ViewModel* vm = it.next()->getViewModel();
2832       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
2833         continue;
2834
2835       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
2836       if( vtkVM ) vtkVM->setPreSelectionMode( mode );
2837     }
2838 #endif
2839   }
2840 #endif
2841
2842 #ifndef DISABLE_VTKVIEWER
2843   if ( sec == QString( "VTKViewer" ) && param == QString( "enable_selection" ) )
2844   {
2845     bool isToEnableSelection = resMgr->booleanValue( "VTKViewer", "enable_selection", true );
2846     QList<SUIT_ViewManager*> lst;
2847 #ifndef DISABLE_SALOMEOBJECT
2848     viewManagers( SVTK_Viewer::Type(), lst );
2849     QListIterator<SUIT_ViewManager*> it( lst );
2850     while ( it.hasNext() )
2851     {
2852       SUIT_ViewModel* vm = it.next()->getViewModel();
2853       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
2854         continue;
2855
2856       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
2857       if( vtkVM ) vtkVM->enableSelection( isToEnableSelection );
2858     }
2859 #endif
2860   }
2861 #endif
2862
2863 #ifndef DISABLE_VTKVIEWER
2864   if ( sec == QString( "VTKViewer" ) && (param == QString( "spacemouse_func1_btn" ) ||
2865                                          param == QString( "spacemouse_func2_btn" ) ||
2866                                          param == QString( "spacemouse_func5_btn" ) ) )
2867   {
2868     int btn1 = resMgr->integerValue( "VTKViewer", "spacemouse_func1_btn", 1 );
2869     int btn2 = resMgr->integerValue( "VTKViewer", "spacemouse_func2_btn", 2 );
2870     int btn3 = resMgr->integerValue( "VTKViewer", "spacemouse_func5_btn", 9 );
2871     QList<SUIT_ViewManager*> lst;
2872 #ifndef DISABLE_SALOMEOBJECT
2873     viewManagers( SVTK_Viewer::Type(), lst );
2874     QListIterator<SUIT_ViewManager*> it( lst );
2875     while ( it.hasNext() )
2876     {
2877       SUIT_ViewModel* vm = it.next()->getViewModel();
2878       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
2879         continue;
2880
2881       SVTK_Viewer* vtkVM = dynamic_cast<SVTK_Viewer*>( vm );
2882       if( vtkVM ) vtkVM->setSpacemouseButtons( btn1, btn2, btn3 );
2883     }
2884 #endif
2885   }
2886 #endif
2887   if( sec=="ObjectBrowser" )
2888   {
2889     SUIT_DataBrowser* ob = objectBrowser();
2890     if ( !ob )
2891       return;
2892
2893     if ( param=="auto_size_first" )
2894     {
2895       bool autoSizeFirst = resMgr->booleanValue( "ObjectBrowser", "auto_size_first", true );
2896       ob->setAutoSizeFirstColumn( autoSizeFirst );
2897       if ( autoSizeFirst )
2898         ob->adjustFirstColumnWidth();
2899     }
2900     else if ( param=="auto_size" ) {
2901       bool autoSize = resMgr->booleanValue( "ObjectBrowser", "auto_size", false );
2902       ob->setAutoSizeColumns(autoSize);
2903       if ( autoSize )
2904         ob->adjustColumnsWidth();
2905     }
2906     else if ( param=="resize_on_expand_item" ) {
2907       bool resizeOnExpandItem = resMgr->booleanValue( "ObjectBrowser", "resize_on_expand_item", false );
2908       ob->setResizeOnExpandItem(resizeOnExpandItem);
2909     }
2910     else if ( param == "auto_hide_search_tool" ) {
2911       ob->searchTool()->enableAutoHide( resMgr->booleanValue( "ObjectBrowser", "auto_hide_search_tool" ) );
2912     }
2913   }
2914
2915   if( sec=="Study" )
2916   {
2917     if( param=="auto_save_interval" ) {
2918       myAutoSaveTimer->stop();
2919       int autoSaveInterval = resMgr->integerValue( "Study", "auto_save_interval", 0 );
2920       if ( activeStudy() && autoSaveInterval > 0 ) myAutoSaveTimer->start( autoSaveInterval*60000 );
2921     }
2922   }
2923
2924 #ifndef DISABLE_PYCONSOLE
2925   if( sec=="PyConsole" && pythonConsole() )
2926   {
2927     if ( param=="font" ) {
2928       pythonConsole()->setFont( resMgr->fontValue( "PyConsole", "font" ) );
2929     }
2930     else if ( param=="show_banner" ) {
2931       pythonConsole()->setIsShowBanner( resMgr->booleanValue( "PyConsole", "show_banner", true ) );
2932     }
2933   }
2934 #endif
2935
2936   if( sec=="MRU" )
2937   {
2938     QtxMRUAction* mru = ::qobject_cast<QtxMRUAction*>( action( MRUId ) );
2939     if ( mru ) {
2940       if ( param == "visible_count" )
2941         mru->setVisibleCount( resMgr->integerValue( "MRU", "visible_count", 5 ) );    // 5 MRU items by default
2942       else if ( param == "max_count" )
2943         mru->setHistoryCount( resMgr->integerValue( "MRU", "max_count", -1 ) );       // unlimited history by default
2944       else if ( param == "insert_mode" )
2945         mru->setInsertMode( resMgr->integerValue( "MRU", "insert_mode", 0 ) );        // QtxMRUAction::MoveFirst by default
2946       else if ( param == "link_type" )
2947         mru->setLinkType( resMgr->integerValue( "MRU", "link_type", 0 ) );            // QtxMRUAction::LinkAuto by default
2948       else if ( param == "show_clear" )
2949         mru->setClearPossible( resMgr->booleanValue( "MRU", "show_clear", false ) );  // do not show "Clear" item by default
2950       else if ( param == "show_mru" )
2951         mru->setVisible( resMgr->booleanValue( "MRU", "show_mru", false ) );          // do not show MRU menu item by default
2952     }
2953   }
2954   if ( sec == "language" && param == "language" )
2955   {
2956     SUIT_MessageBox::information( desktop(), tr( "WRN_WARNING" ), tr( "LANG_CHANGED" ) );
2957   }
2958   if ( sec == "desktop" && param == "opaque_resize" ) {
2959     bool opaqueResize = resMgr->booleanValue( "desktop", "opaque_resize", false );
2960     QMainWindow::DockOptions dopts = desktop()->dockOptions();
2961     if ( opaqueResize ) dopts |= QMainWindow::AnimatedDocks;
2962     else                dopts &= ~QMainWindow::AnimatedDocks;
2963     desktop()->setDockOptions( dopts );
2964     desktop()->setOpaqueResize( opaqueResize );
2965     if ( dynamic_cast<STD_TabDesktop*>( desktop() ) )
2966       dynamic_cast<STD_TabDesktop*>( desktop() )->workstack()->setOpaqueResize( opaqueResize );
2967   }
2968
2969   if ( sec == "ExternalBrowser" && param == "use_external_browser" ) {
2970     if ( resMgr->booleanValue("ExternalBrowser", "use_external_browser", false ) )
2971     {
2972       QtxWebBrowser::shutdown();
2973     }
2974   }
2975
2976 #ifndef DISABLE_PLOT2DVIEWER
2977   QList<SUIT_ViewManager*> lst;
2978   viewManagers( Plot2d_Viewer::Type(), lst );
2979   QListIterator<SUIT_ViewManager*> itPlot2d( lst );
2980   while ( itPlot2d.hasNext() ) {
2981     SUIT_ViewManager* viewMgr = itPlot2d.next();
2982     SUIT_ViewModel* vm = viewMgr->getViewModel();
2983     if ( !vm || !vm->inherits( "Plot2d_Viewer" ) )
2984       continue;
2985
2986     Plot2d_Viewer* Plot2dVM = dynamic_cast<Plot2d_Viewer*>( vm );
2987
2988     viewMgr->setViewModel( vm  );
2989     Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( viewMgr->getActiveView() );
2990     if( wnd ) {
2991       Plot2d_ViewFrame* frame = wnd->getViewFrame();
2992       frame->SetPreference();
2993     }
2994   }
2995 #endif
2996 }
2997
2998 /*!
2999   Loads preferences
3000 */
3001 void LightApp_Application::loadPreferences()
3002 {
3003   CAM_Application::loadPreferences();
3004
3005   SUIT_ResourceMgr* aResMgr = resourceMgr();
3006
3007   if ( !aResMgr )
3008     return;
3009
3010   static bool mru_load = true;
3011   if ( mru_load )
3012   {
3013     QtxMRUAction* mru = ::qobject_cast<QtxMRUAction*>( action( MRUId ) );
3014     if ( mru ) {
3015       mru->setVisible( aResMgr->booleanValue( "MRU", "show_mru", false ) );         // do not show MRU menu item by default
3016       mru->setVisibleCount( aResMgr->integerValue( "MRU", "visible_count", 5 ) );   // 5 MRU items by default
3017       mru->setHistoryCount( aResMgr->integerValue( "MRU", "max_count", -1 ) );      // unlimited history by default
3018       mru->setInsertMode( aResMgr->integerValue( "MRU", "insert_mode", 0 ) );       // QtxMRUAction::MoveFirst by default
3019       mru->setLinkType( aResMgr->integerValue( "MRU", "link_type", 0 ) );           // QtxMRUAction::LinkAuto by default
3020       mru->setClearPossible( aResMgr->booleanValue( "MRU", "show_clear", false ) ); // do not show "Clear" item by default
3021       mru->loadLinks( aResMgr, "MRU" );
3022     }
3023     mru_load = false;
3024   }
3025
3026   myWinVis.clear();
3027   QStringList mods = aResMgr->parameters( "windows_visibility" );
3028   for ( QStringList::const_iterator itr = mods.begin(); itr != mods.end(); ++itr )
3029   {
3030     QByteArray arr;
3031     if ( aResMgr->value( "windows_visibility", *itr, arr ) )
3032       myWinVis.insert( *itr, arr );
3033   }
3034
3035   if ( desktop() ) {
3036     desktop()->retrieveGeometry( aResMgr->stringValue( "desktop", "geometry" ) );
3037     bool opaqueResize = aResMgr->booleanValue( "desktop", "opaque_resize", false );
3038     QMainWindow::DockOptions dopts = desktop()->dockOptions();
3039     if ( opaqueResize ) dopts |= QMainWindow::AnimatedDocks;
3040     else                dopts &= ~QMainWindow::AnimatedDocks;
3041     desktop()->setDockOptions( dopts );
3042     desktop()->setOpaqueResize( opaqueResize );
3043     if ( dynamic_cast<STD_TabDesktop*>( desktop() ) )
3044       dynamic_cast<STD_TabDesktop*>( desktop() )->workstack()->setOpaqueResize( opaqueResize );
3045   }
3046 }
3047
3048 /*!
3049   Saves preferences
3050 */
3051 void LightApp_Application::savePreferences()
3052 {
3053   CAM_Application::savePreferences();
3054
3055   saveDockWindowsState();
3056
3057   SUIT_ResourceMgr* aResMgr = resourceMgr();
3058
3059   if ( !aResMgr )
3060     return;
3061
3062   QtxMRUAction* mru = ::qobject_cast<QtxMRUAction*>( action( MRUId ) );
3063   if ( mru )
3064     mru->saveLinks( aResMgr, "MRU" );
3065
3066   for ( WinVis::const_iterator itr = myWinVis.begin(); itr != myWinVis.end(); ++itr )
3067     aResMgr->setValue( "windows_visibility", itr.key(), itr.value() );
3068
3069   if ( desktop() )
3070     aResMgr->setValue( "desktop", "geometry", desktop()->storeGeometry() );
3071
3072   aResMgr->save();
3073 }
3074
3075 /*!
3076   Updates desktop title
3077 */
3078 void LightApp_Application::updateDesktopTitle()
3079 {
3080   QString aTitle = applicationName();
3081   QString aVer = applicationVersion();
3082   if ( !aVer.isEmpty() )
3083     aTitle += QString( " " ) + aVer;
3084
3085   if ( activeStudy() ) {
3086     QString sName = SUIT_Tools::file( activeStudy()->studyName().trimmed(), false );
3087     aTitle += QString( " - [%1]" ).arg( sName );
3088   }
3089
3090   desktop()->setWindowTitle( aTitle );
3091 }
3092
3093 /*!
3094   \brief Get map of the operations which can be performed
3095   on the module activation.
3096
3097   The method should return the map of the kind \c {<id>:<name>}
3098   where \c <id> is an integer identifier of the operation and
3099   \c <name> is a title for the button to be added to the
3100   dialog box. After user selects the required operation by the
3101   clicking the corresponding button in the dialog box, its identifier
3102   is passed to the moduleActionSelected() method to process
3103   the made choice.
3104
3105   \return map of the operations
3106   \sa moduleActionSelected()
3107 */
3108 QMap<int, QString> LightApp_Application::activateModuleActions() const
3109 {
3110   QMap<int, QString> opmap;
3111   opmap.insert( NewStudyId,  tr( "ACTIVATE_MODULE_OP_NEW" ) );
3112   opmap.insert( OpenStudyId, tr( "ACTIVATE_MODULE_OP_OPEN" ) );
3113   return opmap;
3114 }
3115
3116 /*!
3117   \brief Called when the used selectes required operation chosen
3118   from "Activate module" dialog box.
3119
3120   Performs the required operation according to the user choice.
3121
3122   \param id operation identifier
3123   \sa activateModuleActions()
3124 */
3125 void LightApp_Application::moduleActionSelected( const int id )
3126 {
3127   switch ( id ) {
3128   case NewStudyId:
3129     onNewDoc();
3130     break;
3131   case OpenStudyId:
3132     onOpenDoc();
3133     break;
3134   default:
3135     break;
3136   }
3137 }
3138
3139 /*!
3140   Updates windows after close document
3141 */
3142 void LightApp_Application::afterCloseDoc()
3143 {
3144   updateWindows();
3145
3146   CAM_Application::afterCloseDoc();
3147 }
3148
3149 /*!
3150   Updates actions of active module
3151 */
3152 void LightApp_Application::updateModuleActions()
3153 {
3154   QString modName;
3155   if ( activeModule() ) {
3156     modName = activeModule()->moduleName();
3157     if ( !isModuleAccessible( modName ) ) {
3158       QList<SUIT_Application*> apps = SUIT_Session::session()->applications();
3159       foreach( SUIT_Application* app, apps ) {
3160         LightApp_Application* lapp = dynamic_cast<LightApp_Application*>( app );
3161         if ( lapp && lapp != this )
3162           lapp->removeModuleAction( modName );
3163       }
3164     }
3165   }
3166
3167   LightApp_ModuleAction* moduleAction =
3168     qobject_cast<LightApp_ModuleAction*>( action( ModulesListId ) );
3169   if ( moduleAction )
3170     moduleAction->setActiveModule( modName );
3171 }
3172
3173 void LightApp_Application::removeModuleAction( const QString& modName )
3174 {
3175   LightApp_ModuleAction* moduleAction =
3176     qobject_cast<LightApp_ModuleAction*>( action( ModulesListId ) );
3177   if ( moduleAction )
3178     moduleAction->removeModule( modName );
3179 }
3180
3181 /*!
3182   Gets current windows.
3183   \param winMap - output current windows map.
3184 */
3185 void LightApp_Application::currentWindows( QMap<int, int>& winMap ) const
3186 {
3187   winMap.clear();
3188   if ( !activeStudy() )
3189     return;
3190
3191   if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) )
3192     ((LightApp_Module*)activeModule())->windows( winMap );
3193   else
3194     defaultWindows( winMap );
3195 }
3196
3197 /*!
3198   Gets current view managers.
3199   \param lst - output current view managers list.
3200 */
3201 void LightApp_Application::currentViewManagers( QStringList& lst ) const
3202 {
3203   lst.clear();
3204   if ( !activeStudy() )
3205     return;
3206
3207   if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) )
3208     ((LightApp_Module*)activeModule())->viewManagers( lst );
3209   else
3210     defaultViewManagers( lst );
3211 }
3212
3213 /*!
3214   Updates windows
3215 */
3216 void LightApp_Application::updateWindows()
3217 {
3218   QMap<int, int> winMap;
3219   currentWindows( winMap );
3220
3221   if ( activeStudy() )
3222   {
3223     for ( QMap<int, int>::ConstIterator it = winMap.begin(); it != winMap.end(); ++it )
3224     {
3225       if ( !dockWindow( it.key() ) )
3226         getWindow( it.key() );
3227     }
3228   }
3229
3230   for ( WinMap::ConstIterator it = myWin.begin(); it != myWin.end(); ++it )
3231   {
3232     QWidget* wid = it.value();
3233     if ( activeStudy() )
3234       wid->setVisible( winMap.contains( it.key() ) );
3235     else
3236       delete wid;
3237   }
3238
3239   if ( activeStudy() )
3240     loadDockWindowsState();
3241   else
3242     myWin.clear();
3243 }
3244
3245 /*!
3246   Updates view managers
3247 */
3248 void LightApp_Application::updateViewManagers()
3249 {
3250   QStringList lst;
3251   currentViewManagers( lst );
3252
3253   for ( QStringList::const_iterator it = lst.begin(); it != lst.end(); ++it )
3254     getViewManager( *it, true );
3255 }
3256
3257 /*!
3258   Loads windows geometry
3259 */
3260 void LightApp_Application::loadDockWindowsState()
3261 {
3262   if ( !desktop() )
3263     return;
3264   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3265   bool storeWin = aResMgr->booleanValue( "Study", "store_positions", true );
3266   bool storeTb = aResMgr->booleanValue( "Study", "store_tool_positions", true );
3267
3268   QString modName;
3269   if ( activeModule() )
3270     modName = activeModule()->name();
3271
3272   QtxResourceMgr::WorkingMode prevMode = aResMgr->workingMode();
3273   aResMgr->setWorkingMode(QtxResourceMgr::IgnoreUserValues);
3274   QByteArray aDefaultState;
3275   aResMgr->value("windows_geometry", modName , aDefaultState );
3276   QByteArray aDefaultVisibility;
3277   aResMgr->value("windows_visibility", modName , aDefaultVisibility );
3278   bool hasDefaultVisibility = !aDefaultVisibility.isEmpty();
3279   aResMgr->setWorkingMode(prevMode);
3280   
3281   if( !storeWin && !storeTb && aDefaultState.isEmpty() && !hasDefaultVisibility)
3282     return;
3283
3284   if ( aResMgr->hasValue("windows_geometry" ,modName ) ) {
3285     QByteArray arr;
3286     aResMgr->value("windows_geometry", modName , arr );
3287     QByteArray aTargetArray = processState(arr, storeWin, storeTb, aDefaultState);
3288     desktop()->restoreState( aTargetArray );
3289   }
3290
3291   if ( !myWinVis.contains( modName ) && aDefaultVisibility.isEmpty())
3292     return;
3293
3294   QMap<QString, bool> *tbMap = 0;
3295   QMap<QString, bool> *dwMap = 0;
3296   
3297   QMap<QString, bool> userTbMap, userDwMap;
3298   dockWindowsState( myWinVis[modName], userTbMap, userDwMap );
3299
3300   QMap<QString, bool> defaultTbMap, defaultDwMap;
3301   if(hasDefaultVisibility) {
3302     dockWindowsState( aDefaultVisibility, defaultTbMap, defaultDwMap);    
3303   }
3304
3305   if(storeTb) {
3306     tbMap =  &userTbMap;
3307   } else {
3308     if(hasDefaultVisibility){
3309       tbMap =  &defaultTbMap;
3310     }
3311   }
3312
3313   if(storeWin) {
3314     dwMap =  &userDwMap;
3315   } else {
3316     if(hasDefaultVisibility){
3317       dwMap =  &defaultDwMap;
3318     }
3319   }
3320   
3321   if(tbMap) {
3322     QList<QToolBar*> tbList = findToolBars();
3323     for ( QList<QToolBar*>::iterator tit = tbList.begin(); tit != tbList.end(); ++tit )
3324       { 
3325         QToolBar* tb = *tit;
3326         if ( tbMap->contains( tb->objectName() ) ) {      
3327           tb->setVisible( (*tbMap)[tb->objectName()] );
3328         }
3329       }
3330   }
3331
3332   if(dwMap) {
3333     QList<QDockWidget*> dwList = qFindChildren<QDockWidget*>( desktop() );
3334     for ( QList<QDockWidget*>::iterator dit = dwList.begin(); dit != dwList.end(); ++dit )
3335       {
3336         QDockWidget* dw = *dit;
3337         
3338         QObject* po = Qtx::findParent( dw, "QMainWindow" );
3339         if ( po != desktop() )
3340           continue;
3341         
3342         if ( dwMap->contains( dw->objectName() ) )
3343           dw->setVisible( (*dwMap)[dw->objectName()] );
3344       }
3345   }
3346 }
3347
3348
3349 /*!
3350   Saves windows geometry
3351 */
3352 void LightApp_Application::saveDockWindowsState()
3353 {
3354   if ( !desktop() )
3355     return;
3356
3357   bool storeWin = resourceMgr()->booleanValue( "Study", "store_positions", true );
3358   bool storeTb = resourceMgr()->booleanValue( "Study", "store_tool_positions", true );
3359
3360   if( !storeWin && !storeTb )
3361     return;
3362
3363   QString modName;
3364   if ( activeModule() )
3365     modName = activeModule()->name();
3366
3367   QByteArray arr = desktop()->saveState();
3368   resourceMgr()->setValue( "windows_geometry", modName, processState(arr, storeWin, storeTb) );
3369
3370   QByteArray visArr;
3371   if ( myWinVis.contains( modName ) )
3372     visArr = myWinVis[modName];
3373
3374   QMap<QString, bool> tbMap, dwMap;
3375   dockWindowsState( visArr, tbMap, dwMap );
3376
3377   QList<QToolBar*> tbList = qFindChildren<QToolBar*>( desktop() );
3378   for ( QList<QToolBar*>::iterator it = tbList.begin(); it != tbList.end(); ++it )
3379   {
3380     QToolBar* tb = *it;
3381     tbMap.insert( tb->objectName(), tb->toggleViewAction()->isChecked() );
3382   }
3383
3384   QList<QDockWidget*> dwList = qFindChildren<QDockWidget*>( desktop() );
3385   for ( QList<QDockWidget*>::iterator it = dwList.begin(); it != dwList.end(); ++it )
3386   {
3387     QDockWidget* wid = *it;
3388     dwMap.insert( wid->objectName(), wid->toggleViewAction()->isChecked() );
3389   }
3390
3391   visArr = dockWindowsState( tbMap, dwMap );
3392
3393   myWinVis.insert( modName, visArr );
3394 }
3395
3396 QByteArray LightApp_Application::dockWindowsState( const QMap<QString, bool>& tb, const QMap<QString, bool>& dw ) const
3397 {
3398   QByteArray visArr;
3399   QDataStream stream( &visArr, QIODevice::WriteOnly );
3400
3401   stream << (uchar)ToolBarMarker;
3402   stream << tb.size();
3403   for ( QMap<QString, bool>::const_iterator tit = tb.begin(); tit != tb.end(); ++tit )
3404   {
3405     stream << tit.key();
3406     stream << (uchar)( tit.value() ? 1 : 0 );
3407   }
3408
3409   stream << (uchar)DockWidgetMarker;
3410   stream << dw.size();
3411   for ( QMap<QString, bool>::const_iterator wit = dw.begin(); wit != dw.end(); ++wit )
3412   {
3413     stream << wit.key();
3414     stream << (uchar)( wit.value() ? 1 : 0 );
3415   }
3416
3417   return visArr;
3418 }
3419
3420 void LightApp_Application::dockWindowsState( const QByteArray& arr, QMap<QString, bool>& tb, QMap<QString, bool>& dw ) const
3421 {
3422   tb.clear();
3423   dw.clear();
3424
3425   QByteArray visArr = arr;
3426   QDataStream stream( &visArr, QIODevice::ReadOnly );
3427
3428   uchar marker;
3429   stream >> marker;
3430   if ( marker != ToolBarMarker )
3431     return;
3432
3433   int lines;
3434   stream >> lines;
3435   for ( int i = 0; i < lines; ++i )
3436   {
3437     QString objectName;
3438     stream >> objectName;
3439     uchar shown;
3440     stream >> shown;
3441     tb.insert( objectName, shown );
3442   }
3443
3444   stream >> marker;
3445   if ( marker != DockWidgetMarker )
3446     return;
3447
3448   stream >> lines;
3449   for ( int j = 0; j < lines; ++j )
3450   {
3451     QString objectName;
3452     stream >> objectName;
3453     uchar shown;
3454     stream >> shown;
3455     dw.insert( objectName, shown );
3456   }
3457 }
3458
3459 /*!
3460   Adds icon names for modules
3461 */
3462 void LightApp_Application::moduleIconNames( QMap<QString, QString>& iconMap ) const
3463 {
3464   iconMap.clear();
3465
3466   SUIT_ResourceMgr* resMgr = resourceMgr();
3467   if ( !resMgr )
3468     return;
3469
3470   QStringList modList;
3471   modules( modList, false );
3472
3473   for ( QStringList::const_iterator it = modList.begin(); it != modList.end(); ++it )
3474   {
3475     QString modName = *it;
3476     QString modIntr = moduleName( modName );
3477     QString modIcon = resMgr->stringValue( modIntr, "icon", QString() );
3478
3479     if ( modIcon.isEmpty() )
3480       continue;
3481
3482     if ( SUIT_Tools::extension( modIcon ).isEmpty() )
3483       modIcon += QString( ".png" );
3484
3485     iconMap.insert( modName, modIcon );
3486   }
3487 }
3488
3489 /*!
3490   Inserts items in popup, which necessary for current application
3491 */
3492 void LightApp_Application::contextMenuPopup( const QString& type, QMenu* thePopup, QString& title )
3493 {
3494   //Add "Rename" item
3495   LightApp_SelectionMgr* selMgr = LightApp_Application::selectionMgr();
3496   bool cacheIsOn = selMgr->isSelectionCacheEnabled();
3497   selMgr->setSelectionCacheEnabled( true );
3498
3499   SUIT_DataBrowser* ob = objectBrowser();
3500
3501   CAM_Application::contextMenuPopup( type, thePopup, title );
3502
3503   if ( ob && type == ob->popupClientType() ) {
3504     thePopup->addSeparator();
3505     QAction* a = thePopup->addAction( tr( "MEN_REFRESH" ), this, SLOT( onRefresh() ) );
3506     if ( ob->shortcutKey(SUIT_DataBrowser::UpdateShortcut) )
3507       a->setShortcut( ob->shortcutKey(SUIT_DataBrowser::UpdateShortcut) );
3508   }
3509
3510   if ( selMgr && ob ) {
3511     SALOME_ListIO selected;
3512     selMgr->selectedObjects( selected );
3513     if(selected.Extent() == 1){
3514       Handle(SALOME_InteractiveObject) anIObject = selected.First();
3515       SUIT_DataObject* obj = findObject(anIObject->getEntry());
3516       if(obj && obj->renameAllowed()) {
3517         QAction* a = new QAction(tr("MEN_RENAME_OBJ"), thePopup);
3518         connect( a, SIGNAL( triggered(bool) ), ob, SLOT( onStartEditing() ) );
3519         if ( ob->shortcutKey(SUIT_DataBrowser::RenameShortcut) )
3520           a->setShortcut( ob->shortcutKey(SUIT_DataBrowser::RenameShortcut) );
3521
3522         QList<QAction*> acts = thePopup->actions();
3523         QAction* firstAction = acts.count() > 0 ? acts.first() : 0;
3524         thePopup->insertAction(firstAction,a);
3525       }
3526     }
3527   }
3528
3529   selMgr->setSelectionCacheEnabled( cacheIsOn );
3530 }
3531
3532 /*!
3533   Create empty study
3534 */
3535 void LightApp_Application::createEmptyStudy()
3536 {
3537   CAM_Application::createEmptyStudy();
3538
3539   if ( objectBrowser() )
3540     objectBrowser()->updateTree();
3541
3542   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
3543   if ( aResMgr && activeStudy() ) {
3544     int autoSaveInterval = aResMgr->integerValue( "Study", "auto_save_interval", 0 );
3545     if ( autoSaveInterval > 0 ) myAutoSaveTimer->start( autoSaveInterval*60000 );
3546   }
3547 }
3548
3549 /*!Set desktop:*/
3550 void LightApp_Application::setDesktop( SUIT_Desktop* desk )
3551 {
3552   CAM_Application::setDesktop( desk );
3553
3554   if ( desk ) {
3555     connect( desk, SIGNAL( message( const QString& ) ),
3556              this, SLOT( onDesktopMessage( const QString& ) ), Qt::UniqueConnection );
3557   }
3558 }
3559
3560 /*!
3561   Activates module
3562   \param mod - module to be activated
3563 */
3564 bool LightApp_Application::activateModule( CAM_Module* mod )
3565 {
3566   bool res = CAM_Application::activateModule( mod );
3567
3568   if ( objectBrowser() )
3569     objectBrowser()->updateTree();
3570
3571   return res;
3572 }
3573
3574 /*!
3575   \return keyborad accelerators manager object
3576 */
3577 SUIT_Accel* LightApp_Application::accel() const
3578 {
3579   return myAccel;
3580 }
3581
3582 /*!
3583   Removes dead widget container from map
3584 */
3585 void LightApp_Application::onWCDestroyed( QObject* ob )
3586 {
3587   // remove destroyed widget container from windows map
3588   for ( WinMap::ConstIterator itr = myWin.begin(); itr != myWin.end(); ++itr )
3589   {
3590     if ( itr.value() != ob )
3591       continue;
3592
3593     int key = itr.key();
3594     myWin.remove( key );
3595     break;
3596   }
3597 }
3598
3599 void LightApp_Application::onMRUActivated( const QString& name )
3600 {
3601   SUIT_Session* s = SUIT_Session::session();
3602   if ( s && s->activeApplication() == this )
3603     onOpenDoc( name );
3604 }
3605
3606 void LightApp_Application::onStylePreferences()
3607 {
3608   Style_PrefDlg dlg( desktop() );
3609   dlg.exec();
3610
3611   resourceMgr()->setValue( "Style", "use_salome_style", Style_Salome::isActive() );
3612 }
3613
3614 void LightApp_Application::onFullScreen(){
3615   if(myScreenHelper) {
3616     if(desktop()->isFullScreen())
3617       myScreenHelper->switchToNormalScreen();
3618     else
3619       myScreenHelper->switchToFullScreen();
3620   }
3621 }
3622
3623 /*!
3624   Connects just added view manager
3625 */
3626 void LightApp_Application::addViewManager( SUIT_ViewManager* vm )
3627 {
3628   connect( vm, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
3629            this, SLOT( onCloseView( SUIT_ViewManager* ) ) );
3630   CAM_Application::addViewManager( vm );
3631 }
3632
3633 /*!
3634   Remove view manager from memory
3635 */
3636 void LightApp_Application::removeViewManager( SUIT_ViewManager* vm )
3637 {
3638   disconnect( vm, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
3639            this, SLOT( onCloseView( SUIT_ViewManager* ) ) );
3640   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>(activeStudy());
3641   if (aStudy )
3642     aStudy->removeViewMgr(vm->getGlobalId());
3643
3644   CAM_Application::removeViewManager( vm );
3645
3646   LightApp_SelectionMgr* selMgr = selectionMgr();
3647   QList<SUIT_Selector*> selectors;
3648   selMgr->selectors( selectors );
3649   foreach( SUIT_Selector* selector, selectors ) {
3650     if ( selector->owner() == vm->getViewModel() ) {
3651       delete selector;
3652     }
3653   }
3654
3655   // IPAL22894: Crash on closing OCC view
3656   //delete vm;
3657   vm->deleteLater();
3658 }
3659
3660 /*!
3661   Renames active window of desktop
3662 */
3663 void LightApp_Application::onRenameWindow()
3664 {
3665   if( !desktop() )
3666     return;
3667
3668   QWidget* w = desktop()->activeWindow();
3669   if( !w )
3670     return;
3671
3672   bool ok;
3673   QString name = QInputDialog::getText( w, tr( "TOT_RENAME" ), tr( "PRP_RENAME" ), QLineEdit::Normal, w->windowTitle(), &ok );
3674   if( ok && !name.isEmpty() )
3675     w->setWindowTitle( name );
3676 }
3677
3678 /*!
3679   Closes active window of desktop
3680 */
3681 void LightApp_Application::onCloseWindow()
3682 {
3683   if( !desktop() )
3684     return;
3685
3686   QWidget* w = desktop()->activeWindow();
3687   if( !w )
3688     return;
3689
3690   w->close();
3691 }
3692
3693 /*!
3694   Closes all windows of desktop
3695 */
3696 void LightApp_Application::onCloseAllWindow()
3697 {
3698   STD_TabDesktop* desk = dynamic_cast<STD_TabDesktop*>( desktop() );
3699   if( !desk )
3700     return;
3701
3702   QList<SUIT_ViewWindow*> wndList = desk->windows();
3703   SUIT_ViewWindow* wnd;
3704   foreach( wnd, wndList )
3705   {
3706     if ( wnd )
3707       wnd->close();
3708   }
3709 }
3710
3711 /*!
3712   Groups all windows of desktop
3713 */
3714 void LightApp_Application::onGroupAllWindow()
3715 {
3716   STD_TabDesktop* desk = dynamic_cast<STD_TabDesktop*>( desktop() );
3717   if( !desk )
3718     return;
3719
3720   QtxWorkstack* wgStack = desk->workstack();
3721   if ( wgStack )
3722     wgStack->stack();
3723 }
3724
3725 /*!
3726   \return if the library of module exists
3727   \param moduleTitle - title of module
3728 */
3729 bool LightApp_Application::isLibExists( const QString& moduleTitle ) const
3730 {
3731   if( moduleTitle.isEmpty() )
3732     return false;
3733
3734   QString lib = moduleLibrary( moduleTitle );
3735
3736   //abd: changed libSalomePyQtGUI to SalomePyQtGUI for WIN32
3737   bool isPythonModule = lib.contains("SalomePyQtGUI");
3738   bool isPythonLightModule = lib.contains("SalomePyQtGUILight");
3739
3740   QStringList paths;
3741 #ifdef WIN32
3742   paths = QString(::getenv( "PATH" )).split( ";", QString::SkipEmptyParts );
3743 #else
3744   paths = QString(::getenv( "LD_LIBRARY_PATH" )).split( ":", QString::SkipEmptyParts );
3745 #endif
3746
3747   bool isLibFound = false;
3748   QStringList::const_iterator anIt = paths.begin(), aLast = paths.end();
3749   for( ; anIt!=aLast; anIt++ )
3750   {
3751     QFileInfo inf( Qtx::addSlash( *anIt ) + lib );
3752
3753     if( inf.exists() )
3754       {
3755         isLibFound = true;
3756         break;
3757       }
3758   }
3759
3760   if ( !isLibFound )
3761     {
3762       INFOS( "\n****************************************************************" << std::endl
3763           << "*    Warning: library " << lib.toLatin1().constData() << " cannot be found" << std::endl
3764           << "*    Module " << moduleTitle.toLatin1().constData() << " will not be available in GUI mode" << std::endl
3765           << "****************************************************************" << std::endl );
3766     }
3767   else if ( !isPythonModule && !isPythonLightModule)
3768     return true;
3769
3770   if ( isPythonModule || isPythonLightModule)
3771     {
3772       QString pylib = moduleName( moduleTitle ) + QString(".py");
3773       QString pylibgui = moduleName( moduleTitle ) + QString("GUI.py");
3774
3775       // Check the python library
3776 // #ifdef WIN32
3777 //       paths = QString(::getenv( "PATH" )).split( ";", QString::SkipEmptyParts );
3778 // #else
3779       paths = QString(::getenv( "PYTHONPATH" )).split( ":", QString::SkipEmptyParts );
3780 // #endif
3781       bool isPyLib = false, isPyGuiLib = false;
3782       QStringList::const_iterator anIt = paths.begin(), aLast = paths.end();
3783       for( ; anIt!=aLast; anIt++ )
3784         {
3785           QFileInfo inf( Qtx::addSlash( *anIt ) + pylib );
3786           QFileInfo infgui( Qtx::addSlash( *anIt ) + pylibgui );
3787
3788           if(!isPythonLightModule)
3789             if( !isPyLib && inf.exists() )
3790               isPyLib = true;
3791
3792           if( !isPyGuiLib && infgui.exists() )
3793             isPyGuiLib = true;
3794
3795           if ((isPyLib || isPythonLightModule ) && isPyGuiLib && isLibFound)
3796             return true;
3797         }
3798
3799       printf( "\n****************************************************************\n" );
3800       printf( "*    Warning: python library for %s cannot be found:\n", moduleTitle.toLatin1().constData() );
3801       if (!isPyLib)
3802         printf( "*    No module named %s\n", moduleName( moduleTitle ).toLatin1().constData() );
3803       if (!isPyGuiLib)
3804         printf( "*    No module named %s\n", (moduleName( moduleTitle ) + QString("GUI")).toLatin1().constData() );
3805       printf( "****************************************************************\n" );
3806       return true;
3807   }
3808   return false;
3809 }
3810
3811 /*!
3812   \return default name for an active study
3813 */
3814 void LightApp_Application::setDefaultStudyName( const QString& theName )
3815 {
3816   QStringList anInfoList;
3817   modules( anInfoList, false );
3818
3819   LightApp_Study* aStudy = (LightApp_Study*)activeStudy();
3820   if( anInfoList.count() == 1 && // to avoid a conflict between different modules
3821       !aStudy->isSaved() )
3822   {
3823     aStudy->setStudyName( theName );
3824     updateDesktopTitle();
3825   }
3826 }
3827
3828 /*!
3829   Custom event handler
3830 */
3831 bool LightApp_Application::event( QEvent* e )
3832 {
3833   if( e && e->type()==2000 )
3834   {
3835     SALOME_CustomEvent* ce = ( SALOME_CustomEvent* )e;
3836     QString* d = ( QString* )ce->data();
3837     if( SUIT_MessageBox::question(0, tr("WRN_WARNING"),
3838                                   d ? *d : "",
3839                                   SUIT_MessageBox::Yes | SUIT_MessageBox::No,
3840                                   SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes )
3841       showPreferences( tr( "PREF_APP" ) );
3842     if( d )
3843       delete d;
3844     return true;
3845   }
3846   return CAM_Application::event( e );
3847 }
3848
3849 /*! Check data object */
3850 bool LightApp_Application::checkDataObject(LightApp_DataObject* theObj)
3851 {
3852   if (theObj)
3853     {
3854       bool isSuitable = !theObj->entry().isEmpty() &&
3855                         !theObj->componentDataType().isEmpty() &&
3856                         !theObj->name().isEmpty();
3857       return isSuitable;
3858     }
3859
3860   return false;
3861 }
3862
3863 int LightApp_Application::openChoice( const QString& aName )
3864 {
3865   int choice = CAM_Application::openChoice( aName );
3866
3867   if ( choice == OpenExist ) // The document is already open.
3868   {
3869     // Do you want to reload it?
3870     if ( SUIT_MessageBox::question( desktop(), tr( "WRN_WARNING" ), tr( "QUE_DOC_ALREADYOPEN" ).arg( aName ),
3871                                     SUIT_MessageBox::Yes | SUIT_MessageBox::No, SUIT_MessageBox::No ) == SUIT_MessageBox::Yes )
3872       choice = OpenReload;
3873   }
3874
3875   return choice;
3876 }
3877
3878 bool LightApp_Application::openAction( const int choice, const QString& aName )
3879 {
3880   bool res = false;
3881   switch ( choice )
3882   {
3883   case OpenReload:
3884     {
3885       STD_Application* app = 0;
3886       SUIT_Session* session = SUIT_Session::session();
3887       QList<SUIT_Application*> appList = session->applications();
3888       for ( QList<SUIT_Application*>::iterator it = appList.begin(); it != appList.end() && !app; ++it )
3889       {
3890         if ( (*it)->activeStudy() && (*it)->activeStudy()->studyName() == aName )
3891           app = ::qobject_cast<STD_Application*>( *it );
3892       }
3893
3894       if ( app )
3895       {
3896         app->onCloseDoc( false );
3897         appList = session->applications();
3898         STD_Application* other = 0;
3899         for ( QList<SUIT_Application*>::iterator it = appList.begin(); it != appList.end() && !other; ++it )
3900           other = ::qobject_cast<STD_Application*>( *it );
3901
3902         if ( other )
3903           res = other->onOpenDoc( aName );
3904       }
3905     }
3906     break;
3907   default:
3908     res = CAM_Application::openAction( choice, aName );
3909     break;
3910   }
3911
3912   return res;
3913 }
3914
3915 QStringList LightApp_Application::viewManagersTypes() const
3916 {
3917   QStringList aTypesList;
3918   aTypesList += myUserWmTypes;
3919 #ifndef DISABLE_GLVIEWER
3920   aTypesList<<GLViewer_Viewer::Type();
3921 #endif
3922 #ifndef DISABLE_PLOT2DVIEWER
3923   aTypesList<<Plot2d_Viewer::Type();
3924 #endif
3925 #ifndef DISABLE_QXGRAPHVIEWER
3926   aTypesList<<QxScene_Viewer::Type();
3927 #endif
3928 #ifndef DISABLE_OCCVIEWER
3929   aTypesList<<OCCViewer_Viewer::Type();
3930 #endif
3931 #ifndef DISABLE_VTKVIEWER
3932  #ifndef DISABLE_SALOMEOBJECT
3933   aTypesList<<SVTK_Viewer::Type();
3934  #else
3935   aTypesList<<VTKViewer_Viewer::Type();
3936  #endif
3937 #endif
3938   return aTypesList;
3939 }
3940 /*!
3941  * Removes all view managers of known types
3942  * Other view managers are ignored
3943  */
3944 void LightApp_Application::clearKnownViewManagers()
3945 {
3946   QStringList aTypesList = viewManagersTypes();
3947   QList<SUIT_ViewManager*> aMgrList;
3948   viewManagers( aMgrList );
3949   foreach (SUIT_ViewManager* aMgr, aMgrList) {
3950     if (aTypesList.contains(aMgr->getType()))
3951       removeViewManager(aMgr);
3952   }
3953 }
3954
3955 /*!
3956   Copy of current selection
3957  */
3958 void LightApp_Application::onCopy()
3959 {
3960   LightApp_Module* m = dynamic_cast<LightApp_Module*>( activeModule() );
3961   if( m )
3962     m->copy();
3963 }
3964
3965 /*!
3966   Paste of current data in clipboard
3967  */
3968 void LightApp_Application::onPaste()
3969 {
3970   LightApp_Module* m = dynamic_cast<LightApp_Module*>( activeModule() );
3971   if( m )
3972     m->paste();
3973 }
3974
3975 /*!
3976   Browse (i.e. set focus on) the published objects
3977   \param theIsApplyAndClose - flag indicating that the dialog for creating objects
3978                               has been accepted by Ok (or Apply & Close) button
3979   \param theIsOptimizedBrowsing - flag switching to optimized browsing mode
3980                                   (to select the first published object only)
3981   \return entry of the selected object
3982  */
3983 QString LightApp_Application::browseObjects( const QStringList& theEntryList,
3984                                              const bool theIsApplyAndClose,
3985                                              const bool theIsOptimizedBrowsing )
3986 {
3987   QString aResult;
3988   if( SUIT_ResourceMgr* aResourceMgr = resourceMgr() )
3989   {
3990     int aBrowsePolicy = aResourceMgr->integerValue( "ObjectBrowser", "browse_published_object", (int)BP_Never );
3991     switch( aBrowsePolicy )
3992     {
3993       case BP_Never:
3994         return aResult;
3995       case BP_ApplyAndClose:
3996         if( !theIsApplyAndClose )
3997           return aResult;
3998       case BP_Always:
3999       default:
4000         break;
4001     }
4002   }
4003
4004   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( activeStudy() );
4005   if( !aStudy )
4006     return aResult;
4007
4008   SUIT_DataBrowser* anOB = objectBrowser();
4009   if( !anOB )
4010     return aResult;
4011
4012   SUIT_AbstractModel* aModel = dynamic_cast<SUIT_AbstractModel*>( anOB->model() );
4013   if( !aModel )
4014     return aResult;
4015
4016   QStringListIterator anIter( theEntryList );
4017   if( theIsOptimizedBrowsing )
4018   {
4019     // go to the last entry
4020     anIter.toBack();
4021     if( anIter.hasPrevious() )
4022       anIter.previous();
4023   }
4024
4025   // scroll to each entry in the list
4026   // (in optimized mode - to the last entry only)
4027   QString anEntry;
4028   LightApp_DataObject* anObject = 0;
4029   while( anIter.hasNext() )
4030   {
4031     anEntry = anIter.next();
4032     if( !anEntry.isEmpty() )
4033     {
4034       anObject = aStudy->findObjectByEntry( anEntry );
4035       if( anObject )
4036       {
4037         QModelIndex anIndex = aModel->index( anObject );
4038         anOB->treeView()->scrollTo( anIndex );
4039       }
4040     }
4041   }
4042
4043   // always select the last object
4044   if( anObject && !anEntry.isEmpty() )
4045   {
4046     QList<SUIT_Selector*> aSelectorList;
4047     selectionMgr()->selectors( "ObjectBrowser", aSelectorList );
4048     if( !aSelectorList.isEmpty() )
4049     {
4050       if( LightApp_OBSelector* aSelector = dynamic_cast<LightApp_OBSelector*>( aSelectorList.first() ) )
4051       {
4052         bool anIsAutoBlock = aSelector->autoBlock();
4053
4054         // temporarily disable auto block, to emit LightApp_SelectionMgr::currentSelectionChanged() signal
4055         aSelector->setAutoBlock( false );
4056
4057         SUIT_DataOwnerPtrList aList;
4058 #ifndef DISABLE_SALOMEOBJECT
4059         Handle(SALOME_InteractiveObject) aSObj = new SALOME_InteractiveObject
4060           ( anObject->entry().toLatin1().constData(),
4061             anObject->componentDataType().toLatin1().constData(),
4062             anObject->name().toLatin1().constData() );
4063         LightApp_DataOwner* owner = new LightApp_DataOwner( aSObj  );
4064 #else
4065         LightApp_DataOwner* owner = new LightApp_DataOwner( anEntry );
4066 #endif
4067
4068         aList.append( owner );
4069         selectionMgr()->setSelected( aList );
4070         aResult = anEntry;
4071
4072         // restore auto block flag
4073         aSelector->setAutoBlock( anIsAutoBlock );
4074       }
4075     }
4076   }
4077
4078   return aResult;
4079 }
4080
4081 SUIT_DataObject* LightApp_Application::findObject( const QString& id ) const
4082 {
4083   LightApp_Study* study = dynamic_cast<LightApp_Study*>( activeStudy() );
4084   return study ? study->findObjectByEntry( id ) : 0;
4085 }
4086
4087 /*!
4088   Checks that an object can be renamed.
4089   \param entry entry of the object
4090   \brief Return \c true if object can be renamed
4091 */
4092 bool LightApp_Application::renameAllowed( const QString& /*entry*/) const {
4093   return false;
4094 }
4095
4096 /*!
4097   Rename object by entry.
4098   \param entry entry of the object
4099   \param name new name of the object
4100   \brief Return \c true if rename operation finished successfully, \c false otherwise.
4101 */
4102 bool LightApp_Application::renameObject( const QString& entry, const QString& ) {
4103   return false;
4104 }
4105
4106 /*! Process standard messages from desktop */
4107 void LightApp_Application::onDesktopMessage( const QString& message )
4108 {
4109   const QString sectionSeparator = "/";
4110
4111   if ( message.toLower() == "updateobjectbrowser" ||
4112        message.toLower() == "updateobjbrowser" ) {
4113     // update object browser
4114     updateObjectBrowser();
4115   }
4116   else {
4117     QStringList data = message.split( sectionSeparator );
4118     if ( data.count() > 1 ) {
4119       QString msgType = data[0].trimmed();
4120       LightApp_Module* sMod = 0;
4121       CAM_Module* mod = module( msgType );
4122       if ( !mod )
4123         mod = module( moduleTitle( msgType ) );
4124       if ( mod && mod->inherits( "LightApp_Module" ) )
4125         sMod = (LightApp_Module*)mod;
4126
4127       if ( msgType.toLower() == "preferences" ) {
4128         // requested preferences change: should be given as "preferences/<section>/<name>/<value>"
4129         // for example "preferences/Study/multi_file_dump/true"
4130         if ( data.count() > 3 ) {
4131           QString section = data[1].trimmed();
4132           QString param   = data[2].trimmed();
4133           QString value   = QStringList( data.mid(3) ).join( sectionSeparator );
4134           resourceMgr()->setValue( section, param, value );
4135         }
4136       }
4137       else if ( sMod ) {
4138         // received message for the module
4139         QString msg = QStringList( data.mid(1) ).join( sectionSeparator );
4140         sMod->message( msg );
4141       }
4142     }
4143   }
4144 }
4145
4146 /*!
4147   Internal method. 
4148   Returns all top level toolbars.
4149   Note : Result list contains only main window toolbars, not including toolbars from viewers.
4150 */
4151 QList<QToolBar*> LightApp_Application::findToolBars() {
4152   QList<QToolBar*> aResult;
4153   QList<QToolBar*> tbList = qFindChildren<QToolBar*>( desktop() );
4154   for ( QList<QToolBar*>::iterator tit = tbList.begin(); tit != tbList.end(); ++tit ) {
4155     QToolBar* tb = *tit;    
4156     QObject* po = Qtx::findParent( tb, "QMainWindow" );
4157     if ( po != desktop() )
4158       continue; 
4159     aResult.append(tb);
4160   }
4161   return aResult;
4162 }
4163
4164 /*!
4165   Internal method to parse toolbars and dockable windows state.
4166  */
4167 QByteArray LightApp_Application::processState(QByteArray& input, const bool processWin,const bool processTb, QByteArray defaultState) {
4168
4169   QByteArray aRes;
4170   bool hasDefaultState  = !defaultState.isEmpty();
4171   bool isDockWinWriten = false;
4172   if(processWin && processTb) {
4173     aRes = input;
4174   } else if(!processWin && !processTb ) {
4175     if(hasDefaultState)
4176       aRes = defaultState;
4177   } else {
4178     QDataStream aData(&aRes, QIODevice::WriteOnly);
4179     QList<QToolBar*> aToolBars = findToolBars();
4180
4181     QStringList aNames;
4182     for ( QList<QToolBar*>::iterator tit = aToolBars.begin(); tit != aToolBars.end(); ++tit ) { 
4183       QToolBar* tb = *tit;
4184       aNames.append(tb->objectName());
4185     }
4186
4187     int toolBarMarkerIndex = getToolbarMarkerIndex(input,aNames);
4188     QDataStream anInputData(&input, QIODevice::ReadOnly);
4189     if(toolBarMarkerIndex < 0)
4190       return aRes;
4191
4192     int toolBarMarkerIndexDef;
4193     if(hasDefaultState) {
4194       toolBarMarkerIndexDef = getToolbarMarkerIndex(defaultState, aNames);
4195       if(toolBarMarkerIndexDef < 0)
4196         return aRes;      
4197     }
4198     QDataStream anInputDataDef(&defaultState, QIODevice::ReadOnly);
4199
4200     QDataStream* aTargetData = 0;
4201     int          aTargetIndex = -1;
4202
4203     if(processWin) {
4204       //Write date from users settings
4205       aTargetData = &anInputData;
4206       aTargetIndex = toolBarMarkerIndex;
4207     } else {
4208       //Write date from default settings
4209       if(hasDefaultState) {
4210         aTargetData = &anInputDataDef;
4211         aTargetIndex = toolBarMarkerIndexDef;   
4212       }
4213     }
4214
4215     if(aTargetData && aTargetIndex >= 0 ) {
4216       aTargetData->device()->seek(0);
4217       while( aTargetData->device()->pos() < aTargetIndex ) {
4218         uchar ch;
4219         *aTargetData >> ch;
4220         aData<<ch;
4221       }
4222       isDockWinWriten = true;
4223     }
4224     
4225     aTargetData = 0;
4226     aTargetIndex = -1;
4227
4228     if(processTb) {
4229       aTargetData = &anInputData;
4230       aTargetIndex = toolBarMarkerIndex;
4231     } else {
4232       if(hasDefaultState) {
4233         aTargetData = &anInputDataDef;
4234         aTargetIndex = toolBarMarkerIndexDef;   
4235       }      
4236     }
4237
4238     if(aTargetData && aTargetIndex >= 0) {
4239       int index;
4240       if(!isDockWinWriten ) {
4241         //Write version marker
4242         int marker, version;
4243         aTargetData->device()->seek(0);
4244         *aTargetData >> marker;
4245         *aTargetData >> version;
4246         aData << marker;
4247         aData << version;
4248         aData << (uchar) QDockWidgetMarker;
4249         aData << (int) 0;
4250         int shift = 4*sizeof(int) + sizeof(QSize);
4251         index = aTargetIndex - shift;
4252       } else {
4253         index = aTargetIndex;
4254       }
4255       
4256       aTargetData->device()->seek(index);
4257       while(!aTargetData->atEnd()) {
4258         uchar ch;
4259         *aTargetData >> ch;
4260         aData << ch;
4261       }
4262     } else { // Not treat toolbars
4263       aData << (uchar) QToolBarMarker;
4264       aData << (int) 0; //Nb toolbars = 0
4265     }
4266   }
4267   return aRes;
4268 }
4269
4270 /*!
4271   \brief Emits operationFinished signal.
4272   \param theModuleName the name of the module which perfomed the operation
4273   \param theOperationName the operation name
4274   \param theEntryList the list of the created objects entries
4275 */
4276 void LightApp_Application::emitOperationFinished( const QString& theModuleName,
4277                                                   const QString& theOperationName,
4278                                                   const QStringList& theEntryList )
4279 {
4280   emit operationFinished( theModuleName, theOperationName, theEntryList );
4281 }