1 // Copyright (C) 2010-2016 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>
49 const QString PVGUI_DataModel::RESTORE_FLAG_FILE = "do_restore_paravis_references.par";
52 * XML processing functions to handle the PV state file.
56 void processElements(QDomNode& thePropertyNode, QStringList& theFileNames,
57 const QString& theNewPath, bool theRestore)
59 QDomNode aElementNode = thePropertyNode.firstChild();
60 while (aElementNode.isElement()) {
61 QDomElement aElement = aElementNode.toElement();
62 if (aElement.tagName() == "Element") {
63 QString aIndex = aElement.attribute("index");
65 QString aValue = aElement.attribute("value");
66 if (!aValue.isNull()) {
67 if (theNewPath.isEmpty()) {
68 QFileInfo aFInfo(aValue);
69 if (aFInfo.exists()) {
71 aElement.setAttribute("value", aFInfo.fileName());
76 aElement.setAttribute("value", QString(theNewPath) + aValue);
81 aElementNode = aElementNode.nextSibling();
85 void processProperties(QDomNode& theProxyNode, QStringList& theFileNames,
86 const QString& theNewPath, bool theRestore)
88 QDomNode aPropertyNode = theProxyNode.firstChild();
89 while (aPropertyNode.isElement()) {
90 QDomElement aProperty = aPropertyNode.toElement();
91 QString aName = aProperty.attribute("name");
92 if ((aName == "FileName") || (aName == "FileNameInfo") || (aName == "FileNames")) {
93 processElements(aPropertyNode, theFileNames, theNewPath, theRestore);
95 aPropertyNode = aPropertyNode.nextSibling();
100 void processProxies(QDomNode& theNode, QStringList& theFileNames,
101 const QString& theNewPath, bool theRestore)
103 QDomNode aProxyNode = theNode.firstChild();
104 while (aProxyNode.isElement()) {
105 QDomElement aProxy = aProxyNode.toElement();
106 if (aProxy.tagName() == "Proxy") {
107 QString aGroup = aProxy.attribute("group");
108 if (aGroup == "sources") {
109 processProperties(aProxyNode, theFileNames, theNewPath, theRestore);
112 aProxyNode = aProxyNode.nextSibling();
116 bool processAllFilesInState(const QString& aFileName, QStringList& theFileNames,
117 const QString& theNewPath, bool theRestore)
119 QFile aFile(aFileName);
120 if (!aFile.open(QFile::ReadOnly)) {
121 MESSAGE("Can't open state file "<<aFileName.toStdString());
125 bool aRes = aDoc.setContent(&aFile);
129 MESSAGE("File "<<aFileName.toStdString()<<" is not XML document");
133 QDomElement aRoot = aDoc.documentElement();
134 if ( aRoot.isNull() ) {
135 MESSAGE( "Invalid XML root" );
139 QDomNode aNode = aRoot.firstChild();
140 while (aRes && !aNode.isNull() ) {
141 aRes = aNode.isElement();
143 QDomElement aSection = aNode.toElement();
144 if (aSection.tagName() == "ServerManagerState") {
145 processProxies(aNode, theFileNames, theNewPath, theRestore);
148 aNode = aNode.nextSibling();
150 if (!aFile.open(QFile::WriteOnly | QFile::Truncate)) {
151 MESSAGE("Can't open state file "<<aFileName.toStdString()<<" for writing");
154 QTextStream out(&aFile);
163 PVGUI_DataModel::PVGUI_DataModel( PVGUI_Module* theModule ):
164 LightApp_DataModel(theModule),
168 PVGUI_DataModel::~PVGUI_DataModel()
171 bool PVGUI_DataModel::create( CAM_Study* theStudy) {
172 bool res = LightApp_DataModel::create(theStudy);
173 publishComponent(theStudy);
177 void PVGUI_DataModel::publishComponent( CAM_Study* theStudy ) {
178 LightApp_Study* study = dynamic_cast<LightApp_Study*>( theStudy );
179 CAM_ModuleObject *aModelRoot = dynamic_cast<CAM_ModuleObject*>( root());
180 if( study && aModelRoot == NULL ) {
181 aModelRoot = createModuleObject( theStudy->root() );
182 aModelRoot->setDataModel( this );
187 bool PVGUI_DataModel::dumpPython( const QString& path, CAM_Study* std,
188 bool isMultiFile, QStringList& listOfFiles)
191 LightApp_Study* study = dynamic_cast<LightApp_Study*>( std );
195 std::string aTmpDir = study->GetTmpDir( path.toLatin1().constData(), isMultiFile );
196 std::string aFile = aTmpDir + "paravis_dump.tmp";
198 listOfFiles.append(aTmpDir.c_str());
199 listOfFiles.append("paravis_dump.tmp");
201 QFile file(aFile.c_str());
202 if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
205 PVGUI_Module * mod = (PVGUI_Module *) getModule();
206 QString trace(mod->getTraceString());
211 abuffer.push_back(QString("def RebuildData():"));
212 QStringList lst(trace.split("\n"));
213 foreach(QString elem, lst)
215 QString s = " " + elem;
216 abuffer.push_back(s);
218 abuffer.push_back(QString(" pass"));
219 trace = abuffer.join("\n");
221 QTextStream out(&file);
222 out << trace.toStdString().c_str() << "\n";
230 \brief Open data model (read ParaView pipeline state from the files).
231 \param theName study file path
232 \param theStudy study pointer
233 \param theList list of the (temporary) files with data
234 \return operation status (\c true on success and \c false on error)
236 bool PVGUI_DataModel::open( const QString& theName, CAM_Study* theStudy, QStringList theList)
239 LightApp_Study* aDoc = dynamic_cast<LightApp_Study*>( theStudy );
243 LightApp_DataModel::open( theName, aDoc, theList );
244 publishComponent(theStudy);
246 // The first list item contains path to a temporary
247 // directory, where the persistent files was placed
248 if ( theList.count() > 0 ) {
249 QString aTmpDir ( theList[0] );
251 if ( theList.size() >= 2 ) {
252 myStudyURL = theName;
253 QString aFullPath = SUIT_Tools::addSlash( aTmpDir ) + theList[1];
254 // std::cout << "open: tmp dir is" << aFullPath.toStdString() << std::endl;
255 PVGUI_Module * mod = dynamic_cast<PVGUI_Module *>(getModule());
258 bool doRestore = false;
259 QStringList srcFilesEmpty;
260 createAndCheckRestoreFlag(aTmpDir, srcFilesEmpty, /*out*/doRestore);
263 // Update state file so that it points to new dir:
264 processAllFilesInState(aFullPath, srcFilesEmpty, aTmpDir.toStdString().c_str(), true);
267 mod->loadParaviewState(aFullPath);
278 * Create an empty file indicating whether source files in the pipeline should be restored.
280 bool PVGUI_DataModel::createAndCheckRestoreFlag(const QString& tmpdir, QStringList& listOfFiles, bool & alreadyThere)
282 QString aFullPath = SUIT_Tools::addSlash( tmpdir ) + RESTORE_FLAG_FILE;
291 bool ret = f.open(QFile::WriteOnly);
295 listOfFiles << RESTORE_FLAG_FILE;
303 \brief Save data model (write ParaView pipeline to the files).
304 \param listOfFiles returning list of the (temporary) files with saved data
305 \return operation status (\c true on success and \c false on error)
307 bool PVGUI_DataModel::save( QStringList& theListOfFiles)
309 bool isMultiFile = false; // TODO: decide, how to access this parameter
312 LightApp_DataModel::save( theListOfFiles );
314 LightApp_Study* study = dynamic_cast<LightApp_Study*>( getModule()->getApp()->activeStudy() );
315 QString aTmpDir = study->GetTmpDir( myStudyURL.toLatin1(), isMultiFile ).c_str();
316 // std::cout << "save: tmp dir is" << aTmpDir.toStdString() << std::endl;
318 QString aFileName = SUIT_Tools::file( myStudyURL, false ) + "_PARAVIS.pvsm";
319 QString aFullPath = aTmpDir + aFileName;
321 PVGUI_Module * mod = dynamic_cast<PVGUI_Module *>(getModule());
322 QStringList srcFiles;
325 // Create ParaView state file:
326 mod->saveParaviewState(aFullPath.toStdString().c_str());
328 // add this to the list to be saved:
329 theListOfFiles << aTmpDir;
330 theListOfFiles << aFileName;
332 // Potentially save referenced files:
333 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
334 int aSavingType = aResourceMgr->integerValue( "PARAVIS", "savestate_type", 0 );
337 bool isBuiltIn = false;
341 switch (aSavingType) {
342 case 0: // Save referenced files when they are accessible
343 createAndCheckRestoreFlag(aTmpDir, theListOfFiles ,unused);
344 processAllFilesInState(aFullPath, srcFiles, nullS, false);
346 case 1: // Save referenced files only if this is the builtin server
347 aServer = pqApplicationCore::instance()->getActiveServer();
349 isBuiltIn = !aServer->isRemote();
352 createAndCheckRestoreFlag(aTmpDir, theListOfFiles, unused);
353 processAllFilesInState(aFullPath, srcFiles, nullS, false);
356 case 2: // Do not save referenced file
364 // Copying valid source files to the temp directory and adding them to the list
365 foreach(QString fName, srcFiles)
371 QString newPth(SUIT_Tools::addSlash( aTmpDir ) + inf.fileName());
372 if (fSrc.copy(newPth))
374 theListOfFiles << inf.fileName();
383 \brief Save data model (write ParaView pipeline state to the files).
384 \param url study file path
385 \param study study pointer
386 \param listOfFiles returning list of the (temporary) files with saved data
387 \return operation status (\c true on success and \c false on error)
389 bool PVGUI_DataModel::saveAs( const QString& url, CAM_Study* study, QStringList& theListOfFiles)
392 return save( theListOfFiles );