mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Add name variable for path in project file
Add support for user defined variables in the path section of the project file
This commit is contained in:
@@ -190,6 +190,7 @@ list(
|
|||||||
ProjectDataModel/WellLog/CMakeLists_files.cmake
|
ProjectDataModel/WellLog/CMakeLists_files.cmake
|
||||||
ProjectDataModel/WellMeasurement/CMakeLists_files.cmake
|
ProjectDataModel/WellMeasurement/CMakeLists_files.cmake
|
||||||
ProjectDataModel/WellPath/CMakeLists_files.cmake
|
ProjectDataModel/WellPath/CMakeLists_files.cmake
|
||||||
|
ProjectDataModel/Tools/CMakeLists_files.cmake
|
||||||
ProjectDataModelCommands/CMakeLists_files.cmake
|
ProjectDataModelCommands/CMakeLists_files.cmake
|
||||||
ProjectDataModelCommands/CommandRouter/CMakeLists_files.cmake
|
ProjectDataModelCommands/CommandRouter/CMakeLists_files.cmake
|
||||||
GeoMech/GeoMechVisualization/CMakeLists_files.cmake
|
GeoMech/GeoMechVisualization/CMakeLists_files.cmake
|
||||||
|
@@ -138,6 +138,22 @@ QString RimCase::gridFileName() const
|
|||||||
return m_caseFileName().path();
|
return m_caseFileName().path();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RimCase::DisplayNameEnum RimCase::displayNameType() const
|
||||||
|
{
|
||||||
|
return m_displayNameOption();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RimCase::setDisplayNameType( RimCaseDisplayNameTools::DisplayName displayNameType )
|
||||||
|
{
|
||||||
|
m_displayNameOption = displayNameType;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@@ -63,6 +63,8 @@ public:
|
|||||||
void setGridFileName( const QString& fileName );
|
void setGridFileName( const QString& fileName );
|
||||||
QString gridFileName() const;
|
QString gridFileName() const;
|
||||||
|
|
||||||
|
DisplayNameEnum displayNameType() const;
|
||||||
|
void setDisplayNameType( RimCaseDisplayNameTools::DisplayName displayNameType );
|
||||||
void setCustomCaseName( const QString& caseName );
|
void setCustomCaseName( const QString& caseName );
|
||||||
void updateAutoShortName();
|
void updateAutoShortName();
|
||||||
void updateOptionSensitivity();
|
void updateOptionSensitivity();
|
||||||
|
@@ -93,6 +93,8 @@
|
|||||||
#include "RimWellPath.h"
|
#include "RimWellPath.h"
|
||||||
#include "RimWellPathCollection.h"
|
#include "RimWellPathCollection.h"
|
||||||
|
|
||||||
|
#include "Tools/RiaVariableMapper.h"
|
||||||
|
|
||||||
#ifdef USE_QTCHARTS
|
#ifdef USE_QTCHARTS
|
||||||
#include "RimEnsembleFractureStatisticsPlot.h"
|
#include "RimEnsembleFractureStatisticsPlot.h"
|
||||||
#include "RimEnsembleFractureStatisticsPlotCollection.h"
|
#include "RimEnsembleFractureStatisticsPlotCollection.h"
|
||||||
@@ -116,6 +118,7 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
CAF_PDM_SOURCE_INIT( RimProject, "ResInsightProject" );
|
CAF_PDM_SOURCE_INIT( RimProject, "ResInsightProject" );
|
||||||
@@ -277,6 +280,8 @@ void RimProject::close()
|
|||||||
|
|
||||||
fileName = "";
|
fileName = "";
|
||||||
|
|
||||||
|
m_globalPathList = "";
|
||||||
|
|
||||||
mainWindowCurrentModelIndexPaths = "";
|
mainWindowCurrentModelIndexPaths = "";
|
||||||
mainWindowTreeViewStates = "";
|
mainWindowTreeViewStates = "";
|
||||||
plotWindowCurrentModelIndexPaths = "";
|
plotWindowCurrentModelIndexPaths = "";
|
||||||
@@ -1519,155 +1524,12 @@ void RimProject::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, Q
|
|||||||
uiTreeOrdering.skipRemainingChildren( true );
|
uiTreeOrdering.skipRemainingChildren( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PATHIDCHAR "$"
|
|
||||||
|
|
||||||
class GlobalPathListMapper
|
|
||||||
{
|
|
||||||
const QString pathIdBaseString = "PathId_";
|
|
||||||
|
|
||||||
public:
|
|
||||||
GlobalPathListMapper( const QString& globalPathListTable )
|
|
||||||
{
|
|
||||||
m_maxUsedIdNumber = 0;
|
|
||||||
QStringList pathPairs = RiaTextStringTools::splitSkipEmptyParts( globalPathListTable, ";" );
|
|
||||||
|
|
||||||
for ( const QString& pathIdPathPair : pathPairs )
|
|
||||||
{
|
|
||||||
QStringList pathIdPathComponents = pathIdPathPair.trimmed().split( PATHIDCHAR );
|
|
||||||
|
|
||||||
if ( pathIdPathComponents.size() == 3 && pathIdPathComponents[0].size() == 0 )
|
|
||||||
{
|
|
||||||
QString pathIdCore = pathIdPathComponents[1];
|
|
||||||
QString pathId = PATHIDCHAR + pathIdCore + PATHIDCHAR;
|
|
||||||
QString path = pathIdPathComponents[2].trimmed();
|
|
||||||
|
|
||||||
// Check if we have a standard id, and store the max number
|
|
||||||
|
|
||||||
if ( pathIdCore.startsWith( pathIdBaseString ) )
|
|
||||||
{
|
|
||||||
bool isOk = false;
|
|
||||||
QString numberText = pathIdCore.right( pathIdCore.size() - pathIdBaseString.size() );
|
|
||||||
size_t idNumber = numberText.toUInt( &isOk );
|
|
||||||
|
|
||||||
if ( isOk )
|
|
||||||
{
|
|
||||||
m_maxUsedIdNumber = std::max( m_maxUsedIdNumber, idNumber );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for unique pathId
|
|
||||||
{
|
|
||||||
auto pathIdPathPairIt = m_oldPathIdToPathMap.find( pathId );
|
|
||||||
|
|
||||||
if ( pathIdPathPairIt != m_oldPathIdToPathMap.end() )
|
|
||||||
{
|
|
||||||
// Error: pathID is already used
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for multiple identical paths
|
|
||||||
{
|
|
||||||
auto pathPathIdPairIt = m_oldPathToPathIdMap.find( path );
|
|
||||||
|
|
||||||
if ( pathPathIdPairIt != m_oldPathToPathIdMap.end() )
|
|
||||||
{
|
|
||||||
// Warning: path has already been assigned a pathId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_oldPathIdToPathMap[pathId] = path;
|
|
||||||
m_oldPathToPathIdMap[path] = pathId;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Error: The text is ill formatted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString addPathAndGetId( const QString& path )
|
|
||||||
{
|
|
||||||
// Want to re-use ids from last save to avoid unnecessary changes and make the behavior predictable
|
|
||||||
QString pathId;
|
|
||||||
QString trimmedPath = path.trimmed();
|
|
||||||
|
|
||||||
auto pathToIdIt = m_oldPathToPathIdMap.find( trimmedPath );
|
|
||||||
if ( pathToIdIt != m_oldPathToPathIdMap.end() )
|
|
||||||
{
|
|
||||||
pathId = pathToIdIt->second;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto pathPathIdPairIt = m_newPathToPathIdMap.find( trimmedPath );
|
|
||||||
if ( pathPathIdPairIt != m_newPathToPathIdMap.end() )
|
|
||||||
{
|
|
||||||
pathId = pathPathIdPairIt->second;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pathId = createUnusedId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_newPathIdToPathMap[pathId] = trimmedPath;
|
|
||||||
m_newPathToPathIdMap[trimmedPath] = pathId;
|
|
||||||
|
|
||||||
return pathId;
|
|
||||||
};
|
|
||||||
|
|
||||||
QString newGlobalPathListTable() const
|
|
||||||
{
|
|
||||||
QString pathList;
|
|
||||||
pathList += "\n";
|
|
||||||
for ( const auto& pathIdPathPairIt : m_newPathIdToPathMap )
|
|
||||||
{
|
|
||||||
pathList += " " + pathIdPathPairIt.first + " " + pathIdPathPairIt.second + ";\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
pathList += " ";
|
|
||||||
|
|
||||||
return pathList;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString pathFromPathId( const QString& pathId, bool* isFound ) const
|
|
||||||
{
|
|
||||||
auto it = m_oldPathIdToPathMap.find( pathId );
|
|
||||||
if ( it != m_oldPathIdToPathMap.end() )
|
|
||||||
{
|
|
||||||
( *isFound ) = true;
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
( *isFound ) = false;
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString createUnusedId()
|
|
||||||
{
|
|
||||||
m_maxUsedIdNumber++;
|
|
||||||
|
|
||||||
QString numberString = QString( "%1" ).arg( (uint)m_maxUsedIdNumber, 3, 10, QChar( '0' ) );
|
|
||||||
QString pathIdentifier = PATHIDCHAR + pathIdBaseString + numberString + PATHIDCHAR;
|
|
||||||
|
|
||||||
return pathIdentifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t m_maxUsedIdNumber; // Set when parsing the globalPathListTable. Increment while creating new id's
|
|
||||||
|
|
||||||
std::map<QString, QString> m_newPathIdToPathMap;
|
|
||||||
std::map<QString, QString> m_newPathToPathIdMap;
|
|
||||||
|
|
||||||
std::map<QString, QString> m_oldPathIdToPathMap;
|
|
||||||
std::map<QString, QString> m_oldPathToPathIdMap;
|
|
||||||
};
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RimProject::transferPathsToGlobalPathList()
|
void RimProject::transferPathsToGlobalPathList()
|
||||||
{
|
{
|
||||||
GlobalPathListMapper pathListMapper( m_globalPathList() );
|
RiaVariableMapper variableMapper( m_globalPathList() );
|
||||||
|
|
||||||
std::vector<caf::FilePath*> filePaths = allFilePaths();
|
std::vector<caf::FilePath*> filePaths = allFilePaths();
|
||||||
for ( caf::FilePath* filePath : filePaths )
|
for ( caf::FilePath* filePath : filePaths )
|
||||||
@@ -1675,12 +1537,54 @@ void RimProject::transferPathsToGlobalPathList()
|
|||||||
QString path = filePath->path();
|
QString path = filePath->path();
|
||||||
if ( !path.isEmpty() )
|
if ( !path.isEmpty() )
|
||||||
{
|
{
|
||||||
QString pathId = pathListMapper.addPathAndGetId( path );
|
QString pathId = variableMapper.addPathAndGetId( path );
|
||||||
filePath->setPath( pathId );
|
filePath->setPath( pathId );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_globalPathList = pathListMapper.newGlobalPathListTable();
|
for ( auto summaryCase : allSummaryCases() )
|
||||||
|
{
|
||||||
|
if ( summaryCase->displayNameType() == RimCaseDisplayNameTools::DisplayName::CUSTOM )
|
||||||
|
{
|
||||||
|
// At this point, after the replace of variables into caf::FilePath objects, the variable name is stored in
|
||||||
|
// the summary case object. Read out the variable name and append "_name" for custom summary variables.
|
||||||
|
|
||||||
|
QString variableName = summaryCase->summaryHeaderFilename();
|
||||||
|
variableName = variableName.remove( RiaVariableMapper::variableToken() );
|
||||||
|
|
||||||
|
variableName = RiaVariableMapper::variableToken() + variableName + RiaVariableMapper::postfixName() +
|
||||||
|
RiaVariableMapper::variableToken();
|
||||||
|
|
||||||
|
QString variableValue = summaryCase->displayCaseName();
|
||||||
|
variableMapper.addVariable( variableName, variableValue );
|
||||||
|
|
||||||
|
summaryCase->setCustomCaseName( variableName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( auto gridCase : allGridCases() )
|
||||||
|
{
|
||||||
|
if ( gridCase->displayNameType() == RimCaseDisplayNameTools::DisplayName::CUSTOM )
|
||||||
|
{
|
||||||
|
// At this point, after the replace of variables into caf::FilePath objects, the variable name is stored in
|
||||||
|
// the summary case object. Read out the variable name and append "_name" for custom summary variables.
|
||||||
|
|
||||||
|
QString variableName = gridCase->gridFileName();
|
||||||
|
variableName = variableName.remove( RiaVariableMapper::variableToken() );
|
||||||
|
|
||||||
|
variableName = RiaVariableMapper::variableToken() + variableName + RiaVariableMapper::postfixName() +
|
||||||
|
RiaVariableMapper::variableToken();
|
||||||
|
|
||||||
|
QString variableValue = gridCase->caseUserDescription();
|
||||||
|
variableMapper.addVariable( variableName, variableValue );
|
||||||
|
|
||||||
|
gridCase->setCustomCaseName( variableName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variableMapper.replaceVariablesInValues();
|
||||||
|
|
||||||
|
m_globalPathList = variableMapper.variableTableAsText();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@@ -1688,31 +1592,65 @@ void RimProject::transferPathsToGlobalPathList()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RimProject::distributePathsFromGlobalPathList()
|
void RimProject::distributePathsFromGlobalPathList()
|
||||||
{
|
{
|
||||||
GlobalPathListMapper pathListMapper( m_globalPathList() );
|
RiaVariableMapper pathListMapper( m_globalPathList() );
|
||||||
|
|
||||||
std::vector<caf::FilePath*> filePaths = allFilePaths();
|
std::vector<caf::FilePath*> filePaths = allFilePaths();
|
||||||
for ( caf::FilePath* filePath : filePaths )
|
for ( caf::FilePath* filePath : filePaths )
|
||||||
{
|
{
|
||||||
QString pathIdCandidate = filePath->path().trimmed();
|
QString pathIdCandidate = filePath->path().trimmed();
|
||||||
QStringList pathIdComponents = pathIdCandidate.split( PATHIDCHAR );
|
QStringList pathIdComponents = pathIdCandidate.split( RiaVariableMapper::variableToken() );
|
||||||
|
|
||||||
if ( pathIdComponents.size() == 3 && pathIdComponents[0].size() == 0 && pathIdComponents[1].size() > 0 &&
|
if ( pathIdComponents.size() == 3 && pathIdComponents[0].size() == 0 && pathIdComponents[1].size() > 0 &&
|
||||||
pathIdComponents[2].size() == 0 )
|
pathIdComponents[2].size() == 0 )
|
||||||
{
|
{
|
||||||
bool isFound = false;
|
bool isFound = false;
|
||||||
QString path = pathListMapper.pathFromPathId( pathIdCandidate, &isFound );
|
QString path = pathListMapper.valueForVariable( pathIdCandidate, &isFound );
|
||||||
if ( isFound )
|
if ( isFound )
|
||||||
{
|
{
|
||||||
filePath->setPath( path );
|
filePath->setPath( path );
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// The pathId can not be found in the path list
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
for ( auto summaryCase : allSummaryCases() )
|
||||||
{
|
{
|
||||||
// The pathIdCandidate is probably a real path. Leave alone.
|
if ( summaryCase->displayNameType() == RimCaseDisplayNameTools::DisplayName::CUSTOM )
|
||||||
|
{
|
||||||
|
auto variableName = summaryCase->displayCaseName();
|
||||||
|
|
||||||
|
bool isFound = false;
|
||||||
|
QString variableValue = pathListMapper.valueForVariable( variableName, &isFound );
|
||||||
|
if ( isFound )
|
||||||
|
{
|
||||||
|
summaryCase->setCustomCaseName( variableValue );
|
||||||
|
}
|
||||||
|
else if ( variableName.contains( RiaVariableMapper::postfixName() + RiaVariableMapper::variableToken() ) )
|
||||||
|
{
|
||||||
|
// The variable name is not found in the variable list, but the name indicates a variable. Reset to full
|
||||||
|
// case name.
|
||||||
|
summaryCase->setDisplayNameOption( RimCaseDisplayNameTools::DisplayName::FULL_CASE_NAME );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( auto gridCase : allGridCases() )
|
||||||
|
{
|
||||||
|
if ( gridCase->displayNameType() == RimCaseDisplayNameTools::DisplayName::CUSTOM )
|
||||||
|
{
|
||||||
|
auto variableName = gridCase->caseUserDescription();
|
||||||
|
|
||||||
|
bool isFound = false;
|
||||||
|
QString variableValue = pathListMapper.valueForVariable( variableName, &isFound );
|
||||||
|
if ( isFound )
|
||||||
|
{
|
||||||
|
gridCase->setCustomCaseName( variableValue );
|
||||||
|
}
|
||||||
|
else if ( variableName.contains( RiaVariableMapper::postfixName() + RiaVariableMapper::variableToken() ) )
|
||||||
|
{
|
||||||
|
// The variable name is not found in the variable list, but the name indicates a variable. Reset to full
|
||||||
|
// case name.
|
||||||
|
gridCase->setDisplayNameType( RimCaseDisplayNameTools::DisplayName::FULL_CASE_NAME );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -304,6 +304,14 @@ QString RimSummaryCase::nativeCaseName() const
|
|||||||
return caseName();
|
return caseName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RimCaseDisplayNameTools::DisplayName RimSummaryCase::displayNameType() const
|
||||||
|
{
|
||||||
|
return m_displayNameOption();
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@@ -57,17 +57,15 @@ public:
|
|||||||
virtual QString summaryHeaderFilename() const;
|
virtual QString summaryHeaderFilename() const;
|
||||||
QString displayCaseName() const;
|
QString displayCaseName() const;
|
||||||
QString nativeCaseName() const;
|
QString nativeCaseName() const;
|
||||||
|
void setCustomCaseName( const QString& caseName );
|
||||||
|
void updateAutoShortName();
|
||||||
|
RimCaseDisplayNameTools::DisplayName displayNameType() const;
|
||||||
|
void setDisplayNameOption( RimCaseDisplayNameTools::DisplayName displayNameOption );
|
||||||
|
|
||||||
void setCaseId( int caseId );
|
void setCaseId( int caseId );
|
||||||
int caseId() const;
|
int caseId() const;
|
||||||
|
|
||||||
void setCustomCaseName( const QString& caseName );
|
|
||||||
|
|
||||||
caf::AppEnum<RiaDefines::EclipseUnitSystem> unitsSystem();
|
|
||||||
|
|
||||||
void setDisplayNameOption( RimCaseDisplayNameTools::DisplayName displayNameOption );
|
|
||||||
void updateAutoShortName();
|
|
||||||
void updateOptionSensitivity();
|
void updateOptionSensitivity();
|
||||||
|
|
||||||
void refreshMetaData();
|
void refreshMetaData();
|
||||||
|
|
||||||
virtual void createSummaryReaderInterface() = 0;
|
virtual void createSummaryReaderInterface() = 0;
|
||||||
@@ -78,6 +76,8 @@ public:
|
|||||||
|
|
||||||
void setSummaryHeaderFileName( const QString& fileName );
|
void setSummaryHeaderFileName( const QString& fileName );
|
||||||
|
|
||||||
|
caf::AppEnum<RiaDefines::EclipseUnitSystem> unitsSystem();
|
||||||
|
|
||||||
bool isObservedData() const;
|
bool isObservedData() const;
|
||||||
|
|
||||||
bool showRealizationDataSources() const;
|
bool showRealizationDataSources() const;
|
||||||
|
@@ -0,0 +1,11 @@
|
|||||||
|
set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RiaVariableMapper.h)
|
||||||
|
|
||||||
|
set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RiaVariableMapper.cpp)
|
||||||
|
|
||||||
|
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
|
||||||
|
list(APPEND CODE_SOURCE_FILES ${SOURCE_GROUP_SOURCE_FILES})
|
||||||
|
|
||||||
|
source_group(
|
||||||
|
"Tools" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES}
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake
|
||||||
|
)
|
228
ApplicationLibCode/ProjectDataModel/Tools/RiaVariableMapper.cpp
Normal file
228
ApplicationLibCode/ProjectDataModel/Tools/RiaVariableMapper.cpp
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2022- Equinor ASA
|
||||||
|
//
|
||||||
|
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||||
|
// for more details.
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "RiaVariableMapper.h"
|
||||||
|
#include "RiaTextStringTools.h"
|
||||||
|
|
||||||
|
#include <QRegularExpression>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RiaVariableMapper::RiaVariableMapper( const QString& variableNameValueTable )
|
||||||
|
{
|
||||||
|
m_maxUsedIdNumber = 0;
|
||||||
|
QStringList lines = RiaTextStringTools::splitSkipEmptyParts( variableNameValueTable, ";" );
|
||||||
|
|
||||||
|
QRegularExpression realizationRe =
|
||||||
|
QRegularExpression( QString( "[%1]\\w*[%2]" ).arg( variableToken() ).arg( variableToken() ) );
|
||||||
|
|
||||||
|
for ( const QString& line : lines )
|
||||||
|
{
|
||||||
|
QRegularExpressionMatch match = realizationRe.match( line );
|
||||||
|
if ( match.hasMatch() )
|
||||||
|
{
|
||||||
|
QString variableName = match.captured();
|
||||||
|
QString variableNameStripped = variableName;
|
||||||
|
variableNameStripped.replace( variableToken(), "" );
|
||||||
|
|
||||||
|
QString variableValue = line.right( line.size() - match.capturedEnd() ).trimmed();
|
||||||
|
|
||||||
|
// Check if we have a standard id, and store the max number
|
||||||
|
|
||||||
|
if ( variableNameStripped.startsWith( pathIdBaseString() ) )
|
||||||
|
{
|
||||||
|
bool isOk = false;
|
||||||
|
QString numberText = variableNameStripped.right( variableNameStripped.size() - pathIdBaseString().size() );
|
||||||
|
size_t idNumber = numberText.toUInt( &isOk );
|
||||||
|
|
||||||
|
if ( isOk )
|
||||||
|
{
|
||||||
|
m_maxUsedIdNumber = std::max( m_maxUsedIdNumber, idNumber );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_variableToValueMap[variableName] = variableValue;
|
||||||
|
m_valueToVariableMap[variableValue] = variableName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resolveVariablesUsedInValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
QString RiaVariableMapper::addPathAndGetId( const QString& path )
|
||||||
|
{
|
||||||
|
auto computePathId = [this]( const auto& trimmedPath ) -> QString {
|
||||||
|
QString pathId;
|
||||||
|
auto pathToIdIt = m_valueToVariableMap.find( trimmedPath );
|
||||||
|
if ( pathToIdIt != m_valueToVariableMap.end() )
|
||||||
|
{
|
||||||
|
pathId = pathToIdIt->second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto pathPathIdPairIt = m_pathToPathIdMap.find( trimmedPath );
|
||||||
|
if ( pathPathIdPairIt != m_pathToPathIdMap.end() )
|
||||||
|
{
|
||||||
|
pathId = pathPathIdPairIt->second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pathId = createUnusedId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pathId;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Want to re-use ids from last save to avoid unnecessary changes and make the behavior predictable
|
||||||
|
QString trimmedPath = path.trimmed();
|
||||||
|
QString pathId = computePathId( trimmedPath );
|
||||||
|
|
||||||
|
addVariable( pathId, trimmedPath );
|
||||||
|
|
||||||
|
m_pathToPathIdMap[trimmedPath] = pathId;
|
||||||
|
|
||||||
|
return pathId;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
QString RiaVariableMapper::variableTableAsText() const
|
||||||
|
{
|
||||||
|
std::vector<std::pair<QString, QString>> sortedVariables;
|
||||||
|
for ( const auto& it : m_newVariableToValueMap )
|
||||||
|
{
|
||||||
|
sortedVariables.emplace_back( it );
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString pathText = variableToken() + pathIdBaseString();
|
||||||
|
|
||||||
|
// Put path variables at the end of the list
|
||||||
|
std::sort( sortedVariables.begin(), sortedVariables.end(), [pathText]( const auto& lhs, const auto& rhs ) {
|
||||||
|
bool isLhsPath = lhs.first.startsWith( pathText );
|
||||||
|
bool isRhsPath = rhs.first.startsWith( pathText );
|
||||||
|
|
||||||
|
if ( isLhsPath && !isRhsPath ) return false;
|
||||||
|
if ( !isLhsPath && isRhsPath ) return true;
|
||||||
|
|
||||||
|
return lhs.first < rhs.first;
|
||||||
|
} );
|
||||||
|
|
||||||
|
QString textTable;
|
||||||
|
textTable += "\n";
|
||||||
|
|
||||||
|
for ( const auto& variableNameValuePair : sortedVariables )
|
||||||
|
{
|
||||||
|
textTable += " " + variableNameValuePair.first + " " + variableNameValuePair.second + ";\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
textTable += " ";
|
||||||
|
|
||||||
|
return textTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RiaVariableMapper::addVariable( const QString& variableName, const QString& variableValue )
|
||||||
|
{
|
||||||
|
m_newVariableToValueMap[variableName] = variableValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
QString RiaVariableMapper::valueForVariable( const QString& variableName, bool* isFound ) const
|
||||||
|
{
|
||||||
|
auto it = m_variableToValueMap.find( variableName );
|
||||||
|
if ( it != m_variableToValueMap.end() )
|
||||||
|
{
|
||||||
|
if ( isFound ) *isFound = true;
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isFound ) *isFound = false;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
QString RiaVariableMapper::createUnusedId()
|
||||||
|
{
|
||||||
|
m_maxUsedIdNumber++;
|
||||||
|
|
||||||
|
QString numberString = QString( "%1" ).arg( (uint)m_maxUsedIdNumber, 3, 10, QChar( '0' ) );
|
||||||
|
QString pathIdentifier = variableToken() + pathIdBaseString() + numberString + variableToken();
|
||||||
|
|
||||||
|
return pathIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
// Replace all variables with text in variable values
|
||||||
|
// $MyPath$ = /path/to/my/file
|
||||||
|
// $MyFile$ = $MyPath$/myFile.txt => $MyFile$ = /path/to/my/file/myFile.txt
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RiaVariableMapper::resolveVariablesUsedInValues()
|
||||||
|
{
|
||||||
|
for ( auto& variableValuePair : m_variableToValueMap )
|
||||||
|
{
|
||||||
|
QString variableValue = variableValuePair.second;
|
||||||
|
|
||||||
|
for ( const auto& [otherVariableName, otherVariableValue] : m_variableToValueMap )
|
||||||
|
{
|
||||||
|
variableValue.replace( otherVariableName, otherVariableValue );
|
||||||
|
}
|
||||||
|
|
||||||
|
variableValuePair.second = variableValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
// Replace text in variable values with variables
|
||||||
|
// $MyPath$ = /path/to/my/file
|
||||||
|
// $PathId_001$ = $MyPath$/myFile.txt => $PathId_001$ = $MyPath$/myFile.txt
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RiaVariableMapper::replaceVariablesInValues()
|
||||||
|
{
|
||||||
|
// Move all non-path variables from the original map imported from the project file to the new map
|
||||||
|
for ( auto& [variableName, variableValue] : m_variableToValueMap )
|
||||||
|
{
|
||||||
|
if ( !variableName.startsWith( variableToken() + pathIdBaseString() ) )
|
||||||
|
{
|
||||||
|
m_newVariableToValueMap[variableName] = variableValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace text with variables
|
||||||
|
for ( auto& [variableName, variableValue] : m_newVariableToValueMap )
|
||||||
|
{
|
||||||
|
for ( const auto& [otherVariableName, otherVariableValue] : m_newVariableToValueMap )
|
||||||
|
{
|
||||||
|
if ( otherVariableName != variableName )
|
||||||
|
{
|
||||||
|
variableValue.replace( otherVariableValue, otherVariableName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,54 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2022- Equinor ASA
|
||||||
|
//
|
||||||
|
// 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 <http://www.gnu.org/licenses/gpl.html>
|
||||||
|
// for more details.
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
class RiaVariableMapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static QString variableToken() { return "$"; }
|
||||||
|
static QString pathIdBaseString() { return "PathId_"; }
|
||||||
|
static QString postfixName() { return "_Name"; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
RiaVariableMapper( const QString& variableNameValueTable );
|
||||||
|
|
||||||
|
QString addPathAndGetId( const QString& path );
|
||||||
|
|
||||||
|
void addVariable( const QString& variableName, const QString& variableValue );
|
||||||
|
QString valueForVariable( const QString& variableName, bool* isFound ) const;
|
||||||
|
|
||||||
|
void replaceVariablesInValues();
|
||||||
|
QString variableTableAsText() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString createUnusedId();
|
||||||
|
void resolveVariablesUsedInValues();
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t m_maxUsedIdNumber;
|
||||||
|
|
||||||
|
std::map<QString, QString> m_newVariableToValueMap;
|
||||||
|
std::map<QString, QString> m_pathToPathIdMap;
|
||||||
|
|
||||||
|
std::map<QString, QString> m_variableToValueMap;
|
||||||
|
std::map<QString, QString> m_valueToVariableMap;
|
||||||
|
};
|
@@ -84,6 +84,7 @@ set(SOURCE_GROUP_SOURCE_FILES
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/opm-summary-Test.cpp
|
${CMAKE_CURRENT_LIST_DIR}/opm-summary-Test.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RifEclipseTextFileReader-Test.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RifEclipseTextFileReader-Test.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RiaSummaryStringTools-Test.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RiaSummaryStringTools-Test.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RiaVariableMapper-Test.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(RESINSIGHT_ENABLE_GRPC)
|
if(RESINSIGHT_ENABLE_GRPC)
|
||||||
|
102
ApplicationLibCode/UnitTests/RiaVariableMapper-Test.cpp
Normal file
102
ApplicationLibCode/UnitTests/RiaVariableMapper-Test.cpp
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "Tools/RiaVariableMapper.h"
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
TEST( RiaVariableMapperTest, BasicUsage )
|
||||||
|
{
|
||||||
|
QString inputText = R"(
|
||||||
|
$MyVar$ /path/to/file;
|
||||||
|
$PathId_001$ myFile.txt;
|
||||||
|
)";
|
||||||
|
|
||||||
|
RiaVariableMapper mapper( inputText );
|
||||||
|
|
||||||
|
bool isFound = false;
|
||||||
|
QString value;
|
||||||
|
|
||||||
|
value = mapper.valueForVariable( "$MyVar$", &isFound );
|
||||||
|
EXPECT_TRUE( isFound );
|
||||||
|
EXPECT_STREQ( value.toStdString().data(), "/path/to/file" );
|
||||||
|
|
||||||
|
value = mapper.valueForVariable( "$PathId_001$", &isFound );
|
||||||
|
EXPECT_TRUE( isFound );
|
||||||
|
EXPECT_STREQ( value.toStdString().data(), "myFile.txt" );
|
||||||
|
|
||||||
|
mapper.valueForVariable( "not present", &isFound );
|
||||||
|
EXPECT_FALSE( isFound );
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
TEST( RiaVariableMapperTest, UserDefinedVariables )
|
||||||
|
{
|
||||||
|
QString inputText = R"(
|
||||||
|
$MyVar$ /path/to/file;
|
||||||
|
$TestVar$ a different variable;
|
||||||
|
)";
|
||||||
|
|
||||||
|
RiaVariableMapper mapper( inputText );
|
||||||
|
|
||||||
|
mapper.addPathAndGetId( "/path/to/file/myFile.txt" );
|
||||||
|
mapper.addPathAndGetId( "/path/to/file/myFile2.txt" );
|
||||||
|
|
||||||
|
mapper.replaceVariablesInValues();
|
||||||
|
|
||||||
|
QString table = mapper.variableTableAsText();
|
||||||
|
|
||||||
|
QString expectedText = R"(
|
||||||
|
$MyVar$ /path/to/file;
|
||||||
|
$TestVar$ a different variable;
|
||||||
|
$PathId_001$ $MyVar$/myFile.txt;
|
||||||
|
$PathId_002$ $MyVar$/myFile2.txt;
|
||||||
|
)";
|
||||||
|
|
||||||
|
EXPECT_TRUE( table == expectedText );
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
TEST( RiaVariableMapperTest, UserDefinedVariablesRecursive )
|
||||||
|
{
|
||||||
|
QString inputText = R"(
|
||||||
|
$MyVar2$ $MyVar1$/to/file;
|
||||||
|
$MyVar1$ /path;
|
||||||
|
$TestVar$ a different variable;
|
||||||
|
)";
|
||||||
|
|
||||||
|
RiaVariableMapper mapper( inputText );
|
||||||
|
|
||||||
|
mapper.addPathAndGetId( "/path/to/file/myFile.txt" );
|
||||||
|
mapper.addPathAndGetId( "/path/to/file/myFile2.txt" );
|
||||||
|
|
||||||
|
mapper.replaceVariablesInValues();
|
||||||
|
|
||||||
|
QString table = mapper.variableTableAsText();
|
||||||
|
|
||||||
|
QString expectedText = R"(
|
||||||
|
$MyVar1$ /path;
|
||||||
|
$MyVar2$ $MyVar1$/to/file;
|
||||||
|
$TestVar$ a different variable;
|
||||||
|
$PathId_001$ $MyVar2$/myFile.txt;
|
||||||
|
$PathId_002$ $MyVar2$/myFile2.txt;
|
||||||
|
)";
|
||||||
|
|
||||||
|
EXPECT_TRUE( table == expectedText );
|
||||||
|
|
||||||
|
RiaVariableMapper otherMapper( table );
|
||||||
|
bool isFound = false;
|
||||||
|
|
||||||
|
QString value = otherMapper.valueForVariable( "$MyVar1$", &isFound );
|
||||||
|
EXPECT_TRUE( value == "/path" );
|
||||||
|
|
||||||
|
value = otherMapper.valueForVariable( "$MyVar2$", &isFound );
|
||||||
|
EXPECT_TRUE( value == "/path/to/file" );
|
||||||
|
|
||||||
|
value = otherMapper.valueForVariable( "$PathId_001$", &isFound );
|
||||||
|
EXPECT_TRUE( value == "/path/to/file/myFile.txt" );
|
||||||
|
}
|
Reference in New Issue
Block a user