Start work on search panel

This commit is contained in:
Kovid Goyal 2020-01-18 19:15:27 +05:30
parent 90eb2c43f0
commit 8db373d3b5
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
6 changed files with 128 additions and 3 deletions

View File

@ -140,8 +140,8 @@ class SearchBox2(QComboBox): # {{{
icon = QIcon(I(icon))
return self.lineEdit().addAction(icon, position)
def initialize(self, opt_name, colorize=False, help_text=_('Search')):
self.as_you_type = config['search_as_you_type']
def initialize(self, opt_name, colorize=False, help_text=_('Search'), as_you_type=None):
self.as_you_type = config['search_as_you_type'] if as_you_type is None else as_you_type
self.opt_name = opt_name
items = []
for item in config[opt_name]:

View File

@ -0,0 +1,107 @@
#!/usr/bin/env python2
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
from __future__ import absolute_import, division, print_function, unicode_literals
import textwrap
from collections import namedtuple
from PyQt5.Qt import (
QCheckBox, QComboBox, QHBoxLayout, QIcon, Qt, QToolButton, QVBoxLayout, QWidget,
pyqtSignal
)
from calibre.gui2.viewer.web_view import vprefs
from calibre.gui2.widgets2 import HistoryComboBox
Search = namedtuple('Search', 'text mode case_sensitive backwards')
class SearchInput(QWidget):
do_search = pyqtSignal(object)
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.l = l = QVBoxLayout(self)
l.setContentsMargins(0, 0, 0, 0)
h = QHBoxLayout()
h.setContentsMargins(0, 0, 0, 0)
l.addLayout(h)
self.search_box = sb = HistoryComboBox(self)
sb.lineEdit().setPlaceholderText(_('Search'))
sb.lineEdit().setClearButtonEnabled(True)
sb.lineEdit().returnPressed.connect(self.find_next)
sb.initialize('viewer-search-box-history')
h.addWidget(sb)
self.next_button = nb = QToolButton(self)
h.addWidget(nb)
nb.setFocusPolicy(Qt.NoFocus)
nb.setIcon(QIcon(I('arrow-down.png')))
nb.clicked.connect(self.find_next)
nb.setToolTip(_('Find next match'))
self.prev_button = nb = QToolButton(self)
h.addWidget(nb)
nb.setFocusPolicy(Qt.NoFocus)
nb.setIcon(QIcon(I('arrow-up.png')))
nb.clicked.connect(self.find_previous)
nb.setToolTip(_('Find previous match'))
h = QHBoxLayout()
h.setContentsMargins(0, 0, 0, 0)
l.addLayout(h)
self.query_type = qt = QComboBox(self)
qt.setFocusPolicy(Qt.NoFocus)
qt.addItem(_('Normal'), 'normal')
qt.addItem(_('Regex'), 'regex')
qt.setToolTip(textwrap.fill(_('Choose the type of search: Normal will search'
' for the entered text, Regex will interpret the text as a'
' regular expression')))
qt.setCurrentIndex(qt.findData(vprefs.get('viewer-search-mode', 'normal') or 'normal'))
h.addWidget(qt)
self.case_sensitive = cs = QCheckBox(_('Case sensitive'), self)
cs.setFocusPolicy(Qt.NoFocus)
cs.setChecked(bool(vprefs.get('viewer-search-case-sensitive', False)))
h.addWidget(cs)
def search_query(self, backwards=False):
text = self.search_box.currentText().strip()
if text:
return Search(text, self.query_type.currentData() or 'normal', self.case_sensitive.isChecked(), backwards)
def emit_search(self, backwards=False):
vprefs['viewer-search-case-sensitive'] = self.case_sensitive.isChecked()
vprefs['viewer-search-mode'] = self.query_type.currentData()
sq = self.search_query(backwards)
if sq is not None:
self.do_search.emit(sq)
def find_next(self):
self.emit_search()
def find_previous(self):
self.emit_search(backwards=True)
def focus_input(self):
self.search_box.setFocus(Qt.OtherFocusReason)
le = self.search_box.lineEdit()
le.end(False)
le.selectAll()
class SearchPanel(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.l = l = QVBoxLayout(self)
self.search_input = si = SearchInput(self)
l.addWidget(si)
l.addStretch(10)
def focus_input(self):
self.search_input.focus_input()

View File

@ -33,6 +33,7 @@ from calibre.gui2.viewer.convert_book import (
)
from calibre.gui2.viewer.lookup import Lookup
from calibre.gui2.viewer.overlay import LoadingOverlay
from calibre.gui2.viewer.search import SearchPanel
from calibre.gui2.viewer.toc import TOC, TOCSearch, TOCView
from calibre.gui2.viewer.toolbars import ActionsToolBar
from calibre.gui2.viewer.web_view import (
@ -68,6 +69,7 @@ def dock_defs():
d(_('Table of Contents'), 'toc', Qt.LeftDockWidgetArea),
d(_('Lookup'), 'lookup', Qt.RightDockWidgetArea),
d(_('Bookmarks'), 'bookmarks', Qt.RightDockWidgetArea)
d(_('Search'), 'search', Qt.LeftDockWidgetArea)
d(_('Inspector'), 'inspector', Qt.RightDockWidgetArea, Qt.AllDockWidgetAreas)
return ans
@ -134,6 +136,9 @@ class EbookViewer(MainWindow):
w.l.addWidget(self.toc), w.l.addWidget(self.toc_search), w.l.setContentsMargins(0, 0, 0, 0)
self.toc_dock.setWidget(w)
self.search_widget = w = SearchPanel(self)
self.search_dock.setWidget(w)
self.lookup_widget = w = Lookup(self)
self.lookup_dock.visibilityChanged.connect(self.lookup_widget.visibility_changed)
self.lookup_dock.setWidget(w)
@ -151,6 +156,7 @@ class EbookViewer(MainWindow):
self.web_view.cfi_changed.connect(self.cfi_changed)
self.web_view.reload_book.connect(self.reload_book)
self.web_view.toggle_toc.connect(self.toggle_toc)
self.web_view.show_search.connect(self.show_search)
self.web_view.toggle_bookmarks.connect(self.toggle_bookmarks)
self.web_view.toggle_inspector.connect(self.toggle_inspector)
self.web_view.toggle_lookup.connect(self.toggle_lookup)
@ -237,6 +243,10 @@ class EbookViewer(MainWindow):
def toggle_toc(self):
self.toc_dock.setVisible(not self.toc_dock.isVisible())
def show_search(self):
self.search_dock.setVisible(True)
self.search_widget.focus_input()
def toggle_bookmarks(self):
is_visible = self.bookmarks_dock.isVisible()
self.bookmarks_dock.setVisible(not is_visible)

View File

@ -244,6 +244,7 @@ class ViewerBridge(Bridge):
toggle_bookmarks = from_js()
toggle_inspector = from_js()
toggle_lookup = from_js()
show_search = from_js()
quit = from_js()
update_current_toc_nodes = from_js(object, object)
toggle_full_screen = from_js()
@ -412,6 +413,7 @@ class WebView(RestartingWebEngineView):
cfi_changed = pyqtSignal(object)
reload_book = pyqtSignal()
toggle_toc = pyqtSignal()
show_search = pyqtSignal()
toggle_bookmarks = pyqtSignal()
toggle_inspector = pyqtSignal()
toggle_lookup = pyqtSignal()
@ -455,6 +457,7 @@ class WebView(RestartingWebEngineView):
self.bridge.set_local_storage.connect(self.set_local_storage)
self.bridge.reload_book.connect(self.reload_book)
self.bridge.toggle_toc.connect(self.toggle_toc)
self.bridge.show_search.connect(self.show_search)
self.bridge.toggle_bookmarks.connect(self.toggle_bookmarks)
self.bridge.toggle_inspector.connect(self.toggle_inspector)
self.bridge.toggle_lookup.connect(self.toggle_lookup)

View File

@ -529,6 +529,9 @@ class View:
def show_search(self):
self.hide_overlays()
if runtime.is_standalone_viewer:
ui_operations.show_search()
else:
self.search_overlay.show()
def show_content_popup(self):

View File

@ -339,6 +339,8 @@ if window is window.top:
to_python.toggle_inspector()
ui_operations.content_file_changed = def(name):
to_python.content_file_changed(name)
ui_operations.show_search = def():
to_python.show_search()
ui_operations.reset_interface = def():
sd = get_session_data()
defaults = session_defaults()