24 std::vector< std::pair< QString, std::function< QString( const QString & ) > > > QgsPathResolver::sCustomResolvers;
27 : mBaseFileName( baseFileName )
36 for (
const auto &resolver : sCustomResolvers )
37 filename = resolver.second( filename );
39 if ( filename.isEmpty() )
42 QString src = filename;
43 if ( src.startsWith( QLatin1String(
"inbuilt:" ) ) )
49 if ( mBaseFileName.isNull() )
56 if ( ! vsiPrefix.isEmpty() )
60 if ( src.startsWith( QLatin1String(
"/vsi" ), Qt::CaseInsensitive ) )
61 src.remove( 0, vsiPrefix.size() );
67 if ( !src.startsWith( QLatin1String(
"./" ) ) && !src.startsWith( QLatin1String(
"../" ) ) )
70 if ( src.startsWith(
"\\\\" ) ||
71 src.startsWith(
"//" ) ||
72 ( src[0].isLetter() && src[1] ==
':' ) )
75 return vsiPrefix + src;
81 return vsiPrefix + src;
90 QFileInfo pfi( mBaseFileName );
91 QString home = pfi.absolutePath();
93 return vsiPrefix + src;
95 QFileInfo fi( home +
'/' + src );
99 return vsiPrefix + src;
103 return vsiPrefix + fi.canonicalFilePath();
107 QString srcPath = src;
108 QString projPath = mBaseFileName;
110 if ( projPath.isEmpty() )
112 return vsiPrefix + src;
115 #if defined(Q_OS_WIN) 116 srcPath.replace(
'\\',
'/' );
117 projPath.replace(
'\\',
'/' );
119 bool uncPath = projPath.startsWith(
"//" );
122 QStringList srcElems = srcPath.split(
'/', QString::SkipEmptyParts );
123 QStringList projElems = projPath.split(
'/', QString::SkipEmptyParts );
125 #if defined(Q_OS_WIN) 128 projElems.insert( 0,
"" );
129 projElems.insert( 0,
"" );
134 projElems.removeLast();
137 projElems << srcElems;
138 projElems.removeAll( QStringLiteral(
"." ) );
142 while ( ( pos = projElems.indexOf( QStringLiteral(
".." ) ) ) > 0 )
145 projElems.removeAt( pos - 1 );
146 projElems.removeAt( pos - 1 );
149 #if !defined(Q_OS_WIN) 151 projElems.prepend( QString() );
154 return vsiPrefix + projElems.join( QStringLiteral(
"/" ) );
159 QString
id = QUuid::createUuid().toString();
160 sCustomResolvers.emplace_back( std::make_pair(
id, processor ) );
166 const size_t prevCount = sCustomResolvers.size();
167 sCustomResolvers.erase( std::remove_if( sCustomResolvers.begin(), sCustomResolvers.end(), [id]( std::pair< QString, std::function< QString( const QString & ) > > &a )
169 return a.first == id;
170 } ), sCustomResolvers.end() );
171 return prevCount != sCustomResolvers.size();
187 if ( mBaseFileName.isEmpty() )
193 QFileInfo pfi( QFileInfo( mBaseFileName ).path() );
194 QString projPath = pfi.canonicalFilePath();
198 if ( projPath.isEmpty() )
199 projPath = pfi.absoluteFilePath();
201 if ( projPath.isEmpty() )
208 QString srcPath { src };
211 if ( url.isLocalFile( ) )
213 srcPath = url.path();
214 urlQuery = url.query();
217 QFileInfo srcFileInfo( srcPath );
218 if ( srcFileInfo.exists() )
219 srcPath = srcFileInfo.canonicalFilePath();
223 if ( ! vsiPrefix.isEmpty() )
225 srcPath.remove( 0, vsiPrefix.size() );
228 #if defined( Q_OS_WIN ) 229 const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
231 srcPath.replace(
'\\',
'/' );
233 if ( srcPath.startsWith(
"//" ) )
236 srcPath =
"\\\\" + srcPath.mid( 2 );
239 projPath.replace(
'\\',
'/' );
240 if ( projPath.startsWith(
"//" ) )
243 projPath =
"\\\\" + projPath.mid( 2 );
246 const Qt::CaseSensitivity cs = Qt::CaseSensitive;
249 QStringList projElems = projPath.split(
'/', QString::SkipEmptyParts );
250 QStringList srcElems = srcPath.split(
'/', QString::SkipEmptyParts );
252 projElems.removeAll( QStringLiteral(
"." ) );
253 srcElems.removeAll( QStringLiteral(
"." ) );
257 while ( !srcElems.isEmpty() &&
258 !projElems.isEmpty() &&
259 srcElems[0].compare( projElems[0], cs ) == 0 )
261 srcElems.removeFirst();
262 projElems.removeFirst();
272 if ( !projElems.isEmpty() )
275 for (
int i = 0; i < projElems.size(); i++ )
277 srcElems.insert( 0, QStringLiteral(
".." ) );
284 srcElems.insert( 0, QStringLiteral(
"." ) );
288 QString returnPath { vsiPrefix + srcElems.join( QStringLiteral(
"/" ) ) };
289 if ( ! urlQuery.isEmpty() )
291 returnPath.append(
'?' );
292 returnPath.append( urlQuery );
static QString setPathPreprocessor(const std::function< QString(const QString &filename)> &processor)
Sets a path pre-processor function, which allows for manipulation of paths and data sources prior to ...
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
static bool removePathPreprocessor(const QString &id)
Removes the custom pre-processor function with matching id.
static QString pkgDataPath()
Returns the common root path of all application data directories.
QString qgsVsiPrefix(const QString &path)
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
QgsPathResolver(const QString &baseFileName=QString())
Initialize path resolver with a base filename. Null filename means no conversion between relative/abs...