From 5127951302820742335b603e1f09c99f91e808f7 Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Sun, 28 Aug 2022 15:22:41 +0200 Subject: [PATCH 01/24] basic image pop-up on hover --- gotify_tray/database/default_settings.py | 3 + gotify_tray/gui/MainApplication.py | 12 ++- gotify_tray/gui/designs/widget_settings.py | 58 +++++++------ gotify_tray/gui/designs/widget_settings.ui | 96 +++++++++++++--------- gotify_tray/gui/widgets/ImagePopup.py | 46 +++++++++++ gotify_tray/gui/widgets/MainWindow.py | 2 + gotify_tray/gui/widgets/MessageWidget.py | 14 +++- gotify_tray/gui/widgets/SettingsDialog.py | 8 ++ gotify_tray/gui/widgets/__init__.py | 1 + 9 files changed, 174 insertions(+), 66 deletions(-) create mode 100644 gotify_tray/gui/widgets/ImagePopup.py diff --git a/gotify_tray/database/default_settings.py b/gotify_tray/database/default_settings.py index 6ce350d..6017525 100644 --- a/gotify_tray/database/default_settings.py +++ b/gotify_tray/database/default_settings.py @@ -19,4 +19,7 @@ DEFAULT_SETTINGS = { "MainWindow/label/size": 25, "MainWindow/button/size": 33, "MainWindow/application/icon/size": 40, + "ImagePopup/enabled": False, + "ImagePopup/w": 400, + "ImagePopup/h": 400, } diff --git a/gotify_tray/gui/MainApplication.py b/gotify_tray/gui/MainApplication.py index a3107c9..d50e062 100644 --- a/gotify_tray/gui/MainApplication.py +++ b/gotify_tray/gui/MainApplication.py @@ -31,7 +31,7 @@ from .models import ( MessagesModelItem, MessageItemDataRole, ) -from .widgets import MainWindow, SettingsDialog, Tray +from .widgets import ImagePopup, MainWindow, SettingsDialog, Tray settings = Settings("gotify-tray") @@ -65,6 +65,7 @@ class MainApplication(QtWidgets.QApplication): settings.value("Server/client_token", type=str), ) + self.cache = Cache() self.downloader = Downloader() self.messages_model = MessagesModel() @@ -308,6 +309,14 @@ class MainApplication(QtWidgets.QApplication): return self.messages_model.clear() + + def image_popup_callback(self, link: str, pos: QtCore.QPoint): + if (filename := self.cache.lookup(link)) or (filename := self.downloader.get_filename(link)): # TODO: preload links + self.image_popup = ImagePopup(filename, pos, link) + self.image_popup.show() + else: + # TODO + logger.warning(f"Image {link} is not in the cache") def refresh_callback(self): # Manual refresh -> also reset the image cache @@ -358,6 +367,7 @@ class MainApplication(QtWidgets.QApplication): self.application_selection_changed_callback ) self.main_window.delete_message.connect(self.delete_message_callback) + self.main_window.image_popup.connect(self.image_popup_callback) self.watchdog.closed.connect(lambda: self.listener_closed_callback(None, None)) diff --git a/gotify_tray/gui/designs/widget_settings.py b/gotify_tray/gui/designs/widget_settings.py index 3a0f95c..0ccd047 100644 --- a/gotify_tray/gui/designs/widget_settings.py +++ b/gotify_tray/gui/designs/widget_settings.py @@ -12,7 +12,7 @@ from PyQt6 import QtCore, QtGui, QtWidgets class Ui_Dialog(object): def setupUi(self, Dialog): Dialog.setObjectName("Dialog") - Dialog.resize(384, 274) + Dialog.resize(384, 272) self.gridLayout = QtWidgets.QGridLayout(Dialog) self.gridLayout.setObjectName("gridLayout") self.buttonBox = QtWidgets.QDialogButtonBox(Dialog) @@ -30,17 +30,6 @@ class Ui_Dialog(object): self.groupBox_notifications.setObjectName("groupBox_notifications") self.gridLayout_4 = QtWidgets.QGridLayout(self.groupBox_notifications) self.gridLayout_4.setObjectName("gridLayout_4") - spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) - self.gridLayout_4.addItem(spacerItem, 0, 2, 1, 1) - self.label_notification_duration_ms = QtWidgets.QLabel(self.groupBox_notifications) - self.label_notification_duration_ms.setObjectName("label_notification_duration_ms") - self.gridLayout_4.addWidget(self.label_notification_duration_ms, 1, 2, 1, 1) - self.label_notification_priority = QtWidgets.QLabel(self.groupBox_notifications) - self.label_notification_priority.setObjectName("label_notification_priority") - self.gridLayout_4.addWidget(self.label_notification_priority, 0, 0, 1, 1) - self.label_notification_duration = QtWidgets.QLabel(self.groupBox_notifications) - self.label_notification_duration.setObjectName("label_notification_duration") - self.gridLayout_4.addWidget(self.label_notification_duration, 1, 0, 1, 1) self.spin_duration = QtWidgets.QSpinBox(self.groupBox_notifications) self.spin_duration.setMinimum(500) self.spin_duration.setMaximum(30000) @@ -53,6 +42,17 @@ class Ui_Dialog(object): self.spin_priority.setProperty("value", 5) self.spin_priority.setObjectName("spin_priority") self.gridLayout_4.addWidget(self.spin_priority, 0, 1, 1, 1) + spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.gridLayout_4.addItem(spacerItem, 0, 2, 1, 1) + self.label_notification_duration_ms = QtWidgets.QLabel(self.groupBox_notifications) + self.label_notification_duration_ms.setObjectName("label_notification_duration_ms") + self.gridLayout_4.addWidget(self.label_notification_duration_ms, 1, 2, 1, 1) + self.label_notification_duration = QtWidgets.QLabel(self.groupBox_notifications) + self.label_notification_duration.setObjectName("label_notification_duration") + self.gridLayout_4.addWidget(self.label_notification_duration, 1, 0, 1, 1) + self.label_notification_priority = QtWidgets.QLabel(self.groupBox_notifications) + self.label_notification_priority.setObjectName("label_notification_priority") + self.gridLayout_4.addWidget(self.label_notification_priority, 0, 0, 1, 1) self.cb_notify = QtWidgets.QCheckBox(self.groupBox_notifications) self.cb_notify.setObjectName("cb_notify") self.gridLayout_4.addWidget(self.cb_notify, 2, 0, 1, 3) @@ -102,18 +102,26 @@ class Ui_Dialog(object): self.verticalLayout.setObjectName("verticalLayout") self.groupBox = QtWidgets.QGroupBox(self.tab_advanced) self.groupBox.setObjectName("groupBox") - self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.groupBox) - self.verticalLayout_2.setObjectName("verticalLayout_2") - self.pb_export = QtWidgets.QPushButton(self.groupBox) - self.pb_export.setObjectName("pb_export") - self.verticalLayout_2.addWidget(self.pb_export) - self.pb_import = QtWidgets.QPushButton(self.groupBox) - self.pb_import.setObjectName("pb_import") - self.verticalLayout_2.addWidget(self.pb_import) + self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.groupBox) + self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.pb_reset = QtWidgets.QPushButton(self.groupBox) self.pb_reset.setObjectName("pb_reset") - self.verticalLayout_2.addWidget(self.pb_reset) + self.horizontalLayout_2.addWidget(self.pb_reset) + self.pb_import = QtWidgets.QPushButton(self.groupBox) + self.pb_import.setObjectName("pb_import") + self.horizontalLayout_2.addWidget(self.pb_import) + self.pb_export = QtWidgets.QPushButton(self.groupBox) + self.pb_export.setObjectName("pb_export") + self.horizontalLayout_2.addWidget(self.pb_export) self.verticalLayout.addWidget(self.groupBox) + self.groupBox_2 = QtWidgets.QGroupBox(self.tab_advanced) + self.groupBox_2.setObjectName("groupBox_2") + self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox_2) + self.gridLayout_2.setObjectName("gridLayout_2") + self.cb_image_popup = QtWidgets.QCheckBox(self.groupBox_2) + self.cb_image_popup.setObjectName("cb_image_popup") + self.gridLayout_2.addWidget(self.cb_image_popup, 0, 0, 1, 1) + self.verticalLayout.addWidget(self.groupBox_2) self.groupBox_logging = QtWidgets.QGroupBox(self.tab_advanced) self.groupBox_logging.setObjectName("groupBox_logging") self.gridLayout_6 = QtWidgets.QGridLayout(self.groupBox_logging) @@ -154,8 +162,8 @@ class Ui_Dialog(object): Dialog.setWindowTitle(_translate("Dialog", "Dialog")) self.groupBox_notifications.setTitle(_translate("Dialog", "Notifications")) self.label_notification_duration_ms.setText(_translate("Dialog", "ms")) - self.label_notification_priority.setText(_translate("Dialog", "Minimum priority to show notifications:")) self.label_notification_duration.setText(_translate("Dialog", "Notification duration:")) + self.label_notification_priority.setText(_translate("Dialog", "Minimum priority to show notifications:")) self.cb_notify.setText(_translate("Dialog", "Show a notification for missed messages after reconnecting")) self.groupBox_server_info.setTitle(_translate("Dialog", "Server info")) self.pb_change_server_info.setText(_translate("Dialog", "Change server info")) @@ -166,9 +174,11 @@ class Ui_Dialog(object): self.pb_font_message_content.setText(_translate("Dialog", "Message")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_fonts), _translate("Dialog", "Fonts")) self.groupBox.setTitle(_translate("Dialog", "Settings")) - self.pb_export.setText(_translate("Dialog", "Export")) - self.pb_import.setText(_translate("Dialog", "Import")) self.pb_reset.setText(_translate("Dialog", "Reset")) + self.pb_import.setText(_translate("Dialog", "Import")) + self.pb_export.setText(_translate("Dialog", "Export")) + self.groupBox_2.setTitle(_translate("Dialog", "Image pop-up")) + self.cb_image_popup.setText(_translate("Dialog", "Show an image pop-up when hovering over image URLs")) self.groupBox_logging.setTitle(_translate("Dialog", "Logging")) self.label_logging.setText(_translate("Dialog", "Level")) self.pb_open_log.setToolTip(_translate("Dialog", "Open logfile")) diff --git a/gotify_tray/gui/designs/widget_settings.ui b/gotify_tray/gui/designs/widget_settings.ui index 3f3579b..63fb668 100644 --- a/gotify_tray/gui/designs/widget_settings.ui +++ b/gotify_tray/gui/designs/widget_settings.ui @@ -7,7 +7,7 @@ 0 0 384 - 274 + 272 @@ -40,40 +40,6 @@ Notifications - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - ms - - - - - - - Minimum priority to show notifications: - - - - - - - Notification duration: - - - @@ -100,6 +66,40 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + ms + + + + + + + Notification duration: + + + + + + + Minimum priority to show notifications: + + + @@ -233,11 +233,11 @@ Settings - + - + - Export + Reset @@ -249,9 +249,25 @@ - + - Reset + Export + + + + + + + + + + Image pop-up + + + + + + Show an image pop-up when hovering over image URLs diff --git a/gotify_tray/gui/widgets/ImagePopup.py b/gotify_tray/gui/widgets/ImagePopup.py new file mode 100644 index 0000000..e61955d --- /dev/null +++ b/gotify_tray/gui/widgets/ImagePopup.py @@ -0,0 +1,46 @@ +from PyQt6 import QtCore, QtGui, QtWidgets + +from gotify_tray.database import Settings + + +settings = Settings("gotify-tray") + + +class ImagePopup(QtWidgets.QLabel): + def __init__(self, filename: str, pos: QtCore.QPoint, link: str = None): + """Create and show a pop-up image under the cursor + + Args: + filename (str): The path to the image to display + pos (QtCore.QPoint): The location at which the image should be displayed + link (str, optional): The URL of the image. Defaults to None. + """ + super(ImagePopup, self).__init__() + self.link = link + + self.setWindowFlags(QtCore.Qt.WindowType.ToolTip) + self.installEventFilter(self) + + self.setPixmap( + QtGui.QPixmap(filename).scaled( + settings.value("ImagePopup/w", type=int), + settings.value("ImagePopup/h", type=int), + QtCore.Qt.AspectRatioMode.KeepAspectRatio, + ) + ) + self.move(pos - QtCore.QPoint(30, 30)) + self.show() + + def eventFilter(self, object: QtCore.QObject, event: QtCore.QEvent) -> bool: + if event.type() == QtCore.QEvent.Type.Leave: + # Close the pop-up on mouse leave + self.close() + elif ( + event.type() == QtCore.QEvent.Type.MouseButtonPress + and event.button() == QtCore.Qt.MouseButton.LeftButton + and self.link + ): + # Open the image URL on left click + QtGui.QDesktopServices.openUrl(QtCore.QUrl(self.link)) + + return super().eventFilter(object, event) diff --git a/gotify_tray/gui/widgets/MainWindow.py b/gotify_tray/gui/widgets/MainWindow.py index 21faa98..541f44c 100644 --- a/gotify_tray/gui/widgets/MainWindow.py +++ b/gotify_tray/gui/widgets/MainWindow.py @@ -21,6 +21,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): delete_all = QtCore.pyqtSignal(QtGui.QStandardItem) delete_message = QtCore.pyqtSignal(MessagesModelItem) application_selection_changed = QtCore.pyqtSignal(QtGui.QStandardItem) + image_popup = QtCore.pyqtSignal(str, QtCore.QPoint) def __init__( self, application_model: ApplicationModel, messages_model: MessagesModel @@ -103,6 +104,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): self.messages_model.indexFromItem(message_item), message_widget ) message_widget.deletion_requested.connect(self.delete_message.emit) + message_widget.image_popup.connect(self.image_popup.emit) def currentApplicationIndex(self) -> QtCore.QModelIndex: return self.listView_applications.selectionModel().currentIndex() diff --git a/gotify_tray/gui/widgets/MessageWidget.py b/gotify_tray/gui/widgets/MessageWidget.py index db1cde6..3b6eb9c 100644 --- a/gotify_tray/gui/widgets/MessageWidget.py +++ b/gotify_tray/gui/widgets/MessageWidget.py @@ -1,8 +1,10 @@ +import os + from PyQt6 import QtCore, QtGui, QtWidgets from ..models.MessagesModel import MessageItemDataRole, MessagesModelItem from ..designs.widget_message import Ui_Form -from gotify_tray.database import Settings +from gotify_tray.database import Cache, Settings from gotify_tray.utils import convert_links, get_abs_path @@ -11,6 +13,7 @@ settings = Settings("gotify-tray") class MessageWidget(QtWidgets.QWidget, Ui_Form): deletion_requested = QtCore.pyqtSignal(MessagesModelItem) + image_popup = QtCore.pyqtSignal(str, QtCore.QPoint) def __init__(self, message_item: MessagesModelItem, image_path: str = ""): super(MessageWidget, self).__init__() @@ -86,7 +89,16 @@ class MessageWidget(QtWidgets.QWidget, Ui_Form): self.label_date.setFont(font_date) self.label_message.setFont(font_content) + def link_hovered_callback(self, link: str): + if not settings.value("ImagePopup/enabled", type=bool): + return + + _, ext = os.path.splitext(link) + if ext in [".jpg", ".jpeg", ".png"]: + self.image_popup.emit(link, QtGui.QCursor.pos()) + def link_callbacks(self): self.pb_delete.clicked.connect( lambda: self.deletion_requested.emit(self.message_item) ) + self.label_message.linkHovered.connect(self.link_hovered_callback) diff --git a/gotify_tray/gui/widgets/SettingsDialog.py b/gotify_tray/gui/widgets/SettingsDialog.py index b4024c5..0940ade 100644 --- a/gotify_tray/gui/widgets/SettingsDialog.py +++ b/gotify_tray/gui/widgets/SettingsDialog.py @@ -82,6 +82,10 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog): ) self.layout_fonts_message.addWidget(self.message_widget) + # Advanced + self.cb_image_popup.setChecked(settings.value("ImagePopup/enabled", type=bool)) + # TODO: w/h + def change_server_info_callback(self): self.server_changed = verify_server(force_new=True, enable_import=False) @@ -174,6 +178,7 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog): self.pb_export.clicked.connect(self.export_callback) self.pb_import.clicked.connect(self.import_callback) self.pb_reset.clicked.connect(self.reset_callback) + self.cb_image_popup.stateChanged.connect(self.settings_changed_callback) def apply_settings(self): # Priority @@ -203,6 +208,9 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog): self.message_widget.label_message.font().toString(), ) + # Advanced + settings.setValue("ImagePopup/enabled", self.cb_image_popup.isChecked()) + self.settings_changed = False self.buttonBox.button( QtWidgets.QDialogButtonBox.StandardButton.Apply diff --git a/gotify_tray/gui/widgets/__init__.py b/gotify_tray/gui/widgets/__init__.py index d43f65f..2f9952f 100644 --- a/gotify_tray/gui/widgets/__init__.py +++ b/gotify_tray/gui/widgets/__init__.py @@ -1,3 +1,4 @@ +from .ImagePopup import ImagePopup from .MessageWidget import MessageWidget from .MainWindow import MainWindow from .ServerInfoDialog import ServerInfoDialog From 2f0d389be44862dce569b9978f27b6dedf620152 Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Sun, 28 Aug 2022 16:06:46 +0200 Subject: [PATCH 02/24] make sure the pop-up is closed when the main window is hidden --- gotify_tray/gui/MainApplication.py | 6 +++++- gotify_tray/gui/widgets/MainWindow.py | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/gotify_tray/gui/MainApplication.py b/gotify_tray/gui/MainApplication.py index d50e062..77ebe9c 100644 --- a/gotify_tray/gui/MainApplication.py +++ b/gotify_tray/gui/MainApplication.py @@ -313,10 +313,13 @@ class MainApplication(QtWidgets.QApplication): def image_popup_callback(self, link: str, pos: QtCore.QPoint): if (filename := self.cache.lookup(link)) or (filename := self.downloader.get_filename(link)): # TODO: preload links self.image_popup = ImagePopup(filename, pos, link) - self.image_popup.show() else: # TODO logger.warning(f"Image {link} is not in the cache") + + def main_window_hidden_callback(self): + if image_popup := getattr(self, "image_popup", None): + image_popup.close() def refresh_callback(self): # Manual refresh -> also reset the image cache @@ -368,6 +371,7 @@ class MainApplication(QtWidgets.QApplication): ) self.main_window.delete_message.connect(self.delete_message_callback) self.main_window.image_popup.connect(self.image_popup_callback) + self.main_window.hidden.connect(self.main_window_hidden_callback) self.watchdog.closed.connect(lambda: self.listener_closed_callback(None, None)) diff --git a/gotify_tray/gui/widgets/MainWindow.py b/gotify_tray/gui/widgets/MainWindow.py index 541f44c..26ed8b3 100644 --- a/gotify_tray/gui/widgets/MainWindow.py +++ b/gotify_tray/gui/widgets/MainWindow.py @@ -22,6 +22,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): delete_message = QtCore.pyqtSignal(MessagesModelItem) application_selection_changed = QtCore.pyqtSignal(QtGui.QStandardItem) image_popup = QtCore.pyqtSignal(str, QtCore.QPoint) + hidden = QtCore.pyqtSignal() def __init__( self, application_model: ApplicationModel, messages_model: MessagesModel @@ -175,3 +176,4 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def closeEvent(self, e: QtGui.QCloseEvent) -> None: self.hide() + self.hidden.emit() From db03edf0621b4a47420f00ad625f4832cbceca65 Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Sun, 28 Aug 2022 16:07:50 +0200 Subject: [PATCH 03/24] center the image on the cursor --- gotify_tray/gui/widgets/ImagePopup.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gotify_tray/gui/widgets/ImagePopup.py b/gotify_tray/gui/widgets/ImagePopup.py index e61955d..35c2d01 100644 --- a/gotify_tray/gui/widgets/ImagePopup.py +++ b/gotify_tray/gui/widgets/ImagePopup.py @@ -21,14 +21,14 @@ class ImagePopup(QtWidgets.QLabel): self.setWindowFlags(QtCore.Qt.WindowType.ToolTip) self.installEventFilter(self) - self.setPixmap( - QtGui.QPixmap(filename).scaled( + pixmap = QtGui.QPixmap(filename).scaled( settings.value("ImagePopup/w", type=int), settings.value("ImagePopup/h", type=int), QtCore.Qt.AspectRatioMode.KeepAspectRatio, ) - ) - self.move(pos - QtCore.QPoint(30, 30)) + self.setPixmap(pixmap) + + self.move(pos - QtCore.QPoint(pixmap.width()/2, pixmap.height()/2)) self.show() def eventFilter(self, object: QtCore.QObject, event: QtCore.QEvent) -> bool: From bb6aa7089011682ef03f82f7dd50c4347e2f2c92 Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Sun, 28 Aug 2022 16:11:18 +0200 Subject: [PATCH 04/24] scale with SmoothTransformation --- gotify_tray/gui/widgets/ImagePopup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gotify_tray/gui/widgets/ImagePopup.py b/gotify_tray/gui/widgets/ImagePopup.py index 35c2d01..63fdd32 100644 --- a/gotify_tray/gui/widgets/ImagePopup.py +++ b/gotify_tray/gui/widgets/ImagePopup.py @@ -24,7 +24,8 @@ class ImagePopup(QtWidgets.QLabel): pixmap = QtGui.QPixmap(filename).scaled( settings.value("ImagePopup/w", type=int), settings.value("ImagePopup/h", type=int), - QtCore.Qt.AspectRatioMode.KeepAspectRatio, + aspectRatioMode=QtCore.Qt.AspectRatioMode.KeepAspectRatio, + transformMode=QtCore.Qt.TransformationMode.SmoothTransformation ) self.setPixmap(pixmap) From 6dc97dda27c38a5897a8abd20a74118c7a93d0a6 Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Sun, 28 Aug 2022 21:24:41 +0200 Subject: [PATCH 05/24] track underMouse --- gotify_tray/gui/MainApplication.py | 1 + gotify_tray/gui/widgets/ImagePopup.py | 33 +++++++++++++++++++-------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/gotify_tray/gui/MainApplication.py b/gotify_tray/gui/MainApplication.py index 77ebe9c..ce277f2 100644 --- a/gotify_tray/gui/MainApplication.py +++ b/gotify_tray/gui/MainApplication.py @@ -313,6 +313,7 @@ class MainApplication(QtWidgets.QApplication): def image_popup_callback(self, link: str, pos: QtCore.QPoint): if (filename := self.cache.lookup(link)) or (filename := self.downloader.get_filename(link)): # TODO: preload links self.image_popup = ImagePopup(filename, pos, link) + self.image_popup.show() else: # TODO logger.warning(f"Image {link} is not in the cache") diff --git a/gotify_tray/gui/widgets/ImagePopup.py b/gotify_tray/gui/widgets/ImagePopup.py index 63fdd32..b8799bf 100644 --- a/gotify_tray/gui/widgets/ImagePopup.py +++ b/gotify_tray/gui/widgets/ImagePopup.py @@ -20,18 +20,31 @@ class ImagePopup(QtWidgets.QLabel): self.setWindowFlags(QtCore.Qt.WindowType.ToolTip) self.installEventFilter(self) - - pixmap = QtGui.QPixmap(filename).scaled( - settings.value("ImagePopup/w", type=int), - settings.value("ImagePopup/h", type=int), - aspectRatioMode=QtCore.Qt.AspectRatioMode.KeepAspectRatio, - transformMode=QtCore.Qt.TransformationMode.SmoothTransformation - ) - self.setPixmap(pixmap) - self.move(pos - QtCore.QPoint(pixmap.width()/2, pixmap.height()/2)) - self.show() + # Prevent leaving the pop-up open when moving quickly out of the widget + self.popup_timer = QtCore.QTimer() + self.popup_timer.timeout.connect(self.check_mouse) + + pixmap = QtGui.QPixmap(filename).scaled( + settings.value("ImagePopup/w", type=int), + settings.value("ImagePopup/h", type=int), + aspectRatioMode=QtCore.Qt.AspectRatioMode.KeepAspectRatio, + transformMode=QtCore.Qt.TransformationMode.SmoothTransformation, + ) + self.setPixmap(pixmap) + self.move(pos - QtCore.QPoint(15, 15)) + + self.popup_timer.start(500) + + def check_mouse(self): + if not self.underMouse(): + self.close() + + def close(self): + self.popup_timer.stop() + super(ImagePopup, self).close() + def eventFilter(self, object: QtCore.QObject, event: QtCore.QEvent) -> bool: if event.type() == QtCore.QEvent.Type.Leave: # Close the pop-up on mouse leave From 5fdfef27349c46c76f7786d8f95d2b0cafa28d19 Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Thu, 1 Sep 2022 21:38:22 +0200 Subject: [PATCH 06/24] add extensions to default settings --- gotify_tray/database/default_settings.py | 1 + gotify_tray/gui/widgets/MessageWidget.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/gotify_tray/database/default_settings.py b/gotify_tray/database/default_settings.py index 6017525..21a8fcb 100644 --- a/gotify_tray/database/default_settings.py +++ b/gotify_tray/database/default_settings.py @@ -20,6 +20,7 @@ DEFAULT_SETTINGS = { "MainWindow/button/size": 33, "MainWindow/application/icon/size": 40, "ImagePopup/enabled": False, + "ImagePopup/extensions": [".jpg", ".jpeg", ".png", ".svg"], "ImagePopup/w": 400, "ImagePopup/h": 400, } diff --git a/gotify_tray/gui/widgets/MessageWidget.py b/gotify_tray/gui/widgets/MessageWidget.py index 3b6eb9c..2417bf3 100644 --- a/gotify_tray/gui/widgets/MessageWidget.py +++ b/gotify_tray/gui/widgets/MessageWidget.py @@ -94,7 +94,7 @@ class MessageWidget(QtWidgets.QWidget, Ui_Form): return _, ext = os.path.splitext(link) - if ext in [".jpg", ".jpeg", ".png"]: + if ext in settings.value("ImagePopup/extensions", type=list): self.image_popup.emit(link, QtGui.QCursor.pos()) def link_callbacks(self): From 5e77a82629eb78851dc5ec5364bfb768f16820ea Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Thu, 1 Sep 2022 21:39:24 +0200 Subject: [PATCH 07/24] do not read cache twice --- gotify_tray/gui/MainApplication.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/gotify_tray/gui/MainApplication.py b/gotify_tray/gui/MainApplication.py index ce277f2..4d2db87 100644 --- a/gotify_tray/gui/MainApplication.py +++ b/gotify_tray/gui/MainApplication.py @@ -65,7 +65,6 @@ class MainApplication(QtWidgets.QApplication): settings.value("Server/client_token", type=str), ) - self.cache = Cache() self.downloader = Downloader() self.messages_model = MessagesModel() @@ -309,15 +308,14 @@ class MainApplication(QtWidgets.QApplication): return self.messages_model.clear() - + def image_popup_callback(self, link: str, pos: QtCore.QPoint): - if (filename := self.cache.lookup(link)) or (filename := self.downloader.get_filename(link)): # TODO: preload links + if filename := self.downloader.get_filename(link): self.image_popup = ImagePopup(filename, pos, link) self.image_popup.show() else: - # TODO logger.warning(f"Image {link} is not in the cache") - + def main_window_hidden_callback(self): if image_popup := getattr(self, "image_popup", None): image_popup.close() From 4e555631edc2070a219d58147400d67a96ad65ec Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Thu, 1 Sep 2022 21:41:01 +0200 Subject: [PATCH 08/24] do not use the leaveEvent on macos --- gotify_tray/gui/widgets/ImagePopup.py | 17 +++++++++-------- gotify_tray/gui/widgets/MessageWidget.py | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/gotify_tray/gui/widgets/ImagePopup.py b/gotify_tray/gui/widgets/ImagePopup.py index b8799bf..f84d487 100644 --- a/gotify_tray/gui/widgets/ImagePopup.py +++ b/gotify_tray/gui/widgets/ImagePopup.py @@ -1,3 +1,4 @@ +import platform from PyQt6 import QtCore, QtGui, QtWidgets from gotify_tray.database import Settings @@ -18,13 +19,13 @@ class ImagePopup(QtWidgets.QLabel): super(ImagePopup, self).__init__() self.link = link - self.setWindowFlags(QtCore.Qt.WindowType.ToolTip) + self.setWindowFlags(QtCore.Qt.WindowType.Popup) self.installEventFilter(self) - + # Prevent leaving the pop-up open when moving quickly out of the widget self.popup_timer = QtCore.QTimer() self.popup_timer.timeout.connect(self.check_mouse) - + pixmap = QtGui.QPixmap(filename).scaled( settings.value("ImagePopup/w", type=int), settings.value("ImagePopup/h", type=int), @@ -34,19 +35,19 @@ class ImagePopup(QtWidgets.QLabel): self.setPixmap(pixmap) self.move(pos - QtCore.QPoint(15, 15)) - + self.popup_timer.start(500) - + def check_mouse(self): if not self.underMouse(): self.close() - + def close(self): self.popup_timer.stop() super(ImagePopup, self).close() - + def eventFilter(self, object: QtCore.QObject, event: QtCore.QEvent) -> bool: - if event.type() == QtCore.QEvent.Type.Leave: + if platform.system() != "Darwin" and event.type() == QtCore.QEvent.Type.Leave: # Close the pop-up on mouse leave self.close() elif ( diff --git a/gotify_tray/gui/widgets/MessageWidget.py b/gotify_tray/gui/widgets/MessageWidget.py index 2417bf3..70ee1cb 100644 --- a/gotify_tray/gui/widgets/MessageWidget.py +++ b/gotify_tray/gui/widgets/MessageWidget.py @@ -4,7 +4,7 @@ from PyQt6 import QtCore, QtGui, QtWidgets from ..models.MessagesModel import MessageItemDataRole, MessagesModelItem from ..designs.widget_message import Ui_Form -from gotify_tray.database import Cache, Settings +from gotify_tray.database import Settings from gotify_tray.utils import convert_links, get_abs_path From 0cf78c3be600eef79dafb793bdababd5092e1584 Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Fri, 2 Sep 2022 17:21:27 +0200 Subject: [PATCH 09/24] only scale if the image is too large --- gotify_tray/gui/widgets/ImagePopup.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/gotify_tray/gui/widgets/ImagePopup.py b/gotify_tray/gui/widgets/ImagePopup.py index f84d487..8850c6d 100644 --- a/gotify_tray/gui/widgets/ImagePopup.py +++ b/gotify_tray/gui/widgets/ImagePopup.py @@ -26,12 +26,16 @@ class ImagePopup(QtWidgets.QLabel): self.popup_timer = QtCore.QTimer() self.popup_timer.timeout.connect(self.check_mouse) - pixmap = QtGui.QPixmap(filename).scaled( - settings.value("ImagePopup/w", type=int), - settings.value("ImagePopup/h", type=int), - aspectRatioMode=QtCore.Qt.AspectRatioMode.KeepAspectRatio, - transformMode=QtCore.Qt.TransformationMode.SmoothTransformation, - ) + pixmap = QtGui.QPixmap(filename) + W = settings.value("ImagePopup/w", type=int) + H = settings.value("ImagePopup/h", type=int) + if pixmap.height() > H or pixmap.width() > W: + pixmap = pixmap.scaled( + W, + H, + aspectRatioMode=QtCore.Qt.AspectRatioMode.KeepAspectRatio, + transformMode=QtCore.Qt.TransformationMode.SmoothTransformation, + ) self.setPixmap(pixmap) self.move(pos - QtCore.QPoint(15, 15)) From 7a4abb227580894d481d8d26bc83f7637bee9449 Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Fri, 2 Sep 2022 17:40:26 +0200 Subject: [PATCH 10/24] remove url parameters from extension --- gotify_tray/gui/widgets/MessageWidget.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gotify_tray/gui/widgets/MessageWidget.py b/gotify_tray/gui/widgets/MessageWidget.py index 70ee1cb..3aab648 100644 --- a/gotify_tray/gui/widgets/MessageWidget.py +++ b/gotify_tray/gui/widgets/MessageWidget.py @@ -93,7 +93,8 @@ class MessageWidget(QtWidgets.QWidget, Ui_Form): if not settings.value("ImagePopup/enabled", type=bool): return - _, ext = os.path.splitext(link) + qurl = QtCore.QUrl(link) + _, ext = os.path.splitext(qurl.fileName()) if ext in settings.value("ImagePopup/extensions", type=list): self.image_popup.emit(link, QtGui.QCursor.pos()) From 0107beed9a06315411b42e8672eb1a97c4a346c7 Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Fri, 2 Sep 2022 18:17:39 +0200 Subject: [PATCH 11/24] change w/h in settings --- gotify_tray/gui/designs/widget_settings.py | 47 +++++++-- gotify_tray/gui/designs/widget_settings.ui | 107 +++++++++++++++++---- gotify_tray/gui/widgets/SettingsDialog.py | 7 +- 3 files changed, 132 insertions(+), 29 deletions(-) diff --git a/gotify_tray/gui/designs/widget_settings.py b/gotify_tray/gui/designs/widget_settings.py index 0ccd047..7dd9190 100644 --- a/gotify_tray/gui/designs/widget_settings.py +++ b/gotify_tray/gui/designs/widget_settings.py @@ -12,7 +12,7 @@ from PyQt6 import QtCore, QtGui, QtWidgets class Ui_Dialog(object): def setupUi(self, Dialog): Dialog.setObjectName("Dialog") - Dialog.resize(384, 272) + Dialog.resize(384, 300) self.gridLayout = QtWidgets.QGridLayout(Dialog) self.gridLayout.setObjectName("gridLayout") self.buttonBox = QtWidgets.QDialogButtonBox(Dialog) @@ -118,6 +118,29 @@ class Ui_Dialog(object): self.groupBox_2.setObjectName("groupBox_2") self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox_2) self.gridLayout_2.setObjectName("gridLayout_2") + self.horizontalLayout_4 = QtWidgets.QHBoxLayout() + self.horizontalLayout_4.setObjectName("horizontalLayout_4") + self.label = QtWidgets.QLabel(self.groupBox_2) + self.label.setObjectName("label") + self.horizontalLayout_4.addWidget(self.label) + self.spin_popup_w = QtWidgets.QSpinBox(self.groupBox_2) + self.spin_popup_w.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.spin_popup_w.setMinimum(100) + self.spin_popup_w.setMaximum(10000) + self.spin_popup_w.setObjectName("spin_popup_w") + self.horizontalLayout_4.addWidget(self.spin_popup_w) + self.label_2 = QtWidgets.QLabel(self.groupBox_2) + self.label_2.setObjectName("label_2") + self.horizontalLayout_4.addWidget(self.label_2) + self.spin_popup_h = QtWidgets.QSpinBox(self.groupBox_2) + self.spin_popup_h.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.spin_popup_h.setMinimum(100) + self.spin_popup_h.setMaximum(10000) + self.spin_popup_h.setObjectName("spin_popup_h") + self.horizontalLayout_4.addWidget(self.spin_popup_h) + spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_4.addItem(spacerItem4) + self.gridLayout_2.addLayout(self.horizontalLayout_4, 1, 0, 1, 1) self.cb_image_popup = QtWidgets.QCheckBox(self.groupBox_2) self.cb_image_popup.setObjectName("cb_image_popup") self.gridLayout_2.addWidget(self.cb_image_popup, 0, 0, 1, 1) @@ -126,21 +149,21 @@ class Ui_Dialog(object): self.groupBox_logging.setObjectName("groupBox_logging") self.gridLayout_6 = QtWidgets.QGridLayout(self.groupBox_logging) self.gridLayout_6.setObjectName("gridLayout_6") - self.label_logging = QtWidgets.QLabel(self.groupBox_logging) - self.label_logging.setObjectName("label_logging") - self.gridLayout_6.addWidget(self.label_logging, 0, 0, 1, 1) self.combo_logging = QtWidgets.QComboBox(self.groupBox_logging) self.combo_logging.setObjectName("combo_logging") self.gridLayout_6.addWidget(self.combo_logging, 0, 1, 1, 1) + spacerItem5 = QtWidgets.QSpacerItem(190, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.gridLayout_6.addItem(spacerItem5, 0, 3, 1, 1) self.pb_open_log = QtWidgets.QPushButton(self.groupBox_logging) self.pb_open_log.setMaximumSize(QtCore.QSize(30, 16777215)) self.pb_open_log.setObjectName("pb_open_log") self.gridLayout_6.addWidget(self.pb_open_log, 0, 2, 1, 1) - spacerItem4 = QtWidgets.QSpacerItem(190, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) - self.gridLayout_6.addItem(spacerItem4, 0, 3, 1, 1) + self.label_logging = QtWidgets.QLabel(self.groupBox_logging) + self.label_logging.setObjectName("label_logging") + self.gridLayout_6.addWidget(self.label_logging, 0, 0, 1, 1) self.verticalLayout.addWidget(self.groupBox_logging) - spacerItem5 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) - self.verticalLayout.addItem(spacerItem5) + spacerItem6 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout.addItem(spacerItem6) self.tabWidget.addTab(self.tab_advanced, "") self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) @@ -178,11 +201,17 @@ class Ui_Dialog(object): self.pb_import.setText(_translate("Dialog", "Import")) self.pb_export.setText(_translate("Dialog", "Export")) self.groupBox_2.setTitle(_translate("Dialog", "Image pop-up")) + self.label.setToolTip(_translate("Dialog", "Maximum pop-up width")) + self.label.setText(_translate("Dialog", "Width")) + self.spin_popup_w.setToolTip(_translate("Dialog", "Maximum pop-up width")) + self.label_2.setToolTip(_translate("Dialog", "Maximum pop-up height")) + self.label_2.setText(_translate("Dialog", "Height")) + self.spin_popup_h.setToolTip(_translate("Dialog", "Maximum pop-up height")) self.cb_image_popup.setText(_translate("Dialog", "Show an image pop-up when hovering over image URLs")) self.groupBox_logging.setTitle(_translate("Dialog", "Logging")) - self.label_logging.setText(_translate("Dialog", "Level")) self.pb_open_log.setToolTip(_translate("Dialog", "Open logfile")) self.pb_open_log.setText(_translate("Dialog", "...")) + self.label_logging.setText(_translate("Dialog", "Level")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_advanced), _translate("Dialog", "Advanced")) diff --git a/gotify_tray/gui/designs/widget_settings.ui b/gotify_tray/gui/designs/widget_settings.ui index 63fb668..fa9e1d1 100644 --- a/gotify_tray/gui/designs/widget_settings.ui +++ b/gotify_tray/gui/designs/widget_settings.ui @@ -7,7 +7,7 @@ 0 0 384 - 272 + 300 @@ -264,6 +264,75 @@ Image pop-up + + + + + + Maximum pop-up width + + + Width + + + + + + + Maximum pop-up width + + + Qt::AlignCenter + + + 100 + + + 10000 + + + + + + + Maximum pop-up height + + + Height + + + + + + + Maximum pop-up height + + + Qt::AlignCenter + + + 100 + + + 10000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + @@ -280,16 +349,22 @@ Logging - - - - Level - - - + + + + Qt::Horizontal + + + + 190 + 20 + + + + @@ -306,18 +381,12 @@ - - - - Qt::Horizontal + + + + Level - - - 190 - 20 - - - + diff --git a/gotify_tray/gui/widgets/SettingsDialog.py b/gotify_tray/gui/widgets/SettingsDialog.py index 0940ade..3117a3b 100644 --- a/gotify_tray/gui/widgets/SettingsDialog.py +++ b/gotify_tray/gui/widgets/SettingsDialog.py @@ -84,7 +84,8 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog): # Advanced self.cb_image_popup.setChecked(settings.value("ImagePopup/enabled", type=bool)) - # TODO: w/h + self.spin_popup_w.setValue(settings.value("ImagePopup/w", type=int)) + self.spin_popup_h.setValue(settings.value("ImagePopup/h", type=int)) def change_server_info_callback(self): self.server_changed = verify_server(force_new=True, enable_import=False) @@ -179,6 +180,8 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog): self.pb_import.clicked.connect(self.import_callback) self.pb_reset.clicked.connect(self.reset_callback) self.cb_image_popup.stateChanged.connect(self.settings_changed_callback) + self.spin_popup_w.valueChanged.connect(self.settings_changed_callback) + self.spin_popup_h.valueChanged.connect(self.settings_changed_callback) def apply_settings(self): # Priority @@ -210,6 +213,8 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog): # Advanced settings.setValue("ImagePopup/enabled", self.cb_image_popup.isChecked()) + settings.setValue("ImagePopup/w", self.spin_popup_w.value()) + settings.setValue("ImagePopup/h", self.spin_popup_h.value()) self.settings_changed = False self.buttonBox.button( From 685761b9736de6e0100ba2f7b08b683d9ad32cfe Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Sat, 3 Sep 2022 13:06:28 +0200 Subject: [PATCH 12/24] make group box checkable --- gotify_tray/gui/designs/widget_settings.py | 27 ++++++++++------------ gotify_tray/gui/designs/widget_settings.ui | 18 ++++++--------- gotify_tray/gui/widgets/SettingsDialog.py | 6 ++--- 3 files changed, 22 insertions(+), 29 deletions(-) diff --git a/gotify_tray/gui/designs/widget_settings.py b/gotify_tray/gui/designs/widget_settings.py index 7dd9190..fe511fd 100644 --- a/gotify_tray/gui/designs/widget_settings.py +++ b/gotify_tray/gui/designs/widget_settings.py @@ -12,7 +12,7 @@ from PyQt6 import QtCore, QtGui, QtWidgets class Ui_Dialog(object): def setupUi(self, Dialog): Dialog.setObjectName("Dialog") - Dialog.resize(384, 300) + Dialog.resize(384, 277) self.gridLayout = QtWidgets.QGridLayout(Dialog) self.gridLayout.setObjectName("gridLayout") self.buttonBox = QtWidgets.QDialogButtonBox(Dialog) @@ -114,25 +114,26 @@ class Ui_Dialog(object): self.pb_export.setObjectName("pb_export") self.horizontalLayout_2.addWidget(self.pb_export) self.verticalLayout.addWidget(self.groupBox) - self.groupBox_2 = QtWidgets.QGroupBox(self.tab_advanced) - self.groupBox_2.setObjectName("groupBox_2") - self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox_2) + self.groupbox_image_popup = QtWidgets.QGroupBox(self.tab_advanced) + self.groupbox_image_popup.setCheckable(True) + self.groupbox_image_popup.setObjectName("groupbox_image_popup") + self.gridLayout_2 = QtWidgets.QGridLayout(self.groupbox_image_popup) self.gridLayout_2.setObjectName("gridLayout_2") self.horizontalLayout_4 = QtWidgets.QHBoxLayout() self.horizontalLayout_4.setObjectName("horizontalLayout_4") - self.label = QtWidgets.QLabel(self.groupBox_2) + self.label = QtWidgets.QLabel(self.groupbox_image_popup) self.label.setObjectName("label") self.horizontalLayout_4.addWidget(self.label) - self.spin_popup_w = QtWidgets.QSpinBox(self.groupBox_2) + self.spin_popup_w = QtWidgets.QSpinBox(self.groupbox_image_popup) self.spin_popup_w.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) self.spin_popup_w.setMinimum(100) self.spin_popup_w.setMaximum(10000) self.spin_popup_w.setObjectName("spin_popup_w") self.horizontalLayout_4.addWidget(self.spin_popup_w) - self.label_2 = QtWidgets.QLabel(self.groupBox_2) + self.label_2 = QtWidgets.QLabel(self.groupbox_image_popup) self.label_2.setObjectName("label_2") self.horizontalLayout_4.addWidget(self.label_2) - self.spin_popup_h = QtWidgets.QSpinBox(self.groupBox_2) + self.spin_popup_h = QtWidgets.QSpinBox(self.groupbox_image_popup) self.spin_popup_h.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) self.spin_popup_h.setMinimum(100) self.spin_popup_h.setMaximum(10000) @@ -140,11 +141,8 @@ class Ui_Dialog(object): self.horizontalLayout_4.addWidget(self.spin_popup_h) spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) self.horizontalLayout_4.addItem(spacerItem4) - self.gridLayout_2.addLayout(self.horizontalLayout_4, 1, 0, 1, 1) - self.cb_image_popup = QtWidgets.QCheckBox(self.groupBox_2) - self.cb_image_popup.setObjectName("cb_image_popup") - self.gridLayout_2.addWidget(self.cb_image_popup, 0, 0, 1, 1) - self.verticalLayout.addWidget(self.groupBox_2) + self.gridLayout_2.addLayout(self.horizontalLayout_4, 0, 0, 1, 1) + self.verticalLayout.addWidget(self.groupbox_image_popup) self.groupBox_logging = QtWidgets.QGroupBox(self.tab_advanced) self.groupBox_logging.setObjectName("groupBox_logging") self.gridLayout_6 = QtWidgets.QGridLayout(self.groupBox_logging) @@ -200,14 +198,13 @@ class Ui_Dialog(object): self.pb_reset.setText(_translate("Dialog", "Reset")) self.pb_import.setText(_translate("Dialog", "Import")) self.pb_export.setText(_translate("Dialog", "Export")) - self.groupBox_2.setTitle(_translate("Dialog", "Image pop-up")) + self.groupbox_image_popup.setTitle(_translate("Dialog", "Image pop-up for URLs")) self.label.setToolTip(_translate("Dialog", "Maximum pop-up width")) self.label.setText(_translate("Dialog", "Width")) self.spin_popup_w.setToolTip(_translate("Dialog", "Maximum pop-up width")) self.label_2.setToolTip(_translate("Dialog", "Maximum pop-up height")) self.label_2.setText(_translate("Dialog", "Height")) self.spin_popup_h.setToolTip(_translate("Dialog", "Maximum pop-up height")) - self.cb_image_popup.setText(_translate("Dialog", "Show an image pop-up when hovering over image URLs")) self.groupBox_logging.setTitle(_translate("Dialog", "Logging")) self.pb_open_log.setToolTip(_translate("Dialog", "Open logfile")) self.pb_open_log.setText(_translate("Dialog", "...")) diff --git a/gotify_tray/gui/designs/widget_settings.ui b/gotify_tray/gui/designs/widget_settings.ui index fa9e1d1..79c7fdc 100644 --- a/gotify_tray/gui/designs/widget_settings.ui +++ b/gotify_tray/gui/designs/widget_settings.ui @@ -7,7 +7,7 @@ 0 0 384 - 300 + 277 @@ -259,12 +259,15 @@ - + - Image pop-up + Image pop-up for URLs + + + true - + @@ -333,13 +336,6 @@ - - - - Show an image pop-up when hovering over image URLs - - - diff --git a/gotify_tray/gui/widgets/SettingsDialog.py b/gotify_tray/gui/widgets/SettingsDialog.py index 3117a3b..fb28817 100644 --- a/gotify_tray/gui/widgets/SettingsDialog.py +++ b/gotify_tray/gui/widgets/SettingsDialog.py @@ -83,7 +83,7 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog): self.layout_fonts_message.addWidget(self.message_widget) # Advanced - self.cb_image_popup.setChecked(settings.value("ImagePopup/enabled", type=bool)) + self.groupbox_image_popup.setChecked(settings.value("ImagePopup/enabled", type=bool)) self.spin_popup_w.setValue(settings.value("ImagePopup/w", type=int)) self.spin_popup_h.setValue(settings.value("ImagePopup/h", type=int)) @@ -179,7 +179,7 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog): self.pb_export.clicked.connect(self.export_callback) self.pb_import.clicked.connect(self.import_callback) self.pb_reset.clicked.connect(self.reset_callback) - self.cb_image_popup.stateChanged.connect(self.settings_changed_callback) + self.groupbox_image_popup.toggled.connect(self.settings_changed_callback) self.spin_popup_w.valueChanged.connect(self.settings_changed_callback) self.spin_popup_h.valueChanged.connect(self.settings_changed_callback) @@ -212,7 +212,7 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog): ) # Advanced - settings.setValue("ImagePopup/enabled", self.cb_image_popup.isChecked()) + settings.setValue("ImagePopup/enabled", self.groupbox_image_popup.isChecked()) settings.setValue("ImagePopup/w", self.spin_popup_w.value()) settings.setValue("ImagePopup/h", self.spin_popup_h.value()) From 28fef2c9de1c9bf55c09ff6175f585633ab06acb Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Sun, 28 Aug 2022 15:22:41 +0200 Subject: [PATCH 13/24] basic image pop-up on hover --- gotify_tray/database/default_settings.py | 3 ++ gotify_tray/gui/MainApplication.py | 12 +++++- gotify_tray/gui/designs/widget_settings.py | 32 +++++++++------ gotify_tray/gui/designs/widget_settings.ui | 26 +++++++++--- gotify_tray/gui/widgets/ImagePopup.py | 46 ++++++++++++++++++++++ gotify_tray/gui/widgets/MainWindow.py | 2 + gotify_tray/gui/widgets/MessageWidget.py | 14 ++++++- gotify_tray/gui/widgets/SettingsDialog.py | 8 ++++ gotify_tray/gui/widgets/__init__.py | 1 + 9 files changed, 126 insertions(+), 18 deletions(-) create mode 100644 gotify_tray/gui/widgets/ImagePopup.py diff --git a/gotify_tray/database/default_settings.py b/gotify_tray/database/default_settings.py index db8d6dc..b2f32d4 100644 --- a/gotify_tray/database/default_settings.py +++ b/gotify_tray/database/default_settings.py @@ -20,4 +20,7 @@ DEFAULT_SETTINGS = { "MainWindow/label/size": 25, "MainWindow/button/size": 33, "MainWindow/application/icon/size": 40, + "ImagePopup/enabled": False, + "ImagePopup/w": 400, + "ImagePopup/h": 400, } diff --git a/gotify_tray/gui/MainApplication.py b/gotify_tray/gui/MainApplication.py index 1d16eb5..e3db4a1 100644 --- a/gotify_tray/gui/MainApplication.py +++ b/gotify_tray/gui/MainApplication.py @@ -31,7 +31,7 @@ from .models import ( MessagesModelItem, MessageItemDataRole, ) -from .widgets import MainWindow, SettingsDialog, Tray +from .widgets import ImagePopup, MainWindow, SettingsDialog, Tray settings = Settings("gotify-tray") @@ -65,6 +65,7 @@ class MainApplication(QtWidgets.QApplication): settings.value("Server/client_token", type=str), ) + self.cache = Cache() self.downloader = Downloader() self.messages_model = MessagesModel() @@ -308,6 +309,14 @@ class MainApplication(QtWidgets.QApplication): return self.messages_model.clear() + + def image_popup_callback(self, link: str, pos: QtCore.QPoint): + if (filename := self.cache.lookup(link)) or (filename := self.downloader.get_filename(link)): # TODO: preload links + self.image_popup = ImagePopup(filename, pos, link) + self.image_popup.show() + else: + # TODO + logger.warning(f"Image {link} is not in the cache") def refresh_callback(self): # Manual refresh -> also reset the image cache @@ -362,6 +371,7 @@ class MainApplication(QtWidgets.QApplication): self.application_selection_changed_callback ) self.main_window.delete_message.connect(self.delete_message_callback) + self.main_window.image_popup.connect(self.image_popup_callback) self.watchdog.closed.connect(lambda: self.listener_closed_callback(None, None)) diff --git a/gotify_tray/gui/designs/widget_settings.py b/gotify_tray/gui/designs/widget_settings.py index 530e3e3..a4bddb7 100644 --- a/gotify_tray/gui/designs/widget_settings.py +++ b/gotify_tray/gui/designs/widget_settings.py @@ -105,18 +105,26 @@ class Ui_Dialog(object): self.verticalLayout.setObjectName("verticalLayout") self.groupBox = QtWidgets.QGroupBox(self.tab_advanced) self.groupBox.setObjectName("groupBox") - self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.groupBox) - self.verticalLayout_2.setObjectName("verticalLayout_2") - self.pb_export = QtWidgets.QPushButton(self.groupBox) - self.pb_export.setObjectName("pb_export") - self.verticalLayout_2.addWidget(self.pb_export) - self.pb_import = QtWidgets.QPushButton(self.groupBox) - self.pb_import.setObjectName("pb_import") - self.verticalLayout_2.addWidget(self.pb_import) + self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.groupBox) + self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.pb_reset = QtWidgets.QPushButton(self.groupBox) self.pb_reset.setObjectName("pb_reset") - self.verticalLayout_2.addWidget(self.pb_reset) + self.horizontalLayout_2.addWidget(self.pb_reset) + self.pb_import = QtWidgets.QPushButton(self.groupBox) + self.pb_import.setObjectName("pb_import") + self.horizontalLayout_2.addWidget(self.pb_import) + self.pb_export = QtWidgets.QPushButton(self.groupBox) + self.pb_export.setObjectName("pb_export") + self.horizontalLayout_2.addWidget(self.pb_export) self.verticalLayout.addWidget(self.groupBox) + self.groupBox_2 = QtWidgets.QGroupBox(self.tab_advanced) + self.groupBox_2.setObjectName("groupBox_2") + self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox_2) + self.gridLayout_2.setObjectName("gridLayout_2") + self.cb_image_popup = QtWidgets.QCheckBox(self.groupBox_2) + self.cb_image_popup.setObjectName("cb_image_popup") + self.gridLayout_2.addWidget(self.cb_image_popup, 0, 0, 1, 1) + self.verticalLayout.addWidget(self.groupBox_2) self.groupBox_logging = QtWidgets.QGroupBox(self.tab_advanced) self.groupBox_logging.setObjectName("groupBox_logging") self.gridLayout_6 = QtWidgets.QGridLayout(self.groupBox_logging) @@ -170,9 +178,11 @@ class Ui_Dialog(object): self.pb_font_message_content.setText(_translate("Dialog", "Message")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_fonts), _translate("Dialog", "Fonts")) self.groupBox.setTitle(_translate("Dialog", "Settings")) - self.pb_export.setText(_translate("Dialog", "Export")) - self.pb_import.setText(_translate("Dialog", "Import")) self.pb_reset.setText(_translate("Dialog", "Reset")) + self.pb_import.setText(_translate("Dialog", "Import")) + self.pb_export.setText(_translate("Dialog", "Export")) + self.groupBox_2.setTitle(_translate("Dialog", "Image pop-up")) + self.cb_image_popup.setText(_translate("Dialog", "Show an image pop-up when hovering over image URLs")) self.groupBox_logging.setTitle(_translate("Dialog", "Logging")) self.label_logging.setText(_translate("Dialog", "Level")) self.pb_open_log.setToolTip(_translate("Dialog", "Open logfile")) diff --git a/gotify_tray/gui/designs/widget_settings.ui b/gotify_tray/gui/designs/widget_settings.ui index 3abaad3..d261fde 100644 --- a/gotify_tray/gui/designs/widget_settings.ui +++ b/gotify_tray/gui/designs/widget_settings.ui @@ -240,11 +240,11 @@ Settings - + - + - Export + Reset @@ -256,9 +256,25 @@ - + - Reset + Export + + + + + + + + + + Image pop-up + + + + + + Show an image pop-up when hovering over image URLs diff --git a/gotify_tray/gui/widgets/ImagePopup.py b/gotify_tray/gui/widgets/ImagePopup.py new file mode 100644 index 0000000..e61955d --- /dev/null +++ b/gotify_tray/gui/widgets/ImagePopup.py @@ -0,0 +1,46 @@ +from PyQt6 import QtCore, QtGui, QtWidgets + +from gotify_tray.database import Settings + + +settings = Settings("gotify-tray") + + +class ImagePopup(QtWidgets.QLabel): + def __init__(self, filename: str, pos: QtCore.QPoint, link: str = None): + """Create and show a pop-up image under the cursor + + Args: + filename (str): The path to the image to display + pos (QtCore.QPoint): The location at which the image should be displayed + link (str, optional): The URL of the image. Defaults to None. + """ + super(ImagePopup, self).__init__() + self.link = link + + self.setWindowFlags(QtCore.Qt.WindowType.ToolTip) + self.installEventFilter(self) + + self.setPixmap( + QtGui.QPixmap(filename).scaled( + settings.value("ImagePopup/w", type=int), + settings.value("ImagePopup/h", type=int), + QtCore.Qt.AspectRatioMode.KeepAspectRatio, + ) + ) + self.move(pos - QtCore.QPoint(30, 30)) + self.show() + + def eventFilter(self, object: QtCore.QObject, event: QtCore.QEvent) -> bool: + if event.type() == QtCore.QEvent.Type.Leave: + # Close the pop-up on mouse leave + self.close() + elif ( + event.type() == QtCore.QEvent.Type.MouseButtonPress + and event.button() == QtCore.Qt.MouseButton.LeftButton + and self.link + ): + # Open the image URL on left click + QtGui.QDesktopServices.openUrl(QtCore.QUrl(self.link)) + + return super().eventFilter(object, event) diff --git a/gotify_tray/gui/widgets/MainWindow.py b/gotify_tray/gui/widgets/MainWindow.py index 21faa98..541f44c 100644 --- a/gotify_tray/gui/widgets/MainWindow.py +++ b/gotify_tray/gui/widgets/MainWindow.py @@ -21,6 +21,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): delete_all = QtCore.pyqtSignal(QtGui.QStandardItem) delete_message = QtCore.pyqtSignal(MessagesModelItem) application_selection_changed = QtCore.pyqtSignal(QtGui.QStandardItem) + image_popup = QtCore.pyqtSignal(str, QtCore.QPoint) def __init__( self, application_model: ApplicationModel, messages_model: MessagesModel @@ -103,6 +104,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): self.messages_model.indexFromItem(message_item), message_widget ) message_widget.deletion_requested.connect(self.delete_message.emit) + message_widget.image_popup.connect(self.image_popup.emit) def currentApplicationIndex(self) -> QtCore.QModelIndex: return self.listView_applications.selectionModel().currentIndex() diff --git a/gotify_tray/gui/widgets/MessageWidget.py b/gotify_tray/gui/widgets/MessageWidget.py index db1cde6..3b6eb9c 100644 --- a/gotify_tray/gui/widgets/MessageWidget.py +++ b/gotify_tray/gui/widgets/MessageWidget.py @@ -1,8 +1,10 @@ +import os + from PyQt6 import QtCore, QtGui, QtWidgets from ..models.MessagesModel import MessageItemDataRole, MessagesModelItem from ..designs.widget_message import Ui_Form -from gotify_tray.database import Settings +from gotify_tray.database import Cache, Settings from gotify_tray.utils import convert_links, get_abs_path @@ -11,6 +13,7 @@ settings = Settings("gotify-tray") class MessageWidget(QtWidgets.QWidget, Ui_Form): deletion_requested = QtCore.pyqtSignal(MessagesModelItem) + image_popup = QtCore.pyqtSignal(str, QtCore.QPoint) def __init__(self, message_item: MessagesModelItem, image_path: str = ""): super(MessageWidget, self).__init__() @@ -86,7 +89,16 @@ class MessageWidget(QtWidgets.QWidget, Ui_Form): self.label_date.setFont(font_date) self.label_message.setFont(font_content) + def link_hovered_callback(self, link: str): + if not settings.value("ImagePopup/enabled", type=bool): + return + + _, ext = os.path.splitext(link) + if ext in [".jpg", ".jpeg", ".png"]: + self.image_popup.emit(link, QtGui.QCursor.pos()) + def link_callbacks(self): self.pb_delete.clicked.connect( lambda: self.deletion_requested.emit(self.message_item) ) + self.label_message.linkHovered.connect(self.link_hovered_callback) diff --git a/gotify_tray/gui/widgets/SettingsDialog.py b/gotify_tray/gui/widgets/SettingsDialog.py index 45fb368..7d38427 100644 --- a/gotify_tray/gui/widgets/SettingsDialog.py +++ b/gotify_tray/gui/widgets/SettingsDialog.py @@ -86,6 +86,10 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog): ) self.layout_fonts_message.addWidget(self.message_widget) + # Advanced + self.cb_image_popup.setChecked(settings.value("ImagePopup/enabled", type=bool)) + # TODO: w/h + def change_server_info_callback(self): self.server_changed = verify_server(force_new=True, enable_import=False) @@ -179,6 +183,7 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog): self.pb_export.clicked.connect(self.export_callback) self.pb_import.clicked.connect(self.import_callback) self.pb_reset.clicked.connect(self.reset_callback) + self.cb_image_popup.stateChanged.connect(self.settings_changed_callback) def apply_settings(self): # Priority @@ -211,6 +216,9 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog): self.message_widget.label_message.font().toString(), ) + # Advanced + settings.setValue("ImagePopup/enabled", self.cb_image_popup.isChecked()) + self.settings_changed = False self.buttonBox.button( QtWidgets.QDialogButtonBox.StandardButton.Apply diff --git a/gotify_tray/gui/widgets/__init__.py b/gotify_tray/gui/widgets/__init__.py index d43f65f..2f9952f 100644 --- a/gotify_tray/gui/widgets/__init__.py +++ b/gotify_tray/gui/widgets/__init__.py @@ -1,3 +1,4 @@ +from .ImagePopup import ImagePopup from .MessageWidget import MessageWidget from .MainWindow import MainWindow from .ServerInfoDialog import ServerInfoDialog From 1b4fec83d40f4b2e15de0889e1090fe92af49662 Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Sun, 28 Aug 2022 16:06:46 +0200 Subject: [PATCH 14/24] make sure the pop-up is closed when the main window is hidden --- gotify_tray/gui/MainApplication.py | 6 +++++- gotify_tray/gui/widgets/MainWindow.py | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/gotify_tray/gui/MainApplication.py b/gotify_tray/gui/MainApplication.py index e3db4a1..3bba6ba 100644 --- a/gotify_tray/gui/MainApplication.py +++ b/gotify_tray/gui/MainApplication.py @@ -313,10 +313,13 @@ class MainApplication(QtWidgets.QApplication): def image_popup_callback(self, link: str, pos: QtCore.QPoint): if (filename := self.cache.lookup(link)) or (filename := self.downloader.get_filename(link)): # TODO: preload links self.image_popup = ImagePopup(filename, pos, link) - self.image_popup.show() else: # TODO logger.warning(f"Image {link} is not in the cache") + + def main_window_hidden_callback(self): + if image_popup := getattr(self, "image_popup", None): + image_popup.close() def refresh_callback(self): # Manual refresh -> also reset the image cache @@ -372,6 +375,7 @@ class MainApplication(QtWidgets.QApplication): ) self.main_window.delete_message.connect(self.delete_message_callback) self.main_window.image_popup.connect(self.image_popup_callback) + self.main_window.hidden.connect(self.main_window_hidden_callback) self.watchdog.closed.connect(lambda: self.listener_closed_callback(None, None)) diff --git a/gotify_tray/gui/widgets/MainWindow.py b/gotify_tray/gui/widgets/MainWindow.py index 541f44c..26ed8b3 100644 --- a/gotify_tray/gui/widgets/MainWindow.py +++ b/gotify_tray/gui/widgets/MainWindow.py @@ -22,6 +22,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): delete_message = QtCore.pyqtSignal(MessagesModelItem) application_selection_changed = QtCore.pyqtSignal(QtGui.QStandardItem) image_popup = QtCore.pyqtSignal(str, QtCore.QPoint) + hidden = QtCore.pyqtSignal() def __init__( self, application_model: ApplicationModel, messages_model: MessagesModel @@ -175,3 +176,4 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def closeEvent(self, e: QtGui.QCloseEvent) -> None: self.hide() + self.hidden.emit() From dc81f443aae4cdaa7a58f648be5d741030e42ad2 Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Sun, 28 Aug 2022 16:07:50 +0200 Subject: [PATCH 15/24] center the image on the cursor --- gotify_tray/gui/widgets/ImagePopup.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gotify_tray/gui/widgets/ImagePopup.py b/gotify_tray/gui/widgets/ImagePopup.py index e61955d..35c2d01 100644 --- a/gotify_tray/gui/widgets/ImagePopup.py +++ b/gotify_tray/gui/widgets/ImagePopup.py @@ -21,14 +21,14 @@ class ImagePopup(QtWidgets.QLabel): self.setWindowFlags(QtCore.Qt.WindowType.ToolTip) self.installEventFilter(self) - self.setPixmap( - QtGui.QPixmap(filename).scaled( + pixmap = QtGui.QPixmap(filename).scaled( settings.value("ImagePopup/w", type=int), settings.value("ImagePopup/h", type=int), QtCore.Qt.AspectRatioMode.KeepAspectRatio, ) - ) - self.move(pos - QtCore.QPoint(30, 30)) + self.setPixmap(pixmap) + + self.move(pos - QtCore.QPoint(pixmap.width()/2, pixmap.height()/2)) self.show() def eventFilter(self, object: QtCore.QObject, event: QtCore.QEvent) -> bool: From a53ff4cee2dc26b444f9f705b540a95bede87e6b Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Sun, 28 Aug 2022 16:11:18 +0200 Subject: [PATCH 16/24] scale with SmoothTransformation --- gotify_tray/gui/widgets/ImagePopup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gotify_tray/gui/widgets/ImagePopup.py b/gotify_tray/gui/widgets/ImagePopup.py index 35c2d01..63fdd32 100644 --- a/gotify_tray/gui/widgets/ImagePopup.py +++ b/gotify_tray/gui/widgets/ImagePopup.py @@ -24,7 +24,8 @@ class ImagePopup(QtWidgets.QLabel): pixmap = QtGui.QPixmap(filename).scaled( settings.value("ImagePopup/w", type=int), settings.value("ImagePopup/h", type=int), - QtCore.Qt.AspectRatioMode.KeepAspectRatio, + aspectRatioMode=QtCore.Qt.AspectRatioMode.KeepAspectRatio, + transformMode=QtCore.Qt.TransformationMode.SmoothTransformation ) self.setPixmap(pixmap) From 6b2536916fb547374215b2eef9ab8f6714fc43bc Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Sun, 28 Aug 2022 21:24:41 +0200 Subject: [PATCH 17/24] track underMouse --- gotify_tray/gui/MainApplication.py | 1 + gotify_tray/gui/widgets/ImagePopup.py | 33 +++++++++++++++++++-------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/gotify_tray/gui/MainApplication.py b/gotify_tray/gui/MainApplication.py index 3bba6ba..c99b802 100644 --- a/gotify_tray/gui/MainApplication.py +++ b/gotify_tray/gui/MainApplication.py @@ -313,6 +313,7 @@ class MainApplication(QtWidgets.QApplication): def image_popup_callback(self, link: str, pos: QtCore.QPoint): if (filename := self.cache.lookup(link)) or (filename := self.downloader.get_filename(link)): # TODO: preload links self.image_popup = ImagePopup(filename, pos, link) + self.image_popup.show() else: # TODO logger.warning(f"Image {link} is not in the cache") diff --git a/gotify_tray/gui/widgets/ImagePopup.py b/gotify_tray/gui/widgets/ImagePopup.py index 63fdd32..b8799bf 100644 --- a/gotify_tray/gui/widgets/ImagePopup.py +++ b/gotify_tray/gui/widgets/ImagePopup.py @@ -20,18 +20,31 @@ class ImagePopup(QtWidgets.QLabel): self.setWindowFlags(QtCore.Qt.WindowType.ToolTip) self.installEventFilter(self) - - pixmap = QtGui.QPixmap(filename).scaled( - settings.value("ImagePopup/w", type=int), - settings.value("ImagePopup/h", type=int), - aspectRatioMode=QtCore.Qt.AspectRatioMode.KeepAspectRatio, - transformMode=QtCore.Qt.TransformationMode.SmoothTransformation - ) - self.setPixmap(pixmap) - self.move(pos - QtCore.QPoint(pixmap.width()/2, pixmap.height()/2)) - self.show() + # Prevent leaving the pop-up open when moving quickly out of the widget + self.popup_timer = QtCore.QTimer() + self.popup_timer.timeout.connect(self.check_mouse) + + pixmap = QtGui.QPixmap(filename).scaled( + settings.value("ImagePopup/w", type=int), + settings.value("ImagePopup/h", type=int), + aspectRatioMode=QtCore.Qt.AspectRatioMode.KeepAspectRatio, + transformMode=QtCore.Qt.TransformationMode.SmoothTransformation, + ) + self.setPixmap(pixmap) + self.move(pos - QtCore.QPoint(15, 15)) + + self.popup_timer.start(500) + + def check_mouse(self): + if not self.underMouse(): + self.close() + + def close(self): + self.popup_timer.stop() + super(ImagePopup, self).close() + def eventFilter(self, object: QtCore.QObject, event: QtCore.QEvent) -> bool: if event.type() == QtCore.QEvent.Type.Leave: # Close the pop-up on mouse leave From 7957c0c4d65539dce3e0f3f43f55bb6ba6e8b75d Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Thu, 1 Sep 2022 21:38:22 +0200 Subject: [PATCH 18/24] add extensions to default settings --- gotify_tray/database/default_settings.py | 1 + gotify_tray/gui/widgets/MessageWidget.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/gotify_tray/database/default_settings.py b/gotify_tray/database/default_settings.py index b2f32d4..2c8b65a 100644 --- a/gotify_tray/database/default_settings.py +++ b/gotify_tray/database/default_settings.py @@ -21,6 +21,7 @@ DEFAULT_SETTINGS = { "MainWindow/button/size": 33, "MainWindow/application/icon/size": 40, "ImagePopup/enabled": False, + "ImagePopup/extensions": [".jpg", ".jpeg", ".png", ".svg"], "ImagePopup/w": 400, "ImagePopup/h": 400, } diff --git a/gotify_tray/gui/widgets/MessageWidget.py b/gotify_tray/gui/widgets/MessageWidget.py index 3b6eb9c..2417bf3 100644 --- a/gotify_tray/gui/widgets/MessageWidget.py +++ b/gotify_tray/gui/widgets/MessageWidget.py @@ -94,7 +94,7 @@ class MessageWidget(QtWidgets.QWidget, Ui_Form): return _, ext = os.path.splitext(link) - if ext in [".jpg", ".jpeg", ".png"]: + if ext in settings.value("ImagePopup/extensions", type=list): self.image_popup.emit(link, QtGui.QCursor.pos()) def link_callbacks(self): From 70ec1d2efa59d1f44ed3feb44e718cefcda9bd67 Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Thu, 1 Sep 2022 21:39:24 +0200 Subject: [PATCH 19/24] do not read cache twice --- gotify_tray/gui/MainApplication.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/gotify_tray/gui/MainApplication.py b/gotify_tray/gui/MainApplication.py index c99b802..d5651b6 100644 --- a/gotify_tray/gui/MainApplication.py +++ b/gotify_tray/gui/MainApplication.py @@ -65,7 +65,6 @@ class MainApplication(QtWidgets.QApplication): settings.value("Server/client_token", type=str), ) - self.cache = Cache() self.downloader = Downloader() self.messages_model = MessagesModel() @@ -309,15 +308,14 @@ class MainApplication(QtWidgets.QApplication): return self.messages_model.clear() - + def image_popup_callback(self, link: str, pos: QtCore.QPoint): - if (filename := self.cache.lookup(link)) or (filename := self.downloader.get_filename(link)): # TODO: preload links + if filename := self.downloader.get_filename(link): self.image_popup = ImagePopup(filename, pos, link) self.image_popup.show() else: - # TODO logger.warning(f"Image {link} is not in the cache") - + def main_window_hidden_callback(self): if image_popup := getattr(self, "image_popup", None): image_popup.close() From 3b9931826ac09d4edbb7017f62458e7a41f2ee65 Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Thu, 1 Sep 2022 21:41:01 +0200 Subject: [PATCH 20/24] do not use the leaveEvent on macos --- gotify_tray/gui/widgets/ImagePopup.py | 17 +++++++++-------- gotify_tray/gui/widgets/MessageWidget.py | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/gotify_tray/gui/widgets/ImagePopup.py b/gotify_tray/gui/widgets/ImagePopup.py index b8799bf..f84d487 100644 --- a/gotify_tray/gui/widgets/ImagePopup.py +++ b/gotify_tray/gui/widgets/ImagePopup.py @@ -1,3 +1,4 @@ +import platform from PyQt6 import QtCore, QtGui, QtWidgets from gotify_tray.database import Settings @@ -18,13 +19,13 @@ class ImagePopup(QtWidgets.QLabel): super(ImagePopup, self).__init__() self.link = link - self.setWindowFlags(QtCore.Qt.WindowType.ToolTip) + self.setWindowFlags(QtCore.Qt.WindowType.Popup) self.installEventFilter(self) - + # Prevent leaving the pop-up open when moving quickly out of the widget self.popup_timer = QtCore.QTimer() self.popup_timer.timeout.connect(self.check_mouse) - + pixmap = QtGui.QPixmap(filename).scaled( settings.value("ImagePopup/w", type=int), settings.value("ImagePopup/h", type=int), @@ -34,19 +35,19 @@ class ImagePopup(QtWidgets.QLabel): self.setPixmap(pixmap) self.move(pos - QtCore.QPoint(15, 15)) - + self.popup_timer.start(500) - + def check_mouse(self): if not self.underMouse(): self.close() - + def close(self): self.popup_timer.stop() super(ImagePopup, self).close() - + def eventFilter(self, object: QtCore.QObject, event: QtCore.QEvent) -> bool: - if event.type() == QtCore.QEvent.Type.Leave: + if platform.system() != "Darwin" and event.type() == QtCore.QEvent.Type.Leave: # Close the pop-up on mouse leave self.close() elif ( diff --git a/gotify_tray/gui/widgets/MessageWidget.py b/gotify_tray/gui/widgets/MessageWidget.py index 2417bf3..70ee1cb 100644 --- a/gotify_tray/gui/widgets/MessageWidget.py +++ b/gotify_tray/gui/widgets/MessageWidget.py @@ -4,7 +4,7 @@ from PyQt6 import QtCore, QtGui, QtWidgets from ..models.MessagesModel import MessageItemDataRole, MessagesModelItem from ..designs.widget_message import Ui_Form -from gotify_tray.database import Cache, Settings +from gotify_tray.database import Settings from gotify_tray.utils import convert_links, get_abs_path From b640c7a852b7803e658449d45d940c24080a4dbe Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Fri, 2 Sep 2022 17:21:27 +0200 Subject: [PATCH 21/24] only scale if the image is too large --- gotify_tray/gui/widgets/ImagePopup.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/gotify_tray/gui/widgets/ImagePopup.py b/gotify_tray/gui/widgets/ImagePopup.py index f84d487..8850c6d 100644 --- a/gotify_tray/gui/widgets/ImagePopup.py +++ b/gotify_tray/gui/widgets/ImagePopup.py @@ -26,12 +26,16 @@ class ImagePopup(QtWidgets.QLabel): self.popup_timer = QtCore.QTimer() self.popup_timer.timeout.connect(self.check_mouse) - pixmap = QtGui.QPixmap(filename).scaled( - settings.value("ImagePopup/w", type=int), - settings.value("ImagePopup/h", type=int), - aspectRatioMode=QtCore.Qt.AspectRatioMode.KeepAspectRatio, - transformMode=QtCore.Qt.TransformationMode.SmoothTransformation, - ) + pixmap = QtGui.QPixmap(filename) + W = settings.value("ImagePopup/w", type=int) + H = settings.value("ImagePopup/h", type=int) + if pixmap.height() > H or pixmap.width() > W: + pixmap = pixmap.scaled( + W, + H, + aspectRatioMode=QtCore.Qt.AspectRatioMode.KeepAspectRatio, + transformMode=QtCore.Qt.TransformationMode.SmoothTransformation, + ) self.setPixmap(pixmap) self.move(pos - QtCore.QPoint(15, 15)) From 23250acf31d9089b6f64a13a6f6e151d8188003c Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Fri, 2 Sep 2022 17:40:26 +0200 Subject: [PATCH 22/24] remove url parameters from extension --- gotify_tray/gui/widgets/MessageWidget.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gotify_tray/gui/widgets/MessageWidget.py b/gotify_tray/gui/widgets/MessageWidget.py index 70ee1cb..3aab648 100644 --- a/gotify_tray/gui/widgets/MessageWidget.py +++ b/gotify_tray/gui/widgets/MessageWidget.py @@ -93,7 +93,8 @@ class MessageWidget(QtWidgets.QWidget, Ui_Form): if not settings.value("ImagePopup/enabled", type=bool): return - _, ext = os.path.splitext(link) + qurl = QtCore.QUrl(link) + _, ext = os.path.splitext(qurl.fileName()) if ext in settings.value("ImagePopup/extensions", type=list): self.image_popup.emit(link, QtGui.QCursor.pos()) From 96cf4f71f0596d6e824998e07c5e71221ea03f49 Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Fri, 2 Sep 2022 18:17:39 +0200 Subject: [PATCH 23/24] change w/h in settings --- gotify_tray/gui/designs/widget_settings.py | 45 +++++++-- gotify_tray/gui/designs/widget_settings.ui | 105 +++++++++++++++++---- gotify_tray/gui/widgets/SettingsDialog.py | 7 +- 3 files changed, 130 insertions(+), 27 deletions(-) diff --git a/gotify_tray/gui/designs/widget_settings.py b/gotify_tray/gui/designs/widget_settings.py index a4bddb7..649a69b 100644 --- a/gotify_tray/gui/designs/widget_settings.py +++ b/gotify_tray/gui/designs/widget_settings.py @@ -121,6 +121,29 @@ class Ui_Dialog(object): self.groupBox_2.setObjectName("groupBox_2") self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox_2) self.gridLayout_2.setObjectName("gridLayout_2") + self.horizontalLayout_4 = QtWidgets.QHBoxLayout() + self.horizontalLayout_4.setObjectName("horizontalLayout_4") + self.label = QtWidgets.QLabel(self.groupBox_2) + self.label.setObjectName("label") + self.horizontalLayout_4.addWidget(self.label) + self.spin_popup_w = QtWidgets.QSpinBox(self.groupBox_2) + self.spin_popup_w.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.spin_popup_w.setMinimum(100) + self.spin_popup_w.setMaximum(10000) + self.spin_popup_w.setObjectName("spin_popup_w") + self.horizontalLayout_4.addWidget(self.spin_popup_w) + self.label_2 = QtWidgets.QLabel(self.groupBox_2) + self.label_2.setObjectName("label_2") + self.horizontalLayout_4.addWidget(self.label_2) + self.spin_popup_h = QtWidgets.QSpinBox(self.groupBox_2) + self.spin_popup_h.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.spin_popup_h.setMinimum(100) + self.spin_popup_h.setMaximum(10000) + self.spin_popup_h.setObjectName("spin_popup_h") + self.horizontalLayout_4.addWidget(self.spin_popup_h) + spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_4.addItem(spacerItem4) + self.gridLayout_2.addLayout(self.horizontalLayout_4, 1, 0, 1, 1) self.cb_image_popup = QtWidgets.QCheckBox(self.groupBox_2) self.cb_image_popup.setObjectName("cb_image_popup") self.gridLayout_2.addWidget(self.cb_image_popup, 0, 0, 1, 1) @@ -129,21 +152,21 @@ class Ui_Dialog(object): self.groupBox_logging.setObjectName("groupBox_logging") self.gridLayout_6 = QtWidgets.QGridLayout(self.groupBox_logging) self.gridLayout_6.setObjectName("gridLayout_6") - self.label_logging = QtWidgets.QLabel(self.groupBox_logging) - self.label_logging.setObjectName("label_logging") - self.gridLayout_6.addWidget(self.label_logging, 0, 0, 1, 1) self.combo_logging = QtWidgets.QComboBox(self.groupBox_logging) self.combo_logging.setObjectName("combo_logging") self.gridLayout_6.addWidget(self.combo_logging, 0, 1, 1, 1) + spacerItem5 = QtWidgets.QSpacerItem(190, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.gridLayout_6.addItem(spacerItem5, 0, 3, 1, 1) self.pb_open_log = QtWidgets.QPushButton(self.groupBox_logging) self.pb_open_log.setMaximumSize(QtCore.QSize(30, 16777215)) self.pb_open_log.setObjectName("pb_open_log") self.gridLayout_6.addWidget(self.pb_open_log, 0, 2, 1, 1) - spacerItem4 = QtWidgets.QSpacerItem(190, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) - self.gridLayout_6.addItem(spacerItem4, 0, 3, 1, 1) + self.label_logging = QtWidgets.QLabel(self.groupBox_logging) + self.label_logging.setObjectName("label_logging") + self.gridLayout_6.addWidget(self.label_logging, 0, 0, 1, 1) self.verticalLayout.addWidget(self.groupBox_logging) - spacerItem5 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) - self.verticalLayout.addItem(spacerItem5) + spacerItem6 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout.addItem(spacerItem6) self.tabWidget.addTab(self.tab_advanced, "") self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) @@ -182,11 +205,17 @@ class Ui_Dialog(object): self.pb_import.setText(_translate("Dialog", "Import")) self.pb_export.setText(_translate("Dialog", "Export")) self.groupBox_2.setTitle(_translate("Dialog", "Image pop-up")) + self.label.setToolTip(_translate("Dialog", "Maximum pop-up width")) + self.label.setText(_translate("Dialog", "Width")) + self.spin_popup_w.setToolTip(_translate("Dialog", "Maximum pop-up width")) + self.label_2.setToolTip(_translate("Dialog", "Maximum pop-up height")) + self.label_2.setText(_translate("Dialog", "Height")) + self.spin_popup_h.setToolTip(_translate("Dialog", "Maximum pop-up height")) self.cb_image_popup.setText(_translate("Dialog", "Show an image pop-up when hovering over image URLs")) self.groupBox_logging.setTitle(_translate("Dialog", "Logging")) - self.label_logging.setText(_translate("Dialog", "Level")) self.pb_open_log.setToolTip(_translate("Dialog", "Open logfile")) self.pb_open_log.setText(_translate("Dialog", "...")) + self.label_logging.setText(_translate("Dialog", "Level")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_advanced), _translate("Dialog", "Advanced")) diff --git a/gotify_tray/gui/designs/widget_settings.ui b/gotify_tray/gui/designs/widget_settings.ui index d261fde..421b54f 100644 --- a/gotify_tray/gui/designs/widget_settings.ui +++ b/gotify_tray/gui/designs/widget_settings.ui @@ -271,6 +271,75 @@ Image pop-up + + + + + + Maximum pop-up width + + + Width + + + + + + + Maximum pop-up width + + + Qt::AlignCenter + + + 100 + + + 10000 + + + + + + + Maximum pop-up height + + + Height + + + + + + + Maximum pop-up height + + + Qt::AlignCenter + + + 100 + + + 10000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + @@ -287,16 +356,22 @@ Logging - - - - Level - - - + + + + Qt::Horizontal + + + + 190 + 20 + + + + @@ -313,18 +388,12 @@ - - - - Qt::Horizontal + + + + Level - - - 190 - 20 - - - + diff --git a/gotify_tray/gui/widgets/SettingsDialog.py b/gotify_tray/gui/widgets/SettingsDialog.py index 7d38427..cd5ff93 100644 --- a/gotify_tray/gui/widgets/SettingsDialog.py +++ b/gotify_tray/gui/widgets/SettingsDialog.py @@ -88,7 +88,8 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog): # Advanced self.cb_image_popup.setChecked(settings.value("ImagePopup/enabled", type=bool)) - # TODO: w/h + self.spin_popup_w.setValue(settings.value("ImagePopup/w", type=int)) + self.spin_popup_h.setValue(settings.value("ImagePopup/h", type=int)) def change_server_info_callback(self): self.server_changed = verify_server(force_new=True, enable_import=False) @@ -184,6 +185,8 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog): self.pb_import.clicked.connect(self.import_callback) self.pb_reset.clicked.connect(self.reset_callback) self.cb_image_popup.stateChanged.connect(self.settings_changed_callback) + self.spin_popup_w.valueChanged.connect(self.settings_changed_callback) + self.spin_popup_h.valueChanged.connect(self.settings_changed_callback) def apply_settings(self): # Priority @@ -218,6 +221,8 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog): # Advanced settings.setValue("ImagePopup/enabled", self.cb_image_popup.isChecked()) + settings.setValue("ImagePopup/w", self.spin_popup_w.value()) + settings.setValue("ImagePopup/h", self.spin_popup_h.value()) self.settings_changed = False self.buttonBox.button( From de5b535a15824cf23edc8817c1d8a424a615cb17 Mon Sep 17 00:00:00 2001 From: "dries.k" Date: Sat, 3 Sep 2022 13:06:28 +0200 Subject: [PATCH 24/24] make group box checkable --- gotify_tray/gui/designs/widget_settings.py | 25 ++++++++++------------ gotify_tray/gui/designs/widget_settings.ui | 16 ++++++-------- gotify_tray/gui/widgets/SettingsDialog.py | 6 +++--- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/gotify_tray/gui/designs/widget_settings.py b/gotify_tray/gui/designs/widget_settings.py index 649a69b..fe146ac 100644 --- a/gotify_tray/gui/designs/widget_settings.py +++ b/gotify_tray/gui/designs/widget_settings.py @@ -117,25 +117,26 @@ class Ui_Dialog(object): self.pb_export.setObjectName("pb_export") self.horizontalLayout_2.addWidget(self.pb_export) self.verticalLayout.addWidget(self.groupBox) - self.groupBox_2 = QtWidgets.QGroupBox(self.tab_advanced) - self.groupBox_2.setObjectName("groupBox_2") - self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox_2) + self.groupbox_image_popup = QtWidgets.QGroupBox(self.tab_advanced) + self.groupbox_image_popup.setCheckable(True) + self.groupbox_image_popup.setObjectName("groupbox_image_popup") + self.gridLayout_2 = QtWidgets.QGridLayout(self.groupbox_image_popup) self.gridLayout_2.setObjectName("gridLayout_2") self.horizontalLayout_4 = QtWidgets.QHBoxLayout() self.horizontalLayout_4.setObjectName("horizontalLayout_4") - self.label = QtWidgets.QLabel(self.groupBox_2) + self.label = QtWidgets.QLabel(self.groupbox_image_popup) self.label.setObjectName("label") self.horizontalLayout_4.addWidget(self.label) - self.spin_popup_w = QtWidgets.QSpinBox(self.groupBox_2) + self.spin_popup_w = QtWidgets.QSpinBox(self.groupbox_image_popup) self.spin_popup_w.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) self.spin_popup_w.setMinimum(100) self.spin_popup_w.setMaximum(10000) self.spin_popup_w.setObjectName("spin_popup_w") self.horizontalLayout_4.addWidget(self.spin_popup_w) - self.label_2 = QtWidgets.QLabel(self.groupBox_2) + self.label_2 = QtWidgets.QLabel(self.groupbox_image_popup) self.label_2.setObjectName("label_2") self.horizontalLayout_4.addWidget(self.label_2) - self.spin_popup_h = QtWidgets.QSpinBox(self.groupBox_2) + self.spin_popup_h = QtWidgets.QSpinBox(self.groupbox_image_popup) self.spin_popup_h.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) self.spin_popup_h.setMinimum(100) self.spin_popup_h.setMaximum(10000) @@ -143,11 +144,8 @@ class Ui_Dialog(object): self.horizontalLayout_4.addWidget(self.spin_popup_h) spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) self.horizontalLayout_4.addItem(spacerItem4) - self.gridLayout_2.addLayout(self.horizontalLayout_4, 1, 0, 1, 1) - self.cb_image_popup = QtWidgets.QCheckBox(self.groupBox_2) - self.cb_image_popup.setObjectName("cb_image_popup") - self.gridLayout_2.addWidget(self.cb_image_popup, 0, 0, 1, 1) - self.verticalLayout.addWidget(self.groupBox_2) + self.gridLayout_2.addLayout(self.horizontalLayout_4, 0, 0, 1, 1) + self.verticalLayout.addWidget(self.groupbox_image_popup) self.groupBox_logging = QtWidgets.QGroupBox(self.tab_advanced) self.groupBox_logging.setObjectName("groupBox_logging") self.gridLayout_6 = QtWidgets.QGridLayout(self.groupBox_logging) @@ -204,14 +202,13 @@ class Ui_Dialog(object): self.pb_reset.setText(_translate("Dialog", "Reset")) self.pb_import.setText(_translate("Dialog", "Import")) self.pb_export.setText(_translate("Dialog", "Export")) - self.groupBox_2.setTitle(_translate("Dialog", "Image pop-up")) + self.groupbox_image_popup.setTitle(_translate("Dialog", "Image pop-up for URLs")) self.label.setToolTip(_translate("Dialog", "Maximum pop-up width")) self.label.setText(_translate("Dialog", "Width")) self.spin_popup_w.setToolTip(_translate("Dialog", "Maximum pop-up width")) self.label_2.setToolTip(_translate("Dialog", "Maximum pop-up height")) self.label_2.setText(_translate("Dialog", "Height")) self.spin_popup_h.setToolTip(_translate("Dialog", "Maximum pop-up height")) - self.cb_image_popup.setText(_translate("Dialog", "Show an image pop-up when hovering over image URLs")) self.groupBox_logging.setTitle(_translate("Dialog", "Logging")) self.pb_open_log.setToolTip(_translate("Dialog", "Open logfile")) self.pb_open_log.setText(_translate("Dialog", "...")) diff --git a/gotify_tray/gui/designs/widget_settings.ui b/gotify_tray/gui/designs/widget_settings.ui index 421b54f..2b32ffa 100644 --- a/gotify_tray/gui/designs/widget_settings.ui +++ b/gotify_tray/gui/designs/widget_settings.ui @@ -266,12 +266,15 @@ - + - Image pop-up + Image pop-up for URLs + + + true - + @@ -340,13 +343,6 @@ - - - - Show an image pop-up when hovering over image URLs - - - diff --git a/gotify_tray/gui/widgets/SettingsDialog.py b/gotify_tray/gui/widgets/SettingsDialog.py index cd5ff93..90ee6aa 100644 --- a/gotify_tray/gui/widgets/SettingsDialog.py +++ b/gotify_tray/gui/widgets/SettingsDialog.py @@ -87,7 +87,7 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog): self.layout_fonts_message.addWidget(self.message_widget) # Advanced - self.cb_image_popup.setChecked(settings.value("ImagePopup/enabled", type=bool)) + self.groupbox_image_popup.setChecked(settings.value("ImagePopup/enabled", type=bool)) self.spin_popup_w.setValue(settings.value("ImagePopup/w", type=int)) self.spin_popup_h.setValue(settings.value("ImagePopup/h", type=int)) @@ -184,7 +184,7 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog): self.pb_export.clicked.connect(self.export_callback) self.pb_import.clicked.connect(self.import_callback) self.pb_reset.clicked.connect(self.reset_callback) - self.cb_image_popup.stateChanged.connect(self.settings_changed_callback) + self.groupbox_image_popup.toggled.connect(self.settings_changed_callback) self.spin_popup_w.valueChanged.connect(self.settings_changed_callback) self.spin_popup_h.valueChanged.connect(self.settings_changed_callback) @@ -220,7 +220,7 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog): ) # Advanced - settings.setValue("ImagePopup/enabled", self.cb_image_popup.isChecked()) + settings.setValue("ImagePopup/enabled", self.groupbox_image_popup.isChecked()) settings.setValue("ImagePopup/w", self.spin_popup_w.value()) settings.setValue("ImagePopup/h", self.spin_popup_h.value())