From 74a4e36f9062d4b64f2536787d090eb9f7162d3b Mon Sep 17 00:00:00 2001
From: math <mathdu@protonmail.com>
Date: Sat, 19 Mar 2022 01:54:02 -0300
Subject: [PATCH] add option to open image with external program by default

---
 resources/langs/nheko_en.ts              |  5 ++++
 resources/qml/delegates/ImageMessage.qml |  2 +-
 src/UserSettingsPage.cpp                 | 30 ++++++++++++++++++++++++
 src/UserSettingsPage.h                   |  7 ++++++
 src/timeline/TimelineViewManager.h       |  1 +
 5 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/resources/langs/nheko_en.ts b/resources/langs/nheko_en.ts
index 7aba5fecd..c071962a8 100644
--- a/resources/langs/nheko_en.ts
+++ b/resources/langs/nheko_en.ts
@@ -2908,6 +2908,11 @@ Reason: %4</translation>
         <source>Use identicons</source>
         <translation>Use identicons</translation>
     </message>
+    <message>
+        <location line="+2"/>
+        <source>Open images with external program</source>
+        <translation>Open images with external program</translation>
+    </message>
     <message>
         <location line="+2"/>
         <source>Decrypt messages in sidebar</source>
diff --git a/resources/qml/delegates/ImageMessage.qml b/resources/qml/delegates/ImageMessage.qml
index efd4f4a5d..2ee8da7fb 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 bcc6ef52b..b5aecab2d 100644
--- a/src/UserSettingsPage.cpp
+++ b/src/UserSettingsPage.cpp
@@ -84,6 +84,7 @@ UserSettings::load(std::optional<QString> 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 67fa89c77..a45375611 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<QStringList> 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<QStringList> 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<QStringList> 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 393b14790..309c879f1 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)
+
-- 
GitLab