1 // Copyright (C) 2010-2015 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Adrien Bruneton (CEA)
23 #include "PVGUI_DataModel.h"
24 #include "PVGUI_Module.h"
27 #include <LightApp_Study.h>
28 #include <LightApp_Module.h>
29 #include <LightApp_Application.h>
30 #include <LightApp_DataModel.h>
31 #include <CAM_DataObject.h>
32 #include <SUIT_Tools.h>
33 #include <SUIT_Session.h>
34 #include <SUIT_ResourceMgr.h>
37 #include <utilities.h>
42 #include <QTextStream>
46 #include <pqApplicationCore.h>
48 #include <pqFixPathsInStateFilesBehavior.h>
50 const QString PVGUI_DataModel::RESTORE_FLAG_FILE = "do_restore_paravis_references.par";
53 * XML processing functions to handle the PV state file.
57 void processElements(QDomNode& thePropertyNode, QStringList& theFileNames,
58 const QString& theNewPath, bool theRestore)
60 QDomNode aElementNode = thePropertyNode.firstChild();
61 while (aElementNode.isElement()) {
62 QDomElement aElement = aElementNode.toElement();
63 if (aElement.tagName() == "Element") {
64 QString aIndex = aElement.attribute("index");
66 QString aValue = aElement.attribute("value");
67 if (!aValue.isNull()) {
68 if (theNewPath.isEmpty()) {
69 QFileInfo aFInfo(aValue);
70 if (aFInfo.exists()) {
72 aElement.setAttribute("value", aFInfo.fileName());
77 aElement.setAttribute("value", QString(theNewPath) + aValue);
82 aElementNode = aElementNode.nextSibling();
86 void processProperties(QDomNode& theProxyNode, QStringList& theFileNames,
87 const QString& theNewPath, bool theRestore)
89 QDomNode aPropertyNode = theProxyNode.firstChild();
90 while (aPropertyNode.isElement()) {
91 QDomElement aProperty = aPropertyNode.toElement();
92 QString aName = aProperty.attribute("name");
93 if ((aName == "FileName") || (aName == "FileNameInfo") || (aName == "FileNames")) {
94 processElements(aPropertyNode, theFileNames, theNewPath, theRestore);
96 aPropertyNode = aPropertyNode.nextSibling();
101 void processProxies(QDomNode& theNode, QStringList& theFileNames,
102 const QString& theNewPath, bool theRestore)
104 QDomNode aProxyNode = theNode.firstChild();
105 while (aProxyNode.isElement()) {
106 QDomElement aProxy = aProxyNode.toElement();
107 if (aProxy.tagName() == "Proxy") {
108 QString aGroup = aProxy.attribute("group");
109 if (aGroup == "sources") {
110 processProperties(aProxyNode, theFileNames, theNewPath, theRestore);
113 aProxyNode = aProxyNode.nextSibling();
117 bool processAllFilesInState(const QString& aFileName, QStringList& theFileNames,
118 const QString& theNewPath, bool theRestore)
120 QFile aFile(aFileName);
121 if (!aFile.open(QFile::ReadOnly)) {
122 MESSAGE("Can't open state file "<<aFileName.toStdString());
126 bool aRes = aDoc.setContent(&aFile);
130 MESSAGE("File "<<aFileName.toStdString()<<" is not XML document");
134 QDomElement aRoot = aDoc.documentElement();
135 if ( aRoot.isNull() ) {
136 MESSAGE( "Invalid XML root" );
140 QDomNode aNode = aRoot.firstChild();
141 while (aRes && !aNode.isNull() ) {
142 aRes = aNode.isElement();
144 QDomElement aSection = aNode.toElement();
145 if (aSection.tagName() == "ServerManagerState") {
146 processProxies(aNode, theFileNames, theNewPath, theRestore);
149 aNode = aNode.nextSibling();
151 if (!aFile.open(QFile::WriteOnly | QFile::Truncate)) {
152 MESSAGE("Can't open state file "<<aFileName.toStdString()<<" for writing");
155 QTextStream out(&aFile);
164 PVGUI_DataModel::PVGUI_DataModel( PVGUI_Module* theModule ):
165 LightApp_DataModel(theModule),
169 PVGUI_DataModel::~PVGUI_DataModel()
172 bool PVGUI_DataModel::create( CAM_Study* theStudy) {
173 bool res = LightApp_DataModel::create(theStudy);
174 publishComponent(theStudy);
178 void PVGUI_DataModel::publishComponent( CAM_Study* theStudy ) {
179 LightApp_Study* study = dynamic_cast<LightApp_Study*>( theStudy );
180 CAM_ModuleObject *aModelRoot = dynamic_cast<CAM_ModuleObject*>( root());
181 if( study && aModelRoot == NULL ) {
182 aModelRoot = createModuleObject( theStudy->root() );
183 aModelRoot->setDataModel( this );
188 bool PVGUI_DataModel::dumpPython( const QString& path, CAM_Study* std,
189 bool isMultiFile, QStringList& listOfFiles)
192 LightApp_Study* study = dynamic_cast<LightApp_Study*>( std );
196 std::string aTmpDir = study->GetTmpDir( path.toLatin1().constData(), isMultiFile );
197 std::string aFile = aTmpDir + "paravis_dump.tmp";
199 listOfFiles.append(aTmpDir.c_str());
200 listOfFiles.append("paravis_dump.tmp");
202 QFile file(aFile.c_str());
203 if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
206 PVGUI_Module * mod = (PVGUI_Module *) getModule();
207 QString trace(mod->getTraceString());
212 abuffer.push_back(QString("def RebuildData( theStudy ):"));
213 QStringList lst(trace.split("\n"));
214 foreach(QString elem, lst)
216 QString s = " " + elem;
217 abuffer.push_back(s);
219 abuffer.push_back(QString(" pass"));
220 trace = abuffer.join("\n");
222 QTextStream out(&file);
223 out << trace.toStdString().c_str() << "\n";
231 \brief Open data model (read ParaView pipeline state from the files).
232 \param theName study file path
233 \param theStudy study pointer
234 \param theList list of the (temporary) files with data
235 \return operation status (\c true on success and \c false on error)
237 bool PVGUI_DataModel::open( const QString& theName, CAM_Study* theStudy, QStringList theList)
240 LightApp_Study* aDoc = dynamic_cast<LightApp_Study*>( theStudy );
244 LightApp_DataModel::open( theName, aDoc, theList );
245 publishComponent(theStudy);
247 // The first list item contains path to a temporary
248 // directory, where the persistent files was placed
249 if ( theList.count() > 0 ) {
250 QString aTmpDir ( theList[0] );
252 if ( theList.size() >= 2 ) {
253 myStudyURL = theName;
254 QString aFullPath = SUIT_Tools::addSlash( aTmpDir ) + theList[1];
255 // std::cout << "open: tmp dir is" << aFullPath.toStdString() << std::endl;
256 PVGUI_Module * mod = dynamic_cast<PVGUI_Module *>(getModule());
259 bool doRestore = false;
260 QStringList srcFilesEmpty;
261 createAndCheckRestoreFlag(aTmpDir, srcFilesEmpty, /*out*/doRestore);
264 // Update state file so that it points to new dir:
265 processAllFilesInState(aFullPath, srcFilesEmpty, aTmpDir.toStdString().c_str(), true);
268 pqFixPathsInStateFilesBehavior::blockDialog(true);
269 mod->loadParaviewState(aFullPath);
270 pqFixPathsInStateFilesBehavior::blockDialog(false);
281 * Create an empty file indicating whether source files in the pipeline should be restored.
283 bool PVGUI_DataModel::createAndCheckRestoreFlag(const QString& tmpdir, QStringList& listOfFiles, bool & alreadyThere)
285 QString aFullPath = SUIT_Tools::addSlash( tmpdir ) + RESTORE_FLAG_FILE;
294 bool ret = f.open(QFile::WriteOnly);
298 listOfFiles << RESTORE_FLAG_FILE;
306 \brief Save data model (write ParaView pipeline to the files).
307 \param listOfFiles returning list of the (temporary) files with saved data
308 \return operation status (\c true on success and \c false on error)
310 bool PVGUI_DataModel::save( QStringList& theListOfFiles)
312 bool isMultiFile = false; // TODO: decide, how to access this parameter
315 LightApp_DataModel::save( theListOfFiles );
317 LightApp_Study* study = dynamic_cast<LightApp_Study*>( getModule()->getApp()->activeStudy() );
318 QString aTmpDir = study->GetTmpDir( myStudyURL.toLatin1(), isMultiFile ).c_str();
319 // std::cout << "save: tmp dir is" << aTmpDir.toStdString() << std::endl;
321 QString aFileName = SUIT_Tools::file( myStudyURL, false ) + "_PARAVIS.pvsm";
322 QString aFullPath = aTmpDir + aFileName;
324 PVGUI_Module * mod = dynamic_cast<PVGUI_Module *>(getModule());
325 QStringList srcFiles;
328 // Create ParaView state file:
329 mod->saveParaviewState(aFullPath.toStdString().c_str());
331 // add this to the list to be saved:
332 theListOfFiles << aTmpDir;
333 theListOfFiles << aFileName;
335 // Potentially save referenced files:
336 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
337 int aSavingType = aResourceMgr->integerValue( "PARAVIS", "savestate_type", 0 );
340 bool isBuiltIn = false;
344 switch (aSavingType) {
345 case 0: // Save referenced files when they are accessible
346 createAndCheckRestoreFlag(aTmpDir, theListOfFiles ,unused);
347 processAllFilesInState(aFullPath, srcFiles, nullS, false);
349 case 1: // Save referenced files only if this is the builtin server
350 aServer = pqApplicationCore::instance()->getActiveServer();
352 isBuiltIn != aServer->isRemote();
355 createAndCheckRestoreFlag(aTmpDir, theListOfFiles, unused);
356 processAllFilesInState(aFullPath, srcFiles, nullS, false);
359 case 2: // Do not save referenced file
367 // Copying valid source files to the temp directory and adding them to the list
368 foreach(QString fName, srcFiles)
374 QString newPth(SUIT_Tools::addSlash( aTmpDir ) + inf.fileName());
375 if (fSrc.copy(newPth))
377 theListOfFiles << inf.fileName();
386 \brief Save data model (write ParaView pipeline state to the files).
387 \param url study file path
388 \param study study pointer
389 \param listOfFiles returning list of the (temporary) files with saved data
390 \return operation status (\c true on success and \c false on error)
392 bool PVGUI_DataModel::saveAs( const QString& url, CAM_Study* study, QStringList& theListOfFiles)
395 return save( theListOfFiles );