Allow setting the color of all columns with a single rule in Preferences->Look & Feel->Column Coloring

This commit is contained in:
Kovid Goyal 2012-12-20 22:58:01 +05:30
commit 20b73d94b9
3 changed files with 47 additions and 15 deletions

View File

@ -27,6 +27,7 @@ from calibre import strftime, isbytestring
from calibre.constants import filesystem_encoding, DEBUG from calibre.constants import filesystem_encoding, DEBUG
from calibre.gui2.library import DEFAULT_SORT from calibre.gui2.library import DEFAULT_SORT
from calibre.utils.localization import calibre_langcode_to_name from calibre.utils.localization import calibre_langcode_to_name
from calibre.library.coloring import color_row_key
def human_readable(size, precision=1): def human_readable(size, precision=1):
""" Convert a size in bytes into megabytes """ """ Convert a size in bytes into megabytes """
@ -84,6 +85,7 @@ class BooksModel(QAbstractTableModel): # {{{
self.headers = {} self.headers = {}
self.alignment_map = {} self.alignment_map = {}
self.color_cache = defaultdict(dict) self.color_cache = defaultdict(dict)
self.color_row_fmt_cache = None
self.buffer_size = buffer self.buffer_size = buffer
self.metadata_backup = None self.metadata_backup = None
self.bool_yes_icon = QIcon(I('ok.png')) self.bool_yes_icon = QIcon(I('ok.png'))
@ -169,12 +171,14 @@ class BooksModel(QAbstractTableModel): # {{{
def refresh_ids(self, ids, current_row=-1): def refresh_ids(self, ids, current_row=-1):
self.color_cache = defaultdict(dict) self.color_cache = defaultdict(dict)
self.color_row_fmt_cache = None
rows = self.db.refresh_ids(ids) rows = self.db.refresh_ids(ids)
if rows: if rows:
self.refresh_rows(rows, current_row=current_row) self.refresh_rows(rows, current_row=current_row)
def refresh_rows(self, rows, current_row=-1): def refresh_rows(self, rows, current_row=-1):
self.color_cache = defaultdict(dict) self.color_cache = defaultdict(dict)
self.color_row_fmt_cache = None
for row in rows: for row in rows:
if row == current_row: if row == current_row:
self.new_bookdisplay_data.emit( self.new_bookdisplay_data.emit(
@ -206,6 +210,7 @@ class BooksModel(QAbstractTableModel): # {{{
def count_changed(self, *args): def count_changed(self, *args):
self.color_cache = defaultdict(dict) self.color_cache = defaultdict(dict)
self.color_row_fmt_cache = None
self.count_changed_signal.emit(self.db.count()) self.count_changed_signal.emit(self.db.count())
def row_indices(self, index): def row_indices(self, index):
@ -337,6 +342,7 @@ class BooksModel(QAbstractTableModel): # {{{
def reset(self): def reset(self):
self.color_cache = defaultdict(dict) self.color_cache = defaultdict(dict)
self.color_row_fmt_cache = None
QAbstractTableModel.reset(self) QAbstractTableModel.reset(self)
def resort(self, reset=True): def resort(self, reset=True):
@ -727,17 +733,21 @@ class BooksModel(QAbstractTableModel): # {{{
return QVariant(QColor('lightgreen')) return QVariant(QColor('lightgreen'))
elif role == Qt.ForegroundRole: elif role == Qt.ForegroundRole:
key = self.column_map[col] key = self.column_map[col]
mi = None self._mi_for_col_color = None
for k, fmt in self.db.prefs['column_color_rules']:
if k != key:
continue
id_ = self.id(index) id_ = self.id(index)
if self.color_row_fmt_cache is None:
d = dict(self.db.prefs['column_color_rules'])
self.color_row_fmt_cache = d.get(color_row_key, '')
def get_column_color(key, fmt):
if id_ in self.color_cache: if id_ in self.color_cache:
if key in self.color_cache[id_]: if key in self.color_cache[id_]:
return self.color_cache[id_][key] return self.color_cache[id_][key]
try: try:
if mi is None: if self._mi_for_col_color is None:
mi = self.db.get_metadata(id_, index_is_id=True) self._mi_for_col_color = self.db.get_metadata(id_, index_is_id=True)
mi = self._mi_for_col_color
color = self.formatter.safe_format(fmt, mi, '', mi) color = self.formatter.safe_format(fmt, mi, '', mi)
if color in self.colors: if color in self.colors:
color = QColor(color) color = QColor(color)
@ -746,7 +756,15 @@ class BooksModel(QAbstractTableModel): # {{{
self.color_cache[id_][key] = color self.color_cache[id_][key] = color
return color return color
except: except:
continue pass
for k, fmt in self.db.prefs['column_color_rules']:
if k == key:
col = get_column_color(key, fmt)
if col is not None:
self._mi_for_col_color = None
return col
if self.is_custom_column(key) and \ if self.is_custom_column(key) and \
self.custom_columns[key]['datatype'] == 'enumeration': self.custom_columns[key]['datatype'] == 'enumeration':
cc = self.custom_columns[self.column_map[col]]['display'] cc = self.custom_columns[self.column_map[col]]['display']
@ -757,9 +775,19 @@ class BooksModel(QAbstractTableModel): # {{{
try: try:
color = QColor(colors[values.index(txt)]) color = QColor(colors[values.index(txt)])
if color.isValid(): if color.isValid():
self._mi_for_col_color = None
return QVariant(color) return QVariant(color)
except: except:
pass pass
if self.color_row_fmt_cache:
key = color_row_key
col = get_column_color(key, self.color_row_fmt_cache)
if col is not None:
self._mi_for_col_color = None
return col
self._mi_for_col_color = None
return NONE return NONE
elif role == Qt.DecorationRole: elif role == Qt.DecorationRole:
if self.column_to_dc_decorator_map[col] is not None: if self.column_to_dc_decorator_map[col] is not None:

View File

@ -19,10 +19,12 @@ from calibre.gui2 import error_dialog
from calibre.gui2.dialogs.template_dialog import TemplateDialog from calibre.gui2.dialogs.template_dialog import TemplateDialog
from calibre.gui2.metadata.single_download import RichTextDelegate from calibre.gui2.metadata.single_download import RichTextDelegate
from calibre.library.coloring import (Rule, conditionable_columns, from calibre.library.coloring import (Rule, conditionable_columns,
displayable_columns, rule_from_template) displayable_columns, rule_from_template, color_row_key)
from calibre.utils.localization import lang_map from calibre.utils.localization import lang_map
from calibre.utils.icu import lower from calibre.utils.icu import lower
all_columns_string = _('All Columns')
class ConditionEditor(QWidget): # {{{ class ConditionEditor(QWidget): # {{{
ACTION_MAP = { ACTION_MAP = {
@ -312,12 +314,10 @@ class RuleEditor(QDialog): # {{{
b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon) b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon)
b.setMinimumContentsLength(15) b.setMinimumContentsLength(15)
for key in sorted( for key in sorted(displayable_columns(fm), key=sort_key):
displayable_columns(fm), name = all_columns_string if key == color_row_key else fm[key]['name']
key=sort_key):
name = fm[key]['name']
if name: if name:
self.column_box.addItem(key, key) self.column_box.addItem(name, key)
self.column_box.setCurrentIndex(0) self.column_box.setCurrentIndex(0)
self.color_box.addItems(QColor.colorNames()) self.color_box.addItems(QColor.colorNames())
@ -427,7 +427,8 @@ class RulesModel(QAbstractListModel): # {{{
col, rule = self.rules[row] col, rule = self.rules[row]
except: except:
return None return None
if col == color_row_key:
col = all_columns_string
if role == Qt.DisplayRole: if role == Qt.DisplayRole:
return self.rule_to_html(col, rule) return self.rule_to_html(col, rule)
if role == Qt.UserRole: if role == Qt.UserRole:

View File

@ -11,6 +11,8 @@ __docformat__ = 'restructuredtext en'
import binascii, re, json import binascii, re, json
from textwrap import dedent from textwrap import dedent
color_row_key = '*row'
class Rule(object): # {{{ class Rule(object): # {{{
SIGNATURE = '# BasicColorRule():' SIGNATURE = '# BasicColorRule():'
@ -205,6 +207,7 @@ def conditionable_columns(fm):
yield key yield key
def displayable_columns(fm): def displayable_columns(fm):
yield color_row_key
for key in fm.displayable_field_keys(): for key in fm.displayable_field_keys():
if key not in ('sort', 'author_sort', 'comments', 'formats', if key not in ('sort', 'author_sort', 'comments', 'formats',
'identifiers', 'path'): 'identifiers', 'path'):