mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add calibre://show-note to link to notes
This commit is contained in:
parent
c966582265
commit
d74fa0e4da
@ -127,6 +127,29 @@ This opens a book details window on the specified book from the specified librar
|
|||||||
current library or the selected book.
|
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:
|
||||||
|
|
||||||
Hex encoding of URL parameters
|
Hex encoding of URL parameters
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
from qt.core import (
|
from qt.core import (
|
||||||
QByteArray, QDialog, QDialogButtonBox, QIcon, QLabel, QSize, Qt, QTextDocument,
|
QApplication, QByteArray, QDialog, QDialogButtonBox, QIcon, QLabel, QMimeData,
|
||||||
QVBoxLayout,
|
QSize, Qt, QTextDocument, QUrl, QVBoxLayout,
|
||||||
)
|
)
|
||||||
|
|
||||||
from calibre import prepare_string_for_xml
|
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))
|
b.setToolTip(_('Search the calibre library for books by: {}').format(self.item_val))
|
||||||
else:
|
else:
|
||||||
b.setToolTip(_('Search the calibre library for books with: {}').format(self.item_val))
|
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)
|
l.addWidget(self.bb)
|
||||||
|
|
||||||
def sizeHint(self):
|
def sizeHint(self):
|
||||||
@ -105,6 +110,17 @@ class ShowNoteDialog(Dialog):
|
|||||||
def open_item_link(self, url):
|
def open_item_link(self, url):
|
||||||
safe_open_url(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):
|
def edit(self):
|
||||||
d = EditNoteDialog(self.field, self.item_id, self.db, self)
|
d = EditNoteDialog(self.field, self.item_id, self.db, self)
|
||||||
if d.exec() == QDialog.DialogCode.Accepted:
|
if d.exec() == QDialog.DialogCode.Accepted:
|
||||||
|
@ -709,6 +709,52 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
|||||||
return
|
return
|
||||||
details = self.iactions['Show Book Details']
|
details = self.iactions['Show Book Details']
|
||||||
details.show_book_info(library_id=library_id, library_path=library_path, book_id=book_id)
|
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':
|
elif action == 'show-book':
|
||||||
parts = tuple(filter(None, path.split('/')))
|
parts = tuple(filter(None, path.split('/')))
|
||||||
if len(parts) != 2:
|
if len(parts) != 2:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user