mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
Edit Book: Move keyboard focus to the editor after running a saved search
This commit is contained in:
parent
fd103111bf
commit
880c889a23
@ -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
|
||||||
|
@ -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=''):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user