Merge commit '4fd9b29b7508027ce66d65e7acd28415b3a72385'
This commit is contained in:
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -93,7 +93,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
make build-macos
|
make build-macos
|
||||||
brew install create-dmg
|
brew install create-dmg
|
||||||
create-dmg --volname "Gotify Tray" --app-drop-link 0 0 --no-internet-enable "gotify-tray.dmg" "./dist/Gotify-Tray.app"
|
create-dmg --volname "Gotify Tray" --app-drop-link 0 0 --no-internet-enable "gotify-tray.dmg" "./dist/Gotify Tray.app"
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
|
|||||||
2
.github/workflows/develop.yml
vendored
2
.github/workflows/develop.yml
vendored
@@ -74,7 +74,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
make build-macos
|
make build-macos
|
||||||
brew install create-dmg
|
brew install create-dmg
|
||||||
create-dmg --volname "Gotify Tray" --app-drop-link 0 0 --no-internet-enable "gotify-tray.dmg" "./dist/Gotify-Tray.app"
|
create-dmg --volname "Gotify Tray" --app-drop-link 0 0 --no-internet-enable "gotify-tray.dmg" "./dist/Gotify Tray.app"
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
|
|||||||
64
BUILDING.md
Normal file
64
BUILDING.md
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
## Get the source and install the requirements:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ git clone https://github.com/seird/gotify-tray.git
|
||||||
|
$ cd gotify-tray
|
||||||
|
$ pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Run from source
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ python -m gotify_tray
|
||||||
|
```
|
||||||
|
|
||||||
|
### Create a pyinstaller executable
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ pip install pyinstaller
|
||||||
|
$ pyinstaller gotify-tray.spec
|
||||||
|
```
|
||||||
|
An executable is created at `dist/gotify-tray/`.
|
||||||
|
|
||||||
|
### Create a macos .app
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ pip install pyinstaller Pillow
|
||||||
|
$ pyinstaller gotify-tray.spec
|
||||||
|
```
|
||||||
|
|
||||||
|
### Inno setup (Windows)
|
||||||
|
|
||||||
|
Create an installer for windows with inno setup from pyinstaller output:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ iscc gotify-tray.iss
|
||||||
|
```
|
||||||
|
|
||||||
|
### Create and install a pip package
|
||||||
|
|
||||||
|
- Create the pip package:
|
||||||
|
```shell
|
||||||
|
$ python -m build
|
||||||
|
```
|
||||||
|
|
||||||
|
- Install the pip package:
|
||||||
|
```shell
|
||||||
|
$ pip install dist/gotify_tray-0.1.14-py3-none-any.whl
|
||||||
|
```
|
||||||
|
|
||||||
|
- Launch:
|
||||||
|
```shell
|
||||||
|
$ gotify-tray
|
||||||
|
```
|
||||||
|
|
||||||
|
### Create a deb package
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ make build
|
||||||
|
|
||||||
|
# or install
|
||||||
|
|
||||||
|
$ sudo make install
|
||||||
|
```
|
||||||
2
Makefile
2
Makefile
@@ -11,7 +11,7 @@ build-macos: clean
|
|||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
pip install pyinstaller
|
pip install pyinstaller
|
||||||
pip install Pillow
|
pip install Pillow
|
||||||
pyinstaller gotify-tray-macos.spec
|
pyinstaller gotify-tray.spec
|
||||||
|
|
||||||
install: build
|
install: build
|
||||||
sudo dpkg -i dist/gotify-tray_amd64.deb
|
sudo dpkg -i dist/gotify-tray_amd64.deb
|
||||||
|
|||||||
88
README.md
88
README.md
@@ -4,15 +4,21 @@
|
|||||||
A tray notification application for receiving messages from a [Gotify server](https://github.com/gotify/server).
|
A tray notification application for receiving messages from a [Gotify server](https://github.com/gotify/server).
|
||||||
|
|
||||||
|
|
||||||
## Download
|
## Getting started
|
||||||
|
|
||||||
|
|
||||||
[Download the latest release.](https://github.com/seird/gotify-tray/releases/latest)
|
- [Download the latest release.](https://github.com/seird/gotify-tray/releases/latest)
|
||||||
|
|
||||||
or, install via pip:
|
- or, install via pip:
|
||||||
```
|
```shell
|
||||||
$ pip install gotify-tray
|
$ pip install gotify-tray
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- or, run from source:
|
||||||
|
```shell
|
||||||
|
$ pip install -r requirements.txt
|
||||||
|
$ python -m gotify_tray
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
@@ -41,77 +47,11 @@ Windows 10 | KDE
|
|||||||

|

|
||||||
|
|
||||||
|
|
||||||
## Manual Installation
|
## Build instructions
|
||||||
|
|
||||||
Get the source and install the requirements:
|
See [BUILDING](BUILDING.md).
|
||||||
|
|
||||||
```
|
|
||||||
$ git clone https://github.com/seird/gotify-tray.git
|
|
||||||
$ cd gotify-tray
|
|
||||||
$ pip install -r requirements.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### Run from source
|
|
||||||
|
|
||||||
```
|
|
||||||
$ python -m gotify_tray
|
|
||||||
```
|
|
||||||
|
|
||||||
### Create a pyinstaller executable
|
|
||||||
|
|
||||||
```
|
|
||||||
$ pip install pyinstaller
|
|
||||||
$ pyinstaller gotify-tray.spec
|
|
||||||
```
|
|
||||||
An executable is created at `dist/gotify-tray/`.
|
|
||||||
|
|
||||||
### Create a macos .app
|
|
||||||
|
|
||||||
```
|
|
||||||
$ pip install pyinstaller Pillow
|
|
||||||
$ pyinstaller gotify-tray-macos.spec
|
|
||||||
```
|
|
||||||
|
|
||||||
### Inno setup (Windows)
|
|
||||||
|
|
||||||
Create an installer for windows with inno setup from pyinstaller output:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ iscc gotify-tray.iss
|
|
||||||
```
|
|
||||||
|
|
||||||
### Create and install a pip package
|
|
||||||
|
|
||||||
- Create the pip package:
|
|
||||||
```
|
|
||||||
$ python -m build
|
|
||||||
```
|
|
||||||
|
|
||||||
- Install the pip package:
|
|
||||||
```
|
|
||||||
$ pip install dist/gotify_tray-0.1.14-py3-none-any.whl
|
|
||||||
```
|
|
||||||
|
|
||||||
- Launch:
|
|
||||||
```
|
|
||||||
$ gotify-tray
|
|
||||||
```
|
|
||||||
|
|
||||||
### Create a deb package
|
|
||||||
|
|
||||||
```
|
|
||||||
$ make build
|
|
||||||
|
|
||||||
# or install
|
|
||||||
|
|
||||||
$ sudo make install
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- python >=3.8
|
- python >=3.8
|
||||||
- PyQt6
|
|
||||||
- requests
|
|
||||||
- websocket-client
|
|
||||||
|
|||||||
2
debian/DEBIAN/control
vendored
2
debian/DEBIAN/control
vendored
@@ -2,5 +2,5 @@ Package: gotify-tray
|
|||||||
Version: 0.1.14
|
Version: 0.1.14
|
||||||
Architecture: amd64
|
Architecture: amd64
|
||||||
Maintainer: k.dries@protonmail.com
|
Maintainer: k.dries@protonmail.com
|
||||||
Description: gotify-tray
|
Description: Gotify Tray
|
||||||
A tray notification application for receiving messages from a Gotify server.
|
A tray notification application for receiving messages from a Gotify server.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Name=gotify-tray
|
Name=Gotify Tray
|
||||||
Comment=A tray notification application for receiving messages from a Gotify server.
|
Comment=A tray notification application for receiving messages from a Gotify server.
|
||||||
Path=/usr/lib/gotify-tray
|
Path=/usr/lib/gotify-tray
|
||||||
Exec=/usr/lib/gotify-tray/gotify-tray
|
Exec=/usr/lib/gotify-tray/gotify-tray
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
# -*- mode: python -*-
|
|
||||||
|
|
||||||
block_cipher = None
|
|
||||||
|
|
||||||
a = Analysis(['gotify_tray/__main__.py'],
|
|
||||||
pathex=[os.getcwd()],
|
|
||||||
binaries=[],
|
|
||||||
datas=[('gotify_tray/gui/images', 'gotify_tray/gui/images')],
|
|
||||||
hiddenimports=[],
|
|
||||||
hookspath=[],
|
|
||||||
runtime_hooks=[],
|
|
||||||
excludes=[],
|
|
||||||
win_no_prefer_redirects=False,
|
|
||||||
win_private_assemblies=False,
|
|
||||||
cipher=block_cipher,
|
|
||||||
noarchive=False)
|
|
||||||
pyz = PYZ(a.pure, a.zipped_data,
|
|
||||||
cipher=block_cipher)
|
|
||||||
exe = EXE(pyz,
|
|
||||||
a.scripts,
|
|
||||||
[],
|
|
||||||
exclude_binaries=True,
|
|
||||||
name='gotify-tray',
|
|
||||||
debug=False,
|
|
||||||
bootloader_ignore_signals=False,
|
|
||||||
strip=False,
|
|
||||||
upx=True,
|
|
||||||
console=False,
|
|
||||||
version='version.py',
|
|
||||||
icon='logo.ico')
|
|
||||||
coll = COLLECT(exe,
|
|
||||||
a.binaries,
|
|
||||||
a.zipfiles,
|
|
||||||
a.datas,
|
|
||||||
strip=False,
|
|
||||||
upx=True,
|
|
||||||
name='gotify-tray')
|
|
||||||
app = BUNDLE(coll,
|
|
||||||
name='Gotify-Tray.app',
|
|
||||||
icon='logo.ico',
|
|
||||||
bundle_identifier=None)
|
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
# -*- mode: python -*-
|
# -*- mode: python -*-
|
||||||
|
|
||||||
|
import platform
|
||||||
|
|
||||||
block_cipher = None
|
block_cipher = None
|
||||||
|
|
||||||
a = Analysis(['gotify_tray/__main__.py'],
|
a = Analysis(['gotify_tray/__main__.py'],
|
||||||
@@ -35,3 +37,9 @@ coll = COLLECT(exe,
|
|||||||
strip=False,
|
strip=False,
|
||||||
upx=True,
|
upx=True,
|
||||||
name='gotify-tray')
|
name='gotify-tray')
|
||||||
|
|
||||||
|
if platform.system() == "Darwin":
|
||||||
|
app = BUNDLE(coll,
|
||||||
|
name='Gotify Tray.app',
|
||||||
|
icon='logo.ico',
|
||||||
|
bundle_identifier=None)
|
||||||
|
|||||||
@@ -14,9 +14,14 @@ DEFAULT_SETTINGS = {
|
|||||||
"tray/notifications/priority": 5,
|
"tray/notifications/priority": 5,
|
||||||
"tray/notifications/duration_ms": 5000,
|
"tray/notifications/duration_ms": 5000,
|
||||||
"tray/notifications/icon/show": True,
|
"tray/notifications/icon/show": True,
|
||||||
|
"tray/notifications/click": True,
|
||||||
"watchdog/interval/s": 60,
|
"watchdog/interval/s": 60,
|
||||||
"MessageWidget/image/size": 33,
|
"MessageWidget/image/size": 33,
|
||||||
"MainWindow/label/size": 25,
|
"MainWindow/label/size": 25,
|
||||||
"MainWindow/button/size": 33,
|
"MainWindow/button/size": 33,
|
||||||
"MainWindow/application/icon/size": 40,
|
"MainWindow/application/icon/size": 40,
|
||||||
|
"ImagePopup/enabled": False,
|
||||||
|
"ImagePopup/extensions": [".jpg", ".jpeg", ".png", ".svg"],
|
||||||
|
"ImagePopup/w": 400,
|
||||||
|
"ImagePopup/h": 400,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ from .models import (
|
|||||||
MessagesModelItem,
|
MessagesModelItem,
|
||||||
MessageItemDataRole,
|
MessageItemDataRole,
|
||||||
)
|
)
|
||||||
from .widgets import MainWindow, SettingsDialog, Tray
|
from .widgets import ImagePopup, MainWindow, SettingsDialog, Tray
|
||||||
|
|
||||||
|
|
||||||
settings = Settings("gotify-tray")
|
settings = Settings("gotify-tray")
|
||||||
@@ -309,6 +309,17 @@ class MainApplication(QtWidgets.QApplication):
|
|||||||
|
|
||||||
self.messages_model.clear()
|
self.messages_model.clear()
|
||||||
|
|
||||||
|
def image_popup_callback(self, link: str, pos: QtCore.QPoint):
|
||||||
|
if filename := self.downloader.get_filename(link):
|
||||||
|
self.image_popup = ImagePopup(filename, pos, link)
|
||||||
|
self.image_popup.show()
|
||||||
|
else:
|
||||||
|
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):
|
def refresh_callback(self):
|
||||||
# Manual refresh -> also reset the image cache
|
# Manual refresh -> also reset the image cache
|
||||||
Cache().clear()
|
Cache().clear()
|
||||||
@@ -335,6 +346,10 @@ class MainApplication(QtWidgets.QApplication):
|
|||||||
closed_callback=self.listener_closed_callback,
|
closed_callback=self.listener_closed_callback,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def tray_notification_clicked_callback(self):
|
||||||
|
if settings.value("tray/notifications/click", type=bool):
|
||||||
|
self.main_window.bring_to_front()
|
||||||
|
|
||||||
def tray_activated_callback(
|
def tray_activated_callback(
|
||||||
self, reason: QtWidgets.QSystemTrayIcon.ActivationReason
|
self, reason: QtWidgets.QSystemTrayIcon.ActivationReason
|
||||||
):
|
):
|
||||||
@@ -349,7 +364,7 @@ class MainApplication(QtWidgets.QApplication):
|
|||||||
self.tray.actionSettings.triggered.connect(self.settings_callback)
|
self.tray.actionSettings.triggered.connect(self.settings_callback)
|
||||||
self.tray.actionShowWindow.triggered.connect(self.main_window.bring_to_front)
|
self.tray.actionShowWindow.triggered.connect(self.main_window.bring_to_front)
|
||||||
self.tray.actionReconnect.triggered.connect(self.reconnect_callback)
|
self.tray.actionReconnect.triggered.connect(self.reconnect_callback)
|
||||||
self.tray.messageClicked.connect(self.main_window.bring_to_front)
|
self.tray.messageClicked.connect(self.tray_notification_clicked_callback)
|
||||||
self.tray.activated.connect(self.tray_activated_callback)
|
self.tray.activated.connect(self.tray_activated_callback)
|
||||||
|
|
||||||
self.main_window.refresh.connect(self.refresh_callback)
|
self.main_window.refresh.connect(self.refresh_callback)
|
||||||
@@ -358,6 +373,8 @@ class MainApplication(QtWidgets.QApplication):
|
|||||||
self.application_selection_changed_callback
|
self.application_selection_changed_callback
|
||||||
)
|
)
|
||||||
self.main_window.delete_message.connect(self.delete_message_callback)
|
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))
|
self.watchdog.closed.connect(lambda: self.listener_closed_callback(None, None))
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ from PyQt6 import QtCore, QtGui, QtWidgets
|
|||||||
class Ui_Dialog(object):
|
class Ui_Dialog(object):
|
||||||
def setupUi(self, Dialog):
|
def setupUi(self, Dialog):
|
||||||
Dialog.setObjectName("Dialog")
|
Dialog.setObjectName("Dialog")
|
||||||
Dialog.resize(384, 274)
|
Dialog.resize(384, 285)
|
||||||
self.gridLayout = QtWidgets.QGridLayout(Dialog)
|
self.gridLayout = QtWidgets.QGridLayout(Dialog)
|
||||||
self.gridLayout.setObjectName("gridLayout")
|
self.gridLayout.setObjectName("gridLayout")
|
||||||
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
|
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
|
||||||
@@ -30,32 +30,35 @@ class Ui_Dialog(object):
|
|||||||
self.groupBox_notifications.setObjectName("groupBox_notifications")
|
self.groupBox_notifications.setObjectName("groupBox_notifications")
|
||||||
self.gridLayout_4 = QtWidgets.QGridLayout(self.groupBox_notifications)
|
self.gridLayout_4 = QtWidgets.QGridLayout(self.groupBox_notifications)
|
||||||
self.gridLayout_4.setObjectName("gridLayout_4")
|
self.gridLayout_4.setObjectName("gridLayout_4")
|
||||||
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
|
self.cb_notify = QtWidgets.QCheckBox(self.groupBox_notifications)
|
||||||
self.gridLayout_4.addItem(spacerItem, 0, 2, 1, 1)
|
self.cb_notify.setObjectName("cb_notify")
|
||||||
self.label_notification_duration_ms = QtWidgets.QLabel(self.groupBox_notifications)
|
self.gridLayout_4.addWidget(self.cb_notify, 2, 0, 1, 3)
|
||||||
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 = QtWidgets.QLabel(self.groupBox_notifications)
|
||||||
self.label_notification_duration.setObjectName("label_notification_duration")
|
self.label_notification_duration.setObjectName("label_notification_duration")
|
||||||
self.gridLayout_4.addWidget(self.label_notification_duration, 1, 0, 1, 1)
|
self.gridLayout_4.addWidget(self.label_notification_duration, 1, 0, 1, 1)
|
||||||
self.spin_duration = QtWidgets.QSpinBox(self.groupBox_notifications)
|
self.label_notification_duration_ms = QtWidgets.QLabel(self.groupBox_notifications)
|
||||||
self.spin_duration.setMinimum(500)
|
self.label_notification_duration_ms.setObjectName("label_notification_duration_ms")
|
||||||
self.spin_duration.setMaximum(30000)
|
self.gridLayout_4.addWidget(self.label_notification_duration_ms, 1, 2, 1, 1)
|
||||||
self.spin_duration.setSingleStep(100)
|
|
||||||
self.spin_duration.setObjectName("spin_duration")
|
|
||||||
self.gridLayout_4.addWidget(self.spin_duration, 1, 1, 1, 1)
|
|
||||||
self.spin_priority = QtWidgets.QSpinBox(self.groupBox_notifications)
|
self.spin_priority = QtWidgets.QSpinBox(self.groupBox_notifications)
|
||||||
self.spin_priority.setMinimum(1)
|
self.spin_priority.setMinimum(1)
|
||||||
self.spin_priority.setMaximum(10)
|
self.spin_priority.setMaximum(10)
|
||||||
self.spin_priority.setProperty("value", 5)
|
self.spin_priority.setProperty("value", 5)
|
||||||
self.spin_priority.setObjectName("spin_priority")
|
self.spin_priority.setObjectName("spin_priority")
|
||||||
self.gridLayout_4.addWidget(self.spin_priority, 0, 1, 1, 1)
|
self.gridLayout_4.addWidget(self.spin_priority, 0, 1, 1, 1)
|
||||||
self.cb_notify = QtWidgets.QCheckBox(self.groupBox_notifications)
|
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
|
||||||
self.cb_notify.setObjectName("cb_notify")
|
self.gridLayout_4.addItem(spacerItem, 0, 2, 1, 1)
|
||||||
self.gridLayout_4.addWidget(self.cb_notify, 2, 0, 1, 3)
|
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.spin_duration = QtWidgets.QSpinBox(self.groupBox_notifications)
|
||||||
|
self.spin_duration.setMinimum(500)
|
||||||
|
self.spin_duration.setMaximum(30000)
|
||||||
|
self.spin_duration.setSingleStep(100)
|
||||||
|
self.spin_duration.setObjectName("spin_duration")
|
||||||
|
self.gridLayout_4.addWidget(self.spin_duration, 1, 1, 1, 1)
|
||||||
|
self.cb_notification_click = QtWidgets.QCheckBox(self.groupBox_notifications)
|
||||||
|
self.cb_notification_click.setObjectName("cb_notification_click")
|
||||||
|
self.gridLayout_4.addWidget(self.cb_notification_click, 3, 0, 1, 3)
|
||||||
self.verticalLayout_4.addWidget(self.groupBox_notifications)
|
self.verticalLayout_4.addWidget(self.groupBox_notifications)
|
||||||
self.groupBox_server_info = QtWidgets.QGroupBox(self.tab_general)
|
self.groupBox_server_info = QtWidgets.QGroupBox(self.tab_general)
|
||||||
self.groupBox_server_info.setObjectName("groupBox_server_info")
|
self.groupBox_server_info.setObjectName("groupBox_server_info")
|
||||||
@@ -102,37 +105,66 @@ class Ui_Dialog(object):
|
|||||||
self.verticalLayout.setObjectName("verticalLayout")
|
self.verticalLayout.setObjectName("verticalLayout")
|
||||||
self.groupBox = QtWidgets.QGroupBox(self.tab_advanced)
|
self.groupBox = QtWidgets.QGroupBox(self.tab_advanced)
|
||||||
self.groupBox.setObjectName("groupBox")
|
self.groupBox.setObjectName("groupBox")
|
||||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.groupBox)
|
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.groupBox)
|
||||||
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
self.horizontalLayout_2.setObjectName("horizontalLayout_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.pb_reset = QtWidgets.QPushButton(self.groupBox)
|
self.pb_reset = QtWidgets.QPushButton(self.groupBox)
|
||||||
self.pb_reset.setObjectName("pb_reset")
|
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.verticalLayout.addWidget(self.groupBox)
|
||||||
|
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_image_popup)
|
||||||
|
self.label.setObjectName("label")
|
||||||
|
self.horizontalLayout_4.addWidget(self.label)
|
||||||
|
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_image_popup)
|
||||||
|
self.label_2.setObjectName("label_2")
|
||||||
|
self.horizontalLayout_4.addWidget(self.label_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)
|
||||||
|
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, 0, 0, 1, 1)
|
||||||
|
self.verticalLayout.addWidget(self.groupbox_image_popup)
|
||||||
self.groupBox_logging = QtWidgets.QGroupBox(self.tab_advanced)
|
self.groupBox_logging = QtWidgets.QGroupBox(self.tab_advanced)
|
||||||
self.groupBox_logging.setObjectName("groupBox_logging")
|
self.groupBox_logging.setObjectName("groupBox_logging")
|
||||||
self.gridLayout_6 = QtWidgets.QGridLayout(self.groupBox_logging)
|
self.gridLayout_6 = QtWidgets.QGridLayout(self.groupBox_logging)
|
||||||
self.gridLayout_6.setObjectName("gridLayout_6")
|
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 = QtWidgets.QComboBox(self.groupBox_logging)
|
||||||
self.combo_logging.setObjectName("combo_logging")
|
self.combo_logging.setObjectName("combo_logging")
|
||||||
self.gridLayout_6.addWidget(self.combo_logging, 0, 1, 1, 1)
|
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 = QtWidgets.QPushButton(self.groupBox_logging)
|
||||||
self.pb_open_log.setMaximumSize(QtCore.QSize(30, 16777215))
|
self.pb_open_log.setMaximumSize(QtCore.QSize(30, 16777215))
|
||||||
self.pb_open_log.setObjectName("pb_open_log")
|
self.pb_open_log.setObjectName("pb_open_log")
|
||||||
self.gridLayout_6.addWidget(self.pb_open_log, 0, 2, 1, 1)
|
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.label_logging = QtWidgets.QLabel(self.groupBox_logging)
|
||||||
self.gridLayout_6.addItem(spacerItem4, 0, 3, 1, 1)
|
self.label_logging.setObjectName("label_logging")
|
||||||
|
self.gridLayout_6.addWidget(self.label_logging, 0, 0, 1, 1)
|
||||||
self.verticalLayout.addWidget(self.groupBox_logging)
|
self.verticalLayout.addWidget(self.groupBox_logging)
|
||||||
spacerItem5 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding)
|
spacerItem6 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding)
|
||||||
self.verticalLayout.addItem(spacerItem5)
|
self.verticalLayout.addItem(spacerItem6)
|
||||||
self.tabWidget.addTab(self.tab_advanced, "")
|
self.tabWidget.addTab(self.tab_advanced, "")
|
||||||
self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1)
|
self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1)
|
||||||
|
|
||||||
@@ -153,10 +185,11 @@ class Ui_Dialog(object):
|
|||||||
_translate = QtCore.QCoreApplication.translate
|
_translate = QtCore.QCoreApplication.translate
|
||||||
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
|
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
|
||||||
self.groupBox_notifications.setTitle(_translate("Dialog", "Notifications"))
|
self.groupBox_notifications.setTitle(_translate("Dialog", "Notifications"))
|
||||||
|
self.cb_notify.setText(_translate("Dialog", "Show a notification for missed messages after reconnecting"))
|
||||||
|
self.label_notification_duration.setText(_translate("Dialog", "Notification duration:"))
|
||||||
self.label_notification_duration_ms.setText(_translate("Dialog", "ms"))
|
self.label_notification_duration_ms.setText(_translate("Dialog", "ms"))
|
||||||
self.label_notification_priority.setText(_translate("Dialog", "Minimum priority to show notifications:"))
|
self.label_notification_priority.setText(_translate("Dialog", "Minimum priority to show notifications:"))
|
||||||
self.label_notification_duration.setText(_translate("Dialog", "Notification duration:"))
|
self.cb_notification_click.setText(_translate("Dialog", "Clicking the notification pop-up opens the main window"))
|
||||||
self.cb_notify.setText(_translate("Dialog", "Show a notification for missed messages after reconnecting"))
|
|
||||||
self.groupBox_server_info.setTitle(_translate("Dialog", "Server info"))
|
self.groupBox_server_info.setTitle(_translate("Dialog", "Server info"))
|
||||||
self.pb_change_server_info.setText(_translate("Dialog", "Change server info"))
|
self.pb_change_server_info.setText(_translate("Dialog", "Change server info"))
|
||||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_general), _translate("Dialog", "General"))
|
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_general), _translate("Dialog", "General"))
|
||||||
@@ -166,13 +199,20 @@ class Ui_Dialog(object):
|
|||||||
self.pb_font_message_content.setText(_translate("Dialog", "Message"))
|
self.pb_font_message_content.setText(_translate("Dialog", "Message"))
|
||||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_fonts), _translate("Dialog", "Fonts"))
|
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_fonts), _translate("Dialog", "Fonts"))
|
||||||
self.groupBox.setTitle(_translate("Dialog", "Settings"))
|
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_reset.setText(_translate("Dialog", "Reset"))
|
||||||
|
self.pb_import.setText(_translate("Dialog", "Import"))
|
||||||
|
self.pb_export.setText(_translate("Dialog", "Export"))
|
||||||
|
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.groupBox_logging.setTitle(_translate("Dialog", "Logging"))
|
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.setToolTip(_translate("Dialog", "Open logfile"))
|
||||||
self.pb_open_log.setText(_translate("Dialog", "..."))
|
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"))
|
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_advanced), _translate("Dialog", "Advanced"))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>384</width>
|
<width>384</width>
|
||||||
<height>274</height>
|
<height>285</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -40,30 +40,10 @@
|
|||||||
<string>Notifications</string>
|
<string>Notifications</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_4">
|
<layout class="QGridLayout" name="gridLayout_4">
|
||||||
<item row="0" column="2">
|
<item row="2" column="0" colspan="3">
|
||||||
<spacer name="horizontalSpacer_3">
|
<widget class="QCheckBox" name="cb_notify">
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="2">
|
|
||||||
<widget class="QLabel" name="label_notification_duration_ms">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>ms</string>
|
<string>Show a notification for missed messages after reconnecting</string>
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label_notification_priority">
|
|
||||||
<property name="text">
|
|
||||||
<string>Minimum priority to show notifications:</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -74,16 +54,10 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="1" column="2">
|
||||||
<widget class="QSpinBox" name="spin_duration">
|
<widget class="QLabel" name="label_notification_duration_ms">
|
||||||
<property name="minimum">
|
<property name="text">
|
||||||
<number>500</number>
|
<string>ms</string>
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>30000</number>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<number>100</number>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -100,10 +74,43 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0" colspan="3">
|
<item row="0" column="2">
|
||||||
<widget class="QCheckBox" name="cb_notify">
|
<spacer name="horizontalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_notification_priority">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Show a notification for missed messages after reconnecting</string>
|
<string>Minimum priority to show notifications:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QSpinBox" name="spin_duration">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>500</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>30000</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0" colspan="3">
|
||||||
|
<widget class="QCheckBox" name="cb_notification_click">
|
||||||
|
<property name="text">
|
||||||
|
<string>Clicking the notification pop-up opens the main window</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -233,11 +240,11 @@
|
|||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Settings</string>
|
<string>Settings</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="pb_export">
|
<widget class="QPushButton" name="pb_reset">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Export</string>
|
<string>Reset</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -249,31 +256,118 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="pb_reset">
|
<widget class="QPushButton" name="pb_export">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Reset</string>
|
<string>Export</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupbox_image_popup">
|
||||||
|
<property name="title">
|
||||||
|
<string>Image pop-up for URLs</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Maximum pop-up width</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Width</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="spin_popup_w">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Maximum pop-up width</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>10000</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Maximum pop-up height</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Height</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="spin_popup_h">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Maximum pop-up height</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>10000</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_logging">
|
<widget class="QGroupBox" name="groupBox_logging">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Logging</string>
|
<string>Logging</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_6">
|
<layout class="QGridLayout" name="gridLayout_6">
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label_logging">
|
|
||||||
<property name="text">
|
|
||||||
<string>Level</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QComboBox" name="combo_logging"/>
|
<widget class="QComboBox" name="combo_logging"/>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="3">
|
||||||
|
<spacer name="horizontalSpacer_5">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>190</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
<item row="0" column="2">
|
<item row="0" column="2">
|
||||||
<widget class="QPushButton" name="pb_open_log">
|
<widget class="QPushButton" name="pb_open_log">
|
||||||
<property name="maximumSize">
|
<property name="maximumSize">
|
||||||
@@ -290,18 +384,12 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="3">
|
<item row="0" column="0">
|
||||||
<spacer name="horizontalSpacer_5">
|
<widget class="QLabel" name="label_logging">
|
||||||
<property name="orientation">
|
<property name="text">
|
||||||
<enum>Qt::Horizontal</enum>
|
<string>Level</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
</widget>
|
||||||
<size>
|
|
||||||
<width>190</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|||||||
65
gotify_tray/gui/widgets/ImagePopup.py
Normal file
65
gotify_tray/gui/widgets/ImagePopup.py
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import platform
|
||||||
|
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.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)
|
||||||
|
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))
|
||||||
|
|
||||||
|
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 platform.system() != "Darwin" and 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)
|
||||||
@@ -21,6 +21,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
|||||||
delete_all = QtCore.pyqtSignal(QtGui.QStandardItem)
|
delete_all = QtCore.pyqtSignal(QtGui.QStandardItem)
|
||||||
delete_message = QtCore.pyqtSignal(MessagesModelItem)
|
delete_message = QtCore.pyqtSignal(MessagesModelItem)
|
||||||
application_selection_changed = QtCore.pyqtSignal(QtGui.QStandardItem)
|
application_selection_changed = QtCore.pyqtSignal(QtGui.QStandardItem)
|
||||||
|
image_popup = QtCore.pyqtSignal(str, QtCore.QPoint)
|
||||||
|
hidden = QtCore.pyqtSignal()
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, application_model: ApplicationModel, messages_model: MessagesModel
|
self, application_model: ApplicationModel, messages_model: MessagesModel
|
||||||
@@ -72,6 +74,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
|||||||
font_title.fromString(s)
|
font_title.fromString(s)
|
||||||
else:
|
else:
|
||||||
font_title.setBold(True)
|
font_title.setBold(True)
|
||||||
|
font_title.setPointSize(font_title.pointSize() + 2)
|
||||||
self.label_application.setFont(font_title)
|
self.label_application.setFont(font_title)
|
||||||
|
|
||||||
# Set tooltips
|
# Set tooltips
|
||||||
@@ -102,6 +105,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
|||||||
self.messages_model.indexFromItem(message_item), message_widget
|
self.messages_model.indexFromItem(message_item), message_widget
|
||||||
)
|
)
|
||||||
message_widget.deletion_requested.connect(self.delete_message.emit)
|
message_widget.deletion_requested.connect(self.delete_message.emit)
|
||||||
|
message_widget.image_popup.connect(self.image_popup.emit)
|
||||||
|
|
||||||
def currentApplicationIndex(self) -> QtCore.QModelIndex:
|
def currentApplicationIndex(self) -> QtCore.QModelIndex:
|
||||||
return self.listView_applications.selectionModel().currentIndex()
|
return self.listView_applications.selectionModel().currentIndex()
|
||||||
@@ -172,3 +176,4 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
|||||||
|
|
||||||
def closeEvent(self, e: QtGui.QCloseEvent) -> None:
|
def closeEvent(self, e: QtGui.QCloseEvent) -> None:
|
||||||
self.hide()
|
self.hide()
|
||||||
|
self.hidden.emit()
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
from PyQt6 import QtCore, QtGui, QtWidgets
|
from PyQt6 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
from ..models.MessagesModel import MessageItemDataRole, MessagesModelItem
|
from ..models.MessagesModel import MessageItemDataRole, MessagesModelItem
|
||||||
@@ -11,6 +13,7 @@ settings = Settings("gotify-tray")
|
|||||||
|
|
||||||
class MessageWidget(QtWidgets.QWidget, Ui_Form):
|
class MessageWidget(QtWidgets.QWidget, Ui_Form):
|
||||||
deletion_requested = QtCore.pyqtSignal(MessagesModelItem)
|
deletion_requested = QtCore.pyqtSignal(MessagesModelItem)
|
||||||
|
image_popup = QtCore.pyqtSignal(str, QtCore.QPoint)
|
||||||
|
|
||||||
def __init__(self, message_item: MessagesModelItem, image_path: str = ""):
|
def __init__(self, message_item: MessagesModelItem, image_path: str = ""):
|
||||||
super(MessageWidget, self).__init__()
|
super(MessageWidget, self).__init__()
|
||||||
@@ -86,7 +89,17 @@ class MessageWidget(QtWidgets.QWidget, Ui_Form):
|
|||||||
self.label_date.setFont(font_date)
|
self.label_date.setFont(font_date)
|
||||||
self.label_message.setFont(font_content)
|
self.label_message.setFont(font_content)
|
||||||
|
|
||||||
|
def link_hovered_callback(self, link: str):
|
||||||
|
if not settings.value("ImagePopup/enabled", type=bool):
|
||||||
|
return
|
||||||
|
|
||||||
|
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())
|
||||||
|
|
||||||
def link_callbacks(self):
|
def link_callbacks(self):
|
||||||
self.pb_delete.clicked.connect(
|
self.pb_delete.clicked.connect(
|
||||||
lambda: self.deletion_requested.emit(self.message_item)
|
lambda: self.deletion_requested.emit(self.message_item)
|
||||||
)
|
)
|
||||||
|
self.label_message.linkHovered.connect(self.link_hovered_callback)
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import logging
|
import logging
|
||||||
import platform
|
import platform
|
||||||
import os
|
import os
|
||||||
import webbrowser
|
|
||||||
|
|
||||||
from gotify_tray.database import Settings
|
from gotify_tray.database import Settings
|
||||||
from gotify_tray.gotify import GotifyMessageModel
|
from gotify_tray.gotify import GotifyMessageModel
|
||||||
from gotify_tray.gui.models import MessagesModelItem
|
from gotify_tray.gui.models import MessagesModelItem
|
||||||
from . import MessageWidget
|
from . import MessageWidget
|
||||||
from gotify_tray.utils import verify_server
|
from gotify_tray.utils import verify_server, open_file
|
||||||
from gotify_tray.tasks import ExportSettingsTask, ImportSettingsTask
|
from gotify_tray.tasks import ExportSettingsTask, ImportSettingsTask
|
||||||
from PyQt6 import QtCore, QtGui, QtWidgets
|
from PyQt6 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
@@ -57,6 +56,10 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog):
|
|||||||
settings.value("message/check_missed/notify", type=bool)
|
settings.value("message/check_missed/notify", type=bool)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.cb_notification_click.setChecked(
|
||||||
|
settings.value("tray/notifications/click", type=bool)
|
||||||
|
)
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
self.combo_logging.addItems(
|
self.combo_logging.addItems(
|
||||||
[
|
[
|
||||||
@@ -83,6 +86,11 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog):
|
|||||||
)
|
)
|
||||||
self.layout_fonts_message.addWidget(self.message_widget)
|
self.layout_fonts_message.addWidget(self.message_widget)
|
||||||
|
|
||||||
|
# Advanced
|
||||||
|
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))
|
||||||
|
|
||||||
def change_server_info_callback(self):
|
def change_server_info_callback(self):
|
||||||
self.server_changed = verify_server(force_new=True, enable_import=False)
|
self.server_changed = verify_server(force_new=True, enable_import=False)
|
||||||
|
|
||||||
@@ -150,6 +158,7 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog):
|
|||||||
self.spin_priority.valueChanged.connect(self.settings_changed_callback)
|
self.spin_priority.valueChanged.connect(self.settings_changed_callback)
|
||||||
self.spin_duration.valueChanged.connect(self.settings_changed_callback)
|
self.spin_duration.valueChanged.connect(self.settings_changed_callback)
|
||||||
self.cb_notify.stateChanged.connect(self.settings_changed_callback)
|
self.cb_notify.stateChanged.connect(self.settings_changed_callback)
|
||||||
|
self.cb_notification_click.stateChanged.connect(self.settings_changed_callback)
|
||||||
|
|
||||||
# Server info
|
# Server info
|
||||||
self.pb_change_server_info.clicked.connect(self.change_server_info_callback)
|
self.pb_change_server_info.clicked.connect(self.change_server_info_callback)
|
||||||
@@ -157,7 +166,7 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog):
|
|||||||
# Logging
|
# Logging
|
||||||
self.combo_logging.currentTextChanged.connect(self.settings_changed_callback)
|
self.combo_logging.currentTextChanged.connect(self.settings_changed_callback)
|
||||||
self.pb_open_log.clicked.connect(
|
self.pb_open_log.clicked.connect(
|
||||||
lambda: webbrowser.open(logger.root.handlers[0].baseFilename)
|
lambda: open_file(logger.root.handlers[0].baseFilename)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Fonts
|
# Fonts
|
||||||
@@ -175,12 +184,18 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog):
|
|||||||
self.pb_export.clicked.connect(self.export_callback)
|
self.pb_export.clicked.connect(self.export_callback)
|
||||||
self.pb_import.clicked.connect(self.import_callback)
|
self.pb_import.clicked.connect(self.import_callback)
|
||||||
self.pb_reset.clicked.connect(self.reset_callback)
|
self.pb_reset.clicked.connect(self.reset_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)
|
||||||
|
|
||||||
def apply_settings(self):
|
def apply_settings(self):
|
||||||
# Priority
|
# Priority
|
||||||
settings.setValue("tray/notifications/priority", self.spin_priority.value())
|
settings.setValue("tray/notifications/priority", self.spin_priority.value())
|
||||||
settings.setValue("tray/notifications/duration_ms", self.spin_duration.value())
|
settings.setValue("tray/notifications/duration_ms", self.spin_duration.value())
|
||||||
settings.setValue("message/check_missed/notify", self.cb_notify.isChecked())
|
settings.setValue("message/check_missed/notify", self.cb_notify.isChecked())
|
||||||
|
settings.setValue(
|
||||||
|
"tray/notifications/click", self.cb_notification_click.isChecked()
|
||||||
|
)
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
selected_level = self.combo_logging.currentText()
|
selected_level = self.combo_logging.currentText()
|
||||||
@@ -204,6 +219,11 @@ class SettingsDialog(QtWidgets.QDialog, Ui_Dialog):
|
|||||||
self.message_widget.label_message.font().toString(),
|
self.message_widget.label_message.font().toString(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Advanced
|
||||||
|
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())
|
||||||
|
|
||||||
self.settings_changed = False
|
self.settings_changed = False
|
||||||
self.buttonBox.button(
|
self.buttonBox.button(
|
||||||
QtWidgets.QDialogButtonBox.StandardButton.Apply
|
QtWidgets.QDialogButtonBox.StandardButton.Apply
|
||||||
|
|||||||
@@ -23,13 +23,13 @@ class Tray(QtWidgets.QSystemTrayIcon):
|
|||||||
# Tray menu items
|
# Tray menu items
|
||||||
menu = QtWidgets.QMenu()
|
menu = QtWidgets.QMenu()
|
||||||
|
|
||||||
self.actionSettings = QtGui.QAction("Settings", self)
|
self.actionShowWindow = QtGui.QAction("Show Window", self)
|
||||||
menu.addAction(self.actionSettings)
|
menu.addAction(self.actionShowWindow)
|
||||||
|
|
||||||
menu.addSeparator()
|
menu.addSeparator()
|
||||||
|
|
||||||
self.actionShowWindow = QtGui.QAction("Show Window", self)
|
self.actionSettings = QtGui.QAction("Settings", self)
|
||||||
menu.addAction(self.actionShowWindow)
|
menu.addAction(self.actionSettings)
|
||||||
|
|
||||||
menu.addSeparator()
|
menu.addSeparator()
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from .ImagePopup import ImagePopup
|
||||||
from .MessageWidget import MessageWidget
|
from .MessageWidget import MessageWidget
|
||||||
from .MainWindow import MainWindow
|
from .MainWindow import MainWindow
|
||||||
from .ServerInfoDialog import ServerInfoDialog
|
from .ServerInfoDialog import ServerInfoDialog
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
|
import platform
|
||||||
import re
|
import re
|
||||||
|
import subprocess
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@@ -46,3 +48,12 @@ def get_abs_path(s) -> str:
|
|||||||
h = Path(__file__).parent.parent
|
h = Path(__file__).parent.parent
|
||||||
p = Path(s)
|
p = Path(s)
|
||||||
return os.path.join(h, p).replace("\\", "/")
|
return os.path.join(h, p).replace("\\", "/")
|
||||||
|
|
||||||
|
|
||||||
|
def open_file(filename: str):
|
||||||
|
if platform.system() == "Linux":
|
||||||
|
subprocess.call(["xdg-open", filename])
|
||||||
|
elif platform.system() == "Windows":
|
||||||
|
os.startfile(filename)
|
||||||
|
elif platform.system() == "Darwin":
|
||||||
|
subprocess.call(["open", filename])
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 34 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 32 KiB |
@@ -1,4 +1,4 @@
|
|||||||
requests==2.28.1
|
requests==2.28.1
|
||||||
websocket-client==1.3.3
|
websocket-client==1.4.0
|
||||||
pyqt6==6.3.1
|
pyqt6==6.3.1
|
||||||
python-dateutil==2.8.2
|
python-dateutil==2.8.2
|
||||||
|
|||||||
Reference in New Issue
Block a user