Skip to content

Commit cdd320d

Browse files
authored
Merge pull request #235 from semuconsulting/RC-1.6.1
RC 1.6.1
2 parents f381c85 + 16adecb commit cdd320d

29 files changed

+290
-173
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,13 @@ For more comprehensive installation instructions, please refer to [INSTALLATION.
144144

145145
#### <a name="config">Saving and loading configuration settings</a>
146146

147-
- Configuration settings for PyGPSClient can be saved and recalled via the Menu..File..Save Configuration and Menu..File..Load Configuration options. By default, PyGPSClient will look for a file named `pygpsclient.json` in the user's home directory. Certain configuration settings require manual editing e.g. custom preset UBX, NMEA and TTY commands and tag colour schemes - see details below.
147+
- Configuration settings for PyGPSClient can be saved and recalled via the Menu..File..Save/Load Configuration options. By default, PyGPSClient will look for a file named `pygpsclient.json` in the user's home directory. Certain configuration settings require manual editing e.g. custom preset UBX, NMEA and TTY commands and tag colour schemes - see details below.
148148
- It is recommended to re-save the configuration settings after each PyGPSClient version update, or if you see the warning "Consider re-saving" on startup.
149149
- PyGPSClient will prompt you to stop all running input and output streams before loading a new configuration.
150150

151151
#### <a name="transient">Toplevel ('pop-up') dialog setting</a>
152152

153-
- The behaviour of Toplevel ('pop-up') dialogs will depend on the screen resolution. If the width or height of a Toplevel dialog exceeds the screen resolution, the dialog will be displayed in a scrollable, resizeable window. Otherwise, the dialog is displayed as a fixed, non-resizeable panel.
153+
- The behaviour of Toplevel ('pop-up') dialogs will depend on the screen resolution and 'transient' setting. If the width or height of a Toplevel dialog exceeds the screen resolution, the dialog will be displayed in a scrollable, resizeable window. Otherwise, the dialog is displayed as a fixed, non-resizeable panel.
154154
- A boolean configuration setting `transient_dialog_b` governs whether Toplevel dialogs are 'transient' (i.e. always on top of main application dialog) or not. Changing this setting to `0` allows Toplevel dialogs to be minimised independently of the main application window, but be mindful that some dialogs may end up hidden behind others e.g. "Open file/folder" dialogs. **If a file open button appears unresponsive, check that the "Open file/folder" panel isn't already open but obscured**.
155155
- If you're accessing the desktop via a VNC session (e.g. to a headless Raspberry Pi) it is recommended to keep the setting at the default `1`, as VNC may not recognise keystrokes on overlaid non-transient windows.
156156

RELEASE_NOTES.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# PyGPSClient Release Notes
22

3+
### RELEASE 1.6.1
4+
5+
1. Updates to main application window geometry (size and position) handling. Current window geometry is now saved to json configuration file as `screengeom_s` (e.g. `"1373x798+71+44"`), and will be restored on restart. Default startup geometry is centered at 75% of screen resolution.
6+
37
### RELEASE 1.6.0
48

59
FIXES:

src/pygpsclient/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@
88
:license: BSD 3-Clause
99
"""
1010

11-
__version__ = "1.6.0"
11+
__version__ = "1.6.1"

src/pygpsclient/about_dialog.py

Lines changed: 48 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,12 @@
1111
"""
1212

1313
import logging
14-
from platform import python_version
14+
from platform import machine, python_version
1515
from tkinter import Button, Checkbutton, Frame, IntVar, Label, Tcl
1616
from webbrowser import open_new_tab
1717

1818
from PIL import Image, ImageTk
19-
from pygnssutils import version as PGVERSION
20-
from pynmeagps import version as NMEAVERSION
21-
from pyqgc import version as QGCVERSION
22-
from pyrtcm import version as RTCMVERSION
23-
from pysbf2 import version as SBFVERSION
24-
from pyspartn import version as SPARTNVERSION
25-
from pyubx2 import version as UBXVERSION
26-
27-
from pygpsclient._version import __version__ as VERSION
19+
2820
from pygpsclient.globals import (
2921
ERRCOL,
3022
ICON_APP128,
@@ -36,22 +28,22 @@
3628
SPONSOR_URL,
3729
TRACEMODE_WRITE,
3830
)
39-
from pygpsclient.helpers import brew_installed, check_latest
31+
from pygpsclient.helpers import LIBVERSIONS, brew_installed, check_for_updates
4032
from pygpsclient.sqlite_handler import SQLSTATUS
41-
from pygpsclient.strings import ABOUTTXT, BREWWARN, COPYRIGHT, DLGTABOUT, GITHUB_URL
33+
from pygpsclient.strings import (
34+
ABOUTTXT,
35+
BREWUPDATE,
36+
BREWWARN,
37+
COPYRIGHT,
38+
DLGTABOUT,
39+
GITHUB_URL,
40+
NA,
41+
UPDATEERR,
42+
UPDATEINPROG,
43+
UPDATERESTART,
44+
)
4245
from pygpsclient.toplevel_dialog import ToplevelDialog
4346

44-
LIBVERSIONS = {
45-
"PyGPSClient": VERSION,
46-
"pygnssutils": PGVERSION,
47-
"pyubx2": UBXVERSION,
48-
"pysbf2": SBFVERSION,
49-
"pyqgc": QGCVERSION,
50-
"pynmeagps": NMEAVERSION,
51-
"pyrtcm": RTCMVERSION,
52-
"pyspartn": SPARTNVERSION,
53-
}
54-
5547

5648
class AboutDialog(ToplevelDialog):
5749
"""
@@ -73,7 +65,6 @@ def __init__(self, app, *args, **kwargs): # pylint: disable=unused-argument
7365
self._img_sponsor = ImageTk.PhotoImage(Image.open(ICON_SPONSOR))
7466
self._checkonstartup = IntVar()
7567
self._checkonstartup.set(self.__app.configuration.get("checkforupdate_b"))
76-
self._updates = []
7768

7869
super().__init__(app, DLGTABOUT)
7970

@@ -102,6 +93,7 @@ def _body(self):
10293
self._lbl_python_version = Label(
10394
self._frm_body,
10495
text=(
96+
f"Arch: {machine()} "
10597
f"Python: {python_version()} Tk: {tkv} "
10698
f"Spatial: {SQLSTATUS[self.__app.db_enabled]}"
10799
),
@@ -118,7 +110,7 @@ def _body(self):
118110
)
119111
self._btn_checkupdate = Button(
120112
self._frm_body,
121-
text="Check for updates",
113+
text="",
122114
width=14,
123115
cursor="hand2",
124116
)
@@ -175,7 +167,7 @@ def _attach_events(self):
175167
Bind events to dialog.
176168
"""
177169

178-
self._btn_checkupdate.bind("<Button>", self._check_for_update)
170+
self._set_update_btn_mode(False)
179171
self._lbl_github.bind("<Button>", self._on_github)
180172
self._lbl_sponsoricon.bind("<Button>", self._on_sponsor)
181173
self._lbl_copyright.bind("<Button>", self._on_license)
@@ -197,7 +189,7 @@ def _on_github(self, *args, **kwargs): # pylint: disable=unused-argument
197189
"""
198190

199191
if brew_installed():
200-
self._brew_warning()
192+
self.status_label = (BREWWARN, INFOCOL)
201193
return
202194

203195
open_new_tab(GITHUB_URL)
@@ -209,7 +201,7 @@ def _on_sponsor(self, *args, **kwargs): # pylint: disable=unused-argument
209201
"""
210202

211203
if brew_installed():
212-
self._brew_warning()
204+
self.status_label = (BREWWARN, INFOCOL)
213205
return
214206

215207
open_new_tab(SPONSOR_URL)
@@ -221,7 +213,7 @@ def _on_license(self, *args, **kwargs): # pylint: disable=unused-argument
221213
"""
222214

223215
if brew_installed():
224-
self._brew_warning()
216+
self.status_label = (BREWWARN, INFOCOL)
225217
return
226218

227219
open_new_tab(LICENSE_URL)
@@ -232,49 +224,56 @@ def _check_for_update(self, *args, **kwargs): # pylint: disable=unused-argument
232224
Check for updates.
233225
"""
234226

235-
self.status_label = ""
236-
self._updates = []
237-
for i, (nam, current) in enumerate(LIBVERSIONS.items()):
238-
latest = check_latest(nam)
227+
versions = check_for_updates()
228+
self.status_label = ("Checking for updates...", INFOCOL)
229+
for i, (nam, current, latest) in enumerate(versions):
239230
txt = f"{nam}: {current}"
240231
if latest == current:
241232
txt += " ✓"
242233
col = OKCOL
243-
elif latest == "N/A":
234+
elif latest == NA:
244235
txt += " - Info not available!"
245236
col = ERRCOL
246237
else:
247-
self._updates.append(nam)
248238
txt += f" - Latest version is {latest}"
249239
col = ERRCOL
250240
self._lbl_lib_versions[i].config(text=txt, fg=col)
251241

252-
if len(self._updates) > 0:
253-
self._btn_checkupdate.config(text="UPDATE", fg=INFOCOL)
254-
self._btn_checkupdate.bind("<Button>", self._do_update)
242+
updates = [nam for (nam, current, latest) in versions if latest != current]
243+
if len(updates) > 0:
244+
self.status_label = ("Updates available", OKCOL)
245+
self._set_update_btn_mode(True)
246+
else:
247+
self.status_label = ("No updates available", INFOCOL)
255248

256249
def _do_update(self, *args, **kwargs): # pylint: disable=unused-argument
257250
"""
258251
Run python update.
259252
"""
260253

261254
if brew_installed():
262-
self._brew_warning()
255+
self.status_label = (BREWUPDATE, INFOCOL)
263256
return
264257

265-
self._btn_checkupdate.config(text="UPDATING...", fg=INFOCOL)
266-
self.update_idletasks()
267-
rc = self.__app.do_app_update(self._updates)
258+
self.status_label = (UPDATEINPROG, INFOCOL)
259+
rc = self.__app.do_app_update()
268260
if rc:
269-
self._btn_checkupdate.config(text="RESTART APP", fg=OKCOL)
270-
self._btn_checkupdate.bind("<Button>", self.__app.on_exit)
261+
self.status_label = (UPDATERESTART, OKCOL)
271262
else:
272-
self._btn_checkupdate.config(text="UPDATE FAILED", fg=ERRCOL)
273-
self._btn_checkupdate.bind("<Button>", self._check_for_update)
263+
self.status_label = (UPDATEERR.format(err=rc), ERRCOL)
264+
self._set_update_btn_mode(False)
274265

275-
def _brew_warning(self):
266+
def _set_update_btn_mode(self, update: bool):
276267
"""
277-
Display warning that some functionality unavailable with Homebrew.
268+
Set Check for update button label and binding.
269+
270+
:param bool update: False = check, True = update
278271
"""
279272

280-
self.status_label = (BREWWARN, INFOCOL)
273+
if update:
274+
self._btn_checkupdate.config(text="UPDATE", fg=OKCOL)
275+
self._btn_checkupdate.bind("<Button>", self._do_update)
276+
else:
277+
self._btn_checkupdate.config(text="CHECK FOR UPDATES", fg=INFOCOL)
278+
self._btn_checkupdate.bind("<Button>", self._check_for_update)
279+
self.update_idletasks()

0 commit comments

Comments
 (0)