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