27 typedef std::vector< std::pair< QString, std::function< QString(
const QString & ) > > >
CustomResolvers;
32 : mBaseFileName( baseFileName ), mAttachmentDir( attachmentDir )
42 for (
const auto &resolver : customResolvers )
43 filename = resolver.second( filename );
45 if ( filename.isEmpty() )
48 QString src = filename;
49 if ( src.startsWith( QLatin1String(
"inbuilt:" ) ) )
55 if ( src.startsWith( QLatin1String(
"localized:" ) ) )
57 QStringList parts = src.split(
"|" );
60 if ( !parts[0].isEmpty() )
62 return parts.join(
"|" );
69 if ( src.startsWith( QLatin1String(
"attachment:" ) ) )
72 return QDir( mAttachmentDir ).absoluteFilePath( src.mid( 11 ) );
75 if ( mBaseFileName.isNull() )
82 if ( ! vsiPrefix.isEmpty() )
86 if ( src.startsWith( QLatin1String(
"/vsi" ), Qt::CaseInsensitive ) )
87 src.remove( 0, vsiPrefix.size() );
93 if ( !src.startsWith( QLatin1String(
"./" ) ) && !src.startsWith( QLatin1String(
"../" ) ) )
96 if ( src.startsWith(
"\\\\" ) ||
97 src.startsWith(
"//" ) ||
98 ( src[0].isLetter() && src[1] ==
':' ) )
101 return vsiPrefix + src;
107 return vsiPrefix + src;
116 const QFileInfo pfi( mBaseFileName );
117 const QString home = pfi.absolutePath();
118 if ( home.isEmpty() )
119 return vsiPrefix + src;
121 const QFileInfo fi( home +
'/' + src );
125 return vsiPrefix + src;
129 return vsiPrefix + fi.canonicalFilePath();
133 QString srcPath = src;
134 QString projPath = mBaseFileName;
136 if ( projPath.isEmpty() )
138 return vsiPrefix + src;
141 #if defined(Q_OS_WIN)
142 srcPath.replace(
'\\',
'/' );
143 projPath.replace(
'\\',
'/' );
145 bool uncPath = projPath.startsWith(
"//" );
149 projPath = QFileInfo( projPath ).absoluteFilePath();
151 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
152 QStringList srcElems = srcPath.split(
'/', QString::SkipEmptyParts );
153 QStringList projElems = projPath.split(
'/', QString::SkipEmptyParts );
155 const QStringList srcElems = srcPath.split(
'/', Qt::SkipEmptyParts );
156 QStringList projElems = projPath.split(
'/', Qt::SkipEmptyParts );
159 #if defined(Q_OS_WIN)
162 projElems.insert( 0,
"" );
163 projElems.insert( 0,
"" );
168 projElems.removeLast();
171 projElems << srcElems;
172 projElems.removeAll( QStringLiteral(
"." ) );
176 while ( ( pos = projElems.indexOf( QLatin1String(
".." ) ) ) > 0 )
179 projElems.removeAt( pos - 1 );
180 projElems.removeAt( pos - 1 );
183 #if !defined(Q_OS_WIN)
185 projElems.prepend( QString() );
188 return vsiPrefix + projElems.join( QLatin1Char(
'/' ) );
193 QString
id = QUuid::createUuid().toString();
194 sCustomResolvers()->emplace_back( std::make_pair(
id, processor ) );
200 const size_t prevCount = sCustomResolvers()->size();
201 sCustomResolvers()->erase( std::remove_if( sCustomResolvers()->begin(), sCustomResolvers()->end(), [
id]( std::pair< QString, std::function< QString(
const QString & ) > > &a )
203 return a.first == id;
204 } ), sCustomResolvers()->end() );
205 return prevCount != sCustomResolvers()->size();
210 QString
id = QUuid::createUuid().toString();
211 sCustomWriters()->emplace_back( std::make_pair(
id, writer ) );
217 const size_t prevCount = sCustomWriters->size();
218 sCustomWriters()->erase( std::remove_if( sCustomWriters->begin(), sCustomWriters->end(), [
id]( std::pair< QString, std::function< QString(
const QString & ) > > &a )
220 return a.first == id;
221 } ), sCustomWriters->end() );
222 return prevCount != sCustomWriters->size();
234 if ( !localizedPath.isEmpty() )
235 return QStringLiteral(
"localized:" ) + localizedPath;
238 for (
const auto &writer : customWriters )
239 src = writer.second( src );
247 if ( !mAttachmentDir.isEmpty() && src.startsWith( mAttachmentDir ) )
250 return QStringLiteral(
"attachment:" ) + QFileInfo( src ).fileName();
253 if ( mBaseFileName.isEmpty() )
259 const QFileInfo pfi( QFileInfo( mBaseFileName ).path() );
260 QString projPath = pfi.canonicalFilePath();
264 if ( projPath.isEmpty() )
265 projPath = pfi.absoluteFilePath();
267 if ( projPath.isEmpty() )
273 const QUrl url { src };
274 QString srcPath { src };
277 if ( url.isLocalFile( ) )
279 srcPath = url.path();
280 urlQuery = url.query();
283 const QFileInfo srcFileInfo( srcPath );
284 if ( srcFileInfo.exists() )
285 srcPath = srcFileInfo.canonicalFilePath();
289 if ( ! vsiPrefix.isEmpty() )
291 srcPath.remove( 0, vsiPrefix.size() );
294 #if defined( Q_OS_WIN )
295 const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
297 srcPath.replace(
'\\',
'/' );
299 if ( srcPath.startsWith(
"//" ) )
302 srcPath =
"\\\\" + srcPath.mid( 2 );
305 projPath.replace(
'\\',
'/' );
306 if ( projPath.startsWith(
"//" ) )
309 projPath =
"\\\\" + projPath.mid( 2 );
312 const Qt::CaseSensitivity cs = Qt::CaseSensitive;
315 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
316 QStringList projElems = projPath.split(
'/', QString::SkipEmptyParts );
317 QStringList srcElems = srcPath.split(
'/', QString::SkipEmptyParts );
319 QStringList projElems = projPath.split(
'/', Qt::SkipEmptyParts );
320 QStringList srcElems = srcPath.split(
'/', Qt::SkipEmptyParts );
323 projElems.removeAll( QStringLiteral(
"." ) );
324 srcElems.removeAll( QStringLiteral(
"." ) );
328 while ( !srcElems.isEmpty() &&
329 !projElems.isEmpty() &&
330 srcElems[0].compare( projElems[0], cs ) == 0 )
332 srcElems.removeFirst();
333 projElems.removeFirst();
343 if ( !projElems.isEmpty() )
346 for (
int i = 0; i < projElems.size(); i++ )
348 srcElems.insert( 0, QStringLiteral(
".." ) );
355 srcElems.insert( 0, QStringLiteral(
"." ) );
359 QString returnPath { vsiPrefix + srcElems.join( QLatin1Char(
'/' ) ) };
360 if ( ! urlQuery.isEmpty() )
362 returnPath.append(
'?' );
363 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.
static bool removePathWriter(const QString &id)
Removes the custom writer function with matching id.
static QString setPathWriter(const std::function< QString(const QString &filename)> &writer)
Sets a path writer function, which allows for manipulation of paths and data sources prior to writing...
QString qgsVsiPrefix(const QString &path)
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
std::vector< std::pair< QString, std::function< QString(const QString &) > > > CustomResolvers