diff --git a/resources/images/icon_choose.png b/resources/images/icon_choose.png new file mode 100644 index 0000000000..5a34aca1df Binary files /dev/null and b/resources/images/icon_choose.png differ diff --git a/src/calibre/gui2/library/models.py b/src/calibre/gui2/library/models.py index a32c3f1cbc..70fa0ccbda 100644 --- a/src/calibre/gui2/library/models.py +++ b/src/calibre/gui2/library/models.py @@ -48,18 +48,20 @@ def default_image(): class ColumnColor(object): - def __init__(self): + def __init__(self, formatter, colors): self.mi = None + self.formatter = formatter + self.colors = colors - def __call__(self, id_, key, fmt, db, formatter, color_cache, colors): + def __call__(self, id_, key, fmt, db, color_cache): if id_ in color_cache and key in color_cache[id_]: self.mi = None return color_cache[id_][key] try: if self.mi is None: self.mi = db.get_metadata(id_, index_is_id=True) - color = formatter.safe_format(fmt, self.mi, '', self.mi) - if color in colors: + color = self.formatter.safe_format(fmt, self.mi, '', self.mi) + if color in self.colors: color = QColor(color) if color.isValid(): color = QVariant(color) @@ -72,10 +74,11 @@ class ColumnColor(object): class ColumnIcon(object): - def __init__(self): + def __init__(self, formatter): self.mi = None + self.formatter = formatter - def __call__(self, id_, key, fmt, kind, db, formatter, icon_cache): + 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_]: self.mi = None @@ -83,12 +86,17 @@ class ColumnIcon(object): try: if self.mi is None: self.mi = db.get_metadata(id_, index_is_id=True) - icon = formatter.safe_format(fmt, self.mi, '', self.mi) + icon = self.formatter.safe_format(fmt, self.mi, '', self.mi) if icon: + if icon in icon_bitmap_cache: + icon_bitmap = icon_bitmap_cache[icon] + icon_cache[id_][dex] = icon_bitmap + return icon_bitmap d = os.path.join(config_dir, 'cc_icons', icon) if (os.path.exists(d)): - icon = QIcon(d) - icon_cache[id_][dex] = icon + icon_bitmap = QIcon(d) + icon_cache[id_][dex] = icon_bitmap + icon_bitmap_cache[icon] = icon_bitmap self.mi = None return icon except: @@ -121,8 +129,13 @@ class BooksModel(QAbstractTableModel): # {{{ def __init__(self, parent=None, buffer=40): QAbstractTableModel.__init__(self, parent) self.db = None - self.column_color = ColumnColor() - self.column_icon = ColumnIcon() + + self.formatter = SafeFormat() + 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.book_on_device = None self.editable_cols = ['title', 'authors', 'rating', 'publisher', 'tags', 'series', 'timestamp', 'pubdate', @@ -134,9 +147,6 @@ class BooksModel(QAbstractTableModel): # {{{ self.column_map = [] self.headers = {} self.alignment_map = {} - self.color_cache = defaultdict(dict) - self.icon_cache = defaultdict(dict) - self.color_row_fmt_cache = None self.buffer_size = buffer self.metadata_backup = None self.bool_yes_icon = QIcon(I('ok.png')) @@ -147,10 +157,14 @@ class BooksModel(QAbstractTableModel): # {{{ self.ids_to_highlight_set = set() self.current_highlighted_idx = None self.highlight_only = False - self.colors = frozenset([unicode(c) for c in QColor.colorNames()]) - self.formatter = SafeFormat() self.read_config() + def _clear_caches(self): + self.color_cache = defaultdict(dict) + self.icon_cache = defaultdict(dict) + self.icon_bitmap_cache = {} + self.color_row_fmt_cache = None + 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') @@ -221,17 +235,13 @@ class BooksModel(QAbstractTableModel): # {{{ def refresh_ids(self, ids, current_row=-1): - self.color_cache = defaultdict(dict) - self.icon_cache = defaultdict(dict) - self.color_row_fmt_cache = None + self._clear_caches() rows = self.db.refresh_ids(ids) if rows: self.refresh_rows(rows, current_row=current_row) def refresh_rows(self, rows, current_row=-1): - self.color_cache = defaultdict(dict) - self.icon_cache = defaultdict(dict) - self.color_row_fmt_cache = None + self._clear_caches() for row in rows: if row == current_row: self.new_bookdisplay_data.emit( @@ -262,9 +272,7 @@ class BooksModel(QAbstractTableModel): # {{{ return ret def count_changed(self, *args): - self.color_cache = defaultdict(dict) - self.icon_cache = defaultdict(dict) - self.color_row_fmt_cache = None + self._clear_caches() self.count_changed_signal.emit(self.db.count()) def row_indices(self, index): @@ -395,9 +403,7 @@ class BooksModel(QAbstractTableModel): # {{{ self.resort(reset=reset) def reset(self): - self.color_cache = defaultdict(dict) - self.icon_cache = defaultdict(dict) - self.color_row_fmt_cache = None + self._clear_caches() QAbstractTableModel.reset(self) def resort(self, reset=True): @@ -784,12 +790,14 @@ class BooksModel(QAbstractTableModel): # {{{ rules = self.db.prefs['column_icon_rules'] if rules: key = self.column_map[col] - id_ = self.id(index) - self.column_icon.mi = None + id_ = None for kind, k, fmt in rules: if k == key and kind == 'icon_only': + 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.formatter, self.icon_cache) + self.icon_cache, self.icon_bitmap_cache) if ccicon is not None: return NONE self.icon_cache[id_][key+'icon_only'] = None @@ -811,7 +819,7 @@ class BooksModel(QAbstractTableModel): # {{{ for k, fmt in self.db.prefs['column_color_rules']: if k == key: ccol = self.column_color(id_, key, fmt, self.db, - self.formatter, self.color_cache, self.colors) + self.color_cache) if ccol is not None: return ccol @@ -832,7 +840,7 @@ class BooksModel(QAbstractTableModel): # {{{ for fmt in self.color_row_fmt_cache: ccol = self.column_color(id_, color_row_key, fmt, self.db, - self.formatter, self.color_cache, self.colors) + self.color_cache) if ccol is not None: return ccol @@ -847,15 +855,17 @@ class BooksModel(QAbstractTableModel): # {{{ rules = self.db.prefs['column_icon_rules'] if rules: key = self.column_map[col] - id_ = self.id(index) - self.column_icon.mi = None + id_ = None need_icon_with_text = False for kind, k, fmt in rules: if k == key and kind in ('icon', 'icon_only'): + if id_ is None: + id_ = self.id(index) + self.column_icon.mi = None if kind == 'icon': need_icon_with_text = True - ccicon = self.column_icon(id_, key, fmt, 'icon', self.db, - self.formatter, self.icon_cache) + 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: diff --git a/src/calibre/gui2/preferences/coloring.py b/src/calibre/gui2/preferences/coloring.py index 19a113a78a..ad9a7a9af2 100644 --- a/src/calibre/gui2/preferences/coloring.py +++ b/src/calibre/gui2/preferences/coloring.py @@ -253,14 +253,21 @@ class RuleEditor(QDialog): # {{{ QDialog.__init__(self, parent) self.fm = fm + if pref_name == 'column_color_rules': + self.rule_kind = 'color' + rule_text = _('coloring') + else: + self.rule_kind = 'icon' + rule_text = _('icon') + self.setWindowIcon(QIcon(I('format-fill-color.png'))) - self.setWindowTitle(_('Create/edit a column coloring rule')) + self.setWindowTitle(_('Create/edit a column {0} rule').format(rule_text)) self.l = l = QGridLayout(self) self.setLayout(l) - self.l1 = l1 = QLabel(_('Create a coloring rule by' - ' filling in the boxes below')) + self.l1 = l1 = QLabel(_('Create a column {0} rule by' + ' filling in the boxes below'.format(rule_text))) l.addWidget(l1, 0, 0, 1, 8) self.f1 = QFrame(self) @@ -270,11 +277,9 @@ class RuleEditor(QDialog): # {{{ self.l2 = l2 = QLabel(_('Set the')) l.addWidget(l2, 2, 0) - if pref_name == 'column_color_rules': - self.rule_kind = 'color' + if self.rule_kind == 'color': l.addWidget(QLabel(_('color'))) else: - self.rule_kind = 'icon' self.kind_box = QComboBox(self) for tt, t in icon_rule_kinds: self.kind_box.addItem(tt, t) @@ -626,12 +631,7 @@ class EditRules(QWidget): # {{{ self.l = l = QGridLayout(self) self.setLayout(l) - self.l1 = l1 = QLabel('

'+_( - 'You can control the color of columns in the' - ' book list by creating "rules" that tell calibre' - ' what color to use. Click the Add Rule button below' - ' to get started.

You can change an existing rule by double' - ' clicking it.')) + self.l1 = l1 = QLabel('') l1.setWordWrap(True) l.addWidget(l1, 0, 0, 1, 2) @@ -678,6 +678,21 @@ class EditRules(QWidget): # {{{ self.rules_view.setModel(self.model) self.fm = fm self.mi = mi + if pref_name == 'column_color_rules': + self.l1.setText('

'+_( + 'You can control the color of columns in the' + ' book list by creating "rules" that tell calibre' + ' what color to use. Click the Add Rule button below' + ' to get started.

You can change an existing rule by' + ' double clicking it.')) + else: + self.l1.setText('

'+_( + 'You can add icons to columns in the' + ' book list by creating "rules" that tell calibre' + ' what icon to use. Click the Add Rule button below' + ' to get started.

You can change an existing rule by' + ' double clicking it.')) + self.add_advanced_button.setVisible(False) def _add_rule(self, dlg): if dlg.exec_() == dlg.Accepted: diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py index 52ca95cdc5..b3423e5a8c 100644 --- a/src/calibre/gui2/preferences/look_feel.py +++ b/src/calibre/gui2/preferences/look_feel.py @@ -185,7 +185,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.icon_rules = EditRules(self.tabWidget) self.icon_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.icon_rules, - QIcon(I('format-fill-color.png')), _('Column icons')) + QIcon(I('icon_choose.png')), _('Column icons')) self.tabWidget.setCurrentIndex(0) keys = [QKeySequence('F11', QKeySequence.PortableText), QKeySequence(