diff --git a/filmatyk/gui.py b/filmatyk/gui.py index b6b442e..959ef2a 100644 --- a/filmatyk/gui.py +++ b/filmatyk/gui.py @@ -145,8 +145,8 @@ def __init__(self, debugMode=False, isOnLinux=False): # load the savefile self.dataManager = DataManager(self.getFilename(), VERSION) userdata = self.dataManager.load() - # create the options manager - self.options = Options(userdata.options_json) + # initialize the options manager + Options.init(userdata.options_json) # construct the window: first the notebook for tabbed view self.notebook = ttk.Notebook(root) self.notebook.grid(row=0, column=0, padx=5, pady=5, sticky=tk.NW) @@ -256,7 +256,7 @@ def saveUserData(self): if not ( any([db.isDirty for db in self.databases]) or any([ps.isDirty for ps in self.presenters]) or - self.options.isDirty + Options.isDirty ): return # construct the UserData object @@ -268,7 +268,7 @@ def saveUserData(self): series_data=self.databases[1].storeToString(), games_conf=self.presenters[2].storeToString(), games_data=self.databases[2].storeToString(), - options_json=self.options.storeToString(), + options_json=Options.storeToString(), ) # request the manager to save it self.dataManager.save(serialized_data) diff --git a/filmatyk/options.py b/filmatyk/options.py index 6182236..7ca72c7 100644 --- a/filmatyk/options.py +++ b/filmatyk/options.py @@ -1,3 +1,21 @@ +"""Options is a globally accessible class holding all program options. + +The only exported object is a singleton instance of the Options class. Usage: + from options import Options +The instance has to be initialized (by passing a JSON string with serialized +initial values) or at least confirmed on assuming default values: + Options.init(json_string) +After that - and ONLY after that - it can be used in two ways. +Access to an option value: + Options.get('option_name') +Direct access to the underlying TkVar: + Options.var('option_name') + +This gives a convenient access to options from wherever in the program, +assuming the actual call to get or var happens AFTER the initialization of the +instance. +""" + import json import os @@ -5,21 +23,25 @@ from tkinter import ttk -class Options(): +class _Options(): """Stores program options as named Tk variables, allowing easy serialization. Options wraps around a simple dict of Tk vars, which enables the following: * easy access to option values (using get), - * simple binding of option variables to Tk widgets (using variable), + * simple binding of option variables to Tk widgets (using var), * serialization and deserialization to JSON (using storeToString). Defining a new option is done simply by adding it to the prototypes list. """ option_prototypes = [ ] - def __init__(self, json_string:str='{}'): + def __init__(self): self.variables = {} self.isDirty = False + self.isInit = False + + def init(self, json_string:str='{}'): + """Restore the JSON-serialized values.""" saved_values = json.loads(json_string) for name, vtype, default in self.option_prototypes: variable = vtype() @@ -27,6 +49,7 @@ def __init__(self, json_string:str='{}'): variable.set(value) variable.trace('w', self.__touched_callback) self.variables[name] = variable + self.isInit = True def storeToString(self): """Serialize the options to a JSON string.""" @@ -36,12 +59,19 @@ def storeToString(self): def get(self, name): """Get the value of a named option.""" + if not self.isInit: + raise AttributeError return self.variables[name].get() - def variable(self, name): + def var(self, name): """Get Tk variable object of a named option.""" + if not self.isInit: + raise AttributeError return self.variables[name] def __touched_callback(self, *args): """Set the dirty flag whenever an option changes.""" self.isDirty = True + + +Options = _Options()