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