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