mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Implement multi-searches
This commit is contained in:
parent
91a993643e
commit
cb2b41f28e
@ -743,17 +743,28 @@ def initialize_search_request(state, action, current_editor, current_editor_name
|
|||||||
editor = current_editor
|
editor = current_editor
|
||||||
marked = True
|
marked = True
|
||||||
|
|
||||||
return editor, where, files, do_all, marked, get_search_regex(state)
|
return editor, where, files, do_all, marked
|
||||||
|
|
||||||
def run_search(
|
def run_search(
|
||||||
state, action, current_editor, current_editor_name, searchable_names,
|
searches, action, current_editor, current_editor_name, searchable_names,
|
||||||
gui_parent, show_editor, edit_file, show_current_diff, add_savepoint, rewind_savepoint, set_modified):
|
gui_parent, show_editor, edit_file, show_current_diff, add_savepoint, rewind_savepoint, set_modified):
|
||||||
|
|
||||||
editor, where, files, do_all, marked, pat = initialize_search_request(state, action, current_editor, current_editor_name, searchable_names)
|
if isinstance(searches, dict):
|
||||||
|
searches = [searches]
|
||||||
|
|
||||||
|
editor, where, files, do_all, marked = initialize_search_request(searches[0], action, current_editor, current_editor_name, searchable_names)
|
||||||
|
wrap = searches[0]['wrap']
|
||||||
|
|
||||||
|
errfind = searches[0]['find']
|
||||||
|
if len(searches) > 1:
|
||||||
|
errfind = _('the selected searches')
|
||||||
|
|
||||||
|
searches = [(get_search_regex(search), search['replace']) for search in searches]
|
||||||
|
|
||||||
def no_match():
|
def no_match():
|
||||||
QApplication.restoreOverrideCursor()
|
QApplication.restoreOverrideCursor()
|
||||||
msg = '<p>' + _('No matches were found for %s') % ('<pre style="font-style:italic">' + prepare_string_for_xml(state['find']) + '</pre>')
|
msg = '<p>' + _('No matches were found for %s') % ('<pre style="font-style:italic">' + prepare_string_for_xml(errfind) + '</pre>')
|
||||||
if not state['wrap']:
|
if not wrap:
|
||||||
msg += '<p>' + _('You have turned off search wrapping, so all text might not have been searched.'
|
msg += '<p>' + _('You have turned off search wrapping, so all text might not have been searched.'
|
||||||
' Try the search again, with wrapping enabled. Wrapping is enabled via the'
|
' Try the search again, with wrapping enabled. Wrapping is enabled via the'
|
||||||
' "Wrap" checkbox at the bottom of the search panel.')
|
' "Wrap" checkbox at the bottom of the search panel.')
|
||||||
@ -761,22 +772,24 @@ def run_search(
|
|||||||
gui_parent, _('Not found'), msg, show=True)
|
gui_parent, _('Not found'), msg, show=True)
|
||||||
|
|
||||||
def do_find():
|
def do_find():
|
||||||
|
for p, __ in searches:
|
||||||
if editor is not None:
|
if editor is not None:
|
||||||
if editor.find(pat, marked=marked, save_match='gui'):
|
if editor.find(p, marked=marked, save_match='gui'):
|
||||||
|
return
|
||||||
|
if wrap and not files and editor.find(p, wrap=True, marked=marked, save_match='gui'):
|
||||||
return
|
return
|
||||||
if not files:
|
|
||||||
if not state['wrap']:
|
|
||||||
return no_match()
|
|
||||||
return editor.find(pat, wrap=True, marked=marked, save_match='gui') or no_match()
|
|
||||||
for fname, syntax in files.iteritems():
|
for fname, syntax in files.iteritems():
|
||||||
if fname in editors:
|
ed = editors.get(fname, None)
|
||||||
if not editors[fname].find(pat, complete=True, save_match='gui'):
|
if ed is not None:
|
||||||
|
if not wrap and ed is editor:
|
||||||
continue
|
continue
|
||||||
|
if ed.find(p, complete=True, save_match='gui'):
|
||||||
return show_editor(fname)
|
return show_editor(fname)
|
||||||
|
else:
|
||||||
raw = current_container().raw_data(fname)
|
raw = current_container().raw_data(fname)
|
||||||
if pat.search(raw) is not None:
|
if p.search(raw) is not None:
|
||||||
edit_file(fname, syntax)
|
edit_file(fname, syntax)
|
||||||
if editors[fname].find(pat, complete=True, save_match='gui'):
|
if editors[fname].find(p, complete=True, save_match='gui'):
|
||||||
return
|
return
|
||||||
return no_match()
|
return no_match()
|
||||||
|
|
||||||
@ -792,13 +805,14 @@ def run_search(
|
|||||||
def do_replace():
|
def do_replace():
|
||||||
if editor is None:
|
if editor is None:
|
||||||
return no_replace()
|
return no_replace()
|
||||||
if not editor.replace(pat, state['replace'], saved_match='gui'):
|
for p, repl in searches:
|
||||||
|
if editor.replace(p, repl, saved_match='gui'):
|
||||||
|
return True
|
||||||
return no_replace(_(
|
return no_replace(_(
|
||||||
'Currently selected text does not match the search query.'))
|
'Currently selected text does not match the search query.'))
|
||||||
return True
|
|
||||||
|
|
||||||
def count_message(action, count, show_diff=False):
|
def count_message(action, count, show_diff=False):
|
||||||
msg = _('%(action)s %(num)s occurrences of %(query)s' % dict(num=count, query=state['find'], action=action))
|
msg = _('%(action)s %(num)s occurrences of %(query)s' % dict(num=count, query=errfind, action=action))
|
||||||
if show_diff and count > 0:
|
if show_diff and count > 0:
|
||||||
d = MessageBox(MessageBox.INFO, _('Searching done'), prepare_string_for_xml(msg), parent=gui_parent, show_copy_button=False)
|
d = MessageBox(MessageBox.INFO, _('Searching done'), prepare_string_for_xml(msg), parent=gui_parent, show_copy_button=False)
|
||||||
d.diffb = b = d.bb.addButton(_('See what &changed'), d.bb.ActionRole)
|
d.diffb = b = d.bb.addButton(_('See what &changed'), d.bb.ActionRole)
|
||||||
@ -813,18 +827,29 @@ def run_search(
|
|||||||
if not files and editor is None:
|
if not files and editor is None:
|
||||||
return 0
|
return 0
|
||||||
lfiles = files or {current_editor_name:editor.syntax}
|
lfiles = files or {current_editor_name:editor.syntax}
|
||||||
|
updates = set()
|
||||||
|
raw_data = {}
|
||||||
for n, syntax in lfiles.iteritems():
|
for n, syntax in lfiles.iteritems():
|
||||||
if n in editors:
|
if n in editors:
|
||||||
raw = editors[n].get_raw_data()
|
raw = editors[n].get_raw_data()
|
||||||
else:
|
else:
|
||||||
raw = current_container().raw_data(n)
|
raw = current_container().raw_data(n)
|
||||||
|
raw_data[n] = raw
|
||||||
|
|
||||||
|
for p, repl in searches:
|
||||||
|
for n, syntax in lfiles.iteritems():
|
||||||
|
raw = raw_data[n]
|
||||||
if replace:
|
if replace:
|
||||||
raw, num = pat.subn(state['replace'], raw)
|
raw, num = p.subn(repl, raw)
|
||||||
|
if num > 0:
|
||||||
|
updates.add(n)
|
||||||
|
raw_data[n] = raw
|
||||||
else:
|
else:
|
||||||
num = len(pat.findall(raw))
|
num = len(p.findall(raw))
|
||||||
count += num
|
count += num
|
||||||
if replace and num > 0:
|
|
||||||
|
for n in updates:
|
||||||
|
raw = raw_data[n]
|
||||||
if n in editors:
|
if n in editors:
|
||||||
editors[n].replace_data(raw)
|
editors[n].replace_data(raw)
|
||||||
else:
|
else:
|
||||||
@ -843,7 +868,7 @@ def run_search(
|
|||||||
return do_find()
|
return do_find()
|
||||||
if action == 'replace-all':
|
if action == 'replace-all':
|
||||||
if marked:
|
if marked:
|
||||||
return count_message(_('Replaced'), editor.all_in_marked(pat, state['replace']))
|
return count_message(_('Replaced'), sum(editor.all_in_marked(p, repl) for p, repl in searches))
|
||||||
add_savepoint(_('Before: Replace all'))
|
add_savepoint(_('Before: Replace all'))
|
||||||
count = do_all()
|
count = do_all()
|
||||||
if count == 0:
|
if count == 0:
|
||||||
@ -853,7 +878,7 @@ def run_search(
|
|||||||
return
|
return
|
||||||
if action == 'count':
|
if action == 'count':
|
||||||
if marked:
|
if marked:
|
||||||
return count_message(_('Found'), editor.all_in_marked(pat))
|
return count_message(_('Found'), sum(editor.all_in_marked(p) for p, __ in searches))
|
||||||
return do_all(replace=False)
|
return do_all(replace=False)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
Loading…
x
Reference in New Issue
Block a user