Add calibre://show-note to link to notes

This commit is contained in:
Kovid Goyal 2023-09-22 20:58:26 +05:30
parent c966582265
commit d74fa0e4da
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 87 additions and 2 deletions

View File

@ -127,6 +127,29 @@ This opens a book details window on the specified book from the specified librar
current library or the selected book.
Open the notes associated with an author/tag/etc
------------------------------------------------------
The URL syntax is::
calibre://book-details/Library_Name/Field_Name/id_Item_Id
This opens a window showing the notes of the specified item.
The easiest way to create such URLs is to show the notes you want
in calibre and click the :guilabel:`Copy URL` button to copy the URL
to the clipboard and paste it wherever you need.
Here ``Field_Name`` is the name of the columns such as ``authors`` or ``tags``.
For user created columns, replace the leading ``#`` in the field name with
an underscore, so ``#mytags`` becomes ``_mytags``.
In addition to specifying items by id using ``Item_Id`` you can also specify
them by name using either ``val_Item_Name`` or ``hex_Hex_Encoded_Item_Name``.
For example::
calibre://book-details/Library_Name/authors/val_John%20Doe
.. _hex_encoding:
Hex encoding of URL parameters

View File

@ -3,8 +3,8 @@
import os
from qt.core import (
QByteArray, QDialog, QDialogButtonBox, QIcon, QLabel, QSize, Qt, QTextDocument,
QVBoxLayout,
QApplication, QByteArray, QDialog, QDialogButtonBox, QIcon, QLabel, QMimeData,
QSize, Qt, QTextDocument, QUrl, QVBoxLayout,
)
from calibre import prepare_string_for_xml
@ -97,6 +97,11 @@ class ShowNoteDialog(Dialog):
b.setToolTip(_('Search the calibre library for books by: {}').format(self.item_val))
else:
b.setToolTip(_('Search the calibre library for books with: {}').format(self.item_val))
b = self.bb.addButton(_('Copy &URL'), QDialogButtonBox.ButtonRole.ActionRole)
b.setIcon(QIcon.ic('insert-link.png'))
b.clicked.connect(self.copy_url)
b.setToolTip(_('Copy a calibre:// URL to the clipboard that can be used to link to this note from other programs'))
l.addWidget(self.bb)
def sizeHint(self):
@ -105,6 +110,17 @@ class ShowNoteDialog(Dialog):
def open_item_link(self, url):
safe_open_url(url)
def copy_url(self):
f = self.field
if f.startswith('#'):
f = '_' + f[1:]
url = f'calibre://show-note/{self.db.server_library_id}/{f}/id_{self.item_id}'
cb = QApplication.instance().clipboard()
md = QMimeData()
md.setText(url)
md.setUrls([QUrl(url)])
cb.setMimeData(md)
def edit(self):
d = EditNoteDialog(self.field, self.item_id, self.db, self)
if d.exec() == QDialog.DialogCode.Accepted:

View File

@ -709,6 +709,52 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
return
details = self.iactions['Show Book Details']
details.show_book_info(library_id=library_id, library_path=library_path, book_id=book_id)
elif action == 'show-note':
parts = tuple(filter(None, path.split('/')))
if len(parts) != 3:
return
library_id, field, itemx = parts
library_id = decode_library_id(library_id)
library_path = self.library_broker.path_for_library_id(library_id)
if library_path is None:
prints('Ignoring unknown library id', library_id, file=sys.stderr)
return
if field.startswith('_'):
field = '#' + field[1:]
item_id = item_val = None
if itemx.startswith('id_'):
try:
item_id = int(itemx[3:])
except Exception:
prints('Ignoring invalid item id', itemx, file=sys.stderr)
return
elif itemx.startswith('hex_'):
try:
item_val = bytes.fromhex(itemx[4:]).decode('utf-8')
except Exception:
prints('Ignoring invalid item hexval', itemx, file=sys.stderr)
return
elif itemx.startswith('val_'):
item_val = itemx[4:]
else:
prints('Ignoring invalid item hexval', itemx, file=sys.stderr)
return
def doit():
nonlocal item_id, item_val
db = self.current_db.new_api
if item_id is None:
item_id = db.get_item_id(field, item_val)
if item_id is None:
prints('The item named:', item_val, 'was not found', file=sys.stderr)
return
if db.notes_for(field, item_id):
from calibre.gui2.dialogs.show_category_note import ShowNoteDialog
ShowNoteDialog(field, item_id, db, parent=self).show()
else:
prints(f'No notes available for {field}:{itemx}', file=sys.stderr)
self.perform_url_action(library_id, library_path, doit)
elif action == 'show-book':
parts = tuple(filter(None, path.split('/')))
if len(parts) != 2: