From 462bc16aceb130bcc72361239ae5bc30fa0fcb9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Fri, 12 Apr 2013 08:31:59 +0200 Subject: [PATCH] Rewrite of the searchpath system for external file references The Relocation code is not yet completely working for the advanced cases p4#: 21251 --- ApplicationCode/ProjectDataModel/RimCase.cpp | 128 ++++++++++++++++++ ApplicationCode/ProjectDataModel/RimCase.h | 5 +- .../ProjectDataModel/RimInputCase.cpp | 29 +--- .../ProjectDataModel/RimInputCase.h | 2 +- .../ProjectDataModel/RimProject.cpp | 13 +- .../ProjectDataModel/RimResultCase.cpp | 39 +----- .../ProjectDataModel/RimResultCase.h | 2 +- 7 files changed, 153 insertions(+), 65 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimCase.cpp b/ApplicationCode/ProjectDataModel/RimCase.cpp index a65675f6a5..5c5f99bbc5 100644 --- a/ApplicationCode/ProjectDataModel/RimCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimCase.cpp @@ -351,3 +351,131 @@ RimReservoirCellResultsStorage* RimCase::results(RifReaderInterface::PorosityMod return m_fractureModelResults(); } + + +//-------------------------------------------------------------------------------------------------- +/// Relocate the supplied file name, based on the search path as follows: +/// fileName, newProjectPath/fileNameWoPath, relocatedPath/fileNameWoPath +/// If the file is not found in any of the positions, the fileName is returned unchanged +/// +/// The relocatedPath is found in this way: +/// use the start of newProjectPath +/// plus the end of the path to m_gridFileName +/// such that the common start of oldProjectPath and m_gridFileName is removed from m_gridFileName +/// and replaced with the start of newProjectPath up to where newProjectPath starts to be equal to oldProjectPath +//-------------------------------------------------------------------------------------------------- +QString RimCase::relocateFile(const QString& fileName, const QString& newProjectPath, const QString& oldProjectPath, + bool* foundFile, std::vector* searchedPaths) +{ + if (foundFile) *foundFile = true; + + if (searchedPaths) searchedPaths->push_back(fileName); + if (QFile::exists(fileName)) + { + return fileName; + } + + // First check in the new project file directory + { + QString fileNameWithoutPath = QFileInfo(fileName).fileName(); + QString candidate = QDir::fromNativeSeparators(newProjectPath + QDir::separator() + fileNameWithoutPath); + if (searchedPaths) searchedPaths->push_back(candidate); + + if (QFile::exists(candidate)) + { + return candidate; + } + } + + QFileInfo gridFileInfo(fileName); + QFileInfo oldProjPathInfo(oldProjectPath); + QFileInfo newProjPathInfo(newProjectPath); + + QString gridFilePath = gridFileInfo.canonicalPath(); + QStringList gridPathElements = gridFilePath.split("/", QString::KeepEmptyParts); + QString oldProjPath = oldProjPathInfo.canonicalPath(); + QStringList oldProjPathElements = oldProjPath.split("/", QString::KeepEmptyParts); + QString newProjPath = newProjPathInfo.canonicalPath(); + QStringList newProjPathElements = newProjPath.split("/", QString::KeepEmptyParts); + + bool pathStartsAreEqual = false; + bool pathEndsDiffer = false; + int firstDiffIdx = 0; + for ( firstDiffIdx = 0; firstDiffIdx < gridPathElements.size() && firstDiffIdx < oldProjPathElements.size(); ++firstDiffIdx) + { + if (gridPathElements[firstDiffIdx] == oldProjPathElements[firstDiffIdx]) + { + pathStartsAreEqual = pathStartsAreEqual || !gridPathElements[firstDiffIdx].isEmpty(); + } + else + { + pathEndsDiffer = true; + break; + } + } + + if (!pathEndsDiffer && firstDiffIdx < gridPathElements.size() || firstDiffIdx < oldProjPathElements.size()) + { + pathEndsDiffer = true; + } + + if (pathStartsAreEqual) + { + if (pathEndsDiffer) + { + QString oldGridFilePathEnd; + for (int i = firstDiffIdx; i < gridPathElements.size(); ++i) + { + oldGridFilePathEnd += gridPathElements[i]; + oldGridFilePathEnd += "/"; + } + + // Find the new Project File Start Path + + QStringList oldProjectFilePathEndElements; + for (int i = firstDiffIdx; i < oldProjPathElements.size(); ++i) + { + oldProjectFilePathEndElements.push_back(oldProjPathElements[i]); + } + + int ppIdx = oldProjectFilePathEndElements.size() -1; + int lastDiffIdx = newProjPathElements.size() -1; + + for (; lastDiffIdx >= 0 && ppIdx >= 0; --lastDiffIdx, --ppIdx) + { + if (oldProjectFilePathEndElements[ppIdx] != newProjPathElements[lastDiffIdx]) + { + break; + } + } + + QString newProjecetFileStartPath; + for (int i = 0; i <= lastDiffIdx; ++i) + { + newProjecetFileStartPath += newProjPathElements[i]; + newProjecetFileStartPath += "/"; + } + + QString relocationPath = newProjecetFileStartPath + oldGridFilePathEnd; + + QString relocatedFileName = relocationPath + gridFileInfo.fileName(); + + if (searchedPaths) searchedPaths->push_back(relocatedFileName); + + if (QFile::exists(relocatedFileName)) + { + return relocatedFileName; + } + } + else + { + // The Grid file was located in the same dir as the Project file. This is supposed to be handled above. + CVF_ASSERT(false); + } + } + + // return the unchanged filename, if we could not find a valid relocation file + if (foundFile) *foundFile = false; + + return fileName; +} diff --git a/ApplicationCode/ProjectDataModel/RimCase.h b/ApplicationCode/ProjectDataModel/RimCase.h index bb913e6393..aa2fa9bd1f 100644 --- a/ApplicationCode/ProjectDataModel/RimCase.h +++ b/ApplicationCode/ProjectDataModel/RimCase.h @@ -68,7 +68,7 @@ public: virtual QString locationOnDisc() const { return QString(); } virtual QString gridFileName() const { return QString(); } - virtual void updateFilePathsFromProjectPath(const QString& projectPath) { }; + virtual void updateFilePathsFromProjectPath(const QString& projectPath, const QString& oldProjectPath) { }; RimCaseCollection* parentCaseCollection(); RimIdenticalGridCaseGroup* parentGridCaseGroup(); @@ -85,7 +85,8 @@ protected: protected: void computeCachedData(); void setReservoirData(RigCaseData* eclipseCase); - + static QString relocateFile(const QString& fileName, const QString& newProjectPath, const QString& oldProjectPath, + bool* foundFile, std::vector* searchedPaths); private: cvf::ref m_rigEclipseCase; diff --git a/ApplicationCode/ProjectDataModel/RimInputCase.cpp b/ApplicationCode/ProjectDataModel/RimInputCase.cpp index d3825f5e01..b81c30d8ae 100644 --- a/ApplicationCode/ProjectDataModel/RimInputCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimInputCase.cpp @@ -423,37 +423,18 @@ QString RimInputCase::locationOnDisc() const return fi.absolutePath(); } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimInputCase::updateFilePathsFromProjectPath(const QString& projectPath) +void RimInputCase::updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) { - QString candidate; + bool foundFile = false; + std::vector searchedPaths; - if (!QFile::exists(m_gridFileName)) - { - QString fileNameWithoutPath = QFileInfo(m_gridFileName).fileName(); - candidate = QDir::fromNativeSeparators(projectPath + QDir::separator() + fileNameWithoutPath); - if (QFile::exists(candidate)) - { - m_gridFileName = candidate; - } - } + m_gridFileName = relocateFile(m_gridFileName(), newProjectPath, oldProjectPath, &foundFile, &searchedPaths); for (size_t i = 0; i < m_additionalFileNames().size(); i++) { - QString additionalFileName = m_additionalFileNames()[i]; - - if (!QFile::exists(additionalFileName)) - { - QString fileNameWithoutPath = QFileInfo(additionalFileName).fileName(); - candidate = QDir::fromNativeSeparators(projectPath + QDir::separator() + fileNameWithoutPath); - if (QFile::exists(candidate)) - { - m_additionalFileNames.v()[i] = candidate; - } - } + m_additionalFileNames.v()[i] = relocateFile(m_additionalFileNames()[i], newProjectPath, oldProjectPath, &foundFile, &searchedPaths); } - } diff --git a/ApplicationCode/ProjectDataModel/RimInputCase.h b/ApplicationCode/ProjectDataModel/RimInputCase.h index dd74303efb..1766fc9f3d 100644 --- a/ApplicationCode/ProjectDataModel/RimInputCase.h +++ b/ApplicationCode/ProjectDataModel/RimInputCase.h @@ -63,7 +63,7 @@ public: virtual QString locationOnDisc() const; virtual QString gridFileName() const { return m_gridFileName();} - virtual void updateFilePathsFromProjectPath(const QString& projectPath); + virtual void updateFilePathsFromProjectPath(const QString& projectPath, const QString& oldProjectPath); private: void addFiles(const QStringList& newFileNames); diff --git a/ApplicationCode/ProjectDataModel/RimProject.cpp b/ApplicationCode/ProjectDataModel/RimProject.cpp index 452c468b51..166e05c4d3 100644 --- a/ApplicationCode/ProjectDataModel/RimProject.cpp +++ b/ApplicationCode/ProjectDataModel/RimProject.cpp @@ -236,16 +236,23 @@ void RimProject::insertCaseInCaseGroup(RimIdenticalGridCaseGroup* caseGroup, Rim //-------------------------------------------------------------------------------------------------- void RimProject::setProjectFileNameAndUpdateDependencies(const QString& fileName) { + // Extract the filename of the project file when it was saved + QString oldProjectFileName = this->fileName; + // Replace with the new actual filename this->fileName = fileName; // Loop over all reservoirs and update file path QFileInfo fileInfo(fileName); - QString projectPath = fileInfo.path(); + QString newProjectPath = fileInfo.path(); + + QFileInfo fileInfoOld(oldProjectFileName); + QString oldProjectPath = fileInfoOld.path(); + for (size_t i = 0; i < reservoirs.size(); i++) { - reservoirs[i]->updateFilePathsFromProjectPath(projectPath); + reservoirs[i]->updateFilePathsFromProjectPath(newProjectPath, oldProjectPath); } // Case groups : Loop over all reservoirs in and update file path @@ -256,7 +263,7 @@ void RimProject::setProjectFileNameAndUpdateDependencies(const QString& fileName for (size_t j = 0; j < cg->caseCollection()->reservoirs().size(); j++) { - cg->caseCollection()->reservoirs()[j]->updateFilePathsFromProjectPath(projectPath); + cg->caseCollection()->reservoirs()[j]->updateFilePathsFromProjectPath(newProjectPath, oldProjectPath); } } } diff --git a/ApplicationCode/ProjectDataModel/RimResultCase.cpp b/ApplicationCode/ProjectDataModel/RimResultCase.cpp index bf23b21470..7cbd9fe12d 100644 --- a/ApplicationCode/ProjectDataModel/RimResultCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultCase.cpp @@ -265,43 +265,14 @@ void RimResultCase::readGridDimensions(std::vector< std::vector >& gridDime //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimResultCase::updateFilePathsFromProjectPath(const QString& projectPath) +void RimResultCase::updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) { + bool foundFile = false; + std::vector searchedPaths; + // Update filename and folder paths when opening project from a different file location - if (!QFile::exists(caseFileName())) - { - QFileInfo gridFileInfo(caseFileName()); - QString gridFileBaseName = gridFileInfo.completeBaseName(); - QString candidate; + caseFileName = relocateFile(caseFileName(), newProjectPath, oldProjectPath, &foundFile, &searchedPaths); - candidate = QDir::fromNativeSeparators(locationOnDisc() + QDir::separator() + gridFileBaseName + ".EGRID"); - if (QFile::exists(candidate)) - { - caseFileName = candidate; - return; - } - - candidate = QDir::fromNativeSeparators(locationOnDisc() + QDir::separator() + gridFileBaseName + ".GRID"); - if (QFile::exists(candidate)) - { - caseFileName = candidate; - return; - } - - candidate = QDir::fromNativeSeparators(projectPath + QDir::separator() + gridFileBaseName + ".EGRID"); - if (QFile::exists(candidate)) - { - caseFileName = candidate; - return; - } - - candidate = QDir::fromNativeSeparators(projectPath + QDir::separator() + gridFileBaseName + ".GRID"); - if (QFile::exists(candidate)) - { - caseFileName = candidate; - return; - } - } } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimResultCase.h b/ApplicationCode/ProjectDataModel/RimResultCase.h index b8123fa996..b85dbde04e 100644 --- a/ApplicationCode/ProjectDataModel/RimResultCase.h +++ b/ApplicationCode/ProjectDataModel/RimResultCase.h @@ -49,7 +49,7 @@ public: // Overrides from RimCase virtual QString locationOnDisc() const; virtual QString gridFileName() const { return caseFileName();} - virtual void updateFilePathsFromProjectPath(const QString& projectPath); + virtual void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath); private: cvf::ref createMockModel(QString modelName);