From 19261f15eede6fdf17ec5769a31f8e28c69486bf Mon Sep 17 00:00:00 2001
From: Charles Haley <>
Date: Sun, 29 May 2011 20:12:31 +0100
Subject: [PATCH] Add field box to color wizard
---
.../gui2/dialogs/template_line_editor.py | 169 ++++++++++++------
src/calibre/gui2/preferences/look_feel.py | 3 +-
src/calibre/utils/formatter_functions.py | 16 +-
3 files changed, 127 insertions(+), 61 deletions(-)
diff --git a/src/calibre/gui2/dialogs/template_line_editor.py b/src/calibre/gui2/dialogs/template_line_editor.py
index 3d199b156c..bea2c4e316 100644
--- a/src/calibre/gui2/dialogs/template_line_editor.py
+++ b/src/calibre/gui2/dialogs/template_line_editor.py
@@ -5,12 +5,16 @@ __license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal ' +
- _('You can enter more than one tag per box, separated by commas. '
+ _('You can enter more than one value per box, separated by commas. '
'The comparison ignores letter case.
'
- 'A tag value can be a regular expression. Check the box to turn '
+ 'A value can be a regular expression. Check the box to turn '
'them on. When using regular expressions, note that the wizard '
'puts anchors (^ and $) around the expression, so you '
'must ensure your expression matches from the beginning '
- 'to the end of the tag.
'
+ 'to the end of the column you are checking.
'
'Regular expression examples:') + '' +
- _('
.*
matches any tag. No empty tags are '
- 'checked, so you don\'t need to worry about empty stringsA.*
matches any tag beginning with A.*mystery.*
matches any tag containing '
+ _('.*
matches anything in the column. No '
+ 'empty values are checked, so you don\'t need to worry about '
+ 'empty stringsA.*
matches anything beginning with A.*mystery.*
matches anything containing '
'the word "mystery"
' + - _('Check this box if the tag box contains regular expressions') + '
') - l.addWidget(c, 0, 1, 1, 1) + _('Check this box if the values box contains regular expressions') + '') + l.addWidget(c, 0, 2, 1, 1) - c = QLabel(_('Color if tag found')) + c = QLabel(_('Color if value found')) c.setToolTip('' + _('At least one of the two color boxes must have a value. Leave ' 'one color box empty if you want the template to use the next ' 'line in this wizard. If both boxes are filled in, the rest of ' 'the lines in this wizard will be ignored.') + '
') - l.addWidget(c, 0, 2, 1, 1) - c = QLabel(_('Color if tag not found')) + l.addWidget(c, 0, 3, 1, 1) + c = QLabel(_('Color if value not found')) c.setToolTip('' + _('This box is usually filled in only on the last test. If it is ' - 'filled in before the last test, then the color for tag found box ' + 'filled in before the last test, then the color for value found box ' 'must be empty or all the rest of the tests will be ignored.') + '
') - l.addWidget(c, 0, 3, 1, 1) + l.addWidget(c, 0, 4, 1, 1) self.tagboxes = [] self.colorboxes = [] self.nfcolorboxes = [] self.reboxes = [] + self.colboxes = [] self.colors = [unicode(s) for s in list(QColor.colorNames())] self.colors.insert(0, '') for i in range(0, 10): + w = QComboBox() + w.addItems(self.columns) + l.addWidget(w, i+1, 0, 1, 1) + self.colboxes.append(w) + tb = MultiCompleteLineEdit(self) tb.set_separator(', ') - tb.update_items_cache(self.tags) self.tagboxes.append(tb) - l.addWidget(tb, i+1, 0, 1, 1) + l.addWidget(tb, i+1, 1, 1, 1) + w.currentIndexChanged[str].connect(partial(self.column_changed, valbox=tb)) w = QCheckBox(self) self.reboxes.append(w) - l.addWidget(w, i+1, 1, 1, 1) - - w = QComboBox(self) - w.addItems(self.colors) - self.colorboxes.append(w) l.addWidget(w, i+1, 2, 1, 1) w = QComboBox(self) w.addItems(self.colors) - self.nfcolorboxes.append(w) + self.colorboxes.append(w) l.addWidget(w, i+1, 3, 1, 1) + w = QComboBox(self) + w.addItems(self.colors) + self.nfcolorboxes.append(w) + l.addWidget(w, i+1, 4, 1, 1) + if txt: lines = txt.split('\n')[3:] i = 0 @@ -141,37 +175,59 @@ class TagWizard(QDialog): t, c = vals nc = '' re = False + f = 'tags' else: - t,c,nc,re = vals + t,c,f,nc,re = vals try: self.colorboxes[i].setCurrentIndex(self.colorboxes[i].findText(c)) self.nfcolorboxes[i].setCurrentIndex(self.nfcolorboxes[i].findText(nc)) self.tagboxes[i].setText(t) self.reboxes[i].setChecked(re == '2') + self.colboxes[i].setCurrentIndex(self.colboxes[i].findText(f)) except: pass i += 1 bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel, parent=self) - l.addWidget(bb, 100, 2, 1, 2) + l.addWidget(bb, 100, 3, 1, 2) bb.accepted.connect(self.accepted) bb.rejected.connect(self.reject) self.template = '' + def column_changed(self, s, valbox=None): + k = unicode(s) + if k in self.completion_values: + valbox.update_items_cache(self.completion_values[k]['v']) + if self.completion_values[k]['m']: + valbox.set_separator(', ') + else: + valbox.set_separator(None) + else: + valbox.update_items_cache([]) + valbox.set_separator(None) + def accepted(self): res = ("program:\n#tag wizard -- do not directly edit\n" - " t = field('tags');\n first_non_empty(\n") + " first_non_empty(\n") lines = [] - for tb, cb, nfcb, reb in zip(self.tagboxes, self.colorboxes, - self.nfcolorboxes, self.reboxes): - tags = [t.strip() for t in unicode(tb.text()).split(',') if t.strip()] + for tb, cb, fb, nfcb, reb in zip(self.tagboxes, self.colorboxes, + self.colboxes, self.nfcolorboxes, self.reboxes): + f = unicode(fb.currentText()) + if not f: + continue + m = self.completion_values[f]['m'] c = unicode(cb.currentText()).strip() nfc = unicode(nfcb.currentText()).strip() re = reb.checkState() - if re == 2: - tags = '$|^'.join(tags) + if m: + tags = [t.strip() for t in unicode(tb.text()).split(',') if t.strip()] + if re == 2: + tags = '$|^'.join(tags) + else: + tags = ','.join(tags) else: - tags = ','.join(tags) + tags = unicode(tb.text()).strip() + if not tags or not (c or nfc): continue if c not in self.colors: @@ -185,24 +241,33 @@ class TagWizard(QDialog): show=True, show_copy_button=False) return False if re == 2: - lines.append(" in_list(t, ',', '^{0}$', '{1}', '{2}')".\ - format(tags, c, nfc)) + if m: + lines.append(" in_list(field('{3}'), ',', '^{0}$', '{1}', '{2}')".\ + format(tags, c, nfc, f)) + else: + lines.append(" contains(field('{3}'), '{0}', '{1}', '{2}')".\ + format(tags, c, nfc, f)) else: - lines.append(" str_in_list(t, ',', '{0}', '{1}', '{2}')".\ - format(tags, c, nfc)) + if m: + lines.append(" str_in_list(field('{3}'), ',', '{0}', '{1}', '{2}')".\ + format(tags, c, nfc, f)) + else: + lines.append(" strcmp(field('{3}'), '{0}', '{2}', '{1}', '{2}')".\ + format(tags, c, nfc, f)) res += ',\n'.join(lines) res += ')\n' self.template = res res = '' - for tb, cb, nfcb, reb in zip(self.tagboxes, self.colorboxes, - self.nfcolorboxes, self.reboxes): + for tb, cb, fb, nfcb, reb in zip(self.tagboxes, self.colorboxes, + self.colboxes, self.nfcolorboxes, self.reboxes): t = unicode(tb.text()).strip() if t.endswith(','): t = t[:-1] c = unicode(cb.currentText()).strip() + f = unicode(fb.currentText()) nfc = unicode(nfcb.currentText()).strip() re = unicode(reb.checkState()) - if t and c: - res += '#' + t + ':|:' + c + ':|:' + nfc + ':|:' + re + '\n' + if f and t and c: + res += '#' + t + ':|:' + c + ':|:' + f +':|:' + nfc + ':|:' + re + '\n' self.template += res self.accept() diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py index 37e4588b9b..79db1aecf8 100644 --- a/src/calibre/gui2/preferences/look_feel.py +++ b/src/calibre/gui2/preferences/look_feel.py @@ -204,7 +204,6 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): choices.sort(key=sort_key) choices.insert(0, '') self.column_color_count = db.column_color_count+1 - tags = db.all_tags() mi=None try: @@ -217,7 +216,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): r('column_color_name_'+str(i), db.prefs, choices=choices) r('column_color_template_'+str(i), db.prefs) tpl = getattr(self, 'opt_column_color_template_'+str(i)) - tpl.set_tags(tags) + tpl.set_db(db) tpl.set_mi(mi) toolbutton = getattr(self, 'opt_column_color_wizard_'+str(i)) toolbutton.clicked.connect(tpl.tag_wizard) diff --git a/src/calibre/utils/formatter_functions.py b/src/calibre/utils/formatter_functions.py index 32822e1d72..b66aec2cb9 100644 --- a/src/calibre/utils/formatter_functions.py +++ b/src/calibre/utils/formatter_functions.py @@ -331,9 +331,10 @@ class BuiltinInList(BuiltinFormatterFunction): def evaluate(self, formatter, kwargs, mi, locals, val, sep, pat, fv, nfv): l = [v.strip() for v in val.split(sep) if v.strip()] - for v in l: - if re.search(pat, v, flags=re.I): - return fv + if l: + for v in l: + if re.search(pat, v, flags=re.I): + return fv return nfv class BuiltinStrInList(BuiltinFormatterFunction): @@ -349,10 +350,11 @@ class BuiltinStrInList(BuiltinFormatterFunction): def evaluate(self, formatter, kwargs, mi, locals, val, sep, str, fv, nfv): l = [v.strip() for v in val.split(sep) if v.strip()] c = [v.strip() for v in str.split(sep) if v.strip()] - for v in l: - for t in c: - if strcmp(t, v) == 0: - return fv + if l: + for v in l: + for t in c: + if strcmp(t, v) == 0: + return fv return nfv class BuiltinRe(BuiltinFormatterFunction):