mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
Merge branch 'master' of https://github.com/cbhaley/calibre
This commit is contained in:
commit
f27ca196d8
@ -242,6 +242,11 @@ The following functions are available in addition to those described in single-f
|
||||
* ``author_links(val_separator, pair_separator)`` -- returns a string containing a list of authors and that author's link values in the form ``author1 val_separator author1link pair_separator author2 val_separator author2link`` etc. An author is separated from its link value by the ``val_separator`` string with no added spaces. ``author:linkvalue`` pairs are separated by the ``pair_separator`` string argument with no added spaces. It is up to you to choose separator strings that do not occur in author names or links. An author is included even if the author link is empty.
|
||||
* ``author_sorts(val_separator)`` -- returns a string containing a list of author's sort values for the authors of the book. The sort is the one in the author metadata (different from the author_sort in books). The returned list has the form author sort 1 ``val_separator`` author sort 2 etc. The author sort values in this list are in the same order as the authors of the book. If you want spaces around ``val_separator`` then include them in the separator string
|
||||
* ``booksize()`` -- returns the value of the calibre 'size' field. Returns '' if there are no formats.
|
||||
* ``check_yes_no(field_name, is_undefined, is_false, is_true)`` -- checks the value of the yes/no field named by the lookup key ``field_name`` for a value specified by the parameters, returning "yes" if a match is found, otherwise returning an empty string. Set the parameter ``is_undefined``, ``is_false``, or ``is_true`` to 1 (the number) to check that condition, otherwise set it to 0. Example::
|
||||
|
||||
check_yes_no("#bool", 1, 0, 1)
|
||||
|
||||
returns "yes" if the yes/no field ``"#bool"`` is either undefined (neither True nor False) or True. More than one of ``is_undefined``, ``is_false``, or ``is_true`` can be set to 1. This function is usually used by the ``test()`` or ``is_empty()`` functions.
|
||||
* ``cmp(x, y, lt, eq, gt)`` -- compares x and y after converting both to numbers. Returns ``lt`` if x < y. Returns ``eq`` if x == y. Otherwise returns ``gt``.
|
||||
* ``current_library_name()`` -- return the last name on the path to the current calibre library. This function can be called in template program mode using the template ``{:'current_library_name()'}``.
|
||||
* ``current_library_path()`` -- return the path to the current calibre library. This function can be called in template program mode using the template ``{:'current_library_path()'}``.
|
||||
|
@ -164,6 +164,7 @@ class Bool(Base):
|
||||
l.addWidget(c)
|
||||
c.clicked.connect(self.set_to_no)
|
||||
|
||||
if self.db.prefs.get('bools_are_tristate'):
|
||||
t = _('Clear')
|
||||
c = QPushButton(t, parent)
|
||||
width = c.fontMetrics().boundingRect(t).width() + 7
|
||||
|
@ -38,10 +38,17 @@ icon_rule_kinds = [(_('icon with text'), 'icon'),
|
||||
class ConditionEditor(QWidget): # {{{
|
||||
|
||||
ACTION_MAP = {
|
||||
'bool2' : (
|
||||
(_('is true'), 'is true',),
|
||||
(_('is false'), 'is not true'),
|
||||
),
|
||||
'bool' : (
|
||||
(_('is true'), 'is true',),
|
||||
(_('is not true'), 'is not true'),
|
||||
(_('is false'), 'is false'),
|
||||
(_('is undefined'), 'is undefined')
|
||||
(_('is not false'), 'is not false'),
|
||||
(_('is undefined'), 'is undefined'),
|
||||
(_('is defined'), 'is defined'),
|
||||
),
|
||||
'ondevice' : (
|
||||
(_('is true'), 'is set',),
|
||||
@ -200,6 +207,10 @@ class ConditionEditor(QWidget): # {{{
|
||||
if col:
|
||||
m = self.fm[col]
|
||||
dt = m['datatype']
|
||||
if dt == 'bool':
|
||||
from calibre.gui2.ui import get_gui
|
||||
if not get_gui().current_db.prefs.get('bools_are_tristate'):
|
||||
dt = 'bool2'
|
||||
if dt in self.action_map:
|
||||
actions = self.action_map[dt]
|
||||
else:
|
||||
|
@ -62,6 +62,7 @@ class Rule(object): # {{{
|
||||
return None
|
||||
conditions = [x for x in map(self.apply_condition, self.conditions) if x is not None]
|
||||
conditions = (',\n' + ' '*9).join(conditions)
|
||||
if len(self.conditions) > 1:
|
||||
return dedent('''\
|
||||
program:
|
||||
{sig}
|
||||
@ -70,6 +71,13 @@ class Rule(object): # {{{
|
||||
), '{color}', '');
|
||||
''').format(sig=self.signature, conditions=conditions,
|
||||
color=self.color)
|
||||
else:
|
||||
return dedent('''\
|
||||
program:
|
||||
{sig}
|
||||
test({conditions}, '{color}', '');
|
||||
''').format(sig=self.signature, conditions=conditions,
|
||||
color=self.color)
|
||||
|
||||
def apply_condition(self, condition):
|
||||
col, action, val = condition
|
||||
@ -112,10 +120,13 @@ class Rule(object): # {{{
|
||||
return "test(ondevice(), '', '1')"
|
||||
|
||||
def bool_condition(self, col, action, val):
|
||||
test = {'is true': 'True',
|
||||
'is false': 'False',
|
||||
'is undefined': 'None'}[action]
|
||||
return "strcmp('%s', raw_field('%s'), '', '1', '')"%(test, col)
|
||||
test = {'is true': '0, 0, 1',
|
||||
'is not true': '1, 1, 0',
|
||||
'is false': '0, 1, 0',
|
||||
'is not false': '1, 0, 1',
|
||||
'is undefined': '1, 0, 0',
|
||||
'is defined': '0, 1, 1'}[action]
|
||||
return "check_yes_no('%s', %s)"%(col, test)
|
||||
|
||||
def number_condition(self, col, action, val):
|
||||
lt, eq, gt = {
|
||||
|
@ -1602,12 +1602,42 @@ class BuiltinAuthorSorts(BuiltinFormatterFunction):
|
||||
names = [sort_data.get(n) for n in mi.authors if n.strip()]
|
||||
return val_sep.join(n for n in names)
|
||||
|
||||
class BuiltinCheckYesNo(BuiltinFormatterFunction):
|
||||
name = 'check_yes_no'
|
||||
arg_count = 4
|
||||
category = 'If-then-else'
|
||||
__doc__ = doc = _('check_yes_no(field_name, is_undefined, is_false, is_true) '
|
||||
'-- checks the value of the yes/no field named by the '
|
||||
'lookup key field_name for a value specified by the '
|
||||
'parameters, returning "yes" if a match is found, otherwise '
|
||||
'returning an empty string. Set the parameter is_undefined, '
|
||||
'is_false, or is_true to 1 (the number) to check that '
|
||||
'condition, otherwise set it to 0. Example: '
|
||||
'check_yes_no("#bool", 1, 0, 1) returns "yes" if the '
|
||||
'yes/no field "#bool" is either undefined (neither True '
|
||||
'nor False) or True. More than one of is_undefined, '
|
||||
'is_false, or is_true can be set to 1. This function '
|
||||
'is usually used by the test() or is_empty() functions.')
|
||||
|
||||
def evaluate(self, formatter, kwargs, mi, locals, field, is_undefined, is_false, is_true):
|
||||
res = getattr(mi, field, None)
|
||||
if res is None:
|
||||
if is_undefined == '1':
|
||||
return 'yes'
|
||||
return ""
|
||||
if not isinstance(res, bool):
|
||||
raise ValueError(_('check_yes_no requires the field be a Yes/No custom column'))
|
||||
if is_false == '1' and not res:
|
||||
return 'yes'
|
||||
if is_true == '1' and res:
|
||||
return 'yes'
|
||||
return ""
|
||||
|
||||
_formatter_builtins = [
|
||||
BuiltinAdd(), BuiltinAnd(), BuiltinApproximateFormats(), BuiltinAssign(),
|
||||
BuiltinAuthorLinks(), BuiltinAuthorSorts(), BuiltinBooksize(),
|
||||
BuiltinCapitalize(), BuiltinCmp(), BuiltinContains(), BuiltinCount(),
|
||||
BuiltinCurrentLibraryName(), BuiltinCurrentLibraryPath(),
|
||||
BuiltinCapitalize(), BuiltinCheckYesNo(), BuiltinCmp(), BuiltinContains(),
|
||||
BuiltinCount(), BuiltinCurrentLibraryName(), BuiltinCurrentLibraryPath(),
|
||||
BuiltinDaysBetween(), BuiltinDivide(), BuiltinEval(), BuiltinFirstNonEmpty(),
|
||||
BuiltinField(), BuiltinFinishFormatting(), BuiltinFirstMatchingCmp(),
|
||||
BuiltinFormatDate(), BuiltinFormatNumber(), BuiltinFormatsModtimes(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user