diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index 7ead59ac06..101932a777 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -286,14 +286,15 @@ class Cache(object): ''' with self.write_lock: self.backend.read_tables() + bools_are_tristate = self.backend.prefs['bools_are_tristate'] for field, table in self.backend.tables.iteritems(): - self.fields[field] = create_field(field, table) + self.fields[field] = create_field(field, table, bools_are_tristate) if table.metadata['datatype'] == 'composite': self.composites[field] = self.fields[field] self.fields['ondevice'] = create_field('ondevice', - VirtualTable('ondevice')) + VirtualTable('ondevice'), bools_are_tristate) for name, field in self.fields.iteritems(): if name[0] == '#' and name.endswith('_index'): diff --git a/src/calibre/db/fields.py b/src/calibre/db/fields.py index aeee1b6f45..7ade57b1a2 100644 --- a/src/calibre/db/fields.py +++ b/src/calibre/db/fields.py @@ -26,7 +26,7 @@ class Field(object): is_many_many = False is_composite = False - def __init__(self, name, table): + def __init__(self, name, table, bools_are_tristate): self.name, self.table = name, table dt = self.metadata['datatype'] self.has_text_data = dt in {'text', 'comments', 'series', 'enumeration'} @@ -43,6 +43,10 @@ class Field(object): self._default_sort_key = 0 elif dt == 'bool': self._default_sort_key = None + if bools_are_tristate: + self._sort_key = lambda x:{True: 1, False: 2, None: 3}.get(x, 3) + else: + self._sort_key = lambda x:{True: 1, False: 2, None: 2}.get(x, 2) elif dt == 'datetime': self._default_sort_key = UNDEFINED_DATE if tweaks['sort_dates_using_visible_fields']: @@ -248,7 +252,7 @@ class CompositeField(OneToOneField): class OnDeviceField(OneToOneField): - def __init__(self, name, table): + def __init__(self, name, table, bools_are_tristate): self.name = name self.book_on_device_func = None self.is_multiple = False @@ -565,7 +569,7 @@ class TagsField(ManyToManyField): ans.append(c) return ans -def create_field(name, table): +def create_field(name, table, bools_are_tristate): cls = { ONE_ONE: OneToOneField, MANY_ONE: ManyToOneField, @@ -585,5 +589,5 @@ def create_field(name, table): cls = CompositeField elif table.metadata['datatype'] == 'series': cls = SeriesField - return cls(name, table) + return cls(name, table, bools_are_tristate) diff --git a/src/calibre/db/tests/reading.py b/src/calibre/db/tests/reading.py index 4c87662de3..5d1061ecae 100644 --- a/src/calibre/db/tests/reading.py +++ b/src/calibre/db/tests/reading.py @@ -125,7 +125,7 @@ class ReadingTest(BaseTest): def test_sorting(self): # {{{ 'Test sorting' - cache = self.init_cache(self.library_path) + cache = self.init_cache() for field, order in { 'title' : [2, 1, 3], 'authors': [2, 1, 3], @@ -147,7 +147,7 @@ class ReadingTest(BaseTest): '#rating':[3, 2, 1], '#series':[3, 2, 1], '#tags':[3, 2, 1], - '#yesno':[3, 1, 2], + '#yesno':[2, 1, 3], '#comments':[3, 2, 1], }.iteritems(): x = list(reversed(order)) @@ -189,6 +189,11 @@ class ReadingTest(BaseTest): c2 = self.init_cache() self.assertEqual([3, 2, 1], c2.multisort([('pubdate', True)])) + # Test bool sorting when not tristate + cache.set_pref('bools_are_tristate', False) + c2 = self.init_cache() + self.assertEqual([2, 3, 1], c2.multisort([('#yesno', True), ('id', False)])) + # }}} def test_get_metadata(self): # {{{