mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Allow specifying arbitrary colors for column coloring rules
This commit is contained in:
parent
a7d4fa16f0
commit
fce3f56826
@ -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('''
|
||||
<span style="color: {c}; background-color: {bg1}"> {st} </span>
|
||||
<span style="color: {c}; background-color: {bg2}"> {st} </span>
|
||||
@ -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:')
|
||||
|
@ -6,6 +6,8 @@ from __future__ import (unicode_literals, division, absolute_import,
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
|
||||
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)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user