mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Edit Book: Fix individual find and replace not working in regex mode if the search expression uses lookbehind/lookahead operators
This commit is contained in:
parent
8f9abe9aa5
commit
3ff7f39b4b
@ -690,21 +690,21 @@ class Boss(QObject):
|
|||||||
|
|
||||||
def do_find():
|
def do_find():
|
||||||
if editor is not None:
|
if editor is not None:
|
||||||
if editor.find(pat, marked=marked):
|
if editor.find(pat, marked=marked, save_match='gui'):
|
||||||
return
|
return
|
||||||
if not files:
|
if not files:
|
||||||
if not state['wrap']:
|
if not state['wrap']:
|
||||||
return no_match()
|
return no_match()
|
||||||
return editor.find(pat, wrap=True, marked=marked) or 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:
|
if fname in editors:
|
||||||
if not editors[fname].find(pat, complete=True):
|
if not editors[fname].find(pat, complete=True, save_match='gui'):
|
||||||
continue
|
continue
|
||||||
return self.show_editor(fname)
|
return self.show_editor(fname)
|
||||||
raw = current_container().raw_data(fname)
|
raw = current_container().raw_data(fname)
|
||||||
if pat.search(raw) is not None:
|
if pat.search(raw) is not None:
|
||||||
self.edit_file(fname, syntax)
|
self.edit_file(fname, syntax)
|
||||||
if editors[fname].find(pat, complete=True):
|
if editors[fname].find(pat, complete=True, save_match='gui'):
|
||||||
return
|
return
|
||||||
return no_match()
|
return no_match()
|
||||||
|
|
||||||
@ -720,7 +720,7 @@ class Boss(QObject):
|
|||||||
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']):
|
if not editor.replace(pat, state['replace'], saved_match='gui'):
|
||||||
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
|
return True
|
||||||
|
@ -115,6 +115,7 @@ class TextEdit(PlainTextEdit):
|
|||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
PlainTextEdit.__init__(self, parent)
|
PlainTextEdit.__init__(self, parent)
|
||||||
|
self.saved_matches = {}
|
||||||
self.smarts = NullSmarts(self)
|
self.smarts = NullSmarts(self)
|
||||||
self.current_cursor_line = None
|
self.current_cursor_line = None
|
||||||
self.current_search_mark = None
|
self.current_search_mark = None
|
||||||
@ -256,7 +257,7 @@ class TextEdit(PlainTextEdit):
|
|||||||
self.current_search_mark = None
|
self.current_search_mark = None
|
||||||
self.update_extra_selections()
|
self.update_extra_selections()
|
||||||
|
|
||||||
def find_in_marked(self, pat, wrap=False):
|
def find_in_marked(self, pat, wrap=False, save_match=None):
|
||||||
if self.current_search_mark is None:
|
if self.current_search_mark is None:
|
||||||
return False
|
return False
|
||||||
csm = self.current_search_mark.cursor
|
csm = self.current_search_mark.cursor
|
||||||
@ -298,6 +299,8 @@ class TextEdit(PlainTextEdit):
|
|||||||
self.setTextCursor(c)
|
self.setTextCursor(c)
|
||||||
# Center search result on screen
|
# Center search result on screen
|
||||||
self.centerCursor()
|
self.centerCursor()
|
||||||
|
if save_match is not None:
|
||||||
|
self.saved_matches[save_match] = m
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def all_in_marked(self, pat, template=None):
|
def all_in_marked(self, pat, template=None):
|
||||||
@ -316,9 +319,9 @@ class TextEdit(PlainTextEdit):
|
|||||||
self.update_extra_selections()
|
self.update_extra_selections()
|
||||||
return count
|
return count
|
||||||
|
|
||||||
def find(self, pat, wrap=False, marked=False, complete=False):
|
def find(self, pat, wrap=False, marked=False, complete=False, save_match=None):
|
||||||
if marked:
|
if marked:
|
||||||
return self.find_in_marked(pat, wrap=wrap)
|
return self.find_in_marked(pat, wrap=wrap, save_match=save_match)
|
||||||
reverse = pat.flags & regex.REVERSE
|
reverse = pat.flags & regex.REVERSE
|
||||||
c = self.textCursor()
|
c = self.textCursor()
|
||||||
c.clearSelection()
|
c.clearSelection()
|
||||||
@ -353,12 +356,23 @@ class TextEdit(PlainTextEdit):
|
|||||||
self.setTextCursor(c)
|
self.setTextCursor(c)
|
||||||
# Center search result on screen
|
# Center search result on screen
|
||||||
self.centerCursor()
|
self.centerCursor()
|
||||||
|
if save_match is not None:
|
||||||
|
self.saved_matches[save_match] = m
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def replace(self, pat, template):
|
def replace(self, pat, template, saved_match='gui'):
|
||||||
c = self.textCursor()
|
c = self.textCursor()
|
||||||
raw = unicode(c.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n')
|
raw = unicode(c.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n')
|
||||||
m = pat.fullmatch(raw)
|
m = pat.fullmatch(raw)
|
||||||
|
if m is None:
|
||||||
|
# This can happen if either the user changed the selected text or
|
||||||
|
# the search expression uses lookahead/lookbehind operators. See if
|
||||||
|
# the saved match matches the currently selected text and
|
||||||
|
# use it, if so.
|
||||||
|
if saved_match is not None and saved_match in self.saved_matches:
|
||||||
|
saved = self.saved_matches.pop(saved_match)
|
||||||
|
if saved.group() == raw:
|
||||||
|
m = saved
|
||||||
if m is None:
|
if m is None:
|
||||||
return False
|
return False
|
||||||
text = m.expand(template)
|
text = m.expand(template)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user