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