def __init__(self, master): ConfigurationPage.__init__(self, master) self.columnconfigure(1, weight=1) self.add_checkbox( "shell.clear_for_new_process", tr("Clear Shell before starting new process (Run, Debug, Stop/Restart, ...)" ), 5, 0, columnspan=2, pady=(0, 10), ) self.add_checkbox( "shell.tty_mode", tr("Terminal emulation") + " (" + tr("supports basic ANSI-colors and styles") + ", \\a, \\r, \\b)", 10, 0, columnspan=2, pady=(0, 10), ) max_lines_var = get_workbench().get_variable("shell.max_lines") max_lines_label = ttk.Label( self, text=tr( tr("Maximum number of lines to keep.") + "\n" + tr("NB! Large values may cause poor performance!")), ) max_lines_label.grid(row=20, column=0, sticky=tk.W) max_lines_combo = ttk.Combobox( self, width=9, exportselection=False, textvariable=max_lines_var, state="readonly", values=[100, 500, 1000, 5000, 10000, 50000, 100000], ) max_lines_combo.grid(row=20, column=1, sticky=tk.W, padx=10) squeeze_var = get_workbench().get_variable("shell.squeeze_threshold") squeeze_label = ttk.Label( self, text=tr("Maximum length of line fragments before squeezing")) squeeze_label.grid(row=22, column=0, sticky="w") squeeze_combo = ttk.Combobox( self, width=9, exportselection=False, textvariable=squeeze_var, state="readonly", values=[500, 1000, 1500, 2000, 3000, 4000, 5000, 10000], ) squeeze_combo.grid(row=22, column=1, sticky=tk.W, padx=10, pady=10) self.add_checkbox( "shell.auto_inspect_values", tr("Open evaluated values in Object inspector"), 30, 0, columnspan=2, pady=(0, 10), )
def notify_missing_selection(self): messagebox.showerror( tr("Nothing selected"), tr("Select an item and try again!"), master=self )
def _init_fonts(self): self._original_editor_family = get_workbench().get_option( "view.editor_font_family") self._original_editor_size = get_workbench().get_option( "view.editor_font_size") self._original_io_family = get_workbench().get_option( "view.io_font_family") self._original_io_size = get_workbench().get_option( "view.io_font_size") self._editor_family_variable = create_string_var( self._original_editor_family, modification_listener=self._update_appearance) self._editor_size_variable = create_string_var( self._original_editor_size, modification_listener=self._update_appearance) self._io_family_variable = create_string_var( self._original_io_family, modification_listener=self._update_appearance) self._io_size_variable = create_string_var( self._original_io_size, modification_listener=self._update_appearance) ttk.Label(self, text=tr("Editor font")).grid(row=1, column=3, sticky="w", pady=(0, 5), padx=(25, 5)) editor_family_combo = ttk.Combobox( self, exportselection=False, state="readonly", height=15, textvariable=self._editor_family_variable, values=self._get_families_to_show(), ) editor_family_combo.grid(row=1, column=4, sticky="nwe", pady=(0, 5)) editor_size_combo = ttk.Combobox( self, width=4, exportselection=False, textvariable=self._editor_size_variable, state="readonly", height=15, values=[str(x) for x in range(3, 73)], ) editor_size_combo.grid(row=1, column=5, sticky="nwe", pady=(0, 5), padx=(5, 0)) ttk.Label(self, text=tr("IO font")).grid(row=2, column=3, sticky="w", pady=(0, 5), padx=(25, 5)) io_family_combo = ttk.Combobox( self, exportselection=False, state="readonly", height=15, textvariable=self._io_family_variable, values=self._get_families_to_show(), ) io_family_combo.grid(row=2, column=4, sticky="nwe", pady=(0, 5)) io_size_combo = ttk.Combobox( self, width=4, exportselection=False, textvariable=self._io_size_variable, state="readonly", height=15, values=[str(x) for x in range(3, 73)], ) io_size_combo.grid(row=2, column=5, sticky="nwe", pady=(0, 5), padx=(5, 0))
def perform_delete(self, paths, description): get_runner().send_command_and_wait( InlineCommand("delete", paths=paths, description=description), dialog_title=tr("Deleting"), )
def __init__(self, master, show_expand_buttons=True): self.show_expand_buttons = show_expand_buttons self._cached_child_data = {} self.path_to_highlight = None ttk.Frame.__init__(self, master, borderwidth=0, relief="flat") self.vert_scrollbar = ttk.Scrollbar( self, orient=tk.VERTICAL, style=scrollbar_style("Vertical") ) self.vert_scrollbar.grid(row=0, column=1, sticky=tk.NSEW, rowspan=3) tktextext.fixwordbreaks(tk._default_root) self.building_breadcrumbs = False self.init_header(row=0, column=0) spacer = ttk.Frame(self, height=1) spacer.grid(row=1, sticky="nsew") self.tree = ttk.Treeview( self, columns=["#0", "kind", "path", "name", "modified", "size"], displaycolumns=( # 4, # 5 ), yscrollcommand=self.vert_scrollbar.set, selectmode="extended", ) self.tree.grid(row=2, column=0, sticky=tk.NSEW) self.vert_scrollbar["command"] = self.tree.yview self.columnconfigure(0, weight=1) self.rowconfigure(2, weight=1) self.tree["show"] = "tree" self.tree.bind("<3>", self.on_secondary_click, True) if misc_utils.running_on_mac_os(): self.tree.bind("<2>", self.on_secondary_click, True) self.tree.bind("<Control-1>", self.on_secondary_click, True) self.tree.bind("<Double-Button-1>", self.on_double_click, True) self.tree.bind("<<TreeviewOpen>>", self.on_open_node) wb = get_workbench() self.folder_icon = wb.get_image("folder") self.python_file_icon = wb.get_image("python-icon") self.text_file_icon = wb.get_image("text-file") self.generic_file_icon = wb.get_image("generic-file") self.hard_drive_icon = wb.get_image("hard-drive") self.tree.column("#0", width=200, anchor=tk.W) self.tree.heading("#0", text=tr("Name"), anchor=tk.W) self.tree.column("modified", width=60, anchor=tk.W) self.tree.heading("modified", text=tr("Modified"), anchor=tk.W) self.tree.column("size", width=40, anchor=tk.E) self.tree.heading("size", text=tr("Size (bytes)"), anchor=tk.E) self.tree.column("kind", width=30, anchor=tk.W) # self.tree.heading("kind", text="Kind") # self.tree.column("path", width=300, anchor=tk.W) # self.tree.heading("path", text="path") # self.tree.column("name", width=60, anchor=tk.W) # self.tree.heading("name", text="name") # set-up root node self.tree.set(ROOT_NODE_ID, "kind", "root") self.menu = tk.Menu(self.tree, tearoff=False) self.current_focus = None
def load_plugin(): get_workbench().add_configuration_page("assistant", tr("Assistant"), AssistantConfigPage, 80)
def _create_toolbar(self): toolbar = ttk.Frame(self, style="ViewToolbar.TFrame") self.title_label = ttk.Label( toolbar, style="ViewToolbar.TLabel", text="" # borderwidth=1, # background=ui_utils.get_main_background() ) self.title_label.grid(row=0, column=3, sticky="nsew", pady=5, padx=5) toolbar.columnconfigure(3, weight=1) self.tabs = [] def create_tab(col, caption, page): if page == self.active_page: style = "Active.ViewTab.TLabel" else: style = "Inactive.ViewTab.TLabel" tab = ttk.Label(toolbar, text=caption, style=style) tab.grid(row=0, column=col, pady=5, padx=5, sticky="nsew") self.tabs.append(tab) page.tab = tab def on_click(event): if self.active_page == page: return else: if self.active_page is not None: self.active_page.grid_forget() self.active_page.tab.configure(style="Inactive.ViewTab.TLabel") self.active_page = page page.grid(row=1, column=0, sticky="nsew", padx=0) tab.configure(style="Active.ViewTab.TLabel") if self.active_page == self.attributes_page and ( self.object_info is None or not self.object_info.get("attributes") ): self.request_object_info() tab.bind("<1>", on_click) # create_tab(1, "Overview", self.general_page) create_tab(5, "Data", self.content_page) create_tab(6, "Atts", self.attributes_page) def create_navigation_link(col, image_filename, action, tooltip, padx=0): button = ttk.Button( toolbar, # command=handler, image=get_workbench().get_image(image_filename), style="ViewToolbar.Toolbutton", # TODO: does this cause problems in some Macs? state=tk.NORMAL, ) ui_utils.create_tooltip(button, tooltip) button.grid(row=0, column=col, sticky=tk.NE, padx=padx, pady=4) button.bind("<Button-1>", action) return button def configure(event): if event.width > 20: self.title_label.configure(wraplength=event.width - 10) self.title_label.bind("<Configure>", configure, True) self.back_button = create_navigation_link( 1, "nav-backward", self.navigate_back, tr("Previous object"), (5, 0) ) self.forward_button = create_navigation_link( 2, "nav-forward", self.navigate_forward, tr("Next object") ) self.back_links = [] self.forward_links = [] return toolbar
def __init__(self, master): import webbrowser super().__init__(master) main_frame = ttk.Frame(self) main_frame.grid(sticky=tk.NSEW, ipadx=15, ipady=15) main_frame.rowconfigure(0, weight=1) main_frame.columnconfigure(0, weight=1) self.title(tr("About Thonny")) self.resizable(height=tk.FALSE, width=tk.FALSE) self.protocol("WM_DELETE_WINDOW", self._ok) # bg_frame = ttk.Frame(self) # gives proper color in aqua # bg_frame.grid() heading_font = tkinter.font.nametofont("TkHeadingFont").copy() heading_font.configure(size=19, weight="bold") heading_label = ttk.Label( main_frame, text="Thonny " + thonny.get_version(), font=heading_font ) heading_label.grid() url = "https://thonny.org" url_font = tkinter.font.nametofont("TkDefaultFont").copy() url_font.configure(underline=1) url_label = ttk.Label( main_frame, text=url, style="Url.TLabel", cursor="hand2", font=url_font ) url_label.grid() url_label.bind("<Button-1>", lambda _: webbrowser.open(url)) if platform.system() == "Linux": try: import distro # distro don't need to be installed system_desc = distro.name(True) except ImportError: system_desc = "Linux" if "32" not in system_desc and "64" not in system_desc: system_desc += " " + self.get_os_word_size_guess() else: system_desc = ( platform.system() + " " + platform.release() + " " + self.get_os_word_size_guess() ) platform_label = ttk.Label( main_frame, justify=tk.CENTER, text=system_desc + "\n" + "Python " + get_python_version_string(maxsize=sys.maxsize) + "\n" + "Tk " + ui_utils.get_tk_version_str(), ) platform_label.grid(pady=20) credits_label = ttk.Label( main_frame, text=tr( "Made in\n" + "University of Tartu, Estonia,\n" + "with the help from\n" + "open-source community,\n" + "Raspberry Pi Foundation\n" + "and Cybernetica AS" ), style="Url.TLabel", cursor="hand2", font=url_font, justify="center", ) credits_label.grid() credits_label.bind( "<Button-1>", lambda _: webbrowser.open("https://github.com/thonny/thonny/blob/master/CREDITS.rst"), ) license_font = tkinter.font.nametofont("TkDefaultFont").copy() license_font.configure(size=7) license_label = ttk.Label( main_frame, text="Copyright (©) " + str(datetime.datetime.now().year) + " Aivar Annamaa\n" + tr( "This program comes with\n" + "ABSOLUTELY NO WARRANTY!\n" + "It is free software, and you are welcome to\n" + "redistribute it under certain conditions, see\n" + "https://opensource.org/licenses/MIT\n" + "for details" ), justify=tk.CENTER, font=license_font, ) license_label.grid(pady=20) ok_button = ttk.Button(main_frame, text="OK", command=self._ok, default="active") ok_button.grid(pady=(0, 15)) ok_button.focus_set() self.bind("<Return>", self._ok, True) self.bind("<Escape>", self._ok, True)
def load_plugin(): add_micropython_backend("CircuitPython", CircuitPythonProxy, tr("CircuitPython (generic)"), CircuitPythonConfigPage)
def get_unknown_version_text(self): return tr("Please wait") + "..."
def get_ok_text(self): return tr("Install")
def __init__(self, master, host, user, method): super(PasswordDialog, self).__init__(master) self.password = "" self.save_password = False margin = self.get_padding() spacing = margin // 2 self.title(tr("Authentication")) if method == PUBLIC_KEY_WITH_PASS_METHOD: prompt = tr("Enter the passphrase of your private key for\n{}") else: assert method == PASSWORD_METHOD prompt = tr("Enter your password for\n{}") prompt = prompt.format(user + "@" + host) self.prompt_label = ttk.Label(self.main_frame, text=prompt) self.prompt_label.grid(row=1, column=1, columnspan=2, padx=margin, pady=(margin, spacing)) self.entry_widget = ttk.Entry(self.main_frame, width=15, show="•") self.bind("<Return>", self.on_ok, True) self.bind("<Escape>", self.on_cancel, True) self.bind("<KP_Enter>", self.on_ok, True) self.entry_widget.grid(row=3, column=1, columnspan=2, sticky="we", padx=margin, pady=(0, spacing)) self.save_variable = tk.BooleanVar(value=False) self.save_checkbox = ttk.Checkbutton( self.main_frame, text=tr("Save password"), variable=self.save_variable, offvalue=False, onvalue=True, ) if method == PASSWORD_METHOD: self.save_checkbox.grid(row=5, padx=margin, pady=(0, spacing), column=1, columnspan=2, sticky="w") self.ok_button = ttk.Button(self.main_frame, text=tr("OK"), command=self.on_ok, default="active") self.ok_button.grid(row=10, column=1, padx=(margin, spacing), pady=(margin, margin), sticky="e") self.cancel_button = ttk.Button(self.main_frame, text=tr("Cancel"), command=self.on_cancel) self.cancel_button.grid(row=10, column=2, padx=(0, margin), pady=(margin, margin), sticky="e") self.main_frame.columnconfigure(1, weight=1) self.entry_widget.focus_set()
def load_plugin() -> None: get_workbench().add_view(AstView, tr("Program tree"), "s")
def load_plugin() -> None: get_workbench().add_configuration_page("shell", tr("Shell"), ShellConfigurationPage, 70)
def __init__(self, master): super().__init__(master) self._has_opened_firmware_flasher = False intro_label = ttk.Label(self, text=self._get_intro_text()) intro_label.grid(row=0, column=0, sticky="nw") driver_url = self._get_usb_driver_url() if driver_url: driver_url_label = create_url_label(self, driver_url) driver_url_label.grid(row=1, column=0, sticky="nw") port_label = ttk.Label( self, text="Port or WebREPL" if self.allow_webrepl else tr("Port")) port_label.grid(row=3, column=0, sticky="nw", pady=(10, 0)) self._ports_by_desc = { p.description if p.device in p.description else p.description + " (" + p.device + ")": p.device for p in list_serial_ports() } self._ports_by_desc["< " + tr("Try to detect port automatically") + " >"] = "auto" self._WEBREPL_OPTION_DESC = "< WebREPL >" if self.allow_webrepl: self._ports_by_desc[self._WEBREPL_OPTION_DESC] = "webrepl" def port_order(p): _, name = p if name is None: return "" elif name.startswith("COM") and len(name) == 4: # Make one-digit COM ports go before COM10 return name.replace("COM", "COM0") else: return name # order by port, auto first port_descriptions = [ key for key, _ in sorted(self._ports_by_desc.items(), key=port_order) ] self._port_desc_variable = create_string_var( self.get_stored_port_desc(), self._on_change_port) self._port_combo = ttk.Combobox( self, exportselection=False, textvariable=self._port_desc_variable, values=port_descriptions, ) self._port_combo.state(["!disabled", "readonly"]) self._port_combo.grid(row=4, column=0, sticky="new") self.columnconfigure(0, weight=1) self._webrepl_frame = None self._flashing_frame = None last_row = ttk.Frame(self) last_row.grid(row=100, sticky="swe") self.rowconfigure(100, weight=1) last_row.columnconfigure(1, weight=1) advanced_link = ui_utils.create_action_label( last_row, tr("Advanced options"), lambda event: self._show_advanced_options()) # advanced_link.grid(row=0, column=1, sticky="e") if self._has_flashing_dialog(): firmware_link = ui_utils.create_action_label( last_row, tr("Install or update firmware"), self._on_click_firmware_installer_link, ) firmware_link.grid(row=1, column=1, sticky="e") self._on_change_port()
def __init__(self, master, kind, initial_dir): super().__init__(master=master) self.result = None self.updating_selection = False self.kind = kind if kind == "open": self.title(tr("Open from %s") % get_runner().get_node_label()) else: assert kind == "save" self.title(tr("Save to %s") % get_runner().get_node_label()) background = ttk.Frame(self) background.grid(row=0, column=0, sticky="nsew") self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) self.browser = DialogRemoteFileBrowser(background, self) self.browser.grid(row=0, column=0, columnspan=4, sticky="nsew", pady=20, padx=20) self.browser.configure(borderwidth=1, relief="groove") self.browser.tree.configure(selectmode="browse") self.name_label = ttk.Label(background, text=tr("File name:")) self.name_label.grid(row=1, column=0, pady=(0, 20), padx=20, sticky="w") self.name_var = create_string_var("") self.name_entry = ttk.Entry( background, textvariable=self.name_var, state="normal" if kind == "save" else "disabled") self.name_entry.grid(row=1, column=1, pady=(0, 20), padx=(0, 20), sticky="we") self.name_entry.bind("<KeyRelease>", self.on_name_edit, True) self.ok_button = ttk.Button(background, text=tr("OK"), command=self.on_ok) self.ok_button.grid(row=1, column=2, pady=(0, 20), padx=(0, 20), sticky="e") self.cancel_button = ttk.Button(background, text=tr("Cancel"), command=self.on_cancel) self.cancel_button.grid(row=1, column=3, pady=(0, 20), padx=(0, 20), sticky="e") background.rowconfigure(0, weight=1) background.columnconfigure(1, weight=1) self.bind("<Escape>", self.on_cancel, True) self.bind("<Return>", self.on_ok, True) self.protocol("WM_DELETE_WINDOW", self.on_cancel) self.tree_select_handler_id = self.browser.tree.bind( "<<TreeviewSelect>>", self.on_tree_select, True) self.browser.request_focus_into(initial_dir) self.name_entry.focus_set()
def __init__(self, master): super().__init__(master) self.add_checkbox( "assistance.open_assistant_on_errors", tr("Open Assistant automatically when program crashes with an exception" ), row=2, columnspan=2, ) self.add_checkbox( "assistance.open_assistant_on_warnings", tr("Open Assistant automatically when it has warnings for your code" ), row=3, columnspan=2, ) if get_workbench().get_option("assistance.use_pylint", "missing") != "missing": self.add_checkbox("assistance.use_pylint", tr("Perform selected Pylint checks"), row=4, columnspan=2) if get_workbench().get_option("assistance.use_mypy", "missing") != "missing": self.add_checkbox("assistance.use_mypy", tr("Perform MyPy checks"), row=5, columnspan=2) disabled_checks_label = ttk.Label( self, text=tr("Disabled checks (one id per line)")) disabled_checks_label.grid(row=8, sticky="nw", pady=(10, 0), columnspan=2) self.disabled_checks_box = TextFrame( self, vertical_scrollbar_style=scrollbar_style("Vertical"), horizontal_scrollbar_style=scrollbar_style("Horizontal"), horizontal_scrollbar_class=ui_utils.AutoScrollbar, wrap="word", font="TkDefaultFont", # cursor="arrow", padx=5, pady=5, height=4, borderwidth=1, relief="groove", ) self.disabled_checks_box.grid(row=9, sticky="nsew", pady=(0, 10), columnspan=2) self.disabled_checks_box.text.insert( "1.0", "\n".join( get_workbench().get_option("assistance.disabled_checks"))) self.columnconfigure(1, weight=1) self.rowconfigure(9, weight=1)
def _delete_paths(self, paths): get_runner().send_command_and_wait( InlineCommand("delete", paths=paths), dialog_title=tr("Deleting"), )
def _init_commands(self): # TODO: do these commands have to be in EditorNotebook ?? # Create a module level function install_editor_notebook ?? # Maybe add them separately, when notebook has been installed ?? get_workbench().add_command( "new_file", "file", tr("New"), self._cmd_new_file, caption=tr("New"), default_sequence=select_sequence("<Control-n>", "<Command-n>"), extra_sequences=["<Control-Greek_nu>"], group=10, image="new-file", include_in_toolbar=True, ) get_workbench().add_command( "open_file", "file", tr("Open..."), self._cmd_open_file, caption=tr("Load"), default_sequence=select_sequence("<Control-o>", "<Command-o>"), extra_sequences=["<Control-Greek_omicron>"], group=10, image="open-file", include_in_toolbar=True, ) get_workbench().add_command("recents", "file", tr("Recent files"), group=10, submenu=self._recent_menu) # http://stackoverflow.com/questions/22907200/remap-default-keybinding-in-tkinter get_workbench().bind_class("Text", "<Control-o>", self._control_o) get_workbench().bind_class("Text", "<Control-Greek_omicron>", self._control_o) rebind_control_a(get_workbench()) get_workbench().add_command( "close_file", "file", tr("Close"), self._cmd_close_file, default_sequence=select_sequence("<Control-w>", "<Command-w>"), extra_sequences=["<Control-Greek_finalsmallsigma>"], tester=lambda: self.get_current_editor() is not None, group=10, ) get_workbench().add_command( "close_files", "file", tr("Close all"), self.close_tabs, tester=lambda: self.get_current_editor() is not None, default_sequence=select_sequence("<Control-W>", "<Command-Alt-w>"), group=10, ) get_workbench().add_command( "save_file", "file", tr("Save"), self._cmd_save_file, caption=tr("Save"), default_sequence=select_sequence("<Control-s>", "<Command-s>"), extra_sequences=["<Control-Greek_sigma>"], tester=self._cmd_save_file_enabled, group=10, image="save-file", include_in_toolbar=True, ) get_workbench().add_command( "save_all_files", "file", tr("Save All files"), self._cmd_save_all_files, caption=tr("Save All files"), default_sequence=select_sequence("<Control-Alt-s>", "<Command-Alt-s>"), tester=self._cmd_save_all_files_enabled, group=10, ) get_workbench().add_command( "save_file_as", "file", tr("Save as..."), self._cmd_save_file_as, default_sequence=select_sequence("<Control-Shift-S>", "<Command-Shift-s>"), extra_sequences=["<Control-Greek_SIGMA>"], tester=lambda: self.get_current_editor() is not None, group=10, ) get_workbench().add_command( "save_copy", "file", tr("Save copy..."), self._cmd_save_copy, tester=lambda: self.get_current_editor() is not None, group=10, ) get_workbench().add_command( "move_rename_file", "file", tr("Move / rename..."), self._cmd_move_rename_file, tester=self._cmd_move_rename_file_enabled, group=10, ) get_workbench().createcommand("::tk::mac::OpenDocument", self._mac_open_document)
def cancel_work(self): # worker should periodically check this value self._state = "cancelling" self.set_action_text(tr("Cancelling"))
def load_plugin() -> None: get_workbench().add_view(ObjectInspector, tr("Object inspector"), "se")
def get_ok_text(self): return tr("OK")
def perform_mkdir(self, parent_dir, name): path = (parent_dir + self.get_dir_separator() + name).replace("//", "/") get_runner().send_command_and_wait( InlineCommand("mkdir", path=path), dialog_title=tr("Creating directory"), )
def get_cancel_text(self): return tr("Cancel")
def add_last_menu_items(self, context): self.menu.add_command(label=tr("Properties"), command=self.show_properties) if context == "button": self.menu.add_command(label=tr("Storage space"), command=self.show_fs_info)
def load_plugin() -> None: get_workbench().add_view(VariablesView, tr("Variables"), "ne", default_position_key="AAA")
def load_plugin() -> None: get_workbench().add_configuration_page("theme", tr("Theme & Font"), ThemeAndFontConfigurationPage, 40)
def get_full_label(self): if self.is_connected(): return self.get_node_label() + " @ " + self._port else: return self.get_node_label() + " (" + tr("Not connected") + ")"
def load_plugin() -> None: get_workbench().set_default( "file.last_browser_folder", normpath_with_actual_case(os.path.expanduser("~"))) get_workbench().add_view(FilesView, tr("Files"), "nw")
def __init__(self, master): ConfigurationPage.__init__(self, master) self.add_checkbox( "general.single_instance", tr("Allow only single Thonny instance"), row=1, columnspan=2 ) self.add_checkbox( "general.event_logging", tr("Log program usage events"), row=4, columnspan=2 ) self.add_checkbox( "file.reopen_all_files", tr("Reopen all files from previous session"), row=5, columnspan=2, ) self.add_checkbox( "general.disable_notification_sound", tr("Disable notification sound"), row=6, columnspan=2, ) self.add_checkbox( "general.debug_mode", tr("Debug mode (provides more detailed diagnostic logs)"), row=7, columnspan=2, ) # language self._language_name_var = tk.StringVar( value=languages.LANGUAGES_DICT.get(get_workbench().get_option("general.language"), "") ) self._language_label = ttk.Label(self, text=tr("Language")) self._language_label.grid(row=10, column=0, sticky=tk.W, padx=(0, 10), pady=(10, 0)) self._language_combo = ttk.Combobox( self, width=20, exportselection=False, textvariable=self._language_name_var, state="readonly", height=15, values=list(languages.LANGUAGES_DICT.values()), ) self._language_combo.grid(row=10, column=1, sticky=tk.W, pady=(10, 0)) # Mode ttk.Label(self, text=tr("UI mode")).grid( row=20, column=0, sticky=tk.W, padx=(0, 10), pady=(10, 0) ) self.add_combobox( "general.ui_mode", ["simple", "regular", "expert"], row=20, column=1, pady=(10, 0), width=10, ) # scaling self._scaling_label = ttk.Label(self, text=tr("UI scaling factor")) self._scaling_label.grid(row=30, column=0, sticky=tk.W, padx=(0, 10), pady=(10, 0)) scalings = ["default"] + sorted({0.5, 0.75, 1.0, 1.25, 1.33, 1.5, 2.0, 2.5, 3.0, 4.0}) self.add_combobox("general.scaling", scalings, row=30, column=1, pady=(10, 0), width=10) self._font_scaling_var = get_workbench().get_variable("general.font_scaling_mode") self._font_scaling_label = ttk.Label(self, text=tr("Font scaling mode")) self._font_scaling_label.grid(row=40, column=0, sticky=tk.W, padx=(0, 10), pady=(10, 0)) self.add_combobox( "general.font_scaling_mode", ["default", "extra", "automatic"], row=40, column=1, pady=(10, 0), width=10, ) reopen_label = ttk.Label( self, text=tr("NB! Restart Thonny after changing these options!"), font="BoldTkDefaultFont", ) reopen_label.grid(row=100, column=0, sticky=tk.W, pady=20, columnspan=2) self.columnconfigure(1, weight=1)