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