Add about dialog
This commit is contained in:
parent
8d332e1262
commit
833b734434
2
LICENSE
2
LICENSE
@ -1,4 +1,4 @@
|
||||
MIT License Copyright (c) 2020 - 2021 Faerbit
|
||||
MIT License Copyright (c) 2020 - 2022 Faerbit
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
1
Pipfile
1
Pipfile
@ -7,6 +7,7 @@ name = "pypi"
|
||||
pyside6 = "~=6.3"
|
||||
requests = "~=2.28"
|
||||
requests-futures = "~=1.0"
|
||||
packaging = "~=21.3"
|
||||
|
||||
[dev-packages]
|
||||
pyinstaller = "~=5.1"
|
||||
|
84
Pipfile.lock
generated
84
Pipfile.lock
generated
@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "4397ad9a6ead53a68420c5e59d49fc0a7655f9a0079ee66548e0115e6fc3914d"
|
||||
"sha256": "633aca7e0b43a295ce3429d3e12976a4c16dcf422cee53e37d266f8000ef5feb"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
@ -40,6 +40,22 @@
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==3.4"
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
"sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb",
|
||||
"sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==21.3"
|
||||
},
|
||||
"pyparsing": {
|
||||
"hashes": [
|
||||
"sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb",
|
||||
"sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.8'",
|
||||
"version": "==3.0.9"
|
||||
},
|
||||
"pyside6": {
|
||||
"hashes": [
|
||||
"sha256:4d47a1bac761f480fa06d93d0d9a72603eb6625f1e503288125caaff716e9e97",
|
||||
@ -123,7 +139,7 @@
|
||||
"sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb",
|
||||
"sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"index": "pypi",
|
||||
"version": "==21.3"
|
||||
},
|
||||
"pep517": {
|
||||
@ -134,70 +150,6 @@
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==0.13.0"
|
||||
},
|
||||
"pillow": {
|
||||
"hashes": [
|
||||
"sha256:0030fdbd926fb85844b8b92e2f9449ba89607231d3dd597a21ae72dc7fe26927",
|
||||
"sha256:030e3460861488e249731c3e7ab59b07c7853838ff3b8e16aac9561bb345da14",
|
||||
"sha256:0ed2c4ef2451de908c90436d6e8092e13a43992f1860275b4d8082667fbb2ffc",
|
||||
"sha256:136659638f61a251e8ed3b331fc6ccd124590eeff539de57c5f80ef3a9594e58",
|
||||
"sha256:13b725463f32df1bfeacbf3dd197fb358ae8ebcd8c5548faa75126ea425ccb60",
|
||||
"sha256:1536ad017a9f789430fb6b8be8bf99d2f214c76502becc196c6f2d9a75b01b76",
|
||||
"sha256:15928f824870535c85dbf949c09d6ae7d3d6ac2d6efec80f3227f73eefba741c",
|
||||
"sha256:17d4cafe22f050b46d983b71c707162d63d796a1235cdf8b9d7a112e97b15bac",
|
||||
"sha256:1802f34298f5ba11d55e5bb09c31997dc0c6aed919658dfdf0198a2fe75d5490",
|
||||
"sha256:1cc1d2451e8a3b4bfdb9caf745b58e6c7a77d2e469159b0d527a4554d73694d1",
|
||||
"sha256:1fd6f5e3c0e4697fa7eb45b6e93996299f3feee73a3175fa451f49a74d092b9f",
|
||||
"sha256:254164c57bab4b459f14c64e93df11eff5ded575192c294a0c49270f22c5d93d",
|
||||
"sha256:2ad0d4df0f5ef2247e27fc790d5c9b5a0af8ade9ba340db4a73bb1a4a3e5fb4f",
|
||||
"sha256:2c58b24e3a63efd22554c676d81b0e57f80e0a7d3a5874a7e14ce90ec40d3069",
|
||||
"sha256:2d33a11f601213dcd5718109c09a52c2a1c893e7461f0be2d6febc2879ec2402",
|
||||
"sha256:336b9036127eab855beec9662ac3ea13a4544a523ae273cbf108b228ecac8437",
|
||||
"sha256:337a74fd2f291c607d220c793a8135273c4c2ab001b03e601c36766005f36885",
|
||||
"sha256:37ff6b522a26d0538b753f0b4e8e164fdada12db6c6f00f62145d732d8a3152e",
|
||||
"sha256:3d1f14f5f691f55e1b47f824ca4fdcb4b19b4323fe43cc7bb105988cad7496be",
|
||||
"sha256:4134d3f1ba5f15027ff5c04296f13328fecd46921424084516bdb1b2548e66ff",
|
||||
"sha256:4ad2f835e0ad81d1689f1b7e3fbac7b01bb8777d5a985c8962bedee0cc6d43da",
|
||||
"sha256:50dff9cc21826d2977ef2d2a205504034e3a4563ca6f5db739b0d1026658e004",
|
||||
"sha256:510cef4a3f401c246cfd8227b300828715dd055463cdca6176c2e4036df8bd4f",
|
||||
"sha256:5aed7dde98403cd91d86a1115c78d8145c83078e864c1de1064f52e6feb61b20",
|
||||
"sha256:69bd1a15d7ba3694631e00df8de65a8cb031911ca11f44929c97fe05eb9b6c1d",
|
||||
"sha256:6bf088c1ce160f50ea40764f825ec9b72ed9da25346216b91361eef8ad1b8f8c",
|
||||
"sha256:6e8c66f70fb539301e064f6478d7453e820d8a2c631da948a23384865cd95544",
|
||||
"sha256:74a04183e6e64930b667d321524e3c5361094bb4af9083db5c301db64cd341f3",
|
||||
"sha256:75e636fd3e0fb872693f23ccb8a5ff2cd578801251f3a4f6854c6a5d437d3c04",
|
||||
"sha256:7761afe0126d046974a01e030ae7529ed0ca6a196de3ec6937c11df0df1bc91c",
|
||||
"sha256:7888310f6214f19ab2b6df90f3f06afa3df7ef7355fc025e78a3044737fab1f5",
|
||||
"sha256:7b0554af24df2bf96618dac71ddada02420f946be943b181108cac55a7a2dcd4",
|
||||
"sha256:7c7b502bc34f6e32ba022b4a209638f9e097d7a9098104ae420eb8186217ebbb",
|
||||
"sha256:808add66ea764ed97d44dda1ac4f2cfec4c1867d9efb16a33d158be79f32b8a4",
|
||||
"sha256:831e648102c82f152e14c1a0938689dbb22480c548c8d4b8b248b3e50967b88c",
|
||||
"sha256:93689632949aff41199090eff5474f3990b6823404e45d66a5d44304e9cdc467",
|
||||
"sha256:96b5e6874431df16aee0c1ba237574cb6dff1dcb173798faa6a9d8b399a05d0e",
|
||||
"sha256:9a54614049a18a2d6fe156e68e188da02a046a4a93cf24f373bffd977e943421",
|
||||
"sha256:a138441e95562b3c078746a22f8fca8ff1c22c014f856278bdbdd89ca36cff1b",
|
||||
"sha256:a647c0d4478b995c5e54615a2e5360ccedd2f85e70ab57fbe817ca613d5e63b8",
|
||||
"sha256:a9c9bc489f8ab30906d7a85afac4b4944a572a7432e00698a7239f44a44e6efb",
|
||||
"sha256:ad2277b185ebce47a63f4dc6302e30f05762b688f8dc3de55dbae4651872cdf3",
|
||||
"sha256:adabc0bce035467fb537ef3e5e74f2847c8af217ee0be0455d4fec8adc0462fc",
|
||||
"sha256:b6d5e92df2b77665e07ddb2e4dbd6d644b78e4c0d2e9272a852627cdba0d75cf",
|
||||
"sha256:bc431b065722a5ad1dfb4df354fb9333b7a582a5ee39a90e6ffff688d72f27a1",
|
||||
"sha256:bdd0de2d64688ecae88dd8935012c4a72681e5df632af903a1dca8c5e7aa871a",
|
||||
"sha256:c79698d4cd9318d9481d89a77e2d3fcaeff5486be641e60a4b49f3d2ecca4e28",
|
||||
"sha256:cb6259196a589123d755380b65127ddc60f4c64b21fc3bb46ce3a6ea663659b0",
|
||||
"sha256:d5b87da55a08acb586bad5c3aa3b86505f559b84f39035b233d5bf844b0834b1",
|
||||
"sha256:dcd7b9c7139dc8258d164b55696ecd16c04607f1cc33ba7af86613881ffe4ac8",
|
||||
"sha256:dfe4c1fedfde4e2fbc009d5ad420647f7730d719786388b7de0999bf32c0d9fd",
|
||||
"sha256:ea98f633d45f7e815db648fd7ff0f19e328302ac36427343e4432c84432e7ff4",
|
||||
"sha256:ec52c351b35ca269cb1f8069d610fc45c5bd38c3e91f9ab4cbbf0aebc136d9c8",
|
||||
"sha256:eef7592281f7c174d3d6cbfbb7ee5984a671fcd77e3fc78e973d492e9bf0eb3f",
|
||||
"sha256:f07f1f00e22b231dd3d9b9208692042e29792d6bd4f6639415d2f23158a80013",
|
||||
"sha256:f3fac744f9b540148fa7715a435d2283b71f68bfb6d4aae24482a890aed18b59",
|
||||
"sha256:fa768eff5f9f958270b081bb33581b4b569faabf8774726b283edb06617101dc",
|
||||
"sha256:fac2d65901fb0fdf20363fbd345c01958a742f2dc62a8dd4495af66e3ff502a4"
|
||||
],
|
||||
"markers": "sys_platform == 'win32'",
|
||||
"version": "==9.2.0"
|
||||
},
|
||||
"pyinstaller": {
|
||||
"hashes": [
|
||||
"sha256:0ac78f1145be34adda8afb5fe4c8d659172140092c055994dab57ee2190bec71",
|
||||
|
@ -9,3 +9,4 @@ build-backend = "setuptools.build_meta"
|
||||
[tool.setuptools_scm]
|
||||
version_scheme = "guess-next-dev"
|
||||
local_scheme = "dirty-tag"
|
||||
write_to = "src/fime/_version.py"
|
||||
|
@ -21,6 +21,7 @@ python_requires = >=3.8
|
||||
install_requires =
|
||||
requests
|
||||
requests-futures
|
||||
packaging
|
||||
|
||||
[options.packages.find]
|
||||
where = src
|
||||
@ -32,4 +33,3 @@ qt6 = PySide6
|
||||
[options.entry_points]
|
||||
gui_scripts =
|
||||
fime = fime.main:main
|
||||
|
||||
|
1
src/fime/.gitignore
vendored
Normal file
1
src/fime/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
_version.py
|
@ -0,0 +1 @@
|
||||
from _version import __version__, __version_tuple__
|
5
src/fime/_version.py
Normal file
5
src/fime/_version.py
Normal file
@ -0,0 +1,5 @@
|
||||
# coding: utf-8
|
||||
# file generated by setuptools_scm
|
||||
# don't change, don't track in version control
|
||||
__version__ = version = '1.0.0.dev0'
|
||||
__version_tuple__ = version_tuple = (1, 0, 0, 'dev0')
|
139
src/fime/about.py
Normal file
139
src/fime/about.py
Normal file
@ -0,0 +1,139 @@
|
||||
import sys
|
||||
import traceback
|
||||
from copy import copy
|
||||
from textwrap import dedent
|
||||
from threading import Lock
|
||||
from typing import Optional
|
||||
|
||||
from packaging.version import Version
|
||||
from requests_futures.sessions import FuturesSession
|
||||
|
||||
from fime.progressindicator import ProgressIndicator
|
||||
from fime.util import get_icon
|
||||
|
||||
try:
|
||||
from PySide6 import QtCore, QtGui, QtWidgets
|
||||
except ImportError:
|
||||
from PySide2 import QtCore, QtGui, QtWidgets
|
||||
|
||||
import fime
|
||||
|
||||
URL = "https://gitlab.com/faerbit/fime/-/releases/permalink/latest"
|
||||
|
||||
|
||||
class UpdateChecker:
|
||||
def __init__(self):
|
||||
self.session = FuturesSession()
|
||||
future = self.session.get(URL, allow_redirects=False)
|
||||
future.add_done_callback(self.process_response)
|
||||
self.lock = Lock()
|
||||
self._done = False
|
||||
self.result = "Could not determined latest fime version"
|
||||
|
||||
@property
|
||||
def done(self):
|
||||
with self.lock:
|
||||
ret = copy(self._done)
|
||||
return ret
|
||||
|
||||
def process_response(self, future):
|
||||
try:
|
||||
resp = future.result()
|
||||
if resp.status_code != 302 or "Location" not in resp.headers:
|
||||
raise RuntimeError("Requested unexpectedly did not redirect")
|
||||
latest_version = resp.headers["Location"].split("/")[-1]
|
||||
latest_version = Version(latest_version)
|
||||
own_version = Version(fime.__version__)
|
||||
if own_version == latest_version:
|
||||
self.result = "Latest fime version installed"
|
||||
elif own_version > latest_version:
|
||||
self.result = f"Older fime version available: {latest_version}"
|
||||
else:
|
||||
self.result = f"Newer fime version available: {latest_version}"
|
||||
except Exception:
|
||||
print("Could not get update info:\n", file=sys.stderr)
|
||||
print(traceback.format_exc(), file=sys.stderr)
|
||||
finally:
|
||||
with self.lock:
|
||||
self._done = True
|
||||
|
||||
|
||||
class About(QtWidgets.QDialog):
|
||||
def __init__(self, parent, *args, **kwargs):
|
||||
super().__init__(parent, *args, **kwargs)
|
||||
self.setWindowTitle("About")
|
||||
|
||||
text = dedent(f"""\
|
||||
fime
|
||||
Copyright (c) 2020 - 2022 Faerbit
|
||||
<a href="https://gitlab.com/faerbit/fime/-/blob/main/LICENSE">License</a>
|
||||
|
||||
fime Version {fime.__version__}
|
||||
Qt Version {QtCore.__version__}
|
||||
Python Version {sys.version}
|
||||
""")
|
||||
text = text.replace("\n", "<br/>")
|
||||
version_label = QtWidgets.QLabel(self)
|
||||
version_label.setText(text)
|
||||
version_label.setTextFormat(QtCore.Qt.RichText)
|
||||
version_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction)
|
||||
version_label.setOpenExternalLinks(True)
|
||||
version_label.setAlignment(QtCore.Qt.AlignHCenter)
|
||||
|
||||
self.update_layout = QtWidgets.QHBoxLayout()
|
||||
|
||||
self.ok_button = QtWidgets.QPushButton()
|
||||
self.ok_button.setText("OK")
|
||||
self.ok_button.setIcon(get_icon("dialog-ok"))
|
||||
self.ok_button.pressed.connect(self.accept)
|
||||
self.ok_button.setAutoDefault(True)
|
||||
|
||||
hlayout = QtWidgets.QHBoxLayout()
|
||||
hlayout.addStretch(66)
|
||||
hlayout.addWidget(self.ok_button, 33)
|
||||
|
||||
vlayout = QtWidgets.QVBoxLayout()
|
||||
vlayout.addWidget(version_label)
|
||||
vlayout.addLayout(self.update_layout)
|
||||
vlayout.addLayout(hlayout)
|
||||
|
||||
self.setLayout(vlayout)
|
||||
|
||||
self.update_checker: Optional[UpdateChecker] = None
|
||||
self.update_timer = QtCore.QTimer(self)
|
||||
self.update_timer.setInterval(500)
|
||||
self.update_timer.timeout.connect(self.timer_callback)
|
||||
|
||||
def clear_update_layout(self):
|
||||
while self.update_layout.count():
|
||||
child = self.update_layout.takeAt(0)
|
||||
if child.widget():
|
||||
child.widget().deleteLater()
|
||||
|
||||
def timer_callback(self):
|
||||
if self.update_checker.done:
|
||||
self.clear_update_layout()
|
||||
update_label = QtWidgets.QLabel(self)
|
||||
update_label.setText(self.update_checker.result)
|
||||
update_label.setAlignment(QtCore.Qt.AlignHCenter)
|
||||
|
||||
self.update_layout.addWidget(update_label)
|
||||
self.update_timer.stop()
|
||||
|
||||
def showEvent(self, _):
|
||||
self.clear_update_layout()
|
||||
|
||||
progress_indicator = ProgressIndicator(self)
|
||||
progress_indicator.setAnimationDelay(70)
|
||||
progress_indicator.startAnimation()
|
||||
|
||||
update_label = QtWidgets.QLabel(self)
|
||||
update_label.setText("Checking for latest version...")
|
||||
|
||||
self.update_layout.addStretch()
|
||||
self.update_layout.addWidget(progress_indicator)
|
||||
self.update_layout.addWidget(update_label)
|
||||
self.update_layout.addStretch()
|
||||
|
||||
self.update_checker = UpdateChecker()
|
||||
self.update_timer.start()
|
@ -3,6 +3,7 @@ import signal
|
||||
import sys
|
||||
from functools import partial
|
||||
|
||||
from fime.about import About
|
||||
from fime.config import Config
|
||||
from fime.worklog import WorklogDialog
|
||||
|
||||
@ -54,6 +55,8 @@ class App:
|
||||
self.worklogDialog = WorklogDialog(config, Worklog(lcd), None)
|
||||
self.worklogDialog.accepted.connect(self.log_edited)
|
||||
|
||||
self.about = About(None)
|
||||
|
||||
self.tray = QtWidgets.QSystemTrayIcon()
|
||||
self.tray.setIcon(icon)
|
||||
self.tray.setContextMenu(self.menu)
|
||||
@ -104,7 +107,7 @@ class App:
|
||||
add_tasks(self.tasks.tasks)
|
||||
|
||||
menu_items.append((1, None))
|
||||
already_taken = (len(self.tasks.tasks) + 4) * action_height
|
||||
already_taken = (len(self.tasks.tasks) + 5) * action_height
|
||||
available_space = get_screen_height(self.menu) * 0.8 - already_taken
|
||||
jira_entry_count = int(available_space // action_height)
|
||||
add_tasks(self.tasks.jira_tasks[-jira_entry_count:])
|
||||
@ -122,6 +125,7 @@ class App:
|
||||
|
||||
menu_items.append((1, None))
|
||||
|
||||
menu_items.append(("About", self.about.show))
|
||||
menu_items.append(("Close", self.app.quit))
|
||||
|
||||
if self.menu_flipped:
|
||||
@ -159,6 +163,19 @@ class App:
|
||||
self.taskEdit.tasks = self.tasks.tasks
|
||||
self.taskEdit.show()
|
||||
|
||||
#@QtCore.Slot()
|
||||
#def about(self):
|
||||
#max_line_length = reduce(lambda x, y: max(x, len(y)), text.splitlines(), 0)
|
||||
#print(max_line_length)
|
||||
#final_text = ""
|
||||
#for line in text.splitlines():
|
||||
# final_text += line.center(max_line_length)
|
||||
# final_text += "\n"
|
||||
#print(final_text)
|
||||
#QtWidgets.QMessageBox.about(None, "About", final_text)
|
||||
#a = About(None)
|
||||
#a.show()
|
||||
|
||||
|
||||
def excepthook(original, e_type, e_value, tb_obj):
|
||||
if e_type is FimeException:
|
||||
|
Loading…
Reference in New Issue
Block a user