mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
improve relative path support
git-svn-id: http://svn.osgeo.org/qgis/trunk@11571 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
parent
a211d66d8f
commit
ddd64be82b
@ -223,6 +223,14 @@ public:
|
||||
*/
|
||||
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
|
||||
|
@ -152,20 +152,7 @@ bool QgsMapLayer::readXML( QDomNode & layer_node )
|
||||
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 );
|
||||
|
||||
if ( fi.exists() )
|
||||
{
|
||||
mDataSource = fi.canonicalFilePath();
|
||||
}
|
||||
}
|
||||
}
|
||||
mDataSource = QgsProject::instance()->readPath( mDataSource );
|
||||
|
||||
// Set the CRS from project file, asking the user if necessary.
|
||||
// Make it the saved CRS to have WMS layer projected correctly.
|
||||
@ -280,20 +267,8 @@ bool QgsMapLayer::writeXML( QDomNode & layer_node, QDomDocument & document )
|
||||
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 );
|
||||
|
@ -1300,3 +1300,154 @@ void QgsProject::dumpProperties() const
|
||||
{
|
||||
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( "/" );
|
||||
}
|
||||
|
@ -255,6 +255,15 @@ class CORE_EXPORT QgsProject : public QObject
|
||||
*/
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user