///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2011- Statoil ASA // Copyright (C) 2013- Ceetron Solutions AS // Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. // // See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RimTools.h" #include "RimCase.h" #include "RimColorLegend.h" #include "RimColorLegendCollection.h" #include "RimEclipseCase.h" #include "RimGeoMechCase.h" #include "RimOilField.h" #include "RimProject.h" #include "RimWellLogFile.h" #include "RimWellPath.h" #include "RimWellPathCollection.h" #include "cafPdmUiItem.h" #include "cafUtils.h" #include #include #include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RimTools::getCacheRootDirectoryPathFromProject() { if ( !RimProject::current() ) { return QString(); } QString projectFileName = RimProject::current()->fileName(); QString cacheRootFolderPath; QFileInfo fileInfo( projectFileName ); cacheRootFolderPath = fileInfo.canonicalPath(); cacheRootFolderPath += "/" + fileInfo.completeBaseName(); return cacheRootFolderPath; } //-------------------------------------------------------------------------------------------------- /// 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 but converted to Qt Style path /// separators: "/" /// /// 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 RimTools::relocateFile( const QString& originalFileName, const QString& currentProjectPath, const QString& previousProjectPath, bool* foundFile, std::vector* searchedPaths ) { if ( foundFile ) *foundFile = true; // Make sure we have a Qt formatted path ( using "/" not "\") QString fileName = QDir::fromNativeSeparators( originalFileName ); QString newProjectPath = QDir::fromNativeSeparators( currentProjectPath ); QString oldProjectPath = QDir::fromNativeSeparators( previousProjectPath ); // If we from a file or whatever gets a real windows path on linux, we need to manually convert it // because Qt will not. QDir::fromNativeSeparators does nothing on linux. bool isWindowsPath = false; if ( originalFileName.count( "/" ) ) isWindowsPath = false; // "/" are not allowed in a windows path else if ( originalFileName.count( "\\" ) && !caf::Utils::fileExists( originalFileName ) ) // To make sure we do not // convert single linux // files containing "\" { isWindowsPath = true; } if ( isWindowsPath ) { // Windows absolute path detected. transform. fileName.replace( QString( "\\" ), QString( "/" ) ); } if ( searchedPaths ) searchedPaths->push_back( fileName ); if ( caf::Utils::fileExists( 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 ( caf::Utils::fileExists( candidate ) ) { return candidate; } } // Then find the possible move of a directory structure where projects and files referenced are moved in "paralell" QFileInfo fileNameFileInfo( QDir::fromNativeSeparators( fileName ) ); QString fileNamePath = fileNameFileInfo.path(); QString fileNameWithoutPath = fileNameFileInfo.fileName(); QStringList fileNamePathElements = fileNamePath.split( "/", QString::KeepEmptyParts ); QString oldProjPath = QDir::fromNativeSeparators( oldProjectPath ); QStringList oldProjPathElements = oldProjPath.split( "/", QString::KeepEmptyParts ); QString newProjPath = QDir::fromNativeSeparators( newProjectPath ); QStringList newProjPathElements = newProjPath.split( "/", QString::KeepEmptyParts ); // Find the possible equal start of the old project path, and the referenced file bool pathStartsAreEqual = false; bool pathEndsDiffer = false; int firstDiffIdx = 0; for ( firstDiffIdx = 0; firstDiffIdx < fileNamePathElements.size() && firstDiffIdx < oldProjPathElements.size(); ++firstDiffIdx ) { #ifdef WIN32 // When comparing parts of a file path, the drive letter has been seen to be a mix of // upper and lower cases. Always use case insensitive compare on Windows, as this is a valid approach // for all parts for a file path Qt::CaseSensitivity cs = Qt::CaseInsensitive; #else Qt::CaseSensitivity cs = Qt::CaseSensitive; #endif if ( fileNamePathElements[firstDiffIdx].compare( oldProjPathElements[firstDiffIdx], cs ) == 0 ) { pathStartsAreEqual = pathStartsAreEqual || !fileNamePathElements[firstDiffIdx].isEmpty(); } else { pathEndsDiffer = true; break; } } if ( !pathEndsDiffer && firstDiffIdx < fileNamePathElements.size() || firstDiffIdx < oldProjPathElements.size() ) { pathEndsDiffer = true; } // If the path starts are equal, try to substitute it in the referenced file, with the corresponding new project // path start if ( pathStartsAreEqual ) { if ( pathEndsDiffer ) { QString oldFileNamePathEnd; for ( int i = firstDiffIdx; i < fileNamePathElements.size(); ++i ) { oldFileNamePathEnd += fileNamePathElements[i]; oldFileNamePathEnd += "/"; } // Find the new Project File Start Path QStringList oldProjectFilePathEndElements; for ( int i = firstDiffIdx; i < oldProjPathElements.size(); ++i ) { oldProjectFilePathEndElements.push_back( oldProjPathElements[i] ); } int lastProjectDiffIdx = newProjPathElements.size() - 1; { int ppIdx = oldProjectFilePathEndElements.size() - 1; for ( ; lastProjectDiffIdx >= 0 && ppIdx >= 0; --lastProjectDiffIdx, --ppIdx ) { if ( oldProjectFilePathEndElements[ppIdx] != newProjPathElements[lastProjectDiffIdx] ) { break; } } } QString newProjectFileStartPath; for ( int i = 0; i <= lastProjectDiffIdx; ++i ) { newProjectFileStartPath += newProjPathElements[i]; newProjectFileStartPath += "/"; } QString relocationPath = newProjectFileStartPath + oldFileNamePathEnd; QString relocatedFileName = relocationPath + fileNameWithoutPath; if ( searchedPaths ) searchedPaths->push_back( relocatedFileName ); if ( caf::Utils::fileExists( relocatedFileName ) ) { return relocatedFileName; } } else { // The Grid file was located in the same dir as the Project file. This is supposed to be handled above. // So we did not find it } } // return the unchanged filename, if we could not find a valid relocation file if ( foundFile ) *foundFile = false; return fileName; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::wellPathOptionItems( QList* options ) { CVF_ASSERT( options ); if ( !options ) return; auto wellPathColl = RimTools::wellPathCollection(); if ( wellPathColl ) { caf::IconProvider wellIcon( ":/Well.svg" ); for ( auto wellPath : wellPathColl->allWellPaths() ) { options->push_back( caf::PdmOptionItemInfo( wellPath->name(), wellPath, false, wellIcon ) ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::wellPathWithFormationsOptionItems( QList* options ) { CVF_ASSERT( options ); if ( !options ) return; std::vector wellPaths; RimTools::wellPathWithFormations( &wellPaths ); caf::IconProvider wellIcon( ":/Well.svg" ); for ( auto wellPath : wellPaths ) { options->push_back( caf::PdmOptionItemInfo( wellPath->name(), wellPath, false, wellIcon ) ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::wellPathWithFormations( std::vector* wellPaths ) { auto wellPathColl = RimTools::wellPathCollection(); if ( wellPathColl ) { for ( RimWellPath* wellPath : wellPathColl->allWellPaths() ) { if ( wellPath->hasFormations() ) { wellPaths->push_back( wellPath ); } } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::caseOptionItems( QList* options ) { CVF_ASSERT( options ); if ( !options ) return; RimProject* proj = RimProject::current(); if ( proj ) { std::vector cases; proj->allCases( cases ); for ( RimCase* c : cases ) { options->push_back( caf::PdmOptionItemInfo( c->caseUserDescription(), c, false, c->uiIconProvider() ) ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::eclipseCaseOptionItems( QList* options ) { CVF_ASSERT( options ); if ( !options ) return; RimProject* proj = RimProject::current(); if ( proj ) { std::vector cases; proj->allCases( cases ); for ( RimCase* c : cases ) { RimEclipseCase* eclipseCase = dynamic_cast( c ); if ( eclipseCase ) { options->push_back( caf::PdmOptionItemInfo( c->caseUserDescription(), c, false, c->uiIconProvider() ) ); } } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::geoMechCaseOptionItems( QList* options ) { CVF_ASSERT( options ); if ( !options ) return; RimProject* proj = RimProject::current(); if ( proj ) { std::vector cases; proj->allCases( cases ); for ( RimCase* c : cases ) { RimGeoMechCase* geoMechCase = dynamic_cast( c ); if ( geoMechCase ) { options->push_back( caf::PdmOptionItemInfo( c->caseUserDescription(), c, false, c->uiIconProvider() ) ); } } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::colorLegendOptionItems( QList* options ) { CVF_ASSERT( options ); if ( !options ) return; RimProject* project = RimProject::current(); RimColorLegendCollection* colorLegendCollection = project->colorLegendCollection(); std::vector colorLegends = colorLegendCollection->allColorLegends(); for ( RimColorLegend* colorLegend : colorLegends ) { options->push_back( caf::PdmOptionItemInfo( colorLegend->colorLegendName(), colorLegend, false, colorLegend->paletteIconProvider() ) ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimWellPathCollection* RimTools::wellPathCollection() { RimProject* proj = RimProject::current(); if ( proj && proj->activeOilField() ) { return proj->activeOilField()->wellPathCollection(); } return nullptr; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::timeStepsForCase( RimCase* gridCase, QList* options ) { QStringList timeStepNames; if ( gridCase ) { timeStepNames = gridCase->timeStepStrings(); } for ( int i = 0; i < timeStepNames.size(); i++ ) { options->push_back( caf::PdmOptionItemInfo( timeStepNames[i], i ) ); } }