Salome HOME
0023191: [CEA 1607] REGRESSION : the file hdf does not save the data PARAVIS
authorabn <adrien.bruneton@cea.fr>
Mon, 19 Oct 2015 12:25:23 +0000 (14:25 +0200)
committervsr <vsr@opencascade.com>
Tue, 10 Nov 2015 15:01:25 +0000 (18:01 +0300)
src/PVGUI/PVGUI_DataModel.cxx
src/PVGUI/PVGUI_DataModel.h
src/PVGUI/PVGUI_Module.cxx
src/PVGUI/PVGUI_Module.h
src/PVGUI/resources/PARAVIS_msg_en.ts
src/PVGUI/resources/PARAVIS_msg_fr.ts
src/PVGUI/resources/PARAVIS_msg_ja.ts

index 6c563e8d3425f3bd2fd60fe6a96e72a1c2e46297..7917899be849bacb2a38f148a10b8a57d2cf992f 100644 (file)
 
 // GUI includes
 #include <LightApp_Study.h>
+#include <LightApp_Module.h>
+#include <LightApp_Application.h>
+#include <LightApp_DataModel.h>
 #include <CAM_DataObject.h>
+#include <SUIT_Tools.h>
+#include <SUIT_Session.h>
+#include <SUIT_ResourceMgr.h>
+
+// KERNEL
+#include <utilities.h>
 
 // Qt includes
 #include <QFile>
+#include <QFileInfo>
 #include <QTextStream>
+#include <QDomNode>
+
+// ParaView include
+#include <pqApplicationCore.h>
+#include <pqServer.h>
+#include <pqFixPathsInStateFilesBehavior.h>
+
+const QString PVGUI_DataModel::RESTORE_FLAG_FILE = "do_restore_paravis_references.par";
+
+/*!
+ * XML processing functions to handle the PV state file.
+ */
+namespace {
+
+  void processElements(QDomNode& thePropertyNode, QStringList& theFileNames,
+                       const QString& theNewPath, bool theRestore)
+  {
+    QDomNode aElementNode = thePropertyNode.firstChild();
+    while (aElementNode.isElement()) {
+      QDomElement aElement = aElementNode.toElement();
+      if (aElement.tagName() == "Element") {
+        QString aIndex = aElement.attribute("index");
+        if (aIndex == "0") {
+          QString aValue = aElement.attribute("value");
+          if (!aValue.isNull()) {
+            if (theNewPath.isEmpty()) {
+              QFileInfo aFInfo(aValue);
+              if (aFInfo.exists()) {
+                theFileNames<<aValue;
+                aElement.setAttribute("value", aFInfo.fileName());
+              }
+              break;
+            } else {
+              if (theRestore)
+                aElement.setAttribute("value", QString(theNewPath) + aValue);
+            }
+          }
+        }
+      }
+      aElementNode = aElementNode.nextSibling();
+    }
+  }
+
+  void processProperties(QDomNode& theProxyNode, QStringList& theFileNames,
+                         const QString& theNewPath, bool theRestore)
+  {
+    QDomNode aPropertyNode = theProxyNode.firstChild();
+    while (aPropertyNode.isElement()) {
+      QDomElement aProperty = aPropertyNode.toElement();
+      QString aName = aProperty.attribute("name");
+      if ((aName == "FileName") || (aName == "FileNameInfo") || (aName == "FileNames")) {
+        processElements(aPropertyNode, theFileNames, theNewPath, theRestore);
+      }
+      aPropertyNode = aPropertyNode.nextSibling();
+    }
+  }
+
+
+  void processProxies(QDomNode& theNode, QStringList& theFileNames,
+                      const QString& theNewPath, bool theRestore)
+  {
+    QDomNode aProxyNode = theNode.firstChild();
+    while (aProxyNode.isElement()) {
+      QDomElement aProxy = aProxyNode.toElement();
+      if (aProxy.tagName() == "Proxy") {
+        QString aGroup = aProxy.attribute("group");
+        if (aGroup == "sources") {
+          processProperties(aProxyNode, theFileNames, theNewPath, theRestore);
+        }
+      }
+      aProxyNode = aProxyNode.nextSibling();
+    }
+  }
+
+  bool processAllFilesInState(const QString& aFileName, QStringList& theFileNames,
+                              const QString& theNewPath, bool theRestore)
+  {
+    QFile aFile(aFileName);
+    if (!aFile.open(QFile::ReadOnly)) {
+      MESSAGE("Can't open state file "<<aFileName.toStdString());
+      return false;
+    }
+    QDomDocument aDoc;
+    bool aRes = aDoc.setContent(&aFile);
+    aFile.close();
+
+    if (!aRes) {
+      MESSAGE("File "<<aFileName.toStdString()<<" is not XML document");
+      return false;
+    }
+
+    QDomElement aRoot = aDoc.documentElement();
+    if ( aRoot.isNull() ) {
+      MESSAGE( "Invalid XML root" );
+      return false;
+    }
+
+    QDomNode aNode = aRoot.firstChild();
+    while (aRes  && !aNode.isNull() ) {
+      aRes = aNode.isElement();
+      if ( aRes ) {
+        QDomElement aSection = aNode.toElement();
+        if (aSection.tagName() == "ServerManagerState") {
+          processProxies(aNode, theFileNames, theNewPath, theRestore);
+        }
+      }
+      aNode = aNode.nextSibling();
+    }
+    if (!aFile.open(QFile::WriteOnly | QFile::Truncate)) {
+      MESSAGE("Can't open state file "<<aFileName.toStdString()<<" for writing");
+      return false;
+    }
+    QTextStream out(&aFile);
+    aDoc.save(out, 2);
+    aFile.close();
+
+    return true;
+  }
+}
+
 
 PVGUI_DataModel::PVGUI_DataModel( PVGUI_Module* theModule ):
-  LightApp_DataModel(theModule)
+  LightApp_DataModel(theModule),
+  myStudyURL("")
 {}
 
 PVGUI_DataModel::~PVGUI_DataModel()
 {}
 
+bool PVGUI_DataModel::create( CAM_Study* theStudy) {
+  bool res = LightApp_DataModel::create(theStudy);
+  publishComponent(theStudy);
+  return res;
+}
+
+void PVGUI_DataModel::publishComponent( CAM_Study* theStudy ) {
+  LightApp_Study* study = dynamic_cast<LightApp_Study*>( theStudy );
+  CAM_ModuleObject *aModelRoot = dynamic_cast<CAM_ModuleObject*>( root());
+  if( study && aModelRoot == NULL ) {
+    aModelRoot = createModuleObject( theStudy->root() );
+    aModelRoot->setDataModel( this );
+    setRoot(aModelRoot);
+  }
+}
+
 bool PVGUI_DataModel::dumpPython( const QString& path, CAM_Study* std,
             bool isMultiFile, QStringList& listOfFiles)
 {
@@ -80,26 +227,170 @@ bool PVGUI_DataModel::dumpPython( const QString& path, CAM_Study* std,
   return true;
 }
 
-/*-----------------------------------------------------------------------------------------*/
-bool PVGUI_DataModel::open( const QString& theName, CAM_Study* theStudy, QStringList theList) {
-  bool res = LightApp_DataModel::open(theName, theStudy, theList);
+/*!
+  \brief Open data model (read ParaView pipeline state from the files).
+  \param theName study file path
+  \param theStudy study pointer
+  \param theList list of the (temporary) files with data
+  \return operation status (\c true on success and \c false on error)
+*/
+bool PVGUI_DataModel::open( const QString& theName, CAM_Study* theStudy, QStringList theList)
+{
+  bool ret = false;
+  LightApp_Study* aDoc = dynamic_cast<LightApp_Study*>( theStudy );
+  if ( !aDoc )
+    return false;
+
+  LightApp_DataModel::open( theName, aDoc, theList );
   publishComponent(theStudy);
-  return res;
+
+  // The first list item contains path to a temporary
+  // directory, where the persistent files was placed
+  if ( theList.count() > 0 ) {
+    QString aTmpDir ( theList[0] );
+
+    if ( theList.size() >= 2 ) {
+      myStudyURL = theName;
+      QString aFullPath = SUIT_Tools::addSlash( aTmpDir ) + theList[1];
+//      std::cout << "open: tmp dir is" << aFullPath.toStdString() << std::endl;
+      PVGUI_Module * mod = dynamic_cast<PVGUI_Module *>(getModule());
+      if (mod)
+        {
+          bool doRestore = false;
+          QStringList srcFilesEmpty;
+          createAndCheckRestoreFlag(aTmpDir, srcFilesEmpty, /*out*/doRestore);
+          if(doRestore)
+            {
+              // Update state file so that it points to new dir:
+              processAllFilesInState(aFullPath, srcFilesEmpty, aTmpDir.toStdString().c_str(), true);
+            }
+
+          pqFixPathsInStateFilesBehavior::blockDialog(true);
+          mod->loadParaviewState(aFullPath);
+          pqFixPathsInStateFilesBehavior::blockDialog(false);
+          ret = true;
+        }
+      ret = true;
+    }
+  }
+
+  return ret;
 }
 
-/*-----------------------------------------------------------------------------------------*/
-bool PVGUI_DataModel::create( CAM_Study* theStudy) {
-  bool res = LightApp_DataModel::create(theStudy);
-  publishComponent(theStudy);
-  return res;
+/*!
+ * Create an empty file indicating whether source files in the pipeline should be restored.
+ */
+bool PVGUI_DataModel::createAndCheckRestoreFlag(const QString& tmpdir, QStringList& listOfFiles, bool & alreadyThere)
+{
+  QString aFullPath = SUIT_Tools::addSlash( tmpdir ) + RESTORE_FLAG_FILE;
+  QFile f(aFullPath);
+  if (f.exists())
+    {
+    alreadyThere = true;
+    return true;
+    }
+  else
+    {
+      bool ret = f.open(QFile::WriteOnly);
+      if (ret)
+        {
+        f.close();
+        listOfFiles << RESTORE_FLAG_FILE;
+        }
+      return ret;
+    }
 }
-/*-----------------------------------------------------------------------------------------*/
-void PVGUI_DataModel::publishComponent( CAM_Study* theStudy ) {
-  LightApp_Study* study = dynamic_cast<LightApp_Study*>( theStudy );
-  CAM_ModuleObject *aModelRoot = dynamic_cast<CAM_ModuleObject*>( root());
-  if( study && aModelRoot == NULL ) {
-    aModelRoot = createModuleObject( theStudy->root() );
-    aModelRoot->setDataModel( this );
-    setRoot(aModelRoot);
+
+
+/*!
+  \brief Save data model (write ParaView pipeline to the files).
+  \param listOfFiles returning list of the (temporary) files with saved data
+  \return operation status (\c true on success and \c false on error)
+*/
+bool PVGUI_DataModel::save( QStringList& theListOfFiles)
+{
+  bool isMultiFile = false; // TODO: decide, how to access this parameter
+  bool ret = false;
+
+  LightApp_DataModel::save( theListOfFiles );
+
+  LightApp_Study* study = dynamic_cast<LightApp_Study*>( getModule()->getApp()->activeStudy() );
+  QString aTmpDir = study->GetTmpDir( myStudyURL.toLatin1(), isMultiFile ).c_str();
+//  std::cout << "save: tmp dir is" << aTmpDir.toStdString() << std::endl;
+
+  QString aFileName = SUIT_Tools::file( myStudyURL, false ) + "_PARAVIS.pvsm";
+  QString aFullPath = aTmpDir + aFileName;
+
+  PVGUI_Module * mod = dynamic_cast<PVGUI_Module *>(getModule());
+  QStringList srcFiles;
+  if (mod)
+    {
+      // Create ParaView state file:
+      mod->saveParaviewState(aFullPath.toStdString().c_str());
+
+      // add this to the list to be saved:
+      theListOfFiles << aTmpDir;
+      theListOfFiles << aFileName;
+
+      // Potentially save referenced files:
+      SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
+      int aSavingType = aResourceMgr->integerValue( "PARAVIS", "savestate_type", 0 );
+
+      bool unused;
+      bool isBuiltIn = false;
+      pqServer* aServer;
+      QString nullS;
+
+      switch (aSavingType) {
+        case 0: // Save referenced files when they are accessible
+          createAndCheckRestoreFlag(aTmpDir, theListOfFiles ,unused);
+          processAllFilesInState(aFullPath, srcFiles, nullS, false);
+          break;
+        case 1: // Save referenced files only if this is the builtin server
+          aServer = pqApplicationCore::instance()->getActiveServer();
+          if (aServer)
+            isBuiltIn != aServer->isRemote();
+          if(isBuiltIn)
+            {
+              createAndCheckRestoreFlag(aTmpDir, theListOfFiles, unused);
+              processAllFilesInState(aFullPath, srcFiles, nullS, false);
+            }
+          break;
+        case 2: // Do not save referenced file
+          break;
+        default:
+          break;
+      }
+
+      ret = true;
+    }
+  // Copying valid source files to the temp directory and adding them to the list
+  foreach(QString fName, srcFiles)
+  {
+    QFile fSrc(fName);
+    if (fSrc.exists())
+      {
+        QFileInfo inf(fSrc);
+        QString newPth(SUIT_Tools::addSlash( aTmpDir ) + inf.fileName());
+        if (fSrc.copy(newPth))
+          {
+            theListOfFiles << inf.fileName();
+          }
+      }
   }
+
+  return ret;
+}
+
+/*!
+  \brief Save data model (write ParaView pipeline state to the files).
+  \param url study file path
+  \param study study pointer
+  \param listOfFiles returning list of the (temporary) files with saved data
+  \return operation status (\c true on success and \c false on error)
+*/
+bool PVGUI_DataModel::saveAs( const QString& url, CAM_Study* study, QStringList& theListOfFiles)
+{
+  myStudyURL = url;
+  return save( theListOfFiles );
 }
index 755e0e28075416b3cc8218d730f610bbb1772452..16220c6211891bfc4d88239bd97aec077f4627bb 100644 (file)
@@ -41,10 +41,18 @@ public:
 
   virtual bool dumpPython( const QString&,  CAM_Study*, bool, QStringList& );
   virtual bool open( const QString&, CAM_Study*, QStringList );
+  virtual bool save( QStringList& );
+  virtual bool saveAs( const QString&, CAM_Study*, QStringList& );
   virtual bool create( CAM_Study* );
 
 private:
   void publishComponent(CAM_Study*);
+
+  bool createAndCheckRestoreFlag(const QString& tmpdir, QStringList& listOfFiles, bool & alreadyThere);
+
+  QString              myStudyURL;
+
+  static const QString RESTORE_FLAG_FILE;
 };
 
 #endif /* PVGUIDATAMODEL_H_ */
index 247f4b69637da5492a189856c5b6cd04cc9f7bfc..b11dc1864b885a9e748d14463220cd7370154d80 100644 (file)
@@ -837,9 +837,9 @@ void PVGUI_Module::saveTrace( const char* theName )
 /*!
   \brief Saves ParaView state to a disk file
 */
-void PVGUI_Module::saveParaviewState( const char* theFileName )
+void PVGUI_Module::saveParaviewState( const QString& theFileName )
 {
-  pqApplicationCore::instance()->saveState( theFileName );
+  pqApplicationCore::instance()->saveState( theFileName.toStdString().c_str() );
 }
 
 /*!
@@ -856,9 +856,9 @@ void PVGUI_Module::clearParaviewState()
 /*!
   \brief Restores ParaView state from a disk file
 */
-void PVGUI_Module::loadParaviewState( const char* theFileName )
+void PVGUI_Module::loadParaviewState( const QString& theFileName )
 {
-  pqApplicationCore::instance()->loadState( theFileName, getActiveServer() );
+  pqApplicationCore::instance()->loadState( theFileName.toStdString().c_str(), getActiveServer() );
 }
 
 /*!
@@ -893,7 +893,6 @@ void PVGUI_Module::createPreferences()
   addPreference( tr( "PREF_NO_EXT_PVSERVER" ), aParaVisSettingsTab, 
                  LightApp_Preferences::Bool, PARAVIS_MODULE_NAME, "no_ext_pv_server" );
 
-  /* VSR: not used
   int aSaveType = addPreference( tr( "PREF_SAVE_TYPE_LBL" ), aParaVisSettingsTab,
                                  LightApp_Preferences::Selector,
                                  PARAVIS_MODULE_NAME, "savestate_type" );
@@ -904,7 +903,6 @@ void PVGUI_Module::createPreferences()
   aStrings << tr("PREF_SAVE_TYPE_0") << tr("PREF_SAVE_TYPE_1") << tr("PREF_SAVE_TYPE_2");
   setPreferenceProperty( aSaveType, "strings", aStrings );
   setPreferenceProperty( aSaveType, "indexes", aIndices );
-  */
 
   // ... "Language" group <<start>>
   int traceGroup = addPreference( tr( "PREF_GROUP_TRACE" ), aParaVisSettingsTab );
index 3cac7f89d896273252166f2bb1524a6baf6fc0fa..929293b21d9fbef60e167ec61c924f2e06d4d66c 100644 (file)
@@ -122,8 +122,9 @@ public:
 
   void openFile( const char* );                   // not used inside PARAVIS
   void executeScript( const char* );              // not used inside PARAVIS
-  void saveParaviewState( const char* );          // not used inside PARAVIS
-  void loadParaviewState( const char* );          // not used inside PARAVIS
+
+  void saveParaviewState( const QString& );
+  void loadParaviewState( const QString& );
   void clearParaviewState();
 
   QString getTraceString();
index fd6d323c2b96fe1b7b0e44d02b4cdecb131c9a67..55e4ba6a69c5fe6a96f1f184dd19f29264f72dab 100644 (file)
     </message>
     <message>
         <source>PREF_SAVE_TYPE_0</source>
-        <translation>Save referenced files only for builtin server</translation>
+        <translation>Always save referenced files when they are accessible</translation>
     </message>
     <message>
         <source>PREF_SAVE_TYPE_1</source>
-        <translation>Always save referenced files when they are accessible</translation>
+        <translation>Save referenced files only for builtin server</translation>
     </message>
     <message>
         <source>PREF_SAVE_TYPE_2</source>
index 7f149ccba55070a3b5679868ffeae24dd2b1f5f6..7b1430167edf961d10c39a037159fd232081bfbb 100644 (file)
     </message>
     <message>
         <source>PREF_SAVE_TYPE_0</source>
-        <translation>N&apos;enregistrer les fichiers de référence qu&apos;au serveur de babillard</translation>
+        <translation>Toujours enregistrer les fichiers de référence s&apos;ils sont accessibles</translation>
     </message>
     <message>
         <source>PREF_SAVE_TYPE_1</source>
-        <translation>Toujours enregistrer les fichiers de référence s&apos;ils sont accessibles</translation>
+        <translation>N&apos;enregistrer les fichiers de référence que pour le serveur builtin</translation>
     </message>
     <message>
         <source>PREF_SAVE_TYPE_2</source>
index 5dde22f1dcd28787cd95020e963fba5f191031ec..34f554ce2f998ad1104a4386a6fd88b13cffd21d 100644 (file)
     </message>
     <message>
       <source>PREF_SAVE_TYPE_0</source>
-      <translation>掲示板サーバーだけに参照ファイルを保存します。</translation>
+      <translation>アクセス可能な場合は常に参照のファイルを保存します。</translation>
     </message>
     <message>
       <source>PREF_SAVE_TYPE_1</source>
-      <translation>アクセス可能な場合は常に参照のファイルを保存します。</translation>
-    </message>
+      <translation>掲示板サーバーだけに参照ファイルを保存します。</translation>
+    </message>    
     <message>
       <source>PREF_SAVE_TYPE_2</source>
       <translation>参照ファイルを保存します。</translation>