diff --git a/resources/langs/nheko_en.ts b/resources/langs/nheko_en.ts index 7aba5fec..c071962a 100644 --- a/resources/langs/nheko_en.ts +++ b/resources/langs/nheko_en.ts @@ -2908,6 +2908,11 @@ Reason: %4 Use identicons Use identicons + + + Open images with external program + Open images with external program + Decrypt messages in sidebar diff --git a/resources/qml/delegates/ImageMessage.qml b/resources/qml/delegates/ImageMessage.qml index efd4f4a5..2ee8da7f 100644 --- a/resources/qml/delegates/ImageMessage.qml +++ b/resources/qml/delegates/ImageMessage.qml @@ -68,7 +68,7 @@ Item { TapHandler { //enabled: type == MtxEvent.ImageMessage && (img.status == Image.Ready || mxcimage.loaded) onSingleTapped: { - TimelineManager.openImageOverlay(room, url, eventId); + Settings.openImageExternal ? room.openMedia(eventId) : TimelineManager.openImageOverlay(room, url, eventId); eventPoint.accepted = true; } gesturePolicy: TapHandler.ReleaseWithinBounds diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp index bcc6ef52..b5aecab2 100644 --- a/src/UserSettingsPage.cpp +++ b/src/UserSettingsPage.cpp @@ -84,6 +84,7 @@ UserSettings::load(std::optional profile) avatarCircles_ = settings.value(QStringLiteral("user/avatar_circles"), true).toBool(); useIdenticon_ = settings.value(QStringLiteral("user/use_identicon"), true).toBool(); + openImageExternal_ = settings.value(QStringLiteral("user/open_image_external"), false).toBool(); decryptSidebar_ = settings.value(QStringLiteral("user/decrypt_sidebar"), true).toBool(); privacyScreen_ = settings.value(QStringLiteral("user/privacy_screen"), false).toBool(); privacyScreenTimeout_ = @@ -687,6 +688,16 @@ UserSettings::setUseIdenticon(bool state) save(); } +void +UserSettings::setOpenImageExternal(bool state) +{ + if (state == openImageExternal_) + return; + openImageExternal_ = state; + emit openImageExternalChanged(openImageExternal_); + save(); +} + void UserSettings::applyTheme() { @@ -764,6 +775,7 @@ UserSettings::save() settings.setValue(QStringLiteral("use_stun_server"), useStunServer_); settings.setValue(QStringLiteral("currentProfile"), profile_); settings.setValue(QStringLiteral("use_identicon"), useIdenticon_); + settings.setValue(QStringLiteral("open_image_external"), openImageExternal_); settings.endGroup(); // user @@ -868,6 +880,8 @@ UserSettingsModel::data(const QModelIndex &index, int role) const return tr("Circular Avatars"); case UseIdenticon: return tr("Use identicons"); + case OpenImageExternal: + return tr("Open images with external program"); case DecryptSidebar: return tr("Decrypt messages in sidebar"); case PrivacyScreen: @@ -992,6 +1006,8 @@ UserSettingsModel::data(const QModelIndex &index, int role) const return i->avatarCircles(); case UseIdenticon: return i->useIdenticon(); + case OpenImageExternal: + return i->openImageExternal(); case DecryptSidebar: return i->decryptSidebar(); case PrivacyScreen: @@ -1134,6 +1150,9 @@ UserSettingsModel::data(const QModelIndex &index, int role) const "Change the appearance of user avatars in chats.\nOFF - square, ON - circle."); case UseIdenticon: return tr("Display an identicon instead of a letter when no avatar is set."); + case OpenImageExternal: + return tr("Click to open image with external program. \nSame as Right-Click>Open " + "in External Program"); case DecryptSidebar: return tr("Decrypt the messages shown in the sidebar.\nOnly affects messages in " "encrypted chats."); @@ -1230,6 +1249,7 @@ UserSettingsModel::data(const QModelIndex &index, int role) const case AlertOnNotification: case AvatarCircles: case UseIdenticon: + case OpenImageExternal: case DecryptSidebar: case PrivacyScreen: case MobileMode: @@ -1522,6 +1542,13 @@ UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int } else return false; } + case OpenImageExternal: { + if (value.userType() == QMetaType::Bool) { + i->setOpenImageExternal(value.toBool()); + return true; + } else + return false; + } case DecryptSidebar: { if (value.userType() == QMetaType::Bool) { i->setDecryptSidebar(value.toBool()); @@ -1782,6 +1809,9 @@ UserSettingsModel::UserSettingsModel(QObject *p) connect(s.get(), &UserSettings::useIdenticonChanged, this, [this]() { emit dataChanged(index(UseIdenticon), index(UseIdenticon), {Value}); }); + connect(s.get(), &UserSettings::openImageExternalChanged, this, [this]() { + emit dataChanged(index(OpenImageExternal), index(OpenImageExternal), {Value}); + }); connect(s.get(), &UserSettings::privacyScreenChanged, this, [this]() { emit dataChanged(index(PrivacyScreen), index(PrivacyScreen), {Value}); emit dataChanged(index(PrivacyScreenTimeout), index(PrivacyScreenTimeout), {Enabled}); diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h index 67fa89c7..a4537561 100644 --- a/src/UserSettingsPage.h +++ b/src/UserSettingsPage.h @@ -105,6 +105,7 @@ class UserSettings : public QObject Q_PROPERTY(bool disableCertificateValidation READ disableCertificateValidation WRITE setDisableCertificateValidation NOTIFY disableCertificateValidationChanged) Q_PROPERTY(bool useIdenticon READ useIdenticon WRITE setUseIdenticon NOTIFY useIdenticonChanged) + Q_PROPERTY(bool openImageExternal READ openImageExternal WRITE setOpenImageExternal NOTIFY openImageExternalChanged) Q_PROPERTY(QStringList hiddenPins READ hiddenPins WRITE setHiddenPins NOTIFY hiddenPinsChanged) Q_PROPERTY(QStringList recentReactions READ recentReactions WRITE setRecentReactions NOTIFY @@ -184,6 +185,7 @@ public: void setHiddenWidgets(QStringList hiddenTags); void setRecentReactions(QStringList recent); void setUseIdenticon(bool state); + void setOpenImageExternal(bool state); void setCollapsedSpaces(QList spaces); QString theme() const { return !theme_.isEmpty() ? theme_ : defaultTheme_; } @@ -246,6 +248,7 @@ public: QStringList hiddenWidgets() const { return hiddenWidgets_; } QStringList recentReactions() const { return recentReactions_; } bool useIdenticon() const { return useIdenticon_ && JdenticonProvider::isAvailable(); } + bool openImageExternal() const { return openImageExternal_; } QList collapsedSpaces() const { return collapsedSpaces_; } signals: @@ -297,6 +300,7 @@ signals: void homeserverChanged(QString homeserver); void disableCertificateValidationChanged(bool disabled); void useIdenticonChanged(bool state); + void openImageExternalChanged(bool state); void hiddenPinsChanged(); void hiddenWidgetsChanged(); void recentReactionsChanged(); @@ -361,6 +365,7 @@ private: QStringList recentReactions_; QList collapsedSpaces_; bool useIdenticon_; + bool openImageExternal_; QSettings settings; @@ -384,6 +389,7 @@ class UserSettingsModel : public QAbstractListModel EmojiFont, AvatarCircles, UseIdenticon, + OpenImageExternal, PrivacyScreen, PrivacyScreenTimeout, @@ -491,3 +497,4 @@ public: Q_INVOKABLE void requestCrossSigningSecrets(); Q_INVOKABLE void downloadCrossSigningSecrets(); }; + diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 393b1479..309c879f 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -133,3 +133,4 @@ Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationMac) Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationReady) Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationRequest) Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationStart) +