[QGIS Commit] r11571 - in trunk/qgis: python/core src/core
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Sat Sep 5 15:49:10 EDT 2009
Author: jef
Date: 2009-09-05 15:49:10 -0400 (Sat, 05 Sep 2009)
New Revision: 11571
Modified:
trunk/qgis/python/core/qgsproject.sip
trunk/qgis/src/core/qgsmaplayer.cpp
trunk/qgis/src/core/qgsproject.cpp
trunk/qgis/src/core/qgsproject.h
Log:
improve relative path support
Modified: trunk/qgis/python/core/qgsproject.sip
===================================================================
--- trunk/qgis/python/core/qgsproject.sip 2009-09-05 19:45:32 UTC (rev 11570)
+++ trunk/qgis/python/core/qgsproject.sip 2009-09-05 19:49:10 UTC (rev 11571)
@@ -223,6 +223,14 @@
*/
void dumpProperties() const;
+ /** prepare a filename to save it to the project file
+ @note added in 1.3 */
+ QString writePath( QString filename ) const;
+
+ /** turn filename read from the project file to an absolute path
+ @note added in 1.3 */
+ QString readPath( QString filename ) const;
+
signals:
//! emitted when project is being read
Modified: trunk/qgis/src/core/qgsmaplayer.cpp
===================================================================
--- trunk/qgis/src/core/qgsmaplayer.cpp 2009-09-05 19:45:32 UTC (rev 11570)
+++ trunk/qgis/src/core/qgsmaplayer.cpp 2009-09-05 19:49:10 UTC (rev 11571)
@@ -152,21 +152,8 @@
QDomElement mne = mnl.toElement();
mDataSource = mne.text();
- QFileInfo fi( mDataSource );
- if ( !fi.exists() && fi.isRelative() )
- {
- QFileInfo pfi( QgsProject::instance()->fileName() );
- if ( pfi.exists() )
- {
- fi.setFile( pfi.canonicalPath() + QDir::separator() + mDataSource );
+ mDataSource = QgsProject::instance()->readPath( mDataSource );
- if ( fi.exists() )
- {
- mDataSource = fi.canonicalFilePath();
- }
- }
- }
-
// Set the CRS from project file, asking the user if necessary.
// Make it the saved CRS to have WMS layer projected correctly.
// We will still overwrite whatever GDAL etc picks up anyway
@@ -280,20 +267,8 @@
QDomElement dataSource = document.createElement( "datasource" );
QString src = source();
- QFileInfo srcInfo( src );
- bool absolutePath = QgsProject::instance()->readBoolEntry( "Paths", "/Absolute", true );
- if ( !absolutePath && srcInfo.exists() )
- {
- QFileInfo pfi( QgsProject::instance()->fileName() );
- QgsDebugMsg( "project path: " + pfi.canonicalPath() );
- QgsDebugMsg( "src path: " + srcInfo.canonicalFilePath() );
- if ( srcInfo.canonicalFilePath().startsWith( pfi.canonicalPath() + "/" ) ) // QFileInfo always uses '/' for directory separator.
- {
- src = src.mid( pfi.canonicalPath().size() + 1 );
- QgsDebugMsg( "use relative path: " + src );
- }
- }
+ src = QgsProject::instance()->writePath( src );
QDomText dataSourceText = document.createTextNode( src );
dataSource.appendChild( dataSourceText );
Modified: trunk/qgis/src/core/qgsproject.cpp
===================================================================
--- trunk/qgis/src/core/qgsproject.cpp 2009-09-05 19:45:32 UTC (rev 11570)
+++ trunk/qgis/src/core/qgsproject.cpp 2009-09-05 19:49:10 UTC (rev 11571)
@@ -1300,3 +1300,154 @@
{
dump_( imp_->properties_ );
} // QgsProject::dumpProperties
+
+
+// return the absolute path from a filename read from project file
+QString QgsProject::readPath( QString src ) const
+{
+ if ( readBoolEntry( "Paths", "/Absolute", true ) )
+ {
+ return src;
+ }
+
+ // relative path should always start with ./ or ../
+ if ( !src.startsWith( "./" ) && !src.startsWith( "../" ) )
+ {
+#if defined(Q_OS_WIN)
+ if ( src.startsWith( "\\\\" ) ||
+ ( src[0].isLetter() && src[1] == ':' ) )
+ {
+ // UNC or absolute path
+ return src;
+ }
+#else
+ if ( src[0] == '/' )
+ {
+ // absolute path
+ return src;
+ }
+#endif
+
+ // so this one isn't absolute, but also doesn't start // with ./ or ../.
+ // That means that it was saved with an earlier version of "relative path support",
+ // where the source file had to exist and only the project directory was stripped
+ // from the filename.
+ QFileInfo pfi( fileName() );
+ Q_ASSERT( pfi.exists() );
+ QFileInfo fi( pfi.canonicalPath() + "/" + src );
+
+ if ( !fi.exists() )
+ {
+ return src;
+ }
+ else
+ {
+ return fi.canonicalFilePath();
+ }
+ }
+
+ QString srcPath = src;
+ QString projPath = fileName();
+
+#if defined(Q_OS_WIN)
+ srcPath.replace( "\\", "/" );
+ projPath.replace( "\\", "/" );
+#endif
+
+ QStringList srcElems = srcPath.split( "/", QString::SkipEmptyParts );
+ QStringList projElems = projPath.split( "/", QString::SkipEmptyParts );
+
+ // remove project file element
+ projElems.removeLast();
+
+ // append source path elements
+ projElems.append( srcElems );
+ projElems.removeAll( "." );
+
+ // resolve ..
+ int pos;
+ while (( pos = projElems.indexOf( ".." ) ) > 0 )
+ {
+ // remove preceeding element and ..
+ projElems.removeAt( pos - 1 );
+ projElems.removeAt( pos - 1 );
+ }
+
+ return projElems.join( "/" );
+}
+
+// return the absolute or relative path to write it to the project file
+QString QgsProject::writePath( QString src ) const
+{
+ if ( readBoolEntry( "Paths", "/Absolute", true ) )
+ {
+ return src;
+ }
+
+ QString srcPath = src;
+ QString projPath = fileName();
+
+#if defined( Q_OS_WIN )
+ const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
+
+ srcPath.replace( "\\", "/" );
+
+ if ( srcPath.startsWith( "//" ) )
+ {
+ // keep UNC prefix
+ srcPath = "\\\\" + srcPath.mid( 2 );
+ }
+
+ projPath.replace( "\\", "/" );
+ if ( projPath.startsWith( "//" ) )
+ {
+ // keep UNC prefix
+ projPath = "\\\\" + projPath.mid( 2 );
+ }
+#else
+ const Qt::CaseSensitivity cs = Qt::CaseSensitive;
+#endif
+
+ QStringList projElems = projPath.split( "/", QString::SkipEmptyParts );
+ QStringList srcElems = srcPath.split( "/", QString::SkipEmptyParts );
+
+ // remove project file element
+ projElems.removeLast();
+
+ projElems.removeAll( "." );
+ srcElems.removeAll( "." );
+
+ // remove common part
+ int n = 0;
+ while ( srcElems.size() > 0 &&
+ projElems.size() > 0 &&
+ srcElems[0].compare( projElems[0], cs ) == 0 )
+ {
+ srcElems.removeFirst();
+ projElems.removeFirst();
+ n++;
+ }
+
+ if ( n == 0 )
+ {
+ // no common parts; might not even by a file
+ return src;
+ }
+
+ if ( projElems.size() > 0 )
+ {
+ // go up to the common directory
+ for ( int i = 0; i < projElems.size(); i++ )
+ {
+ srcElems.insert( 0, ".." );
+ }
+ }
+ else
+ {
+ // let it start with . nevertheless,
+ // so relative path always start with either ./ or ../
+ srcElems.insert( 0, "." );
+ }
+
+ return srcElems.join( "/" );
+}
Modified: trunk/qgis/src/core/qgsproject.h
===================================================================
--- trunk/qgis/src/core/qgsproject.h 2009-09-05 19:45:32 UTC (rev 11570)
+++ trunk/qgis/src/core/qgsproject.h 2009-09-05 19:49:10 UTC (rev 11571)
@@ -255,6 +255,15 @@
*/
void dumpProperties() const;
+
+ /** prepare a filename to save it to the project file
+ @note added in 1.3 */
+ QString writePath( QString filename ) const;
+
+ /** turn filename read from the project file to an absolute path
+ @note added in 1.3 */
+ QString readPath( QString filename ) const;
+
signals:
//! emitted when project is being read
More information about the QGIS-commit
mailing list