mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
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:
parent
2e6f0e7a59
commit
15edcbfdb8
@ -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,
|
||||||
|
@ -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):
|
||||||
'''
|
'''
|
||||||
|
@ -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'] = (
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user