Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 43 additions & 34 deletions src/gui/tray/asyncimageresponse.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/*
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: GPL-2.0-or-later
Expand All @@ -6,12 +6,15 @@
#include "asyncimageresponse.h"

#include <QIcon>
#include <QMimeDatabase>
#include <QPainter>
#include <QSvgRenderer>

#include "accountmanager.h"

using namespace Qt::StringLiterals;

AsyncImageResponse::AsyncImageResponse(const QString &id, const QSize &requestedSize)

Check warning on line 17 in src/gui/tray/asyncimageresponse.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/tray/asyncimageresponse.cpp:17:55 [readability-identifier-length]

parameter name 'id' is too short, expected at least 3 characters

Check warning on line 17 in src/gui/tray/asyncimageresponse.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/tray/asyncimageresponse.cpp:17:40 [bugprone-easily-swappable-parameters]

2 adjacent parameters of 'AsyncImageResponse' of similar type ('const int &') are easily swapped by mistake

Check warning on line 17 in src/gui/tray/asyncimageresponse.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/tray/asyncimageresponse.cpp:17:1 [cppcoreguidelines-pro-type-member-init]

constructor does not initialize these fields: _image, _imagePaths, _requestedImageSize, _svgRecolor, _fileIconProvider
{
if (id.isEmpty()) {
setImageAndEmitFinished();
Expand All @@ -19,15 +22,15 @@
}

auto actualId = id;
const auto idSplit = id.split(QStringLiteral("/"), Qt::SkipEmptyParts);
const auto idSplit = id.split('/'_L1, Qt::SkipEmptyParts);
const auto color = QColor(idSplit.last());

if(color.isValid()) {
_svgRecolor = color;
actualId.remove("/" % idSplit.last());
}

_imagePaths = actualId.split(QLatin1Char(';'), Qt::SkipEmptyParts);
_imagePaths = actualId.split(';'_L1, Qt::SkipEmptyParts);
_requestedImageSize = requestedSize;

if (_imagePaths.isEmpty()) {
Expand Down Expand Up @@ -56,10 +59,10 @@
}

const auto imagePath = _imagePaths.at(_index);
if (imagePath.startsWith(QStringLiteral(":/client"))) {
if (imagePath.startsWith(u":/client"_s)) {
setImageAndEmitFinished(QIcon(imagePath).pixmap(_requestedImageSize).toImage());
return;
} else if (imagePath.startsWith(QStringLiteral(":/fileicon"))) {
} else if (imagePath.startsWith(u":/fileicon"_s)) {

Check warning on line 65 in src/gui/tray/asyncimageresponse.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/tray/asyncimageresponse.cpp:65:7 [readability-else-after-return]

do not use 'else' after 'return'
const auto filePath = imagePath.mid(10);
const auto fileInfo = QFileInfo(filePath);
setImageAndEmitFinished(_fileIconProvider.icon(fileInfo).pixmap(_requestedImageSize).toImage());
Expand All @@ -83,7 +86,7 @@
// for some reason trying to use `accountInRequestedServer` causes clang 21 to crash for me :(
const auto accountQnam = accountInRequestedServer->networkAccessManager();
QMetaObject::invokeMethod(accountQnam, [this, accountInRequestedServer, iconUrl]() -> void {
const auto reply = accountInRequestedServer->sendRawRequest(QByteArrayLiteral("GET"), iconUrl);
const auto reply = accountInRequestedServer->sendRawRequest("GET"_ba, iconUrl);
connect(reply, &QNetworkReply::finished, this, [this, reply]() -> void {
QMetaObject::invokeMethod(this, [this, reply]() -> void {
processNetworkReply(reply);
Expand All @@ -109,36 +112,42 @@
const QByteArray imageData = reply->readAll();
// server returns "[]" for some some file previews (have no idea why), so, we use another image
// from the list if available
if (imageData.isEmpty() || imageData == QByteArrayLiteral("[]")) {
if (imageData.isEmpty() || imageData == "[]"_ba) {
processNextImage();
} else {
if (imageData.startsWith(QByteArrayLiteral("<svg"))) {
// SVG image needs proper scaling, let's do it with QPainter and QSvgRenderer
QSvgRenderer svgRenderer;
if (svgRenderer.load(imageData)) {
QImage scaledSvg(_requestedImageSize, QImage::Format_ARGB32);
scaledSvg.fill("transparent");
QPainter painterForSvg(&scaledSvg);
svgRenderer.render(&painterForSvg);

if(!_svgRecolor.isValid()) {
setImageAndEmitFinished(scaledSvg);
return;
}

QImage image(_requestedImageSize, QImage::Format_ARGB32);
image.fill(_svgRecolor);
QPainter imagePainter(&image);
imagePainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
imagePainter.drawImage(0, 0, scaledSvg);
setImageAndEmitFinished(image);
return;
} else {
processNextImage();
}
} else {
setImageAndEmitFinished(QImage::fromData(imageData));
}
return;
}

// Some graphics programs export SVGs that begin with `<?xml version="1.0" [...]` and/or include some comments after that (e.g.
// `<!-- Generator: ...`), so we can't rely on just the response to start with `<svg`.
if (const auto mimetype = QMimeDatabase().mimeTypeForData(imageData);
!(mimetype.isValid() && mimetype.inherits("image/svg+xml"_L1))) {
// Not an SVG: let's let QImage deal with the response.
setImageAndEmitFinished(QImage::fromData(imageData).scaled(_requestedImageSize));
return;
}

// SVG image needs proper scaling, let's do it with QPainter and QSvgRenderer
QSvgRenderer svgRenderer;

Check warning on line 130 in src/gui/tray/asyncimageresponse.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/tray/asyncimageresponse.cpp:130:18 [cppcoreguidelines-init-variables]

variable 'svgRenderer' is not initialized
if (!svgRenderer.load(imageData)) {
processNextImage();
return;
}

QImage scaledSvg(_requestedImageSize, QImage::Format_ARGB32);

Check warning on line 136 in src/gui/tray/asyncimageresponse.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/tray/asyncimageresponse.cpp:136:12 [cppcoreguidelines-init-variables]

variable 'scaledSvg' is not initialized
scaledSvg.fill("transparent");
QPainter painterForSvg(&scaledSvg);

Check warning on line 138 in src/gui/tray/asyncimageresponse.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/tray/asyncimageresponse.cpp:138:14 [cppcoreguidelines-init-variables]

variable 'painterForSvg' is not initialized
svgRenderer.render(&painterForSvg);

if (!_svgRecolor.isValid()) {
setImageAndEmitFinished(scaledSvg);
return;
}

QImage image(_requestedImageSize, QImage::Format_ARGB32);

Check warning on line 146 in src/gui/tray/asyncimageresponse.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/tray/asyncimageresponse.cpp:146:12 [cppcoreguidelines-init-variables]

variable 'image' is not initialized
image.fill(_svgRecolor);
QPainter imagePainter(&image);

Check warning on line 148 in src/gui/tray/asyncimageresponse.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/tray/asyncimageresponse.cpp:148:14 [cppcoreguidelines-init-variables]

variable 'imagePainter' is not initialized
imagePainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
imagePainter.drawImage(0, 0, scaledSvg);
setImageAndEmitFinished(image);
}

Loading