diff --git a/client/brewpi_gui.py b/client/brewpi_gui.py index ec4bf8e..e8a0527 100755 --- a/client/brewpi_gui.py +++ b/client/brewpi_gui.py @@ -5,6 +5,7 @@ import json import sys import threading import time +from pathlib import Path import matplotlib matplotlib.use("Qt5Agg") from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg @@ -15,6 +16,7 @@ from ws.client.ws_client import WsClient from ws.message import MessageDispatcherSync from queue import Queue import asyncio +from user_config import UserConfig # str(SudState.X) values (as sent in the 'State' message) that count as # "running" for enabling/disabling the Start/Pause/Stop toolbar actions. @@ -234,6 +236,7 @@ class Window(QtWidgets.QMainWindow, Ui_MainWindow): QtWidgets.QMainWindow.__init__(self) self.setWindowIcon(QtGui.QIcon('res/beer.png')) self.user_message_signal.connect(self.on_user_message_signal) + self.user_config = UserConfig() loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) @@ -569,16 +572,20 @@ class Window(QtWidgets.QMainWindow, Ui_MainWindow): # Pick the destination up front, on the GUI thread - the actual # write happens in on_sud_changed(), which runs off a worker thread # and must not touch Qt (e.g. open a file dialog) itself. - path, _ = QtWidgets.QFileDialog.getSaveFileName(self, "Save Sud", filter="JSON files (*.json)") + start_dir = self.user_config.get('sud_dir', '') + path, _ = QtWidgets.QFileDialog.getSaveFileName(self, "Save Sud", start_dir, filter="JSON files (*.json)") if not path: return + self.user_config.set('sud_dir', str(Path(path).parent)) self.sud_save_path = path self.msg_sud.send({'Save': True}) def on_action_sud_load(self): - path, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Load Sud", filter="JSON files (*.json)") + start_dir = self.user_config.get('sud_dir', '') + path, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Load Sud", start_dir, filter="JSON files (*.json)") if not path: return + self.user_config.set('sud_dir', str(Path(path).parent)) with open(path) as f: data = json.load(f) self.msg_sud.send({'Load': data}) diff --git a/client/user_config.py b/client/user_config.py new file mode 100644 index 0000000..1f0fb1e --- /dev/null +++ b/client/user_config.py @@ -0,0 +1,27 @@ +import json +from pathlib import Path + +DEFAULT_PATH = Path.home() / ".config" / "brewpi" / "gui.json" + + +class UserConfig: + """Small persisted key/value store for GUI preferences that should + survive across restarts (e.g. the last directory used for a file + dialog) - local user state, not version-controlled config.""" + + def __init__(self, path=DEFAULT_PATH): + self.path = path + self.data = {} + if self.path.exists(): + try: + self.data = json.loads(self.path.read_text()) + except (json.JSONDecodeError, OSError): + self.data = {} + + def get(self, key, default=None): + return self.data.get(key, default) + + def set(self, key, value): + self.data[key] = value + self.path.parent.mkdir(parents=True, exist_ok=True) + self.path.write_text(json.dumps(self.data, indent='\t'))