def __init__(self, parent: tkinter.Misc, textwidget: tkinter.Text, **kwargs: Any) -> None: super().__init__(parent, **kwargs) self._textwidget = textwidget # grid layout: # column 0 column 1 column 2 column 3 # ,---------------------------------------------------------------. # row0| Find: | text entry | | [x] Full words only | # |---------------|---------------|-------|-----------------------| # row1| Replace with: | text entry | | [x] Ignore case | # |---------------------------------------------------------------| # row2| button frame, this thing contains a bunch of buttons | # |---------------------------------------------------------------| # row3| status label with useful-ish text | # |---------------------------------------------------------------| # row4| separator | # `---------------------------------------------------------------' # # note that column 2 is used just for spacing, the separator helps # distinguish this from e.g. status bar below this self.grid_columnconfigure(2, minsize=30) # type: ignore[no-untyped-call] self.grid_columnconfigure(3, weight=1) # type: ignore[no-untyped-call] self.full_words_var = tkinter.BooleanVar() self.ignore_case_var = tkinter.BooleanVar() find_var = tkinter.StringVar() self.find_entry = self._add_entry(0, "Find:") self.find_entry.config(textvariable=find_var) find_var.trace_add("write", self.highlight_all_matches) # because cpython gc cast(Any, self.find_entry).lol = find_var self.replace_entry = self._add_entry(1, "Replace with:") self.find_entry.bind("<Shift-Return>", self._go_to_previous_match, add=True) self.find_entry.bind("<Return>", self._go_to_next_match, add=True) buttonframe = ttk.Frame(self) buttonframe.grid(row=2, column=0, columnspan=4, sticky="we") self.previous_button = ttk.Button(buttonframe, text="Previous match", command=self._go_to_previous_match) self.next_button = ttk.Button(buttonframe, text="Next match", command=self._go_to_next_match) self.replace_this_button = ttk.Button( buttonframe, text="Replace this match", underline=len("Replace "), command=self._replace_this, ) self.replace_all_button = ttk.Button(buttonframe, text="Replace all", underline=len("Replace "), command=self._replace_all) self.previous_button.pack(side="left") self.next_button.pack(side="left") self.replace_this_button.pack(side="left") self.replace_all_button.pack(side="left") self._update_buttons() self.full_words_var.trace_add("write", self.highlight_all_matches) self.ignore_case_var.trace_add("write", self.highlight_all_matches) ttk.Checkbutton(self, text="Full words only", underline=0, variable=self.full_words_var).grid(row=0, column=3, sticky="w") ttk.Checkbutton(self, text="Ignore case", underline=0, variable=self.ignore_case_var).grid(row=1, column=3, sticky="w") self.statuslabel = ttk.Label(self) self.statuslabel.grid(row=3, column=0, columnspan=4, sticky="we") ttk.Separator(self, orient="horizontal").grid(row=4, column=0, columnspan=4, sticky="we") closebutton = ttk.Label(self, cursor="hand2") closebutton.place(relx=1, rely=0, anchor="ne") closebutton.bind("<Button-1>", self.hide, add=True) closebutton.config(image=images.get("closebutton")) # explained in test_find_plugin.py textwidget.bind("<<Selection>>", self._update_buttons, add=True) textwidget.bind("<<SettingChanged:pygments_style>>", self._config_tags, add=True) self._config_tags()
def __init__(self, parent: tkinter.Tk, textwidget: tkinter.Text, **kwargs: Any) -> None: super().__init__(parent, **kwargs) # type: ignore self._textwidget = textwidget # grid layout: # column 0 column 1 column 2 column 3 # ,---------------------------------------------------------------. # row0| Find: | text entry | | [x] Full words only | # |---------------|---------------|-------|-----------------------| # row1| Replace with: | text entry | | [x] Ignore case | # |---------------------------------------------------------------| # row2| button frame, this thing contains a bunch of buttons | # |---------------------------------------------------------------| # row3| status label with useful-ish text | # |---------------------------------------------------------------| # row4| separator | # `---------------------------------------------------------------' # # note that column 2 is used just for spacing, the separator helps # distinguish this from e.g. status bar below this self.grid_columnconfigure(2, minsize=30) self.grid_columnconfigure(3, weight=1) # TODO: use the pygments theme somehow? textwidget.tag_config('find_highlight', foreground='black', background='yellow') self._textwidget.tag_lower('find_highlight', 'sel') self.find_entry = self._add_entry(0, "Find:") find_var = tkinter.StringVar() self.find_entry.config(textvariable=find_var) find_var.trace_add('write', self.highlight_all_matches) # because cpython gc cast(Any, self.find_entry).lol = find_var self.replace_entry = self._add_entry(1, "Replace with:") self.find_entry.bind('<Shift-Return>', self._go_to_previous_match, add=True) self.find_entry.bind('<Return>', self._go_to_next_match, add=True) # commented out because pressing tab in self.find_entry unselects the # text in textwidget for some reason #self.replace_entry.bind('<Return>', self._replace_this) buttonframe = ttk.Frame(self) buttonframe.grid(row=2, column=0, columnspan=4, sticky='we') self.previous_button = ttk.Button(buttonframe, text="Previous match", command=self._go_to_previous_match) self.next_button = ttk.Button(buttonframe, text="Next match", command=self._go_to_next_match) self.replace_this_button = ttk.Button(buttonframe, text="Replace this match", command=self._replace_this) self.replace_all_button = ttk.Button(buttonframe, text="Replace all", command=self._replace_all) self.previous_button.pack(side='left') self.next_button.pack(side='left') self.replace_this_button.pack(side='left') self.replace_all_button.pack(side='left') self._update_buttons() self.full_words_var = tkinter.BooleanVar() self.full_words_var.trace_add('write', self.highlight_all_matches) self.ignore_case_var = tkinter.BooleanVar() self.ignore_case_var.trace_add('write', self.highlight_all_matches) # TODO: add keyboard shortcut for "Full words only". I use it all the # time and reaching mouse is annoying. Tabbing through everything # is also annoying. ttk.Checkbutton(self, text="Full words only", variable=self.full_words_var).grid(row=0, column=3, sticky='w') ttk.Checkbutton(self, text="Ignore case", variable=self.ignore_case_var).grid(row=1, column=3, sticky='w') self.statuslabel = ttk.Label(self) self.statuslabel.grid(row=3, column=0, columnspan=4, sticky='we') ttk.Separator(self, orient='horizontal').grid(row=4, column=0, columnspan=4, sticky='we') closebutton = ttk.Label(self, cursor='hand2') closebutton.place(relx=1, rely=0, anchor='ne') closebutton.bind('<Button-1>', self.hide, add=True) closebutton.config(image=images.get('closebutton')) # explained in test_find_plugin.py textwidget.bind('<<Selection>>', self._update_buttons, add=True)