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