diff options
author | Nicolas Werner <nicolas.werner@hotmail.de> | 2023-04-23 20:55:28 +0200 |
---|---|---|
committer | Nicolas Werner <nicolas.werner@hotmail.de> | 2023-04-23 20:55:28 +0200 |
commit | 6a03615413ef90e378df80fa1e3bc4ef031d5ea6 (patch) | |
tree | c577c21e1c3cda9f7c50a9545c7a57720de762b9 /src | |
parent | Translated using Weblate (Ukrainian) (diff) | |
download | nheko-6a03615413ef90e378df80fa1e3bc4ef031d5ea6.tar.xz |
Copy image to clipboard
Fixes #599
Diffstat (limited to 'src')
-rw-r--r-- | src/timeline/InputBar.cpp | 1 | ||||
-rw-r--r-- | src/timeline/TimelineModel.cpp | 55 | ||||
-rw-r--r-- | src/timeline/TimelineModel.h | 1 | ||||
-rw-r--r-- | src/timeline/TimelineViewManager.cpp | 35 | ||||
-rw-r--r-- | src/timeline/TimelineViewManager.h | 1 |
5 files changed, 91 insertions, 2 deletions
diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp index 879ec7cc..3a626a3c 100644 --- a/src/timeline/InputBar.cpp +++ b/src/timeline/InputBar.cpp @@ -148,6 +148,7 @@ InputBar::insertMimeData(const QMimeData *md) nhlog::ui()->debug("Got mime formats: {}", md->formats().join(QStringLiteral(", ")).toStdString()); + nhlog::ui()->debug("Has image: {}", md->hasImage()); const auto formats = md->formats().filter(QStringLiteral("/")); const auto image = formats.filter(QStringLiteral("image/"), Qt::CaseInsensitive); const auto audio = formats.filter(QStringLiteral("audio/"), Qt::CaseInsensitive); diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index f80f2ee9..5996bea8 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -12,6 +12,7 @@ #include <QDesktopServices> #include <QFileDialog> #include <QGuiApplication> +#include <QMimeData> #include <QMimeDatabase> #include <QRegularExpression> #include <QStandardPaths> @@ -1860,6 +1861,60 @@ TimelineModel::saveMedia(const QString &eventId) const return true; } +bool +TimelineModel::copyMedia(const QString &eventId) const +{ + auto event = events.get(eventId.toStdString(), ""); + if (!event) + return false; + + QString mxcUrl = QString::fromStdString(mtx::accessors::url(*event)); + QString mimeType = QString::fromStdString(mtx::accessors::mimetype(*event)); + qml_mtx_events::EventType eventType = toRoomEventType(*event); + + auto encryptionInfo = mtx::accessors::file(*event); + + const auto url = mxcUrl.toStdString(); + + http::client()->download( + url, + [url, mimeType, eventType, encryptionInfo](const std::string &data, + const std::string &, + const std::string &, + mtx::http::RequestErr err) { + if (err) { + nhlog::net()->warn("failed to retrieve media {}: {} {}", + url, + err->matrix_error.error, + static_cast<int>(err->status_code)); + return; + } + + try { + auto temp = data; + if (encryptionInfo) + temp = + mtx::crypto::to_string(mtx::crypto::decrypt_file(temp, encryptionInfo.value())); + + auto by = QByteArray(temp.data(), (qsizetype)temp.size()); + QMimeData *clipContents = new QMimeData(); + clipContents->setData(mimeType, by); + + if (eventType == qml_mtx_events::EventType::ImageMessage) { + auto img = utils::readImage(QByteArray(data.data(), (qsizetype)data.size())); + clipContents->setImageData(img); + } + + QGuiApplication::clipboard()->setMimeData(clipContents); + + return; + } catch (const std::exception &e) { + nhlog::ui()->warn("Error while copying file to clipboard: {}", e.what()); + } + }); + return true; +} + void TimelineModel::cacheMedia(const QString &eventId, const std::function<void(const QString)> &callback) diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index 0244c1b1..b0d81441 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -320,6 +320,7 @@ public: Q_INVOKABLE void openMedia(const QString &eventId); Q_INVOKABLE void cacheMedia(const QString &eventId); Q_INVOKABLE bool saveMedia(const QString &eventId) const; + Q_INVOKABLE bool copyMedia(const QString &eventId) const; Q_INVOKABLE void showEvent(QString eventId); Q_INVOKABLE void copyLinkToEvent(const QString &eventId) const; diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index b949e4c3..44f288c6 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -5,7 +5,9 @@ #include "TimelineViewManager.h" #include <QApplication> +#include <QClipboard> #include <QFileDialog> +#include <QMimeData> #include <QStandardPaths> #include <QString> @@ -29,8 +31,6 @@ #include "voip/CallManager.h" #include "voip/WebRTCSession.h" -namespace msgs = mtx::events::msg; - namespace { template<template<class...> class Op, class... Args> using is_detected = typename nheko::detail::detector<nheko::nonesuch, void, Op, Args...>::value_t; @@ -319,6 +319,37 @@ TimelineViewManager::saveMedia(QString mxcUrl) } void +TimelineViewManager::copyImage(const QString &mxcUrl) const +{ + const auto url = mxcUrl.toStdString(); + QString mimeType; + + http::client()->download( + url, + [url, mimeType](const std::string &data, + const std::string &, + const std::string &, + mtx::http::RequestErr err) { + if (err) { + nhlog::net()->warn("failed to retrieve media {}: {} {}", + url, + err->matrix_error.error, + static_cast<int>(err->status_code)); + return; + } + + try { + auto img = utils::readImage(QByteArray(data.data(), (qsizetype)data.size())); + QGuiApplication::clipboard()->setImage(img); + + return; + } catch (const std::exception &e) { + nhlog::ui()->warn("Error while copying file to clipboard: {}", e.what()); + } + }); +} + +void TimelineViewManager::updateReadReceipts(const QString &room_id, const std::vector<QString> &event_ids) { diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index ee5cf031..e3279e21 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -56,6 +56,7 @@ public: double proportionalHeight); Q_INVOKABLE void openImagePackSettings(QString roomid); Q_INVOKABLE void saveMedia(QString mxcUrl); + Q_INVOKABLE void copyImage(const QString &mxcUrl) const; Q_INVOKABLE QColor userColor(QString id, QColor background); Q_INVOKABLE QString escapeEmoji(QString str) const; Q_INVOKABLE QString htmlEscape(QString str) const { return str.toHtmlEscaped(); } |