46 for (
const auto &resolver : customResolvers )
47 filename = resolver.second( filename );
49 if ( filename.isEmpty() )
52 QString src = filename;
53 if ( src.startsWith( QLatin1String(
"inbuilt:" ) ) )
59 if ( src.startsWith( QLatin1String(
"localized:" ) ) )
61 QStringList parts = src.split(
"|" );
64 if ( !parts[0].isEmpty() )
66 return parts.join(
"|" );
73 if ( src.startsWith( QLatin1String(
"attachment:" ) ) )
76 return QDir( mAttachmentDir ).absoluteFilePath( src.mid( 11 ) );
79 if ( mBaseFileName.isNull() )
86 if ( ! vsiPrefix.isEmpty() )
90 if ( src.startsWith( QLatin1String(
"/vsi" ), Qt::CaseInsensitive ) )
91 src.remove( 0, vsiPrefix.size() );
97 if ( !src.startsWith( QLatin1String(
"./" ) ) && !src.startsWith( QLatin1String(
"../" ) ) )
100 if ( src.startsWith(
"\\\\" ) ||
101 src.startsWith(
"//" ) ||
102 ( src[0].isLetter() && src[1] ==
':' ) )
105 return vsiPrefix + src;
111 return vsiPrefix + src;
120 const QFileInfo pfi( mBaseFileName );
121 const QString home = pfi.absolutePath();
122 if ( home.isEmpty() )
123 return vsiPrefix + src;
125 const QFileInfo fi( home +
'/' + src );
129 return vsiPrefix + src;
133 return vsiPrefix + fi.canonicalFilePath();
137 QString srcPath = src;
138 QString projPath = mBaseFileName;
140 if ( projPath.isEmpty() )
142 return vsiPrefix + src;
148 thread_local const QRegularExpression delimiterRe( R
"re(delimiter=([^&]+))re" );
149 const QRegularExpressionMatch match = delimiterRe.match( srcPath );
150 if ( match.hasMatch() )
152 const QString delimiter = match.captured( 0 ).replace(
'\\', QLatin1String(
"%5C" ) );
153 srcPath.replace( match.captured( 0 ), delimiter );
156 srcPath.replace(
'\\',
'/' );
157 projPath.replace(
'\\',
'/' );
159 bool uncPath = projPath.startsWith(
"//" );
163 projPath = QFileInfo( projPath ).absoluteFilePath();
165 const QStringList srcElems = srcPath.split(
'/', Qt::SkipEmptyParts );
166 QStringList projElems = projPath.split(
'/', Qt::SkipEmptyParts );
171 projElems.insert( 0,
"" );
172 projElems.insert( 0,
"" );
177 projElems.removeLast();
180 projElems << srcElems;
181 projElems.removeAll( QStringLiteral(
"." ) );
185 while ( ( pos = projElems.indexOf( QLatin1String(
".." ) ) ) > 0 )
188 projElems.removeAt( pos - 1 );
189 projElems.removeAt( pos - 1 );
192#if !defined(Q_OS_WIN)
194 projElems.prepend( QString() );
197 return vsiPrefix + projElems.join( QLatin1Char(
'/' ) );
209 const size_t prevCount = sCustomResolvers()->size();
210 sCustomResolvers()->erase( std::remove_if( sCustomResolvers()->begin(), sCustomResolvers()->end(), [
id]( std::pair< QString, std::function< QString(
const QString & ) > > &a )
212 return a.first == id;
213 } ), sCustomResolvers()->end() );
214 return prevCount != sCustomResolvers()->size();
226 const size_t prevCount = sCustomWriters()->size();
227 sCustomWriters()->erase( std::remove_if( sCustomWriters()->begin(), sCustomWriters()->end(), [
id]( std::pair< QString, std::function< QString(
const QString & ) > > &a )
229 return a.first == id;
230 } ), sCustomWriters()->end() );
231 return prevCount != sCustomWriters()->size();
243 if ( !localizedPath.isEmpty() )
244 return QStringLiteral(
"localized:" ) + localizedPath;
247 for (
const auto &writer : customWriters )
248 src = writer.second( src );
256 if ( !mAttachmentDir.isEmpty() && src.startsWith( mAttachmentDir ) )
259 return QStringLiteral(
"attachment:" ) + QFileInfo( src ).fileName();
262 if ( mBaseFileName.isEmpty() )
268 const QFileInfo pfi( QFileInfo( mBaseFileName ).path() );
269 QString projPath = pfi.canonicalFilePath();
273 if ( projPath.isEmpty() )
274 projPath = pfi.absoluteFilePath();
276 if ( projPath.isEmpty() )
282 const QUrl url { src };
283 QString srcPath { src };
286 if ( url.isLocalFile( ) )
288 srcPath = url.path();
289 urlQuery = url.query();
292 const QFileInfo srcFileInfo( srcPath );
293 if ( srcFileInfo.exists() )
294 srcPath = srcFileInfo.canonicalFilePath();
298 if ( ! vsiPrefix.isEmpty() )
300 srcPath.remove( 0, vsiPrefix.size() );
303#if defined( Q_OS_WIN )
304 const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
306 srcPath.replace(
'\\',
'/' );
308 if ( srcPath.startsWith(
"//" ) )
311 srcPath =
"\\\\" + srcPath.mid( 2 );
314 projPath.replace(
'\\',
'/' );
315 if ( projPath.startsWith(
"//" ) )
318 projPath =
"\\\\" + projPath.mid( 2 );
321 const Qt::CaseSensitivity cs = Qt::CaseSensitive;
324 QStringList projElems = projPath.split(
'/', Qt::SkipEmptyParts );
325 QStringList srcElems = srcPath.split(
'/', Qt::SkipEmptyParts );
327 projElems.removeAll( QStringLiteral(
"." ) );
328 srcElems.removeAll( QStringLiteral(
"." ) );
332 while ( !srcElems.isEmpty() &&
333 !projElems.isEmpty() &&
334 srcElems[0].compare( projElems[0], cs ) == 0 )
336 srcElems.removeFirst();
337 projElems.removeFirst();
347 if ( !projElems.isEmpty() )
350 for (
int i = 0; i < projElems.size(); i++ )
352 srcElems.insert( 0, QStringLiteral(
".." ) );
359 srcElems.insert( 0, QStringLiteral(
"." ) );
363 QString returnPath { vsiPrefix + srcElems.join( QLatin1Char(
'/' ) ) };
364 if ( ! urlQuery.isEmpty() )
366 returnPath.append(
'?' );
367 returnPath.append( urlQuery );