#5147 PdmField<caf::FilePath> now uses a reference list in the start of the project file to store the paths.

This commit is contained in:
Jacob Støren
2019-12-10 14:58:47 +01:00
parent 8e540efa37
commit a9d089df6d
3 changed files with 225 additions and 2 deletions

View File

@@ -316,7 +316,7 @@ bool RiaApplication::openFile( const QString& fileName )
} }
else if ( fileType & RiaDefines::ANY_ECLIPSE_FILE ) else if ( fileType & RiaDefines::ANY_ECLIPSE_FILE )
{ {
loadingSucceded = RicImportGeneralDataFeature::openEclipseFilesFromFileNames( QStringList{ fileName }, true ); loadingSucceded = RicImportGeneralDataFeature::openEclipseFilesFromFileNames( QStringList{fileName}, true );
lastUsedDialogTag = RiaDefines::defaultDirectoryLabel( fileType ); lastUsedDialogTag = RiaDefines::defaultDirectoryLabel( fileType );
} }
@@ -701,7 +701,7 @@ bool RiaApplication::saveProjectAs( const QString& fileName, QString* errorMessa
onProjectBeingSaved(); onProjectBeingSaved();
if ( !m_project->writeFile() ) if ( !m_project->writeProjectFile() )
{ {
CAF_ASSERT( errorMessage ); CAF_ASSERT( errorMessage );
*errorMessage = QString( "Not possible to save project file. Make sure you have sufficient access " *errorMessage = QString( "Not possible to save project file. Make sure you have sufficient access "

View File

@@ -96,6 +96,7 @@
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
#include <QMenu> #include <QMenu>
#include <algorithm>
CAF_PDM_SOURCE_INIT( RimProject, "ResInsightProject" ); CAF_PDM_SOURCE_INIT( RimProject, "ResInsightProject" );
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -112,6 +113,9 @@ RimProject::RimProject( void )
CAF_PDM_InitFieldNoDefault( &m_projectFileVersionString, "ProjectFileVersionString", "", "", "", "" ); CAF_PDM_InitFieldNoDefault( &m_projectFileVersionString, "ProjectFileVersionString", "", "", "", "" );
m_projectFileVersionString.uiCapability()->setUiHidden( true ); m_projectFileVersionString.uiCapability()->setUiHidden( true );
CAF_PDM_InitFieldNoDefault( &m_globalPathList, "ReferencedExternalFiles", "", "", "", "" );
m_globalPathList.uiCapability()->setUiHidden( true );
CAF_PDM_InitFieldNoDefault( &oilFields, "OilFields", "Oil Fields", "", "", "" ); CAF_PDM_InitFieldNoDefault( &oilFields, "OilFields", "Oil Fields", "", "", "" );
oilFields.uiCapability()->setUiHidden( true ); oilFields.uiCapability()->setUiHidden( true );
@@ -254,6 +258,8 @@ void RimProject::close()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimProject::initAfterRead() void RimProject::initAfterRead()
{ {
this->distributePathsFromGlobalPathList();
// Create an empty oil field in case the project did not contain one // Create an empty oil field in case the project did not contain one
if ( oilFields.size() < 1 ) if ( oilFields.size() < 1 )
{ {
@@ -329,6 +335,18 @@ void RimProject::setupBeforeSave()
m_projectFileVersionString = STRPRODUCTVER; m_projectFileVersionString = STRPRODUCTVER;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimProject::writeProjectFile()
{
this->transferPathsToGlobalPathList();
bool couldOpenFile = this->writeFile();
this->distributePathsFromGlobalPathList();
return couldOpenFile;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Support list of multiple script paths divided by ';' /// Support list of multiple script paths divided by ';'
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -1349,3 +1367,202 @@ 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_nextValidIdNumber = 1;
QStringList pathPairs = globalPathListTable.split( ";", QString::SkipEmptyParts );
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_nextValidIdNumber = std::max( m_nextValidIdNumber, 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()
{
QString pathIdentifier = PATHIDCHAR + pathIdBaseString + QString::number( m_nextValidIdNumber ) + PATHIDCHAR;
m_nextValidIdNumber++;
return pathIdentifier;
}
size_t m_nextValidIdNumber; // 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()
{
GlobalPathListMapper pathListMapper( m_globalPathList() );
std::vector<caf::FilePath*> filePaths;
fieldContentsByType( this, filePaths );
for ( caf::FilePath* filePath : filePaths )
{
QString path = filePath->path();
if ( !path.isEmpty() )
{
QString pathId = pathListMapper.addPathAndGetId( path );
filePath->setPath( pathId );
}
}
m_globalPathList = pathListMapper.newGlobalPathListTable();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimProject::distributePathsFromGlobalPathList()
{
GlobalPathListMapper pathListMapper( m_globalPathList() );
std::vector<caf::FilePath*> filePaths;
fieldContentsByType( this, filePaths );
for ( caf::FilePath* filePath : filePaths )
{
QString pathIdCandidate = filePath->path().trimmed();
QStringList pathIdComponents = pathIdCandidate.split( PATHIDCHAR );
if ( pathIdComponents.size() == 3 && pathIdComponents[0].size() == 0 && pathIdComponents[1].size() > 0 &&
pathIdComponents[2].size() == 0 )
{
bool isFound = false;
QString path = pathListMapper.pathFromPathId( pathIdCandidate, &isFound );
if ( isFound )
{
filePath->setPath( path );
}
else
{
// The pathId can not be found in the path list
}
}
else
{
// The pathIdCandidate is probably a real path. Leave alone.
}
}
}

View File

@@ -106,6 +106,8 @@ public:
caf::PdmField<QString> plotWindowTreeViewState; caf::PdmField<QString> plotWindowTreeViewState;
caf::PdmField<QString> plotWindowCurrentModelIndexPath; caf::PdmField<QString> plotWindowCurrentModelIndexPath;
bool writeProjectFile();
void setScriptDirectories( const QString& scriptDirectories ); void setScriptDirectories( const QString& scriptDirectories );
void setPlotTemplateFolders( const QStringList& plotTemplateFolders ); void setPlotTemplateFolders( const QStringList& plotTemplateFolders );
@@ -191,7 +193,11 @@ private:
template <typename T> template <typename T>
void fieldContentsByType( caf::PdmObjectHandle* object, std::vector<T*>& typedFields ); void fieldContentsByType( caf::PdmObjectHandle* object, std::vector<T*>& typedFields );
void transferPathsToGlobalPathList();
void distributePathsFromGlobalPathList();
private: private:
caf::PdmField<QString> m_globalPathList;
caf::PdmField<QString> m_projectFileVersionString; caf::PdmField<QString> m_projectFileVersionString;
caf::PdmChildField<RimDialogData*> m_dialogData; caf::PdmChildField<RimDialogData*> m_dialogData;