mirror of
https://github.com/kovidgoyal/calibre.git
synced 2026-03-21 08:57:52 -04:00
Bookshelf: Clean up emblem rendering re-using code from grid view
This commit is contained in:
parent
c633a18d0f
commit
3947e501c6
@ -224,6 +224,43 @@ def handle_enter_press(self, ev, special_action=None, has_edit_cell=True):
|
||||
return False
|
||||
|
||||
|
||||
def render_emblem(book_id, rule, rule_index, cache, mi, db, formatter, template_cache, column_name='cover_grid'):
|
||||
ans = cache[book_id].get(rule, False)
|
||||
if ans is not False:
|
||||
return ans, mi
|
||||
ans = None
|
||||
if mi is None:
|
||||
mi = db.get_proxy_metadata(book_id)
|
||||
ans = formatter.safe_format(rule, mi, '', mi, column_name=f'{column_name}{rule_index}', template_cache=template_cache) or None
|
||||
cache[book_id][rule] = ans
|
||||
return ans, mi
|
||||
|
||||
|
||||
def cached_emblem(sz: int, cache: dict[str, QPixmap | QIcon], name: str, raw_icon=None):
|
||||
ans = cache.get(name, False)
|
||||
if ans is not False:
|
||||
return ans
|
||||
ans = None
|
||||
if raw_icon is not None:
|
||||
ans = raw_icon
|
||||
elif name == ':ondevice':
|
||||
ans = QIcon.cached_icon('ok.png')
|
||||
elif name:
|
||||
d = themed_icon_name(os.path.join(config_dir, 'cc_icons'), name)
|
||||
if d is not None:
|
||||
ans = QIcon(d)
|
||||
if ans is None:
|
||||
ans = QIcon(os.path.join(config_dir, 'cc_icons', name))
|
||||
if ans is not None and not ans.is_ok():
|
||||
ans = None
|
||||
if ans is not None and sz:
|
||||
ans = ans.pixmap(sz, sz)
|
||||
if ans.isNull():
|
||||
ans = None
|
||||
cache[name] = ans
|
||||
return ans
|
||||
|
||||
|
||||
def image_to_data(image): # {{{
|
||||
# Although this function is no longer used in this file, it is used in
|
||||
# other places in calibre. Don't delete it.
|
||||
@ -644,39 +681,6 @@ class CoverDelegate(QStyledItemDelegate):
|
||||
traceback.print_exc()
|
||||
return '', is_stars
|
||||
|
||||
def render_emblem(self, book_id, rule, rule_index, cache, mi, db, formatter, template_cache):
|
||||
ans = cache[book_id].get(rule, False)
|
||||
if ans is not False:
|
||||
return ans, mi
|
||||
ans = None
|
||||
if mi is None:
|
||||
mi = db.get_proxy_metadata(book_id)
|
||||
ans = formatter.safe_format(rule, mi, '', mi, column_name=f'cover_grid{rule_index}', template_cache=template_cache) or None
|
||||
cache[book_id][rule] = ans
|
||||
return ans, mi
|
||||
|
||||
def cached_emblem(self, cache, name, raw_icon=None):
|
||||
ans = cache.get(name, False)
|
||||
if ans is not False:
|
||||
return ans
|
||||
sz = self.emblem_size
|
||||
ans = None
|
||||
if raw_icon is not None:
|
||||
ans = raw_icon.pixmap(sz, sz)
|
||||
elif name == ':ondevice':
|
||||
ans = QIcon.cached_icon('ok.png').pixmap(sz, sz)
|
||||
elif name:
|
||||
pmap = None
|
||||
d = themed_icon_name(os.path.join(config_dir, 'cc_icons'), name)
|
||||
if d is not None:
|
||||
pmap = QIcon(d).pixmap(sz, sz)
|
||||
if pmap is None:
|
||||
pmap = QIcon(os.path.join(config_dir, 'cc_icons', name)).pixmap(sz, sz)
|
||||
if not pmap.isNull():
|
||||
ans = pmap
|
||||
cache[name] = ans
|
||||
return ans
|
||||
|
||||
def paint(self, painter, option, index):
|
||||
with clip_border_radius(painter, option.rect):
|
||||
QStyledItemDelegate.paint(self, painter, option, empty_index) # draw the hover and selection highlights
|
||||
@ -707,16 +711,16 @@ class CoverDelegate(QStyledItemDelegate):
|
||||
if self.emblem_size > 0:
|
||||
mi = None
|
||||
for i, (kind, column, rule) in enumerate(emblem_rules):
|
||||
icon_name, mi = self.render_emblem(book_id, rule, i, m.cover_grid_emblem_cache, mi, db, m.formatter, m.cover_grid_template_cache)
|
||||
icon_name, mi = render_emblem(book_id, rule, i, m.cover_grid_emblem_cache, mi, db, m.formatter, m.cover_grid_template_cache)
|
||||
if icon_name is not None:
|
||||
for one_icon in filter(None, (i.strip() for i in icon_name.split(':'))):
|
||||
pixmap = self.cached_emblem(m.cover_grid_bitmap_cache, one_icon)
|
||||
pixmap = cached_emblem(self.emblem_size, m.cover_grid_bitmap_cache, one_icon)
|
||||
if pixmap is not None:
|
||||
emblems.append(pixmap)
|
||||
if marked:
|
||||
emblems.insert(0, self.cached_emblem(m.cover_grid_bitmap_cache, ':marked', m.marked_icon))
|
||||
emblems.insert(0, cached_emblem(self.emblem_size, m.cover_grid_bitmap_cache, ':marked', m.marked_icon))
|
||||
if on_device:
|
||||
emblems.insert(0, self.cached_emblem(m.cover_grid_bitmap_cache, ':ondevice'))
|
||||
emblems.insert(0, cached_emblem(self.emblem_size, m.cover_grid_bitmap_cache, ':ondevice'))
|
||||
|
||||
painter.save()
|
||||
right_adjust = 0
|
||||
|
||||
@ -74,10 +74,12 @@ from calibre.ebooks.metadata import authors_to_string, rating_to_stars
|
||||
from calibre.gui2 import config, gprefs, resolve_bookshelf_color
|
||||
from calibre.gui2.library.alternate_views import (
|
||||
ClickStartData,
|
||||
cached_emblem,
|
||||
double_click_action,
|
||||
handle_enter_press,
|
||||
handle_selection_click,
|
||||
handle_selection_drag,
|
||||
render_emblem,
|
||||
selection_for_rows,
|
||||
setup_dnd_interface,
|
||||
)
|
||||
@ -1517,7 +1519,6 @@ class BookshelfView(MomentumScrollMixin, QAbstractScrollArea):
|
||||
# Cover template caching
|
||||
self.template_inited = False
|
||||
self.emblem_rules = []
|
||||
self.template_cache = {}
|
||||
self.template_is_empty = {}
|
||||
self.first_line_renderer = self.build_template_renderer('title', '{title}')
|
||||
self.second_line_renderer = self.build_template_renderer('authors', '')
|
||||
@ -1591,7 +1592,6 @@ class BookshelfView(MomentumScrollMixin, QAbstractScrollArea):
|
||||
def db_pref(key):
|
||||
return db.new_api.pref(key, get_default_from_defaults=True)
|
||||
|
||||
self.template_cache = {}
|
||||
title = db_pref('bookshelf_title_template') or ''
|
||||
self.first_line_renderer = self.build_template_renderer('title', title)
|
||||
authors = db_pref('bookshelf_author_template') or ''
|
||||
@ -1609,6 +1609,8 @@ class BookshelfView(MomentumScrollMixin, QAbstractScrollArea):
|
||||
self.init_template(db)
|
||||
if self.template_is_empty[column_name]:
|
||||
return ''
|
||||
if not (m := self.model()):
|
||||
return ''
|
||||
match template:
|
||||
case '{title}':
|
||||
return db.field_for('title', book_id)
|
||||
@ -1620,21 +1622,21 @@ class BookshelfView(MomentumScrollMixin, QAbstractScrollArea):
|
||||
return db.field_for('sort', book_id)
|
||||
mi = db.get_proxy_metadata(book_id)
|
||||
rslt = mi.formatter.safe_format(
|
||||
template, mi, TEMPLATE_ERROR, mi, column_name=column_name, template_cache=self.template_cache)
|
||||
template, mi, TEMPLATE_ERROR, mi, column_name=column_name, template_cache=m.bookshelf_template_cache)
|
||||
return rslt or ''
|
||||
|
||||
def render_emblem(self, book_id: int) -> str:
|
||||
if not (db := self.dbref()):
|
||||
return ''
|
||||
if not (m := self.model()):
|
||||
return
|
||||
db = m.db.new_api
|
||||
self.init_template(db)
|
||||
if not self.emblem_rules:
|
||||
return ''
|
||||
mi = db.get_proxy_metadata(book_id)
|
||||
for (x,y,t) in self.emblem_rules:
|
||||
rslt = mi.formatter.safe_format(
|
||||
t, mi, TEMPLATE_ERROR, mi, column_name='bookshelf_emblem', template_cache=self.template_cache)
|
||||
if rslt:
|
||||
return rslt
|
||||
mi = None
|
||||
for i, (kind, column, rule) in enumerate(self.emblem_rules):
|
||||
icon_name, mi = render_emblem(book_id, rule, i, m.bookshelf_emblem_cache, mi, db, m.formatter, m.bookshelf_template_cache, column_name='bookshelf')
|
||||
if icon_name:
|
||||
return icon_name
|
||||
return ''
|
||||
|
||||
def refresh_settings(self):
|
||||
@ -1855,10 +1857,8 @@ class BookshelfView(MomentumScrollMixin, QAbstractScrollArea):
|
||||
device_connected = get_gui().device_connected is not None
|
||||
on_device = device_connected and db.field_for('ondevice', book_id)
|
||||
if on_device:
|
||||
if getattr(self, 'on_device_icon', None) is None:
|
||||
self.on_device_icon = QIcon.cached_icon('ok.png')
|
||||
which = above if below else below
|
||||
which.append(self.on_device_icon)
|
||||
which.append(cached_emblem(0, m.bookshelf_bitmap_cache, ':ondevice'))
|
||||
custom = self.render_emblem(book_id)
|
||||
if custom:
|
||||
match gprefs['bookshelf_emblem_position']:
|
||||
@ -1872,7 +1872,8 @@ class BookshelfView(MomentumScrollMixin, QAbstractScrollArea):
|
||||
which = bottom
|
||||
case _:
|
||||
which = above if below and not above else below
|
||||
which.append(QIcon.cached_icon(custom))
|
||||
if icon := cached_emblem(0, m.bookshelf_bitmap_cache, custom):
|
||||
which.append(icon)
|
||||
|
||||
def draw_horizontal(emblems: list[QIcon], position: str) -> None:
|
||||
if not emblems:
|
||||
|
||||
@ -315,11 +315,14 @@ class BooksModel(QAbstractTableModel): # {{{
|
||||
self.icon_cache = defaultdict(dict)
|
||||
self.icon_bitmap_cache = {}
|
||||
self.cover_grid_emblem_cache = defaultdict(dict)
|
||||
self.bookshelf_emblem_cache = defaultdict(dict)
|
||||
self.cover_grid_bitmap_cache = {}
|
||||
self.bookshelf_bitmap_cache = {}
|
||||
self.color_row_fmt_cache = None
|
||||
self.color_template_cache = {}
|
||||
self.icon_template_cache = {}
|
||||
self.cover_grid_template_cache = {}
|
||||
self.bookshelf_template_cache = {}
|
||||
|
||||
def set_row_height(self, height):
|
||||
self.row_height = height
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user