Edit Book: Move keyboard focus to the editor after running a saved search

This commit is contained in:
Kovid Goyal 2014-09-29 12:36:19 +05:30
parent fd103111bf
commit 880c889a23
2 changed files with 48 additions and 13 deletions

View File

@ -773,7 +773,9 @@ class Boss(QObject):
self.gui.central.pre_fill_search(text) self.gui.central.pre_fill_search(text)
def search_action_triggered(self, action, overrides=None): def search_action_triggered(self, action, overrides=None):
if self.gui.saved_searches.isVisible() and self.gui.saved_searches.has_focus(): ss = self.gui.saved_searches.isVisible()
trigger_saved_search = ss and (not self.gui.central.search_panel.isVisible() or self.gui.saved_searches.has_focus())
if trigger_saved_search:
return self.gui.saved_searches.trigger_action(action, overrides=overrides) return self.gui.saved_searches.trigger_action(action, overrides=overrides)
self.search(action, overrides) self.search(action, overrides)
@ -783,9 +785,13 @@ class Boss(QObject):
searchable_names = self.gui.file_list.searchable_names searchable_names = self.gui.file_list.searchable_names
if not searches or not validate_search_request(name, searchable_names, getattr(ed, 'has_marked_text', False), searches[0], self.gui): if not searches or not validate_search_request(name, searchable_names, getattr(ed, 'has_marked_text', False), searches[0], self.gui):
return return
run_search(searches, action, ed, name, searchable_names, ret = run_search(searches, action, ed, name, searchable_names,
self.gui, self.show_editor, self.edit_file, self.show_current_diff, self.add_savepoint, self.rewind_savepoint, self.set_modified) self.gui, self.show_editor, self.edit_file, self.show_current_diff, self.add_savepoint, self.rewind_savepoint, self.set_modified)
self.gui.saved_searches.setFocus(Qt.OtherFocusReason) ed = ret is True and self.gui.central.current_editor
if getattr(ed, 'has_line_numbers', False):
ed.editor.setFocus(Qt.OtherFocusReason)
else:
self.gui.saved_searches.setFocus(Qt.OtherFocusReason)
def search(self, action, overrides=None): def search(self, action, overrides=None):
# Run a search/replace # Run a search/replace
@ -801,8 +807,13 @@ class Boss(QObject):
if not validate_search_request(name, searchable_names, getattr(ed, 'has_marked_text', False), state, self.gui): if not validate_search_request(name, searchable_names, getattr(ed, 'has_marked_text', False), state, self.gui):
return return
run_search(state, action, ed, name, searchable_names, ret = run_search(state, action, ed, name, searchable_names,
self.gui, self.show_editor, self.edit_file, self.show_current_diff, self.add_savepoint, self.rewind_savepoint, self.set_modified) self.gui, self.show_editor, self.edit_file, self.show_current_diff, self.add_savepoint, self.rewind_savepoint, self.set_modified)
ed = ret is True and self.gui.central.current_editor
if getattr(ed, 'has_line_numbers', False):
ed.editor.setFocus(Qt.OtherFocusReason)
else:
self.gui.saved_searches.setFocus(Qt.OtherFocusReason)
def find_word(self, word, locations): def find_word(self, word, locations):
# Go to a word from the spell check dialog # Go to a word from the spell check dialog

View File

@ -31,10 +31,28 @@ REGEX_FLAGS = regex.VERSION1 | regex.WORD | regex.FULLCASE | regex.MULTILINE | r
# The search panel {{{ # The search panel {{{
class PushButton(QPushButton): class AnimatablePushButton(QPushButton):
'A push button that can be animated without actually emitting a clicked signal'
def __init__(self, *args, **kwargs):
QPushButton.__init__(self, *args, **kwargs)
self.timer = t = QTimer(self)
t.setSingleShot(True), t.timeout.connect(self.animate_done)
def animate_click(self, msec=100):
self.setDown(True)
self.update()
self.timer.start(msec)
def animate_done(self):
self.setDown(False)
self.update()
class PushButton(AnimatablePushButton):
def __init__(self, text, action, parent): def __init__(self, text, action, parent):
QPushButton.__init__(self, text, parent) AnimatablePushButton.__init__(self, text, parent)
self.clicked.connect(lambda : parent.search_triggered.emit(action)) self.clicked.connect(lambda : parent.search_triggered.emit(action))
class HistoryBox(HistoryComboBox): class HistoryBox(HistoryComboBox):
@ -652,12 +670,13 @@ class SavedSearches(QWidget):
stack.currentChanged.connect(self.stack_current_changed) stack.currentChanged.connect(self.stack_current_changed)
def pb(text, tooltip=None): def pb(text, tooltip=None):
b = QPushButton(text, self) b = AnimatablePushButton(text, self)
b.setToolTip(tooltip or '') b.setToolTip(tooltip or '')
b.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) b.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
return b return b
mulmsg = '\n\n' + _('The entries are tried in order until the first one matches.') mulmsg = '\n\n' + _('The entries are tried in order until the first one matches.')
self.action_button_map = {}
for text, action, tooltip in [ for text, action, tooltip in [
(_('&Find'), 'find', _('Run the search using the selected entries.') + mulmsg), (_('&Find'), 'find', _('Run the search using the selected entries.') + mulmsg),
@ -666,7 +685,7 @@ class SavedSearches(QWidget):
(_('Replace &all'), 'replace-all', _('Run Replace All for all selected entries in the order selected')), (_('Replace &all'), 'replace-all', _('Run Replace All for all selected entries in the order selected')),
(_('&Count all'), 'count', _('Run Count All for all selected entries')), (_('&Count all'), 'count', _('Run Count All for all selected entries')),
]: ]:
b = pb(text, tooltip) self.action_button_map[action] = b = pb(text, tooltip)
v.addWidget(b) v.addWidget(b)
b.clicked.connect(partial(self.run_search, action)) b.clicked.connect(partial(self.run_search, action))
@ -743,6 +762,9 @@ class SavedSearches(QWidget):
return False return False
def trigger_action(self, action, overrides=None): def trigger_action(self, action, overrides=None):
b = self.action_button_map.get(action)
if b is not None:
b.animate_click(300)
self._run_search(action, overrides) self._run_search(action, overrides)
def stack_current_changed(self, index): def stack_current_changed(self, index):
@ -809,7 +831,8 @@ class SavedSearches(QWidget):
fill_in_search(search) fill_in_search(search)
searches.append(search) searches.append(search)
if not searches: if not searches:
return return error_dialog(self, _('Cannot search'), _(
'No saved search is selected'), show=True)
if overrides: if overrides:
[sc.update(overrides) for sc in searches] [sc.update(overrides) for sc in searches]
self.run_saved_searches.emit(searches, action) self.run_saved_searches.emit(searches, action)
@ -1062,22 +1085,23 @@ def run_search(
for p, __ in searches: for p, __ in searches:
if editor is not None: if editor is not None:
if editor.find(p, marked=marked, save_match='gui'): if editor.find(p, marked=marked, save_match='gui'):
return return True
if wrap and not files and editor.find(p, wrap=True, marked=marked, save_match='gui'): if wrap and not files and editor.find(p, wrap=True, marked=marked, save_match='gui'):
return return True
for fname, syntax in files.iteritems(): for fname, syntax in files.iteritems():
ed = editors.get(fname, None) ed = editors.get(fname, None)
if ed is not None: if ed is not None:
if not wrap and ed is editor: if not wrap and ed is editor:
continue continue
if ed.find(p, complete=True, save_match='gui'): if ed.find(p, complete=True, save_match='gui'):
return show_editor(fname) show_editor(fname)
return True
else: else:
raw = current_container().raw_data(fname) raw = current_container().raw_data(fname)
if p.search(raw) is not None: if p.search(raw) is not None:
edit_file(fname, syntax) edit_file(fname, syntax)
if editors[fname].find(p, complete=True, save_match='gui'): if editors[fname].find(p, complete=True, save_match='gui'):
return return True
return no_match() return no_match()
def no_replace(prefix=''): def no_replace(prefix=''):