From 089d6c172f7564ab5511c19683278fe3deaa457a Mon Sep 17 00:00:00 2001 From: Charles Haley Date: Tue, 17 Sep 2013 10:25:32 +0200 Subject: [PATCH 1/4] Allow an icon rule to put multiple icons on a column --- src/calibre/gui2/library/models.py | 65 ++++++++++------ src/calibre/gui2/library/views.py | 1 + src/calibre/gui2/preferences/coloring.py | 96 +++++++++++++++++++----- 3 files changed, 121 insertions(+), 41 deletions(-) diff --git a/src/calibre/gui2/library/models.py b/src/calibre/gui2/library/models.py index 60768b481e..c5d453b3ff 100644 --- a/src/calibre/gui2/library/models.py +++ b/src/calibre/gui2/library/models.py @@ -9,7 +9,7 @@ import functools, re, os, traceback, errno, time from collections import defaultdict, namedtuple from PyQt4.Qt import (QAbstractTableModel, Qt, pyqtSignal, QIcon, QImage, - QModelIndex, QVariant, QDateTime, QColor, QPixmap) + QModelIndex, QVariant, QDateTime, QColor, QPixmap, QPainter) from calibre.gui2 import NONE, error_dialog from calibre.utils.search_query_parser import ParseException @@ -76,9 +76,10 @@ class ColumnColor(object): # {{{ class ColumnIcon(object): # {{{ - def __init__(self, formatter): + def __init__(self, formatter, model): self.mi = None self.formatter = formatter + self.model = model def __call__(self, id_, key, fmt, kind, db, icon_cache, icon_bitmap_cache): dex = key+kind @@ -88,26 +89,44 @@ class ColumnIcon(object): # {{{ try: if self.mi is None: self.mi = db.get_metadata(id_, index_is_id=True) - icon = self.formatter.safe_format(fmt, self.mi, '', self.mi) - if icon: - if icon in icon_bitmap_cache: - icon_bitmap = icon_bitmap_cache[icon] + icons = self.formatter.safe_format(fmt, self.mi, '', self.mi) + if icons: + if icons in icon_bitmap_cache: + icon_bitmap = icon_bitmap_cache[icons] icon_cache[id_][dex] = icon_bitmap return icon_bitmap - d = os.path.join(config_dir, 'cc_icons', icon) - if (os.path.exists(d)): - icon_bitmap = QPixmap(d) - h = icon_bitmap.height() - w = icon_bitmap.width() - # If the image is landscape and width is more than 50% - # large than height, use the pixmap. This tells Qt to display - # the image full width. It might be clipped to row height. - if w < (3 * h)/2: - icon_bitmap = QIcon(icon_bitmap) - icon_cache[id_][dex] = icon_bitmap - icon_bitmap_cache[icon] = icon_bitmap - self.mi = None - return icon_bitmap + + icon_list = [ic.strip() for ic in icons.split(':')] + icon_bitmaps = [] + total_width = 0 + for icon in icon_list: + d = os.path.join(config_dir, 'cc_icons', icon) + if (os.path.exists(d)): + bm = QPixmap(d) + icon_bitmaps.append(bm) + total_width += bm.width() + if len(icon_bitmaps) > 1: + result = QPixmap(len(icon_list)*128, 128) + result.fill() + painter = QPainter(result) + x = 0 + for bm in icon_bitmaps: + painter.drawPixmap(x, 0, bm) + x += bm.width() + painter.end() + else: + result = icon_bitmaps[0] + + # If the image height is less than the row height, leave it alone + # The -2 allows for a pixel above and below. Also ensure that + # it is always a bit positive + rh = min(2, self.model.row_height - 2) + if result.height() > rh: + result = result.scaledToHeight(rh, mode=Qt.SmoothTransformation) + icon_cache[id_][dex] = result + icon_bitmap_cache[icons] = result + self.mi = None + return result except: pass # }}} @@ -145,7 +164,7 @@ class BooksModel(QAbstractTableModel): # {{{ self.colors = frozenset([unicode(c) for c in QColor.colorNames()]) self._clear_caches() self.column_color = ColumnColor(self.formatter, self.colors) - self.column_icon = ColumnIcon(self.formatter) + self.column_icon = ColumnIcon(self.formatter, self) self.book_on_device = None self.editable_cols = ['title', 'authors', 'rating', 'publisher', @@ -168,6 +187,7 @@ class BooksModel(QAbstractTableModel): # {{{ self.ids_to_highlight_set = set() self.current_highlighted_idx = None self.highlight_only = False + self.row_height = 0 self.read_config() def _clear_caches(self): @@ -176,6 +196,9 @@ class BooksModel(QAbstractTableModel): # {{{ self.icon_bitmap_cache = {} self.color_row_fmt_cache = None + def set_row_height(self, height): + self.row_height = height + def change_alignment(self, colname, alignment): if colname in self.column_map and alignment in ('left', 'right', 'center'): old = self.alignment_map.get(colname, 'left') diff --git a/src/calibre/gui2/library/views.py b/src/calibre/gui2/library/views.py index 6711da1d9b..034f543429 100644 --- a/src/calibre/gui2/library/views.py +++ b/src/calibre/gui2/library/views.py @@ -649,6 +649,7 @@ class BooksView(QTableView): # {{{ self.resizeRowToContents(0) self.verticalHeader().setDefaultSectionSize(self.rowHeight(0) + gprefs['extra_row_spacing']) + self._model.set_row_height(self.rowHeight(0)) self.row_sizing_done = True def resize_column_to_fit(self, column): diff --git a/src/calibre/gui2/preferences/coloring.py b/src/calibre/gui2/preferences/coloring.py index a195c948e5..8370762bba 100644 --- a/src/calibre/gui2/preferences/coloring.py +++ b/src/calibre/gui2/preferences/coloring.py @@ -13,7 +13,7 @@ from PyQt4.Qt import (QWidget, QDialog, QLabel, QGridLayout, QComboBox, QSize, QLineEdit, QIntValidator, QDoubleValidator, QFrame, QColor, Qt, QIcon, QScrollArea, QPushButton, QVBoxLayout, QDialogButtonBox, QToolButton, QListView, QAbstractListModel, pyqtSignal, QSizePolicy, QSpacerItem, - QApplication) + QApplication, QStandardItem, QStandardItemModel, QCheckBox) from calibre import prepare_string_for_xml, sanitize_file_name_unicode from calibre.constants import config_dir @@ -331,7 +331,6 @@ class RuleEditor(QDialog): # {{{ l.addItem(QSpacerItem(10, 10, QSizePolicy.Expanding), 2, 7) else: self.filename_box = QComboBox() - self.filename_box.setInsertPolicy(self.filename_box.InsertAlphabetically) d = os.path.join(config_dir, 'cc_icons') self.icon_file_names = [] if os.path.exists(d): @@ -341,9 +340,15 @@ class RuleEditor(QDialog): # {{{ if icon_file.endswith('.png'): self.icon_file_names.append(icon_file) self.icon_file_names.sort(key=sort_key) - self.update_filename_box() - l.addWidget(self.filename_box, 2, 5) + vb = QVBoxLayout() + self.multiple_icon_cb = QCheckBox(_('Choose more than one icon')) + vb.addWidget(self.multiple_icon_cb) + self.update_filename_box() + self.multiple_icon_cb.clicked.connect(self.multiple_box_clicked) + vb.addWidget(self.filename_box) + l.addLayout(vb, 2, 5) + self.filename_button = QPushButton(QIcon(I('document_open.png')), _('&Add icon')) l.addWidget(self.filename_button, 2, 6) @@ -401,18 +406,37 @@ class RuleEditor(QDialog): # {{{ self.update_color_label() self.color_box.currentIndexChanged.connect(self.update_color_label) else: + self.rule_icon_files = [] self.filename_button.clicked.connect(self.filename_button_clicked) self.resize(self.sizeHint()) + def multiple_box_clicked(self): + self.update_filename_box() + self.update_icon_filenames_in_box() + def update_filename_box(self): - self.filename_box.clear() + doing_multiple = self.multiple_icon_cb.isChecked() + + model = QStandardItemModel() + self.filename_box.setModel(model) self.icon_file_names.sort(key=sort_key) - self.filename_box.addItem('') - self.filename_box.addItems(self.icon_file_names) + if doing_multiple: + item = QStandardItem(_('Open to see checkboxes')) + else: + item = QStandardItem('') + model.appendRow(item) + for i,filename in enumerate(self.icon_file_names): + item = QStandardItem(filename) + if doing_multiple: + item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled); + item.setData(Qt.Unchecked, Qt.CheckStateRole) + else: + item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable); icon = QIcon(os.path.join(config_dir, 'cc_icons', filename)) - self.filename_box.setItemIcon(i+1, icon) + item.setIcon(icon) + model.appendRow(item) def update_color_label(self): pal = QApplication.palette() @@ -432,9 +456,9 @@ class RuleEditor(QDialog): # {{{ all_files=False, select_only_single_file=True) if path: icon_path = path[0] - icon_name = sanitize_file_name_unicode( + icon_name = lower(sanitize_file_name_unicode( os.path.splitext( - os.path.basename(icon_path))[0]+'.png') + os.path.basename(icon_path))[0]+'.png')) if icon_name not in self.icon_file_names: self.icon_file_names.append(icon_name) self.update_filename_box() @@ -449,13 +473,47 @@ class RuleEditor(QDialog): # {{{ except: import traceback traceback.print_exc() - self.filename_box.setCurrentIndex(self.filename_box.findText(icon_name)) + if self.multiple_icon_cb.isChecked(): + if icon_name not in self.rule_icon_files: + self.rule_icon_files.append(icon_name) + self.update_icon_filenames_in_box() + else: + self.filename_box.setCurrentIndex(self.filename_box.findText(icon_name)) self.filename_box.adjustSize() except: import traceback traceback.print_exc() return + def get_filenames_from_box(self): + if self.multiple_icon_cb.isChecked(): + model = self.filename_box.model() + fnames = [] + for i in range(1, model.rowCount()): + item = model.item(i, 0) + if item.checkState() == Qt.Checked: + fnames.append(lower(unicode(item.text()))) + fname = ' : '.join(fnames) + else: + fname = lower(unicode(self.filename_box.currentText())) + return fname + + def update_icon_filenames_in_box(self): + if self.rule_icon_files: + if not self.multiple_icon_cb.isChecked(): + idx = self.filename_box.findText(self.rule_icon_files[0]) + if idx >= 0: + self.filename_box.setCurrentIndex(idx) + else: + self.filename_box.setCurrentIndex(0) + else: + model = self.filename_box.model() + for icon in self.rule_icon_files: + idx = self.filename_box.findText(icon) + if idx >= 0: + item = model.item(idx) + item.setCheckState(Qt.Checked) + def add_blank_condition(self): c = ConditionEditor(self.fm, parent=self.conditions_widget) self.conditions.append(c) @@ -469,12 +527,11 @@ class RuleEditor(QDialog): # {{{ self.color_box.setCurrentIndex(idx) else: self.kind_box.setCurrentIndex(0 if kind == 'icon' else 1) - if rule.color: - idx = self.filename_box.findText(rule.color) - if idx >= 0: - self.filename_box.setCurrentIndex(idx) - else: - self.filename_box.setCurrentIndex(0) + self.rule_icon_files = [ic.strip() for ic in rule.color.split(':')] + if len(self.rule_icon_files) > 1: + self.multiple_icon_cb.setChecked(True) + self.update_filename_box() + self.update_icon_filenames_in_box() for i in range(self.column_box.count()): c = unicode(self.column_box.itemData(i).toString()) @@ -492,10 +549,9 @@ class RuleEditor(QDialog): # {{{ import traceback traceback.print_exc() - def accept(self): if self.rule_kind != 'color': - fname = lower(unicode(self.filename_box.currentText())) + fname = self.get_filenames_from_box() if not fname: error_dialog(self, _('No icon selected'), _('You must choose an icon for this rule'), show=True) @@ -528,7 +584,7 @@ class RuleEditor(QDialog): # {{{ def rule(self): r = Rule(self.fm) if self.rule_kind != 'color': - r.color = unicode(self.filename_box.currentText()) + r.color = self.get_filenames_from_box() else: r.color = unicode(self.color_box.currentText()) idx = self.column_box.currentIndex() From aea90e5c0323b588f6624bf511dfd6ac7e2a7fc7 Mon Sep 17 00:00:00 2001 From: Charles Haley Date: Tue, 17 Sep 2013 12:03:11 +0200 Subject: [PATCH 2/4] Fill with transparent instead of white, and fix silly typo. --- src/calibre/gui2/library/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/calibre/gui2/library/models.py b/src/calibre/gui2/library/models.py index c5d453b3ff..8cd1a63d03 100644 --- a/src/calibre/gui2/library/models.py +++ b/src/calibre/gui2/library/models.py @@ -107,7 +107,7 @@ class ColumnIcon(object): # {{{ total_width += bm.width() if len(icon_bitmaps) > 1: result = QPixmap(len(icon_list)*128, 128) - result.fill() + result.fill(Qt.transparent) painter = QPainter(result) x = 0 for bm in icon_bitmaps: @@ -120,7 +120,7 @@ class ColumnIcon(object): # {{{ # If the image height is less than the row height, leave it alone # The -2 allows for a pixel above and below. Also ensure that # it is always a bit positive - rh = min(2, self.model.row_height - 2) + rh = max(2, self.model.row_height - 2) if result.height() > rh: result = result.scaledToHeight(rh, mode=Qt.SmoothTransformation) icon_cache[id_][dex] = result From 2fe01db0043f94bd67d45528b94078b38c8d0953 Mon Sep 17 00:00:00 2001 From: Charles Haley Date: Tue, 17 Sep 2013 14:29:08 +0200 Subject: [PATCH 3/4] Make icon rules composable. --- src/calibre/gui2/dialogs/template_dialog.py | 17 +++-- src/calibre/gui2/dialogs/template_dialog.ui | 40 ++++------- src/calibre/gui2/library/models.py | 80 +++++++++++++-------- src/calibre/gui2/preferences/coloring.py | 30 ++++---- 4 files changed, 91 insertions(+), 76 deletions(-) diff --git a/src/calibre/gui2/dialogs/template_dialog.py b/src/calibre/gui2/dialogs/template_dialog.py index 3db6e37eb0..ab185d8a6a 100644 --- a/src/calibre/gui2/dialogs/template_dialog.py +++ b/src/calibre/gui2/dialogs/template_dialog.py @@ -7,7 +7,7 @@ import json, os, traceback from PyQt4.Qt import (Qt, QDialog, QDialogButtonBox, QSyntaxHighlighter, QFont, QRegExp, QApplication, QTextCharFormat, QColor, QCursor, - QIcon, QSize) + QIcon, QSize, QVariant) from calibre import sanitize_file_name_unicode from calibre.constants import config_dir @@ -19,7 +19,6 @@ from calibre.ebooks.metadata.book.formatter import SafeFormat from calibre.library.coloring import (displayable_columns, color_row_key) from calibre.gui2 import error_dialog, choose_files, pixmap_to_data - class ParenPosition: def __init__(self, block, pos, paren): @@ -247,9 +246,15 @@ class TemplateDialog(QDialog, Ui_TemplateDialog): self.icon_file_names.append(icon_file) self.icon_file_names.sort(key=sort_key) self.update_filename_box() - self.icon_with_text.setChecked(True) - if icon_rule_kind == 'icon_only': - self.icon_without_text.setChecked(True) + + dex = 0 + from calibre.gui2.preferences.coloring import icon_rule_kinds + for i,tup in enumerate(icon_rule_kinds): + txt,val = tup + self.icon_kind.addItem(txt, userData=QVariant(val)) + if val == icon_rule_kind: + dex = i + self.icon_kind.setCurrentIndex(dex) self.icon_field.setCurrentIndex(self.icon_field.findData(icon_field_key)) if mi: @@ -410,7 +415,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog): self.rule = (unicode(self.colored_field.itemData( self.colored_field.currentIndex()).toString()), txt) elif self.iconing: - rt = 'icon' if self.icon_with_text.isChecked() else 'icon_only' + rt = unicode(self.icon_kind.itemData(self.icon_kind.currentIndex()).toString()) self.rule = (rt, unicode(self.icon_field.itemData( self.icon_field.currentIndex()).toString()), diff --git a/src/calibre/gui2/dialogs/template_dialog.ui b/src/calibre/gui2/dialogs/template_dialog.ui index db9cc16dd9..11dafa4627 100644 --- a/src/calibre/gui2/dialogs/template_dialog.ui +++ b/src/calibre/gui2/dialogs/template_dialog.ui @@ -69,33 +69,19 @@ - - - Kind - - - - - - icon with no text - - - - - - - icon with text - - - - - - - 100 - 0 - - - + + + + + Kind: + + + + + + + + diff --git a/src/calibre/gui2/library/models.py b/src/calibre/gui2/library/models.py index 8cd1a63d03..af6c3e440b 100644 --- a/src/calibre/gui2/library/models.py +++ b/src/calibre/gui2/library/models.py @@ -81,38 +81,49 @@ class ColumnIcon(object): # {{{ self.formatter = formatter self.model = model - def __call__(self, id_, key, fmt, kind, db, icon_cache, icon_bitmap_cache): - dex = key+kind - if id_ in icon_cache and dex in icon_cache[id_]: + def __call__(self, id_, key, fmts, cache_index, db, icon_cache, icon_bitmap_cache): + if id_ in icon_cache and cache_index in icon_cache[id_]: self.mi = None - return icon_cache[id_][dex] + return icon_cache[id_][cache_index] try: if self.mi is None: self.mi = db.get_metadata(id_, index_is_id=True) - icons = self.formatter.safe_format(fmt, self.mi, '', self.mi) + icons = [] + for kind,fmt in fmts: + rule_icons = self.formatter.safe_format(fmt, self.mi, '', self.mi) + if not rule_icons: + continue + icon_list = [ic.strip() for ic in rule_icons.split(':')] + if icon_list and not kind.endswith('_composed'): + icons = icon_list + break + else: + icons.extend(icon_list) + if icons: - if icons in icon_bitmap_cache: - icon_bitmap = icon_bitmap_cache[icons] - icon_cache[id_][dex] = icon_bitmap + icon_string = ':'.join(icons) + if icon_string in icon_bitmap_cache: + icon_bitmap = icon_bitmap_cache[icon_string] + icon_cache[id_][cache_index] = icon_bitmap return icon_bitmap - icon_list = [ic.strip() for ic in icons.split(':')] icon_bitmaps = [] total_width = 0 - for icon in icon_list: + for icon in icons: d = os.path.join(config_dir, 'cc_icons', icon) if (os.path.exists(d)): bm = QPixmap(d) icon_bitmaps.append(bm) total_width += bm.width() if len(icon_bitmaps) > 1: - result = QPixmap(len(icon_list)*128, 128) + i = len(icon_bitmaps) + result = QPixmap((i * 128) + ((i-1)*2), 128) result.fill(Qt.transparent) painter = QPainter(result) x = 0 for bm in icon_bitmaps: painter.drawPixmap(x, 0, bm) - x += bm.width() + x += bm.width() + 2 painter.end() else: result = icon_bitmaps[0] @@ -123,8 +134,8 @@ class ColumnIcon(object): # {{{ rh = max(2, self.model.row_height - 2) if result.height() > rh: result = result.scaledToHeight(rh, mode=Qt.SmoothTransformation) - icon_cache[id_][dex] = result - icon_bitmap_cache[icons] = result + icon_cache[id_][cache_index] = result + icon_bitmap_cache[icon_string] = result self.mi = None return result except: @@ -788,16 +799,21 @@ class BooksModel(QAbstractTableModel): # {{{ if rules: key = self.column_map[col] id_ = None + fmts = [] for kind, k, fmt in rules: - if k == key and kind == 'icon_only': + if k == key and kind in ('icon_only', 'icon_only_composed'): if id_ is None: id_ = self.id(index) self.column_icon.mi = None - ccicon = self.column_icon(id_, key, fmt, 'icon_only', self.db, - self.icon_cache, self.icon_bitmap_cache) - if ccicon is not None: - return NONE - self.icon_cache[id_][key+'icon_only'] = None + fmts.append((kind, fmt)) + + if fmts: + cache_index = key + ':'.join([kind for kind,fmt in fmts]) + ccicon = self.column_icon(id_, key, fmts, cache_index, self.db, + self.icon_cache, self.icon_bitmap_cache) + if ccicon is not None: + return NONE + self.icon_cache[id_][cache_index] = None return self.column_to_dc_map[col](index.row()) elif role in (Qt.EditRole, Qt.ToolTipRole): return self.column_to_dc_map[col](index.row()) @@ -854,21 +870,25 @@ class BooksModel(QAbstractTableModel): # {{{ key = self.column_map[col] id_ = None need_icon_with_text = False + fmts = [] for kind, k, fmt in rules: - if k == key and kind in ('icon', 'icon_only'): + if k == key and kind.startswith('icon'): if id_ is None: id_ = self.id(index) self.column_icon.mi = None - if kind == 'icon': + fmts.append((kind, fmt)) + if kind in ('icon', 'icon_composed'): need_icon_with_text = True - ccicon = self.column_icon(id_, key, fmt, kind, self.db, - self.icon_cache, self.icon_bitmap_cache) - if ccicon is not None: - return ccicon - if need_icon_with_text: - self.icon_cache[id_][key+'icon'] = self.bool_blank_icon - return self.bool_blank_icon - self.icon_cache[id_][key+'icon'] = None + if fmts: + cache_index = key + ':'.join([kind for kind,fmt in fmts]) + ccicon = self.column_icon(id_, key, fmts, cache_index, self.db, + self.icon_cache, self.icon_bitmap_cache) + if ccicon is not None: + return ccicon + if need_icon_with_text: + self.icon_cache[id_][cache_index] = self.bool_blank_icon + return self.bool_blank_icon + self.icon_cache[id_][cache_index] = None elif role == Qt.TextAlignmentRole: cname = self.column_map[index.column()] ans = Qt.AlignVCenter | ALIGNMENT_MAP[self.alignment_map.get(cname, diff --git a/src/calibre/gui2/preferences/coloring.py b/src/calibre/gui2/preferences/coloring.py index 8370762bba..774c0e00c6 100644 --- a/src/calibre/gui2/preferences/coloring.py +++ b/src/calibre/gui2/preferences/coloring.py @@ -29,7 +29,9 @@ from calibre.utils.icu import lower all_columns_string = _('All Columns') icon_rule_kinds = [(_('icon with text'), 'icon'), - (_('icon with no text'), 'icon_only') ] + (_('icon with no text'), 'icon_only'), + (_('composed icons w/text'), 'icon_composed'), + (_('composed icons w/no text'), 'icon_only_composed'),] class ConditionEditor(QWidget): # {{{ @@ -526,7 +528,10 @@ class RuleEditor(QDialog): # {{{ if idx >= 0: self.color_box.setCurrentIndex(idx) else: - self.kind_box.setCurrentIndex(0 if kind == 'icon' else 1) + for i,tup in enumerate(icon_rule_kinds): + if kind == tup[1]: + self.kind_box.setCurrentIndex(i) + break self.rule_icon_files = [ic.strip() for ic in rule.color.split(':')] if len(self.rule_icon_files) > 1: self.multiple_icon_cb.setChecked(True) @@ -691,6 +696,15 @@ class RulesModel(QAbstractListModel): # {{{ self.reset() def rule_to_html(self, kind, col, rule): + trans_kind = 'not found' + if kind == 'color': + trans_kind = _('color') + else: + for tt, t in icon_rule_kinds: + if kind == t: + trans_kind = tt + break + if not isinstance(rule, Rule): if kind == 'color': return _(''' @@ -702,21 +716,11 @@ class RulesModel(QAbstractListModel): # {{{

Advanced Rule: set %(typ)s for column %(col)s:

%(rule)s
''')%dict(col=col, - typ=icon_rule_kinds[0][0] - if kind == icon_rule_kinds[0][1] else icon_rule_kinds[1][0], + typ=trans_kind, rule=prepare_string_for_xml(rule)) conditions = [self.condition_to_html(c) for c in rule.conditions] - trans_kind = 'not found' - if kind == 'color': - trans_kind = _('color') - else: - for tt, t in icon_rule_kinds: - if kind == t: - trans_kind = tt - break - return _('''\

Set the %(kind)s of %(col)s to %(color)s if the following conditions are met:

From 5acef6ba2feb8f464ac58743d5b51b8feef4be7a Mon Sep 17 00:00:00 2001 From: Charles Haley Date: Tue, 17 Sep 2013 15:29:13 +0200 Subject: [PATCH 4/4] Get rid of over-elaborate cache naming --- src/calibre/gui2/library/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/calibre/gui2/library/models.py b/src/calibre/gui2/library/models.py index af6c3e440b..44cf9fe39c 100644 --- a/src/calibre/gui2/library/models.py +++ b/src/calibre/gui2/library/models.py @@ -808,7 +808,7 @@ class BooksModel(QAbstractTableModel): # {{{ fmts.append((kind, fmt)) if fmts: - cache_index = key + ':'.join([kind for kind,fmt in fmts]) + cache_index = key + ':DisplayRole' ccicon = self.column_icon(id_, key, fmts, cache_index, self.db, self.icon_cache, self.icon_bitmap_cache) if ccicon is not None: @@ -880,7 +880,7 @@ class BooksModel(QAbstractTableModel): # {{{ if kind in ('icon', 'icon_composed'): need_icon_with_text = True if fmts: - cache_index = key + ':'.join([kind for kind,fmt in fmts]) + cache_index = key + ':DecorationRole' ccicon = self.column_icon(id_, key, fmts, cache_index, self.db, self.icon_cache, self.icon_bitmap_cache) if ccicon is not None: