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