import tkinter from pathlib import Path from tkinter import ttk from tkinter import filedialog from tkinter import messagebox from source.translation import translate as _ class Window(tkinter.Toplevel): """ A window that let the user select MyStuff pack for a MKWF patch """ def __init__(self): super().__init__() self.root = self.master.root self.title(_("CONFIGURE_MYSTUFF_PATCH")) self.resizable(False, False) self.grab_set() # the others window will be disabled, keeping only this one activated self.disabled_text: str = _("<", "DISABLED", ">") self.root.options["mystuff_pack_selected"] = self.root.options["mystuff_pack_selected"] self.frame_profile = ttk.Frame(self) self.frame_profile.grid(row=1, column=1, sticky="NEWS") self.combobox_profile = ttk.Combobox(self.frame_profile, justify=tkinter.CENTER) self.combobox_profile.grid(row=1, column=1, sticky="NEWS") self.combobox_profile.bind("<>", self.select_profile) self.button_new_profile = ttk.Button( self.frame_profile, text=_("NEW_PROFILE"), command=self.new_profile ) self.button_new_profile.grid(row=1, column=2, sticky="NEWS") self.button_delete_profile = ttk.Button( self.frame_profile, text=_("DELETE_PROFILE"), command=self.delete_profile ) self.button_delete_profile.grid(row=1, column=3, sticky="NEWS") self.frame_mystuff_paths = ttk.Frame(self) self.frame_mystuff_paths.grid(row=2, column=1, sticky="NEWS") self.frame_mystuff_paths.grid_columnconfigure(1, weight=1) self.listbox_mystuff_paths = tkinter.Listbox(self.frame_mystuff_paths) self.listbox_mystuff_paths.grid(row=1, column=1, sticky="NEWS") self.scrollbar_mystuff_paths = ttk.Scrollbar( self.frame_mystuff_paths, command=self.listbox_mystuff_paths.yview ) self.scrollbar_mystuff_paths.grid(row=1, column=2, sticky="NS") self.listbox_mystuff_paths.configure(yscrollcommand=self.scrollbar_mystuff_paths.set) self.frame_mystuff_paths_action = ttk.Frame(self) self.frame_mystuff_paths_action.grid(row=3, column=1, sticky="NEWS") self.button_add_mystuff_path = ttk.Button( self.frame_mystuff_paths_action, text=_("ADD_MYSTUFF"), command=self.add_mystuff_path ) self.button_add_mystuff_path.grid(row=1, column=1) self.button_remove_mystuff_path = ttk.Button( self.frame_mystuff_paths_action, text=_("REMOVE_MYSTUFF"), command=self.remove_mystuff_path ) self.button_remove_mystuff_path.grid(row=1, column=2) self.refresh_profiles() self.select_profile() def refresh_profiles(self) -> None: """ Refresh all the profile """ combobox_values = [self.disabled_text, *self.root.options["mystuff_packs"]] self.combobox_profile.configure(values=combobox_values) self.combobox_profile.current(combobox_values.index( self.root.options["mystuff_pack_selected"] if self.root.options["mystuff_pack_selected"] in self.root.options["mystuff_packs"] else self.disabled_text )) def select_profile(self, event: tkinter.Event = None, profile_name: str = None) -> None: """ Select another profile """ profile_name = self.combobox_profile.get() if profile_name is None else profile_name if not profile_name in self.root.options["mystuff_packs"]: profile_name = self.disabled_text self.combobox_profile.set(profile_name) self.root.options["mystuff_pack_selected"] = profile_name self.listbox_mystuff_paths.delete(0, tkinter.END) is_disabled: bool = (profile_name == self.disabled_text) for children in self.frame_mystuff_paths_action.children.values(): children.configure(state=tkinter.DISABLED if is_disabled else tkinter.NORMAL) if is_disabled: return profile_data = self.root.options["mystuff_packs"][profile_name] for path in profile_data["paths"]: self.listbox_mystuff_paths.insert(tkinter.END, path) def new_profile(self) -> None: """ Save the new profile """ profile_name: str = self.combobox_profile.get() if profile_name in self.root.options["mystuff_packs"]: messagebox.showerror(_("ERROR"), _("MYSTUFF_PROFILE_ALREADY_EXIST")) return for banned_char in "<>": if banned_char in profile_name: messagebox.showerror(_("ERROR"), _("MYSTUFF_PROFILE_FORBIDDEN_NAME")) return self.root.options["mystuff_packs"][profile_name] = {"paths": []} self.refresh_profiles() self.select_profile(profile_name=profile_name) def delete_profile(self) -> None: """ Delete the currently selected profile """ self.root.options["mystuff_packs"].pop(self.root.options["mystuff_pack_selected"]) self.refresh_profiles() self.select_profile() def add_mystuff_path(self) -> None: """ Add a new path to the currently selected MyStuff profile """ if (mystuff_path := filedialog.askdirectory(title=_("SELECT_MYSTUFF"), mustexist=True)) is None: return mystuff_path = Path(mystuff_path) self.root.options["mystuff_packs"][self.root.options["mystuff_pack_selected"]]["paths"].append( str(mystuff_path.resolve()) ) self.select_profile() def remove_mystuff_path(self) -> None: """ Remove the selected MyStuff path from the profile """ selections = self.listbox_mystuff_paths.curselection() if not selections: return for selection in selections: self.root.options["mystuff_packs"][self.root.options["mystuff_pack_selected"]]["paths"].pop(selection) self.select_profile()