Allow auto scrolling through the list of books by pressing the X key. The speed of scrolling can be controlled in Preferences->Look & feel->Cover browser. Useful to have a "slideshow" of book covers

Fixes #1917634 [[Enhancement] Add slideshow capability to cover browser](https://bugs.launchpad.net/calibre/+bug/1917634)
This commit is contained in:
Kovid Goyal 2021-04-15 18:01:48 +05:30
parent 095515b6e8
commit 75333c2b54
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
12 changed files with 138 additions and 34 deletions

View File

@ -782,3 +782,5 @@ calibre has several keyboard shortcuts to save you time and mouse movement. Thes
- Re-apply the current sort
* - :kbd:`Ctrl+Q`
- Quit calibre
* - :kbd:`X`
- Toggle autoscroll of the book list

View File

@ -970,6 +970,12 @@ class ActionOpenFolder(InterfaceActionBase):
' calibre library')
class ActionAutoscrollBooks(InterfaceActionBase):
name = 'Autoscroll Books'
actual_plugin = 'calibre.gui2.actions.auto_scroll:AutoscrollBooksAction'
description = _('Auto scroll through the list of books')
class ActionSendToDevice(InterfaceActionBase):
name = 'Send To Device'
actual_plugin = 'calibre.gui2.actions.device:SendToDeviceAction'
@ -1115,7 +1121,7 @@ plugins += [ActionAdd, ActionFetchAnnotations, ActionGenerateCatalog,
ActionCopyToLibrary, ActionTweakEpub, ActionUnpackBook, ActionNextMatch, ActionStore,
ActionPluginUpdater, ActionPickRandom, ActionEditToC, ActionSortBy,
ActionMarkBooks, ActionEmbed, ActionTemplateTester, ActionTagMapper, ActionAuthorMapper,
ActionVirtualLibrary, ActionBrowseAnnotations, ActionTemplateFunctions]
ActionVirtualLibrary, ActionBrowseAnnotations, ActionTemplateFunctions, ActionAutoscrollBooks]
# }}}

View File

@ -2219,7 +2219,7 @@ class Cache(object):
for book in self._search(expr, virtual_fields=virtual_fields):
c[book].append(lib)
except Exception as e:
c[book].append(_('[Error in virtual library {0}: {1}]').format(lib, str(e)))
c[book].append(_('[Error in Virtual library {0}: {1}]').format(lib, str(e)))
self.vls_for_books_cache = {b:tuple(sorted(libs, key=sort_key)) for b, libs in c.items()}
if not book_ids:
book_ids = self._all_book_ids()

View File

@ -124,7 +124,8 @@ def create_defs():
'Edit Metadata', 'Send To Device', 'Save To Disk',
'Connect Share', 'Copy To Library', None,
'Convert Books', 'View', 'Open Folder', 'Show Book Details',
'Similar Books', 'Tweak ePub', None, 'Remove Books',
'Similar Books', 'Tweak ePub', None, 'Remove Books', None,
'Autoscroll Books'
)
defs['show_splash_screen'] = True
@ -198,6 +199,7 @@ def create_defs():
defs['browse_annots_restrict_to_type'] = None
defs['browse_annots_use_stemmer'] = True
defs['annots_export_format'] = 'txt'
defs['books_autoscroll_time'] = 2.0
create_defs()

View File

@ -0,0 +1,23 @@
#!/usr/bin/env python
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
# License: GPLv3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
from calibre.gui2.actions import InterfaceAction
class AutoscrollBooksAction(InterfaceAction):
name = 'Autoscroll Books'
action_spec = (_('Auto scroll through the book list'), 'auto-scroll.png',
_('Auto scroll through the book list, particularly useful with the cover browser open'), _('X'))
dont_add_to = frozenset(('context-menu-device', 'menubar-device'))
action_type = 'current'
def genesis(self):
self.qaction.triggered.connect(self.gui.toggle_auto_scroll)
def location_selected(self, loc):
enabled = loc == 'library'
self.qaction.setEnabled(enabled)
self.menuless_qaction.setEnabled(enabled)

View File

@ -9,15 +9,19 @@ __docformat__ = 'restructuredtext en'
Module to implement the Cover Flow feature
'''
import sys, os, time
import os
import sys
import time
from qt.core import (
QAction, QApplication, QDialog, QFont, QImage, QItemSelectionModel,
QKeySequence, QLabel, QSize, QSizePolicy, QStackedLayout, Qt, QTimer, pyqtSignal
)
from qt.core import (QImage, QSizePolicy, QTimer, QDialog, Qt, QSize, QAction,
QStackedLayout, QLabel, pyqtSignal, QKeySequence, QFont, QApplication, QItemSelectionModel)
from calibre.ebooks.metadata import rating_to_stars
from calibre.constants import islinux
from calibre.gui2 import (config, available_height, available_width, gprefs,
rating_font)
from calibre.ebooks.metadata import rating_to_stars
from calibre.gui2 import (
available_height, available_width, config, gprefs, rating_font
)
from calibre_extensions import pictureflow
@ -190,6 +194,12 @@ class CoverFlow(pictureflow.PictureFlow):
if not gprefs['cover_browser_reflections']:
self.setShowReflections(False)
def one_auto_scroll(self):
if self.currentSlide() >= self.count() - 1:
self.setCurrentSlide(0)
else:
self.showNext()
def set_subtitle_font(self, for_ratings=True):
if for_ratings:
self.setSubtitleFont(QFont(rating_font()))
@ -295,6 +305,28 @@ class CoverFlowMixin(object):
def __init__(self, *args, **kwargs):
pass
def one_auto_scroll(self):
cb_visible = self.cover_flow is not None and self.cb_splitter.button.isChecked()
if cb_visible:
self.cover_flow.one_auto_scroll()
else:
self.library_view.show_next_book()
def toggle_auto_scroll(self):
if not hasattr(self, 'auto_scroll_timer'):
self.auto_scroll_timer = t = QTimer(self)
t.timeout.connect(self.one_auto_scroll)
if self.auto_scroll_timer.isActive():
self.auto_scroll_timer.stop()
else:
self.one_auto_scroll()
self.auto_scroll_timer.start(int(1000 * gprefs['books_autoscroll_time']))
def update_auto_scroll_timeout(self):
if hasattr(self, 'auto_scroll_timer') and self.auto_scroll_timer.isActive():
self.auto_scroll_timer.stop()
self.toggle_auto_scroll()
def init_cover_flow_mixin(self):
self.cover_flow = None
self.cf_last_updated_at = None

View File

@ -1290,6 +1290,14 @@ class BooksView(QTableView): # {{{
self.set_current_row(row, select=False)
break
def show_next_book(self):
ci = self.currentIndex()
if not ci.isValid():
self.set_current_row()
return
n = (ci.row() + 1) % self.model().rowCount(QModelIndex())
self.set_current_row(n)
@property
def next_id(self):
'''

View File

@ -1518,6 +1518,7 @@ void PictureFlow::timerEvent(QTimerEvent* event)
void PictureFlow::dataChanged() { d->dataChanged(); }
void PictureFlow::emitcurrentChanged(int index) { emit currentChanged(index); }
int PictureFlow::count() const { return d->slideCount(); }
int FlowImages::count() { return 0; }
QImage FlowImages::image(int index) { Q_UNUSED(index); return QImage(); }

View File

@ -111,6 +111,8 @@ public:
*/
void setImages(FlowImages *images);
int count() const;
/*!
Returns the dimension of each slide (in pixels).
*/
@ -221,4 +223,3 @@ private:
qreal device_pixel_ratio() const;
qreal last_device_pixel_ratio;
};

View File

@ -35,6 +35,7 @@ public :
PictureFlow(QWidget *parent /TransferThis/ = 0, int queueLength = 3);
void setImages(FlowImages *images);
int count();
QSize slideSize() const;

View File

@ -425,6 +425,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
r('cover_grid_show_title', gprefs)
r('tag_browser_show_counts', gprefs)
r('tag_browser_item_padding', gprefs)
r('books_autoscroll_time', gprefs)
r('qv_respects_vls', gprefs)
r('qv_dclick_changes_column', gprefs)
@ -806,6 +807,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
getattr(gui, view + '_view').set_row_header_visibility()
gui.library_view.refresh_row_sizing()
gui.grid_view.refresh_settings()
gui.update_auto_scroll_timeout()
qv = get_quickview_action_plugin()
if qv:
qv.refill_quickview()

View File

@ -1251,6 +1251,32 @@ them to all have the same width and height</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_26">
<property name="text">
<string>Show ne&amp;xt cover during auto scroll after:</string>
</property>
<property name="buddy">
<cstring>opt_books_autoscroll_time</cstring>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QDoubleSpinBox" name="opt_books_autoscroll_time">
<property name="suffix">
<string> seconds</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>1.000000000000000</double>
</property>
<property name="maximum">
<double>100000.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="quickview_tab">