Put column icons into separate rules and a separate preference.

This commit is contained in:
Charles Haley 2013-01-27 22:36:41 +01:00
parent 316a9539d8
commit e758b9fe42
4 changed files with 138 additions and 119 deletions

View File

@ -781,10 +781,12 @@ class BooksModel(QAbstractTableModel): # {{{
if col >= len(self.column_to_dc_map):
return NONE
if role == Qt.DisplayRole:
rules = self.db.prefs['column_icon_rules']
if rules:
key = self.column_map[col]
id_ = self.id(index)
self.column_icon.mi = None
for kind, k, fmt in self.db.prefs['column_color_rules']:
for kind, k, fmt in rules:
if k == key and kind == 'icon_only':
ccicon = self.column_icon(id_, key, fmt, 'icon_only', self.db,
self.formatter, self.icon_cache)
@ -803,12 +805,11 @@ class BooksModel(QAbstractTableModel): # {{{
self.column_color.mi = None
if self.color_row_fmt_cache is None:
self.color_row_fmt_cache = tuple(fmt for kind, key, fmt in
self.db.prefs['column_color_rules'] if kind == 'color' and
key == color_row_key)
self.color_row_fmt_cache = tuple(fmt for key, fmt in
self.db.prefs['column_color_rules'] if key == color_row_key)
for kind, k, fmt in self.db.prefs['column_color_rules']:
if k == key and kind == 'color':
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)
if ccol is not None:
@ -843,11 +844,13 @@ class BooksModel(QAbstractTableModel): # {{{
if ccicon != NONE:
return ccicon
rules = self.db.prefs['column_icon_rules']
if rules:
key = self.column_map[col]
id_ = self.id(index)
self.column_icon.mi = None
need_icon_with_text = False
for kind, k, fmt in self.db.prefs['column_color_rules']:
for kind, k, fmt in rules:
if k == key and kind in ('icon', 'icon_only'):
if kind == 'icon':
need_icon_with_text = True

View File

@ -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, QHBoxLayout)
QApplication)
from calibre import prepare_string_for_xml, sanitize_file_name_unicode
from calibre.constants import config_dir
@ -28,8 +28,7 @@ from calibre.utils.icu import lower
all_columns_string = _('All Columns')
rule_kinds = [(_('color'), 'color'),
(_('icon with text'), 'icon'),
icon_rule_kinds = [(_('icon with text'), 'icon'),
(_('icon with no text'), 'icon_only') ]
class ConditionEditor(QWidget): # {{{
@ -214,8 +213,6 @@ class ConditionEditor(QWidget): # {{{
col = self.current_col
if not col:
return
m = self.fm[col]
dt = m['datatype']
action = self.current_action
if not action:
return
@ -252,7 +249,7 @@ class ConditionEditor(QWidget): # {{{
class RuleEditor(QDialog): # {{{
def __init__(self, fm, parent=None):
def __init__(self, fm, pref_name, parent=None):
QDialog.__init__(self, parent)
self.fm = fm
@ -273,8 +270,13 @@ class RuleEditor(QDialog): # {{{
self.l2 = l2 = QLabel(_('Set the'))
l.addWidget(l2, 2, 0)
if pref_name == 'column_color_rules':
self.rule_kind = 'color'
l.addWidget(QLabel(_('color')))
else:
self.rule_kind = 'icon'
self.kind_box = QComboBox(self)
for tt, t in rule_kinds:
for tt, t in icon_rule_kinds:
self.kind_box.addItem(tt, t)
l.addWidget(self.kind_box, 2, 1)
@ -287,12 +289,13 @@ class RuleEditor(QDialog): # {{{
self.l4 = l4 = QLabel(_('to'))
l.addWidget(l4, 2, 4)
if self.rule_kind == 'color':
self.color_box = QComboBox(self)
self.color_label = QLabel('Sample text Sample text')
self.color_label.setTextFormat(Qt.RichText)
l.addWidget(self.color_box, 2, 5)
l.addWidget(self.color_label, 2, 6)
else:
self.filename_box = QLabel()
l.addWidget(self.filename_box, 2, 5)
self.filename_button = QPushButton(_('Choose icon'))
@ -331,24 +334,28 @@ class RuleEditor(QDialog): # {{{
self.conditions_widget.layout().setAlignment(Qt.AlignTop)
self.conditions = []
if self.rule_kind == 'color':
for b in (self.column_box, self.color_box):
b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon)
b.setMinimumContentsLength(15)
for key in sorted(displayable_columns(fm),
key=lambda(k): sort_key(fm[k]['name']) if k != color_row_key else 0):
if key == color_row_key and self.rule_kind != 'color':
continue
name = all_columns_string if key == color_row_key else fm[key]['name']
if name:
self.column_box.addItem(name, key)
self.column_box.setCurrentIndex(0)
if self.rule_kind == 'color':
self.color_box.addItems(QColor.colorNames())
self.color_box.setCurrentIndex(0)
self.update_color_label()
self.color_box.currentIndexChanged.connect(self.update_color_label)
self.kind_box.currentIndexChanged[int].connect(self.kind_index_changed)
else:
self.filename_button.clicked.connect(self.filename_button_clicked)
self.resize(self.sizeHint())
self.icon_path = None
@ -363,18 +370,6 @@ class RuleEditor(QDialog): # {{{
<span style="color: {c}; background-color: {bg2}">&nbsp;{st}&nbsp;</span>
'''.format(c=c, bg1=bg1, bg2=bg2, st=_('Sample Text')))
def kind_index_changed(self, dex):
if dex != 0:
self.color_label.setVisible(False)
self.color_box.setVisible(False)
self.filename_box.setVisible(True)
self.filename_button.setVisible(True)
else:
self.color_label.setVisible(True)
self.color_box.setVisible(True)
self.filename_box.setVisible(False)
self.filename_button.setVisible(False)
def filename_button_clicked(self):
try:
path = choose_files(self, 'choose_category_icon',
@ -402,17 +397,12 @@ class RuleEditor(QDialog): # {{{
def apply_rule(self, kind, col, rule):
if kind == 'color':
self.kind_box.setCurrentIndex(0)
self.filename_box.setVisible(False)
self.filename_button.setVisible(False)
if rule.color:
idx = self.color_box.findText(rule.color)
if idx >= 0:
self.color_box.setCurrentIndex(idx)
else:
self.kind_box.setCurrentIndex(1 if kind == 'icon' else 2)
self.color_box.setVisible(False)
self.color_label.setVisible(False)
self.kind_box.setCurrentIndex(0 if kind == 'icon' else 1)
self.filename_box.setText(rule.color)
for i in range(self.column_box.count()):
@ -421,9 +411,11 @@ class RuleEditor(QDialog): # {{{
self.column_box.setCurrentIndex(i)
break
if rule.color:
if kind == 'color':
idx = self.color_box.findText(rule.color)
if idx >= 0:
self.color_box.setCurrentIndex(idx)
else:
self.filename_box.setText(rule.color)
for c in rule.conditions:
@ -438,7 +430,7 @@ class RuleEditor(QDialog): # {{{
def accept(self):
if self.kind_box.currentIndex() != 0:
if self.rule_kind != 'color':
path = self.icon_path
if path:
try:
@ -479,8 +471,7 @@ class RuleEditor(QDialog): # {{{
@property
def rule(self):
r = Rule(self.fm)
kind = unicode(self.kind_box.itemData(self.kind_box.currentIndex()).toString())
if kind != 'color':
if self.rule_kind != 'color':
r.color = unicode(self.filename_box.text())
else:
r.color = unicode(self.color_box.currentText())
@ -490,20 +481,39 @@ class RuleEditor(QDialog): # {{{
condition = c.condition
if condition is not None:
r.add_condition(*condition)
if self.rule_kind == 'icon':
kind = unicode(self.kind_box.itemData(
self.kind_box.currentIndex()).toString())
else:
kind = 'color'
return kind, col, r
# }}}
class RulesModel(QAbstractListModel): # {{{
def __init__(self, prefs, fm, parent=None):
def __init__(self, prefs, fm, pref_name, parent=None):
QAbstractListModel.__init__(self, parent)
self.fm = fm
rules = list(prefs['column_color_rules'])
self.pref_name = pref_name
if pref_name == 'column_color_rules':
self.rule_kind = 'color'
rules = list(prefs[pref_name])
self.rules = []
for col, template in rules:
if col not in self.fm and col != color_row_key: continue
try:
rule = rule_from_template(self.fm, template)
except:
rule = template
self.rules.append(('color', col, rule))
else:
self.rule_kind = 'icon'
rules = list(prefs[pref_name])
self.rules = []
for kind, col, template in rules:
if col not in self.fm: continue
if col not in self.fm and col != color_row_key: continue
try:
rule = rule_from_template(self.fm, template)
except:
@ -547,8 +557,11 @@ class RulesModel(QAbstractListModel): # {{{
if isinstance(r, Rule):
r = r.template
if r is not None:
if kind == 'color':
rules.append((col, r))
else:
rules.append((kind, col, r))
prefs['column_color_rules'] = rules
prefs[self.pref_name] = rules
def move(self, idx, delta):
row = idx.row() + delta
@ -574,7 +587,10 @@ class RulesModel(QAbstractListModel): # {{{
conditions = [self.condition_to_html(c) for c in rule.conditions]
trans_kind = 'not found'
for tt, t in rule_kinds:
if kind == 'color':
trans_kind = _('color')
else:
for tt, t in icon_rule_kinds:
if kind == t:
trans_kind = tt
break
@ -656,8 +672,9 @@ class EditRules(QWidget): # {{{
b.clicked.connect(self.add_advanced)
l.addWidget(b, 3, 0, 1, 2)
def initialize(self, fm, prefs, mi):
self.model = RulesModel(prefs, fm)
def initialize(self, fm, prefs, mi, pref_name):
self.pref_name = pref_name
self.model = RulesModel(prefs, fm, self.pref_name)
self.rules_view.setModel(self.model)
self.fm = fm
self.mi = mi
@ -671,7 +688,7 @@ class EditRules(QWidget): # {{{
self.changed.emit()
def add_rule(self):
d = RuleEditor(self.model.fm)
d = RuleEditor(self.model.fm, self.pref_name)
d.add_blank_condition()
self._add_rule(d)
@ -685,7 +702,7 @@ class EditRules(QWidget): # {{{
except:
return
if isinstance(rule, Rule):
d = RuleEditor(self.model.fm)
d = RuleEditor(self.model.fm, self.pref_name)
d.apply_rule(kind, col, rule)
else:
d = TemplateDialog(self, rule, mi=self.mi, fm=self.fm, color_field=col)
@ -748,7 +765,7 @@ if __name__ == '__main__':
db = db()
if True:
d = RuleEditor(db.field_metadata)
d = RuleEditor(db.field_metadata, 'column_color_rules')
d.add_blank_condition()
d.exec_()

View File

@ -181,6 +181,12 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.edit_rules.changed.connect(self.changed_signal)
self.tabWidget.addTab(self.edit_rules,
QIcon(I('format-fill-color.png')), _('Column coloring'))
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'))
self.tabWidget.setCurrentIndex(0)
keys = [QKeySequence('F11', QKeySequence.PortableText), QKeySequence(
'Ctrl+Shift+F', QKeySequence.PortableText)]
@ -203,7 +209,8 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
mi = db.get_metadata(idx, index_is_id=False)
except:
mi=None
self.edit_rules.initialize(db.field_metadata, db.prefs, mi)
self.edit_rules.initialize(db.field_metadata, db.prefs, mi, 'column_color_rules')
self.icon_rules.initialize(db.field_metadata, db.prefs, mi, 'column_icon_rules')
def restore_defaults(self):
ConfigWidgetBase.restore_defaults(self)
@ -214,6 +221,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.update_font_display()
self.display_model.restore_defaults()
self.edit_rules.clear()
self.icon_rules.clear()
self.changed_signal.emit()
def build_font_obj(self):
@ -273,6 +281,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
rr = True
self.display_model.commit()
self.edit_rules.commit(self.gui.current_db.prefs)
self.icon_rules.commit(self.gui.current_db.prefs)
return rr
def refresh_gui(self, gui):

View File

@ -211,6 +211,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
defs['gui_restriction'] = defs['cs_restriction'] = ''
defs['categories_using_hierarchy'] = []
defs['column_color_rules'] = []
defs['column_icon_rules'] = []
defs['grouped_search_make_user_categories'] = []
defs['similar_authors_search_key'] = 'authors'
defs['similar_authors_match_kind'] = 'match_any'
@ -253,17 +254,6 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
if old_rules:
self.prefs['column_color_rules'] += old_rules
new_rules = []
must_save_new_rules = False
for tup in self.prefs['column_color_rules']:
if len(tup) == 2:
must_save_new_rules = True;
new_rules.append( ('color', tup[0], tup[1]) )
else:
new_rules.append(tup)
if must_save_new_rules:
self.prefs['column_color_rules'] = new_rules
# Migrate saved search and user categories to db preference scheme
def migrate_preference(key, default):
oldval = prefs[key]