Device books view: Add an action to the context menu to easily jump to the matching book in the calibre library view. Fixes #1903418 [Enhancement Request: Device view - book details window shows info from matching book in library](https://bugs.launchpad.net/calibre/+bug/1903418)

This commit is contained in:
Kovid Goyal 2020-11-26 14:58:23 +05:30
parent 2e6f0e7a59
commit 15edcbfdb8
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 63 additions and 3 deletions

View File

@ -1022,6 +1022,12 @@ class ActionMatchBooks(InterfaceActionBase):
description = _('Match book on the devices to books in the library') description = _('Match book on the devices to books in the library')
class ActionShowMatchedBooks(InterfaceActionBase):
name = 'Show Matched Book In Library'
actual_plugin = 'calibre.gui2.actions.match_books:ShowMatchedBookAction'
description = _('Show the book in the calibre library that matches this book')
class ActionCopyToLibrary(InterfaceActionBase): class ActionCopyToLibrary(InterfaceActionBase):
name = 'Copy To Library' name = 'Copy To Library'
actual_plugin = 'calibre.gui2.actions.copy_to_library:CopyToLibraryAction' actual_plugin = 'calibre.gui2.actions.copy_to_library:CopyToLibraryAction'
@ -1101,7 +1107,7 @@ plugins += [ActionAdd, ActionFetchAnnotations, ActionGenerateCatalog,
ActionFetchNews, ActionSaveToDisk, ActionQuickview, ActionPolish, ActionFetchNews, ActionSaveToDisk, ActionQuickview, ActionPolish,
ActionShowBookDetails,ActionRestart, ActionOpenFolder, ActionConnectShare, ActionShowBookDetails,ActionRestart, ActionOpenFolder, ActionConnectShare,
ActionSendToDevice, ActionHelp, ActionPreferences, ActionSimilarBooks, ActionSendToDevice, ActionHelp, ActionPreferences, ActionSimilarBooks,
ActionAddToLibrary, ActionEditCollections, ActionMatchBooks, ActionChooseLibrary, ActionAddToLibrary, ActionEditCollections, ActionMatchBooks, ActionShowMatchedBooks, ActionChooseLibrary,
ActionCopyToLibrary, ActionTweakEpub, ActionUnpackBook, ActionNextMatch, ActionStore, ActionCopyToLibrary, ActionTweakEpub, ActionUnpackBook, ActionNextMatch, ActionStore,
ActionPluginUpdater, ActionPickRandom, ActionEditToC, ActionSortBy, ActionPluginUpdater, ActionPickRandom, ActionEditToC, ActionSortBy,
ActionMarkBooks, ActionEmbed, ActionTemplateTester, ActionTagMapper, ActionAuthorMapper, ActionMarkBooks, ActionEmbed, ActionTemplateTester, ActionTagMapper, ActionAuthorMapper,

View File

@ -1905,6 +1905,14 @@ class Cache(object):
self.clear_search_caches() self.clear_search_caches()
self.clear_composite_caches() self.clear_composite_caches()
@read_api
def books_matching_device_book(self, lpath):
ans = set()
for book_id, (_, _, _, _, lpaths) in self.fields['ondevice'].cache.items():
if lpath in lpaths:
ans.add(book_id)
return ans
@read_api @read_api
def tags_older_than(self, tag, delta=None, must_have_tag=None, must_have_authors=None): def tags_older_than(self, tag, delta=None, must_have_tag=None, must_have_authors=None):
''' '''

View File

@ -117,7 +117,8 @@ def create_defs():
defs['action-layout-context-menu-device'] = ( defs['action-layout-context-menu-device'] = (
'View', 'Save To Disk', None, 'Remove Books', None, 'View', 'Save To Disk', None, 'Remove Books', None,
'Add To Library', 'Edit Collections', 'Match Books' 'Add To Library', 'Edit Collections', 'Match Books',
'Show Matched Book In Library'
) )
defs['action-layout-context-menu-cover-browser'] = ( defs['action-layout-context-menu-cover-browser'] = (

View File

@ -6,7 +6,7 @@ __license__ = 'GPL v3'
__copyright__ = '2013, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2013, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
from calibre.gui2 import error_dialog from calibre.gui2 import error_dialog, question_dialog
from calibre.gui2.actions import InterfaceAction from calibre.gui2.actions import InterfaceAction
from calibre.gui2.dialogs.match_books import MatchBooks from calibre.gui2.dialogs.match_books import MatchBooks
@ -38,3 +38,45 @@ class MatchBookAction(InterfaceAction):
id_ = view.model().indices(rows)[0] id_ = view.model().indices(rows)[0]
MatchBooks(self.gui, view, id_, rows[0]).exec_() MatchBooks(self.gui, view, id_, rows[0]).exec_()
class ShowMatchedBookAction(InterfaceAction):
name = 'Show Matched Book In Library'
action_spec = (_('Show matched book in library'), 'lt.png',
_('Show the book in the calibre library that matches this book'),
())
dont_add_to = frozenset(('menubar', 'toolbar', 'context-menu', 'toolbar-child', 'context-menu-cover-browser'))
action_type = 'current'
def genesis(self):
self.qaction.triggered.connect(self.show_matched_books_in_library)
def location_selected(self, loc):
enabled = loc != 'library'
self.qaction.setEnabled(enabled)
self.menuless_qaction.setEnabled(enabled)
def show_matched_books_in_library(self, *args):
view = self.gui.current_view()
rows = view.selectionModel().selectedRows()
if not rows or len(rows) != 1:
d = error_dialog(self.gui, _('Match books'), _('You must select one book'))
d.exec_()
return
device_book_index = view.model().indices(rows)[0]
device_db = view.model().db
db = self.gui.current_db.new_api
book = device_db[device_book_index]
matching_book_ids = db.books_matching_device_book(book.lpath)
if not matching_book_ids:
if question_dialog(self.gui, _('No matching books'), _(
'No matching books found in the calibre library. Do you want to specify the'
' matching book manually?')):
MatchBooks(self.gui, view, device_book_index, rows[0]).exec_()
return
ids = tuple(sorted(matching_book_ids, reverse=True))
self.gui.library_view.select_rows(ids)
self.gui.show_library_view()
self.gui.iactions['Edit Metadata'].refresh_books_after_metadata_edit(ids)

View File

@ -808,6 +808,9 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
if idx == 3: if idx == 3:
return self.card_b_view return self.card_b_view
def show_library_view(self):
self.location_manager.library_action.trigger()
def booklists(self): def booklists(self):
return self.memory_view.model().db, self.card_a_view.model().db, self.card_b_view.model().db return self.memory_view.model().db, self.card_a_view.model().db, self.card_b_view.model().db