Links to show and mark book in the library

This commit is contained in:
Kovid Goyal 2022-06-09 21:28:28 +05:30
parent 6c51e54d53
commit 55e89079d4
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -8,11 +8,13 @@ import os
import re import re
import traceback import traceback
from contextlib import suppress from contextlib import suppress
from functools import partial
from itertools import count from itertools import count
from qt.core import ( from qt.core import (
QAbstractItemModel, QAbstractItemView, QCheckBox, QDialog, QDialogButtonBox, QAbstractItemModel, QAbstractItemView, QCheckBox, QDialog, QDialogButtonBox,
QFont, QHBoxLayout, QIcon, QLabel, QModelIndex, QPixmap, QPushButton, QRect, QFont, QHBoxLayout, QIcon, QLabel, QMenu, QModelIndex, QPixmap, QPushButton,
QSize, QSplitter, QStackedWidget, Qt, QTreeView, QVBoxLayout, QWidget, pyqtSignal QRect, QSize, QSplitter, QStackedWidget, Qt, QTreeView, QVBoxLayout, QWidget,
pyqtSignal
) )
from threading import Event, Thread from threading import Event, Thread
@ -32,6 +34,18 @@ sanitize_text_pat = re.compile(r'\s+')
fts_url = 'https://www.sqlite.org/fts5.html#full_text_query_syntax' fts_url = 'https://www.sqlite.org/fts5.html#full_text_query_syntax'
def mark_books(*book_ids):
gui = get_gui()
if gui is not None:
gui.iactions['Mark Books'].add_ids(book_ids)
def jump_to_book(book_id):
gui = get_gui()
if gui is not None:
gui.library_view.select_rows((book_id,))
class SearchDelegate(ResultsDelegate): class SearchDelegate(ResultsDelegate):
def result_data(self, result): def result_data(self, result):
@ -322,6 +336,8 @@ class ResultsView(QTreeView):
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.customContextMenuRequested.connect(self.show_context_menu)
self.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection) self.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
self.setHeaderHidden(True) self.setHeaderHidden(True)
self.m = ResultsModel(self) self.m = ResultsModel(self)
@ -355,6 +371,18 @@ class ResultsView(QTreeView):
self.m.search(*a, restrict_to_book_ids=restrict, use_stemming=gprefs['fts_library_use_stemmer']) self.m.search(*a, restrict_to_book_ids=restrict, use_stemming=gprefs['fts_library_use_stemmer'])
self.expandAll() self.expandAll()
def show_context_menu(self, pos):
index = self.indexAt(pos)
results, match = self.m.data_for_index(index)
m = QMenu(self)
if results:
m.addAction(QIcon.ic('auto-scroll.png'), _('Jump to this book in the library'), partial(jump_to_book, results.book_id))
m.addAction(QIcon.ic('marked.png'), _('Mark this book in the library'), partial(mark_books, results.book_id))
m.addSeparator()
m.addAction(QIcon.ic('plus.png'), _('Expand all'), self.expandAll)
m.addAction(QIcon.ic('minus.png'), _('Collapse all'), self.collapseAll)
m.exec(self.mapToGlobal(pos))
class Spinner(ProgressIndicator): class Spinner(ProgressIndicator):
@ -435,9 +463,16 @@ class ResultDetails(QWidget):
self.pixmap_label = pl = QLabel(self) self.pixmap_label = pl = QLabel(self)
pl.setScaledContents(True) pl.setScaledContents(True)
self.current_book_id = -1 self.current_book_id = -1
self.book_info = HTMLDisplay(self) self.book_info = bi = HTMLDisplay(self)
self.book_info.setDefaultStyleSheet('a { text-decoration: none; }') bi.setDefaultStyleSheet('a { text-decoration: none; }')
self.book_info.anchor_clicked.connect(self.mark_current_book) bi.anchor_clicked.connect(self.book_info_anchor_clicked)
def book_info_anchor_clicked(self, url):
if self.current_book_id > 0:
if url.host() == 'mark':
mark_books(self.current_book_id)
elif url.host() == 'jump':
jump_to_book(self.current_book_id)
def resizeEvent(self, ev): def resizeEvent(self, ev):
self.do_layout() self.do_layout()
@ -450,8 +485,11 @@ class ResultDetails(QWidget):
self.pixmap_label.setGeometry(QRect(0, 0, nw, nh)) self.pixmap_label.setGeometry(QRect(0, 0, nw, nh))
w = g.width() - nw - 8 w = g.width() - nw - 8
d = self.book_info.document() d = self.book_info.document()
d.setTextWidth(float(w) - 2 * d.documentMargin()) d.setDocumentMargin(0)
self.book_info.setGeometry(QRect(self.pixmap_label.geometry().right() + 8, 0, w, int(math.ceil(2 * d.documentMargin() + d.size().height())))) d.setTextWidth(float(w))
self.book_info.setGeometry(QRect(self.pixmap_label.geometry().right() + 8, 0, w, int(math.ceil(d.size().height()))))
self.book_info.verticalScrollBar().setVisible(False)
self.book_info.horizontalScrollBar().setVisible(False)
def show_result(self, results, individual_match=None): def show_result(self, results, individual_match=None):
old_current_book_id, self.current_book_id = self.current_book_id, results.book_id old_current_book_id, self.current_book_id = self.current_book_id, results.book_id
@ -466,17 +504,14 @@ class ResultDetails(QWidget):
if results.series: if results.series:
sidx = fmt_sidx(results.series_index or 0, use_roman=config['use_roman_numerals_for_series_number']) sidx = fmt_sidx(results.series_index or 0, use_roman=config['use_roman_numerals_for_series_number'])
text += '<p>' + _('{series_index} of {series}').format(series_index=sidx, series=results.series) + '</p>' text += '<p>' + _('{series_index} of {series}').format(series_index=sidx, series=results.series) + '</p>'
text += '<p><a href="calibre://mark" title="{1}">{0}</a></p>'.format( text += '<p><a href="calibre://jump" title="{1}"><img valign="bottom" src="calibre-icon:///lt.png" width=16 height=16>\xa0{0}</a>\xa0\xa0\xa0 '.format(
_('Mark this book in the library'), '<p>' + _( _('Show'), '<p>' + _('Scroll to this book in the book list and select it.'))
text += '<a href="calibre://mark" title="{1}"><img valig="bottom" src="calibre-icon:///marked.png" width=16 height=16>\xa0{0}</a></p>'.format(
_('Mark'), '<p>' + _(
'Put a pin on this book in the calibre library, for future reference.' 'Put a pin on this book in the calibre library, for future reference.'
' You can search for marked books using the search term: {0}').format('<p>marked:true')) ' You can search for marked books using the search term: {0}').format('<p>marked:true'))
self.book_info.setHtml(text) self.book_info.setHtml(text)
def mark_current_book(self, url):
gui = get_gui()
if gui is not None:
gui.iactions['Mark Books'].add_ids((self.current_book_id,))
class DetailsPanel(QStackedWidget): class DetailsPanel(QStackedWidget):
@ -513,6 +548,7 @@ p { margin: 0; }
<div style="margin-top: 1em"><a href="{fts_url}">Full syntax reference</a></div> <div style="margin-top: 1em"><a href="{fts_url}">Full syntax reference</a></div>
''').format(fts_url=fts_url)) ''').format(fts_url=fts_url))
hp.setFocusPolicy(Qt.FocusPolicy.NoFocus) hp.setFocusPolicy(Qt.FocusPolicy.NoFocus)
hp.document().setDocumentMargin(0)
hp.anchor_clicked.connect(safe_open_url) hp.anchor_clicked.connect(safe_open_url)
self.addWidget(hp) self.addWidget(hp)
# }}} # }}}
@ -592,6 +628,6 @@ if __name__ == '__main__':
w = ResultsPanel(parent=d) w = ResultsPanel(parent=d)
l.addWidget(w) l.addWidget(w)
l.addWidget(bb) l.addWidget(bb)
w.sip.search_box.setText('NEAR(control unreasonable)') w.sip.search_box.setText('asimov')
w.sip.search_button.click() w.sip.search_button.click()
d.exec() d.exec()