def __init__(self, parent, description, scriptButtonName, optionsCallback, scriptCallback, *args, **kwargs): # Initialize Superclass title = kwargs.get('title') or scriptButtonName relief = kwargs.get('relief') ttk.Labelframe.__init__(self, parent, text=title, relief=relief) # Add Description label desc_label = Text(self, wrap='word', font='TkTextFont', height=kwargs.get('height') or 4) desc_label.insert("1.0", description) desc_label['state'] = 'disabled' desc_label.grid(row=0, column=0, sticky=(N, S), padx=10, pady=5) # Add Settings button settings_button = ttk.Button(self, text='Settings', command=optionsCallback) bind_button(settings_button) settings_button.grid(row=1, column=0, sticky=(E, W), padx=10, pady=5) # Add Run Script button script_button = ttk.Button(self, text=scriptButtonName, command=scriptCallback) bind_button(script_button) script_button.grid(row=2, column=0, sticky=(E, W), padx=10, pady=5) # Make resizeable self.columnconfigure(0, weight='1') for i in range(3): self.rowconfigure(i, weight='1')
def __init__(self, parent, *args, **kwargs): self.title = kwargs.get("title") or "Select Folder" relief = kwargs.get("relief") or "solid" self.path = kwargs.get("path") or "No Path Specified" ttk.Labelframe.__init__(self, parent, relief=relief, text=self.title) # Textbox that contains the path self.path_textbox = Text(self, width=40, height=1, wrap="none", font='TkDefaultFont') self.path_textbox.insert("1.0", self.path) self.path_textbox["state"] = "disabled" self.path_textbox.grid(column=0, row=0, padx=10, pady=5, sticky=(E, W)) # Button that prompts user for a new path path_button = ttk.Button(self, text="Choose Folder", command=self.choose_folder) path_button.grid(column=1, row=0, padx=10, pady=5, sticky=(E, W)) bind_button(path_button) # Allow this to be resizeable self.rowconfigure(0, weight='1') self.columnconfigure(0, weight="1", minsize=200) self.columnconfigure(1, weight="0", minsize=30)
def __init__(self, parent, *args, **kwargs): ttk.Frame.__init__(self, parent, *args, **kwargs) # Parse move_chartz options self.options = parse_options("move_chartz_options.json") # Move chartz selection self.new_chartz = Multiselect(self, input=self.options['chartz'], title='Chartz to Move', key1='name', key2='to', header='Chart Name', addText='Add Chart', orient='vertical', height=10, archive=True) self.new_chartz.grid(row=0, column=0, columnspan=2, sticky=(N, E, S, W), padx=20, pady=10) # Run script/Close buttons close_button = ttk.Button(self, text='Close', command=lambda: parent.master.destroy()) bind_button(close_button) run_script_button = ttk.Button(self, text='Move Chartz', command=self.run_script) bind_button(run_script_button) close_button.grid(row=1, column=0, sticky=(S, W), padx=20, pady=10) run_script_button.grid(row=1, column=1, sticky=(S, E), padx=20, pady=10) # Allow resizing self.rowconfigure(1, weight="1") self.columnconfigure(1, weight="1")
def __init__(self, parent, options, pathfn, *args, **kwargs): # Initialize superclass title = kwargs.get("title") or "Filler Ordering" relief = kwargs.get("relief") or "solid" self.pathfn = pathfn ttk.Labelframe.__init__(self, parent, text=title, relief=relief) # Set path and current list of filler self.path = options['filler']['directory'] self.list = options['filler']['order'] # Create main treeview treeview_frame = ttk.Frame(self) self.tree = ttk.Treeview(treeview_frame, height=kwargs.get("height") or 8) self.tree.heading('#0', text=kwargs.get("heading") or "Filler Order") self.tree.column('#0', stretch=YES) self.tree.bind('<<TreeviewSelect>>', lambda e: self.tree_selection_changed()) self.bind('<Button-1>', self.clear_selection) self.tree.grid(row=0, column=0, stick=(N, E, S, W)) scrolly = ttk.Scrollbar(treeview_frame, orient='vertical', command=self.tree.yview) self.tree['yscrollcommand'] = scrolly.set scrolly.grid(row=0, column=1, sticky=(N, S, E, W)) treeview_frame.columnconfigure(0, weight='1') treeview_frame.rowconfigure(0, weight='1') treeview_frame.grid(row=0, column=0, padx=10, pady=5, sticky=(N, E, S, W)) self.rowconfigure(0, weight='1') for i in range(2): self.columnconfigure(0, weight='1') # Create up, down, and refresh buttons button_frame = ttk.Frame(self) self.up = ttk.Button(button_frame, text='Move Up', command=self.move_up) self.up.state(["disabled"]) bind_button(self.up) self.down = ttk.Button(button_frame, text='Move Down', command=self.move_down) self.down.state(["disabled"]) bind_button(self.down) self.refresh = ttk.Button(button_frame, text='Refresh', command=self.refresh) bind_button(self.refresh) self.up.grid(row=0, column=0, padx=10, pady=5, sticky=S) self.refresh.grid(row=1, column=0, padx=10, pady=5) self.down.grid(row=2, column=0, padx=10, pady=5, sticky=N) for i in range(3): button_frame.rowconfigure(i, weight='1') button_frame.columnconfigure(0, weight='1') button_frame.grid(row=0, column=1, sticky=(N, E, S, W), padx=10, pady=5) # Initialize tree self.add_list_to_tree(options['filler']['order'])
def __init__(self, parent, options, callback, *args, **kwargs): Toplevel.__init__(self, parent) self.options: Dict = options self.callback = callback self.protocol("WM_DELETE_WINDOW", self.destroy_self) # Set title self.title("Folder Creator Options") self.lift() self.focus_force() self.minsize(600, 525) # Create mainframe mainframe = ttk.Frame(self) # Create notebook n = ttk.Notebook(mainframe, width=750, height=500, padding=5) # Add each frame to the notebook self.download = DownloadOptions(n, self.options) self.verify = ValidateOptions(n, self.options) self.pages = PagesOptions(n, self.options) self.filler = FillerOptions(n, self.options) self.toc = TOCOptions(n, self.options) self.chartz = ChartzOptions(n, self.options) self.dollies = DollieOptions(n, self.options) self.rules = RulesOptions(n, self.options) n.add(self.download, text='Download', underline=0) n.add(self.verify, text='Review', underline=0) n.add(self.chartz, text='Chartz', underline=0) n.add(self.dollies, text='Dollies', underline=2) n.add(self.filler, text='Filler', underline=0) n.add(self.toc, text='Table of Contents', underline=0) n.add(self.pages, text='Pages', underline=0) n.add(self.rules, text='Custom Rules', underline=1) n.select(kwargs.get('tab') or 0) n.enable_traversal() n.grid(row=0, column=0, columnspan=2, sticky=(N, E, S, W)) # Add save and cancel buttons cancel_button = ttk.Button(mainframe, text='Cancel', command=self.destroy_self) bind_button(cancel_button) save_button = ttk.Button(mainframe, text='Save Settings', command=self.save_options) bind_button(save_button) cancel_button.grid(row=1, column=0, sticky=(S, W), padx=25, pady=15) save_button.grid(row=1, column=1, sticky=(S, E), padx=25, pady=15) # Allow resizing mainframe.columnconfigure(0, weight='1') mainframe.rowconfigure(0, weight='1') mainframe.grid(row=0, column=0, sticky=(N, E, S, W)) self.columnconfigure(0, weight='1') self.rowconfigure(0, weight='1')
def __init__(self, parent, *args, **kwargs): ttk.Frame.__init__(self, parent, *args, **kwargs) # Parse redvest options self.options = parse_options("redvest_options.json") # Parent folder selection self.parent_entry = LabledEntry( self, title='Redvest Subdirectory Folder', label='Enter Subdirectory Folder Name', defaultEntry=self.options['parent-name'], info='Directory Structure: Redvest -> Subdirectory -> Session') self.parent_entry.grid(row=0, column=0, columnspan=2, sticky=(N, S, E, W), padx=20, pady=10) # Folder name selection self.folder_entry = LabledEntry( self, title='Create New Redvest Session Folder', label='New Folder Name', defaultEntry=self.options['folder-name']) self.folder_entry.grid(row=1, column=0, columnspan=2, sticky=(N, E, S, W), padx=20, pady=10) # Select Chartz multiselect self.select_chartz = Multiselect(self, input=self.options['chartz'], title='Select Chartz for Redvest', header='Chart Name', addText='Add Chart', height=7) self.select_chartz.grid(row=2, column=0, columnspan=2, sticky=(N, E, S, W), padx=20, pady=10) # Individual Sections sep_sec_frame = ttk.LabelFrame(self, text='Separated Section Parts') self.sep_sec = BooleanVar() self.sep_sec.set(self.options['individual-sections']) sep_sec_checkbox = ttk.Checkbutton( sep_sec_frame, text='Include Separated Section Parts', variable=self.sep_sec) sep_sec_checkbox.grid(row=0, column=0, padx=10, pady=5) sep_sec_frame.rowconfigure(0, weight='1') sep_sec_frame.columnconfigure(0, weight='1') sep_sec_frame.grid(row=3, column=0, columnspan=2, sticky=(N, E, S, W), padx=20, pady=10) # Run script/Close buttons close_button = ttk.Button(self, text='Close', command=lambda: parent.master.destroy()) bind_button(close_button) run_script_button = ttk.Button(self, text='Create Redvest Folder', command=self.run_script) bind_button(run_script_button) close_button.grid(row=4, column=0, sticky=(S, W), padx=20, pady=10) run_script_button.grid(row=4, column=1, sticky=(S, E), padx=20, pady=10) # Make resizeable for i in range(5): self.rowconfigure(i, weight='1') self.columnconfigure(1, weight='1')
def __init__(self, parent, *args, **kwargs): ttk.Frame.__init__(self, parent, *args, **kwargs) # Parse upload files options self.options = parse_options("upload_options.json") # Directory selection self.select_directory = SelectDirectory(self, path=self.options["resources-directory"], title='Select Resources Folder') self.select_directory.grid(row=0, column=0, columnspan=2, sticky=(N, E, S, W), padx=20, pady=10) # Mode selection + title match checkbox self.mode = IntVar() self.mode.set(self.options["mode"]) self.title_match = BooleanVar() self.title_match.set(self.options["require-titles-match"]) mode_frame = ttk.Labelframe(self, text='Select Mode') update = ttk.Radiobutton(mode_frame, text='Update Files', variable=self.mode, value=0) add = ttk.Radiobutton(mode_frame, text='Add Files', variable=self.mode, value=1) update_and_add = ttk.Radiobutton(mode_frame, text='Add and Update', variable=self.mode, value=2) title_match_checkbox = ttk.Checkbutton(mode_frame, text='Enforce Matching Titles', variable=self.title_match) mode_frame.grid(row=1, column=0, columnspan=2, sticky=(N, E, S, W), padx=20, pady=10) update.grid(row=0, column=0) add.grid(row=0, column=1) update_and_add.grid(row=0, column=2) title_match_checkbox.grid(row=0, column=3, padx=20) # New chartz selection self.new_chartz = Multiselect(self, input=self.options['new-chartz'], title='Create New Chartz', key1='name', key2='to', header='Chart Name', addText='Add New Chart', height=3, archive=True) self.new_chartz.grid(row=2, column=0, columnspan=2, sticky=(N, E, S, W), padx=20, pady=10) # File extensions selection self.file_extensions = Multiselect(self, input=self.options["supported-file-types"], title='Supported File Types', header='File Type', addText='Add File Type', warn=True, height=6) self.file_extensions.grid(row=3, column=0, columnspan=2, sticky=(N, E, S, W), padx=20, pady=10) # Run script/Close buttons close_button = ttk.Button(self, text='Close', command=lambda: parent.master.destroy()) bind_button(close_button) run_script_button = ttk.Button(self, text='Upload Files', command=self.run_script) bind_button(run_script_button) close_button.grid(row=4, column=0, sticky=(S, W), padx=20, pady=10) run_script_button.grid(row=4, column=1, sticky=(S, E), padx=20, pady=10) # Allow resizing for row in range(5): self.rowconfigure(row, weight="1") self.columnconfigure(0, weight="1") for col in range(4): mode_frame.columnconfigure(col, weight="1", minsize="80")
def __init__(self, parent, script, callback, *args, **kwargs): # Set variables self.script = script self.callback = callback self.safe_to_abort = kwargs.get('safe') or False self.destroy_after_callback = False self.active = True self.name = kwargs.get("name") or "Script" title = kwargs.get("title") or "Script Progress" self.old_stdout = sys.stdout # Initialize window Toplevel.__init__(self, parent) self.lift() self.focus_force() self.title(title) self.resizable(FALSE, FALSE) self.protocol("WM_DELETE_WINDOW", self.destroy_self) # Create mainframe mainframe = ttk.Frame(self) self.rowconfigure(0, weight='1') self.columnconfigure(0, weight='1') # Create label self.label = ttk.Label(mainframe, text=f'{self.name} script in progress...') self.label.grid(row=0, column=0, sticky=(N, S, E, W), padx=20, pady=10) # Create progressbar self.prog_bar = ttk.Progressbar(mainframe, orient='horizontal', mode='indeterminate', length=200) self.prog_bar.start(25) self.prog_bar.grid(row=0, column=1, sticky=(N, E, W), padx=20, pady=10) # Create text console area within dummy frame dummy_frame = ttk.Frame(mainframe) self.console = Text(dummy_frame, width=70, height=15, wrap='none', font='TkFixedFont') self.console["state"] = "disabled" self.console.bind("<1>", lambda event: self.console.focus_set()) self.console.grid(row=0, column=0, sticky=(N, E, S, W)) self.console.tag_configure('warning', foreground='Orange') self.console.tag_configure('error', foreground='Red') self.console.tag_configure('success', foreground='Green') self.console.tag_config('normal', foreground='Black') scrollx = ttk.Scrollbar(dummy_frame, orient='horizontal', command=self.console.xview) scrolly = ttk.Scrollbar(dummy_frame, orient='vertical', command=self.console.yview) self.console['xscrollcommand'] = scrollx.set self.console['yscrollcommand'] = scrolly.set scrollx.grid(row=1, column=0, sticky=(E, W, N)) scrolly.grid(row=0, column=1, sticky=(N, S, W)) dummy_frame.grid(row=2, column=0, columnspan=2, padx=20, pady=2, sticky=(N, S, E, W)) dummy_frame.rowconfigure(0, weight='1') dummy_frame.columnconfigure(0, weight='1') # Map stdout to this console class RedirectStdout(object): def __init__(self, text_area: Text): self.text_area = text_area def write(self, str): self.text_area['state'] = 'normal' self.text_area.insert("end", str, self.add_tags(str)) self.text_area.see("end") self.text_area['state'] = 'disabled' def add_tags(self, str): if 'WARNING' in str: return ('warning') elif 'ERROR' in str or 'Aborting' in str: return ('error') elif 'uccess' in str: return ('success') else: return ('none') sys.stdout = RedirectStdout(self.console) # Create abort/return button self.button_text = StringVar() self.main_button = ttk.Button(mainframe, textvariable=self.button_text, command=self.destroy_self) bind_button(self.main_button) self.main_button.grid(row=3, column=0, columnspan=2, sticky=S, padx=20, pady=10) # Set button text if not self.safe_to_abort: self.button_text.set(f'Unsafe to Abort {self.name} Script') self.main_button.state(['disabled']) else: self.button_text.set(f'Abort {self.name} Script') # Allow resizing mainframe.columnconfigure(0, weight="1") mainframe.columnconfigure(1, weight="1") mainframe.rowconfigure(0, weight="1") mainframe.rowconfigure(1, weight="1") mainframe.rowconfigure(2, weight="1") mainframe.grid(row=0, column=0, sticky=(N, E, S, W)) # Start thread def inner_callback(code): self.deactivate() self.callback(code) reset_stop_script() self.deiconify() if (self.destroy_after_callback): self.destroy() self.thread = spawn_thread(self.script, inner_callback, self.name)
def __init__(self, parent, *args, **kwargs): ttk.Frame.__init__(self, parent, *args, **kwargs) self.options = parse_options('parts.json') self.DELIMETERS = (":", "|") parts_frame = ttk.Labelframe(self, text='Configure Part Mappings') # Add info label info = ttk.Label( parts_frame, justify='center', text= f'Each line of text is a part alias configuration.\nThe part name is followed by "{self.DELIMETERS[0]}", and aliases are delimited by "{self.DELIMETERS[1]}".\nFor example, if you wish for files "All Right Now - Toobz" and\n"All Right Now - Tööbz" to be mapped to the same folder,\nyou would enter "Toobz{self.DELIMETERS[0]} Toobz {self.DELIMETERS[1]} Tööbz"' ) info.grid(row=0, column=0, padx=10, pady=5) # Add text input area dummy_frame = ttk.Frame(parts_frame) self.parts_text = CustomText(dummy_frame, width=70, height=15, wrap='none', font=('TkDefaultFont'), undo=True) self.parts_text.grid(row=0, column=0, sticky=(N, E, S, W)) self.parts_text.tag_configure('delimeter-0-good', font=('TkFixedFont'), foreground='green') self.parts_text.tag_configure('delimeter-0-bad', font=('TkFixedFont'), foreground='red') self.parts_text.tag_configure('delimeter-1-good', font=('TkFixedFont'), foreground='blue') self.parts_text.tag_configure('delimeter-1-bad', font=('TkFixedFont'), foreground='red') self.parts_text.bind('<<TextModified>>', self.tag_delimeters) scrollx = ttk.Scrollbar(dummy_frame, orient='horizontal', command=self.parts_text.xview) scrolly = ttk.Scrollbar(dummy_frame, orient='vertical', command=self.parts_text.yview) self.parts_text['xscrollcommand'] = scrollx.set self.parts_text['yscrollcommand'] = scrolly.set scrollx.grid(row=1, column=0, sticky=(E, W, N)) scrolly.grid(row=0, column=1, sticky=(N, S, W)) parts_frame.grid(row=0, column=0, columnspan=2, sticky=(N, E, S, W), padx=20, pady=10) dummy_frame.grid(row=1, column=0, sticky=(N, E, S, W), padx=10, pady=5) dummy_frame.rowconfigure(0, weight='1') dummy_frame.columnconfigure(0, weight='1') # Populate text self.populate_parts(self.options['parts']) # Make Text Area Resizeable parts_frame.columnconfigure(0, weight='1') parts_frame.rowconfigure(1, weight='1') # Add exclusion selection self.exclusions = Multiselect( self, input=self.options['exclude'], title='Parts to Exclude from Live Digital Library', header='Part Name', addText='Add Part', warn=True, height=5) self.exclusions.grid(row=1, column=0, columnspan=2, padx=20, pady=10, sticky=(N, E, S, W)) # Run script/Close buttons close_button = ttk.Button(self, text='Close', command=lambda: parent.master.destroy()) bind_button(close_button) run_script_button = ttk.Button(self, text='Remake Shortcuts', command=self.run_script) bind_button(run_script_button) close_button.grid(row=2, column=0, sticky=(S, W), padx=20, pady=10) run_script_button.grid(row=2, column=1, sticky=(S, E), padx=20, pady=10) # Allow resizing self.rowconfigure(0, weight="1") self.rowconfigure(1, weight="1") self.columnconfigure(1, weight="1")
def __init__(self, parent, input, *args, **kwargs): # Initialize superclass title = kwargs.get("title") or "Select Items" relief = kwargs.get("relief") or "solid" ttk.Labelframe.__init__(self, parent, text=title, relief=relief) # Initialize treeview list key1 = kwargs.get('key1') key2 = kwargs.get('key2') names = [] locs = [] if not key1 or not key2: names = input else: names = [item[key1] for item in input] locs = [item[key2] for item in input] left_col = kwargs.get("header") or "Item" self.right_col = ['Destination'] if key1 and key2 else [] # Define treeview treeview_frame = ttk.Frame(self) self.reverse = False self.tree = ttk.Treeview(treeview_frame, columns=self.right_col, height=kwargs.get("height") or 5) self.tree.heading('#0', text=left_col, command=lambda: self.tree_sort()) self.tree.column('#0', stretch=YES) if len(self.right_col) > 0: self.tree.heading('#1', text=self.right_col[0]) self.tree.column('#1', stretch=YES, width=80) self.tree.bind('<<TreeviewSelect>>', lambda e: self.tree_selection_changed()) self.tree.bind('<Control-a>', self.select_all) self.bind('<Button-1>', self.clear_selection) self.tree.grid(row=0, column=0, stick=(N, E, S, W)) scrolly = ttk.Scrollbar(treeview_frame, orient='vertical', command=self.tree.yview) self.tree['yscrollcommand'] = scrolly.set scrolly.grid(row=0, column=1, sticky=(N, S, E, W)) treeview_frame.columnconfigure(0, weight='1') treeview_frame.rowconfigure(0, weight='1') # New item entry self.entry_text = StringVar() entry = ttk.Entry(self, textvariable=self.entry_text) self.entry_text.trace_add('write', self.entry_changed) # Add item entry add_text = kwargs.get("addText") or 'Add Item' self.add_entry = ttk.Button(self, text=add_text, command=self.add_item_cmd) self.add_entry.state(["disabled"]) bind_button(self.add_entry) entry.bind("<Return>", lambda e: self.add_entry.invoke()) entry.bind("<KP_Enter>", lambda e: self.add_entry.invoke()) # Select destination radio buttons self.destination = None select_dest_frame = None if len(self.right_col) > 0: select_dest_frame = ttk.Frame(self) self.destination = IntVar() self.destination.set(0) current_chartz = ttk.Radiobutton(select_dest_frame, text='Current Chartz', variable=self.destination, value=0) old_chartz = ttk.Radiobutton(select_dest_frame, text='Old Chartz', variable=self.destination, value=1) future_chartz = ttk.Radiobutton(select_dest_frame, text='Future Chartz', variable=self.destination, value=2) current_chartz.grid(row=0, column=0, sticky=(N, S)) old_chartz.grid(row=0, column=1, sticky=(N, S)) future_chartz.grid(row=0, column=2, sticky=(N, S)) if kwargs.get("archive"): archive = ttk.Radiobutton(select_dest_frame, text='Archive', variable=self.destination, value=3) archive.grid(row=0, column=3, sticky=(N, S)) for i in range(4): select_dest_frame.columnconfigure(i, weight="1") # Delete selection/all buttons self.del_sel = ttk.Button(self, text='Delete Selection', command=self.delete_selection) self.del_sel.state(['disabled']) bind_button(self.del_sel) self.warn_before_deleting = kwargs.get('warn') self.del_all = ttk.Button(self, text='Delete All', command=self.delete_all) self.del_all.state(['disabled']) bind_button(self.del_all) # Add items to treeview for i in range(len(names)): loc = locs[i] if i < len(locs) else None self.insert_data(names[i], loc) self.tree_sort(False) # Grid the items/handle orientation if kwargs.get('orient') == 'vertical': sel_dest_enabled = select_dest_frame != None entry.grid(row=0, column=0, padx=10, pady=2, sticky=E) self.add_entry.grid(row=0, column=1, padx=2, pady=5, sticky=W) if sel_dest_enabled: select_dest_frame.grid(row=1, column=0, columnspan=2, sticky=N, padx=10, pady=5) treeview_frame.grid(row=1 + sel_dest_enabled, column=0, columnspan=2, padx=10, pady=5, sticky=(N, S, E, W)) self.del_sel.grid(row=2 + sel_dest_enabled, column=0, sticky=W, padx=10, pady=5) self.del_all.grid(row=2 + sel_dest_enabled, column=1, sticky=E, padx=10, pady=5) # Resize rows/columns self.columnconfigure(0, weight='1') self.columnconfigure(1, weight='1') for i in range(3 + sel_dest_enabled): self.rowconfigure(i, weight='1') else: treeview_frame.grid(row=0, column=0, rowspan=3, padx=10, pady=5, sticky=(N, E, S, W)) entry.grid(row=0, column=1, padx=10, pady=5, sticky=(W, E, S)) self.add_entry.grid(row=0, column=2, sticky=(E, W, S), padx=10, pady=5) if (select_dest_frame != None): select_dest_frame.grid(row=1, column=1, columnspan=2, sticky=(N, E, W), padx=10, pady=5) self.del_sel.grid(row=2, column=1, sticky=(N, E, W), padx=10, pady=5) self.del_all.grid(row=2, column=2, sticky=(N, E, W), padx=10, pady=5) # Resize rows, cols for i in range(3): self.rowconfigure(i, weight="1") self.columnconfigure(i, weight="1")
def __init__(self, parent, *args, **kwargs): ttk.Frame.__init__(self, parent, *args, **kwargs) # Parse folder creator options self.options = parse_options("folder_creator_options.json") # Target Directory selection self.select_directory = SelectDirectory(self, path=self.options["folder-dir"], title='Select Target Directory') self.select_directory.grid(row=0, column=0, columnspan=3, sticky=(N, E, S, W), padx=20, pady=10) # Folder Name Selection self.folder_name_entry = LabledEntry(self, title='Enter Output Folder Name', label='Output Name', defaultEntry=self.options['folder-name']) self.folder_name_entry.grid(row=1, column=0, sticky=(N, S, W, E), padx=20, pady=10) # Verbose Output Selection verbose_frame = ttk.LabelFrame(self, text='Console Logging') self.verbose = BooleanVar() self.verbose.set(self.options['verbose']) verbose_checkbox = ttk.Checkbutton(verbose_frame, text='Verbose Logging', variable=self.verbose) verbose_checkbox.grid(row=0, column=0, padx=10, pady=5) verbose_frame.rowconfigure(0, weight='1') verbose_frame.columnconfigure(0, weight='1') verbose_frame.grid(row=1, column=1, sticky=(N, E, S, W), padx=20, pady=10) # Workflows workflow_frame = ttk.Frame(self) # Download Files Workflow dl_workflow = FolderCreatorWorkflow(parent=workflow_frame, description="Downloads files from the Digial Library onto your local machine at the target directory specified above", scriptButtonName="Download Files", scriptCallback=self.runDownloadScript, optionsCallback=lambda: self.open_options(0)) dl_workflow.grid(row=0, column=0, sticky=(N, E, S, W), padx=0, pady=5) # Validate Folders Workflow validate_workflow = FolderCreatorWorkflow(parent=workflow_frame, description="Validates the folder structure at the target directory, and optionally outputs a sample table of contents", scriptButtonName='Validate Folder', scriptCallback=self.runValidateScript, optionsCallback=lambda: self.open_options(1)) validate_workflow.grid(row=0, column=1, sticky=(N, E, S, W), padx=20, pady=5) # Create Folders workflow create_folders = FolderCreatorWorkflow(parent=workflow_frame, description="Writes the folders to the Output folder in the target directory\n\nThis takes about 2-5 minutes", scriptButtonName='Generate Folders', scriptCallback=self.runFolderCreatorScript, optionsCallback=lambda: self.open_options(2)) create_folders.grid(row=0, column=2, sticky=(N, E, S, W), padx=0, pady=5) # Make Workflow Frame resizeable workflow_frame.grid(row=2, column=0, columnspan=3, sticky=(N, E, S, W), padx=20, pady=10) workflow_frame.rowconfigure(0, weight='1') for i in range(3): workflow_frame.columnconfigure(i, weight='1') # Run script/Close buttons close_button = ttk.Button(self, text='Close', command=lambda: parent.master.destroy()) bind_button(close_button) close_button.grid(row=3, column=0, sticky=(S, W), padx=20, pady=10) # Make resizeable for i in range(4): self.rowconfigure(i, weight='1') self.columnconfigure(1, weight='1')