Merge pull request #406 from rnhmjoj/open-in

Add "open in external program" action
This commit is contained in:
DeepBlueV7.X 2021-01-24 05:52:44 +01:00 committed by GitHub
commit a5944ab047
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 8 deletions

View File

@ -124,6 +124,12 @@ Page {
text: qsTr("Save as")
onTriggered: TimelineManager.timeline.saveMedia(messageContextMenu.eventId)
}
MenuItem {
visible: messageContextMenu.eventType == MtxEvent.ImageMessage || messageContextMenu.eventType == MtxEvent.VideoMessage || messageContextMenu.eventType == MtxEvent.AudioMessage || messageContextMenu.eventType == MtxEvent.FileMessage || messageContextMenu.eventType == MtxEvent.Sticker
height: visible ? implicitHeight : 0
text: qsTr("Open in external program")
onTriggered: TimelineManager.timeline.openMedia(messageContextMenu.eventId)
}
}

View File

@ -5,6 +5,7 @@
#include <type_traits>
#include <QCache>
#include <QDesktopServices>
#include <QFileDialog>
#include <QMimeDatabase>
#include <QRegularExpression>
@ -1073,6 +1074,14 @@ TimelineModel::addPendingMessage(mtx::events::collections::TimelineEvents event)
std::visit(SendMessageVisitor{this}, event);
}
void
TimelineModel::openMedia(QString eventId)
{
cacheMedia(eventId, [](QString filename) {
QDesktopServices::openUrl(QUrl::fromLocalFile(filename));
});
}
bool
TimelineModel::saveMedia(QString eventId) const
{
@ -1149,7 +1158,7 @@ TimelineModel::saveMedia(QString eventId) const
}
void
TimelineModel::cacheMedia(QString eventId)
TimelineModel::cacheMedia(QString eventId, std::function<void(const QString)> callback)
{
mtx::events::collections::TimelineEvents *event = events.get(eventId.toStdString(), "");
if (!event)
@ -1169,12 +1178,13 @@ TimelineModel::cacheMedia(QString eventId)
QString suffix = QMimeDatabase().mimeTypeForName(mimeType).preferredSuffix();
const auto url = mxcUrl.toStdString();
const auto url = mxcUrl.toStdString();
const auto name = QString(mxcUrl).remove("mxc://");
QFileInfo filename(QString("%1/media_cache/%2.%3")
.arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation))
.arg(QString(mxcUrl).remove("mxc://"))
.arg(name)
.arg(suffix));
if (QDir::cleanPath(filename.path()) != filename.path()) {
if (QDir::cleanPath(name) != name) {
nhlog::net()->warn("mxcUrl '{}' is not safe, not downloading file", url);
return;
}
@ -1183,15 +1193,18 @@ TimelineModel::cacheMedia(QString eventId)
if (filename.isReadable()) {
emit mediaCached(mxcUrl, filename.filePath());
if (callback) {
callback(filename.filePath());
}
return;
}
http::client()->download(
url,
[this, mxcUrl, filename, url, encryptionInfo](const std::string &data,
const std::string &,
const std::string &,
mtx::http::RequestErr err) {
[this, callback, mxcUrl, filename, url, encryptionInfo](const std::string &data,
const std::string &,
const std::string &,
mtx::http::RequestErr err) {
if (err) {
nhlog::net()->warn("failed to retrieve image {}: {} {}",
url,
@ -1213,6 +1226,10 @@ TimelineModel::cacheMedia(QString eventId)
file.write(QByteArray(temp.data(), (int)temp.size()));
file.close();
if (callback) {
callback(filename.filePath());
}
} catch (const std::exception &e) {
nhlog::ui()->warn("Error while saving file to: {}", e.what());
}
@ -1221,6 +1238,12 @@ TimelineModel::cacheMedia(QString eventId)
});
}
void
TimelineModel::cacheMedia(QString eventId)
{
cacheMedia(eventId, NULL);
}
QString
TimelineModel::formatTypingUsers(const std::vector<QString> &users, QColor bg)
{

View File

@ -218,8 +218,10 @@ public:
Q_INVOKABLE void redactEvent(QString id);
Q_INVOKABLE int idToIndex(QString id) const;
Q_INVOKABLE QString indexToId(int index) const;
Q_INVOKABLE void openMedia(QString eventId);
Q_INVOKABLE void cacheMedia(QString eventId);
Q_INVOKABLE bool saveMedia(QString eventId) const;
void cacheMedia(QString eventId, std::function<void(const QString filename)> callback);
std::vector<::Reaction> reactions(const std::string &event_id)
{