mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Finding in the current file works
This commit is contained in:
parent
45b1c409e6
commit
dfb16c58a6
@ -313,6 +313,13 @@ class Boss(QObject):
|
||||
else:
|
||||
pass # marked text TODO: Implement this
|
||||
|
||||
pat = sp.get_regex(state)
|
||||
if action == 'find':
|
||||
found = editor.find(pat)
|
||||
if found:
|
||||
return
|
||||
# TODO: Handle wrapping, depending on state['where']
|
||||
|
||||
def save_book(self):
|
||||
c = current_container()
|
||||
for name, ed in editors.iteritems():
|
||||
|
@ -9,6 +9,7 @@ __copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
import textwrap
|
||||
from future_builtins import map
|
||||
|
||||
import regex
|
||||
from PyQt4.Qt import (
|
||||
QPlainTextEdit, QFontDatabase, QToolTip, QPalette, QFont,
|
||||
QTextEdit, QTextFormat, QWidget, QSize, QPainter, Qt, QRect)
|
||||
@ -20,6 +21,8 @@ from calibre.gui2.tweak_book.editor.syntax.base import SyntaxHighlighter
|
||||
from calibre.gui2.tweak_book.editor.syntax.html import HTMLHighlighter, XMLHighlighter
|
||||
from calibre.gui2.tweak_book.editor.syntax.css import CSSHighlighter
|
||||
|
||||
PARAGRAPH_SEPARATOR = '\u2029'
|
||||
|
||||
_dff = None
|
||||
def default_font_family():
|
||||
global _dff
|
||||
@ -151,6 +154,40 @@ class TextEdit(QPlainTextEdit):
|
||||
self.current_search_mark = None
|
||||
self.update_extra_selections()
|
||||
|
||||
def find(self, pat):
|
||||
reverse = pat.flags & regex.REVERSE
|
||||
c = self.textCursor()
|
||||
c.clearSelection()
|
||||
c.movePosition(c.Start if reverse else c.End, c.KeepAnchor)
|
||||
raw = unicode(c.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n')
|
||||
m = pat.search(raw)
|
||||
if m is None:
|
||||
return False
|
||||
start, end = m.span()
|
||||
if start == end:
|
||||
return False
|
||||
if reverse:
|
||||
# Put the cursor at the start of the match
|
||||
start, end = end, start
|
||||
else:
|
||||
textpos = c.anchor()
|
||||
start, end = textpos + start, textpos + end
|
||||
c.clearSelection()
|
||||
c.setPosition(start)
|
||||
c.setPosition(end, c.KeepAnchor)
|
||||
self.setTextCursor(c)
|
||||
return True
|
||||
|
||||
def replace(self, pat, template):
|
||||
c = self.textCursor()
|
||||
raw = unicode(c.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n')
|
||||
m = pat.fullmatch(raw)
|
||||
if m is None:
|
||||
return False
|
||||
text = m.expand(template)
|
||||
c.insertText(text)
|
||||
return True
|
||||
|
||||
# Line numbers and cursor line {{{
|
||||
def highlight_cursor_line(self):
|
||||
sel = QTextEdit.ExtraSelection()
|
||||
|
@ -70,6 +70,12 @@ class Editor(QMainWindow):
|
||||
def mark_selected_text(self):
|
||||
self.editor.mark_selected_text()
|
||||
|
||||
def find(self, *args, **kwargs):
|
||||
return self.editor.find(*args, **kwargs)
|
||||
|
||||
def replace(self, *args, **kwargs):
|
||||
return self.editor.replace(*args, **kwargs)
|
||||
|
||||
@property
|
||||
def has_marked_text(self):
|
||||
return self.editor.current_search_mark is not None
|
||||
|
@ -12,7 +12,7 @@ from PyQt4.Qt import (
|
||||
|
||||
import regex
|
||||
|
||||
from calibre.gui2.widgets import HistoryLineEdit
|
||||
from calibre.gui2.widgets2 import HistoryLineEdit2
|
||||
from calibre.gui2.tweak_book import tprefs
|
||||
|
||||
REGEX_FLAGS = regex.VERSION1 | regex.WORD | regex.FULLCASE | regex.MULTILINE | regex.UNICODE
|
||||
@ -46,15 +46,16 @@ class SearchWidget(QWidget):
|
||||
|
||||
self.fl = fl = QLabel(_('&Find:'))
|
||||
fl.setAlignment(Qt.AlignRight | Qt.AlignCenter)
|
||||
self.find_text = ft = HistoryLineEdit(self)
|
||||
self.find_text = ft = HistoryLineEdit2(self)
|
||||
ft.initialize('tweak_book_find_edit')
|
||||
ft.returnPressed.connect(lambda : self.search_triggered.emit('find'))
|
||||
fl.setBuddy(ft)
|
||||
l.addWidget(fl, 0, 0)
|
||||
l.addWidget(ft, 0, 1)
|
||||
|
||||
self.rl = rl = QLabel(_('&Replace:'))
|
||||
rl.setAlignment(Qt.AlignRight | Qt.AlignCenter)
|
||||
self.replace_text = rt = HistoryLineEdit(self)
|
||||
self.replace_text = rt = HistoryLineEdit2(self)
|
||||
rt.initialize('tweak_book_replace_edit')
|
||||
rl.setBuddy(rt)
|
||||
l.addWidget(rl, 1, 0)
|
||||
@ -153,7 +154,7 @@ class SearchWidget(QWidget):
|
||||
@dynamic_property
|
||||
def find(self):
|
||||
def fget(self):
|
||||
return unicode(self.find_text.text()).strip()
|
||||
return unicode(self.find_text.text())
|
||||
def fset(self, val):
|
||||
self.find_text.setText(val)
|
||||
return property(fget=fget, fset=fset)
|
||||
@ -161,7 +162,7 @@ class SearchWidget(QWidget):
|
||||
@dynamic_property
|
||||
def replace(self):
|
||||
def fget(self):
|
||||
return unicode(self.replace_text.text()).strip()
|
||||
return unicode(self.replace_text.text())
|
||||
def fset(self, val):
|
||||
self.replace_text.setText(val)
|
||||
return property(fget=fget, fset=fset)
|
||||
@ -227,6 +228,8 @@ class SearchWidget(QWidget):
|
||||
|
||||
# }}}
|
||||
|
||||
regex_cache = {}
|
||||
|
||||
class SearchPanel(QWidget):
|
||||
|
||||
search_triggered = pyqtSignal(object)
|
||||
@ -266,3 +269,19 @@ class SearchPanel(QWidget):
|
||||
def set_where(self, val):
|
||||
self.widget.where = val
|
||||
|
||||
def get_regex(self, state):
|
||||
raw = state['find']
|
||||
if state['mode'] != 'regex':
|
||||
raw = regex.escape(raw, special_only=True)
|
||||
flags = REGEX_FLAGS
|
||||
if not state['case_sensitive']:
|
||||
flags |= regex.IGNORECASE
|
||||
if state['mode'] == 'regex' and state['dot_all']:
|
||||
flags |= regex.DOTALL
|
||||
if state['direction'] == 'up':
|
||||
flags |= regex.REVERSE
|
||||
ans = regex_cache.get((flags, raw), None)
|
||||
if ans is None:
|
||||
ans = regex_cache[(flags, raw)] = regex.compile(raw, flags=flags)
|
||||
return ans
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user