mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 18:54:09 -04:00
Allow S&R funcs to specify they would like to be called once after all matches are found
This commit is contained in:
parent
cf42295fc5
commit
47b0baae85
@ -343,7 +343,15 @@ class TextEdit(PlainTextEdit):
|
||||
if template is None:
|
||||
count = len(pat.findall(raw))
|
||||
else:
|
||||
from calibre.gui2.tweak_book.function_replace import Function
|
||||
repl_is_func = isinstance(template, Function)
|
||||
if repl_is_func:
|
||||
template.init_env()
|
||||
raw, count = pat.subn(template, raw)
|
||||
if repl_is_func:
|
||||
from calibre.gui2.tweak_book.search import show_function_debug_output
|
||||
show_function_debug_output(template)
|
||||
template.end()
|
||||
if count > 0:
|
||||
start_pos = min(c.anchor(), c.position())
|
||||
c.insertText(raw)
|
||||
|
@ -11,7 +11,7 @@ from cStringIO import StringIO
|
||||
|
||||
from PyQt5.Qt import (
|
||||
pyqtSignal, QVBoxLayout, QHBoxLayout, QPlainTextEdit, QLabel, QFontMetrics,
|
||||
QSize, Qt)
|
||||
QSize, Qt, QApplication, QIcon)
|
||||
|
||||
from calibre.ebooks.oeb.polish.utils import apply_func_to_match_groups
|
||||
from calibre.gui2 import error_dialog
|
||||
@ -89,6 +89,14 @@ class Function(object):
|
||||
return json.loads(P('editor-functions.json', data=True, allow_user_override=False))[self.name]
|
||||
return self._source
|
||||
|
||||
def end(self):
|
||||
if getattr(self.func, 'call_after_last_match', False):
|
||||
oo, oe, sys.stdout, sys.stderr = sys.stdout, sys.stderr, self.debug_buf, self.debug_buf
|
||||
try:
|
||||
return self.func(None, self.match_index, self.context_name, self.boss.current_metadata, dictionaries, self.data, functions())
|
||||
finally:
|
||||
sys.stdout, sys.stderr = oo, oe
|
||||
|
||||
class DebugOutput(Dialog):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
@ -98,13 +106,18 @@ class DebugOutput(Dialog):
|
||||
def setup_ui(self):
|
||||
self.l = l = QVBoxLayout(self)
|
||||
self.text = t = QPlainTextEdit(self)
|
||||
self.log_text = ''
|
||||
l.addWidget(t)
|
||||
l.addWidget(self.bb)
|
||||
self.bb.setStandardButtons(self.bb.Close)
|
||||
self.cb = b = self.bb.addButton(_('&Copy to clipboard'), self.bb.ActionRole)
|
||||
b.clicked.connect(self.copy_to_clipboard)
|
||||
b.setIcon(QIcon(I('edit-copy.png')))
|
||||
|
||||
def show_log(self, name, text):
|
||||
self.setWindowTitle(_('Debug output from %s') % name)
|
||||
self.text.setPlainText(self.windowTitle() + '\n\n' + text)
|
||||
self.log_text = text
|
||||
self.show()
|
||||
self.raise_()
|
||||
|
||||
@ -112,6 +125,9 @@ class DebugOutput(Dialog):
|
||||
fm = QFontMetrics(self.text.font())
|
||||
return QSize(fm.averageCharWidth() * 120, 400)
|
||||
|
||||
def copy_to_clipboard(self):
|
||||
QApplication.instance().clipboard().setText(self.log_text)
|
||||
|
||||
def builtin_functions():
|
||||
for name, obj in globals().iteritems():
|
||||
if name.startswith('replace_') and callable(obj):
|
||||
@ -300,7 +316,6 @@ def replace_swapcase(match, number, file_name, metadata, dictionaries, data, fun
|
||||
return apply_func_to_match_groups(match, swapcase)
|
||||
|
||||
if __name__ == '__main__':
|
||||
from PyQt5.Qt import QApplication
|
||||
app = QApplication([])
|
||||
FunctionEditor().exec_()
|
||||
del app
|
||||
|
@ -1262,10 +1262,13 @@ def run_search(
|
||||
if editor is None:
|
||||
return no_replace()
|
||||
for p, repl in searches:
|
||||
if callable(repl):
|
||||
repl_is_func = isinstance(repl, Function)
|
||||
if repl_is_func:
|
||||
repl.init_env(current_editor_name)
|
||||
if editor.replace(p, repl, saved_match='gui'):
|
||||
show_function_debug_output(repl)
|
||||
if repl_is_func:
|
||||
repl.end()
|
||||
show_function_debug_output(repl)
|
||||
return True
|
||||
return no_replace(_(
|
||||
'Currently selected text does not match the search query.'))
|
||||
@ -1296,12 +1299,13 @@ def run_search(
|
||||
raw_data[n] = raw
|
||||
|
||||
for p, repl in searches:
|
||||
if callable(repl):
|
||||
repl_is_func = isinstance(repl, Function)
|
||||
if repl_is_func:
|
||||
repl.init_env()
|
||||
for n, syntax in lfiles.iteritems():
|
||||
raw = raw_data[n]
|
||||
if replace:
|
||||
if callable(repl):
|
||||
if repl_is_func:
|
||||
repl.context_name = n
|
||||
raw, num = p.subn(repl, raw)
|
||||
if num > 0:
|
||||
@ -1310,7 +1314,9 @@ def run_search(
|
||||
else:
|
||||
num = len(p.findall(raw))
|
||||
count += num
|
||||
show_function_debug_output(repl)
|
||||
if repl_is_func:
|
||||
repl.end()
|
||||
show_function_debug_output(repl)
|
||||
|
||||
for n in updates:
|
||||
raw = raw_data[n]
|
||||
|
Loading…
x
Reference in New Issue
Block a user