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