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 );