fix(Chat): Context menu for gif downloads/copies a png file

Detect the MIME type using `QMimeDatabase` from the actual content and
save it in that same format using `QSaveFile`, as `QImage` does NOT
support saving a GIF

Fixes #10747
This commit is contained in:
Lukáš Tinkl 2023-06-12 10:32:27 +02:00 committed by Lukáš Tinkl
parent 31f59a2e81
commit 6bfe79a7f3
4 changed files with 38 additions and 22 deletions

View File

@ -105,8 +105,7 @@ QtObject:
downloadImage(content, path)
proc downloadImageByUrl*(self: Utils, url: string, path: string) {.slot.} =
let pathFormatted = self.formatImagePath(path)
downloadImageByUrl(url, pathFormatted)
downloadImageByUrl(url, path)
proc generateQRCodeSVG*(self: Utils, text: string, border: int = 0): string =
var qr0: array[0..qrcodegen_BUFFER_LEN_MAX, uint8]

View File

@ -224,7 +224,6 @@ QtObject {
function openDownloadImageDialog(imageSource) {
// We don't use `openPopup`, because there's no `FileDialog::closed` signal.
// And multiple file dialogs are (almost) ok
const popup = downloadImageDialogComponent.createObject(popupParent, { imageSource })
popup.open()
}
@ -498,11 +497,7 @@ QtObject {
onRejected: {
destroy()
}
Component.onCompleted: {
open()
}
}
}
]
}

View File

@ -7,9 +7,10 @@ StatusMenu {
property string imageSource
readonly property bool isGif: root.imageSource.toLowerCase().endsWith(".gif")
StatusAction {
text: root.imageSource.endsWith(".gif") ? qsTr("Copy GIF")
: qsTr("Copy image")
text: root.isGif ? qsTr("Copy GIF") : qsTr("Copy image")
icon.name: "copy"
enabled: !!root.imageSource
onTriggered: {
@ -18,8 +19,7 @@ StatusMenu {
}
StatusAction {
text: root.imageSource.endsWith(".gif") ? qsTr("Download GIF")
: qsTr("Download image")
text: root.isGif ? qsTr("Download GIF") : qsTr("Download image")
icon.name: "download"
enabled: !!root.imageSource
onTriggered: {

View File

@ -51,6 +51,8 @@
#include <QSettings>
#include <QTimer>
#include <QSysInfo>
#include <QMimeDatabase>
#include <QSaveFile>
#ifdef QT_QUICKCONTROLS2_LIB
#include <QtQuickControls2/QQuickStyle>
#endif
@ -304,22 +306,42 @@ void dos_qguiapplication_download_imageByUrl(const char *url, const char *filePa
manager.setAutoDeleteReplies(true);
QNetworkReply *reply = manager.get(QNetworkRequest(QUrl(url)));
const auto path = QFile::decodeName(filePath);
auto targetDir = QUrl::fromUserInput(filePath).toLocalFile(); // accept both "file:/foo/bar" and "/foo/bar"
if (targetDir.isEmpty())
targetDir = QDir::homePath();
QObject::connect(reply, &QNetworkReply::finished, [reply, path] {
QObject::connect(reply, &QNetworkReply::finished, [reply, targetDir] {
if(reply->error() == QNetworkReply::NoError) {
// Get current Date/Time information to use in naming of the image file
const QString dateTimeString = QDateTime::currentDateTime().toString("dd-MM-yyyy_hh-mm-ss");
// Extract the image data to be able to load and save it
const auto btArray = reply->readAll();
Q_ASSERT(!btArray.isEmpty());
// Extract the image data to be able to load and save into a QImage
QByteArray btArray = reply->readAll();
QImage image;
image.loadFromData(btArray);
Q_ASSERT(!image.isNull());
image.save(path + "/image_" + dateTimeString + ".png");
// Get current Date/Time information to use in naming of the image file
const auto dateTimeString = QDateTime::currentDateTime().toString(QStringLiteral("dd-MM-yyyy_hh-mm-ss"));
// Get the preferred extension
QMimeDatabase mimeDb;
auto ext = mimeDb.mimeTypeForData(btArray).preferredSuffix();
if (ext.isEmpty())
ext = QStringLiteral("jpg");
// Construct the target path
const auto targetFile = QStringLiteral("%1/image_%2.%3").arg(targetDir, dateTimeString, ext);
// Save the image in a safe way
QSaveFile image(targetFile);
if (!image.open(QIODevice::WriteOnly)) {
qWarning() << "dos_qguiapplication_download_imageByUrl: Downloading image failed while opening the save file:" << targetFile;
return;
}
if (image.write(btArray) != -1)
image.commit();
else
qWarning() << "dos_qguiapplication_download_imageByUrl: Downloading image failed while saving to file:" << targetFile;
}
else {
qWarning() << "dos_qguiapplication_download_imageByUrl: Downloading image failed!";
qWarning() << "dos_qguiapplication_download_imageByUrl: Downloading image" << reply->request().url() << "failed!";
}
});
}