Added delete button and warnings to GUI. Also some stability fixes.

This commit is contained in:
Patrick Marsee 2023-02-02 22:44:08 -05:00
parent 1dfe472a57
commit 86f6cc2659
2 changed files with 74 additions and 23 deletions

View file

@ -59,16 +59,37 @@ Valid commands are:
class Config: class Config:
defaults = {"mods_dir": MODS_DIR,
"seven_dir": "",
"warn_load": True,
"warn_save": True,
"warn_delete": True}
def __init__(self, **kwargs): def __init__(self, **kwargs):
if "mods_dir" in kwargs: self.settings = Config.defaults.copy()
self.mods_dir = kwargs["mods_dir"] for key in kwargs:
else: self.set_val(key, kwargs[key])
self.mods_dir = MODS_DIR
if "seven_dir" in kwargs: def __getattr__(self, name: str):
self.seven_dir = kwargs["seven_dir"] if name in self.settings:
return self.settings[name]
else: else:
self.seven_dir = get_seven_days_install_path() raise AttributeError(f"Config has no attribute named '{name}'.")
def set_val(self, name: str, val: str):
if name in ("warn_load", "warn_save", "warn_delete"):
# boolean
if val.casefold() in ("on", "true", "yes", "y"):
self.settings[name] = True
elif val.casefold() in ("off", "false", "no", "n"):
self.settings[name] = False
else:
raise ValueError(f"Input cannot be interpreted as boolean: '{val}'")
elif name in Config.defaults:
# siletly remove newlines, replace with spaces
# This is to prevent weird things.
self.settings[name] = val.replace("\n", " ")
else:
raise ValueError(f"No configuration setting: '{name}'")
class ModProfiles: class ModProfiles:
@ -203,7 +224,7 @@ def prompt_configuration_cli():
def save_config(cfg: Config) -> bool: def save_config(cfg: Config) -> bool:
try: try:
with open(CONFIG_FILE, 'w') as config_file: with open(CONFIG_FILE, 'w') as config_file:
config_file.write(f"mods_dir={cfg.mods_dir}\nseven_dir={cfg.seven_dir}\n") config_file.write("\n".join([f"{key}={cfg.settings[key]}" for key in cfg.settings]) + "\n")
return True return True
except RuntimeError: except RuntimeError:
return False return False
@ -345,6 +366,9 @@ def command_toggle(args: list, cfg: Config, profiles: ModProfiles):
def command_save(args: list, cfg: Config, profiles: ModProfiles): def command_save(args: list, cfg: Config, profiles: ModProfiles):
if len(args) > 2: if len(args) > 2:
for prof in args[2:]: for prof in args[2:]:
if len(prof) == 0 or prof.isspace():
raise seven_mods.SevenModsError("Profile must have a name.")
if not cfg.warn_save or prof not in profiles.profiles or input("Overwrite? y/N").casefold() == "y":
profiles.profiles[prof] = get_loaded_mods(cfg) profiles.profiles[prof] = get_loaded_mods(cfg)
profiles.save_mod_profiles() profiles.save_mod_profiles()
else: else:
@ -352,6 +376,7 @@ def command_save(args: list, cfg: Config, profiles: ModProfiles):
def command_load(args: list, cfg: Config, profiles: ModProfiles): def command_load(args: list, cfg: Config, profiles: ModProfiles):
if len(args) == 3 and args[2] in profiles.profiles: if len(args) == 3 and args[2] in profiles.profiles:
if not cfg.warn_load or input("Load? y/N").casefold() == "y":
command_disable(args[:2] + ["*"], cfg, profiles) command_disable(args[:2] + ["*"], cfg, profiles)
command_enable(args[:2] + profiles.profiles[args[2]], cfg, profiles) command_enable(args[:2] + profiles.profiles[args[2]], cfg, profiles)
else: else:
@ -360,7 +385,7 @@ def command_load(args: list, cfg: Config, profiles: ModProfiles):
def command_delete(args: list, cfg: Config, profiles: ModProfiles): def command_delete(args: list, cfg: Config, profiles: ModProfiles):
if len(args) > 2: if len(args) > 2:
for prof in args[2:]: for prof in args[2:]:
if prof in profiles.profiles: if prof in profiles.profiles and (not cfg.warn_delete or input("Delete? y/N").casefold() == "y"):
del profiles.profiles[prof] del profiles.profiles[prof]
profiles.save_mod_profiles() profiles.save_mod_profiles()
else: else:
@ -369,7 +394,14 @@ def command_delete(args: list, cfg: Config, profiles: ModProfiles):
print(f"Usage: {args[0]} {args[1]} <profile-name>") print(f"Usage: {args[0]} {args[1]} <profile-name>")
def command_configure(args: list, cfg: Config, profiles: ModProfiles): def command_configure(args: list, cfg: Config, profiles: ModProfiles):
if len(args) == 2:
prompt_configuration_cli() prompt_configuration_cli()
elif len(args) == 4:
if args[2] in Config.defaults:
cfg.set_val(args[2], args[3])
save_config(cfg)
else:
print(f"Usage: {args[0]} {args[1]} [name value]")
def command_help(args: list, cfg: Config, profiles: ModProfiles): def command_help(args: list, cfg: Config, profiles: ModProfiles):
print(HELP_TEXT) print(HELP_TEXT)

View file

@ -69,6 +69,10 @@ class AppFrame(ttk.Frame):
text = "Save", text = "Save",
command = self.command_save_button) command = self.command_save_button)
self.profile_save_btn.grid(column = 3, row = 0) self.profile_save_btn.grid(column = 3, row = 0)
self.profile_delete_btn = ttk.Button(self,
text = "Delete",
command = self.command_delete_button)
self.profile_delete_btn.grid(column = 4, row = 0)
self.mod_list = ttk.Treeview(self, self.mod_list = ttk.Treeview(self,
columns = ("name", "version", "author", "enabled"), columns = ("name", "version", "author", "enabled"),
height = 20, height = 20,
@ -81,7 +85,7 @@ class AppFrame(ttk.Frame):
self.mod_list.tag_configure("ENABLED", foreground = "green") self.mod_list.tag_configure("ENABLED", foreground = "green")
self.mod_list.tag_bind("DISABLED", '<<TreeviewSelect>>', lambda e: self.command_enable(self.mod_list.selection()[0])) self.mod_list.tag_bind("DISABLED", '<<TreeviewSelect>>', lambda e: self.command_enable(self.mod_list.selection()[0]))
self.mod_list.tag_bind("ENABLED", '<<TreeviewSelect>>', lambda e: self.command_disable(self.mod_list.selection()[0])) self.mod_list.tag_bind("ENABLED", '<<TreeviewSelect>>', lambda e: self.command_disable(self.mod_list.selection()[0]))
self.mod_list.grid(column = 0, row = 1, columnspan = 4, sticky = (N, E, S, W)) self.mod_list.grid(column = 0, row = 1, columnspan = 5, sticky = (N, E, S, W))
def prompt_configuration_window(self): def prompt_configuration_window(self):
SEVEN_DIR = "" SEVEN_DIR = ""
@ -157,7 +161,7 @@ class AppFrame(ttk.Frame):
enabled_text = "DISABLED" enabled_text = "DISABLED"
if mod in loaded_mods: if mod in loaded_mods:
enabled_text = "ENABLED" enabled_text = "ENABLED"
values = *self.get_mod_data(mod), enabled_text values = *seven_mods.get_mod_data(mod, self.cfg), enabled_text
self.mod_list.insert("", "end", mod, text = mod, values = values, tags = (enabled_text)) self.mod_list.insert("", "end", mod, text = mod, values = values, tags = (enabled_text))
def refresh_profile_list(self): def refresh_profile_list(self):
@ -184,6 +188,7 @@ class AppFrame(ttk.Frame):
prof = self.profile_var.get() prof = self.profile_var.get()
if prof in self.profiles.profiles: if prof in self.profiles.profiles:
try: try:
if not self.cfg.warn_load or messagebox.askokcancel(message = f'Are you sure you want to load profile"{prof}"?'):
seven_mods.command_disable(["", "", "*"], self.cfg, self.profiles) seven_mods.command_disable(["", "", "*"], self.cfg, self.profiles)
seven_mods.command_enable(["", ""] + self.profiles.profiles[prof], self.cfg, self.profiles) seven_mods.command_enable(["", ""] + self.profiles.profiles[prof], self.cfg, self.profiles)
self.refresh_mod_list() self.refresh_mod_list()
@ -194,14 +199,28 @@ class AppFrame(ttk.Frame):
def command_save_button(self): def command_save_button(self):
prof = self.profile_var.get() prof = self.profile_var.get()
print(f"prof={prof}")
try: try:
if len(prof) == 0 or prof.isspace():
raise seven_mods.SevenModsError("Profile must have a name.")
if not self.cfg.warn_save or prof not in self.profiles.profiles or messagebox.askokcancel(message = f'Are you sure you want to overwrite profile"{prof}"?'):
self.profiles.profiles[prof] = seven_mods.get_loaded_mods(self.cfg) self.profiles.profiles[prof] = seven_mods.get_loaded_mods(self.cfg)
self.profiles.save_mod_profiles() self.profiles.save_mod_profiles()
self.refresh_profile_list() self.refresh_profile_list()
except seven_mods.SevenModsError as e: except seven_mods.SevenModsError as e:
messagebox.showerror(message = str(e)) messagebox.showerror(message = str(e))
def command_delete_button(self):
prof = self.profile_var.get()
try:
if prof in self.profiles.profiles:
if not self.cfg.warn_delete or messagebox.askokcancel(message = f'Are you sure you want to delete profile"{prof}"?'):
del self.profiles.profiles[prof]
self.profiles.save_mod_profiles()
else:
raise seven_mods.SevenModsError(f"Cannot delete non-existant profile: {prof}")
except seven_mods.SevenModsError as e:
messagebox.showerror(message = str(e))
def main(args): def main(args):
root = Tk() root = Tk()
root.title("Seven Mods") root.title("Seven Mods")