47 for (
const auto &resolver : customResolvers )
48 filename = resolver.second( filename );
50 if ( filename.isEmpty() )
53 QString src = filename;
54 if ( src.startsWith( QLatin1String(
"inbuilt:" ) ) )
60 if ( src.startsWith( QLatin1String(
"localized:" ) ) )
62 QStringList parts = src.split(
"|" );
65 if ( !parts[0].isEmpty() )
67 return parts.join(
"|" );
74 if ( src.startsWith( QLatin1String(
"attachment:" ) ) )
77 return QDir( mAttachmentDir ).absoluteFilePath( src.mid( 11 ) );
80 if ( mBaseFileName.isNull() )
87 if ( ! vsiPrefix.isEmpty() )
91 if ( src.startsWith( QLatin1String(
"/vsi" ), Qt::CaseInsensitive ) )
92 src.remove( 0, vsiPrefix.size() );
98 if ( !src.startsWith( QLatin1String(
"./" ) ) && !src.startsWith( QLatin1String(
"../" ) ) )
101 if ( src.startsWith(
"\\\\" ) ||
102 src.startsWith(
"//" ) ||
103 ( src[0].isLetter() && src[1] ==
':' ) )
106 return vsiPrefix + src;
112 return vsiPrefix + src;
121 const QFileInfo pfi( mBaseFileName );
122 const QString home = pfi.absolutePath();
123 if ( home.isEmpty() )
124 return vsiPrefix + src;
126 const QFileInfo fi( home +
'/' + src );
130 return vsiPrefix + src;
134 return vsiPrefix + QDir::cleanPath( fi.absoluteFilePath() );
138 QString srcPath = src;
139 QString projPath = mBaseFileName;
141 if ( projPath.isEmpty() )
143 return vsiPrefix + src;
149 thread_local const QRegularExpression delimiterRe( R
"re(delimiter=([^&]+))re" );
150 const QRegularExpressionMatch match = delimiterRe.match( srcPath );
151 if ( match.hasMatch() )
153 const QString delimiter = match.captured( 0 ).replace(
'\\', QLatin1String(
"%5C" ) );
154 srcPath.replace( match.captured( 0 ), delimiter );
157 srcPath.replace(
'\\',
'/' );
158 projPath.replace(
'\\',
'/' );
160 bool uncPath = projPath.startsWith(
"//" );
164 projPath = QFileInfo( projPath ).absoluteFilePath();
166 const QStringList srcElems = srcPath.split(
'/', Qt::SkipEmptyParts );
167 QStringList projElems = projPath.split(
'/', Qt::SkipEmptyParts );
172 projElems.insert( 0,
"" );
173 projElems.insert( 0,
"" );
178 projElems.removeLast();
181 projElems << srcElems;
182 projElems.removeAll( QStringLiteral(
"." ) );
186 while ( ( pos = projElems.indexOf( QLatin1String(
".." ) ) ) > 0 )
189 projElems.removeAt( pos - 1 );
190 projElems.removeAt( pos - 1 );
193#if !defined(Q_OS_WIN)
195 projElems.prepend( QString() );
198 return vsiPrefix + projElems.join( QLatin1Char(
'/' ) );
210 const size_t prevCount = sCustomResolvers()->size();
211 sCustomResolvers()->erase( std::remove_if( sCustomResolvers()->begin(), sCustomResolvers()->end(), [
id]( std::pair< QString, std::function< QString(
const QString & ) > > &a )
213 return a.first == id;
214 } ), sCustomResolvers()->end() );
215 return prevCount != sCustomResolvers()->size();
227 const size_t prevCount = sCustomWriters()->size();
228 sCustomWriters()->erase( std::remove_if( sCustomWriters()->begin(), sCustomWriters()->end(), [
id]( std::pair< QString, std::function< QString(
const QString & ) > > &a )
230 return a.first == id;
231 } ), sCustomWriters()->end() );
232 return prevCount != sCustomWriters()->size();
244 if ( !localizedPath.isEmpty() )
245 return QStringLiteral(
"localized:" ) + localizedPath;
248 for (
const auto &writer : customWriters )
249 src = writer.second( src );
257 if ( !mAttachmentDir.isEmpty() && src.startsWith( mAttachmentDir ) )
260 return QStringLiteral(
"attachment:" ) + QFileInfo( src ).fileName();
263 if ( mBaseFileName.isEmpty() )
269 const QFileInfo pfi( QFileInfo( mBaseFileName ).path() );
271 QString projPath = pfi.absoluteFilePath();
275 if ( projPath.isEmpty() )
276 projPath = pfi.absoluteFilePath();
278 if ( projPath.isEmpty() )
284 const QUrl url { src };
285 QString srcPath { src };
288 if ( url.isLocalFile( ) )
290 srcPath = url.path();
291 urlQuery = url.query();
294 const QFileInfo srcFileInfo( srcPath );
297 if ( !srcFileInfo.isAbsolute() )
301 if ( srcFileInfo.exists() )
303 srcPath = QDir::cleanPath( srcFileInfo.absoluteFilePath() );
307 if ( ! vsiPrefix.isEmpty() )
309 srcPath.remove( 0, vsiPrefix.size() );
312#if defined( Q_OS_WIN )
313 const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
315 srcPath.replace(
'\\',
'/' );
317 if ( srcPath.startsWith(
"//" ) )
320 srcPath =
"\\\\" + srcPath.mid( 2 );
323 projPath.replace(
'\\',
'/' );
324 if ( projPath.startsWith(
"//" ) )
327 projPath =
"\\\\" + projPath.mid( 2 );
330 const Qt::CaseSensitivity cs = Qt::CaseSensitive;
333 QStringList projElems = projPath.split(
'/', Qt::SkipEmptyParts );
334 QStringList srcElems = srcPath.split(
'/', Qt::SkipEmptyParts );
336 projElems.removeAll( QStringLiteral(
"." ) );
337 srcElems.removeAll( QStringLiteral(
"." ) );
341 while ( !srcElems.isEmpty() &&
342 !projElems.isEmpty() &&
343 srcElems[0].compare( projElems[0], cs ) == 0 )
345 srcElems.removeFirst();
346 projElems.removeFirst();
356 if ( !projElems.isEmpty() )
359 for (
int i = 0; i < projElems.size(); i++ )
361 srcElems.insert( 0, QStringLiteral(
".." ) );
368 srcElems.insert( 0, QStringLiteral(
"." ) );
372 QString returnPath { vsiPrefix + srcElems.join( QLatin1Char(
'/' ) ) };
373 if ( ! urlQuery.isEmpty() )
375 returnPath.append(
'?' );
376 returnPath.append( urlQuery );