mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Edit Book: Spell check dialog: Add a button to undo the last spelling change
This commit is contained in:
parent
155c35f765
commit
02b8f775cb
@ -221,7 +221,7 @@ def replace(text, original_word, new_word, lang):
|
||||
text = text[:idx] + new_word + text[idx+len(original_word):]
|
||||
return text, bool(indices)
|
||||
|
||||
def replace_word(container, new_word, locations, locale):
|
||||
def replace_word(container, new_word, locations, locale, undo_cache=None):
|
||||
changed = set()
|
||||
for loc in locations:
|
||||
node = loc.location_node
|
||||
@ -231,16 +231,26 @@ def replace_word(container, new_word, locations, locale):
|
||||
else:
|
||||
text = getattr(node, attr)
|
||||
replacement = loc.elided_prefix + new_word
|
||||
text, replaced = replace(text, loc.original_word, replacement, locale.langcode)
|
||||
rtext, replaced = replace(text, loc.original_word, replacement, locale.langcode)
|
||||
if replaced:
|
||||
if undo_cache is not None:
|
||||
undo_cache[(loc.file_name, node, is_attr, attr)] = text
|
||||
if is_attr:
|
||||
node.set(attr, text)
|
||||
node.set(attr, rtext)
|
||||
else:
|
||||
setattr(node, attr, text)
|
||||
setattr(node, attr, rtext)
|
||||
container.replace(loc.file_name, node.getroottree().getroot())
|
||||
changed.add(loc.file_name)
|
||||
return changed
|
||||
|
||||
def undo_replace_word(container, undo_cache):
|
||||
changed = set()
|
||||
for (file_name, node, is_attr, attr), text in undo_cache.iteritems():
|
||||
node.set(attr, text) if is_attr else setattr(node, attr, text)
|
||||
container.replace(file_name, node.getroottree().getroot())
|
||||
changed.add(file_name)
|
||||
return changed
|
||||
|
||||
if __name__ == '__main__':
|
||||
import pprint
|
||||
from calibre.gui2.tweak_book import set_book_locale, dictionaries
|
||||
|
@ -20,7 +20,7 @@ from PyQt5.Qt import (
|
||||
QT_VERSION_STR)
|
||||
|
||||
from calibre.constants import __appname__, plugins
|
||||
from calibre.ebooks.oeb.polish.spell import replace_word, get_all_words, merge_locations, get_checkable_file_names
|
||||
from calibre.ebooks.oeb.polish.spell import replace_word, get_all_words, merge_locations, get_checkable_file_names, undo_replace_word
|
||||
from calibre.gui2 import choose_files, error_dialog
|
||||
from calibre.gui2.complete2 import LineEdit
|
||||
from calibre.gui2.languages import LanguagesEdit
|
||||
@ -883,6 +883,7 @@ class SpellCheck(Dialog):
|
||||
Dialog.__init__(self, _('Check spelling'), 'spell-check', parent)
|
||||
self.work_finished.connect(self.work_done, type=Qt.QueuedConnection)
|
||||
self.setAttribute(Qt.WA_DeleteOnClose, False)
|
||||
self.undo_cache = {}
|
||||
|
||||
def setup_ui(self):
|
||||
self.state_name = 'spell-check-table-state-' + QT_VERSION_STR.partition('.')[0]
|
||||
@ -899,6 +900,10 @@ class SpellCheck(Dialog):
|
||||
b.setToolTip('<p>' + _('Re-scan the book for words, useful if you have edited the book since opening this dialog'))
|
||||
b.setIcon(QIcon(I('view-refresh.png')))
|
||||
b.clicked.connect(partial(self.refresh, change_request=None))
|
||||
b = self.bb.addButton(_('&Undo last change'), self.bb.ActionRole)
|
||||
b.setToolTip('<p>' + _('Undo the last spell check word replacement, if any'))
|
||||
b.setIcon(QIcon(I('edit-undo.png')))
|
||||
b.clicked.connect(self.undo_last_change)
|
||||
|
||||
self.progress = p = QWidget(self)
|
||||
s.addWidget(p)
|
||||
@ -1110,7 +1115,8 @@ class SpellCheck(Dialog):
|
||||
self.change_requested.emit(w, new_word)
|
||||
|
||||
def do_change_word(self, w, new_word):
|
||||
changed_files = replace_word(current_container(), new_word, self.words_model.words[w], w[1])
|
||||
self.undo_cache.clear()
|
||||
changed_files = replace_word(current_container(), new_word, self.words_model.words[w], w[1], undo_cache=self.undo_cache)
|
||||
if changed_files:
|
||||
self.word_replaced.emit(changed_files)
|
||||
w = self.words_model.replace_word(w, new_word)
|
||||
@ -1118,6 +1124,16 @@ class SpellCheck(Dialog):
|
||||
if row > -1:
|
||||
self.words_view.highlight_row(row)
|
||||
|
||||
def undo_last_change(self):
|
||||
if not self.undo_cache:
|
||||
return error_dialog(self, _('No changed word'), _(
|
||||
'There is no spelling replacement to undo'), show=True)
|
||||
changed_files = undo_replace_word(current_container(), self.undo_cache)
|
||||
self.undo_cache.clear()
|
||||
if changed_files:
|
||||
self.word_replaced.emit(changed_files)
|
||||
self.refresh()
|
||||
|
||||
def toggle_ignore(self):
|
||||
current = self.words_view.currentIndex()
|
||||
if current.isValid():
|
||||
|
Loading…
x
Reference in New Issue
Block a user