def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) # These can be bound in a parent widget. This doesn't use # enable_traversal() because we want more bindings than it # creates. Undocumented because plugins shouldn't need this. self.bindings: List[Tuple[str, Callable[['tkinter.Event[tkinter.Misc]'], utils.BreakOrNone]]] = [ ('<Control-Prior>', functools.partial( self._on_page_updown, False, -1)), ('<Control-Next>', functools.partial( self._on_page_updown, False, +1)), ('<Control-Shift-Prior>', functools.partial( self._on_page_updown, True, -1)), ('<Control-Shift-Next>', functools.partial( self._on_page_updown, True, +1)), ] for number in range(1, 10): callback = functools.partial(self._on_alt_n, number) self.bindings.append(('<Alt-Key-%d>' % number, callback)) self.bind('<<NotebookTabChanged>>', self._focus_selected_tab, add=True) self.bind('<Button-1>', self._on_click, add=True) utils.bind_mouse_wheel(self, self._on_wheel, add=True)
def __init__(self, parent, filetype, **kwargs): super().__init__(parent, **kwargs) self.set_filetype(filetype) # FIXME: lots of things have been turned into plugins, but # there's still wayyyy too much stuff in here... partial = functools.partial # pep8 line length self.bind('<BackSpace>', partial(self._on_delete, False)) self.bind('<Control-BackSpace>', partial(self._on_delete, True)) self.bind('<Control-Delete>', partial(self._on_delete, True)) self.bind('<Shift-Control-Delete>', partial(self._on_delete, True, shifted=True)) self.bind('<Shift-Control-BackSpace>', partial(self._on_delete, True, shifted=True)) self.bind('<Return>', (lambda event: self.cursor_has_moved())) self.bind('<parenright>', self._on_closing_brace, add=True) self.bind('<bracketright>', self._on_closing_brace, add=True) self.bind('<braceright>', self._on_closing_brace, add=True) self.bind('<Control-z>', self.undo) self.bind('<Control-y>', self.redo) self.bind('<Control-x>', self.cut) self.bind('<Control-c>', self.copy) self.bind('<Control-v>', self.paste) self.bind('<Control-a>', self.select_all) self.bind('<Control-plus>', lambda event: self.on_wheel('up')) self.bind('<Control-minus>', lambda event: self.on_wheel('down')) self.bind('<Control-0>', lambda event: self.on_wheel('reset')) utils.bind_mouse_wheel(self, self.on_wheel, prefixes='Control-')
def __init__(self, parent, filetype, **kwargs): super().__init__(parent, **kwargs) self.set_filetype(filetype) # FIXME: lots of things have been turned into plugins, but # there's still wayyyy too much stuff in here... partial = functools.partial # pep8 line length self.bind('<BackSpace>', partial(self._on_delete, False)) self.bind('<Control-BackSpace>', partial(self._on_delete, True)) self.bind('<Control-Delete>', partial(self._on_delete, True)) self.bind('<Shift-Control-Delete>', partial(self._on_delete, True, shifted=True)) self.bind('<Shift-Control-BackSpace>', partial(self._on_delete, True, shifted=True)) self.bind('<Return>', (lambda event: self.cursor_has_moved())) self.bind('<parenright>', self._on_closing_brace, add=True) self.bind('<bracketright>', self._on_closing_brace, add=True) self.bind('<braceright>', self._on_closing_brace, add=True) # most other things work by default, but these don't self.bind('<Control-v>', self._paste) self.bind('<Control-y>', self._redo) self.bind('<Control-a>', self._select_all) utils.bind_mouse_wheel(self, self._on_ctrl_wheel, prefixes='Control-')
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # These can be bound in a parent widget. This doesn't use # enable_traversal() because we want more bindings than it # creates. # TODO: document these? partial = functools.partial # pep-8 line length self.bindings = [ ('<Control-Prior>', partial(self._on_page_updown, False, -1)), ('<Control-Next>', partial(self._on_page_updown, False, +1)), ('<Control-Shift-Prior>', partial(self._on_page_updown, True, -1)), ('<Control-Shift-Next>', partial(self._on_page_updown, True, +1)), ] for number in range(1, 10): callback = functools.partial(self._on_alt_n, number) self.bindings.append(('<Alt-Key-%d>' % number, callback)) self.bind('<<NotebookTabChanged>>', self._focus_selected_tab, add=True) self.bind('<Button-1>', self._on_click, add=True) utils.bind_mouse_wheel(self, self._on_wheel, add=True)
def _fill_menus_with_default_stuff() -> None: # Make sure to get the order of menus right: # File, Edit, <everything else>, Help get_menu("Help") # handled specially in get_menu get_menu("File") get_menu("Edit") def new_file() -> None: get_tab_manager().add_tab(tabs.FileTab(get_tab_manager())) def open_files() -> None: paths: Sequence[str] = filedialog.askopenfilenames( **filedialog_kwargs) # type: ignore # tkinter returns '' if the user cancels, and i'm arfaid that python # devs might "fix" a future version to return None if not paths: return for path in map(pathlib.Path, paths): try: tab = tabs.FileTab.open_file(get_tab_manager(), path) except (UnicodeError, OSError) as e: log.exception("opening '%s' failed", path) utils.errordialog( type(e).__name__, "Opening failed!", traceback.format_exc()) continue get_tab_manager().add_tab(tab) def save_file(save_as: bool) -> None: tab = get_tab_manager().select() assert isinstance(tab, tabs.FileTab) if save_as: tab.save_as() else: tab.save() def close_selected_tab() -> None: tab = get_tab_manager().select() assert tab is not None if tab.can_be_closed(): get_tab_manager().close_tab(tab) get_menu("File").add_command(label="New File", command=new_file) get_menu("File").add_command(label="Open", command=open_files) get_menu("File").add_command(label="Save", command=functools.partial(save_file, False)) get_menu("File").add_command(label="Save As", command=functools.partial(save_file, True)) get_menu("File").add_separator() get_menu("File").add_command(label="Close", command=close_selected_tab) get_menu("File").add_command(label="Quit", command=quit) set_enabled_based_on_tab("File/Save", (lambda tab: isinstance(tab, tabs.FileTab))) set_enabled_based_on_tab("File/Save As", (lambda tab: isinstance(tab, tabs.FileTab))) set_enabled_based_on_tab("File/Close", (lambda tab: tab is not None)) set_enabled_based_on_tab("File/Quit", (lambda tab: tab is None)) def change_font_size(how: Literal['bigger', 'smaller', 'reset']) -> None: if how == 'reset': settings.reset('font_size') return size = settings.get('font_size', int) if how == 'bigger': size += 1 else: size -= 1 if size < 3: return settings.set('font_size', size) # trigger change_font_size() with mouse wheel from any text widget utils.bind_mouse_wheel( 'Text', (lambda updn: change_font_size('bigger' if updn == 'up' else 'smaller')), prefixes='Control-', add=True) get_menu("View").add_command(label="Bigger Font", command=functools.partial( change_font_size, 'bigger')) get_menu("View").add_command(label="Smaller Font", command=functools.partial( change_font_size, 'smaller')) get_menu("View").add_command(label="Reset Font Size", command=functools.partial( change_font_size, 'reset')) set_enabled_based_on_tab("View/Bigger Font", (lambda tab: tab is not None)) set_enabled_based_on_tab("View/Smaller Font", (lambda tab: tab is not None)) set_enabled_based_on_tab("View/Reset Font Size", (lambda tab: tab is not None)) get_menu("Settings").add_command(label="Porcupine Settings", command=settings.show_dialog) def add_link(menu_path: str, label: str, url: str) -> None: def callback() -> None: # lambda doesn't work for this... webbrowser.open(url) # ...because this returns non-None and mypy get_menu(menu_path).add_command(label=label, command=callback) # TODO: porcupine starring button add_link("Help", "Porcupine Wiki", "https://github.com/Akuli/porcupine/wiki") add_link("Help", "Report a problem or request a feature", "https://github.com/Akuli/porcupine/issues/new") add_link("Help/Python", "Free help chat", "http://webchat.freenode.net/?channels=%23%23learnpython") add_link("Help/Python", "My Python tutorial", "https://github.com/Akuli/python-tutorial/blob/master/README.md") add_link("Help/Python", "Official documentation", "https://docs.python.org/")
def __init__(self, manager): super().__init__(manager) self.bind('<Button-1>', self._on_click, add=True) utils.bind_mouse_wheel(self, self._on_wheel, add=True)