diff --git a/src/calibre/gui2/preferences/coloring.py b/src/calibre/gui2/preferences/coloring.py
index 4d8dfce9c5..c3445e886d 100644
--- a/src/calibre/gui2/preferences/coloring.py
+++ b/src/calibre/gui2/preferences/coloring.py
@@ -10,7 +10,7 @@ __docformat__ = 'restructuredtext en'
import os, textwrap
from PyQt4.Qt import (QWidget, QDialog, QLabel, QGridLayout, QComboBox, QSize,
- QLineEdit, QIntValidator, QDoubleValidator, QFrame, QColor, Qt, QIcon,
+ QLineEdit, QIntValidator, QDoubleValidator, QFrame, Qt, QIcon,
QScrollArea, QPushButton, QVBoxLayout, QDialogButtonBox, QToolButton,
QListView, QAbstractListModel, pyqtSignal, QSizePolicy, QSpacerItem,
QApplication, QStandardItem, QStandardItemModel, QCheckBox)
@@ -21,6 +21,7 @@ from calibre.utils.icu import sort_key
from calibre.gui2 import error_dialog, choose_files, pixmap_to_data
from calibre.gui2.dialogs.template_dialog import TemplateDialog
from calibre.gui2.metadata.single_download import RichTextDelegate
+from calibre.gui2.widgets2 import ColorButton
from calibre.library.coloring import (Rule, conditionable_columns,
displayable_columns, rule_from_template, color_row_key)
from calibre.utils.localization import lang_map
@@ -33,7 +34,8 @@ icon_rule_kinds = [(_('icon with text'), 'icon'),
(_('composed icons w/text'), 'icon_composed'),
(_('composed icons w/no text'), 'icon_only_composed'),]
-class ConditionEditor(QWidget): # {{{
+
+class ConditionEditor(QWidget): # {{{
ACTION_MAP = {
'bool' : (
@@ -86,7 +88,6 @@ class ConditionEditor(QWidget): # {{{
for x in ('float', 'rating'):
ACTION_MAP[x] = ACTION_MAP['int']
-
def __init__(self, fm, parent=None):
QWidget.__init__(self, parent)
self.fm = fm
@@ -108,8 +109,6 @@ class ConditionEditor(QWidget): # {{{
self.column_box = QComboBox(self)
l.addWidget(self.column_box, 0, 1)
-
-
self.l2 = l2 = QLabel(two)
l.addWidget(l2, 0, 2)
@@ -277,7 +276,7 @@ class ConditionEditor(QWidget): # {{{
self.value_box.setEnabled(False)
# }}}
-class RuleEditor(QDialog): # {{{
+class RuleEditor(QDialog): # {{{
def __init__(self, fm, pref_name, parent=None):
QDialog.__init__(self, parent)
@@ -329,7 +328,7 @@ class RuleEditor(QDialog): # {{{
l.addWidget(l4, 2, 4)
if self.rule_kind == 'color':
- self.color_box = QComboBox(self)
+ self.color_box = ColorButton(parent=self)
self.color_label = QLabel('Sample text Sample text')
self.color_label.setTextFormat(Qt.RichText)
l.addWidget(self.color_box, 2, 5)
@@ -393,7 +392,7 @@ class RuleEditor(QDialog): # {{{
self.conditions = []
if self.rule_kind == 'color':
- for b in (self.column_box, self.color_box):
+ for b in (self.column_box, ):
b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon)
b.setMinimumContentsLength(15)
@@ -407,10 +406,9 @@ class RuleEditor(QDialog): # {{{
self.column_box.setCurrentIndex(0)
if self.rule_kind == 'color':
- self.color_box.addItems(QColor.colorNames())
- self.color_box.setCurrentIndex(0)
+ self.color_box.color = '#000'
self.update_color_label()
- self.color_box.currentIndexChanged.connect(self.update_color_label)
+ self.color_box.color_changed.connect(self.update_color_label)
else:
self.rule_icon_files = []
self.filename_button.clicked.connect(self.filename_button_clicked)
@@ -436,10 +434,10 @@ class RuleEditor(QDialog): # {{{
for i,filename in enumerate(self.icon_file_names):
item = QStandardItem(filename)
if doing_multiple:
- item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled);
+ item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
item.setData(Qt.Unchecked, Qt.CheckStateRole)
else:
- item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable);
+ item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
icon = QIcon(os.path.join(config_dir, 'cc_icons', filename))
item.setIcon(icon)
model.appendRow(item)
@@ -448,7 +446,7 @@ class RuleEditor(QDialog): # {{{
pal = QApplication.palette()
bg1 = unicode(pal.color(pal.Base).name())
bg2 = unicode(pal.color(pal.AlternateBase).name())
- c = unicode(self.color_box.currentText())
+ c = self.color_box.color
self.color_label.setText('''
{st}
{st}
@@ -528,9 +526,7 @@ class RuleEditor(QDialog): # {{{
def apply_rule(self, kind, col, rule):
if kind == 'color':
if rule.color:
- idx = self.color_box.findText(rule.color)
- if idx >= 0:
- self.color_box.setCurrentIndex(idx)
+ self.color_box.color = rule.color
else:
for i,tup in enumerate(icon_rule_kinds):
if kind == tup[1]:
@@ -595,7 +591,7 @@ class RuleEditor(QDialog): # {{{
if self.rule_kind != 'color':
r.color = self.get_filenames_from_box()
else:
- r.color = unicode(self.color_box.currentText())
+ r.color = self.color_box.color
idx = self.column_box.currentIndex()
col = unicode(self.column_box.itemData(idx).toString())
for c in self.conditions:
@@ -611,7 +607,7 @@ class RuleEditor(QDialog): # {{{
return kind, col, r
# }}}
-class RulesModel(QAbstractListModel): # {{{
+class RulesModel(QAbstractListModel): # {{{
def __init__(self, prefs, fm, pref_name, parent=None):
QAbstractListModel.__init__(self, parent)
@@ -623,7 +619,8 @@ class RulesModel(QAbstractListModel): # {{{
rules = list(prefs[pref_name])
self.rules = []
for col, template in rules:
- if col not in self.fm and col != color_row_key: continue
+ if col not in self.fm and col != color_row_key:
+ continue
try:
rule = rule_from_template(self.fm, template)
except:
@@ -634,7 +631,8 @@ class RulesModel(QAbstractListModel): # {{{
rules = list(prefs[pref_name])
self.rules = []
for kind, col, template in rules:
- if col not in self.fm and col != color_row_key: continue
+ if col not in self.fm and col != color_row_key:
+ continue
try:
rule = rule_from_template(self.fm, template)
except:
@@ -764,7 +762,7 @@ class RulesModel(QAbstractListModel): # {{{
# }}}
-class EditRules(QWidget): # {{{
+class EditRules(QWidget): # {{{
changed = pyqtSignal()
@@ -881,7 +879,7 @@ class EditRules(QWidget): # {{{
icon_rule_kind=kind)
if d.exec_() == d.Accepted:
- if len(d.rule) == 2: # Convert template dialog rules to a triple
+ if len(d.rule) == 2: # Convert template dialog rules to a triple
d.rule = ('color', d.rule[0], d.rule[1])
kind, col, r = d.rule
if kind and r is not None and col:
@@ -945,7 +943,7 @@ if __name__ == '__main__':
d.add_blank_condition()
d.exec_()
- col, r = d.rule
+ kind, col, r = d.rule
print ('Column to be colored:', col)
print ('Template:')
diff --git a/src/calibre/gui2/widgets2.py b/src/calibre/gui2/widgets2.py
index 8d801a91bd..c21a6d7ae1 100644
--- a/src/calibre/gui2/widgets2.py
+++ b/src/calibre/gui2/widgets2.py
@@ -6,6 +6,8 @@ from __future__ import (unicode_literals, division, absolute_import,
__license__ = 'GPL v3'
__copyright__ = '2013, Kovid Goyal '
+from PyQt4.Qt import QPushButton, QPixmap, QIcon, QColor, Qt, QColorDialog, pyqtSignal
+
from calibre.gui2.complete2 import LineEdit
from calibre.gui2.widgets import history
@@ -46,3 +48,45 @@ class HistoryLineEdit2(LineEdit):
history.set(self.store_name, self.history)
self.update_items_cache(self.history)
+class ColorButton(QPushButton):
+
+ color_changed = pyqtSignal(object)
+
+ def __init__(self, initial_color=None, parent=None, choose_text=None):
+ QPushButton.__init__(self, parent)
+ self._color = None
+ self.choose_text = choose_text or _('Choose &color')
+ self.color = initial_color
+ self.clicked.connect(self.choose_color)
+
+ @dynamic_property
+ def color(self):
+ def fget(self):
+ return self._color
+ def fset(self, val):
+ val = unicode(val or '')
+ col = QColor(val)
+ orig = self._color
+ if col.isValid():
+ self._color = val
+ self.setText(val)
+ p = QPixmap(self.iconSize())
+ p.fill(col)
+ self.setIcon(QIcon(p))
+ else:
+ self._color = None
+ self.setText(self.choose_text)
+ self.setIcon(QIcon())
+ if orig != col:
+ self.color_changed.emit(self._color)
+ return property(fget=fget, fset=fset)
+
+ def choose_color(self):
+ col = QColorDialog.getColor(QColor(self._color or Qt.white), self, _('Choose a color'))
+ if col.isValid():
+ r, g, b, a = col.getRgb()
+ if a != 255:
+ self.color = '#%02x%02x%02x%02x' % col.getRgb()
+ else:
+ self.color = '#%02x%02x%02x' % (r, g, b)
+