mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
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:
parent
095515b6e8
commit
75333c2b54
@ -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
|
||||
|
@ -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]
|
||||
|
||||
# }}}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
23
src/calibre/gui2/actions/auto_scroll.py
Normal file
23
src/calibre/gui2/actions/auto_scroll.py
Normal 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)
|
@ -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
|
||||
|
@ -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):
|
||||
'''
|
||||
|
@ -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(); }
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -35,6 +35,7 @@ public :
|
||||
PictureFlow(QWidget *parent /TransferThis/ = 0, int queueLength = 3);
|
||||
|
||||
void setImages(FlowImages *images);
|
||||
int count();
|
||||
|
||||
QSize slideSize() const;
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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&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">
|
||||
|
Loading…
x
Reference in New Issue
Block a user