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