From 10c5b2f9db215e1516626955252e6fe23fdce3fb Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sun, 25 Aug 2019 12:11:33 +1000 Subject: [PATCH] Replace paths pointing to inbuilt data folder with "inbuilt:" prefix during project write, and redirect paths beginning with "inbuilt:" prefix to actual local install folder during project read Allows projects using data like the built-in world map layer to work correctly across different installs --- src/core/qgspathresolver.cpp | 20 ++++++++++++++++++-- tests/src/python/test_qgspathresolver.py | 16 +++++++++++++++- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/core/qgspathresolver.cpp b/src/core/qgspathresolver.cpp index 196ed8cd1e7..fca9cf5ac3e 100644 --- a/src/core/qgspathresolver.cpp +++ b/src/core/qgspathresolver.cpp @@ -16,7 +16,7 @@ #include "qgspathresolver.h" #include "qgis.h" - +#include "qgsapplication.h" #include #include #include @@ -40,6 +40,11 @@ QString QgsPathResolver::readPath( const QString &f ) const return QString(); QString src = filename; + if ( src.startsWith( QLatin1String( "inbuilt:" ) ) ) + { + // strip away "inbuilt:" prefix, replace with actual inbuilt data folder path + return QgsApplication::pkgDataPath() + QStringLiteral( "/resources" ) + src.mid( 8 ); + } if ( mBaseFileName.isNull() ) { @@ -168,7 +173,18 @@ bool QgsPathResolver::removePathPreprocessor( const QString &id ) QString QgsPathResolver::writePath( const QString &src ) const { - if ( mBaseFileName.isEmpty() || src.isEmpty() ) + if ( src.isEmpty() ) + { + return src; + } + + if ( src.startsWith( QgsApplication::pkgDataPath() + QStringLiteral( "/resources" ) ) ) + { + // replace inbuilt data folder path with "inbuilt:" prefix + return QStringLiteral( "inbuilt:" ) + src.mid( QgsApplication::pkgDataPath().length() + 10 ); + } + + if ( mBaseFileName.isEmpty() ) { return src; } diff --git a/tests/src/python/test_qgspathresolver.py b/tests/src/python/test_qgspathresolver.py index 9978877c597..c447d7f7b59 100644 --- a/tests/src/python/test_qgspathresolver.py +++ b/tests/src/python/test_qgspathresolver.py @@ -15,7 +15,12 @@ import qgis # NOQA import tempfile import os import gc -from qgis.core import QgsPathResolver, QgsVectorLayer, QgsProject +from qgis.core import ( + QgsPathResolver, + QgsVectorLayer, + QgsProject, + QgsApplication +) from qgis.testing import start_app, unittest from utilities import unitTestDataPath @@ -130,6 +135,15 @@ class TestQgsPathResolver(unittest.TestCase): # layer should have correct path now self.assertTrue(l.isValid()) + def testInbuiltPath(self): + """ + Test resolving and saving inbuilt data paths + """ + path = "inbuilt:/data/world_map.shp" + self.assertEqual(QgsPathResolver().readPath(path), QgsApplication.pkgDataPath() + '/resources/data/world_map.shp') + + self.assertEqual(QgsPathResolver().writePath(QgsApplication.pkgDataPath() + '/resources/data/world_map.shp'), 'inbuilt:/data/world_map.shp') + if __name__ == '__main__': unittest.main()