mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Make the cover grid customizable
This commit is contained in:
parent
5737ead466
commit
0541a118e6
@ -111,6 +111,10 @@ defs['tags_browser_category_icons'] = {}
|
||||
defs['cover_browser_reflections'] = True
|
||||
defs['extra_row_spacing'] = 0
|
||||
defs['refresh_book_list_on_bulk_edit'] = True
|
||||
defs['cover_grid_width'] = 0
|
||||
defs['cover_grid_height'] = 0
|
||||
defs['cover_grid_color'] = (80, 80, 80)
|
||||
defs['cover_grid_cache_size'] = 200
|
||||
del defs
|
||||
# }}}
|
||||
|
||||
|
@ -20,8 +20,11 @@ from PyQt4.Qt import (
|
||||
QUrl, QDrag, QPoint, QPainter, QRect)
|
||||
|
||||
from calibre import fit_image
|
||||
from calibre.gui2 import gprefs
|
||||
from calibre.utils.config import prefs
|
||||
|
||||
CM_TO_INCH = 0.393701
|
||||
|
||||
# Drag 'n Drop {{{
|
||||
def dragMoveEvent(self, event):
|
||||
event.acceptProposedAction()
|
||||
@ -305,15 +308,39 @@ class CoverCache(dict):
|
||||
def __hash__(self):
|
||||
return id(self)
|
||||
|
||||
def set_limit(self, limit):
|
||||
with self.lock:
|
||||
self.limit = limit
|
||||
if len(self.items) > self.limit:
|
||||
extra = len(self.items) - self.limit
|
||||
remove = tuple(self.iterkeys())[:extra]
|
||||
for k in remove:
|
||||
del self.items[k]
|
||||
|
||||
class CoverDelegate(QStyledItemDelegate):
|
||||
|
||||
def __init__(self, parent, width, height):
|
||||
def __init__(self, parent):
|
||||
super(CoverDelegate, self).__init__(parent)
|
||||
self.set_dimensions()
|
||||
self.cover_cache = CoverCache(limit=gprefs['cover_grid_cache_size'])
|
||||
self.render_queue = Queue()
|
||||
|
||||
def set_dimensions(self):
|
||||
width = self.original_width = gprefs['cover_grid_width']
|
||||
height = self.original_height = gprefs['cover_grid_height']
|
||||
|
||||
if height < 0.1:
|
||||
height = max(185, QApplication.instance().desktop().availableGeometry(self.parent()).height() / 5.0)
|
||||
else:
|
||||
height *= self.parent().logicalDpiY() * CM_TO_INCH
|
||||
|
||||
if width < 0.1:
|
||||
width = 0.75 * height
|
||||
else:
|
||||
width *= self.parent().logicalDpiX() * CM_TO_INCH
|
||||
self.cover_size = QSize(width, height)
|
||||
self.item_size = self.cover_size + QSize(8, 8)
|
||||
self.spacing = max(10, min(50, int(0.1 * width)))
|
||||
self.cover_cache = CoverCache()
|
||||
self.render_queue = Queue()
|
||||
|
||||
def sizeHint(self, option, index):
|
||||
return self.item_size
|
||||
@ -366,11 +393,7 @@ class GridView(QListView):
|
||||
def __init__(self, parent):
|
||||
QListView.__init__(self, parent)
|
||||
setup_dnd_interface(self)
|
||||
pal = QPalette(self.palette())
|
||||
r = g = b = 0x50
|
||||
pal.setColor(pal.Base, QColor(r, g, b))
|
||||
pal.setColor(pal.Text, QColor(Qt.white if (r + g + b)/3.0 < 128 else Qt.black))
|
||||
self.setPalette(pal)
|
||||
self.set_color()
|
||||
self.setUniformItemSizes(True)
|
||||
self.setWrapping(True)
|
||||
self.setFlow(self.LeftToRight)
|
||||
@ -380,7 +403,7 @@ class GridView(QListView):
|
||||
self.setResizeMode(self.Adjust)
|
||||
self.setSelectionMode(self.ExtendedSelection)
|
||||
self.setVerticalScrollMode(self.ScrollPerPixel)
|
||||
self.delegate = CoverDelegate(self, 135, 180)
|
||||
self.delegate = CoverDelegate(self)
|
||||
self.setItemDelegate(self.delegate)
|
||||
self.setSpacing(self.delegate.spacing)
|
||||
self.ignore_render_requests = Event()
|
||||
@ -390,6 +413,21 @@ class GridView(QListView):
|
||||
self.gui = parent
|
||||
self.context_menu = None
|
||||
|
||||
def set_color(self):
|
||||
r, g, b = gprefs['cover_grid_color']
|
||||
pal = QPalette()
|
||||
pal.setColor(pal.Base, QColor(r, g, b))
|
||||
pal.setColor(pal.Text, QColor(Qt.white if (r + g + b)/3.0 < 128 else Qt.black))
|
||||
self.setPalette(pal)
|
||||
|
||||
def refresh_settings(self):
|
||||
if gprefs['cover_grid_width'] != self.delegate.original_width or gprefs['cover_grid_height'] != self.delegate.original_height:
|
||||
self.delegate.set_dimensions()
|
||||
self.setSpacing(self.delegate.spacing)
|
||||
self.delegate.cover_cache.clear()
|
||||
self.set_color()
|
||||
self.delegate.cover_cache.set_limit(gprefs['cover_grid_cache_size'])
|
||||
|
||||
def shown(self):
|
||||
if self.render_thread is None:
|
||||
self.render_thread = Thread(target=self.render_covers)
|
||||
|
@ -5,8 +5,8 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
from PyQt4.Qt import (QApplication, QFont, QFontInfo, QFontDialog,
|
||||
QAbstractListModel, Qt, QIcon, QKeySequence)
|
||||
from PyQt4.Qt import (QApplication, QFont, QFontInfo, QFontDialog, QColorDialog,
|
||||
QAbstractListModel, Qt, QIcon, QKeySequence, QPalette, QColor)
|
||||
|
||||
from calibre.gui2.preferences import ConfigWidgetBase, test_widget, CommaSeparatedList
|
||||
from calibre.gui2.preferences.look_feel_ui import Ui_Form
|
||||
@ -18,7 +18,7 @@ from calibre.utils.icu import sort_key
|
||||
from calibre.gui2.book_details import get_field_list
|
||||
from calibre.gui2.preferences.coloring import EditRules
|
||||
|
||||
class DisplayedFields(QAbstractListModel): # {{{
|
||||
class DisplayedFields(QAbstractListModel): # {{{
|
||||
|
||||
def __init__(self, db, parent=None):
|
||||
QAbstractListModel.__init__(self, parent)
|
||||
@ -110,6 +110,9 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
r('tag_browser_old_look', gprefs, restart_required=True)
|
||||
r('bd_show_cover', gprefs)
|
||||
r('bd_overlay_cover_size', gprefs)
|
||||
r('cover_grid_width', gprefs)
|
||||
r('cover_grid_height', gprefs)
|
||||
r('cover_grid_cache_size', gprefs)
|
||||
|
||||
r('cover_flow_queue_length', config, restart_required=True)
|
||||
r('cover_browser_reflections', gprefs)
|
||||
@ -123,7 +126,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
lang = get_lang()
|
||||
if lang is None or lang not in available_translations():
|
||||
lang = 'en'
|
||||
items = [(l, get_esc_lang(l)) for l in available_translations() \
|
||||
items = [(l, get_esc_lang(l)) for l in available_translations()
|
||||
if l != lang]
|
||||
if lang != 'en':
|
||||
items.append(('en', get_esc_lang('en')))
|
||||
@ -170,7 +173,6 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
r('categories_using_hierarchy', db.prefs, setting=CommaSeparatedList,
|
||||
choices=sorted(list(choices), key=sort_key))
|
||||
|
||||
|
||||
self.current_font = self.initial_font = None
|
||||
self.change_font_button.clicked.connect(self.change_font)
|
||||
|
||||
@ -197,6 +199,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
keys = [unicode(x.toString(QKeySequence.NativeText)) for x in keys]
|
||||
self.fs_help_msg.setText(unicode(self.fs_help_msg.text())%(
|
||||
_(' or ').join(keys)))
|
||||
self.cover_grid_color_button.clicked.connect(self.change_cover_grid_color)
|
||||
|
||||
def initialize(self):
|
||||
ConfigWidgetBase.initialize(self)
|
||||
@ -215,6 +218,12 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
mi=None
|
||||
self.edit_rules.initialize(db.field_metadata, db.prefs, mi, 'column_color_rules')
|
||||
self.icon_rules.initialize(db.field_metadata, db.prefs, mi, 'column_icon_rules')
|
||||
self.set_cg_color(gprefs['cover_grid_color'])
|
||||
|
||||
def set_cg_color(self, val):
|
||||
pal = QPalette()
|
||||
pal.setColor(QPalette.Window, QColor(*val))
|
||||
self.cover_grid_color_label.setPalette(pal)
|
||||
|
||||
def restore_defaults(self):
|
||||
ConfigWidgetBase.restore_defaults(self)
|
||||
@ -227,6 +236,15 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
self.edit_rules.clear()
|
||||
self.icon_rules.clear()
|
||||
self.changed_signal.emit()
|
||||
self.set_cg_color(gprefs.defaults['cover_grid_color'])
|
||||
|
||||
def change_cover_grid_color(self):
|
||||
col = QColorDialog.getColor(self.cover_grid_color_label.palette().color(QPalette.Window),
|
||||
self.gui, _('Choose background color for cover grid'))
|
||||
if col.isValid():
|
||||
col = tuple(col.getRgb())[:3]
|
||||
self.set_cg_color(col)
|
||||
self.changed_signal.emit()
|
||||
|
||||
def build_font_obj(self):
|
||||
font_info = self.current_font
|
||||
@ -286,6 +304,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
self.display_model.commit()
|
||||
self.edit_rules.commit(self.gui.current_db.prefs)
|
||||
self.icon_rules.commit(self.gui.current_db.prefs)
|
||||
gprefs['cover_grid_color'] = tuple(self.cover_grid_color_label.palette().color(QPalette.Window).getRgb())[:3]
|
||||
return rr
|
||||
|
||||
def refresh_gui(self, gui):
|
||||
@ -296,9 +315,11 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
if hasattr(gui.cover_flow, 'setShowReflections'):
|
||||
gui.cover_flow.setShowReflections(gprefs['cover_browser_reflections'])
|
||||
gui.library_view.refresh_row_sizing()
|
||||
gui.grid_view.refresh_settings()
|
||||
|
||||
if __name__ == '__main__':
|
||||
from calibre.gui2 import Application
|
||||
app = Application([])
|
||||
test_widget('Interface', 'Look & Feel')
|
||||
|
||||
|
||||
|
@ -223,6 +223,184 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_5">
|
||||
<attribute name="icon">
|
||||
<iconset resource="../../../../resources/images.qrc">
|
||||
<normaloff>:/images/grid.png</normaloff>:/images/grid.png</iconset>
|
||||
</attribute>
|
||||
<attribute name="title">
|
||||
<string>Cover Grid</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Cover &Width: </string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>opt_cover_grid_width</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="opt_cover_grid_width">
|
||||
<property name="toolTip">
|
||||
<string>The width of displayed covers</string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> cm</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>Cover &Height: </string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>opt_cover_grid_height</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="opt_cover_grid_height">
|
||||
<property name="toolTip">
|
||||
<string>The height of displayed covers</string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> cm</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>A value of zero means set automatically based on screen size</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>Background color for the cover grid:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="cover_grid_color_label">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="cover_grid_color_button">
|
||||
<property name="text">
|
||||
<string>Change &color</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Number of covers to cache in &memory:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>opt_cover_grid_cache_size</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="opt_cover_grid_cache_size">
|
||||
<property name="maximum">
|
||||
<number>3000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>355</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_4">
|
||||
<attribute name="icon">
|
||||
<iconset resource="../../../../resources/images.qrc">
|
||||
|
Loading…
x
Reference in New Issue
Block a user