]> SALOME platform Git repositories - modules/gui.git/blob - src/SalomeApp/SalomeApp_Application.cxx
Salome HOME
848427ac287d968daf2434eb1d6415fd476ccd63
[modules/gui.git] / src / SalomeApp / SalomeApp_Application.cxx
1 // File:      SalomeApp_Application.cxx
2 // Created:   10/22/2004 3:23:45 PM
3 // Author:    Sergey LITONIN
4 // Copyright (C) CEA 2004
5
6 #include "SalomeApp_PyInterp.h" // WARNING! This include must be the first!
7
8 #include "SalomeApp_Application.h"
9
10 #include "SalomeApp_Study.h"
11 #include "SalomeApp_Module.h"
12 #include "SalomeApp_OBFilter.h"
13 #include "SalomeApp_DataModel.h"
14 #include "SalomeApp_DataObject.h"
15 #include "SalomeApp_EventFilter.h"
16 #include "SalomeApp_WidgetContainer.h"
17
18 #include "SalomeApp_AboutDlg.h"
19 #include "SalomeApp_ModuleDlg.h"
20 #include "SalomeApp_Preferences.h"
21 #include "SalomeApp_PreferencesDlg.h"
22 #include "SalomeApp_StudyPropertiesDlg.h"
23 #include "SalomeApp_CheckFileDlg.h"
24
25 #include "SalomeApp_GLSelector.h"
26 #include "SalomeApp_OBSelector.h"
27 #include "SalomeApp_OCCSelector.h"
28 #include "SalomeApp_VTKSelector.h"
29 #include "SalomeApp_SelectionMgr.h"
30
31 #include <LogWindow.h>
32
33 #include <GLViewer_Viewer.h>
34 #include <GLViewer_ViewManager.h>
35
36 #include <Plot2d_ViewManager.h>
37 #include <SPlot2d_ViewModel.h>
38
39 #include <OCCViewer_ViewManager.h>
40 #include <SOCC_ViewModel.h>
41
42 #include <SVTK_ViewModel.h>
43 #include <SVTK_ViewManager.h>
44
45 #include <STD_TabDesktop.h>
46
47 #include "STD_LoadStudiesDlg.h"
48
49 #include <SUIT_Tools.h>
50 #include <SUIT_Session.h>
51
52 #include <QtxToolBar.h>
53 #include <QtxMRUAction.h>
54 #include <QtxDockAction.h>
55 #include <QtxResourceEdit.h>
56
57 #include <OB_Browser.h>
58
59 #include <PythonConsole_PyConsole.h>
60
61 #include <SUIT_FileDlg.h>
62 #include <SUIT_MessageBox.h>
63 #include <SUIT_ResourceMgr.h>
64 #include <SUIT_ActionOperation.h>
65
66 #include <Utils_ORB_INIT.hxx>
67 #include <Utils_SINGLETON.hxx>
68 #include <SALOME_ModuleCatalog_impl.hxx>
69 #include <SALOME_LifeCycleCORBA.hxx>
70
71 #include <qmap.h>
72 #include <qdir.h>
73 #include <qlabel.h>
74 #include <qimage.h>
75 #include <qaction.h>
76 #include <qmenubar.h>
77 #include <qcombobox.h>
78 #include <qmessagebox.h>
79 #include <qapplication.h>
80 #include <qlistbox.h>
81 #include <qregexp.h>
82
83 #include "SALOMEDS_StudyManager.hxx"
84
85 #include "SALOME_ListIteratorOfListIO.hxx"
86 #include "SALOME_ListIO.hxx"
87
88 #define OBJECT_BROWSER_WIDTH 300
89
90 /*!Image for empty icon.*/
91 static const char* imageEmptyIcon[] = {
92 "20 20 1 1",
93 ".      c None",
94 "....................",
95 "....................",
96 "....................",
97 "....................",
98 "....................",
99 "....................",
100 "....................",
101 "....................",
102 "....................",
103 "....................",
104 "....................",
105 "....................",
106 "....................",
107 "....................",
108 "....................",
109 "....................",
110 "....................",
111 "....................",
112 "....................",
113 "...................."};
114
115 /*!Create new instance of SalomeApp_Application.*/
116 extern "C" SALOMEAPP_EXPORT SUIT_Application* createApplication()
117 {
118   return new SalomeApp_Application();
119 }
120
121 SalomeApp_Preferences* SalomeApp_Application::_prefs_ = 0;
122
123 /*
124   Class       : SalomeApp_Application
125   Description : Application containing SalomeApp module
126 */
127
128 /*!Constructor.*/
129 SalomeApp_Application::SalomeApp_Application()
130 : CAM_Application( false ),
131 myPrefs( 0 )
132 {
133   STD_TabDesktop* desk = new STD_TabDesktop();
134
135   setDesktop( desk );
136
137   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
138   QPixmap aLogo = aResMgr->loadPixmap( "SalomeApp", tr( "APP_DEFAULT_ICO" ), false );
139
140   desktop()->setIcon( aLogo );
141   desktop()->setDockableMenuBar( true );
142   desktop()->setDockableStatusBar( false );
143
144   clearViewManagers();
145
146   mySelMgr = new SalomeApp_SelectionMgr( this );
147
148   connect( desk, SIGNAL( closing( SUIT_Desktop*, QCloseEvent* ) ),
149            this, SLOT( onDesktopClosing( SUIT_Desktop*, QCloseEvent* ) ) );
150
151   connect( mySelMgr, SIGNAL( selectionChanged() ), this, SLOT( onSelection() ) );
152 }
153
154 /*!Destructor.
155  *\li Save window geometry.
156  *\li Save desktop geometry.
157  *\li Save resource maneger.
158  *\li Delete selection manager.
159  *\li Destroy event filter.
160  */
161 SalomeApp_Application::~SalomeApp_Application()
162 {
163   saveWindowsGeometry();
164
165   if ( resourceMgr() )
166   {
167     if ( desktop() )
168       desktop()->saveGeometry( resourceMgr(), "desktop" );
169     resourceMgr()->save();
170   }
171
172   delete mySelMgr;
173
174   SalomeApp_EventFilter::Destroy();
175 }
176
177 /*!Start application.*/
178 void SalomeApp_Application::start()
179 {
180   if ( desktop() )
181     desktop()->loadGeometry( resourceMgr(), "desktop" );
182
183   CAM_Application::start();
184
185   QAction* a = action( ViewWindowsId );
186   if ( a && a->inherits( "QtxDockAction" ) )
187     ((QtxDockAction*)a)->setAutoPlace( true );
188
189   SalomeApp_EventFilter::Init();
190
191   updateWindows();
192   updateViewManagers();
193
194   putInfo( "" );
195 }
196
197 /*!Gets application name.*/
198 QString SalomeApp_Application::applicationName() const
199 {
200   return tr( "APP_NAME" );
201 }
202
203 /*!Gets application version.*/
204 QString SalomeApp_Application::applicationVersion() const
205 {
206   static QString _app_version;
207
208   if ( _app_version.isEmpty() )
209   {
210     QString path( ::getenv( "GUI_ROOT_DIR" ) );
211     if ( !path.isEmpty() )
212       path += QDir::separator();
213     path += QString( "bin/salome/VERSION" );
214
215     QFile vf( path );
216     if ( vf.open( IO_ReadOnly ) )
217     {
218       QString line;
219       vf.readLine( line, 1024 );
220       vf.close();
221
222       if ( !line.isEmpty() )
223       {
224         while ( !line.isEmpty() && line.at( line.length() - 1 ) == QChar( '\n' ) )
225           line.remove( line.length() - 1, 1 );
226
227         int idx = line.findRev( ":" );
228         if ( idx != -1 )
229           _app_version = line.mid( idx + 1 ).stripWhiteSpace();
230       }
231     }
232   }
233
234   return _app_version;
235 }
236
237 /*!Load module by \a name.*/
238 CAM_Module* SalomeApp_Application::loadModule( const QString& name )
239 {
240   CAM_Module* mod = CAM_Application::loadModule( name );
241   if ( mod )
242   {
243     connect( this, SIGNAL( studyOpened() ), mod, SLOT( onModelOpened() ) );
244     connect( this, SIGNAL( studySaved() ),  mod, SLOT( onModelSaved() ) );
245     connect( this, SIGNAL( studyClosed() ), mod, SLOT( onModelClosed() ) );
246   }
247   return mod;
248 }
249
250 /*!Activate module by \a modName*/
251 bool SalomeApp_Application::activateModule( const QString& modName )
252 {
253   QString actName;
254   CAM_Module* prevMod = activeModule();
255
256   if ( prevMod )
257     actName = prevMod->moduleName();
258
259   if ( actName == modName )
260     return true;
261
262   saveWindowsGeometry();
263
264   bool status = CAM_Application::activateModule( modName );
265
266   updateModuleActions();
267
268   if ( !status )
269     return false;
270
271   updateWindows();
272   updateViewManagers();
273
274   return true;
275 }
276
277 /*!Gets selection manager.*/
278 SalomeApp_SelectionMgr* SalomeApp_Application::selectionMgr() const
279 {
280   return mySelMgr;
281 }
282
283 /*!Create actions:*/
284 void SalomeApp_Application::createActions()
285 {
286   STD_Application::createActions();
287
288   SUIT_Desktop* desk = desktop();
289   SUIT_ResourceMgr* resMgr = resourceMgr();
290
291   //! Dump study
292   createAction( DumpStudyId, tr( "TOT_DESK_FILE_DUMP_STUDY" ), QIconSet(),
293                 tr( "MEN_DESK_FILE_DUMP_STUDY" ), tr( "PRP_DESK_FILE_DUMP_STUDY" ),
294                 0, desk, false, this, SLOT( onDumpStudy() ) );
295
296   //! Load script
297   createAction( LoadScriptId, tr( "TOT_DESK_FILE_LOAD_SCRIPT" ), QIconSet(),
298                 tr( "MEN_DESK_FILE_LOAD_SCRIPT" ), tr( "PRP_DESK_FILE_LOAD_SCRIPT" ),
299                 0, desk, false, this, SLOT( onLoadScript() ) );
300
301   //! Properties
302   createAction( PropertiesId, tr( "TOT_DESK_PROPERTIES" ), QIconSet(),
303                 tr( "MEN_DESK_PROPERTIES" ), tr( "PRP_DESK_PROPERTIES" ),
304                 0, desk, false, this, SLOT( onProperties() ) );
305
306   //! Preferences
307   createAction( PreferencesId, tr( "TOT_DESK_PREFERENCES" ), QIconSet(),
308                 tr( "MEN_DESK_PREFERENCES" ), tr( "PRP_DESK_PREFERENCES" ),
309                 CTRL+Key_P, desk, false, this, SLOT( onPreferences() ) );
310
311   //! MRU
312   QtxMRUAction* mru = new QtxMRUAction( tr( "TOT_DESK_MRU" ), tr( "MEN_DESK_MRU" ), desk );
313   connect( mru, SIGNAL( activated( QString ) ), this, SLOT( onMRUActivated( QString ) ) );
314   registerAction( MRUId, mru );
315
316   //! default icon for neutral point ('SALOME' module)
317   QPixmap defIcon = resMgr->loadPixmap( "SalomeApp", tr( "APP_DEFAULT_ICO" ), false );
318   if ( defIcon.isNull() )
319     defIcon = QPixmap( imageEmptyIcon );
320
321   //! default icon for any module
322   QPixmap modIcon = resMgr->loadPixmap( "SalomeApp", tr( "APP_MODULE_ICO" ), false );
323   if ( modIcon.isNull() )
324     modIcon = QPixmap( imageEmptyIcon );
325
326   QToolBar* modTBar = new QtxToolBar( true, desk );
327   modTBar->setLabel( tr( "INF_TOOLBAR_MODULES" ) );
328
329   QActionGroup* modGroup = new QActionGroup( this );
330   modGroup->setExclusive( true );
331   modGroup->setUsesDropDown( true );
332
333   QAction* a = createAction( -1, tr( "APP_NAME" ), defIcon, tr( "APP_NAME" ),
334                              tr( "PRP_APP_MODULE" ), 0, desk, true );
335   modGroup->add( a );
336   myActions.insert( QString(), a );
337
338   QMap<QString, QString> iconMap;
339   moduleIconNames( iconMap );
340
341   const int iconSize = 20;
342
343   modGroup->addTo( modTBar );
344   modTBar->addSeparator();
345
346   QStringList modList;
347   modules( modList, false );
348
349   for ( QStringList::Iterator it = modList.begin(); it != modList.end(); ++it )
350   {
351     if ( (*it).isEmpty() )
352       continue;
353
354     QString iconName;
355     if ( iconMap.contains( *it ) )
356       iconName = iconMap[*it];
357
358     QString modName = moduleName( *it );
359
360     QPixmap icon = resMgr->loadPixmap( modName, iconName, false );
361     if ( icon.isNull() )
362       icon = modIcon;
363
364     icon.convertFromImage( icon.convertToImage().smoothScale( iconSize, iconSize, QImage::ScaleMin ) );
365
366     QAction* a = createAction( -1, *it, icon, *it, tr( "PRP_MODULE" ).arg( *it ), 0, desk, true );
367     a->addTo( modTBar );
368     modGroup->add( a );
369
370     myActions.insert( *it, a );
371   }
372
373   SUIT_Tools::simplifySeparators( modTBar );
374
375   //! New window
376
377   int windowMenu = createMenu( tr( "MEN_DESK_WINDOW" ), -1, 100 );
378   int newWinMenu = createMenu( tr( "MEN_DESK_NEWWINDOW" ), windowMenu, -1, 0 );
379   createMenu( separator(), windowMenu, -1, 1 );
380
381   QMap<int, int> accelMap;
382   accelMap[NewGLViewId]  = ALT+Key_G;
383   accelMap[NewPlot2dId]  = ALT+Key_P;
384   accelMap[NewOCCViewId] = ALT+Key_O;
385   accelMap[NewVTKViewId] = ALT+Key_K;
386
387   for ( int id = NewGLViewId; id <= NewVTKViewId; id++ )
388   {
389     QAction* a = createAction( id, tr( QString( "NEW_WINDOW_%1" ).arg( id - NewGLViewId ) ), QIconSet(),
390                                tr( QString( "NEW_WINDOW_%1" ).arg( id - NewGLViewId ) ),
391                                tr( QString( "NEW_WINDOW_%1" ).arg( id - NewGLViewId ) ),
392                                accelMap.contains( id ) ? accelMap[id] : 0, desk, false, this, SLOT( onNewWindow() ) );
393     createMenu( a, newWinMenu, -1 );
394   }
395   connect( modGroup, SIGNAL( selected( QAction* ) ), this, SLOT( onModuleActivation( QAction* ) ) );
396
397   int fileMenu = createMenu( tr( "MEN_DESK_FILE" ), -1 );
398
399   createMenu( DumpStudyId, fileMenu, 10, -1 );
400   createMenu( separator(), fileMenu, -1, 15, -1 );
401   createMenu( LoadScriptId, fileMenu, 10, -1 );
402   createMenu( separator(), fileMenu, -1, 15, -1 );
403   createMenu( PropertiesId, fileMenu, 10, -1 );
404   createMenu( separator(), fileMenu, -1, 15, -1 );
405   createMenu( PreferencesId, fileMenu, 15, -1 );
406   createMenu( separator(), fileMenu, -1, 15, -1 );
407
408   /*
409   createMenu( separator(), fileMenu, -1, 100, -1 );
410   createMenu( MRUId, fileMenu, 100, -1 );
411   createMenu( separator(), fileMenu, -1, 100, -1 );
412   */
413 }
414
415 /*!On module activation action.*/
416 void SalomeApp_Application::onModuleActivation( QAction* a )
417 {
418   if ( !a )
419     return;
420
421   QString modName = a->menuText();
422   if ( modName == tr( "APP_NAME" ) )
423     modName = QString::null;
424
425   // Force user to create/open a study before module activation
426   QMap<QString, QString> iconMap;
427   moduleIconNames( iconMap );
428   QPixmap icon = resourceMgr()->loadPixmap( moduleName( modName ), iconMap[ modName ], false );
429   if ( icon.isNull() )
430     icon = resourceMgr()->loadPixmap( "SalomeApp", tr( "APP_MODULE_BIG_ICO" ), false ); // default icon for any module
431
432   bool cancelled = false;
433   while ( !modName.isEmpty() && !activeStudy() && !cancelled ){
434     SalomeApp_ModuleDlg aDlg( desktop(), modName, icon );
435     int res = aDlg.exec();
436
437     switch ( res ){
438     case 1:
439       onNewDoc();
440       break;
441     case 2:
442       onOpenDoc();
443       break;
444     case 3:
445       //onLoadStudy();
446       //break;
447     case 0:
448     default:
449       putInfo( tr("INF_CANCELLED") );
450       myActions[QString()]->setOn( true );
451       cancelled = true;
452     }
453   }
454
455   if ( !cancelled )
456     activateModule( modName );
457 }
458
459 /*!Default module activation.*/
460 QString SalomeApp_Application::defaultModule() const
461 {
462   QStringList aModuleNames;
463   modules( aModuleNames, false ); // obtain a complete list of module names for the current configuration
464   //! If there's the one and only module --> activate it automatically
465   //! TODO: Possible improvement - default module can be taken from preferences
466   return aModuleNames.count() > 1 ? "" : ( aModuleNames.count() ? aModuleNames.first() : "" );
467 }
468
469 /*!On new window slot.*/
470 void SalomeApp_Application::onNewWindow()
471 {
472   const QObject* obj = sender();
473   if ( !obj || !obj->inherits( "QAction" ) )
474     return;
475
476   QString type;
477   int id = actionId( (QAction*)obj );
478   switch ( id )
479   {
480   case NewGLViewId:
481     type = GLViewer_Viewer::Type();
482     break;
483   case NewPlot2dId:
484     type = Plot2d_Viewer::Type();
485     break;
486   case NewOCCViewId:
487     type = OCCViewer_Viewer::Type();
488     break;
489   case NewVTKViewId:
490     type = VTKViewer_Viewer::Type();
491     break;
492   }
493
494   if ( !type.isEmpty() )
495     createViewManager( type );
496 }
497
498 //=======================================================================
499 //  name    : onNewDoc
500 /*! Purpose : SLOT. Create new document*/
501 //=======================================================================
502 void SalomeApp_Application::onNewDoc()
503 {
504   SUIT_Study* study = activeStudy();
505
506   saveWindowsGeometry();
507
508   CAM_Application::onNewDoc();
509
510   if ( !study ) // new study will be create in THIS application
511   {
512     updateWindows();
513     updateViewManagers();
514   }
515 }
516
517 //=======================================================================
518 // name    : onOpenDoc
519 /*! Purpose : SLOT. Open new document*/
520 //=======================================================================
521 void SalomeApp_Application::onOpenDoc()
522 {
523   SUIT_Study* study = activeStudy();
524   saveWindowsGeometry();
525
526   CAM_Application::onOpenDoc();
527
528   if ( !study ) // new study will be create in THIS application
529   {
530     updateWindows();
531     updateViewManagers();
532   }
533 }
534
535 /*! Purpose : SLOT. Open new document with \a aName.*/
536 bool SalomeApp_Application::onOpenDoc( const QString& aName )
537 {
538   bool res = CAM_Application::onOpenDoc( aName );
539
540   QAction* a = action( MRUId );
541   if ( a && a->inherits( "QtxMRUAction" ) )
542   {
543     QtxMRUAction* mru = (QtxMRUAction*)a;
544     if ( res )
545       mru->insert( aName );
546     else
547       mru->remove( aName );
548   }
549   return res;
550 }
551
552 /*!SLOT. Load document.*/
553 void SalomeApp_Application::onLoadDoc()
554 {
555   QString name, studyname, ext;
556
557   STD_LoadStudiesDlg aDlg( desktop(), TRUE);
558
559   std::vector<std::string> List = studyMgr()->GetOpenStudies();
560
561   SUIT_Session* aSession = SUIT_Session::session();
562   QPtrList<SUIT_Application> aAppList = aSession->applications();
563   SUIT_Application* aApp = 0;
564
565   for (unsigned int ind = 0; ind < List.size(); ind++) {
566      studyname = List[ind].c_str();
567      //Add to list only unloaded studies
568      bool isAlreadyOpen = false;
569      for ( QPtrListIterator<SUIT_Application> it( aAppList ); it.current() && !isAlreadyOpen; ++it )
570        {
571          aApp = it.current();
572          if(!aApp || !aApp->activeStudy()) continue;
573          if ( aApp->activeStudy()->studyName() == studyname ) isAlreadyOpen = true;
574        }
575
576      if ( !isAlreadyOpen ) aDlg.ListComponent->insertItem( studyname );
577   }
578
579   int retVal = aDlg.exec();
580   studyname = aDlg.ListComponent->currentText();
581
582   if (retVal == QDialog::Rejected)
583     return;
584
585   if ( studyname.isNull() || studyname.isEmpty() )
586     return;
587
588   name = studyname;
589   name.replace( QRegExp(":"), "/" );
590
591   if(onLoadDoc(name)) {
592      updateWindows();
593      updateViewManagers();
594      updateObjectBrowser(true);
595   }
596 }
597
598
599 /*!SLOT. Load document with \a aName.*/
600 bool SalomeApp_Application::onLoadDoc( const QString& aName )
601 {
602   bool res = CAM_Application::onLoadDoc( aName );
603
604   /*jfa tmp:QAction* a = action( MRUId );
605   if ( a && a->inherits( "QtxMRUAction" ) )
606   {
607     QtxMRUAction* mru = (QtxMRUAction*)a;
608     if ( res )
609       mru->insert( aName );
610     else
611       mru->remove( aName );
612   }*/
613   return res;
614 }
615
616 /*!Private SLOT. Selection.*/
617 void SalomeApp_Application::onSelection()
618 {
619   onSelectionChanged();
620
621   if ( activeModule() && activeModule()->inherits( "SalomeApp_Module" ) )
622     ((SalomeApp_Module*)activeModule())->selectionChanged();
623 }
624
625 /*!SLOT. Copy objects to study maneger from selection maneger..*/
626 void SalomeApp_Application::onCopy()
627 {
628   SALOME_ListIO list;
629   SalomeApp_SelectionMgr* mgr = selectionMgr();
630   mgr->selectedObjects(list);
631
632   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
633   if(study == NULL) return;
634
635   _PTR(Study) stdDS = study->studyDS();
636   if(!stdDS) return;
637
638   SALOME_ListIteratorOfListIO it( list );
639   if(it.More())
640     {
641       _PTR(SObject) so = stdDS->FindObjectID(it.Value()->getEntry());
642       try {
643         studyMgr()->Copy(so);
644         onSelectionChanged();
645       }
646       catch(...) {
647       }
648     }
649 }
650
651 /*!SLOT. Paste objects to study maneger from selection manager.*/
652 void SalomeApp_Application::onPaste()
653 {
654   SALOME_ListIO list;
655   SalomeApp_SelectionMgr* mgr = selectionMgr();
656   mgr->selectedObjects(list);
657
658   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
659   if(study == NULL) return;
660
661   _PTR(Study) stdDS = study->studyDS();
662   if(!stdDS) return;
663
664   SALOME_ListIteratorOfListIO it( list );
665   if(it.More())
666     {
667       _PTR(SObject) so = stdDS->FindObjectID(it.Value()->getEntry());
668       try {
669         studyMgr()->Paste(so);
670         updateObjectBrowser( true );
671         updateActions(); //SRN: BugID IPAL9377, case 3
672       }
673       catch(...) {
674       }
675     }
676 }
677
678 /*!Sets enable or disable some actions on selection changed.*/
679 void SalomeApp_Application::onSelectionChanged()
680 {
681    SALOME_ListIO list;
682    SalomeApp_SelectionMgr* mgr = selectionMgr();
683    mgr->selectedObjects(list);
684
685    SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
686    if(study == NULL) return;
687
688    _PTR(Study) stdDS = study->studyDS();
689    if(!stdDS) return;
690
691    QAction* qaction;
692
693    SALOME_ListIteratorOfListIO it( list );
694    if(it.More() && list.Extent() == 1)
695    {
696       _PTR(SObject) so = stdDS->FindObjectID(it.Value()->getEntry());
697
698       qaction = action(EditCopyId);
699       if(studyMgr()->CanCopy(so) ) qaction->setEnabled(true);
700       else qaction->setEnabled(false);
701
702       qaction = action(EditPasteId);
703       if( studyMgr()->CanPaste(so) ) qaction->setEnabled(true);
704       else qaction->setEnabled(false);
705    }
706    else {
707      qaction = action(EditCopyId);
708      qaction->setEnabled(false);
709      qaction = action(EditPasteId);
710      qaction->setEnabled(false);
711    }
712 }
713
714 /*!Update object browser.*/
715 void SalomeApp_Application::onRefresh()
716 {
717   updateObjectBrowser( true );
718 }
719
720 /*!Private SLOT. */
721 void SalomeApp_Application::onOpenWith()
722 {
723   QApplication::setOverrideCursor( Qt::waitCursor );
724   SALOME_ListIO aList;
725   SalomeApp_SelectionMgr* mgr = selectionMgr();
726   mgr->selectedObjects(aList);
727   if (aList.Extent() != 1)
728     {
729       QApplication::restoreOverrideCursor();
730       return;
731     }
732   Handle(SALOME_InteractiveObject) aIObj = aList.First();
733   QString aModuleName(aIObj->getComponentDataType());
734   QString aModuleTitle = moduleTitle(aModuleName);
735   activateModule(aModuleTitle);
736   QApplication::restoreOverrideCursor();
737 }
738
739 bool SalomeApp_Application::useStudy(const QString& theName)
740 {
741   createEmptyStudy();
742   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(activeStudy());
743   bool res = false;
744   if (aStudy)
745     res = aStudy->loadDocument( theName );
746   updateDesktopTitle();
747   updateCommandsStatus();
748   return res;
749 }
750
751 /*!Set active study.
752  *\param study - SUIT_Study.
753  */
754 void SalomeApp_Application::setActiveStudy( SUIT_Study* study )
755 {
756   CAM_Application::setActiveStudy( study );
757
758   activateWindows();
759 }
760
761 //=======================================================================
762 // name    : createNewStudy
763 /*! Purpose : Create new study*/
764 //=======================================================================
765 SUIT_Study* SalomeApp_Application::createNewStudy()
766 {
767   SalomeApp_Study* aStudy = new SalomeApp_Study( this );
768
769   // Set up processing of major study-related events
770   connect( aStudy, SIGNAL( created( SUIT_Study* ) ), this, SLOT( onStudyCreated( SUIT_Study* ) ) );
771   connect( aStudy, SIGNAL( opened ( SUIT_Study* ) ), this, SLOT( onStudyOpened ( SUIT_Study* ) ) );
772   connect( aStudy, SIGNAL( saved  ( SUIT_Study* ) ), this, SLOT( onStudySaved  ( SUIT_Study* ) ) );
773   connect( aStudy, SIGNAL( closed ( SUIT_Study* ) ), this, SLOT( onStudyClosed ( SUIT_Study* ) ) );
774
775   return aStudy;
776 }
777
778 //=======================================================================
779 // name    : createNewStudy
780 /*! Purpose : Enable/Disable menu items and toolbar buttons. Rebuild menu*/
781 //=======================================================================
782 void SalomeApp_Application::updateCommandsStatus()
783 {
784   CAM_Application::updateCommandsStatus();
785
786   for ( int id = NewGLViewId; id <= NewVTKViewId; id++ )
787   {
788     QAction* a = action( id );
789     if ( a )
790       a->setEnabled( activeStudy() );
791   }
792
793   // Dump study menu
794   QAction* a = action( DumpStudyId );
795   if ( a )
796     a->setEnabled( activeStudy() );
797
798   // Load script menu
799   a = action( LoadScriptId );
800   if ( a )
801     a->setEnabled( activeStudy() );
802
803   a = action( PropertiesId );
804   if( a )
805     a->setEnabled( activeStudy() );
806
807   a = action(EditCopyId);
808   a->setEnabled(false);
809   a = action(EditPasteId);
810   a->setEnabled(false);
811 }
812
813 //=======================================================================
814 // name    : onHelpAbout
815 /*! Purpose : SLOT. Display "About" message box*/
816 //=======================================================================
817 void SalomeApp_Application::onHelpAbout()
818 {
819   SalomeApp_AboutDlg* dlg = new SalomeApp_AboutDlg( applicationName(), applicationVersion(), desktop() );
820   dlg->exec();
821   delete dlg;
822 }
823
824 QWidget* SalomeApp_Application::window( const int flag, const int studyId ) const
825 {
826   QWidget* wid = 0;
827
828   int sId = studyId;
829   if ( sId < 0 )
830   {
831     if ( !activeStudy() )
832       return 0;
833     else
834       sId = activeStudy()->id();
835   }
836
837   if ( myWindows.contains( flag ) )
838     wid = myWindows[flag]->widget( sId );
839
840   return wid;
841 }
842
843 /*!Adds window to application.
844  *\param wid - QWidget
845  *\param flag - key wor window
846  *\param studyId - study id
847  * Flag used how identificator of window in windows list.
848  */
849 void SalomeApp_Application::addWindow( QWidget* wid, const int flag, const int studyId )
850 {
851   if ( !wid )
852     return;
853
854   int sId = studyId;
855   if ( sId < 0 )
856   {
857     if ( !activeStudy() )
858       return;
859     else
860       sId = activeStudy()->id();
861   }
862
863   if ( !myWindows.contains( flag ) )
864   {
865     QMap<int, int> winMap;
866     currentWindows( winMap );
867
868     myWindows.insert( flag, new SalomeApp_WidgetContainer( flag, desktop() ) );
869     if ( winMap.contains( flag ) )
870       desktop()->moveDockWindow( myWindows[flag], (Dock)winMap[flag] );
871
872     myWindows[flag]->setResizeEnabled( true );
873     myWindows[flag]->setCloseMode( QDockWindow::Always );
874     myWindows[flag]->setName( QString( "dock_window_%1" ).arg( flag ) );
875   }
876
877   QFont f;
878   if( wid->inherits( "PythonConsole" ) )
879     f = ( ( PythonConsole* )wid )->font();
880   else
881     f = wid->font();
882
883   myWindows[flag]->insert( sId, wid );
884   wid->setFont( f );
885
886   setWindowShown( flag, !myWindows[flag]->isEmpty() );
887 }
888
889 /*!Remove window from application.
890  *\param flag - key wor window
891  *\param studyId - study id
892  * Flag used how identificator of window in windows list.
893  */
894 void SalomeApp_Application::removeWindow( const int flag, const int studyId )
895 {
896   if ( !myWindows.contains( flag ) )
897     return;
898
899   int sId = studyId;
900   if ( sId < 0 )
901   {
902     if ( !activeStudy() )
903       return;
904     else
905       sId = activeStudy()->id();
906   }
907
908   QWidget* wid = myWindows[flag]->widget( sId );
909   myWindows[flag]->remove( sId );
910   delete wid;
911
912   setWindowShown( flag, !myWindows[flag]->isEmpty() );
913 }
914
915 /*!Gets window.
916  *\param flag - key wor window
917  *\param studyId - study id
918  * Flag used how identificator of window in windows list.
919  */
920 QWidget* SalomeApp_Application::getWindow( const int flag, const int studyId )
921 {
922   QWidget* wid = window( flag, studyId );
923   if ( !wid )
924     addWindow( wid = createWindow( flag ), flag, studyId );
925
926   return wid;
927 }
928
929 /*!Check is window visible?(with identificator \a type)*/
930 bool SalomeApp_Application::isWindowVisible( const int type ) const
931 {
932   bool res = false;
933   if ( myWindows.contains( type ) )
934   {
935     SUIT_Desktop* desk = ((SalomeApp_Application*)this)->desktop();
936     res = desk && desk->appropriate( myWindows[type] );
937   }
938   return res;
939 }
940
941 /*!Sets window show or hide.
942  *\param type - window identificator.
943  *\param on   - true/false (window show/hide)
944  */
945 void SalomeApp_Application::setWindowShown( const int type, const bool on )
946 {
947   if ( !desktop() || !myWindows.contains( type ) )
948     return;
949
950   QDockWindow* dw = myWindows[type];
951   desktop()->setAppropriate( dw, on );
952   on ? dw->show() : dw->hide();
953 }
954
955 OB_Browser* SalomeApp_Application::objectBrowser()
956 {
957   OB_Browser* ob = 0;
958   QWidget* wid = getWindow( WT_ObjectBrowser );
959   if ( wid->inherits( "OB_Browser" ) )
960     ob = (OB_Browser*)wid;
961   return ob;
962 }
963
964 /*!Gets "LogWindow".*/
965 LogWindow* SalomeApp_Application::logWindow()
966 {
967   LogWindow* lw = 0;
968   QWidget* wid = getWindow( WT_LogWindow );
969   if ( wid->inherits( "LogWindow" ) )
970     lw = (LogWindow*)wid;
971   return lw;
972 }
973
974 /*!Get "PythonConsole"*/
975 PythonConsole* SalomeApp_Application::pythonConsole()
976 {
977   PythonConsole* console = 0;
978   QWidget* wid = getWindow( WT_PyConsole );
979   if ( wid->inherits( "PythonConsole" ) )
980     console = (PythonConsole*)wid;
981   return console;
982 }
983
984 /*!Gets preferences.*/
985 SalomeApp_Preferences* SalomeApp_Application::preferences() const
986 {
987   return preferences( false );
988 }
989
990 /*!Gets view manager*/
991 SUIT_ViewManager* SalomeApp_Application::getViewManager( const QString& vmType, const bool create )
992 {
993   SUIT_ViewManager* aVM = viewManager( vmType );
994   SUIT_ViewManager* anActiveVM = CAM_Application::activeViewManager();
995
996   if ( anActiveVM && anActiveVM->getType() == vmType )
997     aVM = anActiveVM;
998
999   if ( aVM && create )
1000   {
1001     if ( !aVM->getActiveView() )
1002       aVM->createView();
1003     else
1004       aVM->getActiveView()->setFocus();
1005   }
1006   else if ( create )
1007     aVM = createViewManager( vmType );
1008
1009   return aVM;
1010 }
1011
1012 /*!Create view manager.*/
1013 SUIT_ViewManager* SalomeApp_Application::createViewManager( const QString& vmType )
1014 {
1015   SUIT_ResourceMgr* resMgr = resourceMgr();
1016
1017   SUIT_ViewManager* viewMgr = 0;
1018   if ( vmType == GLViewer_Viewer::Type() )
1019   {
1020     viewMgr = new GLViewer_ViewManager( activeStudy(), desktop() );
1021     new SalomeApp_GLSelector( (GLViewer_Viewer2d*)viewMgr->getViewModel(), mySelMgr );
1022   }
1023   else if ( vmType == Plot2d_Viewer::Type() )
1024   {
1025     viewMgr = new Plot2d_ViewManager( activeStudy(), desktop() );
1026     viewMgr->setViewModel( new SPlot2d_Viewer() );// custom view model, which extends SALOME_View interface
1027   }
1028   else if ( vmType == OCCViewer_Viewer::Type() )
1029   {
1030     viewMgr = new OCCViewer_ViewManager( activeStudy(), desktop() );
1031     SOCC_Viewer* vm = new SOCC_Viewer();
1032     vm->setBackgroundColor( resMgr->colorValue( "OCCViewer", "background", vm->backgroundColor() ) );
1033     vm->setTrihedronSize( resMgr->integerValue( "OCCViewer", "trihedron_size", vm->trihedronSize() ) );
1034     int u( 1 ), v( 1 );
1035     vm->isos( u, v );
1036     u = resMgr->integerValue( "OCCViewer", "iso_number_u", u );
1037     v = resMgr->integerValue( "OCCViewer", "iso_number_v", v );
1038     vm->setIsos( u, v );
1039     viewMgr->setViewModel( vm );// custom view model, which extends SALOME_View interface
1040     new SalomeApp_OCCSelector( (OCCViewer_Viewer*)viewMgr->getViewModel(), mySelMgr );
1041   }
1042   else if ( vmType == SVTK_Viewer::Type() )
1043   {
1044     viewMgr = new SVTK_ViewManager( activeStudy(), desktop() );
1045     SVTK_Viewer* vm = (SVTK_Viewer*)viewMgr->getViewModel();
1046     vm->setBackgroundColor( resMgr->colorValue( "VTKViewer", "background", vm->backgroundColor() ) );
1047     vm->setTrihedronSize( resMgr->integerValue( "VTKViewer", "trihedron_size", vm->trihedronSize() ) );
1048     new SalomeApp_VTKSelector((SVTK_Viewer*)viewMgr->getViewModel(),mySelMgr);
1049   }
1050
1051   if ( !viewMgr )
1052     return 0;
1053
1054   addViewManager( viewMgr );
1055   SUIT_ViewWindow* viewWin = viewMgr->createViewWindow();
1056
1057   if ( viewWin && desktop() )
1058     viewWin->resize( (int)( desktop()->width() * 0.6 ), (int)( desktop()->height() * 0.6 ) );
1059
1060   connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
1061            this, SLOT( onCloseView( SUIT_ViewManager* ) ) );
1062
1063   return viewMgr;
1064 }
1065
1066 void SalomeApp_Application::onCloseView( SUIT_ViewManager* theVM )
1067 {
1068   removeViewManager( theVM );
1069 }
1070
1071 /*!Private SLOT. On study created.*/
1072 void SalomeApp_Application::onStudyCreated( SUIT_Study* theStudy )
1073 {
1074   SUIT_DataObject* aRoot = 0;
1075   if ( theStudy && theStudy->root() )
1076   {
1077     aRoot = theStudy->root();
1078     //aRoot->setName( tr( "DATA_MODELS" ) );
1079   }
1080   if ( objectBrowser() != 0 )
1081     objectBrowser()->setRootObject( aRoot );
1082
1083   activateModule( defaultModule() );
1084
1085   activateWindows();
1086 }
1087
1088 /*!Private SLOT. On study opened.*/
1089 void SalomeApp_Application::onStudyOpened( SUIT_Study* theStudy )
1090 {
1091   SUIT_DataObject* aRoot = 0;
1092   if ( theStudy && theStudy->root() )
1093   {
1094     aRoot = theStudy->root();
1095     //aRoot->dump();
1096   }
1097   if ( objectBrowser() != 0 ) {
1098     objectBrowser()->setRootObject( aRoot );
1099   }
1100
1101   activateModule( defaultModule() );
1102
1103   activateWindows();
1104
1105   emit studyOpened();
1106 }
1107
1108 void SalomeApp_Application::onStudySaved( SUIT_Study* )
1109 {
1110   emit studySaved();
1111 }
1112
1113 /*!Private SLOT. On study closed.*/
1114 void SalomeApp_Application::onStudyClosed( SUIT_Study* )
1115 {
1116   emit studyClosed();
1117
1118   activateModule( "" );
1119
1120   saveWindowsGeometry();
1121 }
1122
1123 /*!Private SLOT. On dump study.*/
1124 void SalomeApp_Application::onDumpStudy( )
1125 {
1126   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( activeStudy() );
1127   if ( !appStudy ) return;
1128   _PTR(Study) aStudy = appStudy->studyDS();
1129
1130   QStringList aFilters;
1131   aFilters.append( tr( "PYTHON_FILES_FILTER" ) );
1132
1133   SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg( desktop(), false, tr("PUBLISH_IN_STUDY"), true, true);
1134   fd->setCaption( tr( "TOT_DESK_FILE_DUMP_STUDY" ) );
1135   fd->setFilters( aFilters );
1136   fd->SetChecked(true);
1137   fd->exec();
1138   QString aFileName = fd->selectedFile();
1139   bool toPublish = fd->IsChecked();
1140   delete fd;
1141
1142   if(!aFileName.isEmpty()) {
1143     QFileInfo aFileInfo(aFileName);
1144     aStudy->DumpStudy( aFileInfo.dirPath( true ).latin1(), aFileInfo.baseName().latin1(), toPublish );
1145   }
1146 }
1147
1148 /*!Private SLOT. On load script.*/
1149 void SalomeApp_Application::onLoadScript( )
1150 {
1151   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( activeStudy() );
1152   if ( !appStudy ) return;
1153   _PTR(Study) aStudy = appStudy->studyDS();
1154
1155   if ( aStudy->GetProperties()->IsLocked() ) {
1156     SUIT_MessageBox::warn1 ( desktop(),
1157                              QObject::tr("WRN_WARNING"),
1158                              QObject::tr("WRN_STUDY_LOCKED"),
1159                              QObject::tr("BUT_OK") );
1160     return;
1161   }
1162
1163   QStringList filtersList;
1164   filtersList.append(tr("PYTHON_FILES_FILTER"));
1165   filtersList.append(tr("ALL_FILES_FILTER"));
1166
1167   QString aFile = SUIT_FileDlg::getFileName( desktop(), "", filtersList, tr( "TOT_DESK_FILE_LOAD_SCRIPT" ), true, true );
1168
1169   if ( !aFile.isEmpty() )
1170   {
1171     QString command = QString("execfile(\"%1\")").arg(aFile);
1172
1173     PythonConsole* pyConsole = pythonConsole();
1174
1175     if ( pyConsole )
1176       pyConsole->exec( command );
1177   }
1178 }
1179
1180 /*!Private SLOT. On preferences.*/
1181 void SalomeApp_Application::onPreferences()
1182 {
1183   QApplication::setOverrideCursor( Qt::waitCursor );
1184
1185   SalomeApp_PreferencesDlg* prefDlg = new SalomeApp_PreferencesDlg( preferences( true ), desktop());
1186
1187   QApplication::restoreOverrideCursor();
1188
1189   if ( !prefDlg )
1190     return;
1191
1192   prefDlg->exec();
1193
1194   delete prefDlg;
1195 }
1196
1197 /*!Private SLOT. On open document with name \a aName.*/
1198 void SalomeApp_Application::onMRUActivated( QString aName )
1199 {
1200   onOpenDoc( aName );
1201 }
1202
1203 /*!Private SLOT. On preferences changed.*/
1204 void SalomeApp_Application::onPreferenceChanged( QString& modName, QString& section, QString& param )
1205 {
1206   SalomeApp_Module* sMod = 0;
1207   CAM_Module* mod = module( modName );
1208   if ( mod && mod->inherits( "SalomeApp_Module" ) )
1209     sMod = (SalomeApp_Module*)mod;
1210
1211   if ( sMod )
1212     sMod->preferencesChanged( section, param );
1213   else
1214     preferencesChanged( section, param );
1215 }
1216
1217 /*!Gets file filter.
1218  *\retval QString "(*.hdf)"
1219  */
1220 QString SalomeApp_Application::getFileFilter() const
1221 {
1222   return "(*.hdf)";
1223 }
1224
1225 /*!Remove all windows from study.*/
1226 void SalomeApp_Application::beforeCloseDoc( SUIT_Study* s )
1227 {
1228   CAM_Application::beforeCloseDoc( s );
1229
1230   for ( WindowMap::ConstIterator itr = myWindows.begin(); s && itr != myWindows.end(); ++itr )
1231     removeWindow( itr.key(), s->id() );
1232 }
1233
1234 /*!Update actions.*/
1235 void SalomeApp_Application::updateActions()
1236 {
1237   updateCommandsStatus();
1238 }
1239
1240 /*!Create window.*/
1241 QWidget* SalomeApp_Application::createWindow( const int flag )
1242 {
1243   QWidget* wid = 0;
1244
1245   SUIT_ResourceMgr* resMgr = resourceMgr();
1246
1247   if ( flag == WT_ObjectBrowser )
1248   {
1249     OB_Browser* ob = new OB_Browser( desktop() );
1250     ob->setAutoUpdate( true );
1251     ob->setAutoOpenLevel( 1 );
1252     ob->setCaption( tr( "OBJECT_BROWSER" ) );
1253     ob->resize( OBJECT_BROWSER_WIDTH, ob->height() );
1254     ob->setFilter( new SalomeApp_OBFilter( selectionMgr() ) );
1255
1256     ob->setNameTitle( tr( "OBJ_BROWSER_NAME" ) );
1257
1258     bool autoSize = resMgr->booleanValue( "ObjectBrowser", "auto_size", false );
1259     for ( int i = SalomeApp_DataObject::CT_Value; i <= SalomeApp_DataObject::CT_RefEntry; i++ )
1260     {
1261       ob->addColumn( tr( QString().sprintf( "OBJ_BROWSER_COLUMN_%d", i ) ), i );
1262       ob->setColumnShown( i, resMgr->booleanValue( "ObjectBrowser",
1263                                                    QString().sprintf( "visibility_column_%d", i ), true ) );
1264     }
1265     ob->setWidthMode( autoSize ? QListView::Maximum : QListView::Manual );
1266
1267     // Create OBSelector
1268     new SalomeApp_OBSelector( ob, mySelMgr );
1269
1270     wid = ob;
1271
1272     ob->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
1273   }
1274   else if ( flag == WT_PyConsole )
1275   {
1276     PythonConsole* pyCons = new PythonConsole( desktop(), new SalomeApp_PyInterp() );
1277     pyCons->setCaption( tr( "PYTHON_CONSOLE" ) );
1278     pyCons->setFont( resMgr->fontValue( "PyConsole", "font" ) );
1279     wid = pyCons;
1280
1281     //    pyCons->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
1282   }
1283   else if ( flag == WT_LogWindow )
1284   {
1285     LogWindow* logWin = new LogWindow( desktop() );
1286     logWin->setCaption( tr( "LOG_WINDOW" ) );
1287     wid = logWin;
1288
1289     logWin->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
1290   }
1291
1292   return wid;
1293 }
1294
1295 /*!Default windows(Object Browser, Python Console).
1296  * Adds to map \a aMap.
1297  */
1298 void SalomeApp_Application::defaultWindows( QMap<int, int>& aMap ) const
1299 {
1300   aMap.insert( WT_ObjectBrowser, Qt::DockLeft );
1301   aMap.insert( WT_PyConsole, Qt::DockBottom );
1302   //  aMap.insert( WT_LogWindow, Qt::DockBottom );
1303 }
1304
1305 /*!Default view manager.*/
1306 void SalomeApp_Application::defaultViewManagers( QStringList& ) const
1307 {
1308   /*!Do nothing.*/
1309 }
1310
1311 /*!Gets preferences.
1312  * Create preferences, if \a crt = true.
1313  */
1314 SalomeApp_Preferences* SalomeApp_Application::preferences( const bool crt ) const
1315 {
1316   if ( myPrefs )
1317     return myPrefs;
1318
1319   SalomeApp_Application* that = (SalomeApp_Application*)this;
1320
1321   if ( !_prefs_ && crt )
1322   {
1323     _prefs_ = new SalomeApp_Preferences( resourceMgr() );
1324     that->createPreferences( _prefs_ );
1325   }
1326
1327   that->myPrefs = _prefs_;
1328
1329   QPtrList<SUIT_Application> appList = SUIT_Session::session()->applications();
1330   for ( QPtrListIterator<SUIT_Application> appIt ( appList ); appIt.current(); ++appIt )
1331   {
1332     if ( !appIt.current()->inherits( "SalomeApp_Application" ) )
1333       continue;
1334
1335     SalomeApp_Application* app = (SalomeApp_Application*)appIt.current();
1336
1337     QStringList modNameList;
1338     app->modules( modNameList, false );
1339     for ( QStringList::const_iterator it = modNameList.begin(); it != modNameList.end(); ++it )
1340     {
1341       int id = _prefs_->addPreference( *it );
1342       _prefs_->setItemProperty( id, "info", tr( "PREFERENCES_NOT_LOADED" ).arg( *it ) );
1343     }
1344
1345     ModuleList modList;
1346     app->modules( modList );
1347     for ( ModuleListIterator itr( modList ); itr.current(); ++itr )
1348     {
1349       SalomeApp_Module* mod = 0;
1350       if ( itr.current()->inherits( "SalomeApp_Module" ) )
1351         mod = (SalomeApp_Module*)itr.current();
1352
1353       if ( mod && !_prefs_->hasModule( mod->moduleName() ) )
1354       {
1355         int modCat = _prefs_->addPreference( mod->moduleName() );
1356         _prefs_->setItemProperty( modCat, "info", QString::null );
1357         mod->createPreferences();
1358       }
1359     }
1360   }
1361
1362   connect( myPrefs, SIGNAL( preferenceChanged( QString&, QString&, QString& ) ),
1363            this, SLOT( onPreferenceChanged( QString&, QString&, QString& ) ) );
1364
1365   return myPrefs;
1366 }
1367
1368 /*!Add new module to application.*/
1369 void SalomeApp_Application::moduleAdded( CAM_Module* mod )
1370 {
1371   CAM_Application::moduleAdded( mod );
1372
1373   SalomeApp_Module* salomeMod = 0;
1374   if ( mod && mod->inherits( "SalomeApp_Module" ) )
1375     salomeMod = (SalomeApp_Module*)mod;
1376
1377   if ( myPrefs && salomeMod && !myPrefs->hasModule( salomeMod->moduleName() ) )
1378   {
1379     int modCat = myPrefs->addPreference( mod->moduleName() );
1380     myPrefs->setItemProperty( modCat, "info", QString::null );
1381     salomeMod->createPreferences();
1382   }
1383 }
1384
1385 /*!Create preferences.*/
1386 void SalomeApp_Application::createPreferences( SalomeApp_Preferences* pref )
1387 {
1388   if ( !pref )
1389     return;
1390
1391   int salomeCat = pref->addPreference( tr( "PREF_CATEGORY_SALOME" ) );
1392
1393   int genTab = pref->addPreference( tr( "PREF_TAB_GENERAL" ), salomeCat );
1394   int studyGroup = pref->addPreference( tr( "PREF_GROUP_STUDY" ), genTab );
1395   pref->setItemProperty( studyGroup, "columns", 1 );
1396
1397   pref->addPreference( tr( "PREF_MULTI_FILE" ), studyGroup, SalomeApp_Preferences::Bool, "Study", "multi_file" );
1398   pref->addPreference( tr( "PREF_ASCII_FILE" ), studyGroup, SalomeApp_Preferences::Bool, "Study", "ascii_file" );
1399   int undoPref = pref->addPreference( tr( "PREF_UNDO_LEVEL" ), studyGroup, SalomeApp_Preferences::IntSpin, "Study", "undo_level" );
1400   pref->setItemProperty( undoPref, "min", 1 );
1401   pref->setItemProperty( undoPref, "max", 100 );
1402
1403   int extgroup = pref->addPreference( tr( "PREF_GROUP_EXT_BROWSER" ), genTab );
1404   pref->setItemProperty( extgroup, "columns", 1 );
1405   int apppref = pref->addPreference( tr( "PREF_APP" ), extgroup, SalomeApp_Preferences::File, "ExternalBrowser", "application" );
1406   pref->setItemProperty( apppref, "existing", true );
1407   pref->setItemProperty( apppref, "flags", QFileInfo::ExeUser );
1408
1409   pref->addPreference( tr( "PREF_PARAM" ), extgroup, SalomeApp_Preferences::String, "ExternalBrowser", "parameters" );
1410
1411   int pythonConsoleGroup = pref->addPreference( tr( "PREF_GROUP_PY_CONSOLE" ), genTab );
1412   pref->setItemProperty( pythonConsoleGroup, "columns", 1 );
1413   pref->addPreference( tr( "PREF_FONT" ), pythonConsoleGroup, SalomeApp_Preferences::Font, "PyConsole", "font" );
1414
1415
1416
1417   int obTab = pref->addPreference( tr( "PREF_TAB_OBJBROWSER" ), salomeCat );
1418   int defCols = pref->addPreference( tr( "PREF_GROUP_DEF_COLUMNS" ), obTab );
1419   for ( int i = SalomeApp_DataObject::CT_Value; i <= SalomeApp_DataObject::CT_RefEntry; i++ )
1420   {
1421     pref->addPreference( tr( QString().sprintf( "OBJ_BROWSER_COLUMN_%d", i ) ), defCols,
1422                          SalomeApp_Preferences::Bool, "ObjectBrowser", QString().sprintf( "visibility_column_%d", i ) );
1423   }
1424   pref->setItemProperty( defCols, "columns", 1 );
1425
1426   int objSetGroup = pref->addPreference( tr( "PREF_OBJ_BROWSER_SETTINGS" ), obTab );
1427   pref->addPreference( tr( "PREF_AUTO_SIZE" ), objSetGroup, SalomeApp_Preferences::Bool, "ObjectBrowser", "auto_size" );
1428
1429   int viewTab = pref->addPreference( tr( "PREF_TAB_VIEWERS" ), salomeCat );
1430
1431   int occGroup = pref->addPreference( tr( "PREF_GROUP_OCCVIEWER" ), viewTab );
1432
1433   int vtkGroup = pref->addPreference( tr( "PREF_GROUP_VTKVIEWER" ), viewTab );
1434   pref->setItemProperty( occGroup, "columns", 1 );
1435   pref->setItemProperty( vtkGroup, "columns", 1 );
1436
1437   int occTS = pref->addPreference( tr( "PREF_TRIHEDRON_SIZE" ), occGroup,
1438                                    SalomeApp_Preferences::IntSpin, "OCCViewer", "trihedron_size" );
1439   pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), occGroup,
1440                        SalomeApp_Preferences::Color, "OCCViewer", "background" );
1441
1442   pref->setItemProperty( occTS, "min", 1 );
1443   pref->setItemProperty( occTS, "max", 150 );
1444
1445   int isoU = pref->addPreference( tr( "PREF_ISOS_U" ), occGroup,
1446                                   SalomeApp_Preferences::IntSpin, "OCCViewer", "iso_number_u" );
1447   int isoV = pref->addPreference( tr( "PREF_ISOS_V" ), occGroup,
1448                                   SalomeApp_Preferences::IntSpin, "OCCViewer", "iso_number_v" );
1449
1450   pref->setItemProperty( isoU, "min", 0 );
1451   pref->setItemProperty( isoU, "max", 100000 );
1452
1453   pref->setItemProperty( isoV, "min", 0 );
1454   pref->setItemProperty( isoV, "max", 100000 );
1455
1456   int vtkTS = pref->addPreference( tr( "PREF_TRIHEDRON_SIZE" ), vtkGroup,
1457                                    SalomeApp_Preferences::IntSpin, "VTKViewer", "trihedron_size" );
1458   pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), vtkGroup,
1459                        SalomeApp_Preferences::Color, "VTKViewer", "background" );
1460
1461   pref->setItemProperty( vtkTS, "min", 1 );
1462   pref->setItemProperty( vtkTS, "max", 150 );
1463
1464   int dirTab = pref->addPreference( tr( "PREF_TAB_DIRECTORIES" ), salomeCat );
1465   int dirGroup = pref->addPreference( tr( "PREF_GROUP_DIRECTORIES" ), dirTab );
1466   pref->setItemProperty( dirGroup, "columns", 1 );
1467   pref->addPreference( tr( "" ), dirGroup,
1468                        SalomeApp_Preferences::DirList, "FileDlg", "QuickDirList" );
1469 }
1470
1471 void SalomeApp_Application::preferencesChanged( const QString& sec, const QString& param )
1472 {
1473   SUIT_ResourceMgr* resMgr = resourceMgr();
1474   if ( !resMgr )
1475     return;
1476
1477   if ( sec == QString( "OCCViewer" ) && param == QString( "trihedron_size" ) )
1478   {
1479     int sz = resMgr->integerValue( sec, param, -1 );
1480     QPtrList<SUIT_ViewManager> lst;
1481     viewManagers( OCCViewer_Viewer::Type(), lst );
1482     for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current() && sz >= 0; ++it )
1483     {
1484       SUIT_ViewModel* vm = it.current()->getViewModel();
1485       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
1486         continue;
1487
1488       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
1489       occVM->setTrihedronSize( sz );
1490       occVM->getAISContext()->UpdateCurrentViewer();
1491     }
1492   }
1493
1494   if ( sec == QString( "VTKViewer" ) && param == QString( "trihedron_size" ) )
1495   {
1496     int sz = resMgr->integerValue( sec, param, -1 );
1497     QPtrList<SUIT_ViewManager> lst;
1498     viewManagers( SVTK_Viewer::Type(), lst );
1499     for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current() && sz >= 0; ++it )
1500     {
1501       SUIT_ViewModel* vm = it.current()->getViewModel();
1502       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
1503         continue;
1504
1505       SVTK_Viewer* vtkVM = (SVTK_Viewer*)vm;
1506       vtkVM->setTrihedronSize( sz );
1507       vtkVM->Repaint();
1508     }
1509   }
1510
1511   if ( sec == QString( "OCCViewer" ) && ( param == QString( "iso_number_u" ) || param == QString( "iso_number_v" ) ) )
1512   {
1513     QPtrList<SUIT_ViewManager> lst;
1514     viewManagers( OCCViewer_Viewer::Type(), lst );
1515     int u = resMgr->integerValue( sec, "iso_number_u" );
1516     int v = resMgr->integerValue( sec, "iso_number_v" );
1517     for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current(); ++it )
1518       ((OCCViewer_Viewer*)it.current())->setIsos( u, v );
1519   }
1520
1521   if( sec=="ObjectBrowser" )
1522   {
1523     if( param=="auto_size" )
1524     {
1525       OB_Browser* ob = objectBrowser();
1526       if( !ob )
1527         return;
1528
1529       bool autoSize = resMgr->booleanValue( "ObjectBrowser", "auto_size", false );
1530       ob->setWidthMode( autoSize ? QListView::Maximum : QListView::Manual );
1531
1532       updateObjectBrowser( false );
1533     }
1534   }
1535
1536   if( sec=="PyConsole" )
1537   {
1538     if( param=="font" )
1539       if( pythonConsole() )
1540         pythonConsole()->setFont( resMgr->fontValue( "PyConsole", "font" ) );
1541   }
1542 }
1543
1544 /*!Update desktop title.*/
1545 void SalomeApp_Application::updateDesktopTitle() {
1546   QString aTitle = applicationName();
1547   QString aVer = applicationVersion();
1548   if ( !aVer.isEmpty() )
1549     aTitle += QString( " " ) + aVer;
1550
1551   if ( activeStudy() )
1552   {
1553     QString sName = SUIT_Tools::file( activeStudy()->studyName().stripWhiteSpace(), false );
1554     if ( !sName.isEmpty() ) {
1555       SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
1556       _PTR(Study) stdDS = study->studyDS();
1557       if(stdDS) {
1558         if ( stdDS->GetProperties()->IsLocked() ) {
1559           aTitle += QString( " - [%1 (%2)]").arg( sName ).arg( tr( "STUDY_LOCKED" ) );
1560         } else {
1561           aTitle += QString( " - [%1]" ).arg( sName );
1562         }
1563       }
1564     }
1565   }
1566
1567   desktop()->setCaption( aTitle );
1568 }
1569
1570 /*!Update windows after close document.*/
1571 void SalomeApp_Application::afterCloseDoc()
1572 {
1573   updateWindows();
1574
1575   CAM_Application::afterCloseDoc();
1576 }
1577
1578 /*!Gets CORBA::ORB_var*/
1579 CORBA::ORB_var SalomeApp_Application::orb()
1580 {
1581   ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
1582   static CORBA::ORB_var _orb = init( qApp->argc(), qApp->argv() );
1583   return _orb;
1584 }
1585
1586 /*!Create and return SALOMEDS_StudyManager.*/
1587 SALOMEDSClient_StudyManager* SalomeApp_Application::studyMgr()
1588 {
1589   static SALOMEDSClient_StudyManager* _sm = new SALOMEDS_StudyManager();
1590   return _sm;
1591 }
1592
1593 /*!Create and return SALOME_NamingService.*/
1594 SALOME_NamingService* SalomeApp_Application::namingService()
1595 {
1596   static SALOME_NamingService* _ns = new SALOME_NamingService( orb() );
1597   return _ns;
1598 }
1599
1600 /*!Create and return SALOME_LifeCycleCORBA.*/
1601 SALOME_LifeCycleCORBA* SalomeApp_Application::lcc()
1602 {
1603   static SALOME_LifeCycleCORBA* _lcc = new SALOME_LifeCycleCORBA( namingService() );
1604   return _lcc;
1605 }
1606
1607 QString SalomeApp_Application::defaultEngineIOR()
1608 {
1609   /// Look for a default module engine (needed for CORBAless modules to use SALOMEDS persistence)
1610   QString anIOR( "" );
1611   CORBA::Object_ptr anEngine = namingService()->Resolve( "/SalomeAppEngine" );
1612   if ( !CORBA::is_nil( anEngine ) )
1613     anIOR = orb()->object_to_string( anEngine );
1614   return anIOR;
1615 }
1616
1617 /*!Adds icon names for modules.*/
1618 void SalomeApp_Application::moduleIconNames( QMap<QString, QString>& iconMap ) const
1619 {
1620   iconMap.clear();
1621
1622   SUIT_ResourceMgr* resMgr = resourceMgr();
1623   if ( !resMgr )
1624     return;
1625
1626   QStringList modList;
1627   modules( modList, false );
1628
1629   for ( QStringList::const_iterator it = modList.begin(); it != modList.end(); ++it )
1630   {
1631     QString modName = *it;
1632     QString modIntr = moduleName( modName );
1633     QString modIcon = resMgr->stringValue( modIntr, "icon", QString::null );
1634
1635     if ( modIcon.isEmpty() )
1636       continue;
1637
1638     if ( SUIT_Tools::extension( modIcon ).isEmpty() )
1639       modIcon += QString( ".png" );
1640
1641     iconMap.insert( modName, modIcon );
1642   }
1643 }
1644
1645 /*!Update module action.*/
1646 void SalomeApp_Application::updateModuleActions()
1647 {
1648   QString modName;
1649   if ( activeModule() )
1650     modName = activeModule()->moduleName();
1651
1652   if ( myActions.contains( modName ) )
1653     myActions[modName]->setOn( true );
1654 }
1655
1656 /*!Gets current windows.
1657  *\param winMap - output current windows map.
1658  */
1659 void SalomeApp_Application::currentWindows( QMap<int, int>& winMap ) const
1660 {
1661   winMap.clear();
1662   if ( !activeStudy() )
1663     return;
1664
1665   if ( activeModule() && activeModule()->inherits( "SalomeApp_Module" ) )
1666     ((SalomeApp_Module*)activeModule())->windows( winMap );
1667   else
1668     defaultWindows( winMap );
1669 }
1670
1671 /*!Gets current view managers.
1672  *\param lst - output current view managers list.
1673  */
1674 void SalomeApp_Application::currentViewManagers( QStringList& lst ) const
1675 {
1676   lst.clear();
1677   if ( !activeStudy() )
1678     return;
1679
1680   if ( activeModule() && activeModule()->inherits( "SalomeApp_Module" ) )
1681     ((SalomeApp_Module*)activeModule())->viewManagers( lst );
1682   else
1683     defaultViewManagers( lst );
1684 }
1685
1686 /*!Update windows.*/
1687 void SalomeApp_Application::updateWindows()
1688 {
1689   QMap<int, int> winMap;
1690   currentWindows( winMap );
1691
1692   for ( QMap<int, int>::ConstIterator it = winMap.begin(); it != winMap.end(); ++it )
1693     getWindow( it.key() );
1694
1695   loadWindowsGeometry();
1696
1697   for ( WindowMap::ConstIterator itr = myWindows.begin(); itr != myWindows.end(); ++itr )
1698     setWindowShown( itr.key(), !itr.data()->isEmpty() && winMap.contains( itr.key() ) );
1699 }
1700
1701 /*!Update view managers.*/
1702 void SalomeApp_Application::updateViewManagers()
1703 {
1704   QStringList lst;
1705   currentViewManagers( lst );
1706
1707   for ( QStringList::const_iterator it = lst.begin(); it != lst.end(); ++it )
1708     getViewManager( *it, true );
1709 }
1710
1711 /*!Load windows geometry.*/
1712 void SalomeApp_Application::loadWindowsGeometry()
1713 {
1714   QtxDockAction* dockMgr = 0;
1715
1716   QAction* a = action( ViewWindowsId );
1717   if ( a && a->inherits( "QtxDockAction" ) )
1718     dockMgr = (QtxDockAction*)a;
1719
1720   if ( !dockMgr )
1721     return;
1722
1723   QString modName;
1724   if ( activeModule() )
1725     modName = moduleLibrary( activeModule()->moduleName(), false );
1726
1727   QString section = QString( "windows_geometry" );
1728   if ( !modName.isEmpty() )
1729     section += QString( "." ) + modName;
1730
1731   dockMgr->loadGeometry( resourceMgr(), section, false );
1732   dockMgr->restoreGeometry();
1733 }
1734
1735 /*!Save windows geometry.*/
1736 void SalomeApp_Application::saveWindowsGeometry()
1737 {
1738   QtxDockAction* dockMgr = 0;
1739
1740   QAction* a = action( ViewWindowsId );
1741   if ( a && a->inherits( "QtxDockAction" ) )
1742     dockMgr = (QtxDockAction*)a;
1743
1744   if ( !dockMgr )
1745     return;
1746
1747   QString modName;
1748   if ( activeModule() )
1749     modName = moduleLibrary( activeModule()->moduleName(), false );
1750
1751   QString section = QString( "windows_geometry" );
1752   if ( !modName.isEmpty() )
1753     section += QString( "." ) + modName;
1754
1755   dockMgr->storeGeometry();
1756   dockMgr->saveGeometry( resourceMgr(), section, false );
1757 }
1758
1759 /*!Activate windows.*/
1760 void SalomeApp_Application::activateWindows()
1761 {
1762   if ( activeStudy() )
1763   {
1764     for ( WindowMap::Iterator itr = myWindows.begin(); itr != myWindows.end(); ++itr )
1765       itr.data()->activate( activeStudy()->id() );
1766   }
1767 }
1768
1769 /*!Private SLOT. On preferences.*/
1770 void SalomeApp_Application::onProperties()
1771 {
1772   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( activeStudy() );
1773   if( !study )
1774     return;
1775
1776   _PTR(StudyBuilder) SB = study->studyDS()->NewBuilder();
1777   SB->NewCommand();
1778
1779   SalomeApp_StudyPropertiesDlg aDlg( desktop() );
1780   int res = aDlg.exec();
1781   if( res==QDialog::Accepted && aDlg.isChanged() )
1782     SB->CommitCommand();
1783   else
1784     SB->AbortCommand();
1785
1786   //study->updateCaptions();
1787   updateDesktopTitle();
1788 }
1789
1790 /*!*/
1791 QString SalomeApp_Application::getFileName( bool open, const QString& initial, const QString& filters,
1792                                             const QString& caption, QWidget* parent )
1793 {
1794   if ( !parent )
1795     parent = desktop();
1796   QStringList fls = QStringList::split( ";;", filters, false );
1797   return SUIT_FileDlg::getFileName( parent, initial, fls, caption, open, true );
1798 }
1799
1800 /*!*/
1801 QString SalomeApp_Application::getDirectory( const QString& initial, const QString& caption, QWidget* parent )
1802 {
1803   if ( !parent )
1804     parent = desktop();
1805   return SUIT_FileDlg::getExistingDirectory( parent, initial, caption, true );
1806 }
1807
1808 /*!*/
1809 QStringList SalomeApp_Application::getOpenFileNames( const QString& initial, const QString& filters,
1810                                                      const QString& caption, QWidget* parent )
1811 {
1812   if ( !parent )
1813     parent = desktop();
1814   QStringList fls = QStringList::split( ";;", filters, false );
1815   return SUIT_FileDlg::getOpenFileNames( parent, initial, fls, caption, true );
1816 }
1817
1818 /*!*/
1819 void SalomeApp_Application::contextMenuPopup( const QString& type, QPopupMenu* thePopup, QString& title )
1820 {
1821   CAM_Application::contextMenuPopup( type, thePopup, title );
1822
1823   OB_Browser* ob = objectBrowser();
1824   if ( !ob || type != ob->popupClientType() )
1825     return;
1826
1827   thePopup->insertSeparator();
1828   thePopup->insertItem( tr( "MEN_REFRESH" ), this, SLOT( onRefresh() ) );
1829
1830   // "Activate module" item should appear only if it's necessary
1831   SALOME_ListIO aList;
1832   SalomeApp_SelectionMgr* mgr = selectionMgr();
1833   mgr->selectedObjects(aList);
1834   if (aList.Extent() != 1)
1835     return;
1836   Handle(SALOME_InteractiveObject) aIObj = aList.First();
1837   QString aModuleName(aIObj->getComponentDataType());
1838   QString aModuleTitle = moduleTitle(aModuleName);
1839   CAM_Module* currentModule = activeModule();
1840   if (currentModule && currentModule->moduleName() == aModuleTitle)
1841     return;
1842   thePopup->insertItem( tr( "MEN_OPENWITH" ), this, SLOT( onOpenWith() ) );
1843 }
1844
1845 /*!Update obect browser*/
1846 void SalomeApp_Application::updateObjectBrowser( const bool updateModels )
1847 {
1848   // update existing data models (already loaded SComponents)
1849   if ( updateModels )
1850   {
1851     for ( ModuleListIterator it = modules(); it.current(); ++it )
1852     {
1853       CAM_DataModel* camDM = it.current()->dataModel();
1854       if ( camDM && camDM->inherits( "SalomeApp_DataModel" ) )
1855         ((SalomeApp_DataModel*)camDM)->update();
1856     }
1857   }
1858   // update "non-existing" (not loaded yet) data models
1859   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
1860   if ( study )
1861   {
1862     _PTR(Study) stdDS = study->studyDS();
1863     if( stdDS )
1864     {
1865       for ( _PTR(SComponentIterator) it ( stdDS->NewComponentIterator() ); it->More(); it->Next() )
1866       {
1867         _PTR(SComponent) aComponent ( it->Value() );
1868
1869         if ( aComponent->ComponentDataType() == "Interface Applicative" )
1870           continue; // skip the magic "Interface Applicative" component
1871
1872         SalomeApp_DataModel::BuildTree( aComponent, study->root(), study, /*skipExisitng=*/true );
1873       }
1874     }
1875   }
1876
1877   if ( objectBrowser() )
1878   {
1879     objectBrowser()->updateGeometry();
1880     objectBrowser()->updateTree();
1881   }
1882 }
1883
1884 /*!Protected SLOT.On desktop activated.*/
1885 void SalomeApp_Application::onDesktopActivated()
1886 {
1887   CAM_Application::onDesktopActivated();
1888   SalomeApp_Module* aModule = dynamic_cast<SalomeApp_Module*>(activeModule());
1889   if(aModule)
1890     aModule->studyActivated();
1891 }
1892
1893 /*!Create empty study.*/
1894 void SalomeApp_Application::createEmptyStudy()
1895 {
1896   CAM_Application::createEmptyStudy();
1897   if ( objectBrowser() )
1898     objectBrowser()->updateTree();
1899 }
1900
1901 /*!Activate module \a mod.*/
1902 bool SalomeApp_Application::activateModule( CAM_Module* mod )
1903 {
1904   bool res = CAM_Application::activateModule( mod );
1905   if ( objectBrowser() )
1906     objectBrowser()->updateTree();
1907   return res;
1908 }