]> SALOME platform Git repositories - modules/gui.git/blob - src/SalomeApp/SalomeApp_Application.cxx
Salome HOME
c86efc7cb841bdb7b3354b114233a68ec319bcb0
[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 stupa - 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   myWindows[flag]->insert( sId, wid );
878
879   setWindowShown( flag, !myWindows[flag]->isEmpty() );
880 }
881
882 /*!Remove window from application.
883  *\param flag - key wor window
884  *\param studyId - study id
885  * Flag used how identificator of window in windows list.
886  */
887 void SalomeApp_Application::removeWindow( const int flag, const int studyId )
888 {
889   if ( !myWindows.contains( flag ) )
890     return;
891
892   int sId = studyId;
893   if ( sId < 0 )
894   {
895     if ( !activeStudy() )
896       return;
897     else
898       sId = activeStudy()->id();
899   }
900
901   QWidget* wid = myWindows[flag]->widget( sId );
902   myWindows[flag]->remove( sId );
903   delete wid;
904
905   setWindowShown( flag, !myWindows[flag]->isEmpty() );
906 }
907
908 /*!Gets window.
909  *\param flag - key wor window
910  *\param studyId - study id
911  * Flag used how identificator of window in windows list.
912  */
913 QWidget* SalomeApp_Application::getWindow( const int flag, const int studyId )
914 {
915   QWidget* wid = window( flag, studyId );
916   if ( !wid )
917     addWindow( wid = createWindow( flag ), flag, studyId );
918
919   return wid;
920 }
921
922 /*!Check*/
923 bool SalomeApp_Application::isWindowVisible( const int type ) const
924 {
925   bool res = false;
926   if ( myWindows.contains( type ) )
927   {
928     SUIT_Desktop* desk = ((SalomeApp_Application*)this)->desktop();
929     res = desk && desk->appropriate( myWindows[type] );
930   }
931   return res;
932 }
933
934 void SalomeApp_Application::setWindowShown( const int type, const bool on )
935 {
936   if ( !desktop() || !myWindows.contains( type ) )
937     return;
938
939   QDockWindow* dw = myWindows[type];
940   desktop()->setAppropriate( dw, on );
941   on ? dw->show() : dw->hide();
942 }
943
944 OB_Browser* SalomeApp_Application::objectBrowser()
945 {
946   OB_Browser* ob = 0;
947   QWidget* wid = getWindow( WT_ObjectBrowser );
948   if ( wid->inherits( "OB_Browser" ) )
949     ob = (OB_Browser*)wid;
950   return ob;
951 }
952
953 LogWindow* SalomeApp_Application::logWindow()
954 {
955   LogWindow* lw = 0;
956   QWidget* wid = getWindow( WT_LogWindow );
957   if ( wid->inherits( "LogWindow" ) )
958     lw = (LogWindow*)wid;
959   return lw;
960 }
961
962 PythonConsole* SalomeApp_Application::pythonConsole()
963 {
964   PythonConsole* console = 0;
965   QWidget* wid = getWindow( WT_PyConsole );
966   if ( wid->inherits( "PythonConsole" ) )
967     console = (PythonConsole*)wid;
968   return console;
969 }
970
971 SalomeApp_Preferences* SalomeApp_Application::preferences() const
972 {
973   return preferences( false );
974 }
975
976 SUIT_ViewManager* SalomeApp_Application::getViewManager( const QString& vmType, const bool create )
977 {
978   SUIT_ViewManager* aVM = viewManager( vmType );
979   SUIT_ViewManager* anActiveVM = CAM_Application::activeViewManager();
980
981   if ( anActiveVM && anActiveVM->getType() == vmType )
982     aVM = anActiveVM;
983
984   if ( aVM && create )
985   {
986     if ( !aVM->getActiveView() )
987       aVM->createView();
988     else
989       aVM->getActiveView()->setFocus();
990   }
991   else if ( create )
992     aVM = createViewManager( vmType );
993
994   return aVM;
995 }
996
997 SUIT_ViewManager* SalomeApp_Application::createViewManager( const QString& vmType )
998 {
999   SUIT_ResourceMgr* resMgr = resourceMgr();
1000
1001   SUIT_ViewManager* viewMgr = 0;
1002   if ( vmType == GLViewer_Viewer::Type() )
1003   {
1004     viewMgr = new GLViewer_ViewManager( activeStudy(), desktop() );
1005     new SalomeApp_GLSelector( (GLViewer_Viewer2d*)viewMgr->getViewModel(), mySelMgr );
1006   }
1007   else if ( vmType == Plot2d_Viewer::Type() )
1008   {
1009     viewMgr = new Plot2d_ViewManager( activeStudy(), desktop() );
1010     viewMgr->setViewModel( new SPlot2d_Viewer() );// custom view model, which extends SALOME_View interface
1011   }
1012   else if ( vmType == OCCViewer_Viewer::Type() )
1013   {
1014     viewMgr = new OCCViewer_ViewManager( activeStudy(), desktop() );
1015     SOCC_Viewer* vm = new SOCC_Viewer();
1016     vm->setBackgroundColor( resMgr->colorValue( "OCCViewer", "background", vm->backgroundColor() ) );
1017     vm->setTrihedronSize( resMgr->integerValue( "OCCViewer", "trihedron_size", vm->trihedronSize() ) );
1018     int u( 1 ), v( 1 );
1019     vm->isos( u, v );
1020     u = resMgr->integerValue( "OCCViewer", "iso_number_u", u );
1021     v = resMgr->integerValue( "OCCViewer", "iso_number_v", v );
1022     vm->setIsos( u, v );
1023     viewMgr->setViewModel( vm );// custom view model, which extends SALOME_View interface
1024     new SalomeApp_OCCSelector( (OCCViewer_Viewer*)viewMgr->getViewModel(), mySelMgr );
1025   }
1026   else if ( vmType == SVTK_Viewer::Type() )
1027   {
1028     viewMgr = new SVTK_ViewManager( activeStudy(), desktop() );
1029     SVTK_Viewer* vm = (SVTK_Viewer*)viewMgr->getViewModel();
1030     vm->setBackgroundColor( resMgr->colorValue( "VTKViewer", "background", vm->backgroundColor() ) );
1031     vm->setTrihedronSize( resMgr->integerValue( "VTKViewer", "trihedron_size", vm->trihedronSize() ) );
1032     new SalomeApp_VTKSelector((SVTK_Viewer*)viewMgr->getViewModel(),mySelMgr);
1033   }
1034
1035   if ( !viewMgr )
1036     return 0;
1037
1038   addViewManager( viewMgr );
1039   SUIT_ViewWindow* viewWin = viewMgr->createViewWindow();
1040
1041   if ( viewWin && desktop() )
1042     viewWin->resize( (int)( desktop()->width() * 0.6 ), (int)( desktop()->height() * 0.6 ) );
1043
1044   connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
1045            this, SLOT( onCloseView( SUIT_ViewManager* ) ) );
1046
1047   return viewMgr;
1048 }
1049
1050 void SalomeApp_Application::onCloseView( SUIT_ViewManager* theVM )
1051 {
1052   removeViewManager( theVM );
1053 }
1054
1055 void SalomeApp_Application::onStudyCreated( SUIT_Study* theStudy )
1056 {
1057   SUIT_DataObject* aRoot = 0;
1058   if ( theStudy && theStudy->root() )
1059   {
1060     aRoot = theStudy->root();
1061     //aRoot->setName( tr( "DATA_MODELS" ) );
1062   }
1063   if ( objectBrowser() != 0 )
1064     objectBrowser()->setRootObject( aRoot );
1065
1066   activateModule( defaultModule() );
1067
1068   activateWindows();
1069 }
1070
1071 void SalomeApp_Application::onStudyOpened( SUIT_Study* theStudy )
1072 {
1073   SUIT_DataObject* aRoot = 0;
1074   if ( theStudy && theStudy->root() )
1075   {
1076     aRoot = theStudy->root();
1077     //aRoot->dump();
1078   }
1079   if ( objectBrowser() != 0 ) {
1080     objectBrowser()->setRootObject( aRoot );
1081   }
1082
1083   activateModule( defaultModule() );
1084
1085   activateWindows();
1086
1087   emit studyOpened();
1088 }
1089
1090 void SalomeApp_Application::onStudySaved( SUIT_Study* )
1091 {
1092   emit studySaved();
1093 }
1094
1095 void SalomeApp_Application::onStudyClosed( SUIT_Study* )
1096 {
1097   emit studyClosed();
1098
1099   activateModule( "" );
1100
1101   saveWindowsGeometry();
1102 }
1103
1104 void SalomeApp_Application::onDumpStudy( )
1105 {
1106   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( activeStudy() );
1107   if ( !appStudy ) return;
1108   _PTR(Study) aStudy = appStudy->studyDS();
1109
1110   QStringList aFilters;
1111   aFilters.append( tr( "PYTHON_FILES_FILTER" ) );
1112
1113   SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg( desktop(), false, tr("PUBLISH_IN_STUDY"), true, true);
1114   fd->setCaption( tr( "TOT_DESK_FILE_DUMP_STUDY" ) );
1115   fd->setFilters( aFilters );  
1116   fd->SetChecked(true);
1117   fd->exec();
1118   QString aFileName = fd->selectedFile();
1119   bool toPublish = fd->IsChecked();
1120   delete fd;
1121
1122   if(!aFileName.isEmpty()) {
1123     QFileInfo aFileInfo(aFileName);
1124     aStudy->DumpStudy( aFileInfo.dirPath( true ).latin1(), aFileInfo.baseName().latin1(), toPublish );
1125   }
1126 }
1127
1128 void SalomeApp_Application::onLoadScript( )
1129 {
1130   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( activeStudy() );
1131   if ( !appStudy ) return;
1132   _PTR(Study) aStudy = appStudy->studyDS();
1133
1134   if ( aStudy->GetProperties()->IsLocked() ) {
1135     SUIT_MessageBox::warn1 ( desktop(),
1136                              QObject::tr("WRN_WARNING"),
1137                              QObject::tr("WRN_STUDY_LOCKED"),
1138                              QObject::tr("BUT_OK") );
1139     return;
1140   }
1141
1142   QStringList filtersList;
1143   filtersList.append(tr("PYTHON_FILES_FILTER"));
1144   filtersList.append(tr("ALL_FILES_FILTER"));
1145
1146   QString aFile = SUIT_FileDlg::getFileName( desktop(), "", filtersList, tr( "TOT_DESK_FILE_LOAD_SCRIPT" ), true, true );
1147
1148   if ( !aFile.isEmpty() )
1149   {
1150     QString command = QString("execfile(\"%1\")").arg(aFile);
1151
1152     PythonConsole* pyConsole = pythonConsole();
1153
1154     if ( pyConsole )
1155       pyConsole->exec( command );
1156   }
1157 }
1158
1159 void SalomeApp_Application::onPreferences()
1160 {
1161   QApplication::setOverrideCursor( Qt::waitCursor );
1162
1163   SalomeApp_PreferencesDlg* prefDlg = new SalomeApp_PreferencesDlg( preferences( true ), desktop());
1164
1165   QApplication::restoreOverrideCursor();
1166
1167   if ( !prefDlg )
1168     return;
1169
1170   prefDlg->exec();
1171
1172   delete prefDlg;
1173 }
1174
1175 void SalomeApp_Application::onMRUActivated( QString aName )
1176 {
1177   onOpenDoc( aName );
1178 }
1179
1180 void SalomeApp_Application::onPreferenceChanged( QString& modName, QString& section, QString& param )
1181 {
1182   SalomeApp_Module* sMod = 0;
1183   CAM_Module* mod = module( modName );
1184   if ( mod && mod->inherits( "SalomeApp_Module" ) )
1185     sMod = (SalomeApp_Module*)mod;
1186
1187   if ( sMod )
1188     sMod->preferencesChanged( section, param );
1189   else
1190     preferencesChanged( section, param );
1191 }
1192
1193 QString SalomeApp_Application::getFileFilter() const
1194 {
1195   return "(*.hdf)";
1196 }
1197
1198 void SalomeApp_Application::beforeCloseDoc( SUIT_Study* s )
1199 {
1200   CAM_Application::beforeCloseDoc( s );
1201
1202   for ( WindowMap::ConstIterator itr = myWindows.begin(); s && itr != myWindows.end(); ++itr )
1203     removeWindow( itr.key(), s->id() );
1204 }
1205
1206 void SalomeApp_Application::updateActions()
1207 {
1208   updateCommandsStatus();
1209 }
1210
1211 QWidget* SalomeApp_Application::createWindow( const int flag )
1212 {
1213   QWidget* wid = 0;
1214
1215   SUIT_ResourceMgr* resMgr = resourceMgr();
1216
1217   if ( flag == WT_ObjectBrowser )
1218   {
1219     OB_Browser* ob = new OB_Browser( desktop() );
1220     ob->setAutoUpdate( true );
1221     ob->setAutoOpenLevel( 1 );
1222     ob->setCaption( tr( "OBJECT_BROWSER" ) );
1223     ob->resize( OBJECT_BROWSER_WIDTH, ob->height() );
1224     ob->setFilter( new SalomeApp_OBFilter( selectionMgr() ) );
1225
1226     ob->setNameTitle( tr( "OBJ_BROWSER_NAME" ) );
1227
1228     for ( int i = SalomeApp_DataObject::CT_Value; i <= SalomeApp_DataObject::CT_RefEntry; i++ )
1229     {
1230       ob->addColumn( tr( QString().sprintf( "OBJ_BROWSER_COLUMN_%d", i ) ), i );
1231       ob->setColumnShown( i, resMgr->booleanValue( "ObjectBrowser",
1232                                                    QString().sprintf( "visibility_column_%d", i ), true ) );
1233     }
1234
1235     // Create OBSelector
1236     new SalomeApp_OBSelector( ob, mySelMgr );
1237
1238     wid = ob;
1239
1240     ob->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
1241   }
1242   else if ( flag == WT_PyConsole )
1243   {
1244     PythonConsole* pyCons = new PythonConsole( desktop(), new SalomeApp_PyInterp() );
1245     pyCons->setCaption( tr( "PYTHON_CONSOLE" ) );
1246     wid = pyCons;
1247
1248     //    pyCons->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
1249   }
1250   else if ( flag == WT_LogWindow )
1251   {
1252     LogWindow* logWin = new LogWindow( desktop() );
1253     logWin->setCaption( tr( "LOG_WINDOW" ) );
1254     wid = logWin;
1255
1256     logWin->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
1257   }
1258
1259   return wid;
1260 }
1261
1262 void SalomeApp_Application::defaultWindows( QMap<int, int>& aMap ) const
1263 {
1264   aMap.insert( WT_ObjectBrowser, Qt::DockLeft );
1265   aMap.insert( WT_PyConsole, Qt::DockBottom );
1266   //  aMap.insert( WT_LogWindow, Qt::DockBottom );
1267 }
1268
1269 void SalomeApp_Application::defaultViewManagers( QStringList& ) const
1270 {
1271 }
1272
1273 SalomeApp_Preferences* SalomeApp_Application::preferences( const bool crt ) const
1274 {
1275   if ( myPrefs )
1276     return myPrefs;
1277
1278   SalomeApp_Application* that = (SalomeApp_Application*)this;
1279
1280   if ( !_prefs_ && crt )
1281   {
1282     _prefs_ = new SalomeApp_Preferences( resourceMgr() );
1283     that->createPreferences( _prefs_ );
1284   }
1285
1286   that->myPrefs = _prefs_;
1287
1288   QPtrList<SUIT_Application> appList = SUIT_Session::session()->applications();
1289   for ( QPtrListIterator<SUIT_Application> appIt ( appList ); appIt.current(); ++appIt )
1290   {
1291     if ( !appIt.current()->inherits( "SalomeApp_Application" ) )
1292       continue;
1293
1294     SalomeApp_Application* app = (SalomeApp_Application*)appIt.current();
1295
1296     QStringList modNameList;
1297     app->modules( modNameList, false );
1298     for ( QStringList::const_iterator it = modNameList.begin(); it != modNameList.end(); ++it )
1299     {
1300       int id = _prefs_->addPreference( *it );
1301       _prefs_->setItemProperty( id, "info", tr( "PREFERENCES_NOT_LOADED" ).arg( *it ) );
1302     }
1303
1304     ModuleList modList;
1305     app->modules( modList );
1306     for ( ModuleListIterator itr( modList ); itr.current(); ++itr )
1307     {
1308       SalomeApp_Module* mod = 0;
1309       if ( itr.current()->inherits( "SalomeApp_Module" ) )
1310         mod = (SalomeApp_Module*)itr.current();
1311
1312       if ( mod && !_prefs_->hasModule( mod->moduleName() ) )
1313       {
1314         int modCat = _prefs_->addPreference( mod->moduleName() );
1315         _prefs_->setItemProperty( modCat, "info", QString::null );
1316         mod->createPreferences();
1317       }
1318     }
1319   }
1320
1321   connect( myPrefs, SIGNAL( preferenceChanged( QString&, QString&, QString& ) ),
1322            this, SLOT( onPreferenceChanged( QString&, QString&, QString& ) ) );
1323
1324   return myPrefs;
1325 }
1326
1327 void SalomeApp_Application::moduleAdded( CAM_Module* mod )
1328 {
1329   CAM_Application::moduleAdded( mod );
1330
1331   SalomeApp_Module* salomeMod = 0;
1332   if ( mod && mod->inherits( "SalomeApp_Module" ) )
1333     salomeMod = (SalomeApp_Module*)mod;
1334
1335   if ( myPrefs && salomeMod && !myPrefs->hasModule( salomeMod->moduleName() ) )
1336   {
1337     int modCat = myPrefs->addPreference( mod->moduleName() );
1338     myPrefs->setItemProperty( modCat, "info", QString::null );
1339     salomeMod->createPreferences();
1340   }
1341 }
1342
1343 void SalomeApp_Application::createPreferences( SalomeApp_Preferences* pref )
1344 {
1345   if ( !pref )
1346     return;
1347
1348   int salomeCat = pref->addPreference( tr( "PREF_CATEGORY_SALOME" ) );
1349
1350   int genTab = pref->addPreference( tr( "PREF_TAB_GENERAL" ), salomeCat );
1351
1352   int obGroup = pref->addPreference( tr( "PREF_GROUP_OBJBROWSER" ), genTab );
1353   for ( int i = SalomeApp_DataObject::CT_Value; i <= SalomeApp_DataObject::CT_RefEntry; i++ )
1354   {
1355     pref->addPreference( tr( QString().sprintf( "OBJ_BROWSER_COLUMN_%d", i ) ), obGroup,
1356                          SalomeApp_Preferences::Bool, "ObjectBrowser", QString().sprintf( "visibility_column_%d", i ) );
1357   }
1358   pref->setItemProperty( obGroup, "columns", 1 );
1359
1360   int viewTab = pref->addPreference( tr( "PREF_TAB_VIEWERS" ), salomeCat );
1361
1362   int occGroup = pref->addPreference( tr( "PREF_GROUP_OCCVIEWER" ), viewTab );
1363
1364   int vtkGroup = pref->addPreference( tr( "PREF_GROUP_VTKVIEWER" ), viewTab );
1365   pref->setItemProperty( occGroup, "columns", 1 );
1366   pref->setItemProperty( vtkGroup, "columns", 1 );
1367
1368   int occTS = pref->addPreference( tr( "PREF_TRIHEDRON_SIZE" ), occGroup,
1369                                    SalomeApp_Preferences::IntSpin, "OCCViewer", "trihedron_size" );
1370   pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), occGroup,
1371                        SalomeApp_Preferences::Color, "OCCViewer", "background" );
1372
1373   pref->setItemProperty( occTS, "min", 1 );
1374   pref->setItemProperty( occTS, "max", 150 );
1375
1376   int isoU = pref->addPreference( tr( "PREF_ISOS_U" ), occGroup,
1377                                   SalomeApp_Preferences::IntSpin, "OCCViewer", "iso_number_u" );
1378   int isoV = pref->addPreference( tr( "PREF_ISOS_V" ), occGroup,
1379                                   SalomeApp_Preferences::IntSpin, "OCCViewer", "iso_number_v" );
1380
1381   pref->setItemProperty( isoU, "min", 0 );
1382   pref->setItemProperty( isoU, "max", 100000 );
1383
1384   pref->setItemProperty( isoV, "min", 0 );
1385   pref->setItemProperty( isoV, "max", 100000 );
1386
1387   int vtkTS = pref->addPreference( tr( "PREF_TRIHEDRON_SIZE" ), vtkGroup,
1388                                    SalomeApp_Preferences::IntSpin, "VTKViewer", "trihedron_size" );
1389   pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), vtkGroup,
1390                        SalomeApp_Preferences::Color, "VTKViewer", "background" );
1391
1392   pref->setItemProperty( vtkTS, "min", 1 );
1393   pref->setItemProperty( vtkTS, "max", 150 );
1394
1395   int dirTab = pref->addPreference( tr( "PREF_TAB_DIRECTORIES" ), salomeCat );
1396   int dirGroup = pref->addPreference( tr( "PREF_GROUP_DIRECTORIES" ), dirTab );
1397   pref->setItemProperty( dirGroup, "columns", 1 );
1398   pref->addPreference( tr( "" ), dirGroup,
1399                        SalomeApp_Preferences::DirList, "FileDlg", "QuickDirList" );
1400 }
1401
1402 void SalomeApp_Application::preferencesChanged( const QString& sec, const QString& param )
1403 {
1404   SUIT_ResourceMgr* resMgr = resourceMgr();
1405   if ( !resMgr )
1406     return;
1407
1408   if ( sec == QString( "OCCViewer" ) && param == QString( "trihedron_size" ) )
1409   {
1410     int sz = resMgr->integerValue( sec, param, -1 );
1411     QPtrList<SUIT_ViewManager> lst;
1412     viewManagers( OCCViewer_Viewer::Type(), lst );
1413     for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current() && sz >= 0; ++it )
1414     {
1415       SUIT_ViewModel* vm = it.current()->getViewModel();
1416       if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
1417         continue;
1418
1419       OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
1420       occVM->setTrihedronSize( sz );
1421       occVM->getAISContext()->UpdateCurrentViewer();
1422     }
1423   }
1424
1425   if ( sec == QString( "VTKViewer" ) && param == QString( "trihedron_size" ) )
1426   {
1427     int sz = resMgr->integerValue( sec, param, -1 );
1428     QPtrList<SUIT_ViewManager> lst;
1429     viewManagers( SVTK_Viewer::Type(), lst );
1430     for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current() && sz >= 0; ++it )
1431     {
1432       SUIT_ViewModel* vm = it.current()->getViewModel();
1433       if ( !vm || !vm->inherits( "SVTK_Viewer" ) )
1434         continue;
1435
1436       SVTK_Viewer* vtkVM = (SVTK_Viewer*)vm;
1437       vtkVM->setTrihedronSize( sz );
1438       vtkVM->Repaint();
1439     }
1440   }
1441   
1442   if ( sec == QString( "OCCViewer" ) && ( param == QString( "iso_number_u" ) || param == QString( "iso_number_v" ) ) )
1443   {
1444     QPtrList<SUIT_ViewManager> lst;
1445     viewManagers( OCCViewer_Viewer::Type(), lst );
1446     int u = resMgr->integerValue( sec, "iso_number_u" );
1447     int v = resMgr->integerValue( sec, "iso_number_v" );
1448     for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current(); ++it )
1449       ((OCCViewer_Viewer*)it.current())->setIsos( u, v );
1450   }
1451   
1452 }
1453
1454 void SalomeApp_Application::updateDesktopTitle() {
1455   QString aTitle = applicationName();
1456   QString aVer = applicationVersion();
1457   if ( !aVer.isEmpty() )
1458     aTitle += QString( " " ) + aVer;
1459
1460   if ( activeStudy() )
1461   {
1462     QString sName = SUIT_Tools::file( activeStudy()->studyName().stripWhiteSpace(), false );
1463     if ( !sName.isEmpty() ) {
1464       SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
1465       _PTR(Study) stdDS = study->studyDS();
1466       if(stdDS) {
1467         if ( stdDS->GetProperties()->IsLocked() ) {
1468           aTitle += QString( " - [%1 (%2)]").arg( sName ).arg( tr( "STUDY_LOCKED" ) );
1469         } else {
1470           aTitle += QString( " - [%1]" ).arg( sName );
1471         }
1472       }
1473     }
1474   }
1475
1476   desktop()->setCaption( aTitle );
1477 }
1478
1479 void SalomeApp_Application::afterCloseDoc()
1480 {
1481   updateWindows();
1482
1483   CAM_Application::afterCloseDoc();
1484 }
1485
1486 CORBA::ORB_var SalomeApp_Application::orb()
1487 {
1488   ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
1489   static CORBA::ORB_var _orb = init( qApp->argc(), qApp->argv() );
1490   return _orb;
1491 }
1492
1493 SALOMEDSClient_StudyManager* SalomeApp_Application::studyMgr()
1494 {
1495   static SALOMEDSClient_StudyManager* _sm = new SALOMEDS_StudyManager();
1496   return _sm;
1497 }
1498
1499 SALOME_NamingService* SalomeApp_Application::namingService()
1500 {
1501   static SALOME_NamingService* _ns = new SALOME_NamingService( orb() );
1502   return _ns;
1503 }
1504
1505 SALOME_LifeCycleCORBA* SalomeApp_Application::lcc()
1506 {
1507   static SALOME_LifeCycleCORBA* _lcc = new SALOME_LifeCycleCORBA( namingService() );
1508   return _lcc;
1509 }
1510
1511 QString SalomeApp_Application::defaultEngineIOR()
1512 {
1513   // Look for a default module engine (needed for CORBAless modules to use SALOMEDS persistence)
1514   QString anIOR( "" );
1515   CORBA::Object_ptr anEngine = namingService()->Resolve( "/SalomeAppEngine" );
1516   if ( !CORBA::is_nil( anEngine ) )
1517     anIOR = orb()->object_to_string( anEngine );
1518   return anIOR;
1519 }
1520
1521 void SalomeApp_Application::moduleIconNames( QMap<QString, QString>& iconMap ) const
1522 {
1523   iconMap.clear();
1524
1525   SUIT_ResourceMgr* resMgr = resourceMgr();
1526   if ( !resMgr )
1527     return;
1528
1529   QStringList modList;
1530   modules( modList, false );
1531
1532   for ( QStringList::const_iterator it = modList.begin(); it != modList.end(); ++it )
1533   {
1534     QString modName = *it;
1535     QString modIntr = moduleName( modName );
1536     QString modIcon = resMgr->stringValue( modIntr, "icon", QString::null );
1537
1538     if ( modIcon.isEmpty() )
1539       continue;
1540
1541     if ( SUIT_Tools::extension( modIcon ).isEmpty() )
1542       modIcon += QString( ".png" );
1543
1544     iconMap.insert( modName, modIcon );
1545   }
1546 }
1547
1548 void SalomeApp_Application::updateModuleActions()
1549 {
1550   QString modName;
1551   if ( activeModule() )
1552     modName = activeModule()->moduleName();
1553
1554   if ( myActions.contains( modName ) )
1555     myActions[modName]->setOn( true );
1556 }
1557
1558 void SalomeApp_Application::currentWindows( QMap<int, int>& winMap ) const
1559 {
1560   winMap.clear();
1561   if ( !activeStudy() )
1562     return;
1563
1564   if ( activeModule() && activeModule()->inherits( "SalomeApp_Module" ) )
1565     ((SalomeApp_Module*)activeModule())->windows( winMap );
1566   else
1567     defaultWindows( winMap );
1568 }
1569
1570 void SalomeApp_Application::currentViewManagers( QStringList& lst ) const
1571 {
1572   lst.clear();
1573   if ( !activeStudy() )
1574     return;
1575
1576   if ( activeModule() && activeModule()->inherits( "SalomeApp_Module" ) )
1577     ((SalomeApp_Module*)activeModule())->viewManagers( lst );
1578   else
1579     defaultViewManagers( lst );
1580 }
1581
1582 void SalomeApp_Application::updateWindows()
1583 {
1584   QMap<int, int> winMap;
1585   currentWindows( winMap );
1586
1587   for ( QMap<int, int>::ConstIterator it = winMap.begin(); it != winMap.end(); ++it )
1588     getWindow( it.key() );
1589
1590   loadWindowsGeometry();
1591
1592   for ( WindowMap::ConstIterator itr = myWindows.begin(); itr != myWindows.end(); ++itr )
1593     setWindowShown( itr.key(), !itr.data()->isEmpty() && winMap.contains( itr.key() ) );
1594 }
1595
1596 void SalomeApp_Application::updateViewManagers()
1597 {
1598   QStringList lst;
1599   currentViewManagers( lst );
1600
1601   for ( QStringList::const_iterator it = lst.begin(); it != lst.end(); ++it )
1602     getViewManager( *it, true );
1603 }
1604
1605 void SalomeApp_Application::loadWindowsGeometry()
1606 {
1607   QtxDockAction* dockMgr = 0;
1608
1609   QAction* a = action( ViewWindowsId );
1610   if ( a && a->inherits( "QtxDockAction" ) )
1611     dockMgr = (QtxDockAction*)a;
1612
1613   if ( !dockMgr )
1614     return;
1615
1616   QString modName;
1617   if ( activeModule() )
1618     modName = moduleLibrary( activeModule()->moduleName(), false );
1619
1620   QString section = QString( "windows_geometry" );
1621   if ( !modName.isEmpty() )
1622     section += QString( "." ) + modName;
1623
1624   dockMgr->loadGeometry( resourceMgr(), section, false );
1625   dockMgr->restoreGeometry();
1626 }
1627
1628 void SalomeApp_Application::saveWindowsGeometry()
1629 {
1630   QtxDockAction* dockMgr = 0;
1631
1632   QAction* a = action( ViewWindowsId );
1633   if ( a && a->inherits( "QtxDockAction" ) )
1634     dockMgr = (QtxDockAction*)a;
1635
1636   if ( !dockMgr )
1637     return;
1638
1639   QString modName;
1640   if ( activeModule() )
1641     modName = moduleLibrary( activeModule()->moduleName(), false );
1642
1643   QString section = QString( "windows_geometry" );
1644   if ( !modName.isEmpty() )
1645     section += QString( "." ) + modName;
1646
1647   dockMgr->storeGeometry();
1648   dockMgr->saveGeometry( resourceMgr(), section, false );
1649 }
1650
1651 void SalomeApp_Application::activateWindows()
1652 {
1653   if ( activeStudy() )
1654   {
1655     for ( WindowMap::Iterator itr = myWindows.begin(); itr != myWindows.end(); ++itr )
1656       itr.data()->activate( activeStudy()->id() );
1657   }
1658 }
1659
1660 void SalomeApp_Application::onProperties()
1661 {
1662   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( activeStudy() );
1663   if( !study )
1664     return;
1665
1666   _PTR(StudyBuilder) SB = study->studyDS()->NewBuilder();
1667   SB->NewCommand();
1668
1669   SalomeApp_StudyPropertiesDlg aDlg( desktop() );
1670   int res = aDlg.exec();
1671   if( res==QDialog::Accepted && aDlg.isChanged() )
1672     SB->CommitCommand();
1673   else
1674     SB->AbortCommand();
1675
1676   //study->updateCaptions();
1677   updateDesktopTitle();
1678 }
1679
1680 QString SalomeApp_Application::getFileName( bool open, const QString& initial, const QString& filters, 
1681                                             const QString& caption, QWidget* parent )
1682 {
1683   if ( !parent )
1684     parent = desktop();
1685   QStringList fls = QStringList::split( ";;", filters, false );
1686   return SUIT_FileDlg::getFileName( parent, initial, fls, caption, open, true );
1687 }
1688
1689 QString SalomeApp_Application::getDirectory( const QString& initial, const QString& caption, QWidget* parent )
1690 {
1691   if ( !parent )
1692     parent = desktop();
1693   return SUIT_FileDlg::getExistingDirectory( parent, initial, caption, true );
1694 }
1695
1696 QStringList SalomeApp_Application::getOpenFileNames( const QString& initial, const QString& filters, 
1697                                                      const QString& caption, QWidget* parent )
1698 {
1699   if ( !parent )
1700     parent = desktop();
1701   QStringList fls = QStringList::split( ";;", filters, false );
1702   return SUIT_FileDlg::getOpenFileNames( parent, initial, fls, caption, true );
1703 }
1704
1705 void SalomeApp_Application::contextMenuPopup( const QString& type, QPopupMenu* thePopup, QString& title )
1706 {
1707   CAM_Application::contextMenuPopup( type, thePopup, title );
1708   thePopup->insertSeparator();
1709   thePopup->insertItem( tr( "MEN_REFRESH" ), this, SLOT( onRefresh() ) );
1710   
1711   // "Activate module" item should appear only if it's necessary
1712   OB_Browser* ob = objectBrowser();
1713   if ( !ob || type != ob->popupClientType() )
1714     return;
1715   SALOME_ListIO aList;
1716   SalomeApp_SelectionMgr* mgr = selectionMgr();
1717   mgr->selectedObjects(aList);
1718   if (aList.Extent() != 1)
1719     return;
1720   Handle(SALOME_InteractiveObject) aIObj = aList.First();
1721   QString aModuleName(aIObj->getComponentDataType());
1722   QString aModuleTitle = moduleTitle(aModuleName);
1723   CAM_Module* currentModule = activeModule();
1724   if (currentModule && currentModule->moduleName() == aModuleTitle)
1725     return;
1726   thePopup->insertItem( tr( "MEN_OPENWITH" ), this, SLOT( onOpenWith() ) );
1727 }
1728
1729 void SalomeApp_Application::updateObjectBrowser( const bool updateModels )
1730 {
1731   // update existing data models (already loaded SComponents)
1732   if ( updateModels ) 
1733   {
1734     for ( ModuleListIterator it = modules(); it.current(); ++it )
1735     {    
1736       CAM_DataModel* camDM = it.current()->dataModel();
1737       if ( camDM && camDM->inherits( "SalomeApp_DataModel" ) )
1738         ((SalomeApp_DataModel*)camDM)->update();
1739     }
1740   }
1741   // update "non-existing" (not loaded yet) data models
1742   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
1743   if ( study ) 
1744   {
1745     _PTR(Study) stdDS = study->studyDS();
1746     if( stdDS ) 
1747     {
1748       for ( _PTR(SComponentIterator) it ( stdDS->NewComponentIterator() ); it->More(); it->Next() ) 
1749       {
1750         _PTR(SComponent) aComponent ( it->Value() ); 
1751
1752         if ( aComponent->ComponentDataType() == "Interface Applicative" )
1753           continue; // skip the magic "Interface Applicative" component
1754             
1755         SalomeApp_DataModel::BuildTree( aComponent, study->root(), study, /*skipExisitng=*/true );
1756       }
1757     }
1758   }
1759
1760   if ( objectBrowser() )
1761     objectBrowser()->updateTree();
1762 }
1763
1764
1765 //************************************************************
1766 void SalomeApp_Application::onDesktopActivated()
1767 {
1768   CAM_Application::onDesktopActivated();
1769   SalomeApp_Module* aModule = dynamic_cast<SalomeApp_Module*>(activeModule());
1770   if(aModule)
1771     aModule->studyActivated();
1772 }
1773
1774 void SalomeApp_Application::createEmptyStudy()
1775 {
1776   CAM_Application::createEmptyStudy();
1777   if ( objectBrowser() )
1778     objectBrowser()->updateTree();
1779 }
1780
1781 bool SalomeApp_Application::activateModule( CAM_Module* mod )
1782 {
1783   bool res = CAM_Application::activateModule( mod );
1784   if ( objectBrowser() )
1785     objectBrowser()->updateTree();
1786   return res;
1787 }