Show recently viewed books in the View button's drop down menu

This commit is contained in:
Kovid Goyal 2011-04-13 17:02:02 -06:00
parent c9a4cabee8
commit d69fef1f05

View File

@ -6,9 +6,8 @@ __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import os, time
from functools import partial
from PyQt4.Qt import Qt, QMenu
from PyQt4.Qt import Qt, QMenu, QAction, pyqtSignal
from calibre.constants import isosx
from calibre.gui2 import error_dialog, Dispatcher, question_dialog, config, \
@ -18,6 +17,19 @@ from calibre.utils.config import prefs
from calibre.ptempfile import PersistentTemporaryFile
from calibre.gui2.actions import InterfaceAction
class HistoryAction(QAction):
view_historical = pyqtSignal(object)
def __init__(self, id_, title, parent):
QAction.__init__(self, title, parent)
self.id = id_
self.triggered.connect(self._triggered)
def _triggered(self):
self.view_historical.emit(self.id)
class ViewAction(InterfaceAction):
name = 'View'
@ -28,18 +40,41 @@ class ViewAction(InterfaceAction):
self.persistent_files = []
self.qaction.triggered.connect(self.view_book)
self.view_menu = QMenu()
self.view_menu.addAction(_('View'), partial(self.view_book, False))
ac = self.view_menu.addAction(_('View specific format'))
ac.setShortcut((Qt.ControlModifier if isosx else Qt.AltModifier)+Qt.Key_V)
ac = self.view_specific_action = QAction(_('View specific format'),
self.gui)
self.qaction.setMenu(self.view_menu)
ac.setShortcut((Qt.ControlModifier if isosx else Qt.AltModifier)+Qt.Key_V)
ac.triggered.connect(self.view_specific_format, type=Qt.QueuedConnection)
self.view_menu.addSeparator()
ac = self.view_action = QAction(self.qaction.icon(),
self.qaction.text(), self.gui)
ac.triggered.connect(self.view_book)
ac = self.create_action(spec=(_('Read a random book'), 'catalog.png',
None, None), attr='action_pick_random')
ac.triggered.connect(self.view_random)
self.view_menu.addAction(ac)
def initialization_complete(self):
self.build_menus(self.gui.current_db)
def build_menus(self, db):
self.view_menu.clear()
self.view_menu.addAction(self.qaction)
self.view_menu.addAction(self.view_specific_action)
self.view_menu.addSeparator()
self.view_menu.addAction(self.action_pick_random)
self.history_actions = []
history = db.prefs.get('gui_view_history', [])
if history:
self.view_menu.addSeparator()
for id_, title in history:
ac = HistoryAction(id_, title, self.view_menu)
self.view_menu.addAction(ac)
ac.view_historical.connect(self.view_historical)
def view_historical(self, id_):
self._view_calibre_books([id_])
def library_changed(self, db):
self.build_menus(db)
def location_selected(self, loc):
enabled = loc == 'library'
@ -47,15 +82,17 @@ class ViewAction(InterfaceAction):
action.setEnabled(enabled)
def view_format(self, row, format):
fmt_path = self.gui.library_view.model().db.format_abspath(row, format)
if fmt_path:
self._view_file(fmt_path)
id_ = self.gui.library_view.model().id(row)
self.view_format_by_id(id_, format)
def view_format_by_id(self, id_, format):
fmt_path = self.gui.library_view.model().db.format_abspath(id_, format,
db = self.gui.current_db
fmt_path = db.format_abspath(id_, format,
index_is_id=True)
if fmt_path:
title = db.title(id_, index_is_id=True)
self._view_file(fmt_path)
self.update_history([(id_, title)])
def book_downloaded_for_viewing(self, job):
if job.failed:
@ -162,6 +199,54 @@ class ViewAction(InterfaceAction):
self.gui.iactions['Choose Library'].pick_random()
self._view_books([self.gui.library_view.currentIndex()])
def _view_calibre_books(self, ids):
db = self.gui.current_db
views = []
for id_ in ids:
try:
formats = db.formats(id_, index_is_id=True)
except:
error_dialog(self.gui, _('Cannot view'),
_('This book no longer exists in your library'), show=True)
self.update_history([], remove=set([id_]))
continue
title = db.title(id_, index_is_id=True)
if not formats:
error_dialog(self.gui, _('Cannot view'),
_('%s has no available formats.')%(title,), show=True)
continue
formats = formats.upper().split(',')
fmt = formats[0]
for format in prefs['input_format_order']:
if format in formats:
fmt = format
break
views.append((id_, title))
self.view_format_by_id(id_, fmt)
self.update_history(views)
def update_history(self, views, remove=frozenset()):
db = self.gui.current_db
if views:
seen = set()
history = []
for id_, title in views + db.prefs.get('gui_view_history', []):
if title not in seen:
seen.add(title)
history.append((id_, title))
db.prefs['gui_view_history'] = history[:10]
self.build_menus(db)
if remove:
history = db.prefs.get('gui_view_history', [])
history = [x for x in history if x[0] not in remove]
db.prefs['gui_view_history'] = history[:10]
self.build_menus(db)
def _view_books(self, rows):
if not rows or len(rows) == 0:
self._launch_viewer()
@ -171,28 +256,8 @@ class ViewAction(InterfaceAction):
return
if self.gui.current_view() is self.gui.library_view:
for row in rows:
if hasattr(row, 'row'):
row = row.row()
formats = self.gui.library_view.model().db.formats(row)
title = self.gui.library_view.model().db.title(row)
if not formats:
error_dialog(self.gui, _('Cannot view'),
_('%s has no available formats.')%(title,), show=True)
continue
formats = formats.upper().split(',')
in_prefs = False
for format in prefs['input_format_order']:
if format in formats:
in_prefs = True
self.view_format(row, format)
break
if not in_prefs:
self.view_format(row, formats[0])
ids = list(map(self.gui.library_view.model().id, rows))
self._view_calibre_books(ids)
else:
paths = self.gui.current_view().model().paths(rows)
for path in paths: