66#include " asyncimageresponse.h"
77
88#include < QIcon>
9+ #include < QMimeDatabase>
910#include < QPainter>
1011#include < QSvgRenderer>
1112
1213#include " accountmanager.h"
1314
15+ using namespace Qt ::StringLiterals;
16+
1417AsyncImageResponse::AsyncImageResponse (const QString &id, const QSize &requestedSize)
1518{
1619 if (id.isEmpty ()) {
@@ -19,15 +22,15 @@ AsyncImageResponse::AsyncImageResponse(const QString &id, const QSize &requested
1922 }
2023
2124 auto actualId = id;
22- const auto idSplit = id.split (QStringLiteral ( " / " ) , Qt::SkipEmptyParts);
25+ const auto idSplit = id.split (' / ' _L1 , Qt::SkipEmptyParts);
2326 const auto color = QColor (idSplit.last ());
2427
2528 if (color.isValid ()) {
2629 _svgRecolor = color;
2730 actualId.remove (" /" % idSplit.last ());
2831 }
2932
30- _imagePaths = actualId.split (QLatin1Char ( ' ;' ) , Qt::SkipEmptyParts);
33+ _imagePaths = actualId.split (' ;' _L1 , Qt::SkipEmptyParts);
3134 _requestedImageSize = requestedSize;
3235
3336 if (_imagePaths.isEmpty ()) {
@@ -56,10 +59,10 @@ void AsyncImageResponse::processNextImage()
5659 }
5760
5861 const auto imagePath = _imagePaths.at (_index);
59- if (imagePath.startsWith (QStringLiteral ( " :/client" ) )) {
62+ if (imagePath.startsWith (u " :/client" _s )) {
6063 setImageAndEmitFinished (QIcon (imagePath).pixmap (_requestedImageSize).toImage ());
6164 return ;
62- } else if (imagePath.startsWith (QStringLiteral ( " :/fileicon" ) )) {
65+ } else if (imagePath.startsWith (u " :/fileicon" _s )) {
6366 const auto filePath = imagePath.mid (10 );
6467 const auto fileInfo = QFileInfo (filePath);
6568 setImageAndEmitFinished (_fileIconProvider.icon (fileInfo).pixmap (_requestedImageSize).toImage ());
@@ -83,7 +86,7 @@ void AsyncImageResponse::processNextImage()
8386 // for some reason trying to use `accountInRequestedServer` causes clang 21 to crash for me :(
8487 const auto accountQnam = accountInRequestedServer->networkAccessManager ();
8588 QMetaObject::invokeMethod (accountQnam, [this , accountInRequestedServer, iconUrl]() -> void {
86- const auto reply = accountInRequestedServer->sendRawRequest (QByteArrayLiteral ( " GET" ) , iconUrl);
89+ const auto reply = accountInRequestedServer->sendRawRequest (" GET" _ba , iconUrl);
8790 connect (reply, &QNetworkReply::finished, this , [this , reply]() -> void {
8891 QMetaObject::invokeMethod (this , [this , reply]() -> void {
8992 processNetworkReply (reply);
@@ -109,36 +112,42 @@ void AsyncImageResponse::processNetworkReply(QNetworkReply *reply)
109112 const QByteArray imageData = reply->readAll ();
110113 // server returns "[]" for some some file previews (have no idea why), so, we use another image
111114 // from the list if available
112- if (imageData.isEmpty () || imageData == QByteArrayLiteral ( " []" ) ) {
115+ if (imageData.isEmpty () || imageData == " []" _ba ) {
113116 processNextImage ();
114- } else {
115- if (imageData.startsWith (QByteArrayLiteral (" <svg" ))) {
116- // SVG image needs proper scaling, let's do it with QPainter and QSvgRenderer
117- QSvgRenderer svgRenderer;
118- if (svgRenderer.load (imageData)) {
119- QImage scaledSvg (_requestedImageSize, QImage::Format_ARGB32);
120- scaledSvg.fill (" transparent" );
121- QPainter painterForSvg (&scaledSvg);
122- svgRenderer.render (&painterForSvg);
123-
124- if (!_svgRecolor.isValid ()) {
125- setImageAndEmitFinished (scaledSvg);
126- return ;
127- }
128-
129- QImage image (_requestedImageSize, QImage::Format_ARGB32);
130- image.fill (_svgRecolor);
131- QPainter imagePainter (&image);
132- imagePainter.setCompositionMode (QPainter::CompositionMode_DestinationIn);
133- imagePainter.drawImage (0 , 0 , scaledSvg);
134- setImageAndEmitFinished (image);
135- return ;
136- } else {
137- processNextImage ();
138- }
139- } else {
140- setImageAndEmitFinished (QImage::fromData (imageData));
141- }
117+ return ;
118+ }
119+
120+ // Some graphics programs export SVGs that begin with `<?xml version="1.0" [...]` and/or include some comments after that (e.g.
121+ // `<!-- Generator: ...`), so we can't rely on just the response to start with `<svg`.
122+ if (const auto mimetype = QMimeDatabase ().mimeTypeForData (imageData);
123+ !(mimetype.isValid () && mimetype.inherits (" image/svg+xml" _L1))) {
124+ // Not an SVG: let's let QImage deal with the response.
125+ setImageAndEmitFinished (QImage::fromData (imageData).scaled (_requestedImageSize));
126+ return ;
127+ }
128+
129+ // SVG image needs proper scaling, let's do it with QPainter and QSvgRenderer
130+ QSvgRenderer svgRenderer;
131+ if (!svgRenderer.load (imageData)) {
132+ processNextImage ();
133+ return ;
134+ }
135+
136+ QImage scaledSvg (_requestedImageSize, QImage::Format_ARGB32);
137+ scaledSvg.fill (" transparent" );
138+ QPainter painterForSvg (&scaledSvg);
139+ svgRenderer.render (&painterForSvg);
140+
141+ if (!_svgRecolor.isValid ()) {
142+ setImageAndEmitFinished (scaledSvg);
143+ return ;
142144 }
145+
146+ QImage image (_requestedImageSize, QImage::Format_ARGB32);
147+ image.fill (_svgRecolor);
148+ QPainter imagePainter (&image);
149+ imagePainter.setCompositionMode (QPainter::CompositionMode_DestinationIn);
150+ imagePainter.drawImage (0 , 0 , scaledSvg);
151+ setImageAndEmitFinished (image);
143152}
144153
0 commit comments