update find&replace in browser

sadly the UI still stutters on large selections - the calls
to get the selected rows from Qt are really slow.
This commit is contained in:
Damien Elmes 2020-05-05 22:14:12 +10:00
parent 8b557ec382
commit 1852e32183
3 changed files with 52 additions and 30 deletions

View File

@ -111,6 +111,10 @@ class DeckIsFilteredError(Exception):
pass
class InvalidInput(StringError):
pass
def proto_exception_to_native(err: pb.BackendError) -> Exception:
val = err.WhichOneof("value")
if val == "interrupted":
@ -126,7 +130,7 @@ def proto_exception_to_native(err: pb.BackendError) -> Exception:
elif val == "template_parse":
return TemplateError(err.localized)
elif val == "invalid_input":
return StringError(err.localized)
return InvalidInput(err.localized)
elif val == "json_error":
return StringError(err.localized)
elif val == "not_found_error":
@ -747,7 +751,8 @@ class RustBackend:
def field_names_for_note_ids(self, nids: List[int]) -> Sequence[str]:
return self._run_command(
pb.BackendInput(field_names_for_notes=pb.FieldNamesForNotesIn(nids=nids))
pb.BackendInput(field_names_for_notes=pb.FieldNamesForNotesIn(nids=nids)),
release_gil=True,
).field_names_for_notes.fields
def find_and_replace(
@ -769,7 +774,8 @@ class RustBackend:
match_case=not nocase,
field_name=field_name,
)
)
),
release_gil=True,
).find_and_replace

View File

@ -24,7 +24,7 @@ from anki.decks import DeckManager
from anki.lang import _, ngettext
from anki.models import NoteType
from anki.notes import Note
from anki.rsbackend import TR, DeckTreeNode
from anki.rsbackend import TR, DeckTreeNode, InvalidInput
from anki.utils import htmlToTextLine, ids2str, intTime, isMac, isWin
from aqt import AnkiQt, gui_hooks
from aqt.editor import Editor
@ -1926,13 +1926,21 @@ update cards set usn=?, mod=?, did=? where id in """
def onFindReplace(self):
self.editor.saveNow(self._onFindReplace)
def _onFindReplace(self):
sf = self.selectedNotes()
if not sf:
def _onFindReplace(self) -> None:
nids = self.selectedNotes()
if not nids:
return
import anki.find
fields = anki.find.fieldNamesForNotes(self.mw.col, sf)
def find():
return anki.find.fieldNamesForNotes(self.mw.col, nids)
def on_done(fut):
self._on_find_replace_diag(fut.result(), nids)
self.mw.taskman.with_progress(find, on_done, self)
def _on_find_replace_diag(self, fields: List[str], nids: List[int]) -> None:
d = QDialog(self)
frm = aqt.forms.findreplace.Ui_Dialog()
frm.setupUi(d)
@ -1948,34 +1956,38 @@ update cards set usn=?, mod=?, did=? where id in """
field = None
else:
field = fields[frm.field.currentIndex() - 1]
search = frm.find.text()
replace = frm.replace.text()
regex = frm.re.isChecked()
nocase = frm.ignoreCase.isChecked()
self.mw.checkpoint(_("Find and Replace"))
self.mw.progress.start()
# starts progress dialog as well
self.model.beginReset()
try:
changed = self.col.findReplace(
sf,
str(frm.find.text()),
str(frm.replace.text()),
frm.re.isChecked(),
field,
frm.ignoreCase.isChecked(),
)
except sre_constants.error:
showInfo(_("Invalid regular expression."), parent=self)
return
else:
def do_search():
return self.col.findReplace(nids, search, replace, regex, field, nocase)
def on_done(fut):
self.search()
self.mw.requireReset()
finally:
self.model.endReset()
self.mw.progress.finish()
showInfo(
ngettext(
"%(a)d of %(b)d note updated", "%(a)d of %(b)d notes updated", len(sf)
total = len(nids)
try:
changed = fut.result()
except InvalidInput as e:
# failed regex
showWarning(str(e))
return
showInfo(
tr(TR.FINDREPLACE_NOTES_UPDATED, changed=changed, total=total),
parent=self,
)
% {"a": changed, "b": len(sf),},
parent=self,
)
self.mw.taskman.run_in_background(do_search, on_done)
def onFindReplaceHelp(self):
openHelp("findreplace")

View File

@ -0,0 +1,4 @@
findreplace-notes-updated = { $total ->
[one] {$changed} of {$total} note updated
*[other] {$changed} of {$total} notes updated
}