initial commit

This commit is contained in:
dries.k
2021-08-05 18:56:17 +02:00
commit 1520e4d9e7
56 changed files with 3820 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
from typing import Optional, Union
from PyQt6 import QtCore, QtGui
from gotify_tray import gotify
class ApplicationModelItem(QtGui.QStandardItem):
def __init__(
self,
application: gotify.GotifyApplicationModel,
icon: Optional[QtGui.QIcon] = None,
*args,
**kwargs
):
super(ApplicationModelItem, self).__init__(application.name)
self.application = application
if icon:
self.setIcon(icon)
class ApplicationAllMessagesItem(QtGui.QStandardItem):
def __init__(self, *args, **kwargs):
super(ApplicationAllMessagesItem, self).__init__("ALL MESSAGES")
class ApplicationModel(QtGui.QStandardItemModel):
def setItem(self, row: int, column: int, item: Union[ApplicationModelItem, ApplicationAllMessagesItem]) -> None:
super(ApplicationModel, self).setItem(row, column, item)
def itemFromIndex(
self, index: QtCore.QModelIndex
) -> Union[ApplicationModelItem, ApplicationAllMessagesItem]:
return super(ApplicationModel, self).itemFromIndex(index)
def itemFromId(self, appid: int) -> Optional[ApplicationModelItem]:
for row in range(self.rowCount()):
item = self.item(row, 0)
if not isinstance(item, ApplicationModelItem):
continue
if item.application.id == appid:
return item
return None

View File

@@ -0,0 +1,398 @@
import getpass
import logging
import os
import tempfile
from typing import List
from gotify_tray import gotify
from gotify_tray.database import Downloader, Settings
from gotify_tray.tasks import (
DeleteApplicationMessagesTask,
DeleteMessageTask,
DeleteAllMessagesTask,
GetApplicationMessagesTask,
GetApplicationsTask,
GetMessagesTask,
)
from PyQt6 import QtCore, QtGui, QtWidgets
from ..__version__ import __title__
from .ApplicationModel import (
ApplicationAllMessagesItem,
ApplicationModel,
ApplicationModelItem,
)
from .designs.widget_main import Ui_Form as Ui_Main
from .themes import set_theme
from .MessagesModel import MessagesModel, MessagesModelItem
from .MessageWidget import MessageWidget
from .SettingsDialog import SettingsDialog
from .Tray import Tray
settings = Settings("gotify-tray")
logger = logging.getLogger("logger")
downloader = Downloader()
class MainWidget(QtWidgets.QWidget, Ui_Main):
def __init__(
self, application_model: ApplicationModel, messages_model: MessagesModel
):
super(MainWidget, self).__init__()
self.setupUi(self)
self.listView_messages.setModel(messages_model)
self.listView_applications.setModel(application_model)
self.listView_applications.setFixedWidth(180)
icon_size = settings.value("ApplicationModelItem/icon/size", type=int)
self.listView_applications.setIconSize(QtCore.QSize(icon_size, icon_size))
label_size = settings.value("MainWidget/status_image/size", type=int)
self.label_status.setFixedSize(QtCore.QSize(label_size, label_size))
self.label_status_connecting()
def label_status_active(self):
self.label_status.setToolTip("Listening for new messages")
self.label_status.setStyleSheet("QLabel {background-color: green;}")
def label_status_connecting(self):
self.label_status.setToolTip("Connecting...")
self.label_status.setStyleSheet("QLabel {background-color: orange;}")
def label_status_inactive(self):
self.label_status.setToolTip("Listener inactive")
self.label_status.setStyleSheet("QLabel {background-color: grey;}")
def label_status_error(self):
self.label_status.setToolTip("Listener error")
self.label_status.setStyleSheet("QLabel {background-color: red;}")
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, app: QtWidgets.QApplication):
super(MainWindow, self).__init__()
self.app = app
self.shutting_down = False
def init_ui(self):
self.gotify_client = gotify.GotifyClient(
settings.value("Server/url", type=str),
settings.value("Server/client_token", type=str),
)
self.setWindowTitle(__title__)
self.resize(800, 600)
set_theme(self.app, settings.value("MainWindow/theme", type=str))
self.application_model = ApplicationModel()
self.messages_model = MessagesModel()
self.main_widget = MainWidget(self.application_model, self.messages_model)
self.setCentralWidget(self.main_widget)
self.refresh_applications()
self.tray = Tray()
self.tray.show()
self.restore_window_state()
self.gotify_client.listen(
new_message_callback=self.new_message_callback,
opened_callback=self.listener_opened_callback,
closed_callback=self.listener_closed_callback,
)
self.link_callbacks()
self.show()
self.window_state_to_restore = QtCore.Qt.WindowState.WindowNoState
if settings.value("MainWindow/start_minimized", type=bool) and settings.value(
"tray/show", type=bool
):
self.tray_activated_callback(
QtWidgets.QSystemTrayIcon.ActivationReason.Trigger
)
def refresh_applications(self):
self.application_model.clear()
self.messages_model.clear()
self.main_widget.listView_applications.clearSelection()
self.main_widget.listView_applications.setEnabled(False)
self.application_model.setItem(0, 0, ApplicationAllMessagesItem())
def get_applications_callback(
applications: List[gotify.GotifyApplicationModel],
):
for i, application in enumerate(applications):
icon = (
QtGui.QIcon(
downloader.get_filename(
f"{self.gotify_client.url}/{application.image}"
)
)
if settings.value("ApplicationModelItem/icon/show", type=bool)
else None
)
self.application_model.setItem(
i + 1, 0, ApplicationModelItem(application, icon),
)
self.get_applications_task = GetApplicationsTask(self.gotify_client)
self.get_applications_task.success.connect(get_applications_callback)
self.get_applications_task.finished.connect(
self.get_applications_finished_callback
)
self.get_applications_task.start()
def get_applications_finished_callback(self):
self.main_widget.listView_applications.setEnabled(True)
self.main_widget.listView_applications.setCurrentIndex(
self.application_model.index(0, 0)
)
def insert_message(
self,
row: int,
message: gotify.GotifyMessageModel,
application: gotify.GotifyApplicationModel,
):
message_item = MessagesModelItem(message)
self.messages_model.insertRow(row, message_item)
message_widget = MessageWidget(
message_item,
image_path=downloader.get_filename(
f"{self.gotify_client.url}/{application.image}"
)
if settings.value("MessageWidget/image/show", type=bool)
else "",
)
self.main_widget.listView_messages.setIndexWidget(
self.messages_model.indexFromItem(message_item), message_widget
)
message_widget.deletion_requested.connect(
self.message_deletion_requested_callback
)
def listener_opened_callback(self):
self.main_widget.label_status_active()
self.tray.set_icon_ok()
def listener_closed_callback(self, close_status_code: int, close_msg: str):
self.main_widget.label_status_connecting()
self.tray.set_icon_error()
if not self.shutting_down:
self.gotify_client.reconnect()
def application_selection_changed(
self, current: QtCore.QModelIndex, previous: QtCore.QModelIndex
):
if item := self.application_model.itemFromIndex(current):
self.main_widget.label_selected.setText(item.text())
self.messages_model.clear()
if isinstance(item, ApplicationModelItem):
def get_application_messages_callback(
page: gotify.GotifyPagedMessagesModel,
):
for i, message in enumerate(page.messages):
self.insert_message(i, message, item.application)
self.get_application_messages_task = GetApplicationMessagesTask(
item.application.id, self.gotify_client
)
self.get_application_messages_task.success.connect(
get_application_messages_callback
)
self.get_application_messages_task.start()
elif isinstance(item, ApplicationAllMessagesItem):
def get_messages_callback(page: gotify.GotifyPagedMessagesModel):
for i, message in enumerate(page.messages):
if item := self.application_model.itemFromId(message.appid):
self.insert_message(i, message, item.application)
self.get_messages_task = GetMessagesTask(self.gotify_client)
self.get_messages_task.success.connect(get_messages_callback)
self.get_messages_task.start()
def refresh_callback(self):
self.application_model.clear()
self.messages_model.clear()
self.refresh_applications()
if not self.gotify_client.listener.running:
self.gotify_client.listener.reset_wait_time()
else:
self.gotify_client.stop(reset_wait=True)
self.gotify_client.reconnect(increase_wait_time=False)
def delete_all_callback(self):
selection_model = self.main_widget.listView_applications.selectionModel()
if item := self.application_model.itemFromIndex(selection_model.currentIndex()):
self.messages_model.clear()
if isinstance(item, ApplicationModelItem):
self.delete_application_messages_task = DeleteApplicationMessagesTask(
item.application.id, self.gotify_client
)
self.delete_application_messages_task.start()
elif isinstance(item, ApplicationAllMessagesItem):
self.delete_all_messages_task = DeleteAllMessagesTask(
self.gotify_client
)
self.delete_all_messages_task.start()
def new_message_callback(self, message: gotify.GotifyMessageModel):
# Show a notification
application_item = self.application_model.itemFromId(message.appid)
if not self.isActiveWindow() and message.priority >= settings.value(
"tray/notifications/priority", type=int
):
image_url = f"{self.gotify_client.url}/{application_item.application.image}"
self.tray.showMessage(
message.title,
message.message,
QtGui.QIcon(downloader.get_filename(image_url))
if settings.value("tray/notifications/icon/show", type=bool)
else QtWidgets.QSystemTrayIcon.Information,
msecs=settings.value("tray/notifications/duration_ms", type=int),
)
# Add the message to the message_model, if its corresponding application is selected
application_index = (
self.main_widget.listView_applications.selectionModel().currentIndex()
)
if selected_application_item := self.application_model.itemFromIndex(
application_index
):
if isinstance(selected_application_item, ApplicationModelItem):
# A single application is selected
if message.appid == selected_application_item.application.id:
self.insert_message(0, message, application_item.application)
elif isinstance(selected_application_item, ApplicationAllMessagesItem):
# "All messages' is selected
self.insert_message(0, message, application_item.application)
def message_deletion_requested_callback(self, message_item: MessagesModelItem):
self.messages_model.removeRow(message_item.row())
self.delete_message_task = DeleteMessageTask(
message_item.message.id, self.gotify_client
)
self.delete_message_task.start()
def tray_activated_callback(
self, reason: QtWidgets.QSystemTrayIcon.ActivationReason
):
if reason == QtWidgets.QSystemTrayIcon.ActivationReason.Trigger:
if self.windowState() & QtCore.Qt.WindowState.WindowMinimized or self.windowState() == (
QtCore.Qt.WindowState.WindowMinimized
| QtCore.Qt.WindowState.WindowMaximized
):
self.show()
self.setWindowState(
self.window_state_to_restore | QtCore.Qt.WindowState.WindowActive
) # Set the window to its normal state
else:
window_state_temp = self.windowState()
self.setWindowState(QtCore.Qt.WindowState.WindowMinimized)
self.hide()
self.window_state_to_restore = window_state_temp
def message_clicked_callback(self):
self.main_widget.listView_messages.scrollToTop()
self.setWindowState(
self.window_state_to_restore | QtCore.Qt.WindowState.WindowActive
)
self.show()
def settings_callback(self):
settings_dialog = SettingsDialog(self.app)
accepted = settings_dialog.exec()
if accepted and settings_dialog.settings_changed:
settings_dialog.apply_settings()
if settings_dialog.server_changed:
mb = QtWidgets.QMessageBox(
QtWidgets.QMessageBox.Icon.Information,
"Restart",
"Restart to apply server changes",
QtWidgets.QMessageBox.StandardButton.Yes
| QtWidgets.QMessageBox.StandardButton.Cancel,
parent=self,
)
r = mb.exec()
if r == QtWidgets.QMessageBox.StandardButton.Yes:
self.close()
def link_callbacks(self):
self.main_widget.listView_applications.selectionModel().currentChanged.connect(
self.application_selection_changed
)
self.main_widget.pb_refresh.clicked.connect(self.refresh_callback)
self.main_widget.pb_delete_all.clicked.connect(self.delete_all_callback)
self.tray.actionQuit.triggered.connect(self.close)
self.tray.actionSettings.triggered.connect(self.settings_callback)
self.tray.actionToggleWindow.triggered.connect(
lambda: self.tray_activated_callback(
QtWidgets.QSystemTrayIcon.ActivationReason.Trigger
)
)
self.tray.messageClicked.connect(self.message_clicked_callback)
self.tray.activated.connect(self.tray_activated_callback)
def acquire_lock(self) -> bool:
temp_dir = tempfile.gettempdir()
lock_filename = os.path.join(
temp_dir, __title__ + "-" + getpass.getuser() + ".lock"
)
self.lock_file = QtCore.QLockFile(lock_filename)
self.lock_file.setStaleLockTime(0)
return self.lock_file.tryLock()
def restore_window_state(self):
window_geometry = settings.value("MainWindow/geometry", type=QtCore.QByteArray)
window_state = settings.value("MainWindow/state", type=QtCore.QByteArray)
if window_geometry:
self.restoreGeometry(window_geometry)
if window_state:
self.restoreState(window_state)
def save_window_state(self):
settings.setValue("MainWindow/geometry", self.saveGeometry())
settings.setValue("MainWindow/state", self.saveState())
def changeEvent(self, event: QtCore.QEvent) -> None:
if event.type() == QtCore.QEvent.Type.WindowStateChange:
if settings.value("tray/show", type=bool) and settings.value(
"tray/minimize", type=bool
):
if self.windowState() & QtCore.Qt.WindowState.WindowMinimized:
self.window_state_to_restore = (
self.windowState() & ~QtCore.Qt.WindowState.WindowMinimized
)
self.hide()
super(MainWindow, self).changeEvent(event)
def closeEvent(self, e: QtGui.QCloseEvent) -> None:
self.save_window_state()
if settings.value("tray/show", type=bool):
self.tray.hide()
self.lock_file.unlock()
self.shutting_down = True
self.gotify_client.stop()
super(MainWindow, self).closeEvent(e)
self.app.quit()

View File

@@ -0,0 +1,84 @@
import re
from PyQt6 import QtCore, QtGui, QtWidgets
from .MessagesModel import MessagesModelItem
from .designs.widget_message import Ui_Form
from gotify_tray.database import Settings
settings = Settings("gotify-tray")
def convert_links(text):
_link = re.compile(
r'(?:(https://|http://)|(www\.))(\S+\b/?)([!"#$%&\'()*+,\-./:;<=>?@[\\\]^_`{|}~]*)(\s|$)',
re.I,
)
def replace(match):
groups = match.groups()
protocol = groups[0] or "" # may be None
www_lead = groups[1] or "" # may be None
return '<a href="http://{1}{2}" rel="nofollow">{0}{1}{2}</a>{3}{4}'.format(
protocol, www_lead, *groups[2:]
)
return _link.sub(replace, text)
class MessageWidget(QtWidgets.QWidget, Ui_Form):
deletion_requested = QtCore.pyqtSignal(MessagesModelItem)
def __init__(self, message_item: MessagesModelItem, image_path: str = ""):
super(MessageWidget, self).__init__()
self.setupUi(self)
self.setAutoFillBackground(True)
self.message_item = message_item
message = self.message_item.message
# Fonts
font_title = QtGui.QFont()
font_date = QtGui.QFont()
font_content = QtGui.QFont()
font_title.fromString(settings.value("MessageWidget/font/title", type=str))
font_date.fromString(settings.value("MessageWidget/font/date", type=str))
font_content.fromString(settings.value("MessageWidget/font/content", type=str))
self.label_title.setFont(font_title)
self.label_date.setFont(font_date)
self.text_message.setFont(font_content)
self.label_title.setText(message.title)
self.label_date.setText(message.date.strftime("%Y-%m-%d, %H:%M"))
if markdown := message.get("extras", {}).get("client::display", {}).get("contentType") == "text/markdown":
self.text_message.setTextFormat(QtCore.Qt.TextFormat.MarkdownText)
self.text_message.setText(convert_links(message.message))
if image_path:
image_size = settings.value("MessageWidget/image/size", type=int)
self.label_image.setFixedSize(QtCore.QSize(image_size, image_size))
pixmap = QtGui.QPixmap(image_path).scaled(image_size, image_size, aspectRatioMode=QtCore.Qt.AspectRatioMode.KeepAspectRatioByExpanding)
self.label_image.setPixmap(pixmap)
else:
self.label_image.hide()
# Set MessagesModelItem's size hint based on the size of this widget
self.gridLayout_frame.setContentsMargins(10, 5, 10, 5)
self.gridLayout.setContentsMargins(5, 15, 5, 15)
self.adjustSize()
size_hint = self.message_item.sizeHint()
self.message_item.setSizeHint(
QtCore.QSize(
size_hint.width(),
self.height()
)
)
self.pb_delete.setIcon(QtGui.QIcon("gotify_tray/gui/images/trashcan.svg"))
self.pb_delete.setIconSize(QtCore.QSize(24, 24))
self.link_callbacks()
def link_callbacks(self):
self.pb_delete.clicked.connect(lambda: self.deletion_requested.emit(self.message_item))

View File

@@ -0,0 +1,17 @@
from typing import cast
from PyQt6 import QtCore, QtGui, QtWidgets
from gotify_tray import gotify
class MessagesModelItem(QtGui.QStandardItem):
def __init__(self, message: gotify.GotifyMessageModel, *args, **kwargs):
super(MessagesModelItem, self).__init__()
self.message = message
class MessagesModel(QtGui.QStandardItemModel):
def setItem(self, row: int, column: int, item: MessagesModelItem) -> None:
super(MessagesModel, self).setItem(row, column, item)
def itemFromIndex(self, index: QtCore.QModelIndex) -> MessagesModelItem:
return cast(MessagesModelItem, super(MessagesModel, self).itemFromIndex(index))

View File

@@ -0,0 +1,54 @@
from PyQt6 import QtWidgets
from gotify_tray.tasks import VerifyServerInfoTask
from .designs.widget_server import Ui_Dialog
class ServerInfoDialog(QtWidgets.QDialog, Ui_Dialog):
def __init__(self, url: str = "", token: str = ""):
super(ServerInfoDialog, self).__init__()
self.setupUi(self)
self.setWindowTitle("Server info")
self.line_url.setText(url)
self.line_token.setText(token)
self.buttonBox.button(QtWidgets.QDialogButtonBox.StandardButton.Ok).setDisabled(True)
self.link_callbacks()
def test_server_info(self):
self.pb_test.setStyleSheet("")
self.line_url.setStyleSheet("")
self.line_token.setStyleSheet("")
url = self.line_url.text()
client_token = self.line_token.text()
if not url or not client_token:
return
self.pb_test.setDisabled(True)
self.buttonBox.button(QtWidgets.QDialogButtonBox.StandardButton.Ok).setDisabled(True)
self.task = VerifyServerInfoTask(url, client_token)
self.task.success.connect(self.server_info_success)
self.task.incorrect_token.connect(self.incorrect_token_callback)
self.task.incorrect_url.connect(self.incorrect_url_callback)
self.task.start()
def server_info_success(self):
self.pb_test.setEnabled(True)
self.pb_test.setStyleSheet("background-color: rgba(0, 255, 0, 100);")
self.buttonBox.button(QtWidgets.QDialogButtonBox.StandardButton.Ok).setEnabled(True)
def incorrect_token_callback(self):
self.pb_test.setEnabled(True)
self.pb_test.setStyleSheet("background-color: rgba(255, 0, 0, 100);")
self.line_token.setStyleSheet("border: 1px solid red;")
def incorrect_url_callback(self):
self.pb_test.setEnabled(True)
self.pb_test.setStyleSheet("background-color: rgba(255, 0, 0, 100);")
self.line_url.setStyleSheet("border: 1px solid red;")
def link_callbacks(self):
self.pb_test.clicked.connect(self.test_server_info)
self.line_url.textChanged.connect(lambda: self.buttonBox.button(QtWidgets.QDialogButtonBox.StandardButton.Ok).setDisabled(True))
self.line_token.textChanged.connect(lambda: self.buttonBox.button(QtWidgets.QDialogButtonBox.StandardButton.Ok).setDisabled(True))

View File

@@ -0,0 +1,170 @@
from gotify_tray.database import Settings
from gotify_tray.utils import verify_server
from PyQt6 import QtCore, QtGui, QtWidgets
from .designs.widget_settings import Ui_Dialog
from .themes import set_theme
settings = Settings("gotify-tray")
class SettingsDialog(QtWidgets.QDialog, Ui_Dialog):
def __init__(self, app: QtWidgets.QApplication):
super(SettingsDialog, self).__init__()
self.setupUi(self)
self.setWindowTitle("Settings")
self.app = app
self.settings_changed = False
self.changes_applied = False
self.server_changed = False
self.initUI()
self.link_callbacks()
def initUI(self):
self.buttonBox.button(
QtWidgets.QDialogButtonBox.StandardButton.Apply
).setEnabled(False)
# Fonts
self.set_font_labels()
# Theme
self.combo_theme.addItems(["default", "dark"])
self.combo_theme.setCurrentText(settings.value("MainWindow/theme", type=str))
# Icons
self.cb_icons_application.setChecked(
settings.value("ApplicationModelItem/icon/show", type=bool)
)
self.cb_icons_message.setChecked(
settings.value("MessageWidget/image/show", type=bool)
)
self.cb_icons_notification.setChecked(
settings.value("tray/notifications/icon/show", type=bool)
)
# Notifications
self.spin_priority.setValue(
settings.value("tray/notifications/priority", type=int)
)
self.spin_duration.setValue(
settings.value("tray/notifications/duration_ms", type=int)
)
def set_font_labels(self):
self.label_font_message_title.setText(
settings.value("MessageWidget/font/title", type=str)
)
self.label_font_message_date.setText(
settings.value("MessageWidget/font/date", type=str)
)
self.label_font_message_content.setText(
settings.value("MessageWidget/font/content", type=str)
)
def change_font_callback(self, key: str):
font = QtGui.QFont()
font.fromString(settings.value(key, type=str))
font, accepted = QtWidgets.QFontDialog.getFont(font, self, "Select font")
if not accepted:
return
self.settings_changed_callback()
label: QtWidgets.QLabel = getattr(
self, "label_font_message_" + key.split("/")[-1]
)
label.setText(font.toString())
def change_server_info_callback(self):
self.server_changed = verify_server(force_new=True)
def settings_changed_callback(self, *args, **kwargs):
self.settings_changed = True
self.buttonBox.button(
QtWidgets.QDialogButtonBox.StandardButton.Apply
).setEnabled(True)
def reset_settings_callback(self):
response = QtWidgets.QMessageBox.warning(
self,
"Are you sure?",
"Reset all settings?",
QtWidgets.QMessageBox.StandardButton.Ok
| QtWidgets.QMessageBox.StandardButton.Cancel,
defaultButton=QtWidgets.QMessageBox.StandardButton.Cancel,
)
if response == QtWidgets.QMessageBox.StandardButton.Ok:
settings.clear()
def link_callbacks(self):
self.buttonBox.button(
QtWidgets.QDialogButtonBox.StandardButton.Apply
).clicked.connect(self.apply_settings)
# Fonts
self.pb_font_message_title.clicked.connect(
lambda: self.change_font_callback("MessageWidget/font/title")
)
self.pb_font_message_date.clicked.connect(
lambda: self.change_font_callback("MessageWidget/font/date")
)
self.pb_font_message_content.clicked.connect(
lambda: self.change_font_callback("MessageWidget/font/content")
)
# Theme
self.combo_theme.currentTextChanged.connect(self.settings_changed_callback)
# Icons
self.cb_icons_application.stateChanged.connect(self.settings_changed_callback)
self.cb_icons_message.stateChanged.connect(self.settings_changed_callback)
self.cb_icons_notification.stateChanged.connect(self.settings_changed_callback)
# Notifications
self.spin_priority.valueChanged.connect(self.settings_changed_callback)
self.spin_duration.valueChanged.connect(self.settings_changed_callback)
# Server info
self.pb_change_server_info.clicked.connect(self.change_server_info_callback)
def apply_settings(self):
# Fonts
settings.setValue(
"MessageWidget/font/title", self.label_font_message_title.text()
)
settings.setValue(
"MessageWidget/font/date", self.label_font_message_date.text()
)
settings.setValue(
"MessageWidget/font/content", self.label_font_message_content.text()
)
# Theme
settings.setValue("MainWindow/theme", self.combo_theme.currentText())
set_theme(self.app, self.combo_theme.currentText())
# Icons
settings.setValue(
"ApplicationModelItem/icon/show", self.cb_icons_application.isChecked()
)
settings.setValue("MessageWidget/image/show", self.cb_icons_message.isChecked())
settings.setValue(
"tray/notifications/icon/show", self.cb_icons_notification.isChecked()
)
# Priority
settings.setValue("tray/notifications/priority", self.spin_priority.value())
settings.setValue("tray/notifications/duration_ms", self.spin_duration.value())
self.settings_changed = False
self.buttonBox.button(
QtWidgets.QDialogButtonBox.StandardButton.Apply
).setEnabled(False)
self.changes_applied = True

34
gotify_tray/gui/Tray.py Normal file
View File

@@ -0,0 +1,34 @@
from PyQt6 import QtGui, QtWidgets
from gotify_tray.__version__ import __title__
class Tray(QtWidgets.QSystemTrayIcon):
def __init__(self):
super(Tray, self).__init__()
self.set_icon_error()
self.setToolTip(__title__)
# Tray menu items
menu = QtWidgets.QMenu()
self.actionSettings = QtGui.QAction("Settings", self)
menu.addAction(self.actionSettings)
menu.addSeparator()
self.actionToggleWindow = QtGui.QAction("Toggle Window", self)
menu.addAction(self.actionToggleWindow)
menu.addSeparator()
self.actionQuit = QtGui.QAction("Quit", self)
menu.addAction(self.actionQuit)
self.setContextMenu(menu)
def set_icon_ok(self):
self.setIcon(QtGui.QIcon("gotify_tray/gui/images/gotify-small.png"))
def set_icon_error(self):
self.setIcon(QtGui.QIcon("gotify_tray/gui/images/gotify-small-error.png"))

View File

@@ -0,0 +1,2 @@
from .MainWindow import MainWindow
from .ServerInfoDialog import ServerInfoDialog

View File

@@ -0,0 +1,95 @@
# Form implementation generated from reading ui file 'gotify_tray/gui/designs\widget_main.ui'
#
# Created by: PyQt6 UI code generator 6.1.1
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt6 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(809, 572)
self.gridLayout_2 = QtWidgets.QGridLayout(Form)
self.gridLayout_2.setObjectName("gridLayout_2")
self.listView_applications = QtWidgets.QListView(Form)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.listView_applications.sizePolicy().hasHeightForWidth())
self.listView_applications.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setPointSize(13)
self.listView_applications.setFont(font)
self.listView_applications.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers)
self.listView_applications.setWordWrap(True)
self.listView_applications.setObjectName("listView_applications")
self.gridLayout_2.addWidget(self.listView_applications, 0, 0, 1, 1)
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setObjectName("gridLayout")
self.pb_delete_all = QtWidgets.QPushButton(Form)
self.pb_delete_all.setMinimumSize(QtCore.QSize(0, 32))
font = QtGui.QFont()
font.setPointSize(10)
self.pb_delete_all.setFont(font)
self.pb_delete_all.setObjectName("pb_delete_all")
self.gridLayout.addWidget(self.pb_delete_all, 0, 5, 1, 1)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
self.gridLayout.addItem(spacerItem, 0, 3, 1, 1)
self.label_selected = QtWidgets.QLabel(Form)
self.label_selected.setMinimumSize(QtCore.QSize(0, 32))
font = QtGui.QFont()
font.setPointSize(15)
font.setBold(True)
self.label_selected.setFont(font)
self.label_selected.setObjectName("label_selected")
self.gridLayout.addWidget(self.label_selected, 0, 2, 1, 1)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
self.gridLayout.addItem(spacerItem1, 0, 1, 1, 1)
self.pb_refresh = QtWidgets.QPushButton(Form)
self.pb_refresh.setMinimumSize(QtCore.QSize(0, 32))
font = QtGui.QFont()
font.setPointSize(10)
self.pb_refresh.setFont(font)
self.pb_refresh.setObjectName("pb_refresh")
self.gridLayout.addWidget(self.pb_refresh, 0, 4, 1, 1)
self.label_status = QtWidgets.QLabel(Form)
self.label_status.setText("")
self.label_status.setObjectName("label_status")
self.gridLayout.addWidget(self.label_status, 0, 0, 1, 1)
self.listView_messages = QtWidgets.QListView(Form)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.listView_messages.sizePolicy().hasHeightForWidth())
self.listView_messages.setSizePolicy(sizePolicy)
self.listView_messages.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollMode.ScrollPerPixel)
self.listView_messages.setObjectName("listView_messages")
self.gridLayout.addWidget(self.listView_messages, 1, 0, 1, 6)
self.gridLayout_2.addLayout(self.gridLayout, 0, 1, 1, 1)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
Form.setTabOrder(self.pb_refresh, self.pb_delete_all)
Form.setTabOrder(self.pb_delete_all, self.listView_messages)
Form.setTabOrder(self.listView_messages, self.listView_applications)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.pb_delete_all.setText(_translate("Form", "Delete All"))
self.label_selected.setText(_translate("Form", "TextLabel"))
self.pb_refresh.setText(_translate("Form", "Refresh"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec())

View File

@@ -0,0 +1,153 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>809</width>
<height>572</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QListView" name="listView_applications">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="5">
<widget class="QPushButton" name="pb_delete_all">
<property name="minimumSize">
<size>
<width>0</width>
<height>32</height>
</size>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Delete All</string>
</property>
</widget>
</item>
<item row="0" column="3">
<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>
<item row="0" column="2">
<widget class="QLabel" name="label_selected">
<property name="minimumSize">
<size>
<width>0</width>
<height>32</height>
</size>
</property>
<property name="font">
<font>
<pointsize>15</pointsize>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer_2">
<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="4">
<widget class="QPushButton" name="pb_refresh">
<property name="minimumSize">
<size>
<width>0</width>
<height>32</height>
</size>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Refresh</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_status">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="0" colspan="6">
<widget class="QListView" name="listView_messages">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<tabstops>
<tabstop>pb_refresh</tabstop>
<tabstop>pb_delete_all</tabstop>
<tabstop>listView_messages</tabstop>
<tabstop>listView_applications</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,94 @@
# Form implementation generated from reading ui file 'gotify_tray/gui/designs\widget_message.ui'
#
# Created by: PyQt6 UI code generator 6.1.1
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt6 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(454, 122)
self.gridLayout = QtWidgets.QGridLayout(Form)
self.gridLayout.setSizeConstraint(QtWidgets.QLayout.SizeConstraint.SetMinimumSize)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.frame = QtWidgets.QFrame(Form)
self.frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
self.frame.setObjectName("frame")
self.gridLayout_frame = QtWidgets.QGridLayout(self.frame)
self.gridLayout_frame.setSizeConstraint(QtWidgets.QLayout.SizeConstraint.SetMinimumSize)
self.gridLayout_frame.setContentsMargins(-1, 0, -1, 0)
self.gridLayout_frame.setObjectName("gridLayout_frame")
self.label_title = QtWidgets.QLabel(self.frame)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_title.sizePolicy().hasHeightForWidth())
self.label_title.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setPointSize(17)
font.setBold(False)
font.setWeight(50)
self.label_title.setFont(font)
self.label_title.setTextInteractionFlags(QtCore.Qt.TextInteractionFlag.LinksAccessibleByMouse|QtCore.Qt.TextInteractionFlag.TextSelectableByMouse)
self.label_title.setObjectName("label_title")
self.gridLayout_frame.addWidget(self.label_title, 0, 1, 1, 1)
self.text_message = QtWidgets.QLabel(self.frame)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.MinimumExpanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.text_message.sizePolicy().hasHeightForWidth())
self.text_message.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setPointSize(11)
self.text_message.setFont(font)
self.text_message.setWordWrap(True)
self.text_message.setOpenExternalLinks(True)
self.text_message.setTextInteractionFlags(QtCore.Qt.TextInteractionFlag.LinksAccessibleByMouse|QtCore.Qt.TextInteractionFlag.TextSelectableByMouse)
self.text_message.setObjectName("text_message")
self.gridLayout_frame.addWidget(self.text_message, 3, 1, 1, 3)
self.label_date = QtWidgets.QLabel(self.frame)
font = QtGui.QFont()
font.setPointSize(11)
self.label_date.setFont(font)
self.label_date.setTextInteractionFlags(QtCore.Qt.TextInteractionFlag.LinksAccessibleByMouse|QtCore.Qt.TextInteractionFlag.TextSelectableByMouse)
self.label_date.setObjectName("label_date")
self.gridLayout_frame.addWidget(self.label_date, 2, 1, 1, 1)
self.pb_delete = QtWidgets.QPushButton(self.frame)
self.pb_delete.setText("")
self.pb_delete.setFlat(True)
self.pb_delete.setObjectName("pb_delete")
self.gridLayout_frame.addWidget(self.pb_delete, 0, 3, 1, 1)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
self.gridLayout_frame.addItem(spacerItem, 0, 2, 1, 1)
self.label_image = QtWidgets.QLabel(self.frame)
self.label_image.setText("")
self.label_image.setObjectName("label_image")
self.gridLayout_frame.addWidget(self.label_image, 0, 0, 1, 1)
self.gridLayout.addWidget(self.frame, 0, 0, 1, 1)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.label_title.setText(_translate("Form", "Title"))
self.text_message.setText(_translate("Form", "TextLabel"))
self.label_date.setText(_translate("Form", "Date"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec())

View File

@@ -0,0 +1,152 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>454</width>
<height>122</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_frame">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="1">
<widget class="QLabel" name="label_title">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>17</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Title</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="3" column="1" colspan="3">
<widget class="QLabel" name="text_message">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_date">
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>Date</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QPushButton" name="pb_delete">
<property name="text">
<string/>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<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>
<item row="0" column="0">
<widget class="QLabel" name="label_image">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,64 @@
# Form implementation generated from reading ui file 'gotify_tray/gui/designs\widget_server.ui'
#
# Created by: PyQt6 UI code generator 6.1.1
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt6 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(300, 124)
self.gridLayout = QtWidgets.QGridLayout(Dialog)
self.gridLayout.setObjectName("gridLayout")
self.formLayout = QtWidgets.QFormLayout()
self.formLayout.setObjectName("formLayout")
self.label = QtWidgets.QLabel(Dialog)
self.label.setObjectName("label")
self.formLayout.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label)
self.line_url = QtWidgets.QLineEdit(Dialog)
self.line_url.setObjectName("line_url")
self.formLayout.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.line_url)
self.label_2 = QtWidgets.QLabel(Dialog)
self.label_2.setObjectName("label_2")
self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_2)
self.line_token = QtWidgets.QLineEdit(Dialog)
self.line_token.setObjectName("line_token")
self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.line_token)
self.gridLayout.addLayout(self.formLayout, 0, 0, 1, 2)
self.pb_test = QtWidgets.QPushButton(Dialog)
self.pb_test.setObjectName("pb_test")
self.gridLayout.addWidget(self.pb_test, 1, 1, 1, 1)
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Cancel|QtWidgets.QDialogButtonBox.StandardButton.Ok)
self.buttonBox.setObjectName("buttonBox")
self.gridLayout.addWidget(self.buttonBox, 2, 1, 1, 1)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
self.gridLayout.addItem(spacerItem, 1, 0, 1, 1)
self.retranslateUi(Dialog)
self.buttonBox.accepted.connect(Dialog.accept)
self.buttonBox.rejected.connect(Dialog.reject)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.label.setText(_translate("Dialog", "Server url:"))
self.label_2.setText(_translate("Dialog", "Client token:"))
self.pb_test.setText(_translate("Dialog", "Test"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec())

View File

@@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>300</width>
<height>124</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Server url:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="line_url"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Client token:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="line_token"/>
</item>
</layout>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="pb_test">
<property name="text">
<string>Test</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="1" column="0">
<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>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -0,0 +1,175 @@
# Form implementation generated from reading ui file 'gotify_tray/gui/designs\widget_settings.ui'
#
# Created by: PyQt6 UI code generator 6.1.1
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt6 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(375, 540)
self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
self.verticalLayout.setObjectName("verticalLayout")
self.groupBox = QtWidgets.QGroupBox(Dialog)
self.groupBox.setObjectName("groupBox")
self.gridLayout = QtWidgets.QGridLayout(self.groupBox)
self.gridLayout.setObjectName("gridLayout")
self.groupBox_2 = QtWidgets.QGroupBox(self.groupBox)
self.groupBox_2.setObjectName("groupBox_2")
self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox_2)
self.gridLayout_2.setObjectName("gridLayout_2")
self.label_3 = QtWidgets.QLabel(self.groupBox_2)
self.label_3.setObjectName("label_3")
self.gridLayout_2.addWidget(self.label_3, 2, 0, 1, 1)
self.label_2 = QtWidgets.QLabel(self.groupBox_2)
self.label_2.setObjectName("label_2")
self.gridLayout_2.addWidget(self.label_2, 1, 0, 1, 1)
self.pb_font_message_content = QtWidgets.QPushButton(self.groupBox_2)
self.pb_font_message_content.setMaximumSize(QtCore.QSize(30, 16777215))
self.pb_font_message_content.setObjectName("pb_font_message_content")
self.gridLayout_2.addWidget(self.pb_font_message_content, 2, 1, 1, 1)
self.pb_font_message_date = QtWidgets.QPushButton(self.groupBox_2)
self.pb_font_message_date.setMaximumSize(QtCore.QSize(30, 16777215))
self.pb_font_message_date.setObjectName("pb_font_message_date")
self.gridLayout_2.addWidget(self.pb_font_message_date, 1, 1, 1, 1)
self.label = QtWidgets.QLabel(self.groupBox_2)
self.label.setObjectName("label")
self.gridLayout_2.addWidget(self.label, 0, 0, 1, 1)
self.label_font_message_title = QtWidgets.QLabel(self.groupBox_2)
self.label_font_message_title.setObjectName("label_font_message_title")
self.gridLayout_2.addWidget(self.label_font_message_title, 0, 2, 1, 1)
self.pb_font_message_title = QtWidgets.QPushButton(self.groupBox_2)
self.pb_font_message_title.setMaximumSize(QtCore.QSize(30, 16777215))
self.pb_font_message_title.setObjectName("pb_font_message_title")
self.gridLayout_2.addWidget(self.pb_font_message_title, 0, 1, 1, 1)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
self.gridLayout_2.addItem(spacerItem, 0, 3, 1, 1)
self.label_font_message_date = QtWidgets.QLabel(self.groupBox_2)
self.label_font_message_date.setObjectName("label_font_message_date")
self.gridLayout_2.addWidget(self.label_font_message_date, 1, 2, 1, 1)
self.label_font_message_content = QtWidgets.QLabel(self.groupBox_2)
self.label_font_message_content.setObjectName("label_font_message_content")
self.gridLayout_2.addWidget(self.label_font_message_content, 2, 2, 1, 1)
self.gridLayout.addWidget(self.groupBox_2, 0, 0, 1, 1)
self.verticalLayout.addWidget(self.groupBox)
self.groupBox_6 = QtWidgets.QGroupBox(Dialog)
self.groupBox_6.setObjectName("groupBox_6")
self.gridLayout_5 = QtWidgets.QGridLayout(self.groupBox_6)
self.gridLayout_5.setObjectName("gridLayout_5")
self.combo_theme = QtWidgets.QComboBox(self.groupBox_6)
self.combo_theme.setObjectName("combo_theme")
self.gridLayout_5.addWidget(self.combo_theme, 0, 0, 1, 1)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
self.gridLayout_5.addItem(spacerItem1, 0, 1, 1, 1)
self.verticalLayout.addWidget(self.groupBox_6)
self.groupBox_3 = QtWidgets.QGroupBox(Dialog)
self.groupBox_3.setObjectName("groupBox_3")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.groupBox_3)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.cb_icons_application = QtWidgets.QCheckBox(self.groupBox_3)
self.cb_icons_application.setObjectName("cb_icons_application")
self.verticalLayout_2.addWidget(self.cb_icons_application)
self.cb_icons_message = QtWidgets.QCheckBox(self.groupBox_3)
self.cb_icons_message.setObjectName("cb_icons_message")
self.verticalLayout_2.addWidget(self.cb_icons_message)
self.cb_icons_notification = QtWidgets.QCheckBox(self.groupBox_3)
self.cb_icons_notification.setObjectName("cb_icons_notification")
self.verticalLayout_2.addWidget(self.cb_icons_notification)
self.verticalLayout.addWidget(self.groupBox_3)
self.groupBox_5 = QtWidgets.QGroupBox(Dialog)
self.groupBox_5.setObjectName("groupBox_5")
self.gridLayout_4 = QtWidgets.QGridLayout(self.groupBox_5)
self.gridLayout_4.setObjectName("gridLayout_4")
self.spin_priority = QtWidgets.QSpinBox(self.groupBox_5)
self.spin_priority.setMinimum(1)
self.spin_priority.setMaximum(10)
self.spin_priority.setProperty("value", 5)
self.spin_priority.setObjectName("spin_priority")
self.gridLayout_4.addWidget(self.spin_priority, 0, 1, 1, 1)
spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
self.gridLayout_4.addItem(spacerItem2, 0, 2, 1, 1)
self.label_4 = QtWidgets.QLabel(self.groupBox_5)
self.label_4.setObjectName("label_4")
self.gridLayout_4.addWidget(self.label_4, 0, 0, 1, 1)
self.spin_duration = QtWidgets.QSpinBox(self.groupBox_5)
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.label_5 = QtWidgets.QLabel(self.groupBox_5)
self.label_5.setObjectName("label_5")
self.gridLayout_4.addWidget(self.label_5, 1, 0, 1, 1)
self.label_6 = QtWidgets.QLabel(self.groupBox_5)
self.label_6.setObjectName("label_6")
self.gridLayout_4.addWidget(self.label_6, 1, 2, 1, 1)
self.verticalLayout.addWidget(self.groupBox_5)
self.groupBox_4 = QtWidgets.QGroupBox(Dialog)
self.groupBox_4.setObjectName("groupBox_4")
self.gridLayout_3 = QtWidgets.QGridLayout(self.groupBox_4)
self.gridLayout_3.setObjectName("gridLayout_3")
self.pb_change_server_info = QtWidgets.QPushButton(self.groupBox_4)
self.pb_change_server_info.setObjectName("pb_change_server_info")
self.gridLayout_3.addWidget(self.pb_change_server_info, 0, 0, 1, 1)
spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
self.gridLayout_3.addItem(spacerItem3, 0, 1, 1, 1)
self.verticalLayout.addWidget(self.groupBox_4)
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Apply|QtWidgets.QDialogButtonBox.StandardButton.Cancel|QtWidgets.QDialogButtonBox.StandardButton.Ok)
self.buttonBox.setObjectName("buttonBox")
self.verticalLayout.addWidget(self.buttonBox)
self.retranslateUi(Dialog)
self.buttonBox.accepted.connect(Dialog.accept)
self.buttonBox.rejected.connect(Dialog.reject)
QtCore.QMetaObject.connectSlotsByName(Dialog)
Dialog.setTabOrder(self.pb_font_message_title, self.pb_font_message_date)
Dialog.setTabOrder(self.pb_font_message_date, self.pb_font_message_content)
Dialog.setTabOrder(self.pb_font_message_content, self.cb_icons_application)
Dialog.setTabOrder(self.cb_icons_application, self.cb_icons_message)
Dialog.setTabOrder(self.cb_icons_message, self.cb_icons_notification)
Dialog.setTabOrder(self.cb_icons_notification, self.spin_priority)
Dialog.setTabOrder(self.spin_priority, self.spin_duration)
Dialog.setTabOrder(self.spin_duration, self.pb_change_server_info)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.groupBox.setTitle(_translate("Dialog", "Fonts"))
self.groupBox_2.setTitle(_translate("Dialog", "Message"))
self.label_3.setText(_translate("Dialog", "Content"))
self.label_2.setText(_translate("Dialog", "Date"))
self.pb_font_message_content.setText(_translate("Dialog", "..."))
self.pb_font_message_date.setText(_translate("Dialog", "..."))
self.label.setText(_translate("Dialog", "Title"))
self.label_font_message_title.setText(_translate("Dialog", "TextLabel"))
self.pb_font_message_title.setText(_translate("Dialog", "..."))
self.label_font_message_date.setText(_translate("Dialog", "TextLabel"))
self.label_font_message_content.setText(_translate("Dialog", "TextLabel"))
self.groupBox_6.setTitle(_translate("Dialog", "Theme"))
self.groupBox_3.setTitle(_translate("Dialog", "Icons"))
self.cb_icons_application.setText(_translate("Dialog", "Show application icons"))
self.cb_icons_message.setText(_translate("Dialog", "Show message icons"))
self.cb_icons_notification.setText(_translate("Dialog", "Show notification icons"))
self.groupBox_5.setTitle(_translate("Dialog", "Notifications"))
self.label_4.setText(_translate("Dialog", "Minimum priority to show notifications:"))
self.label_5.setText(_translate("Dialog", "Notification duration"))
self.label_6.setText(_translate("Dialog", "ms"))
self.groupBox_4.setTitle(_translate("Dialog", "Server info"))
self.pb_change_server_info.setText(_translate("Dialog", "Change server info"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec())

View File

@@ -0,0 +1,340 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>375</width>
<height>540</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Fonts</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Message</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Content</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Date</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="pb_font_message_content">
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="pb_font_message_date">
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Title</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_font_message_title">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="pb_font_message_title">
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="0" column="3">
<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>
<item row="1" column="2">
<widget class="QLabel" name="label_font_message_date">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="label_font_message_content">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>Theme</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="QComboBox" name="combo_theme"/>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer_4">
<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>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Icons</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="cb_icons_application">
<property name="text">
<string>Show application icons</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cb_icons_message">
<property name="text">
<string>Show message icons</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cb_icons_notification">
<property name="text">
<string>Show notification icons</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Notifications</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="1">
<widget class="QSpinBox" name="spin_priority">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>10</number>
</property>
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item row="0" column="2">
<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_4">
<property name="text">
<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="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Notification duration</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_6">
<property name="text">
<string>ms</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Server info</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QPushButton" name="pb_change_server_info">
<property name="text">
<string>Change server info</string>
</property>
</widget>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer_2">
<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>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>pb_font_message_title</tabstop>
<tabstop>pb_font_message_date</tabstop>
<tabstop>pb_font_message_content</tabstop>
<tabstop>cb_icons_application</tabstop>
<tabstop>cb_icons_message</tabstop>
<tabstop>cb_icons_notification</tabstop>
<tabstop>spin_priority</tabstop>
<tabstop>spin_duration</tabstop>
<tabstop>pb_change_server_info</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg>

After

Width:  |  Height:  |  Size: 155 B

View File

@@ -0,0 +1,12 @@
from PyQt6 import QtWidgets
def set_theme(app: QtWidgets.QApplication, theme: str = "default"):
if theme == "default":
from . import default
app.setPalette(default.palette())
elif theme == "dark":
from . import dark
app.setPalette(dark.palette())

View File

@@ -0,0 +1,19 @@
from PyQt6 import QtCore, QtGui
def palette() -> QtGui.QPalette:
palette = QtGui.QPalette()
palette.setColor(QtGui.QPalette.ColorRole.Window, QtGui.QColor(44, 44, 44))
palette.setColor(QtGui.QPalette.ColorRole.WindowText, QtCore.Qt.GlobalColor.white)
palette.setColor(QtGui.QPalette.ColorRole.Base, QtGui.QColor(52, 52, 52))
palette.setColor(QtGui.QPalette.ColorRole.AlternateBase, QtGui.QColor(44, 44, 44))
palette.setColor(QtGui.QPalette.ColorRole.ToolTipBase, QtCore.Qt.GlobalColor.white)
palette.setColor(QtGui.QPalette.ColorRole.ToolTipText, QtCore.Qt.GlobalColor.white)
palette.setColor(QtGui.QPalette.ColorRole.Text, QtCore.Qt.GlobalColor.white)
palette.setColor(QtGui.QPalette.ColorRole.Button, QtGui.QColor(44, 44, 44))
palette.setColor(QtGui.QPalette.ColorRole.ButtonText, QtCore.Qt.GlobalColor.white)
palette.setColor(QtGui.QPalette.ColorRole.BrightText, QtCore.Qt.GlobalColor.red)
palette.setColor(QtGui.QPalette.ColorRole.Link, QtGui.QColor(198, 99, 255))
palette.setColor(QtGui.QPalette.ColorRole.Highlight, QtGui.QColor(198, 99, 255))
palette.setColor(QtGui.QPalette.ColorRole.HighlightedText, QtCore.Qt.GlobalColor.black)
return palette

View File

@@ -0,0 +1,6 @@
from PyQt6 import QtGui
def palette() -> QtGui.QPalette:
palette = QtGui.QPalette()
return palette