26 typedef std::vector< std::pair< QString, std::function< QString(
const QString & ) > > >
CustomResolvers;
30 : mBaseFileName( baseFileName )
40 for (
const auto &resolver : customResolvers )
41 filename = resolver.second( filename );
43 if ( filename.isEmpty() )
46 QString src = filename;
47 if ( src.startsWith( QLatin1String(
"inbuilt:" ) ) )
53 if ( src.startsWith( QLatin1String(
"localized:" ) ) )
59 if ( mBaseFileName.isNull() )
66 if ( ! vsiPrefix.isEmpty() )
70 if ( src.startsWith( QLatin1String(
"/vsi" ), Qt::CaseInsensitive ) )
71 src.remove( 0, vsiPrefix.size() );
77 if ( !src.startsWith( QLatin1String(
"./" ) ) && !src.startsWith( QLatin1String(
"../" ) ) )
80 if ( src.startsWith(
"\\\\" ) ||
81 src.startsWith(
"//" ) ||
82 ( src[0].isLetter() && src[1] ==
':' ) )
85 return vsiPrefix + src;
91 return vsiPrefix + src;
100 QFileInfo pfi( mBaseFileName );
101 QString home = pfi.absolutePath();
102 if ( home.isEmpty() )
103 return vsiPrefix + src;
105 QFileInfo fi( home +
'/' + src );
109 return vsiPrefix + src;
113 return vsiPrefix + fi.canonicalFilePath();
117 QString srcPath = src;
118 QString projPath = mBaseFileName;
120 if ( projPath.isEmpty() )
122 return vsiPrefix + src;
125 #if defined(Q_OS_WIN)
126 srcPath.replace(
'\\',
'/' );
127 projPath.replace(
'\\',
'/' );
129 bool uncPath = projPath.startsWith(
"//" );
133 projPath = QFileInfo( projPath ).absoluteFilePath();
135 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
136 QStringList srcElems = srcPath.split(
'/', QString::SkipEmptyParts );
137 QStringList projElems = projPath.split(
'/', QString::SkipEmptyParts );
139 QStringList srcElems = srcPath.split(
'/', Qt::SkipEmptyParts );
140 QStringList projElems = projPath.split(
'/', Qt::SkipEmptyParts );
143 #if defined(Q_OS_WIN)
146 projElems.insert( 0,
"" );
147 projElems.insert( 0,
"" );
152 projElems.removeLast();
155 projElems << srcElems;
156 projElems.removeAll( QStringLiteral(
"." ) );
160 while ( ( pos = projElems.indexOf( QLatin1String(
".." ) ) ) > 0 )
163 projElems.removeAt( pos - 1 );
164 projElems.removeAt( pos - 1 );
167 #if !defined(Q_OS_WIN)
169 projElems.prepend( QString() );
172 return vsiPrefix + projElems.join( QLatin1Char(
'/' ) );
177 QString
id = QUuid::createUuid().toString();
178 sCustomResolvers()->emplace_back( std::make_pair(
id, processor ) );
184 const size_t prevCount = sCustomResolvers()->size();
185 sCustomResolvers()->erase( std::remove_if( sCustomResolvers()->begin(), sCustomResolvers()->end(), [
id]( std::pair< QString, std::function< QString(
const QString & ) > > &a )
187 return a.first == id;
188 } ), sCustomResolvers()->end() );
189 return prevCount != sCustomResolvers()->size();
200 if ( !localizedPath.isEmpty() )
201 return QStringLiteral(
"localized:" ) + localizedPath;
209 if ( mBaseFileName.isEmpty() )
215 QFileInfo pfi( QFileInfo( mBaseFileName ).path() );
216 QString projPath = pfi.canonicalFilePath();
220 if ( projPath.isEmpty() )
221 projPath = pfi.absoluteFilePath();
223 if ( projPath.isEmpty() )
230 QString srcPath { src };
233 if ( url.isLocalFile( ) )
235 srcPath = url.path();
236 urlQuery = url.query();
239 QFileInfo srcFileInfo( srcPath );
240 if ( srcFileInfo.exists() )
241 srcPath = srcFileInfo.canonicalFilePath();
245 if ( ! vsiPrefix.isEmpty() )
247 srcPath.remove( 0, vsiPrefix.size() );
250 #if defined( Q_OS_WIN )
251 const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
253 srcPath.replace(
'\\',
'/' );
255 if ( srcPath.startsWith(
"//" ) )
258 srcPath =
"\\\\" + srcPath.mid( 2 );
261 projPath.replace(
'\\',
'/' );
262 if ( projPath.startsWith(
"//" ) )
265 projPath =
"\\\\" + projPath.mid( 2 );
268 const Qt::CaseSensitivity cs = Qt::CaseSensitive;
271 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
272 QStringList projElems = projPath.split(
'/', QString::SkipEmptyParts );
273 QStringList srcElems = srcPath.split(
'/', QString::SkipEmptyParts );
275 QStringList projElems = projPath.split(
'/', Qt::SkipEmptyParts );
276 QStringList srcElems = srcPath.split(
'/', Qt::SkipEmptyParts );
279 projElems.removeAll( QStringLiteral(
"." ) );
280 srcElems.removeAll( QStringLiteral(
"." ) );
284 while ( !srcElems.isEmpty() &&
285 !projElems.isEmpty() &&
286 srcElems[0].compare( projElems[0], cs ) == 0 )
288 srcElems.removeFirst();
289 projElems.removeFirst();
299 if ( !projElems.isEmpty() )
302 for (
int i = 0; i < projElems.size(); i++ )
304 srcElems.insert( 0, QStringLiteral(
".." ) );
311 srcElems.insert( 0, QStringLiteral(
"." ) );
315 QString returnPath { vsiPrefix + srcElems.join( QLatin1Char(
'/' ) ) };
316 if ( ! urlQuery.isEmpty() )
318 returnPath.append(
'?' );
319 returnPath.append( urlQuery );
static QString pkgDataPath()
Returns the common root path of all application data directories.
static QgsLocalizedDataPathRegistry * localizedDataPathRegistry()
Returns the registry of data repositories These are used as paths for basemaps, logos,...
QString globalPath(const QString &localizedPath) const
Returns the global path if the file has been found in one of the paths, an empty string otherwise.
QString localizedPath(const QString &globalPath) const
Returns the localized path if the file has been found in one of the path, an empty string otherwise.
Resolves relative paths into absolute paths and vice versa.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
static bool removePathPreprocessor(const QString &id)
Removes the custom pre-processor function with matching id.
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.
QString qgsVsiPrefix(const QString &path)
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
std::vector< std::pair< QString, std::function< QString(const QString &) > > > CustomResolvers