From 2ba62274621e5cc5ec5404374e960a15cfccdb8f Mon Sep 17 00:00:00 2001 From: mhugent Date: Sun, 31 Oct 2010 17:12:39 +0000 Subject: [PATCH] Store svg fill pathes relativ to default svg directory. Fixes bug #3154 git-svn-id: http://svn.osgeo.org/qgis/trunk@14463 c8812cc2-4d05-0410-92ff-de0c093fc19c --- src/core/qgsapplication.cpp | 110 ++++++++++++++++++ src/core/qgsapplication.h | 7 ++ .../symbology-ng/qgsfillsymbollayerv2.cpp | 5 +- 3 files changed, 120 insertions(+), 2 deletions(-) diff --git a/src/core/qgsapplication.cpp b/src/core/qgsapplication.cpp index ccf1eba641e..1fdaaa1d896 100644 --- a/src/core/qgsapplication.cpp +++ b/src/core/qgsapplication.cpp @@ -482,3 +482,113 @@ void QgsApplication::registerOgrDrivers() OGRRegisterAll(); } } + +QString QgsApplication::absolutePathToRelativePath( const QString& apath, const QString& targetPath ) +{ +#if defined( Q_OS_WIN ) + const Qt::CaseSensitivity cs = Qt::CaseInsensitive; + + aPath.replace( "\\", "/" ); + if ( aPath.startsWith( "//" ) ) + { + // keep UNC prefix + aPath = "\\\\" + aPath.mid( 2 ); + } + + targetPath.replace( "\\", "/" ); + if ( targetPath.startsWith( "//" ) ) + { + // keep UNC prefix + targetPath = "\\\\" + targetPath.mid( 2 ); + } +#else + const Qt::CaseSensitivity cs = Qt::CaseSensitive; +#endif + + QStringList targetElems = targetPath.split( "/", QString::SkipEmptyParts ); + QStringList aPathElems = apath.split( "/", QString::SkipEmptyParts ); + + targetElems.removeAll( "." ); + aPathElems.removeAll( "." ); + + // remove common part + int n = 0; + while ( aPathElems.size() > 0 && + targetElems.size() > 0 && + aPathElems[0].compare( targetElems[0], cs ) == 0 ) + { + aPathElems.removeFirst(); + targetElems.removeFirst(); + n++; + } + + if ( n == 0 ) + { + // no common parts; might not even by a file + return apath; + } + + if ( targetElems.size() > 0 ) + { + // go up to the common directory + for ( int i = 0; i < targetElems.size(); i++ ) + { + aPathElems.insert( 0, ".." ); + } + } + else + { + // let it start with . nevertheless, + // so relative path always start with either ./ or ../ + aPathElems.insert( 0, "." ); + } + + return aPathElems.join( "/" ); +} + +QString QgsApplication::relativePathToAbsolutePath( const QString& rpath, const QString& targetPath ) +{ + // relative path should always start with ./ or ../ + if ( !rpath.startsWith( "./" ) && !rpath.startsWith( "../" ) ) + { + return rpath; + } + +#if defined(Q_OS_WIN) + rPath.replace( "\\", "/" ); + targetPath.replace( "\\", "/" ); + + bool uncPath = targetPath.startsWith( "//" ); +#endif + + QStringList srcElems = rpath.split( "/", QString::SkipEmptyParts ); + QStringList targetElems = targetPath.split( "/", QString::SkipEmptyParts ); + +#if defined(Q_OS_WIN) + if ( uncPath ) + { + targetElems.insert( 0, "" ); + targetElems.insert( 0, "" ); + } +#endif + + // append source path elements + targetElems << srcElems; + targetElems.removeAll( "." ); + + // resolve .. + int pos; + while (( pos = targetElems.indexOf( ".." ) ) > 0 ) + { + // remove preceding element and .. + targetElems.removeAt( pos - 1 ); + targetElems.removeAt( pos - 1 ); + } + +#if !defined(Q_OS_WIN) + // make path absolute + targetElems.prepend( "" ); +#endif + + return targetElems.join( "/" ); +} diff --git a/src/core/qgsapplication.h b/src/core/qgsapplication.h index 9ca683edb88..4246fbc3ad8 100644 --- a/src/core/qgsapplication.h +++ b/src/core/qgsapplication.h @@ -192,6 +192,13 @@ class CORE_EXPORT QgsApplication: public QApplication */ static void registerOgrDrivers(); + /**Converts absolute path to path relative to target + @note: this method was added in version 1.6*/ + static QString absolutePathToRelativePath( const QString& apath, const QString& targetPath ); + /**Converts path relative to target to an absolute path + @note: this method was added in version 1.6*/ + static QString relativePathToAbsolutePath( const QString& rpath, const QString& targetPath ); + private: static QString mPrefixPath; static QString mPluginPath; diff --git a/src/core/symbology-ng/qgsfillsymbollayerv2.cpp b/src/core/symbology-ng/qgsfillsymbollayerv2.cpp index d029941516e..3116eb2f16d 100644 --- a/src/core/symbology-ng/qgsfillsymbollayerv2.cpp +++ b/src/core/symbology-ng/qgsfillsymbollayerv2.cpp @@ -1,6 +1,7 @@ #include "qgsfillsymbollayerv2.h" #include "qgssymbollayerv2utils.h" +#include "qgsapplication.h" #include "qgsrendercontext.h" #include "qgsproject.h" @@ -158,7 +159,7 @@ QgsSymbolLayerV2* QgsSVGFillSymbolLayer::create( const QgsStringMap& properties } if ( properties.contains( "svgFile" ) ) { - svgFilePath = QgsProject::instance()->readPath( properties["svgFile"] ); + svgFilePath = QgsApplication::relativePathToAbsolutePath( properties["svgFile"], QgsApplication::svgPath() ); } if ( !svgFilePath.isEmpty() ) @@ -264,7 +265,7 @@ QgsStringMap QgsSVGFillSymbolLayer::properties() const QgsStringMap map; if ( !mSvgFilePath.isEmpty() ) { - map.insert( "svgFile", QgsProject::instance()->writePath( mSvgFilePath ) ); + map.insert( "svgFile", QgsApplication::absolutePathToRelativePath( mSvgFilePath, QgsApplication::svgPath() ) ); } else {