From 3905ff24585a268a3443dac8a8b40e3d8c81ba4b Mon Sep 17 00:00:00 2001 From: vsr Date: Mon, 21 Nov 2011 13:59:22 +0000 Subject: [PATCH] Merge from BR_PPGP_Dev (GENEPY+ dev) 21/11/2011 --- src/LightApp/LightApp_Application.cxx | 4 +- src/LightApp/LightApp_DataModel.cxx | 9 + src/LightApp/LightApp_DataModel.h | 4 + src/LightApp/LightApp_DataObject.cxx | 102 +++++- src/LightApp/LightApp_DataObject.h | 9 +- src/LightApp/resources/LightApp.xml | 1 + .../SALOME_PYQT_DataModelLight.cxx | 54 +++- .../SALOME_PYQT_DataModelLight.h | 7 +- .../SALOME_PYQT_DataObjectLight.cxx | 49 +++ .../SALOME_PYQT_DataObjectLight.h | 20 +- .../SALOME_PYQT_ModuleLight.cxx | 135 ++++++++ .../SALOME_PYQT_ModuleLight.h | 27 +- src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx | 160 +++++++++ src/SALOME_PYQT/SalomePyQt/SalomePyQt.h | 10 + src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip | 17 +- src/STD/STD_Application.cxx | 6 +- src/STD/STD_TabDesktop.cxx | 10 +- src/SalomeApp/SalomeApp_Application.cxx | 67 ++-- src/SalomeApp/SalomeApp_Application.h | 1 - src/SalomeApp/SalomeApp_DataObject.cxx | 40 ++- src/SalomeApp/SalomeApp_DataObject.h | 10 +- src/SalomeApp/SalomeApp_Study.cxx | 136 +++++++- src/SalomeApp/SalomeApp_Study.h | 2 + src/Session/SalomeApp_Engine_i.cxx | 306 +++++++++++++++--- src/Session/SalomeApp_Engine_i.hxx | 41 ++- src/Session/Session_ServerLauncher.cxx | 11 + src/Session/Session_ServerThread.cxx | 35 +- 27 files changed, 1057 insertions(+), 216 deletions(-) diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index 05894985e..bf2a0e81a 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -645,7 +645,7 @@ void LightApp_Application::createActions() int newWinMenu = createMenu( tr( "MEN_DESK_NEWWINDOW" ), windowMenu, -1, 0 ); createAction( CloseId, tr( "TOT_CLOSE" ), QIcon(), tr( "MEN_DESK_CLOSE" ), tr( "PRP_CLOSE" ), - Qt::SHIFT+Qt::Key_C, desk, false, this, SLOT( onCloseWindow() ) ); + Qt::CTRL+Qt::Key_F4, desk, false, this, SLOT( onCloseWindow() ) ); createAction( CloseAllId, tr( "TOT_CLOSE_ALL" ), QIcon(), tr( "MEN_DESK_CLOSE_ALL" ), tr( "PRP_CLOSE_ALL" ), 0, desk, false, this, SLOT( onCloseAllWindow() ) ); createAction( GroupAllId, tr( "TOT_GROUP_ALL" ), QIcon(), tr( "MEN_DESK_GROUP_ALL" ), tr( "PRP_GROUP_ALL" ), @@ -675,7 +675,7 @@ void LightApp_Application::createActions() #endif createAction( RenameId, tr( "TOT_RENAME" ), QIcon(), tr( "MEN_DESK_RENAME" ), tr( "PRP_RENAME" ), - Qt::SHIFT+Qt::Key_R, desk, false, this, SLOT( onRenameWindow() ) ); + Qt::ALT+Qt::SHIFT+Qt::Key_R, desk, false, this, SLOT( onRenameWindow() ) ); createMenu( RenameId, windowMenu, -1 ); int fileMenu = createMenu( tr( "MEN_DESK_FILE" ), -1 ); diff --git a/src/LightApp/LightApp_DataModel.cxx b/src/LightApp/LightApp_DataModel.cxx index 0c8c40888..8c9675905 100644 --- a/src/LightApp/LightApp_DataModel.cxx +++ b/src/LightApp/LightApp_DataModel.cxx @@ -79,6 +79,15 @@ bool LightApp_DataModel::saveAs( const QString&, CAM_Study*, QStringList& ) return true; } +/*! + Does nothing by default. Should be redefined in light modules + that want to participate in "Dump study" operation. +*/ +bool LightApp_DataModel::dumpPython( const QString&, CAM_Study*, bool, QStringList& ) +{ + return true; +} + /*! Emit closed() */ diff --git a/src/LightApp/LightApp_DataModel.h b/src/LightApp/LightApp_DataModel.h index 994cbecaa..4da6d3675 100644 --- a/src/LightApp/LightApp_DataModel.h +++ b/src/LightApp/LightApp_DataModel.h @@ -55,6 +55,10 @@ public: virtual bool save( QStringList& ); virtual bool saveAs( const QString&, CAM_Study*, QStringList& ); virtual bool close(); + virtual bool dumpPython( const QString&, + CAM_Study*, + bool, + QStringList& ); virtual void update( LightApp_DataObject* = 0, LightApp_Study* = 0 ); diff --git a/src/LightApp/LightApp_DataObject.cxx b/src/LightApp/LightApp_DataObject.cxx index 6dd9f06dc..90e0a64f1 100644 --- a/src/LightApp/LightApp_DataObject.cxx +++ b/src/LightApp/LightApp_DataObject.cxx @@ -244,6 +244,31 @@ QString LightApp_DataObject::entry() const return QString(); } +/*! + \brief Returns the string identifier of the data objects referenced by this one. + + This method should be reimplemented in the subclasses. + Default implementation returns null string. + + \return ID string of the referenced data object +*/ +QString LightApp_DataObject::refEntry() const +{ + return QString(); +} + +/*! + \brief Tells if this data objects is a reference to some other or not. + + The base implementation retuns true, if refEntry() returns non-empty string. + + \return true if refEntry() is a non-empty string. +*/ +bool LightApp_DataObject::isReference() const +{ + return !refEntry().isEmpty(); +} + /*! \brief Get the data object unique key. \return data object key @@ -257,17 +282,88 @@ SUIT_DataObjectKey* LightApp_DataObject::key() const /*! \brief Get object text data for the specified column. - Column with \a id = 0 (NameId) is supposed to be used + Column with \a id == NameId is supposed to be used to get the object name. - Column with \a id = 1 (EntryId) is supposed to be used + Column with \a id == EntryId is supposed to be used to get the object entry. + Column with \a id == RefEntryId is supposed to be used + to show the entry of the object referenced by this one. \param id column id \return object text data */ QString LightApp_DataObject::text( const int id ) const { - return id == EntryId ? entry() : CAM_DataObject::text( id ); + QString txt; + + switch ( id ) + { + case EntryId: + txt = entry(); + break; + case RefEntryId: + // Issue 21379: reference support at LightApp level + if ( isReference() ) + txt = refEntry(); + break; + default: + // Issue 21379: Note that we cannot return some specially decorated + // name string (like "* ref_obj_name") when isReference() returns true, + // since there is no generic way at LightApp level + // to query the object name using refEntry() up to now. + // TODO: Think how to make reference name generation + // more generic at move it here from SalomeApp level... + txt = CAM_DataObject::text( id ); + break; + } + + return txt; +} + +/*! + \brief Get data object color for the specified column. + \param role color role + \param id column id (not used) + \return object color for the specified column +*/ +QColor LightApp_DataObject::color( const ColorRole role, const int id) const +{ + QColor c; + + // Issue 21379: reference support at LightApp level + // Centralized way for choosing text/background color for references. + // Colors for "normal" objects should be chosen by sub-classes. + switch ( role ) + { + case Text: + case Foreground: + // text color (not selected item) + // TODO: think how to detect invalid references... + if ( isReference() ) + c = QColor( 255, 0, 0 ); // valid reference (red) + break; + + case Highlight: + // background color for the highlighted item + // TODO: think how to detect invalid references... + if ( isReference() ) + c = QColor( 255, 0, 0 ); // valid reference (red) + break; + + case HighlightedText: + // text color for the highlighted item + if ( isReference() ) + c = QColor( 255, 255, 255 ); // white + break; + + default: + break; + } + + if ( !c.isValid() ) + c = CAM_DataObject::color( role, id ); + + return c; } /*! diff --git a/src/LightApp/LightApp_DataObject.h b/src/LightApp/LightApp_DataObject.h index 6af26dcc8..ac7ac8c57 100644 --- a/src/LightApp/LightApp_DataObject.h +++ b/src/LightApp/LightApp_DataObject.h @@ -37,8 +37,9 @@ class LIGHTAPP_EXPORT LightApp_DataObject : public virtual CAM_DataObject public: //! Column id - enum { - EntryId = VisibilityId + 1 //!< entry column + enum { + EntryId = VisibilityId + 1, //!< entry column + RefEntryId //!< reference entry column }; public: @@ -48,7 +49,11 @@ public: virtual SUIT_DataObjectKey* key() const; virtual QString entry() const; + virtual QString refEntry() const; + virtual bool isReference() const; + virtual QString text( const int = NameId ) const; + virtual QColor color( const ColorRole, const int = NameId ) const; virtual SUIT_DataObject* componentObject() const; virtual QString componentDataType() const; diff --git a/src/LightApp/resources/LightApp.xml b/src/LightApp/resources/LightApp.xml index fa09126ea..f78854f90 100644 --- a/src/LightApp/resources/LightApp.xml +++ b/src/LightApp/resources/LightApp.xml @@ -76,6 +76,7 @@ +
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 17c8f531b..837029613 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.cxx +++ b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.cxx @@ -40,7 +40,8 @@ SALOME_PYQT_DataModelLight::SALOME_PYQT_DataModelLight(CAM_Module * theModule) : LightApp_DataModel( theModule ), myFileName( "" ), - myStudyURL( "" ) + myStudyURL( "" ), + myModified( false ) { } @@ -66,6 +67,8 @@ bool SALOME_PYQT_DataModelLight::open( const QString& theURL, CAM_Study* study, return false; LightApp_DataModel::open( theURL, aDoc, theListOfFiles ); + + setModified( false ); return aModule->open(theListOfFiles); @@ -93,6 +96,9 @@ bool SALOME_PYQT_DataModelLight::save( QStringList& theListOfFiles) theListOfFiles.append(QString(aTmpDir.c_str())); int listSize = theListOfFiles.size(); aModule->save(theListOfFiles); + + setModified( false ); + //Return true if in the List of files was added item(s) //else return false return theListOfFiles.size() > listSize; @@ -115,25 +121,57 @@ bool SALOME_PYQT_DataModelLight::create( CAM_Study* study ) return true; } +//================================================================================= +// function : dumpPython() +// purpose : Re-defined from LigthApp_DataModel in order to participate +// in dump study process +//================================================================================= +bool SALOME_PYQT_DataModelLight::dumpPython( const QString& theURL, + CAM_Study* theStudy, + bool isMultiFile, + QStringList& theListOfFiles ) +{ + MESSAGE("SALOME_PYQT_DataModelLight::dumpPython()"); + + LightApp_DataModel::dumpPython( theURL, theStudy, isMultiFile, theListOfFiles ); + + LightApp_Study* study = dynamic_cast( theStudy ); + SALOME_PYQT_ModuleLight* aModule = dynamic_cast(module()); + + if(!aModule || !study) + return false; + + std::string aTmpDir = study->GetTmpDir( theURL.toLatin1().constData(), isMultiFile ); + + theListOfFiles.append( QString( aTmpDir.c_str() ) ); + int oldSize = theListOfFiles.size(); + + aModule->dumpPython( theListOfFiles ); + + //Return true if some items have been added, else return false + return theListOfFiles.size() > oldSize; +} + //================================================================================= // function : isModified() -// purpose : default implementation, always returns false so as not to mask study's isModified() +// purpose : returns this model's modification status that can be controlled +// with help of setModified() calls by the underlying Python module //================================================================================= bool SALOME_PYQT_DataModelLight::isModified() const { - return false; + return myModified; } //================================================================================= -// function : isSaved() -// purpose : default implementation, always returns true so as not to mask study's isSaved() +// function : setModified() +// purpose : sets the model's modification status, should be used by +// the underlying Python module when its data changes. //================================================================================= -bool SALOME_PYQT_DataModelLight::isSaved() const +void SALOME_PYQT_DataModelLight::setModified( bool flag ) { - return true; + myModified = flag; } - //================================================================================= // function : close() // purpose : Close data model operation 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 2a6c2f21d..6a9e35391 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.h +++ b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.h @@ -46,9 +46,13 @@ public: virtual bool saveAs ( const QString&, CAM_Study*, QStringList& ); virtual bool close (); virtual bool create ( CAM_Study* ); + virtual bool dumpPython( const QString&, + CAM_Study*, + bool, + QStringList& ); virtual bool isModified () const; - virtual bool isSaved () const; + void setModified( bool ); virtual void update ( LightApp_DataObject* = 0, LightApp_Study* = 0 ); @@ -57,6 +61,7 @@ public: private: QString myFileName; QString myStudyURL; + bool myModified; }; #endif // SALOME_PYQT_DATAMODELLIGHT_H diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataObjectLight.cxx b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataObjectLight.cxx index ecdfce0a7..4db8c6fb6 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataObjectLight.cxx +++ b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataObjectLight.cxx @@ -69,6 +69,24 @@ QString SALOME_PYQT_DataObjectLight::entry() const return myEntry; } +//================================================================================= +// function : SALOME_PYQT_DataObjectLight::refEntry() +// purpose : return entry of the data object referenced by this one (if any) +//================================================================================= +QString SALOME_PYQT_DataObjectLight::refEntry() const +{ + return myRefEntry; +} + +//================================================================================= +// function : SALOME_PYQT_DataObjectLight::setRefEntry() +// purpose : sets entry of the data object referenced by this one +//================================================================================= +void SALOME_PYQT_DataObjectLight::setRefEntry( const QString& refEntry ) +{ + myRefEntry = refEntry; +} + //================================================================================= // function : SALOME_PYQT_DataObjectLight::name() // purpose : return name of object @@ -100,6 +118,32 @@ QString SALOME_PYQT_DataObjectLight::toolTip(const int index) const return myToolTip; } +//================================================================================= +// function : SALOME_PYQT_DataObjectLight::toolTip() +// purpose : return toolTip of object +//================================================================================= +QColor SALOME_PYQT_DataObjectLight::color( const ColorRole role, const int id ) const +{ + QColor c; + + switch ( role ) + { + case Text: + case Foreground: + if ( !isReference() ) + c = myColor; + break; + + default: + break; + } + + // Issue 21379: LightApp_DataObject::color() defines colors for valid references + if ( !c.isValid() ) + c = LightApp_DataObject::color( role, id ); + + return c; +} bool SALOME_PYQT_DataObjectLight::setName(const QString& name) { @@ -126,3 +170,8 @@ void SALOME_PYQT_DataObjectLight::setToolTip(const QString& tooltip) { myToolTip = tooltip; } + +void SALOME_PYQT_DataObjectLight::setColor(const QColor& color) +{ + myColor = color; +} diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataObjectLight.h b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataObjectLight.h index 80d5a2ae0..08b59fc97 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataObjectLight.h +++ b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataObjectLight.h @@ -42,20 +42,28 @@ class SALOME_PYQT_LIGHT_EXPORT SALOME_PYQT_DataObjectLight : public virtual Ligh virtual ~SALOME_PYQT_DataObjectLight(); virtual QString entry() const; + + virtual QString refEntry() const; + void setRefEntry( const QString& refEntry ); virtual QString name() const; - QPixmap icon(const int = NameId) const; - QString toolTip(const int = NameId) const; - - bool setName(const QString& name); - void setIcon(const QString& icon); - void setToolTip(const QString& tooltip); + virtual QPixmap icon(const int = NameId) const; + virtual QString toolTip(const int = NameId) const; + + bool setName(const QString& name); + void setIcon(const QString& icon); + void setToolTip(const QString& tooltip); + + virtual QColor color( const ColorRole, const int = NameId ) const; + void setColor(const QColor& color); private: QString myEntry; + QString myRefEntry; QString myName; QString myToolTip; QPixmap myIcon; + QColor myColor; }; #endif // SALOME_PYQT_DATAOBJECTLIGHT_H 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 a28601baf..512e2bfec 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.cxx +++ b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.cxx @@ -2454,8 +2454,96 @@ void SALOME_PYQT_ModuleLight::saveEvent(QStringList& theListOfFiles) return; if ( PyObject_HasAttrString(myModule, (char*)"saveFiles") ) { + // temporary set myInitModule because saveEvent() method + // might be called by the framework when this module is inactive, + // but still it should be possible to access this module's data + // from Python + myInitModule = this; + PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"saveFiles", (char*)"s", (*it).toLatin1().constData())); + + myInitModule = 0; + + if( !res ) { + PyErr_Print(); + } + else{ + // parse the return value + // result can be one string... + if ( PyString_Check( res ) ) { + QString astr = PyString_AsString( res ); + //SCRUTE(astr); + theListOfFiles.append(astr); + } + //also result can be a list... + else if ( PyList_Check( res ) ) { + int size = PyList_Size( res ); + for ( int i = 0; i < size; i++ ) { + PyObject* value = PyList_GetItem( res, i ); + if( value && PyString_Check( value ) ) { + theListOfFiles.append( PyString_AsString( value ) ); + } + } + } + } + } +} + +/* + * Python dump request. + * Called when user activates dump study operation. + */ +void SALOME_PYQT_ModuleLight::dumpPython(QStringList& theListOfFiles) +{ + MESSAGE("SALOME_PYQT_ModuleLight::dumpPython()") + // perform synchronous request to Python event dispatcher + class DumpEvent: public PyInterp_LockRequest + { + public: + DumpEvent(PyInterp_Interp* _py_interp, + SALOME_PYQT_ModuleLight* _obj, + QStringList& _files_list) + : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true) + myObj( _obj ) , + myFilesList(_files_list) {} + protected: + virtual void execute() + { + myObj->dumpEvent(myFilesList); + } + private: + SALOME_PYQT_ModuleLight* myObj; + QStringList& myFilesList; + }; + + // Posting the request only if dispatcher is not busy! + // Executing the request synchronously + if ( !PyInterp_Dispatcher::Get()->IsBusy() ) + PyInterp_Dispatcher::Get()->Exec( new DumpEvent( myInterp, this, theListOfFiles ) ); +} + +void SALOME_PYQT_ModuleLight::dumpEvent(QStringList& theListOfFiles) +{ + MESSAGE("SALOME_PYQT_ModuleLight::dumpEvent()"); + QStringList::Iterator it = theListOfFiles.begin(); + // Python interpreter should be initialized and Python module should be + // import first + if ( !myInterp || !myModule || (it == theListOfFiles.end())) + return; + + if ( PyObject_HasAttrString(myModule, (char*)"dumpStudy") ) { + // temporary set myInitModule because dumpEvent() method + // might be called by the framework when this module is inactive, + // but still it should be possible to access this module's data + // from Python + myInitModule = this; + + PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"dumpStudy", + (char*)"s", (*it).toLatin1().constData())); + + myInitModule = 0; + if( !res ) { PyErr_Print(); } @@ -2681,6 +2769,53 @@ void SALOME_PYQT_ModuleLight::setToolTip(const QString& obj, const QString& tool } } +/* + * Return color of object + */ +QColor SALOME_PYQT_ModuleLight::getColor(const QString& obj) +{ + SALOME_PYQT_DataObjectLight* dataObj = findObject( obj ); + if( dataObj ) { + return dataObj->color( SUIT_DataObject::Foreground ); + } + return QColor(); +} + +/* + * Set color for object + */ +void SALOME_PYQT_ModuleLight::setColor(const QString& obj, const QColor& color) +{ + SALOME_PYQT_DataObjectLight* dataObj = findObject( obj ); + if( dataObj ) { + dataObj->setColor( color ); + } +} + +/* + * Return entry of the referenced object (if any) + */ +QString SALOME_PYQT_ModuleLight::getReference(const QString& obj) +{ + SALOME_PYQT_DataObjectLight* dataObj = findObject(obj); + if(dataObj) { + return dataObj->refEntry(); + } + return QString::null; +} + + +/* + * Set entry of the referenced object + */ +void SALOME_PYQT_ModuleLight::setReference(const QString& obj, const QString& refEntry) +{ + SALOME_PYQT_DataObjectLight* dataObj = findObject(obj); + if(dataObj) { + dataObj->setRefEntry(refEntry); + } +} + /* * Remove object by entry */ 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 6917f3a1d..cf07211b3 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.h +++ b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.h @@ -123,24 +123,32 @@ public: void setPreferenceProperty( const int, const QString&, const QVariant& ); - void save(QStringList& theListOfFiles); - - bool open(QStringList theListOfFiles); + void save(QStringList& theListOfFiles); + bool open(QStringList theListOfFiles); + void dumpPython(QStringList& theListOfFiles); /*create new SALOME_PYQT_DataObjectLight and return its entry*/ - QString createObject(const QString& parent); - QString createObject(const QString& name, - const QString& iconname, - const QString& tooltip, - const QString& parent); + QString createObject(const QString& parent); + QString createObject(const QString& name, + const QString& iconname, + const QString& tooltip, + const QString& parent); /*Sets Name, Icon and Tool Tip for object*/ void setName(const QString& obj,const QString& iconname); void setIcon(const QString& obj,const QString& name); - void setToolTip(const QString& obj, const QString& name); + void setToolTip(const QString& obj, const QString& tooltip); /*Gets Name and Tool Tip for object*/ QString getName(const QString& obj); QString getToolTip(const QString& obj); + + void setColor(const QString& obj, const QColor& color); + QColor getColor(const QString& obj); + + void setReference( const QString& obj, + const QString& refEntry ); + QString getReference( const QString& obj ); + /*remove object*/ void removeObject(const QString& obj); /*remove child*/ @@ -193,6 +201,7 @@ private: void connectView( const SUIT_ViewWindow* ); void saveEvent(QStringList& theListOfFiles); + void dumpEvent(QStringList& theListOfFiles); void openEvent(QStringList theListOfFiles, bool& opened); SALOME_PYQT_DataObjectLight* findObject(const QString& entry); diff --git a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx index 3429ec9b8..632f4713d 100644 --- a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx +++ b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx @@ -32,6 +32,7 @@ #endif #include // this include must be first!!! +#include #include "SalomePyQt.h" #include @@ -612,6 +613,76 @@ void SalomePyQt::updateObjBrowser( const int studyId, bool updateSelection ) ProcessVoidEvent( new TEvent( studyId, updateSelection ) ); } + +/*! + SalomePyQt::isModified() + \return The modification status of the data model + for the currently active Python module + \sa setModified() +*/ +class TIsModifiedEvent: public SALOME_Event +{ +public: + typedef bool TResult; + TResult myResult; + TIsModifiedEvent() : myResult( false ) {} + virtual void Execute() + { + SALOME_PYQT_ModuleLight* module = getActiveModule(); + if ( !module ) + return; + + SALOME_PYQT_DataModelLight* aModel = + dynamic_cast( module->dataModel() ); + if ( aModel ) + myResult = aModel->isModified(); + } +}; +bool SalomePyQt::isModified() +{ + return ProcessEvent(new TIsModifiedEvent()); +} + +/*! + SalomePyQt::setModified() + + Sets the modification status of the data model for + the currently active Python module. This method should be used + by the Python code in order to enable/disable "Save" operation + depending on the module's data state. + + \param New modification status of the data model + + \sa isModified() +*/ +void SalomePyQt::setModified( bool flag ) +{ + class TEvent: public SALOME_Event + { + bool myFlag; + public: + TEvent( bool flag ) + : myFlag( flag ) {} + virtual void Execute() + { + SALOME_PYQT_ModuleLight* module = getActiveModule(); + if ( !module ) + return; + + SALOME_PYQT_DataModelLight* aModel = + dynamic_cast( module->dataModel() ); + LightApp_Application* aLApp = + dynamic_cast( module->application() ); + if ( !aModel || !aLApp ) + return; + + aModel->setModified( myFlag ); + aLApp->updateActions(); + } + }; + ProcessVoidEvent( new TEvent( flag ) ); +} + /*! \brief Default resource file section name. \internal @@ -2975,6 +3046,52 @@ void SalomePyQt::setToolTip(const QString& obj,const QString& tooltip) ProcessVoidEvent(new TSetToolTipEvent(obj,tooltip)); } +/*! + SalomePyQt::setReference(obj,refEntry) + Set entry to referenced object +*/ +class TSetRefEvent: public SALOME_Event +{ +public: + QString myObj; + QString myRefEntry; + TSetRefEvent( const QString& obj, + const QString& refEntry) : myObj(obj), + myRefEntry(refEntry) {} + virtual void Execute() { + SALOME_PYQT_ModuleLight* module = getActiveModule(); + if ( module ) + module->setReference(myObj,myRefEntry); + } +}; +void SalomePyQt::setReference(const QString& obj,const QString& refEntry) +{ + ProcessVoidEvent(new TSetRefEvent(obj,refEntry)); +} + +/*! + SalomePyQt::setColor(obj,color) + Set object color +*/ +class TSetColorEvent: public SALOME_Event +{ +public: + QString myObj; + QColor myColor; + TSetColorEvent( const QString& obj, + const QColor& color) : myObj(obj), + myColor(color) {} + virtual void Execute() { + SALOME_PYQT_ModuleLight* module = getActiveModule(); + if ( module ) + module->setColor(myObj,myColor); + } +}; +void SalomePyQt::setColor(const QString& obj,const QColor& color) +{ + ProcessVoidEvent(new TSetColorEvent(obj,color)); +} + /*! SalomePyQt::getName(obj) Return name of object @@ -3020,6 +3137,49 @@ QString SalomePyQt::getToolTip(const QString& obj) return ProcessEvent(new TGetToolTipEvent(obj)); } +/*! + SalomePyQt::getReference(obj) + Return entry of the referenced object (if any) +*/ +class TGetRefEvent: public SALOME_Event +{ +public: + typedef QString TResult; + TResult myResult; + QString myObj; + TGetRefEvent( const QString& obj ) : myObj(obj) {} + virtual void Execute() { + SALOME_PYQT_ModuleLight* module = getActiveModule(); + if ( module ) + myResult = module->getReference(myObj); + } +}; +QString SalomePyQt::getReference(const QString& obj) +{ + return ProcessEvent(new TGetRefEvent(obj)); +} + +/*! + SalomePyQt::getColor(obj) + Return the color of the object +*/ +class TGetColorEvent: public SALOME_Event +{ +public: + typedef QColor TResult; + TResult myResult; + QString myObj; + TGetColorEvent( const QString& obj ) : myObj(obj) {} + virtual void Execute() { + SALOME_PYQT_ModuleLight* module = getActiveModule(); + if ( module ) + myResult = module->getColor(myObj); + } +}; +QColor SalomePyQt::getColor(const QString& obj) +{ + return ProcessEvent(new TGetColorEvent(obj)); +} /*! SalomePyQt::removeChild(obj) diff --git a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h index 5114bb024..2fd65b871 100644 --- a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h +++ b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h @@ -133,6 +133,9 @@ public: static bool activateModule( const QString& ); static void updateObjBrowser( const int = 0, bool = true ); + static bool isModified(); + static void setModified( bool ); + static QString getFileName ( QWidget*, const QString&, const QStringList&, const QString&, bool ); static QStringList getOpenFileNames ( QWidget*, const QString&, const QStringList&, const QString& ); static QString getExistingDirectory( QWidget*, const QString&, const QString& ); @@ -152,6 +155,13 @@ public: static QString getName(const QString& obj); static QString getToolTip(const QString& obj); + static void setColor(const QString& obj,const QColor& color); + static QColor getColor(const QString& obj); + + static void setReference( const QString& obj, + const QString& refEntry ); + static QString getReference( const QString& obj ); + static QIcon loadIcon( const QString&, const QString& ); static void helpContext( const QString&, const QString& ); diff --git a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip index 9b7c7b1f5..7c2090b6f 100644 --- a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip +++ b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip @@ -215,7 +215,10 @@ public: 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 void updateObjBrowser( const int = 0, bool = true ) /ReleaseGIL/ ; + + static bool isModified() /ReleaseGIL/ ; + static void setModified( bool ) /ReleaseGIL/ ; static QString getFileName ( QWidget*, const QString&, const QStringList&, const QString&, bool ) /ReleaseGIL/ ; static QStringList getOpenFileNames ( QWidget*, const QString&, const QStringList&, const QString& ) /ReleaseGIL/ ; @@ -223,9 +226,9 @@ public: static QString createObject( const QString& = QString("") ) /ReleaseGIL/ ; static QString createObject( const QString&, - const QString&, - const QString&, - const QString& = QString("") ) /ReleaseGIL/ ; + const QString&, + const QString&, + const QString& = QString("") ) /ReleaseGIL/ ; static void setName(const QString& ,const QString& ) /ReleaseGIL/ ; static void setIcon(const QString& ,const QString& ) /ReleaseGIL/ ; @@ -233,6 +236,12 @@ public: static QString getName(const QString& ) /ReleaseGIL/ ; static QString getToolTip(const QString& ) /ReleaseGIL/ ; + static void setColor( const QString&, const QColor& ) /ReleaseGIL/ ; + static QColor getColor( const QString& ) /ReleaseGIL/ ; + + static void setReference( const QString& ,const QString& ) /ReleaseGIL/ ; + static QString getReference( const QString& ) /ReleaseGIL/ ; + static void removeObject(const QString& ) /ReleaseGIL/ ; static void removeChild(const QString& = QString("") ) /ReleaseGIL/ ; static QStringList getChildren(const QString&=QString("") , const bool = false) /ReleaseGIL/ ; diff --git a/src/STD/STD_Application.cxx b/src/STD/STD_Application.cxx index 3172bbe01..f3c75a91f 100755 --- a/src/STD/STD_Application.cxx +++ b/src/STD/STD_Application.cxx @@ -182,7 +182,7 @@ void STD_Application::createActions() createAction( FileSaveAsId, tr( "TOT_DESK_FILE_SAVEAS" ), QIcon(), tr( "MEN_DESK_FILE_SAVEAS" ), tr( "PRP_DESK_FILE_SAVEAS" ), - Qt::CTRL+Qt::Key_A, desk, false, this, SLOT( onSaveAsDoc() ) ); + Qt::CTRL+Qt::SHIFT+Qt::Key_S, desk, false, this, SLOT( onSaveAsDoc() ) ); createAction( EditCopyId, tr( "TOT_DESK_EDIT_COPY" ), resMgr->loadPixmap( "STD", tr( "ICON_EDIT_COPY" ) ), @@ -196,7 +196,7 @@ void STD_Application::createActions() QAction* a = createAction( ViewStatusBarId, tr( "TOT_DESK_VIEW_STATUSBAR" ), QIcon(), tr( "MEN_DESK_VIEW_STATUSBAR" ), - tr( "PRP_DESK_VIEW_STATUSBAR" ), Qt::SHIFT+Qt::Key_S, desk, true ); + tr( "PRP_DESK_VIEW_STATUSBAR" ), Qt::ALT+Qt::SHIFT+Qt::Key_S, desk, true ); a->setChecked( desk->statusBar()->isVisibleTo( desk ) ); connect( a, SIGNAL( toggled( bool ) ), this, SLOT( onViewStatusBar( bool ) ) ); @@ -205,7 +205,7 @@ void STD_Application::createActions() createAction( HelpAboutId, tr( "TOT_DESK_HELP_ABOUT" ), QIcon(), tr( "MEN_DESK_HELP_ABOUT" ), tr( "PRP_DESK_HELP_ABOUT" ), - Qt::SHIFT+Qt::Key_A, desk, false, this, SLOT( onHelpAbout() ) ); + Qt::ALT+Qt::SHIFT+Qt::Key_A, desk, false, this, SLOT( onHelpAbout() ) ); QtxDockAction* dwa = new QtxDockAction( tr( "TOT_DOCKWINDOWS" ), tr( "MEN_DESK_VIEW_DOCKWINDOWS" ), desk ); diff --git a/src/STD/STD_TabDesktop.cxx b/src/STD/STD_TabDesktop.cxx index 3c410ebd2..780359e02 100644 --- a/src/STD/STD_TabDesktop.cxx +++ b/src/STD/STD_TabDesktop.cxx @@ -56,9 +56,9 @@ myWorkstackAction( 0 ) // But the workstack must occupy as much space as possible -- set Expanding for it. myWorkstack->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); - myWorkstack->setAccel( QtxWorkstack::SplitVertical, Qt::SHIFT + Qt::Key_V ); - myWorkstack->setAccel( QtxWorkstack::SplitHorizontal, Qt::SHIFT + Qt::Key_H ); - myWorkstack->setAccel( QtxWorkstack::Close, Qt::SHIFT + Qt::Key_C ); + myWorkstack->setAccel( QtxWorkstack::SplitVertical, Qt::ALT + Qt::SHIFT + Qt::Key_V ); + myWorkstack->setAccel( QtxWorkstack::SplitHorizontal, Qt::ALT + Qt::SHIFT + Qt::Key_H ); + myWorkstack->setAccel( QtxWorkstack::Close, Qt::CTRL + Qt::Key_F4 ); SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); if ( resMgr ) { @@ -204,14 +204,14 @@ void STD_TabDesktop::createActions() resMgr->loadPixmap( "STD", tr( "ICON_DESK_WINDOW_HSPLIT" ) ) ); myWorkstackAction->setText( QtxWorkstackAction::SplitHorizontal, tr( "MEN_DESK_WINDOW_HSPLIT" ) ); myWorkstackAction->setStatusTip( QtxWorkstackAction::SplitHorizontal, tr( "PRP_DESK_WINDOW_HSPLIT" ) ); - myWorkstackAction->setAccel( QtxWorkstackAction::SplitHorizontal, Qt::SHIFT + Qt::Key_H ); + myWorkstackAction->setAccel( QtxWorkstackAction::SplitHorizontal, Qt::ALT + Qt::SHIFT + Qt::Key_H ); // Split Vertical myWorkstackAction->setIcon( QtxWorkstackAction::SplitVertical, resMgr->loadPixmap( "STD", tr( "ICON_DESK_WINDOW_VSPLIT" ) ) ); myWorkstackAction->setText( QtxWorkstackAction::SplitVertical, tr( "MEN_DESK_WINDOW_VSPLIT" ) ); myWorkstackAction->setStatusTip( QtxWorkstackAction::SplitVertical, tr( "PRP_DESK_WINDOW_VSPLIT" ) ); - myWorkstackAction->setAccel( QtxWorkstackAction::SplitVertical, Qt::SHIFT + Qt::Key_V ); + myWorkstackAction->setAccel( QtxWorkstackAction::SplitVertical, Qt::ALT + Qt::SHIFT + Qt::Key_V ); QtxActionMenuMgr* mMgr = menuMgr(); if ( !mMgr ) diff --git a/src/SalomeApp/SalomeApp_Application.cxx b/src/SalomeApp/SalomeApp_Application.cxx index fcac1c19d..151d84d31 100644 --- a/src/SalomeApp/SalomeApp_Application.cxx +++ b/src/SalomeApp/SalomeApp_Application.cxx @@ -299,7 +299,7 @@ void SalomeApp_Application::createActions() //! Catalog Generator createAction( CatalogGenId, tr( "TOT_DESK_CATALOG_GENERATOR" ), QIcon(), tr( "MEN_DESK_CATALOG_GENERATOR" ), tr( "PRP_DESK_CATALOG_GENERATOR" ), - Qt::SHIFT+Qt::Key_G, desk, false, this, SLOT( onCatalogGen() ) ); + Qt::ALT+Qt::SHIFT+Qt::Key_G, desk, false, this, SLOT( onCatalogGen() ) ); //! Registry Display createAction( RegDisplayId, tr( "TOT_DESK_REGISTRY_DISPLAY" ), QIcon(), @@ -812,21 +812,10 @@ void SalomeApp_Application::onDumpStudy( ) QFileInfo aFileInfo(aFileName); if( aFileInfo.isDir() ) // IPAL19257 return; + + // Issue 21377 - dump study implementation moved to SalomeApp_Study class + bool res = appStudy->dump( aFileName, toPublish, isMultiFile, toSaveGUI ); - int savePoint; - _PTR(AttributeParameter) ap; - _PTR(IParameters) ip = ClientFactory::getIParameters(ap); - if(ip->isDumpPython(appStudy->studyDS())) ip->setDumpPython(appStudy->studyDS()); //Unset DumpPython flag. - if ( toSaveGUI ) { //SRN: Store a visual state of the study at the save point for DumpStudy method - ip->setDumpPython(appStudy->studyDS()); - savePoint = SalomeApp_VisualState( this ).storeState(); //SRN: create a temporary save point - } - bool res = aStudy->DumpStudy( aFileInfo.absolutePath().toStdString(), - aFileInfo.baseName().toStdString(), - toPublish, - isMultiFile); - if ( toSaveGUI ) - appStudy->removeSavePoint(savePoint); //SRN: remove the created temporary save point. if ( !res ) SUIT_MessageBox::warning( desktop(), QObject::tr("WRN_WARNING"), @@ -1001,7 +990,7 @@ void SalomeApp_Application::createPreferences( LightApp_Preferences* pref ) int salomeCat = pref->addPreference( tr( "PREF_CATEGORY_SALOME" ) ); int obTab = pref->addPreference( tr( "PREF_TAB_OBJBROWSER" ), salomeCat ); int defCols = pref->addPreference( tr( "PREF_GROUP_DEF_COLUMNS" ), obTab ); - for ( int i = SalomeApp_DataObject::EntryId; i <= SalomeApp_DataObject::RefEntryId; i++ ) + for ( int i = SalomeApp_DataObject::EntryId; i < SalomeApp_DataObject::LastId; i++ ) { pref->addPreference( tr( QString().sprintf( "OBJ_BROWSER_COLUMN_%d", i-SalomeApp_DataObject::EntryId ).toLatin1() ), defCols, LightApp_Preferences::Bool, "ObjectBrowser", QString().sprintf( "visibility_column_id_%d", i-1 ) ); @@ -1222,20 +1211,6 @@ SALOME_LifeCycleCORBA* SalomeApp_Application::lcc() return &_lcc; } -/*!Return default engine IOR for light modules*/ -QString SalomeApp_Application::defaultEngineIOR() -{ - /// Look for a default module engine (needed for CORBAless modules to use SALOMEDS persistence) - QString anIOR( "" ); - CORBA::Object_ptr anEngine = namingService()->Resolve( "/SalomeAppEngine" ); - if ( !CORBA::is_nil( anEngine ) ) - { - CORBA::String_var objStr = orb()->object_to_string( anEngine ); - anIOR = QString( objStr.in() ); - } - return anIOR; -} - /*!Private SLOT. On preferences.*/ void SalomeApp_Application::onProperties() { @@ -1417,28 +1392,22 @@ void SalomeApp_Application::onRegDisplay() /*!find original object by double click on item */ void SalomeApp_Application::onDblClick( SUIT_DataObject* theObj ) { - SalomeApp_DataObject* obj = dynamic_cast( theObj ); - SalomeApp_Study* study = dynamic_cast( activeStudy() ); + // Issue 21379: References are supported at LightApp_DataObject level + LightApp_DataObject* obj = dynamic_cast( theObj ); - if( study && obj ) + if( obj && obj->isReference() ) { - QString entry = obj->entry(); - _PTR(SObject) sobj = study->studyDS()->FindObjectID( entry.toStdString() ), ref; - - if( sobj && sobj->ReferencedObject( ref ) ) - { - entry = ref->GetID().c_str(); + QString entry = obj->refEntry(); - SUIT_DataOwnerPtrList aList; - aList.append( new LightApp_DataOwner( entry ) ); - selectionMgr()->setSelected( aList, false ); + SUIT_DataOwnerPtrList aList; + aList.append( new LightApp_DataOwner( entry ) ); + selectionMgr()->setSelected( aList, false ); + + SUIT_DataBrowser* ob = objectBrowser(); - SUIT_DataBrowser* ob = objectBrowser(); - - QModelIndexList aSelectedIndexes = ob->selectedIndexes(); - if ( !aSelectedIndexes.isEmpty() ) - ob->treeView()->scrollTo( aSelectedIndexes.first() ); - } + QModelIndexList aSelectedIndexes = ob->selectedIndexes(); + if ( !aSelectedIndexes.isEmpty() ) + ob->treeView()->scrollTo( aSelectedIndexes.first() ); } } @@ -1654,7 +1623,7 @@ bool SalomeApp_Application::useStudy( const QString& theName ) void SalomeApp_Application::objectBrowserColumnsVisibility() { if ( objectBrowser() ) - for ( int i = SalomeApp_DataObject::EntryId; i <= SalomeApp_DataObject::RefEntryId; i++ ) + for ( int i = SalomeApp_DataObject::EntryId; i < SalomeApp_DataObject::LastId; i++ ) { bool shown = resourceMgr()->booleanValue( "ObjectBrowser", QString( "visibility_column_id_%1" ).arg( i-1 ), true ); objectBrowser()->treeView()->setColumnHidden( i, !shown ); diff --git a/src/SalomeApp/SalomeApp_Application.h b/src/SalomeApp/SalomeApp_Application.h index aab013d66..711333875 100644 --- a/src/SalomeApp/SalomeApp_Application.h +++ b/src/SalomeApp/SalomeApp_Application.h @@ -96,7 +96,6 @@ public: static SALOMEDSClient_StudyManager* studyMgr(); static SALOME_NamingService* namingService(); static SALOME_LifeCycleCORBA* lcc(); - static QString defaultEngineIOR(); SUIT_ViewManager* newViewManager(const QString&); void updateSavePointDataObjects( SalomeApp_Study* ); diff --git a/src/SalomeApp/SalomeApp_DataObject.cxx b/src/SalomeApp/SalomeApp_DataObject.cxx index 86fb9f13c..481d3fc2b 100644 --- a/src/SalomeApp/SalomeApp_DataObject.cxx +++ b/src/SalomeApp/SalomeApp_DataObject.cxx @@ -125,7 +125,7 @@ QString SalomeApp_DataObject::text( const int id ) const { QString txt; - // add "Value", "IOR", and "Reference Entry" columns + // Text for "Value" and "IOR" columns switch ( id ) { case ValueId: @@ -141,11 +141,9 @@ QString SalomeApp_DataObject::text( const int id ) const case IORId: txt = ior( referencedObject() ); break; - case RefEntryId : - if ( isReference() ) - txt = entry( referencedObject() ); - break; default: + // Issue 21379: LightApp_DataObject::text() treats "Entry" + // and "Reference Entry" columns txt = LightApp_DataObject::text( id ); break; } @@ -202,9 +200,7 @@ QColor SalomeApp_DataObject::color( const ColorRole role, const int id ) const case Foreground: // text color (not selected item) if ( isReference() ) { - if ( !(QString(referencedObject()->GetName().c_str()).isEmpty()) ) - c = QColor( 255, 0, 0 ); // valid reference (red) - else + if ( QString(referencedObject()->GetName().c_str()).isEmpty() ) c = QColor( 200, 200, 200 ); // invalid reference (grayed) } else if ( myObject ) { @@ -216,12 +212,11 @@ QColor SalomeApp_DataObject::color( const ColorRole role, const int id ) const } } break; + case Highlight: // background color for the highlighted item if ( isReference() ) { - if ( !(QString(referencedObject()->GetName().c_str()).isEmpty()) ) - c = QColor( 255, 0, 0 ); // valid reference (red) - else + if ( QString(referencedObject()->GetName().c_str()).isEmpty() ) c = QColor( 200, 200, 200 ); // invalid reference (grayed) } else if ( myObject ) { @@ -235,14 +230,14 @@ QColor SalomeApp_DataObject::color( const ColorRole role, const int id ) const } } break; - case HighlightedText: - // text color for the highlighted item - if ( isReference() ) - c = QColor( 255, 255, 255 ); // white + default: break; } + + // Issue 21379: LightApp_DataObject::color() defines colors for valid references if ( !c.isValid() ) c = LightApp_DataObject::color( role, id ); + return c; } @@ -329,8 +324,23 @@ _PTR(SObject) SalomeApp_DataObject::object() const return myObject; } +/*! + \brief Returns the string identifier of the data objects referenced by this one. + + Re-implemented from LightApp_DataObject using SALOMEDS API. + + \return ID string of the referenced SObject +*/ +QString SalomeApp_DataObject::refEntry() const +{ + return entry( referencedObject() ); +} + /*! \brief Check if the data object is a reference. + + Re-implemented from LightApp_DataObject using SALOMEDS API. + \return \c true if this data object actually refers to another one */ bool SalomeApp_DataObject::isReference() const diff --git a/src/SalomeApp/SalomeApp_DataObject.h b/src/SalomeApp/SalomeApp_DataObject.h index dc4f28984..f9b2b7446 100644 --- a/src/SalomeApp/SalomeApp_DataObject.h +++ b/src/SalomeApp/SalomeApp_DataObject.h @@ -37,9 +37,9 @@ class SALOMEAPP_EXPORT SalomeApp_DataObject : public virtual LightApp_DataObject public: //! Column id enum { - ValueId = EntryId + 1, //!< value column - IORId, //!< IOR column - RefEntryId //!< reference entry column + ValueId = RefEntryId + 1, //!< value column + IORId, //!< IOR column + LastId //!< indicates last Id value }; public: @@ -58,8 +58,10 @@ public: virtual _PTR(SObject) object() const; - bool isReference() const; + virtual QString refEntry() const; + virtual bool isReference() const; _PTR(SObject) referencedObject() const; + bool hasChildren() const; bool expandable() const; diff --git a/src/SalomeApp/SalomeApp_Study.cxx b/src/SalomeApp/SalomeApp_Study.cxx index c46ea3e69..f16825432 100644 --- a/src/SalomeApp/SalomeApp_Study.cxx +++ b/src/SalomeApp/SalomeApp_Study.cxx @@ -33,6 +33,7 @@ #include #include +#include #include "SALOME_Event.h" #include "Basics_Utils.hxx" @@ -571,7 +572,10 @@ bool SalomeApp_Study::saveDocumentAs( const QString& theFileName ) QListIterator it( list ); QStringList listOfFiles; while ( it.hasNext() ) { - if ( SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)it.next() ) { + // Cast to LightApp class in order to give a chance + // to light modules to save their data + if ( LightApp_DataModel* aModel = + dynamic_cast( it.next() ) ) { listOfFiles.clear(); aModel->saveAs( theFileName, this, listOfFiles ); if ( !listOfFiles.isEmpty() ) @@ -613,7 +617,10 @@ bool SalomeApp_Study::saveDocument() QListIterator it( list ); QStringList listOfFiles; while ( it.hasNext() ) { - if ( SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)it.next() ) { + // Cast to LightApp class in order to give a chance + // to light modules to save their data + if ( LightApp_DataModel* aModel = + dynamic_cast( it.next() ) ) { listOfFiles.clear(); aModel->save(listOfFiles); if ( !listOfFiles.isEmpty() ) @@ -658,6 +665,80 @@ void SalomeApp_Study::closeDocument(bool permanently) } } +/*! + Dump study operation. Writes a Python dump file using + SALOMEDS services. Additionally, gives a chance to light modules + to participate in dump study operation. + + \param theFileName - full path to the output Python file + \param toPublish - if true, all objects are published in a study + by the output script, including those not orignally present + in the current study. + \param isMultiFile - if true, each module's dump is written into + a separate Python file, otherwise a single output file is written + \param toSaveGUI - if true, the GUI state is written + + \return - true if the operation succeeds, and false otherwise. +*/ +bool SalomeApp_Study::dump( const QString& theFileName, + bool toPublish, + bool isMultiFile, + bool toSaveGUI ) +{ + int savePoint; + _PTR(AttributeParameter) ap; + _PTR(IParameters) ip = ClientFactory::getIParameters(ap); + _PTR(Study) aStudy = studyDS(); + + if( ip->isDumpPython( aStudy ) ) + ip->setDumpPython( aStudy ); //Unset DumpPython flag. + + if ( toSaveGUI ) { //SRN: Store a visual state of the study at the save point for DumpStudy method + ip->setDumpPython( aStudy ); + //SRN: create a temporary save point + savePoint = SalomeApp_VisualState( + dynamic_cast( application() ) ).storeState(); + } + + // Issue 21377 - Each data model is asked to dump its data not present in SALOMEDS study. + // This is an optional but important step, it gives a chance to light modules + // to dump their data as a part of common dump study operation + ModelList list; + dataModels( list ); + + QListIterator it( list ); + QStringList listOfFiles; + while ( it.hasNext() ) { + if ( LightApp_DataModel* aModel = + dynamic_cast( it.next() ) ) { + listOfFiles.clear(); + if ( aModel->dumpPython( theFileName, this, isMultiFile, listOfFiles ) && + !listOfFiles.isEmpty() ) + // This call simply passes the data model's dump output to SalomeApp_Engine servant. + // This code is shared with persistence mechanism. + // NOTE: this should be revised if behavior of saveModuleData() changes! + saveModuleData(aModel->module()->name(), listOfFiles); + } + } + + // Now dump SALOMEDS part that also involves SalomeApp_Engine in case if + // any light module is present in the current configuration + QFileInfo aFileInfo( theFileName ); + bool res = aStudy->DumpStudy( aFileInfo.absolutePath().toStdString(), + aFileInfo.baseName().toStdString(), + toPublish, + isMultiFile); + if ( toSaveGUI ) + removeSavePoint( savePoint ); //SRN: remove the created temporary save point. + + // Issue 21377 - Clean up light module data in SalomeApp_Engine servant + // This code is shared with persistence mechanism. + // NOTE: this should be revised if behavior of saveStudyData() changes! + saveStudyData( theFileName ); + + return res; +} + /*! \return true, if study is modified in comparison with last open/save */ @@ -735,16 +816,22 @@ void SalomeApp_Study::openModuleData( QString theModuleName, QStringList& theLis } /*! - Saves data from study + Re-implemented from LightApp_Study, actually does not save anything but + simply cleans up light modules' data */ bool SalomeApp_Study::saveStudyData( const QString& theFileName ) { ModelList list; dataModels( list ); QListIterator it( list ); std::vector listOfFiles(0); - while ( it.hasNext() ) - if ( SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)it.next() ) - SetListOfFiles(aModel->module()->name().toStdString().c_str(), listOfFiles); + while ( it.hasNext() ){ + LightApp_DataModel* aLModel = + dynamic_cast( it.next() ); + // It is safe to call SetListOfFiles() for any kind of module + // because SetListOfFiles() does nothing for full modules :) + if ( aLModel ) + SetListOfFiles(aLModel->module()->name().toStdString().c_str(), listOfFiles); + } return true; } @@ -836,11 +923,14 @@ void SalomeApp_Study::addComponent(const CAM_DataModel* dm) _PTR(Study) aStudy = studyDS(); if (!aStudy) return; - _PTR(SComponent) aComp = aStudy->FindComponent(dm->module()->name().toStdString()); + + std::string aCompDataType = dm->module()->name().toStdString(); + + _PTR(SComponent) aComp = aStudy->FindComponent(aCompDataType); if (!aComp) { // Create SComponent _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder(); - aComp = aBuilder->NewComponent(dm->module()->name().toStdString()); + aComp = aBuilder->NewComponent(aCompDataType); aBuilder->SetName(aComp, dm->module()->moduleName().toStdString()); QString anIconName = dm->module()->iconName(); if (!anIconName.isEmpty()) { @@ -848,8 +938,12 @@ void SalomeApp_Study::addComponent(const CAM_DataModel* dm) if (anAttr) anAttr->SetPixMap(anIconName.toStdString()); } + // Set default engine IOR - aBuilder->DefineComponentInstance(aComp, SalomeApp_Application::defaultEngineIOR().toStdString()); + // Issue 21377 - using separate engine for each type of light module + std::string anEngineIOR = SalomeApp_Engine_i::EngineIORForComponent( aCompDataType.c_str(), + true ); + aBuilder->DefineComponentInstance(aComp, anEngineIOR); //SalomeApp_DataModel::BuildTree( aComp, root(), this, /*skipExisitng=*/true ); SalomeApp_DataModel::synchronize( aComp, this ); } @@ -882,8 +976,10 @@ bool SalomeApp_Study::openDataModel( const QString& studyName, CAM_DataModel* dm QString anEngine; // 1. aModule == 0 means that this is a light module (no CORBA enigine) if (!aModule) { - anEngine = SalomeApp_Application::defaultEngineIOR(); - aSComp = aStudy->FindComponent(dm->module()->name().toStdString()); + // Issue 21377 - using separate engine for each type of light module + std::string aCompDataType = dm->module()->name().toStdString(); + anEngine = SalomeApp_Engine_i::EngineIORForComponent( aCompDataType.c_str(), true ).c_str(); + aSComp = aStudy->FindComponent( aCompDataType ); } else { SalomeApp_DataModel* aDM = dynamic_cast( dm ); @@ -955,30 +1051,38 @@ QString SalomeApp_Study::newStudyName() const } /*! + Note that this method does not create or activate SalomeApp_Engine_i instance, + therefore it can be called safely for any kind of module, but for full + modules it returns an empty list. \return list of files used by module: to be used by CORBAless modules \param theModuleName - name of module */ std::vector SalomeApp_Study::GetListOfFiles( const char* theModuleName ) const { - SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance(); + // Issue 21377 - using separate engine for each type of light module + SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance( theModuleName, false ); if (aDefaultEngine) - return aDefaultEngine->GetListOfFiles(id(), theModuleName); + return aDefaultEngine->GetListOfFiles(id()); std::vector aListOfFiles; return aListOfFiles; } /*! - Sets list of files used by module: to be used by CORBAless modules + Sets list of files used by module: to be used by CORBAless modules. + Note that this method does not create or activate SalomeApp_Engine_i instance, + therefore it can be called safely for any kind of module, but for full + modules it simply does nothing. \param theModuleName - name of module \param theListOfFiles - list of files */ void SalomeApp_Study::SetListOfFiles ( const char* theModuleName, const std::vector theListOfFiles ) { - SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance(); + // Issue 21377 - using separate engine for each type of light module + SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance( theModuleName, false ); if (aDefaultEngine) - aDefaultEngine->SetListOfFiles(theListOfFiles, id(), theModuleName); + aDefaultEngine->SetListOfFiles(theListOfFiles, id()); } /*! diff --git a/src/SalomeApp/SalomeApp_Study.h b/src/SalomeApp/SalomeApp_Study.h index 41ebe3715..2487cd5de 100644 --- a/src/SalomeApp/SalomeApp_Study.h +++ b/src/SalomeApp/SalomeApp_Study.h @@ -55,6 +55,8 @@ public: virtual void closeDocument(bool permanently = true); + virtual bool dump( const QString&, bool, bool, bool ); + virtual bool isSaved() const; virtual bool isModified() const; virtual void Modified(); diff --git a/src/Session/SalomeApp_Engine_i.cxx b/src/Session/SalomeApp_Engine_i.cxx index 639d3e84f..e43c936e9 100644 --- a/src/Session/SalomeApp_Engine_i.cxx +++ b/src/Session/SalomeApp_Engine_i.cxx @@ -28,20 +28,29 @@ // #include "SalomeApp_Engine_i.hxx" -#include "SALOMEDS_Tool.hxx" +#include +#include +#include +#include +#include +#include + +#include +#include +#include #include using namespace std; -SalomeApp_Engine_i* SalomeApp_Engine_i::myInstance = NULL; - /*! Constructor */ -SalomeApp_Engine_i::SalomeApp_Engine_i() +SalomeApp_Engine_i::SalomeApp_Engine_i( const char* theComponentName ) { - myInstance = this; + myComponentName = theComponentName; + MESSAGE("SalomeApp_Engine_i::SalomeApp_Engine_i(): myComponentName = " << + myComponentName << ", this = " << this); } /*! @@ -49,6 +58,8 @@ SalomeApp_Engine_i::SalomeApp_Engine_i() */ SalomeApp_Engine_i::~SalomeApp_Engine_i() { + MESSAGE("SalomeApp_Engine_i::~SalomeApp_Engine_i(): myComponentName = " << + myComponentName << ", this = " << this); } SALOMEDS::TMPFile* SalomeApp_Engine_i::Save (SALOMEDS::SComponent_ptr theComponent, @@ -57,22 +68,23 @@ SALOMEDS::TMPFile* SalomeApp_Engine_i::Save (SALOMEDS::SComponent_ptr theCompone { SALOMEDS::TMPFile_var aStreamFile = new SALOMEDS::TMPFile; - cout << "SalomeApp_Engine_i::Save() isMultiFile = " << isMultiFile << endl; if (CORBA::is_nil(theComponent) || CORBA::is_nil(theComponent->GetStudy())) return aStreamFile._retn(); const int studyId = theComponent->GetStudy()->StudyId(); - cout << "SalomeApp_Engine_i::Save() - studyId = " << studyId << endl; // Get a temporary directory to store a file //std::string aTmpDir = isMultiFile ? theURL : SALOMEDS_Tool::GetTmpDir(); if (myMap.count(studyId)) { - cout << "SalomeApp_Engine_i::Save() - myMap.count(studyId)" << endl; - MapOfListOfFiles mapOfListOfFiles = myMap[studyId]; std::string componentName (theComponent->ComponentDataType()); - cout << "SalomeApp_Engine_i::Save() - componentName = " << componentName << endl; - ListOfFiles listOfFiles = mapOfListOfFiles[componentName]; + + // Error somewhere outside - Save() called with + // wrong SComponent instance + if ( myComponentName != componentName ) + return aStreamFile._retn(); + + const ListOfFiles& listOfFiles = myMap[studyId]; // listOfFiles must contain temporary directory name in its first item // and names of files (relatively the temporary directory) in the others @@ -80,7 +92,6 @@ SALOMEDS::TMPFile* SalomeApp_Engine_i::Save (SALOMEDS::SComponent_ptr theCompone if (n > 0) { // there are some files, containing persistent data of the component std::string aTmpDir = listOfFiles[0]; - cout << "SalomeApp_Engine_i::Save() - aTmpDir = " << aTmpDir << endl; // Create a list to store names of created files SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames; @@ -108,6 +119,12 @@ CORBA::Boolean SalomeApp_Engine_i::Load (SALOMEDS::SComponent_ptr theComponent, if (CORBA::is_nil(theComponent) || CORBA::is_nil(theComponent->GetStudy())) return false; + // Error somewhere outside - Load() called with + // wrong SComponent instance + std::string componentName (theComponent->ComponentDataType()); + if ( myComponentName != componentName ) + return false; + const int studyId = theComponent->GetStudy()->StudyId(); // Create a temporary directory for the component's data files @@ -125,52 +142,259 @@ CORBA::Boolean SalomeApp_Engine_i::Load (SALOMEDS::SComponent_ptr theComponent, for (int i = 1; i < n; i++) listOfFiles[i] = std::string(aSeq[i - 1]); - //MapOfListOfFiles mapOfListOfFiles; - //if (myMap.count(studyId)) - // mapOfListOfFiles = myMap[studyId]; - //std::string componentName (theComponent->ComponentDataType()); - //mapOfListOfFiles[componentName] = listOfFiles; - //myMap[studyId] = mapOfListOfFiles; - - SetListOfFiles(listOfFiles, studyId, theComponent->ComponentDataType()); + SetListOfFiles(listOfFiles, studyId); return true; } -SalomeApp_Engine_i::ListOfFiles SalomeApp_Engine_i::GetListOfFiles (const int theStudyId, - const char* theComponentName) +SalomeApp_Engine_i::ListOfFiles SalomeApp_Engine_i::GetListOfFiles (const int theStudyId) { ListOfFiles aListOfFiles; - if (myMap.count(theStudyId)) + if (myMap.find(theStudyId) != myMap.end()) { - MapOfListOfFiles mapOfListOfFiles = myMap[theStudyId]; - std::string componentName (theComponentName); - if (mapOfListOfFiles.count(componentName)) - aListOfFiles = mapOfListOfFiles[componentName]; + aListOfFiles = myMap[theStudyId]; } return aListOfFiles; } -void SalomeApp_Engine_i::SetListOfFiles (const ListOfFiles theListOfFiles, - const int theStudyId, - const char* theComponentName) +void SalomeApp_Engine_i::SetListOfFiles (const ListOfFiles& theListOfFiles, + const int theStudyId) { - //if (!myMap.count(theStudyId)) { - // MapOfListOfFiles mapOfListOfFiles; - // myMap[theStudyId] = mapOfListOfFiles; - //} - - MapOfListOfFiles& mapOfListOfFiles = myMap[theStudyId]; - std::string componentName (theComponentName); - mapOfListOfFiles[componentName] = theListOfFiles; + myMap[theStudyId] = theListOfFiles; +} + +/*! + * DumpPython implementation for light modules + */ +Engines::TMPFile* SalomeApp_Engine_i::DumpPython(CORBA::Object_ptr theStudy, + CORBA::Boolean isPublished, + CORBA::Boolean isMultiFile, + CORBA::Boolean& isValidScript) +{ + MESSAGE("SalomeApp_Engine_i::DumpPython(): myComponentName = "<< + myComponentName << ", this = " << this); + + // Temporary solution: returning a non-empty sequence + // even if there's nothing to dump, to avoid crashes in SALOMEDS + // TODO: Improve SALOMEDSImpl_Study::DumpStudy() by skipping the components + // with isValidScript == false, and initialize isValidScript by false below. + Engines::TMPFile_var aStreamFile = new Engines::TMPFile(1); + aStreamFile->length( 1 ); + aStreamFile[0] = '\0'; + isValidScript = true; + + if (CORBA::is_nil(theStudy)) + return aStreamFile._retn(); + + SALOMEDS::Study_var studyDS = SALOMEDS::Study::_narrow( theStudy ); + const int studyId = studyDS->StudyId(); + + if (!myMap.count(studyId)) + return aStreamFile._retn(); + + ListOfFiles listOfFiles = myMap[studyId]; + + // listOfFiles must contain temporary directory name in its first item + // and names of files (relatively the temporary directory) in the others + if ( listOfFiles.size() < 2 ) + return aStreamFile._retn(); + + // there are some files, containing persistent data of the component + QString aTmpPath( listOfFiles.front().c_str() ); + QDir aTmpDir( aTmpPath ); + if ( !aTmpDir.exists() ) + return aStreamFile._retn(); + + // Calculate file sizes + QStringList aFilePaths; + QList aFileSizes; + qint64 aBuffSize = 0; + ListOfFiles::const_iterator aFIt = listOfFiles.begin(); + ListOfFiles::const_iterator aFEnd = listOfFiles.end(); + aFIt++; + for (; aFIt != aFEnd; aFIt++){ + QString aFileName( (*aFIt).c_str() ); + if ( !aTmpDir.exists( aFileName ) ){ + continue; + } + + QFile aFile( aTmpDir.filePath( aFileName ) ); + if ( !aFile.open( QIODevice::ReadOnly ) ){ + continue; + } + + aFilePaths.push_back( aTmpDir.filePath( aFileName ) ); + aFileSizes.push_back( aFile.size() ); + aBuffSize += aFileSizes.back(); + + aFile.close(); + } + + if ( !aFilePaths.size() || !aBuffSize ) + return aStreamFile._retn(); + + char* aBuffer = new char[aBuffSize + 1]; + if ( !aBuffer ) + return aStreamFile._retn(); + + // Convert the file(s) to the byte stream, multiple files are simply + // concatenated + // TODO: imporve multi-script support if necessary... + qint64 aCurrPos = 0; + QStringList::const_iterator aFileIt = aFilePaths.begin(); + QStringList::const_iterator aFileEnd = aFilePaths.end(); + QList::const_iterator aSIt = aFileSizes.begin(); + for ( ; aFileIt != aFileEnd; aFileIt++, aSIt++ ){ + QFile aFile( aTmpDir.filePath( *aFileIt ) ); + if ( !aFile.open( QIODevice::ReadOnly ) ){ + continue; + } + + // Incorrect size of file + // Do not remove the bad file to have some diagnostic means + if ( aFile.read( aBuffer + aCurrPos, *aSIt ) != *aSIt ){ + aFile.close(); + return aStreamFile._retn(); + } + + aCurrPos += (*aSIt); + aFile.remove(); + } + + // Here we should end up with empty aTmpDir + // TODO: Handle QDir::rmdir() error status somehow... + aTmpDir.rmdir( aTmpPath ); + + aBuffer[aBuffSize] = '\0'; + CORBA::Octet* anOctetBuf = (CORBA::Octet*)aBuffer; + aStreamFile = new Engines::TMPFile(aBuffSize + 1, aBuffSize + 1, anOctetBuf, 1); + + return aStreamFile._retn(); } /*! - \return shared instance of engine + \return Component data type string for this instance of the engine */ -SalomeApp_Engine_i* SalomeApp_Engine_i::GetInstance() +char* SalomeApp_Engine_i::ComponentDataType() { - return myInstance; + return const_cast( myComponentName.c_str() ); } + +/*! + \return +*/ +CORBA::ORB_var SalomeApp_Engine_i::orb() +{ + ORB_INIT& init = *SINGLETON_::Instance(); + // TODO: using QApplication here looks ugly, think how to + // obtain the ORB reference in a nicer way... + static CORBA::ORB_var _orb = init( qApp->argc(), qApp->argv() ); + return _orb; +} + +/*! + \return +*/ +PortableServer::POA_var SalomeApp_Engine_i::poa() +{ + static PortableServer::POA_var _poa; + if ( CORBA::is_nil( _poa ) ){ + CORBA::Object_var obj = orb()->resolve_initial_references( "RootPOA" ); + _poa = PortableServer::POA::_narrow( obj ); + } + return _poa; +} + +/*! + \return +*/ +SALOME_NamingService* SalomeApp_Engine_i::namingService() +{ + static SALOME_NamingService _ns(orb()); + return &_ns; +} + +/*! + Internal method, creates a CORBA engine for a light SALOME module + with the given "component data type" string, + activates it and registers in SALOME naming service with + /SalomeAppEngine/comp_data_type path. If the engine is already in the + naming service, simply returns and object reference to it. + \param theComponentName - synthetic "component data type" used to identify a given light module + \return Object reference to the CORBA engine +*/ +CORBA::Object_ptr SalomeApp_Engine_i::engineForComponent( const char* theComponentName, + bool toCreate ) +{ + CORBA::Object_var anEngine; + if ( !theComponentName || !strlen( theComponentName ) ) + return anEngine._retn(); + + std::string aPath( "/SalomeAppEngine/" ); + aPath += theComponentName; + anEngine = namingService()->Resolve( aPath.c_str() ); + + // Activating a new instance of the servant + if ( toCreate && CORBA::is_nil( anEngine ) ){ + try { + SalomeApp_Engine_i* aServant = new SalomeApp_Engine_i( theComponentName ); + PortableServer::ObjectId_var id = poa()->activate_object( aServant ); + anEngine = aServant->_this(); + aServant->_remove_ref(); + namingService()->Register( anEngine.in(), aPath.c_str() ); + } + catch (CORBA::SystemException&) { + INFOS("Caught CORBA::SystemException."); + } + catch (CORBA::Exception&) { + INFOS("Caught CORBA::Exception."); + } + catch (...) { + INFOS("Caught unknown exception."); + } + } + + return anEngine._retn(); +} + +/*! + \param theComponentName - synthetic "component data type" used to identify a given light module + \return IOR string for the CORBA engine for a light SALOME module + with the given "component data type" string + \sa GetInstance( const char* theComponentName ) +*/ +std::string SalomeApp_Engine_i::EngineIORForComponent( const char* theComponentName, + bool toCreate ) +{ + std::string anIOR( "" ); + CORBA::Object_var anEngine = engineForComponent( theComponentName, toCreate ); + if ( !CORBA::is_nil( anEngine ) ) + { + CORBA::String_var objStr = orb()->object_to_string( anEngine.in() ); + anIOR = std::string( objStr.in() ); + } + return anIOR; +} + +/*! + \param theComponentName - synthetic "component data type" used to identify a given light module + \return A pointer to corresponding C++ engine instance, null means some internal problems. + \sa EngineIORForComponent( const char* theComponentName ) +*/ +SalomeApp_Engine_i* SalomeApp_Engine_i::GetInstance( const char* theComponentName, + bool toCreate ) +{ + SalomeApp_Engine_i* aServant = 0; + CORBA::Object_var anEngine = engineForComponent( theComponentName, toCreate ); + if ( !CORBA::is_nil( anEngine ) ) + { + PortableServer::Servant aServantBase = poa()->reference_to_servant( anEngine.in() ); + aServant = dynamic_cast( aServantBase ); + } + MESSAGE("SalomeApp_Engine_i::GetInstance(): theComponentName = " << + theComponentName << ", aServant = " << aServant); + return aServant; +} + diff --git a/src/Session/SalomeApp_Engine_i.hxx b/src/Session/SalomeApp_Engine_i.hxx index 965f46b9c..e9030cbb7 100755 --- a/src/Session/SalomeApp_Engine_i.hxx +++ b/src/Session/SalomeApp_Engine_i.hxx @@ -39,11 +39,13 @@ #include #include CORBA_SERVER_HEADER(SalomeApp_Engine) +class SALOME_NamingService; + class SESSION_EXPORT SalomeApp_Engine_i: public POA_SalomeApp::Engine, - public Engines_Component_i + public Engines_Component_i { public: - SalomeApp_Engine_i(); + SalomeApp_Engine_i( const char* theComponentName ); ~SalomeApp_Engine_i(); SALOMEDS::TMPFile* Save( SALOMEDS::SComponent_ptr theComponent, @@ -55,17 +57,22 @@ public: const char* theURL, bool isMultiFile ); + virtual Engines::TMPFile* DumpPython(CORBA::Object_ptr theStudy, + CORBA::Boolean isPublished, + CORBA::Boolean isMultiFile, + CORBA::Boolean& isValidScript); + public: typedef std::vector ListOfFiles; - ListOfFiles GetListOfFiles (const int theStudyId, - const char* theComponentName); - - void SetListOfFiles (const ListOfFiles theListOfFiles, - const int theStudyId, - const char* theComponentName); + ListOfFiles GetListOfFiles (const int theStudyId); + void SetListOfFiles (const ListOfFiles& theListOfFiles, + const int theStudyId); - static SalomeApp_Engine_i* GetInstance(); + static std::string EngineIORForComponent( const char* theComponentName, + bool toCreate ); + static SalomeApp_Engine_i* GetInstance ( const char* theComponentName, + bool toCreate ); public: // methods from SALOMEDS::Driver without implementation. Must be redefined because @@ -73,7 +80,7 @@ public: SALOMEDS::TMPFile* SaveASCII( SALOMEDS::SComponent_ptr, const char*, bool ) {return 0;} CORBA::Boolean LoadASCII( SALOMEDS::SComponent_ptr, const SALOMEDS::TMPFile&, const char*, bool ) {return 0;} void Close( SALOMEDS::SComponent_ptr ) {} - char* ComponentDataType() {return 0;} + char* ComponentDataType(); char* IORToLocalPersistentID( SALOMEDS::SObject_ptr, const char*, CORBA::Boolean, CORBA::Boolean ) {return 0;} char* LocalPersistentIDToIOR( SALOMEDS::SObject_ptr, const char*, CORBA::Boolean, CORBA::Boolean ) {return 0;} bool CanPublishInStudy( CORBA::Object_ptr ) {return 0;} @@ -84,11 +91,17 @@ public: SALOMEDS::SObject_ptr PasteInto( const SALOMEDS::TMPFile&, CORBA::Long, SALOMEDS::SObject_ptr ) {return 0;} private: - typedef std::map MapOfListOfFiles; - typedef std::map MapOfMapOfListOfFiles; - MapOfMapOfListOfFiles myMap; + static CORBA::ORB_var orb(); + static PortableServer::POA_var poa(); + static SALOME_NamingService* namingService(); + static CORBA::Object_ptr engineForComponent( const char* theComponentName, + bool toCreate ); + +private: + typedef std::map MapOfListOfFiles; + MapOfListOfFiles myMap; - static SalomeApp_Engine_i* myInstance; + std::string myComponentName; }; #endif diff --git a/src/Session/Session_ServerLauncher.cxx b/src/Session/Session_ServerLauncher.cxx index df8422f8f..71a8503aa 100755 --- a/src/Session/Session_ServerLauncher.cxx +++ b/src/Session/Session_ServerLauncher.cxx @@ -127,6 +127,17 @@ void Session_ServerLauncher::CheckArgs() } case 1: // looking for server type { + // Temporary solution + // Issue 21337 - no more SalomeApp_Engine_i activation here + // TODO: To be removed as soon as any trace of SalomeAppEngine + // has been eliminated from KERNEL scripts + if (strcmp(_argv[iarg], "SalomeAppEngine")==0){ + argState = 0; + iarg += 2; // skipping "()" + break; + } + // Temporary solution + for (int i=0; i #include "Session_Session_i.hxx" -#include "SalomeApp_Engine_i.hxx" #include #include @@ -56,13 +55,12 @@ using namespace std; -const int Session_ServerThread::NB_SRV_TYP = 7; +const int Session_ServerThread::NB_SRV_TYP = 6; const char* Session_ServerThread::_serverTypes[NB_SRV_TYP] = {"Container", "ModuleCatalog", "Registry", "SALOMEDS", "Session", - "SalomeAppEngine", "ContainerManager"}; /*! @@ -158,13 +156,7 @@ void Session_ServerThread::Init() ActivateSession(_argc, _argv); break; } - case 5: // SalomeApp_Engine - { - NamingService_WaitForServerReadiness(_NS,"/myStudyManager"); - ActivateEngine(_argc, _argv); - break; - } - case 6: // Container Manager + case 5: // Container Manager { NamingService_WaitForServerReadiness(_NS,""); ActivateContainerManager(_argc, _argv); @@ -390,29 +382,6 @@ void Session_ServerThread::ActivateContainer(int argc, } } -void Session_ServerThread::ActivateEngine(int /*argc*/, char ** /*argv*/) -{ - try { - MESSAGE("SalomeApp_Engine thread started"); - SalomeApp_Engine_i* anEngine = new SalomeApp_Engine_i(); - PortableServer::ObjectId_var id =_root_poa->activate_object( anEngine ); - MESSAGE("poa->activate_object( SalomeApp_Engine )"); - - CORBA::Object_var obj = anEngine->_this(); - anEngine->_remove_ref(); - _NS->Register( obj ,"/SalomeAppEngine"); - } - catch (CORBA::SystemException&) { - INFOS("Caught CORBA::SystemException."); - } - catch (CORBA::Exception&) { - INFOS("Caught CORBA::Exception."); - } - catch (...) { - INFOS("Caught unknown exception."); - } -} - void Session_ServerThread::ActivateSession(int argc, char ** argv) { -- 2.39.2