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#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
166 QStringList srcElems = srcPath.split(
'/', QString::SkipEmptyParts );
167 QStringList projElems = projPath.split(
'/', QString::SkipEmptyParts );
169 const QStringList srcElems = srcPath.split(
'/', Qt::SkipEmptyParts );
170 QStringList projElems = projPath.split(
'/', Qt::SkipEmptyParts );
176 projElems.insert( 0,
"" );
177 projElems.insert( 0,
"" );
182 projElems.removeLast();
185 projElems << srcElems;
186 projElems.removeAll( QStringLiteral(
"." ) );
190 while ( ( pos = projElems.indexOf( QLatin1String(
".." ) ) ) > 0 )
193 projElems.removeAt( pos - 1 );
194 projElems.removeAt( pos - 1 );
197#if !defined(Q_OS_WIN)
199 projElems.prepend( QString() );
202 return vsiPrefix + projElems.join( QLatin1Char(
'/' ) );
214 const size_t prevCount = sCustomResolvers()->size();
215 sCustomResolvers()->erase( std::remove_if( sCustomResolvers()->begin(), sCustomResolvers()->end(), [
id]( std::pair< QString, std::function< QString(
const QString & ) > > &a )
217 return a.first == id;
218 } ), sCustomResolvers()->end() );
219 return prevCount != sCustomResolvers()->size();
231 const size_t prevCount = sCustomWriters->size();
232 sCustomWriters()->erase( std::remove_if( sCustomWriters->begin(), sCustomWriters->end(), [
id]( std::pair< QString, std::function< QString(
const QString & ) > > &a )
234 return a.first == id;
235 } ), sCustomWriters->end() );
236 return prevCount != sCustomWriters->size();
248 if ( !localizedPath.isEmpty() )
249 return QStringLiteral(
"localized:" ) + localizedPath;
252 for (
const auto &writer : customWriters )
253 src = writer.second( src );
261 if ( !mAttachmentDir.isEmpty() && src.startsWith( mAttachmentDir ) )
264 return QStringLiteral(
"attachment:" ) + QFileInfo( src ).fileName();
267 if ( mBaseFileName.isEmpty() )
273 const QFileInfo pfi( QFileInfo( mBaseFileName ).path() );
274 QString projPath = pfi.canonicalFilePath();
278 if ( projPath.isEmpty() )
279 projPath = pfi.absoluteFilePath();
281 if ( projPath.isEmpty() )
287 const QUrl url { src };
288 QString srcPath { src };
291 if ( url.isLocalFile( ) )
293 srcPath = url.path();
294 urlQuery = url.query();
297 const QFileInfo srcFileInfo( srcPath );
298 if ( srcFileInfo.exists() )
299 srcPath = srcFileInfo.canonicalFilePath();
303 if ( ! vsiPrefix.isEmpty() )
305 srcPath.remove( 0, vsiPrefix.size() );
308#if defined( Q_OS_WIN )
309 const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
311 srcPath.replace(
'\\',
'/' );
313 if ( srcPath.startsWith(
"//" ) )
316 srcPath =
"\\\\" + srcPath.mid( 2 );
319 projPath.replace(
'\\',
'/' );
320 if ( projPath.startsWith(
"//" ) )
323 projPath =
"\\\\" + projPath.mid( 2 );
326 const Qt::CaseSensitivity cs = Qt::CaseSensitive;
329#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
330 QStringList projElems = projPath.split(
'/', QString::SkipEmptyParts );
331 QStringList srcElems = srcPath.split(
'/', QString::SkipEmptyParts );
333 QStringList projElems = projPath.split(
'/', Qt::SkipEmptyParts );
334 QStringList srcElems = srcPath.split(
'/', Qt::SkipEmptyParts );
337 projElems.removeAll( QStringLiteral(
"." ) );
338 srcElems.removeAll( QStringLiteral(
"." ) );
342 while ( !srcElems.isEmpty() &&
343 !projElems.isEmpty() &&
344 srcElems[0].compare( projElems[0], cs ) == 0 )
346 srcElems.removeFirst();
347 projElems.removeFirst();
357 if ( !projElems.isEmpty() )
360 for (
int i = 0; i < projElems.size(); i++ )
362 srcElems.insert( 0, QStringLiteral(
".." ) );
369 srcElems.insert( 0, QStringLiteral(
"." ) );
373 QString returnPath { vsiPrefix + srcElems.join( QLatin1Char(
'/' ) ) };
374 if ( ! urlQuery.isEmpty() )
376 returnPath.append(
'?' );
377 returnPath.append( urlQuery );