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