mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Make icon rules composable.
This commit is contained in:
parent
9c3e61cee2
commit
2fe01db004
@ -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()),
|
||||
|
@ -69,33 +69,19 @@
|
||||
<widget class="QWidget" name="icon_layout">
|
||||
<layout class="QGridLayout">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QGroupBox">
|
||||
<property name="title">
|
||||
<string>Kind</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="icon_without_text">
|
||||
<widget class="QLabel">
|
||||
<property name="text">
|
||||
<string>icon with no text</string>
|
||||
<string>Kind:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="icon_with_text">
|
||||
<property name="text">
|
||||
<string>icon with text</string>
|
||||
</property>
|
||||
<widget class="QComboBox" name="icon_kind">
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>100</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="icon_chooser_label">
|
||||
|
@ -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,
|
||||
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_][key+'icon_only'] = 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,
|
||||
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_][key+'icon'] = self.bool_blank_icon
|
||||
self.icon_cache[id_][cache_index] = self.bool_blank_icon
|
||||
return self.bool_blank_icon
|
||||
self.icon_cache[id_][key+'icon'] = None
|
||||
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,
|
||||
|
@ -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): # {{{
|
||||
<p>Advanced Rule: set <b>%(typ)s</b> for column <b>%(col)s</b>:
|
||||
<pre>%(rule)s</pre>
|
||||
''')%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 _('''\
|
||||
<p>Set the <b>%(kind)s</b> of <b>%(col)s</b> to <b>%(color)s</b> if the following
|
||||
conditions are met:</p>
|
||||
|
Loading…
x
Reference in New Issue
Block a user