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