mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Enable use of snippets in the search/replace panel and the saved searches dialog
This commit is contained in:
parent
3a30197900
commit
a4a8625783
@ -326,9 +326,9 @@ def expand_template(editor, trigger, template):
|
|||||||
c.endEditBlock()
|
c.endEditBlock()
|
||||||
return tl
|
return tl
|
||||||
|
|
||||||
def find_matching_snip(text, syntax):
|
def find_matching_snip(text, syntax=None):
|
||||||
for key, snip in snippets().iteritems():
|
for key, snip in snippets().iteritems():
|
||||||
if text.endswith(key.trigger) and syntax in key.syntaxes:
|
if text.endswith(key.trigger) and (syntax in key.syntaxes or syntax is None):
|
||||||
return snip, key.trigger
|
return snip, key.trigger
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
@ -393,7 +393,6 @@ class SnippetManager(QObject):
|
|||||||
return False
|
return False
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
# Config {{{
|
# Config {{{
|
||||||
|
|
||||||
class EditSnippet(QWidget):
|
class EditSnippet(QWidget):
|
||||||
|
@ -84,6 +84,7 @@ class PlainTextEdit(QPlainTextEdit):
|
|||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
QPlainTextEdit.__init__(self, parent)
|
QPlainTextEdit.__init__(self, parent)
|
||||||
self.selectionChanged.connect(self.selection_changed)
|
self.selectionChanged.connect(self.selection_changed)
|
||||||
|
self.syntax = None
|
||||||
|
|
||||||
def toPlainText(self):
|
def toPlainText(self):
|
||||||
# QPlainTextEdit's toPlainText implementation replaces nbsp with normal
|
# QPlainTextEdit's toPlainText implementation replaces nbsp with normal
|
||||||
|
@ -14,7 +14,7 @@ from PyQt5.Qt import (
|
|||||||
QWidget, QToolBar, Qt, QHBoxLayout, QSize, QIcon, QGridLayout, QLabel, QTimer,
|
QWidget, QToolBar, Qt, QHBoxLayout, QSize, QIcon, QGridLayout, QLabel, QTimer,
|
||||||
QPushButton, pyqtSignal, QComboBox, QCheckBox, QSizePolicy, QVBoxLayout, QFont,
|
QPushButton, pyqtSignal, QComboBox, QCheckBox, QSizePolicy, QVBoxLayout, QFont,
|
||||||
QLineEdit, QToolButton, QListView, QFrame, QApplication, QStyledItemDelegate,
|
QLineEdit, QToolButton, QListView, QFrame, QApplication, QStyledItemDelegate,
|
||||||
QAbstractListModel, QPlainTextEdit, QModelIndex, QMenu, QItemSelection, QStackedLayout)
|
QAbstractListModel, QModelIndex, QMenu, QItemSelection, QStackedLayout)
|
||||||
|
|
||||||
import regex
|
import regex
|
||||||
|
|
||||||
@ -26,6 +26,8 @@ from calibre.gui2.tweak_book import tprefs, editors, current_container
|
|||||||
from calibre.gui2.tweak_book.function_replace import (
|
from calibre.gui2.tweak_book.function_replace import (
|
||||||
FunctionBox, functions as replace_functions, FunctionEditor, remove_function, Function)
|
FunctionBox, functions as replace_functions, FunctionEditor, remove_function, Function)
|
||||||
from calibre.gui2.tweak_book.widgets import BusyCursor
|
from calibre.gui2.tweak_book.widgets import BusyCursor
|
||||||
|
from calibre.gui2.tweak_book.editor.text import PlainTextEdit
|
||||||
|
from calibre.gui2.tweak_book.editor.snippets import find_matching_snip, parse_template, string_length, SnippetManager
|
||||||
|
|
||||||
from calibre.utils.icu import primary_contains
|
from calibre.utils.icu import primary_contains
|
||||||
|
|
||||||
@ -51,12 +53,42 @@ class AnimatablePushButton(QPushButton):
|
|||||||
self.setDown(False)
|
self.setDown(False)
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
|
class TextEdit(PlainTextEdit):
|
||||||
|
|
||||||
|
def __init__(self, text, parent=None):
|
||||||
|
PlainTextEdit.__init__(self, parent)
|
||||||
|
if text:
|
||||||
|
self.setPlainText(text)
|
||||||
|
self.snippet_manager = SnippetManager(self)
|
||||||
|
|
||||||
|
def keyPressEvent(self, ev):
|
||||||
|
if self.snippet_manager.handle_key_press(ev):
|
||||||
|
return
|
||||||
|
PlainTextEdit.keyPressEvent(self, ev)
|
||||||
|
|
||||||
class PushButton(AnimatablePushButton):
|
class PushButton(AnimatablePushButton):
|
||||||
|
|
||||||
def __init__(self, text, action, parent):
|
def __init__(self, text, action, parent):
|
||||||
AnimatablePushButton.__init__(self, text, parent)
|
AnimatablePushButton.__init__(self, text, parent)
|
||||||
self.clicked.connect(lambda : parent.search_triggered.emit(action))
|
self.clicked.connect(lambda : parent.search_triggered.emit(action))
|
||||||
|
|
||||||
|
def expand_template(line_edit):
|
||||||
|
pos = line_edit.cursorPosition()
|
||||||
|
text = line_edit.text()[:pos]
|
||||||
|
if text:
|
||||||
|
snip, trigger = find_matching_snip(text)
|
||||||
|
if snip is None:
|
||||||
|
error_dialog(line_edit, _('No snippet found'), _(
|
||||||
|
'No matching snippet was found'), show=True)
|
||||||
|
return False
|
||||||
|
text, tab_stops = parse_template(snip['template'])
|
||||||
|
ft = line_edit.text()
|
||||||
|
l = string_length(trigger)
|
||||||
|
line_edit.setText(ft[:pos - l] + text + ft[pos:])
|
||||||
|
line_edit.setCursorPosition(pos - l + string_length(text))
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
class HistoryBox(HistoryComboBox):
|
class HistoryBox(HistoryComboBox):
|
||||||
|
|
||||||
max_history_items = 100
|
max_history_items = 100
|
||||||
@ -67,6 +99,17 @@ class HistoryBox(HistoryComboBox):
|
|||||||
HistoryComboBox.__init__(self, parent)
|
HistoryComboBox.__init__(self, parent)
|
||||||
self.disable_popup = tprefs['disable_completion_popup_for_search']
|
self.disable_popup = tprefs['disable_completion_popup_for_search']
|
||||||
self.clear_msg = clear_msg
|
self.clear_msg = clear_msg
|
||||||
|
self.ignore_snip_expansion = False
|
||||||
|
|
||||||
|
def event(self, ev):
|
||||||
|
if ev.type() in (ev.ShortcutOverride, ev.KeyPress) and ev.key() == Qt.Key_Tab and ev.modifiers() & Qt.CTRL:
|
||||||
|
if not self.ignore_snip_expansion:
|
||||||
|
self.ignore_snip_expansion = True
|
||||||
|
expand_template(self.lineEdit())
|
||||||
|
QTimer.singleShot(100, lambda : setattr(self, 'ignore_snip_expansion', False))
|
||||||
|
ev.accept()
|
||||||
|
return True
|
||||||
|
return HistoryComboBox.event(self, ev)
|
||||||
|
|
||||||
def contextMenuEvent(self, event):
|
def contextMenuEvent(self, event):
|
||||||
menu = self.lineEdit().createStandardContextMenu()
|
menu = self.lineEdit().createStandardContextMenu()
|
||||||
@ -551,12 +594,12 @@ class EditSearch(QFrame): # {{{
|
|||||||
h.addWidget(la), h.addWidget(n)
|
h.addWidget(la), h.addWidget(n)
|
||||||
l.addLayout(h)
|
l.addLayout(h)
|
||||||
|
|
||||||
self.find = f = QPlainTextEdit('', self)
|
self.find = f = TextEdit('', self)
|
||||||
self.la2 = la = QLabel(_('&Find:'))
|
self.la2 = la = QLabel(_('&Find:'))
|
||||||
la.setBuddy(f)
|
la.setBuddy(f)
|
||||||
l.addWidget(la), l.addWidget(f)
|
l.addWidget(la), l.addWidget(f)
|
||||||
|
|
||||||
self.replace = r = QPlainTextEdit('', self)
|
self.replace = r = TextEdit('', self)
|
||||||
self.la3 = la = QLabel(_('&Replace:'))
|
self.la3 = la = QLabel(_('&Replace:'))
|
||||||
la.setBuddy(r)
|
la.setBuddy(r)
|
||||||
l.addWidget(la), l.addWidget(r)
|
l.addWidget(la), l.addWidget(r)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user