1 // File: SalomeApp_Application.cxx
2 // Created: 10/22/2004 3:23:45 PM
3 // Author: Sergey LITONIN
4 // Copyright (C) CEA 2004
6 #include "SalomeApp_PyInterp.h" // WARNING! This include must be the first!
8 #include "SalomeApp_Application.h"
10 #include "SalomeApp_Study.h"
11 #include "SalomeApp_Module.h"
12 #include "SalomeApp_DataModel.h"
13 #include "SalomeApp_DataObject.h"
14 #include "SalomeApp_EventFilter.h"
16 #include "SalomeApp_StudyPropertiesDlg.h"
18 #include "SalomeApp_CheckFileDlg.h"
20 #include "LightApp_Application.h"
21 #include "LightApp_Preferences.h"
22 #include "LightApp_WidgetContainer.h"
23 #include "LightApp_SelectionMgr.h"
25 #include "STD_LoadStudiesDlg.h"
27 #include <SUIT_Tools.h>
28 #include <SUIT_Session.h>
30 #include <OB_Browser.h>
32 #include <PythonConsole_PyConsole.h>
34 #include <SUIT_FileDlg.h>
35 #include <SUIT_MessageBox.h>
36 #include <SUIT_ResourceMgr.h>
37 #include <SUIT_ActionOperation.h>
39 #include <Utils_ORB_INIT.hxx>
40 #include <Utils_SINGLETON.hxx>
41 #include <SALOME_ModuleCatalog_impl.hxx>
42 #include <SALOME_LifeCycleCORBA.hxx>
46 #include <qcombobox.h>
50 #include "SALOMEDS_StudyManager.hxx"
51 #include "SALOMEDS_SObject.hxx"
53 #include "SALOME_ListIteratorOfListIO.hxx"
54 #include "SALOME_ListIO.hxx"
56 #include "ToolsGUI_CatalogGeneratorDlg.h"
57 #include "ToolsGUI_RegWidget.h"
59 #define OBJECT_BROWSER_WIDTH 300
61 /*!Create new instance of SalomeApp_Application.*/
62 extern "C" SALOMEAPP_EXPORT SUIT_Application* createApplication()
64 return new SalomeApp_Application();
68 Class : SalomeApp_Application
69 Description : Application containing SalomeApp module
72 SalomeApp_Application::SalomeApp_Application()
73 : LightApp_Application()
78 *\li Destroy event filter.
80 SalomeApp_Application::~SalomeApp_Application()
82 SalomeApp_EventFilter::Destroy();
85 /*!Start application.*/
86 void SalomeApp_Application::start()
88 LightApp_Application::start();
90 SalomeApp_EventFilter::Init();
94 void SalomeApp_Application::createActions()
96 LightApp_Application::createActions();
98 SUIT_Desktop* desk = desktop();
101 createAction( DumpStudyId, tr( "TOT_DESK_FILE_DUMP_STUDY" ), QIconSet(),
102 tr( "MEN_DESK_FILE_DUMP_STUDY" ), tr( "PRP_DESK_FILE_DUMP_STUDY" ),
103 0, desk, false, this, SLOT( onDumpStudy() ) );
106 createAction( LoadScriptId, tr( "TOT_DESK_FILE_LOAD_SCRIPT" ), QIconSet(),
107 tr( "MEN_DESK_FILE_LOAD_SCRIPT" ), tr( "PRP_DESK_FILE_LOAD_SCRIPT" ),
108 0, desk, false, this, SLOT( onLoadScript() ) );
111 createAction( PropertiesId, tr( "TOT_DESK_PROPERTIES" ), QIconSet(),
112 tr( "MEN_DESK_PROPERTIES" ), tr( "PRP_DESK_PROPERTIES" ),
113 0, desk, false, this, SLOT( onProperties() ) );
115 //! Catalog Generator
116 createAction( CatalogGenId, tr( "TOT_DESK_CATALOG_GENERATOR" ), QIconSet(),
117 tr( "MEN_DESK_CATALOG_GENERATOR" ), tr( "PRP_DESK_CATALOG_GENERATOR" ),
118 0, desk, false, this, SLOT( onCatalogGen() ) );
121 createAction( RegDisplayId, tr( "TOT_DESK_REGISTRY_DISPLAY" ), QIconSet(),
122 tr( "MEN_DESK_REGISTRY_DISPLAY" ), tr( "PRP_DESK_REGISTRY_DISPLAY" ),
123 0, desk, false, this, SLOT( onRegDisplay() ) );
125 int fileMenu = createMenu( tr( "MEN_DESK_FILE" ), -1 );
127 createMenu( DumpStudyId, fileMenu, 10, -1 );
128 createMenu( separator(), fileMenu, -1, 15, -1 );
129 createMenu( LoadScriptId, fileMenu, 10, -1 );
130 createMenu( separator(), fileMenu, -1, 15, -1 );
131 createMenu( PropertiesId, fileMenu, 10, -1 );
132 createMenu( separator(), fileMenu, -1, 15, -1 );
134 int toolsMenu = createMenu( tr( "MEN_DESK_TOOLS" ), -1, -1, 50 );
135 createMenu( CatalogGenId, toolsMenu, 10, -1 );
136 createMenu( RegDisplayId, toolsMenu, 10, -1 );
137 createMenu( separator(), toolsMenu, -1, 15, -1 );
140 /*!SLOT. Load document.*/
141 void SalomeApp_Application::onLoadDoc()
143 QString name, studyname, ext;
145 STD_LoadStudiesDlg aDlg( desktop(), TRUE);
147 std::vector<std::string> List = studyMgr()->GetOpenStudies();
149 SUIT_Session* aSession = SUIT_Session::session();
150 QPtrList<SUIT_Application> aAppList = aSession->applications();
151 SUIT_Application* aApp = 0;
153 for (unsigned int ind = 0; ind < List.size(); ind++) {
154 studyname = List[ind].c_str();
155 //Add to list only unloaded studies
156 bool isAlreadyOpen = false;
157 for ( QPtrListIterator<SUIT_Application> it( aAppList ); it.current() && !isAlreadyOpen; ++it )
160 if(!aApp || !aApp->activeStudy()) continue;
161 if ( aApp->activeStudy()->studyName() == studyname ) isAlreadyOpen = true;
164 if ( !isAlreadyOpen ) aDlg.ListComponent->insertItem( studyname );
167 int retVal = aDlg.exec();
168 studyname = aDlg.ListComponent->currentText();
170 if (retVal == QDialog::Rejected)
173 if ( studyname.isNull() || studyname.isEmpty() )
177 name.replace( QRegExp(":"), "/" );
179 if (LightApp_Application::onLoadDoc(name))
182 updateViewManagers();
183 updateObjectBrowser(true);
187 /*!SLOT. Copy objects to study maneger from selection maneger..*/
188 void SalomeApp_Application::onCopy()
191 LightApp_SelectionMgr* mgr = selectionMgr();
192 mgr->selectedObjects(list);
194 SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
195 if(study == NULL) return;
197 _PTR(Study) stdDS = study->studyDS();
200 SALOME_ListIteratorOfListIO it( list );
203 _PTR(SObject) so = stdDS->FindObjectID(it.Value()->getEntry());
205 studyMgr()->Copy(so);
206 onSelectionChanged();
213 /*!SLOT. Paste objects to study maneger from selection manager.*/
214 void SalomeApp_Application::onPaste()
217 LightApp_SelectionMgr* mgr = selectionMgr();
218 mgr->selectedObjects(list);
220 SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
221 if(study == NULL) return;
223 _PTR(Study) stdDS = study->studyDS();
226 SALOME_ListIteratorOfListIO it( list );
229 _PTR(SObject) so = stdDS->FindObjectID(it.Value()->getEntry());
231 studyMgr()->Paste(so);
232 updateObjectBrowser( true );
233 updateActions(); //SRN: BugID IPAL9377, case 3
240 /*!Sets enable or disable some actions on selection changed.*/
241 void SalomeApp_Application::onSelectionChanged()
244 LightApp_SelectionMgr* mgr = selectionMgr();
245 mgr->selectedObjects(list);
247 SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
248 if(study == NULL) return;
250 _PTR(Study) stdDS = study->studyDS();
255 SALOME_ListIteratorOfListIO it( list );
256 if(it.More() && list.Extent() == 1)
258 _PTR(SObject) so = stdDS->FindObjectID(it.Value()->getEntry());
259 qaction = action(EditCopyId);
260 SALOMEDS_SObject* aSO = dynamic_cast<SALOMEDS_SObject*>(so.get());
261 if(aSO && studyMgr()->CanCopy(so) ) qaction->setEnabled(true);
262 else qaction->setEnabled(false);
264 qaction = action(EditPasteId);
265 if( aSO && studyMgr()->CanPaste(so) ) qaction->setEnabled(true);
266 else qaction->setEnabled(false);
269 qaction = action(EditCopyId);
270 qaction->setEnabled(false);
271 qaction = action(EditPasteId);
272 qaction->setEnabled(false);
276 /*!Delete references.*/
277 void SalomeApp_Application::onDeleteReferences()
280 LightApp_SelectionMgr* mgr = selectionMgr();
281 mgr->selectedObjects(aList);
283 if (aList.Extent() < 1) return;
285 SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(activeStudy());
286 _PTR(Study) aStudyDS = aStudy->studyDS();
287 _PTR(StudyBuilder) aStudyBuilder = aStudyDS->NewBuilder();
290 for ( SALOME_ListIteratorOfListIO it( aList ); it.More(); it.Next() )
292 if ( it.Value()->hasEntry() )
294 _PTR(SObject) aSObject = aStudyDS->FindObjectID( it.Value()->getEntry() );
295 if ( aSObject->ReferencedObject(anObj) )
296 aStudyBuilder->RemoveReference(aSObject);
300 updateObjectBrowser();
303 //=======================================================================
304 // name : createNewStudy
305 /*! Purpose : Create new study*/
306 //=======================================================================
307 SUIT_Study* SalomeApp_Application::createNewStudy()
309 SalomeApp_Study* aStudy = new SalomeApp_Study( this );
311 // Set up processing of major study-related events
312 connect( aStudy, SIGNAL( created( SUIT_Study* ) ), this, SLOT( onStudyCreated( SUIT_Study* ) ) );
313 connect( aStudy, SIGNAL( opened ( SUIT_Study* ) ), this, SLOT( onStudyOpened ( SUIT_Study* ) ) );
314 connect( aStudy, SIGNAL( saved ( SUIT_Study* ) ), this, SLOT( onStudySaved ( SUIT_Study* ) ) );
315 connect( aStudy, SIGNAL( closed ( SUIT_Study* ) ), this, SLOT( onStudyClosed ( SUIT_Study* ) ) );
320 //=======================================================================
321 // name : updateCommandsStatus
322 /*! Purpose : Enable/Disable menu items and toolbar buttons. Rebuild menu*/
323 //=======================================================================
324 void SalomeApp_Application::updateCommandsStatus()
326 LightApp_Application::updateCommandsStatus();
329 QAction* a = action( DumpStudyId );
331 a->setEnabled( activeStudy() );
334 a = action( LoadScriptId );
336 a->setEnabled( activeStudy() );
338 a = action( PropertiesId );
340 a->setEnabled( activeStudy() );
342 a = action(EditCopyId);
343 a->setEnabled(false);
344 a = action(EditPasteId);
345 a->setEnabled(false);
348 /*!Private SLOT. On dump study.*/
349 void SalomeApp_Application::onDumpStudy( )
351 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( activeStudy() );
352 if ( !appStudy ) return;
353 _PTR(Study) aStudy = appStudy->studyDS();
355 QStringList aFilters;
356 aFilters.append( tr( "PYTHON_FILES_FILTER" ) );
358 SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg( desktop(), false, tr("PUBLISH_IN_STUDY"), true, true);
359 fd->setCaption( tr( "TOT_DESK_FILE_DUMP_STUDY" ) );
360 fd->setFilters( aFilters );
361 fd->SetChecked(true);
363 QString aFileName = fd->selectedFile();
364 bool toPublish = fd->IsChecked();
367 if(!aFileName.isEmpty()) {
368 QFileInfo aFileInfo(aFileName);
369 aStudy->DumpStudy( aFileInfo.dirPath( true ).latin1(), aFileInfo.baseName().latin1(), toPublish );
373 /*!Private SLOT. On load script.*/
374 void SalomeApp_Application::onLoadScript( )
376 SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( activeStudy() );
377 if ( !appStudy ) return;
378 _PTR(Study) aStudy = appStudy->studyDS();
380 if ( aStudy->GetProperties()->IsLocked() ) {
381 SUIT_MessageBox::warn1 ( desktop(),
382 QObject::tr("WRN_WARNING"),
383 QObject::tr("WRN_STUDY_LOCKED"),
384 QObject::tr("BUT_OK") );
388 QStringList filtersList;
389 filtersList.append(tr("PYTHON_FILES_FILTER"));
390 filtersList.append(tr("ALL_FILES_FILTER"));
392 QString aFile = SUIT_FileDlg::getFileName( desktop(), "", filtersList, tr( "TOT_DESK_FILE_LOAD_SCRIPT" ), true, true );
394 if ( !aFile.isEmpty() )
396 QString command = QString("execfile(\"%1\")").arg(aFile);
398 PythonConsole* pyConsole = pythonConsole();
401 pyConsole->exec( command );
406 *\retval QString "(*.hdf)"
408 QString SalomeApp_Application::getFileFilter() const
414 QWidget* SalomeApp_Application::createWindow( const int flag )
416 QWidget* wid = LightApp_Application::createWindow(flag);
417 SUIT_ResourceMgr* resMgr = resourceMgr();
419 if ( flag == WT_ObjectBrowser )
421 OB_Browser* ob = (OB_Browser*)wid;
422 bool autoSize = resMgr->booleanValue( "ObjectBrowser", "auto_size", false );
424 for ( int i = SalomeApp_DataObject::CT_Value; i <= SalomeApp_DataObject::CT_RefEntry; i++ )
426 ob->addColumn( tr( QString().sprintf( "OBJ_BROWSER_COLUMN_%d", i ) ), i );
427 ob->setColumnShown( i, resMgr->booleanValue( "ObjectBrowser",
428 QString().sprintf( "visibility_column_%d", i ), true ) );
431 ob->setWidthMode( autoSize ? QListView::Maximum : QListView::Manual );
433 else if ( flag == WT_PyConsole )
437 PythonConsole* pyCons = new PythonConsole( desktop(), new SalomeApp_PyInterp() );
438 pyCons->setCaption( tr( "PYTHON_CONSOLE" ) );
440 // pyCons->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
445 /*!Create preferences.*/
446 void SalomeApp_Application::createPreferences( LightApp_Preferences* pref )
448 LightApp_Application::createPreferences(pref);
453 int salomeCat = pref->addPreference( tr( "PREF_CATEGORY_SALOME" ) );
454 int obTab = pref->addPreference( tr( "PREF_TAB_OBJBROWSER" ), salomeCat );
455 int defCols = pref->addPreference( tr( "PREF_GROUP_DEF_COLUMNS" ), obTab );
456 for ( int i = SalomeApp_DataObject::CT_Value; i <= SalomeApp_DataObject::CT_RefEntry; i++ )
458 pref->addPreference( tr( QString().sprintf( "OBJ_BROWSER_COLUMN_%d", i ) ), defCols,
459 LightApp_Preferences::Bool, "ObjectBrowser", QString().sprintf( "visibility_column_%d", i ) );
461 pref->setItemProperty( defCols, "columns", 1 );
463 int objSetGroup = pref->addPreference( tr( "PREF_OBJ_BROWSER_SETTINGS" ), obTab );
464 pref->addPreference( tr( "PREF_AUTO_SIZE" ), objSetGroup, LightApp_Preferences::Bool, "ObjectBrowser", "auto_size" );
467 /*!Update desktop title.*/
468 void SalomeApp_Application::updateDesktopTitle() {
469 QString aTitle = applicationName();
470 QString aVer = applicationVersion();
471 if ( !aVer.isEmpty() )
472 aTitle += QString( " " ) + aVer;
476 QString sName = SUIT_Tools::file( activeStudy()->studyName().stripWhiteSpace(), false );
477 if ( !sName.isEmpty() ) {
478 SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
480 _PTR(Study) stdDS = study->studyDS();
482 if ( stdDS->GetProperties()->IsLocked() ) {
483 aTitle += QString( " - [%1 (%2)]").arg( sName ).arg( tr( "STUDY_LOCKED" ) );
485 aTitle += QString( " - [%1]" ).arg( sName );
492 desktop()->setCaption( aTitle );
495 /*!Gets CORBA::ORB_var*/
496 CORBA::ORB_var SalomeApp_Application::orb()
498 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
499 static CORBA::ORB_var _orb = init( qApp->argc(), qApp->argv() );
503 /*!Create and return SALOMEDS_StudyManager.*/
504 SALOMEDSClient_StudyManager* SalomeApp_Application::studyMgr()
506 static SALOMEDSClient_StudyManager* _sm = new SALOMEDS_StudyManager();
510 /*!Create and return SALOME_NamingService.*/
511 SALOME_NamingService* SalomeApp_Application::namingService()
513 static SALOME_NamingService* _ns = new SALOME_NamingService( orb() );
517 /*!Create and return SALOME_LifeCycleCORBA.*/
518 SALOME_LifeCycleCORBA* SalomeApp_Application::lcc()
520 static SALOME_LifeCycleCORBA* _lcc = new SALOME_LifeCycleCORBA( namingService() );
524 QString SalomeApp_Application::defaultEngineIOR()
526 /// Look for a default module engine (needed for CORBAless modules to use SALOMEDS persistence)
528 CORBA::Object_ptr anEngine = namingService()->Resolve( "/SalomeAppEngine" );
529 if ( !CORBA::is_nil( anEngine ) )
530 anIOR = orb()->object_to_string( anEngine );
534 /*!Private SLOT. On preferences.*/
535 void SalomeApp_Application::onProperties()
537 SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( activeStudy() );
541 _PTR(StudyBuilder) SB = study->studyDS()->NewBuilder();
544 SalomeApp_StudyPropertiesDlg aDlg( desktop() );
545 int res = aDlg.exec();
546 if( res==QDialog::Accepted && aDlg.isChanged() )
551 //study->updateCaptions();
552 updateDesktopTitle();
556 void SalomeApp_Application::contextMenuPopup( const QString& type, QPopupMenu* thePopup, QString& title )
558 LightApp_Application::contextMenuPopup( type, thePopup, title );
560 OB_Browser* ob = objectBrowser();
561 if ( !ob || type != ob->popupClientType() )
564 // Get selected objects
566 LightApp_SelectionMgr* mgr = selectionMgr();
567 mgr->selectedObjects(aList);
569 // "Delete reference" item should appear only for invalid references
571 // Check if selected objects is invalid references
572 bool isInvalidRefs = true;
574 if ( aList.Extent() < 1 )
575 isInvalidRefs = false;
579 SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(activeStudy());
580 _PTR(Study) aStudyDS = aStudy->studyDS();
582 for ( SALOME_ListIteratorOfListIO it( aList ); it.More() && isInvalidRefs; it.Next() )
584 if ( it.Value()->hasEntry() )
586 _PTR(SObject) aSObject = aStudyDS->FindObjectID( it.Value()->getEntry() );
587 SALOMEDS_SObject* aSO = dynamic_cast<SALOMEDS_SObject*>(aSObject.get());
589 if ( aSObject->ReferencedObject(anObj) == false || !QString(anObj->GetName().c_str()).isEmpty() )
590 isInvalidRefs = false;
595 // Add "Delete refrence" item to popup
598 thePopup->insertSeparator();
599 thePopup->insertItem( tr( "MEN_DELETE_REFERENCE" ), this, SLOT( onDeleteReferences() ) );
603 // "Activate module" item should appear only if it's necessary
604 if (aList.Extent() != 1)
606 Handle(SALOME_InteractiveObject) aIObj = aList.First();
607 QString aModuleName(aIObj->getComponentDataType());
608 QString aModuleTitle = moduleTitle(aModuleName);
609 CAM_Module* currentModule = activeModule();
610 if (currentModule && currentModule->moduleName() == aModuleTitle)
612 thePopup->insertItem( tr( "MEN_OPENWITH" ), this, SLOT( onOpenWith() ) );
615 /*!Update obect browser*/
616 void SalomeApp_Application::updateObjectBrowser( const bool updateModels )
618 // update "non-existing" (not loaded yet) data models
619 SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
622 _PTR(Study) stdDS = study->studyDS();
625 for ( _PTR(SComponentIterator) it ( stdDS->NewComponentIterator() ); it->More(); it->Next() )
627 _PTR(SComponent) aComponent ( it->Value() );
629 if ( aComponent->ComponentDataType() == "Interface Applicative" )
630 continue; // skip the magic "Interface Applicative" component
632 SalomeApp_DataModel::BuildTree( aComponent, study->root(), study, /*skipExisitng=*/true );
636 LightApp_Application::updateObjectBrowser(updateModels);
639 /*!Display Catalog Genenerator dialog */
640 void SalomeApp_Application::onCatalogGen()
642 ToolsGUI_CatalogGeneratorDlg aDlg( desktop() );
646 /*!Display Registry Display dialog */
647 void SalomeApp_Application::onRegDisplay()
649 CORBA::ORB_var anOrb = orb();
650 ToolsGUI_RegWidget* regWnd = ToolsGUI_RegWidget::GetRegWidget( anOrb, desktop(), "Registry" );
653 regWnd->setActiveWindow();
657 void SalomeApp_Application::onOpenWith()
659 QApplication::setOverrideCursor( Qt::waitCursor );
661 LightApp_SelectionMgr* mgr = selectionMgr();
662 mgr->selectedObjects(aList);
663 if (aList.Extent() != 1)
665 QApplication::restoreOverrideCursor();
668 Handle(SALOME_InteractiveObject) aIObj = aList.First();
669 QString aModuleName(aIObj->getComponentDataType());
670 QString aModuleTitle = moduleTitle(aModuleName);
671 activateModule(aModuleTitle);
672 QApplication::restoreOverrideCursor();