From 26b415c2111e2ef1546405e6e70fea3043a912a0 Mon Sep 17 00:00:00 2001 From: san Date: Mon, 5 Sep 2011 13:37:34 +0000 Subject: [PATCH] SALOME 6.3.1 corrections from PPGP team: 1. Correction of the module's root data object creation - it now depends on the concrete study type (light or full) 2. Extending SalomePyQt API by two methods: get active Python module object, activate SALOME module with the given name 3. Minor correction: scaling the module's icon in Obj. Browser to 16x16 size to avoid ugly huge pixmaps for some light modules. --- src/LightApp/LightApp_DataModel.cxx | 31 ++++++++++-- src/LightApp/LightApp_DataModel.h | 2 + src/LightApp/LightApp_Study.cxx | 38 ++++++++++++++ src/LightApp/LightApp_Study.h | 5 ++ .../SALOME_PYQT_DataModelLight.cxx | 8 +-- .../SALOME_PYQT_DataModelLight.h | 2 +- .../SALOME_PYQT_ModuleLight.cxx | 8 +++ .../SALOME_PYQT_ModuleLight.h | 3 ++ src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx | 50 +++++++++++++++++++ src/SALOME_PYQT/SalomePyQt/SalomePyQt.h | 4 ++ src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip | 2 + src/SalomeApp/SalomeApp_DataObject.cxx | 9 +++- src/SalomeApp/SalomeApp_Study.cxx | 48 ++++++++++++++++++ src/SalomeApp/SalomeApp_Study.h | 3 +- 14 files changed, 203 insertions(+), 10 deletions(-) diff --git a/src/LightApp/LightApp_DataModel.cxx b/src/LightApp/LightApp_DataModel.cxx index da1544eee..0c8c40888 100644 --- a/src/LightApp/LightApp_DataModel.cxx +++ b/src/LightApp/LightApp_DataModel.cxx @@ -110,7 +110,10 @@ void LightApp_DataModel::updateWidgets() */ void LightApp_DataModel::update( LightApp_DataObject*, LightApp_Study* ) { - LightApp_ModuleObject* modelRoot = dynamic_cast( root() ); + // san: Previously modelRoot was casted to LightApp_ModuleObject*, + // BUT this is incorrect: in full SALOME the model root has different type. + // Hopefully LightApp_DataObject* is sufficient here. + LightApp_DataObject* modelRoot = dynamic_cast( root() ); DataObjectList ch; QMap aMap; if( modelRoot ) @@ -123,7 +126,7 @@ void LightApp_DataModel::update( LightApp_DataObject*, LightApp_Study* ) build(); - modelRoot = dynamic_cast( root() ); + modelRoot = dynamic_cast( root() ); if( modelRoot ) { DataObjectList new_ch = modelRoot->children(); @@ -207,5 +210,27 @@ void LightApp_DataModel::unregisterColumn( SUIT_DataBrowser* browser, const QStr { SUIT_AbstractModel* m = dynamic_cast( browser ? browser->model() : 0 ); if( m ) - m->unregisterColumn( groupId(), name ); + m->unregisterColumn( groupId(), name ); +} + +/*! + Creates the data model's root (module object) using the study services. + This is important because different study classes use different moduel object classes. + Therefore creation of the module object cannot be done at the data model level + where the type of the current study instance should not be known. + The module object returned by this method should be then passed to the model's setRoot(). + \return the module object instance corresponding to the study type + \sa CAM_DataModel class +*/ +CAM_ModuleObject* LightApp_DataModel::createModuleObject( SUIT_DataObject* theRoot ) const +{ + LightApp_RootObject* aStudyRoot = dynamic_cast( theRoot ); + if ( !aStudyRoot ) + return 0; + + LightApp_Study* aStudy = aStudyRoot->study(); + if ( aStudy ) + return aStudy->createModuleObject( const_cast( this ), + theRoot ); + return 0; } diff --git a/src/LightApp/LightApp_DataModel.h b/src/LightApp/LightApp_DataModel.h index 097fe9ab5..994cbecaa 100644 --- a/src/LightApp/LightApp_DataModel.h +++ b/src/LightApp/LightApp_DataModel.h @@ -38,6 +38,7 @@ class LightApp_Module; class LightApp_Study; class LightApp_DataObject; class SUIT_DataBrowser; +class CAM_ModuleObject; /*! Description : Base class of data model @@ -75,6 +76,7 @@ protected: LightApp_Study* getStudy() const; virtual void build(); virtual void updateWidgets(); + virtual CAM_ModuleObject* createModuleObject( SUIT_DataObject* theRoot ) const; private: int myGroupId; diff --git a/src/LightApp/LightApp_Study.cxx b/src/LightApp/LightApp_Study.cxx index 4bbf7a886..69ecbe9cf 100644 --- a/src/LightApp/LightApp_Study.cxx +++ b/src/LightApp/LightApp_Study.cxx @@ -448,6 +448,44 @@ void LightApp_Study::RemoveTemporaryFiles (const char* theModuleName, const bool myDriver->RemoveTemporaryFiles(theModuleName, isDirDeleted); } +/*! + Virtual method that creates the root object (module object) for the given data model. + The type of the created object depends on the study class, therefore data model classes + should not create their module objects directly and should instead use + LightApp_DataModel::createModuleObject() that in its turn relies on this method. + + \param theDataModel - data model instance to create a module object for + \param theParent - the module object's parent (normally it's the study root) + \return the module object instance + \sa LightApp_DataModel class, SalomeApp_Study class, LightApp_ModuleObject class +*/ +CAM_ModuleObject* LightApp_Study::createModuleObject( LightApp_DataModel* theDataModel, + SUIT_DataObject* theParent ) const +{ + // Calling addComponent() for symmetry with SalomeApp_Study + // Currently it has empty implementation, but maybe in the future things will change... + LightApp_Study* that = const_cast( this ); + that->addComponent( theDataModel ); + + // Avoid creating multiple module objects for the same module + CAM_ModuleObject* res = 0; + + DataObjectList children = root()->children(); + DataObjectList::const_iterator anIt = children.begin(), aLast = children.end(); + for( ; !res && anIt!=aLast; anIt++ ) + { + LightApp_ModuleObject* obj = dynamic_cast( *anIt ); + if ( obj && obj->name() == theDataModel->module()->moduleName() ) + res = obj; + } + + if ( !res ){ + res = new LightApp_ModuleObject( theDataModel, theParent ); + } + + return res; +} + /*! Fills list with components names \param comp - list to be filled diff --git a/src/LightApp/LightApp_Study.h b/src/LightApp/LightApp_Study.h index 72dcfe0c5..428900cda 100644 --- a/src/LightApp/LightApp_Study.h +++ b/src/LightApp/LightApp_Study.h @@ -38,7 +38,9 @@ class SUIT_Study; class SUIT_Application; class CAM_DataModel; +class CAM_ModuleObject; class LightApp_DataObject; +class LightApp_DataModel; //Map to store visual property of the object. //Key: Name of the visual property of the object. @@ -123,6 +125,8 @@ protected: protected: virtual bool openDataModel ( const QString&, CAM_DataModel* ); + virtual CAM_ModuleObject* createModuleObject( LightApp_DataModel* theDataModel, + SUIT_DataObject* theParent ) const; signals: void saved ( SUIT_Study* ); @@ -136,6 +140,7 @@ private: ViewMgrMap myViewMgrMap; friend class LightApp_Application; + friend class LightApp_DataModel; }; #endif diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.cxx b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.cxx index 50c68b261..17c8f531b 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.cxx +++ b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.cxx @@ -152,12 +152,12 @@ void SALOME_PYQT_DataModelLight::update ( LightApp_DataObject* theObj, LightApp_ return; } -LightApp_ModuleObject* SALOME_PYQT_DataModelLight::getRoot() +CAM_DataObject* SALOME_PYQT_DataModelLight::getRoot() { LightApp_Study* study = dynamic_cast( module()->application()->activeStudy() ); - LightApp_ModuleObject *aModelRoot = dynamic_cast(root()); - if(aModelRoot == NULL) { - aModelRoot = new LightApp_ModuleObject(this,study->root()); + CAM_ModuleObject *aModelRoot = dynamic_cast(root()); + if(study && aModelRoot == NULL) { + aModelRoot = createModuleObject( study->root() ); aModelRoot->setDataModel( this ); setRoot(aModelRoot); } diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.h b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.h index b49dc9cc2..2a6c2f21d 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.h +++ b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.h @@ -52,7 +52,7 @@ public: virtual void update ( LightApp_DataObject* = 0, LightApp_Study* = 0 ); - LightApp_ModuleObject* getRoot(); + CAM_DataObject* getRoot(); private: QString myFileName; diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.cxx b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.cxx index cd02deade..a28601baf 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.cxx +++ b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.cxx @@ -2775,3 +2775,11 @@ CAM_DataModel* SALOME_PYQT_ModuleLight::createDataModel() MESSAGE( "SALOME_PYQT_ModuleLight::createDataModel()" ); return new SALOME_PYQT_DataModelLight(this); } + +/*! + * Returns the Python module object currently loaded. + */ +PyObject* SALOME_PYQT_ModuleLight::getPythonModule() +{ + return myModule; +} diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.h b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.h index 0285aef55..6917f3a1d 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.h +++ b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.h @@ -148,6 +148,9 @@ public: /*return list of child objets*/ QStringList getChildren(const QString& obj, const bool rec); + /*Access to the underlying Python module object */ + PyObject* getPythonModule(); + public slots: virtual bool activateModule( SUIT_Study* ); diff --git a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx index 31de3fd94..014b88d9c 100644 --- a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx +++ b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx @@ -519,6 +519,56 @@ const QString SalomePyQt::getActiveComponent() return ProcessEvent( new TGetActiveComponentEvent() ); } +/*! + \fn PyObject* SalomePyQt::getActivePythonModule() + \brief Access to Python module object currently loaded into SALOME_PYQT_ModuleLight container. + \return Python module object currently loaded into SALOME_PYQT_ModuleLight container +*/ + +class TGetActivePyModuleEvent: public SALOME_Event +{ +public: + typedef PyObject* TResult; + TResult myResult; + TGetActivePyModuleEvent() : myResult( 0 ) {} + virtual void Execute() + { + SALOME_PYQT_ModuleLight* module = getActiveModule(); + if ( module ) + myResult = (PyObject*)module->getPythonModule(); + } +}; +PyObject* SalomePyQt::getActivePythonModule() +{ + return ProcessEvent( new TGetActivePyModuleEvent() ); +} + +/*! + \fn bool SalomePyQt::activateModule( const QString& modName ) + \brief Activates SALOME module with the given name + \return True if the module has been activated and False otherwise. +*/ + +class TActivateModuleEvent: public SALOME_Event +{ +public: + typedef bool TResult; + TResult myResult; + QString myModuleName; + TActivateModuleEvent( const QString& modName ) + : myResult( false ), myModuleName( modName ) {} + virtual void Execute() + { + if ( LightApp_Application* anApp = getApplication() ) { + myResult = anApp->activateModule( myModuleName ); + } + } +}; +bool SalomePyQt::activateModule( const QString& modName ) +{ + return ProcessEvent( new TActivateModuleEvent( modName ) ); +} + /*! \brief Update an Object Browser of the specified (by identifier) study. diff --git a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h index 41ca60456..5114bb024 100644 --- a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h +++ b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h @@ -26,6 +26,8 @@ #ifndef SALOME_PYQT_H #define SALOME_PYQT_H +#include + #include #include #include @@ -127,6 +129,8 @@ public: static int getStudyId(); static void putInfo( const QString&, const int = 0 ); static const QString getActiveComponent(); + static PyObject* getActivePythonModule(); + static bool activateModule( const QString& ); static void updateObjBrowser( const int = 0, bool = true ); static QString getFileName ( QWidget*, const QString&, const QStringList&, const QString&, bool ); diff --git a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip index ad092f66a..9b7c7b1f5 100644 --- a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip +++ b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip @@ -213,6 +213,8 @@ public: static int getStudyId() /ReleaseGIL/ ; static void putInfo( const QString&, const int = 0 ) /ReleaseGIL/ ; static const QString getActiveComponent() /ReleaseGIL/ ; + static SIP_PYOBJECT getActivePythonModule() /ReleaseGIL/ ; + static bool activateModule( const QString& ) /ReleaseGIL/ ; static void updateObjBrowser( const int = 0, bool = true ) /ReleaseGIL/ ; static QString getFileName ( QWidget*, const QString&, const QStringList&, const QString&, bool ) /ReleaseGIL/ ; diff --git a/src/SalomeApp/SalomeApp_DataObject.cxx b/src/SalomeApp/SalomeApp_DataObject.cxx index e04a29232..eff0a65c3 100644 --- a/src/SalomeApp/SalomeApp_DataObject.cxx +++ b/src/SalomeApp/SalomeApp_DataObject.cxx @@ -662,10 +662,17 @@ QString SalomeApp_ModuleObject::name() const \brief Get data object icon for the specified column. \param id column id \return object icon for the specified column + \sa CAM_ModuleObject class */ QPixmap SalomeApp_ModuleObject::icon( const int id ) const { - return SalomeApp_DataObject::icon( id ); + QPixmap p = SalomeApp_DataObject::icon( id ); + // The module might not provide a separate small icon + // for Obj. Browser representation -> always try to scale it + // See CAM_ModuleObject::icon() + if ( !p.isNull() ) + p = Qtx::scaleIcon( p, 16 ); + return p; } /*! diff --git a/src/SalomeApp/SalomeApp_Study.cxx b/src/SalomeApp/SalomeApp_Study.cxx index 6f11cdaf5..2972f8add 100644 --- a/src/SalomeApp/SalomeApp_Study.cxx +++ b/src/SalomeApp/SalomeApp_Study.cxx @@ -696,6 +696,54 @@ void SalomeApp_Study::setStudyDS( const _PTR(Study)& s ) myStudyDS = s; } +/*! + Virtual method re-implemented from LightApp_Study in order to create + the module object connected to SALOMEDS - SalomeApp_ModuleObject. + + \param theDataModel - data model instance to create a module object for + \param theParent - the module object's parent (normally it's the study root) + \return the module object instance + \sa LightApp_Study class, LightApp_DataModel class +*/ +CAM_ModuleObject* SalomeApp_Study::createModuleObject( LightApp_DataModel* theDataModel, + SUIT_DataObject* theParent ) const +{ + SalomeApp_Study* that = const_cast( this ); + + // Ensure that SComponent instance is published in the study for the given module + // This line causes automatic creation of SalomeApp_ModuleObject in case if + // WITH_SALOMEDS_OBSERVER is defined + that->addComponent( theDataModel ); + + // SalomeApp_ModuleObject might have been created by SALOMEDS observer + // or by someone else so check if it exists first of all + CAM_ModuleObject* res = 0; + + DataObjectList children = root()->children(); + DataObjectList::const_iterator anIt = children.begin(), aLast = children.end(); + for( ; !res && anIt!=aLast; anIt++ ) + { + SalomeApp_ModuleObject* obj = dynamic_cast( *anIt ); + if ( obj && obj->name() == theDataModel->module()->moduleName() ) + res = obj; + } + + if ( !res ){ + _PTR(Study) aStudy = studyDS(); + if ( !aStudy ) + return res; + + _PTR(SComponent) aComp = aStudy->FindComponent( + theDataModel->module()->name().toStdString() ); + if ( aComp ) + return res; + + res = new SalomeApp_ModuleObject( theDataModel, aComp, theParent ); + } + + return res; +} + /*! Insert data model. */ diff --git a/src/SalomeApp/SalomeApp_Study.h b/src/SalomeApp/SalomeApp_Study.h index 6e9cef141..41ebe3715 100644 --- a/src/SalomeApp/SalomeApp_Study.h +++ b/src/SalomeApp/SalomeApp_Study.h @@ -100,7 +100,8 @@ protected: virtual void dataModelInserted( const CAM_DataModel* ); virtual bool openDataModel( const QString&, CAM_DataModel* ); void setStudyDS(const _PTR(Study)& s ); - + virtual CAM_ModuleObject* createModuleObject( LightApp_DataModel* theDataModel, + SUIT_DataObject* theParent ) const; protected slots: virtual void updateModelRoot( const CAM_DataModel* ); -- 2.39.2