]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Merge from BR_PPGP_Dev (GENEPY+ dev) 21/11/2011
authorvsr <vsr@opencascade.com>
Mon, 21 Nov 2011 13:59:22 +0000 (13:59 +0000)
committervsr <vsr@opencascade.com>
Mon, 21 Nov 2011 13:59:22 +0000 (13:59 +0000)
27 files changed:
src/LightApp/LightApp_Application.cxx
src/LightApp/LightApp_DataModel.cxx
src/LightApp/LightApp_DataModel.h
src/LightApp/LightApp_DataObject.cxx
src/LightApp/LightApp_DataObject.h
src/LightApp/resources/LightApp.xml
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.cxx
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataModelLight.h
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataObjectLight.cxx
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_DataObjectLight.h
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.cxx
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.h
src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx
src/SALOME_PYQT/SalomePyQt/SalomePyQt.h
src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip
src/STD/STD_Application.cxx
src/STD/STD_TabDesktop.cxx
src/SalomeApp/SalomeApp_Application.cxx
src/SalomeApp/SalomeApp_Application.h
src/SalomeApp/SalomeApp_DataObject.cxx
src/SalomeApp/SalomeApp_DataObject.h
src/SalomeApp/SalomeApp_Study.cxx
src/SalomeApp/SalomeApp_Study.h
src/Session/SalomeApp_Engine_i.cxx
src/Session/SalomeApp_Engine_i.hxx
src/Session/Session_ServerLauncher.cxx
src/Session/Session_ServerThread.cxx

index 05894985e0703ae66e0f6070d38c718f3919aa0a..bf2a0e81a3517c7c2d5e167440b6eadb2d1e115c 100644 (file)
@@ -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 );
index 0c8c40888a77a0f02dacb05644dbcdb389d4898a..8c967590567c8dfa10bfc31e43734416595f55d9 100644 (file)
@@ -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()
 */
index 994cbecaaf414b4d17cde861ca99585c9644e7f5..4da6d3675f72f42ca8c9fcbef3f3de9baba28f05 100644 (file)
@@ -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 );
 
index 6dd9f06dcea2a48f55527140d6efbdc643dae4e6..90e0a64f16fb34b2dff2ac2b187064b879c0556f 100644 (file)
@@ -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;
 }
 
 /*!
index 6af26dcc81799a3f1889885be35632d663b62eb6..ac7ac8c57480ae4327488163f3e1fae9398d8522 100644 (file)
@@ -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;
index fa09126ea34b4b70a94cf90e3a6c4577329ba1ba..f78854f909925d25966f82fa0bb18d80104afbc4 100644 (file)
@@ -76,6 +76,7 @@
     <parameter name="SUPERVGraph"  value="${GUI_ROOT_DIR}/share/salome/resources/gui"/>
     <parameter name="QxGraph"      value="${GUI_ROOT_DIR}/share/salome/resources/gui"/>
     <parameter name="ToolsGUI"     value="${GUI_ROOT_DIR}/share/salome/resources/gui"/>
+    <parameter name="LogWindow"    value="${GUI_ROOT_DIR}/share/salome/resources/gui"/>
   </section>
   <section name="desktop" >
     <!-- Default GUI desktop state, position, size -->
index 17c8f531b355012e2331b34dbea59a35cc99e493..8370296139a285a605633fd37664ad9011a4a67c 100644 (file)
@@ -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<LightApp_Study*>( theStudy );
+  SALOME_PYQT_ModuleLight* aModule = dynamic_cast<SALOME_PYQT_ModuleLight*>(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
index 2a6c2f21d37138f6c3550d39419d2dc89e71169f..6a9e3539152b97939e719b432b96d6ff4ac0ee11 100644 (file)
@@ -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
index ecdfce0a76ac34edeac19c29622998f5aaf49a8c..4db8c6fb6161837c3b54888da698b3c2b09aa7b0 100644 (file)
@@ -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;
+}
index 80d5a2ae0df906444ec651e332fdae3cb60632fd..08b59fc9714970a70a94426336f6a3aa1a44aac1 100644 (file)
@@ -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
index a28601bafd959d2a1a6c57de1683e3b866cde697..512e2bfec6abf20f2a4bb2013c516092193a3188 100644 (file)
@@ -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
  */
index 6917f3a1df26dd4cc1eb7721654aab64cdb0d54b..cf07211b3346840d9dc9a50c513f0ba28f7e710e 100644 (file)
@@ -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);
index 3429ec9b80261d13e1854f1497e2872df0adcaf4..632f4713d6e0496cc6168b2b6ec42b49ef4fdbda 100644 (file)
@@ -32,6 +32,7 @@
 #endif
 
 #include <SALOME_PYQT_ModuleLight.h> // this include must be first!!!
+#include <SALOME_PYQT_DataModelLight.h>
 #include "SalomePyQt.h"
 
 #include <QApplication>
@@ -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<SALOME_PYQT_DataModelLight*>( 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<SALOME_PYQT_DataModelLight*>( module->dataModel() );
+      LightApp_Application* aLApp = 
+       dynamic_cast<LightApp_Application*>( 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)
index 5114bb0244f85fd134b0ec9d89d04061dd3fe0d9..2fd65b871e14e267f73c2efb3e2803329023b9fa 100644 (file)
@@ -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& );
index 9b7c7b1f5a9c9f70f212a8696c43151125a1350f..7c2090b6fbb717032e2a60ee357b2487cd183548 100644 (file)
@@ -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/ ;
index 3172bbe01d8eaf70c0d718b41b76896984ef7ed7..f3c75a91f098fe5181bdb96ffb9486d4e9a0435f 100755 (executable)
@@ -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 );
index 3c410ebd20ce965fb89228ea51b5cba81d29ae28..780359e029ac9dd943f63dc53f32238e76bc3122 100644 (file)
@@ -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 )
index fcac1c19d2650852d927d196f9e1723834e8c987..151d84d319bd90a89b67d4acc3df440a5b405c68 100644 (file)
@@ -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<SalomeApp_DataObject*>( theObj );
-  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( activeStudy() );
+  // Issue 21379: References are supported at LightApp_DataObject level
+  LightApp_DataObject* obj = dynamic_cast<LightApp_DataObject*>( 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 );
index aab013d665543e5503506b084de96e048fa40d0f..711333875937697df5e72ed0fff7aa2640e07c56 100644 (file)
@@ -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* );
index 86fb9f13c886fc2440099a6d34841c2fef95d66d..481d3fc2bbb697f1645ea0c2766c4f00673b5175 100644 (file)
@@ -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
index dc4f2898424357b7197982299662ba2f88913d1e..f9b2b7446ed15d6d8ff5d87fbaf70ae10b23253b 100644 (file)
@@ -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;
 
index c46ea3e69968635f528ff3e9008bdf509086f019..f16825432ad72fc9611aa711a86d04a1021d1982 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <QCoreApplication>
 #include <QEvent>
+#include <QFileInfo>
 #include "SALOME_Event.h"
 #include "Basics_Utils.hxx"
 
@@ -571,7 +572,10 @@ bool SalomeApp_Study::saveDocumentAs( const QString& theFileName )
   QListIterator<CAM_DataModel*> 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<LightApp_DataModel*>( it.next() ) ) {
       listOfFiles.clear();
       aModel->saveAs( theFileName, this, listOfFiles );
       if ( !listOfFiles.isEmpty() )
@@ -613,7 +617,10 @@ bool SalomeApp_Study::saveDocument()
   QListIterator<CAM_DataModel*> 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<LightApp_DataModel*>( 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<SalomeApp_Application*>( 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<CAM_DataModel*> it( list );
+  QStringList listOfFiles;
+  while ( it.hasNext() ) {
+    if ( LightApp_DataModel* aModel = 
+        dynamic_cast<LightApp_DataModel*>( 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<CAM_DataModel*> it( list );
   std::vector<std::string> 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<LightApp_DataModel*>( 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<SalomeApp_DataModel*>( 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<std::string> 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<std::string> 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<std::string> 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());
 }
 
 /*!
index 41ebe37153a84c957280209e8eab582ae0054028..2487cd5def1f746030d135a1d4270e6c37baf9b2 100644 (file)
@@ -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();
index 639d3e84f222306c1271936d2b367d5cfcc1fdc9..e43c936e97c2891ee97ebcfd75809cbb06afe260 100644 (file)
 //
 #include "SalomeApp_Engine_i.hxx"
 
-#include "SALOMEDS_Tool.hxx"
+#include <SALOME_NamingService.hxx>
+#include <SALOMEDS_Tool.hxx>
+#include <Utils_ORB_INIT.hxx>
+#include <Utils_SINGLETON.hxx>
+#include <Utils_SALOME_Exception.hxx>
+#include <utilities.h>
+
+#include <QApplication>
+#include <QDir>
+#include <QFile>
 
 #include <iostream>
 
 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<qint64> 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<qint64>::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<char*>( myComponentName.c_str() );
 }
+
+/*!
+  \return 
+*/
+CORBA::ORB_var SalomeApp_Engine_i::orb()
+{
+  ORB_INIT& init = *SINGLETON_<ORB_INIT>::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<SalomeApp_Engine_i*>( aServantBase );
+  } 
+  MESSAGE("SalomeApp_Engine_i::GetInstance(): theComponentName = " <<
+         theComponentName << ", aServant = " << aServant);
+  return aServant;
+}
+
index 965f46b9c6d5d390d843c0a36ca880692c463d0e..e9030cbb7bc57bbf6a1507ac6a9c37a84a473219 100755 (executable)
 #include <SALOMEconfig.h>
 #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<std::string> 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<std::string, ListOfFiles> MapOfListOfFiles;
-  typedef std::map<int, MapOfListOfFiles>    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<int, ListOfFiles> MapOfListOfFiles;
+  MapOfListOfFiles                   myMap;
 
-  static SalomeApp_Engine_i* myInstance;
+  std::string                        myComponentName;
 };
 
 #endif
index df8422f8f811af7208aec9cc78691673ecb656b7..71a8503aac2f7efcfe8f4e6bb8116a315910bdd0 100755 (executable)
@@ -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<Session_ServerThread::NB_SRV_TYP; i++)
                 if (strcmp(_argv[iarg],Session_ServerThread::_serverTypes[i])==0)
                   {
index ff3282e66927a1cdb62ebc449caaddfec05c6d8d..d158208480344dee71d10bcc398d7a5229bd4c16 100755 (executable)
@@ -39,7 +39,6 @@
 #include <RegistryService.hxx>
 
 #include "Session_Session_i.hxx"
-#include "SalomeApp_Engine_i.hxx"
 
 #include <Utils_ORB_INIT.hxx>
 #include <Utils_SINGLETON.hxx>
 
 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)
 {