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