Allow creating keyboard shortcuts to copy show and view URLs for selected books to clipboard. See #1912954 ([Enhancement] Library context menu and keyboard shortcuts for copying links)

This commit is contained in:
Kovid Goyal 2021-02-04 13:27:04 +05:30
parent 4b2c386c95
commit d503102a31
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -6,28 +6,31 @@ __license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import os, shutil, copy import copy
import os
import shutil
from functools import partial from functools import partial
from io import BytesIO from io import BytesIO
from PyQt5.Qt import (
QAction, QApplication, QDialog, QIcon, QMenu, QMimeData, QModelIndex, QTimer, QUrl
)
from PyQt5.Qt import QMenu, QModelIndex, QTimer, QIcon, QApplication, QMimeData, QDialog from calibre.db.errors import NoSuchFormat
from calibre.gui2 import error_dialog, Dispatcher, question_dialog, gprefs
from calibre.gui2.dialogs.metadata_bulk import MetadataBulkDialog
from calibre.gui2.dialogs.confirm_delete import confirm
from calibre.gui2.dialogs.device_category_editor import DeviceCategoryEditor
from calibre.gui2.actions import InterfaceAction
from calibre.ebooks.metadata import authors_to_string from calibre.ebooks.metadata import authors_to_string
from calibre.ebooks.metadata.book.base import Metadata from calibre.ebooks.metadata.book.base import Metadata
from calibre.ebooks.metadata.opf2 import OPF, metadata_to_opf from calibre.ebooks.metadata.opf2 import OPF, metadata_to_opf
from calibre.ebooks.metadata.sources.prefs import msprefs
from calibre.gui2 import Dispatcher, error_dialog, gprefs, question_dialog
from calibre.gui2.actions import InterfaceAction
from calibre.gui2.actions.show_quickview import get_quickview_action_plugin
from calibre.gui2.dialogs.confirm_delete import confirm
from calibre.gui2.dialogs.device_category_editor import DeviceCategoryEditor
from calibre.gui2.dialogs.metadata_bulk import MetadataBulkDialog
from calibre.library.comments import merge_comments
from calibre.utils.config import tweaks from calibre.utils.config import tweaks
from calibre.utils.date import is_date_undefined from calibre.utils.date import is_date_undefined
from calibre.utils.icu import sort_key from calibre.utils.icu import sort_key
from calibre.db.errors import NoSuchFormat from polyglot.builtins import iteritems, map, unicode_type
from calibre.library.comments import merge_comments
from calibre.ebooks.metadata.sources.prefs import msprefs
from calibre.gui2.actions.show_quickview import get_quickview_action_plugin
from polyglot.builtins import iteritems, unicode_type, map
class EditMetadataAction(InterfaceAction): class EditMetadataAction(InterfaceAction):
@ -99,6 +102,57 @@ class EditMetadataAction(InterfaceAction):
self.action_merge.setMenu(mb) self.action_merge.setMenu(mb)
self.qaction.triggered.connect(self.edit_metadata) self.qaction.triggered.connect(self.edit_metadata)
ac = QAction(_('Copy URL to show book in calibre'), self.gui)
ac.setToolTip(_('Copy URLs to show the currently selected books in calibre, to the system clipboard'))
ac.triggered.connect(self.copy_show_link)
self.gui.addAction(ac)
self.gui.keyboard.register_shortcut(
self.unique_name + ' - ' + 'copy_show_book',
ac.text(), description=ac.toolTip(),
action=ac, group=self.action_spec[0])
ac = QAction(_('Copy URL to open book in calibre'), self.gui)
ac.triggered.connect(self.copy_view_link)
ac.setToolTip(_('Copy URLs to open the currently selected books in calibre, to the system clipboard'))
self.gui.addAction(ac)
self.gui.keyboard.register_shortcut(
self.unique_name + ' - ' + 'copy_view_book',
ac.text(), description=ac.toolTip(),
action=ac, group=self.action_spec[0])
def _copy_links(self, lines):
urls = QUrl.fromStringList(lines)
cb = QApplication.instance().clipboard()
md = QMimeData()
md.setText('\n'.join(lines))
md.setUrls(urls)
cb.setMimeData(md)
def copy_show_link(self):
db = self.gui.current_db
ids = [db.id(row.row()) for row in self.gui.library_view.selectionModel().selectedRows()]
db = db.new_api
library_id = getattr(db, 'server_library_id', None)
if not library_id or not ids:
return
lines = [f'calibre://show-book/{library_id}/{book_id}' for book_id in ids]
self._copy_links(lines)
def copy_view_link(self):
from calibre.gui2.actions.view import preferred_format
db = self.gui.current_db
ids = [db.id(row.row()) for row in self.gui.library_view.selectionModel().selectedRows()]
db = db.new_api
library_id = getattr(db, 'server_library_id', None)
if not library_id or not ids:
return
lines = []
for book_id in ids:
formats = db.new_api.formats(book_id, verify_formats=True)
if formats:
fmt = preferred_format(formats)
lines.append(f'calibre://view-book/{library_id}/{book_id}/{fmt}')
if lines:
self._copy_links(lines)
def location_selected(self, loc): def location_selected(self, loc):
enabled = loc == 'library' enabled = loc == 'library'
@ -174,8 +228,8 @@ class EditMetadataAction(InterfaceAction):
_('No books selected'), show=True) _('No books selected'), show=True)
db = self.gui.library_view.model().db db = self.gui.library_view.model().db
ids = [db.id(row.row()) for row in rows] ids = [db.id(row.row()) for row in rows]
from calibre.gui2.metadata.bulk_download import start_download
from calibre.ebooks.metadata.sources.update import update_sources from calibre.ebooks.metadata.sources.update import update_sources
from calibre.gui2.metadata.bulk_download import start_download
update_sources() update_sources()
start_download(self.gui, ids, start_download(self.gui, ids,
Dispatcher(self.metadata_downloaded), Dispatcher(self.metadata_downloaded),
@ -899,8 +953,8 @@ class EditMetadataAction(InterfaceAction):
self.refresh_books_after_metadata_edit(affected_books) self.refresh_books_after_metadata_edit(affected_books)
def set_cover_from_format(self, book_id, fmt): def set_cover_from_format(self, book_id, fmt):
from calibre.utils.config import prefs
from calibre.ebooks.metadata.meta import get_metadata from calibre.ebooks.metadata.meta import get_metadata
from calibre.utils.config import prefs
fmt = fmt.lower() fmt = fmt.lower()
cdata = None cdata = None
db = self.gui.current_db.new_api db = self.gui.current_db.new_api