45 for (
const auto &resolver : customResolvers )
46 filename = resolver.second( filename );
48 if ( filename.isEmpty() )
51 QString src = filename;
52 if ( src.startsWith( QLatin1String(
"inbuilt:" ) ) )
58 if ( src.startsWith( QLatin1String(
"localized:" ) ) )
60 QStringList parts = src.split(
"|" );
63 if ( !parts[0].isEmpty() )
65 return parts.join(
"|" );
72 if ( src.startsWith( QLatin1String(
"attachment:" ) ) )
75 return QDir( mAttachmentDir ).absoluteFilePath( src.mid( 11 ) );
78 if ( mBaseFileName.isNull() )
85 if ( ! vsiPrefix.isEmpty() )
89 if ( src.startsWith( QLatin1String(
"/vsi" ), Qt::CaseInsensitive ) )
90 src.remove( 0, vsiPrefix.size() );
96 if ( !src.startsWith( QLatin1String(
"./" ) ) && !src.startsWith( QLatin1String(
"../" ) ) )
99 if ( src.startsWith(
"\\\\" ) ||
100 src.startsWith(
"//" ) ||
101 ( src[0].isLetter() && src[1] ==
':' ) )
104 return vsiPrefix + src;
110 return vsiPrefix + src;
119 const QFileInfo pfi( mBaseFileName );
120 const QString home = pfi.absolutePath();
121 if ( home.isEmpty() )
122 return vsiPrefix + src;
124 const QFileInfo fi( home +
'/' + src );
128 return vsiPrefix + src;
132 return vsiPrefix + fi.canonicalFilePath();
136 QString srcPath = src;
137 QString projPath = mBaseFileName;
139 if ( projPath.isEmpty() )
141 return vsiPrefix + src;
147 thread_local const QRegularExpression delimiterRe( R
"re(delimiter=([^&]+))re" );
148 const QRegularExpressionMatch match = delimiterRe.match( srcPath );
149 if ( match.hasMatch() )
151 const QString delimiter = match.captured( 0 ).replace(
'\\', QStringLiteral(
"%5C" ) );
152 srcPath.replace( match.captured( 0 ), delimiter );
155 srcPath.replace(
'\\',
'/' );
156 projPath.replace(
'\\',
'/' );
158 bool uncPath = projPath.startsWith(
"//" );
162 projPath = QFileInfo( projPath ).absoluteFilePath();
164#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
165 QStringList srcElems = srcPath.split(
'/', QString::SkipEmptyParts );
166 QStringList projElems = projPath.split(
'/', QString::SkipEmptyParts );
168 const QStringList srcElems = srcPath.split(
'/', Qt::SkipEmptyParts );
169 QStringList projElems = projPath.split(
'/', Qt::SkipEmptyParts );
175 projElems.insert( 0,
"" );
176 projElems.insert( 0,
"" );
181 projElems.removeLast();
184 projElems << srcElems;
185 projElems.removeAll( QStringLiteral(
"." ) );
189 while ( ( pos = projElems.indexOf( QLatin1String(
".." ) ) ) > 0 )
192 projElems.removeAt( pos - 1 );
193 projElems.removeAt( pos - 1 );
196#if !defined(Q_OS_WIN)
198 projElems.prepend( QString() );
201 return vsiPrefix + projElems.join( QLatin1Char(
'/' ) );
213 const size_t prevCount = sCustomResolvers()->size();
214 sCustomResolvers()->erase( std::remove_if( sCustomResolvers()->begin(), sCustomResolvers()->end(), [
id]( std::pair< QString, std::function< QString(
const QString & ) > > &a )
216 return a.first == id;
217 } ), sCustomResolvers()->end() );
218 return prevCount != sCustomResolvers()->size();
230 const size_t prevCount = sCustomWriters->size();
231 sCustomWriters()->erase( std::remove_if( sCustomWriters->begin(), sCustomWriters->end(), [
id]( std::pair< QString, std::function< QString(
const QString & ) > > &a )
233 return a.first == id;
234 } ), sCustomWriters->end() );
235 return prevCount != sCustomWriters->size();
247 if ( !localizedPath.isEmpty() )
248 return QStringLiteral(
"localized:" ) + localizedPath;
251 for (
const auto &writer : customWriters )
252 src = writer.second( src );
260 if ( !mAttachmentDir.isEmpty() && src.startsWith( mAttachmentDir ) )
263 return QStringLiteral(
"attachment:" ) + QFileInfo( src ).fileName();
266 if ( mBaseFileName.isEmpty() )
272 const QFileInfo pfi( QFileInfo( mBaseFileName ).path() );
273 QString projPath = pfi.canonicalFilePath();
277 if ( projPath.isEmpty() )
278 projPath = pfi.absoluteFilePath();
280 if ( projPath.isEmpty() )
286 const QUrl url { src };
287 QString srcPath { src };
290 if ( url.isLocalFile( ) )
292 srcPath = url.path();
293 urlQuery = url.query();
296 const QFileInfo srcFileInfo( srcPath );
297 if ( srcFileInfo.exists() )
298 srcPath = srcFileInfo.canonicalFilePath();
302 if ( ! vsiPrefix.isEmpty() )
304 srcPath.remove( 0, vsiPrefix.size() );
307#if defined( Q_OS_WIN )
308 const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
310 srcPath.replace(
'\\',
'/' );
312 if ( srcPath.startsWith(
"//" ) )
315 srcPath =
"\\\\" + srcPath.mid( 2 );
318 projPath.replace(
'\\',
'/' );
319 if ( projPath.startsWith(
"//" ) )
322 projPath =
"\\\\" + projPath.mid( 2 );
325 const Qt::CaseSensitivity cs = Qt::CaseSensitive;
328#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
329 QStringList projElems = projPath.split(
'/', QString::SkipEmptyParts );
330 QStringList srcElems = srcPath.split(
'/', QString::SkipEmptyParts );
332 QStringList projElems = projPath.split(
'/', Qt::SkipEmptyParts );
333 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 );