def _init() -> None: main_window = get_main_window() main_window.config(menu=tkinter.Menu(main_window, tearoff=False)) main_window.bind('<<PluginsLoaded>>', (lambda event: update_keyboard_shortcuts()), add=True) main_window.bind_class('Text', '<FocusIn>', _fix_text_widget_bindings, add=True) _fill_menus_with_default_stuff()
def _update_shortcuts_for_opening_submenus() -> None: used_letters = set() for virtual_event in get_main_window().event_info(): for physical_event in get_main_window().event_info(virtual_event): match = re.fullmatch(r"<Alt-Key-([a-z])>", physical_event) if match is not None: used_letters.add(match.group(1)) menu = get_menu(None) for submenu_index in range(menu.index("end") + 1): # type: ignore[no-untyped-call] for letter_index, letter in enumerate( menu.entrycget( submenu_index, "label").lower()): # type: ignore[no-untyped-call] if letter in ascii_lowercase and letter not in used_letters: menu.entryconfig(submenu_index, underline=letter_index) used_letters.add(letter) break else: menu.entryconfig(submenu_index, accelerator="")
def _init() -> None: log.debug("_init() starts") main_window = get_main_window() main_window.config(menu=tkinter.Menu(main_window, tearoff=False)) main_window.bind("<<PluginsLoaded>>", (lambda event: update_keyboard_shortcuts()), add=True) main_window.bind_class("Text", "<FocusIn>", _fix_text_widget_bindings, add=True) _fill_menus_with_default_stuff() log.debug("_init() done")
def _update_keyboard_shortcuts_inside_submenus() -> None: main_window = get_main_window() for path, menu, index in _walk_menu_contents(): event_name = f"<<Menubar:{path}>>" # show keyboard shortcuts in menus menu.entryconfig(index, accelerator=utils.get_binding(event_name, menu=True)) # trigger menu items when <<Menubar:Foo/Bar>> events are generated if not main_window.bind(event_name): # FIXME: what if menu item is inserted somewhere else than to end, and indexes change? command = functools.partial(_menu_event_handler, menu, index) main_window.bind(event_name, command, add=True)
def get_menu(path: Optional[str]) -> tkinter.Menu: """ Find a menu widget, creating menus as necessary. For example, ``get_menu("Tools/Python")`` returns a submenu labelled *Python* from a menu named *Tools*. The *Tools* menu is created if it doesn't already exist. If *path* is ``None``, then the menubar itself is returned. """ main_window = get_main_window() main_menu = cast(tkinter.Menu, main_window.nametowidget(main_window.cget('menu'))) if path is None: return main_menu menu = main_menu for label in path.split('/'): submenu_index = _find_item(menu, label) if submenu_index is None: # Need to pass the menu as an explicit argument to tkinter.Menu. # Otherwise add_cascade() below tries to allocate a crazy amount of # memory and freezes everything when running tests (don't know why) submenu = tkinter.Menu(menu, tearoff=False) if menu == main_menu and menu.index('end') is not None: # adding something to non-empty main menu, don't add all the # way to end so that "Help" menu stays at very end last_index = menu.index("end") assert last_index is not None menu.insert_cascade(last_index, label=label, menu=submenu) else: menu.add_cascade(label=label, menu=submenu) menu = submenu else: menu = cast( tkinter.Menu, menu.nametowidget(menu.entrycget(submenu_index, 'menu'))) return menu
def update_keyboard_shortcuts() -> None: """ This function does two things to the *New File* menu item in the *File* menu, and similarly to all other menu items in all menus: * Show *Ctrl+N* next to *New File*. * Ensure that the menu item's callback runs when Ctrl+N is pressed. This has to be called when menus or keyboard shortcuts have been modified. It's called automatically when plugins have been set up. """ main_window = get_main_window() for path, menu, index in _walk_menu_contents(): event_name = f'<<Menubar:{path}>>' # show keyboard shortcuts in menus shortcuts = map(_get_keyboard_shortcut, main_window.event_info(event_name)) menu.entryconfig(index, accelerator=', '.join(shortcuts)) # trigger menu items when <<Menubar:Foo/Bar>> events are generated if not main_window.bind(event_name): command = functools.partial(_menu_event_handler, menu, index) main_window.bind(event_name, command, add=True)
def _generate_event(name: str, junk: object) -> Literal["break"]: get_main_window().event_generate(name) return "break"