mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Tag Browser: Fix incorrect grouping of words starting with graphemes, such as ash. Fixes #1422116 [Some letters break the category splitting](https://bugs.launchpad.net/calibre/+bug/1422116)
Fix Virtual Libraries not working in the View Manager plugin if the user never clicks the Virtual Library button before using the plugin. Merge branch 'master' of https://github.com/cbhaley/calibre
This commit is contained in:
commit
69b15134df
@ -941,11 +941,13 @@ class Cache(object):
|
||||
return self._search_api(self, query, restriction, virtual_fields=virtual_fields, book_ids=book_ids)
|
||||
|
||||
@api
|
||||
def get_categories(self, sort='name', book_ids=None, icon_map=None, already_fixed=None):
|
||||
def get_categories(self, sort='name', book_ids=None, icon_map=None, already_fixed=None,
|
||||
first_letter_sort=False):
|
||||
' Used internally to implement the Tag Browser '
|
||||
try:
|
||||
with self.safe_read_lock:
|
||||
return get_categories(self, sort=sort, book_ids=book_ids, icon_map=icon_map)
|
||||
return get_categories(self, sort=sort, book_ids=book_ids, icon_map=icon_map,
|
||||
first_letter_sort=first_letter_sort)
|
||||
except InvalidLinkTable as err:
|
||||
bad_field = err.field_name
|
||||
if bad_field == already_fixed:
|
||||
|
@ -15,7 +15,7 @@ from future_builtins import map
|
||||
from calibre.ebooks.metadata import author_to_author_sort
|
||||
from calibre.library.field_metadata import TagsIcons
|
||||
from calibre.utils.config_base import tweaks
|
||||
from calibre.utils.icu import sort_key
|
||||
from calibre.utils.icu import sort_key, collation_order
|
||||
|
||||
CATEGORY_SORTS = ('name', 'popularity', 'rating') # This has to be a tuple not a set
|
||||
|
||||
@ -116,19 +116,22 @@ def clean_user_categories(dbcache):
|
||||
pass
|
||||
return new_cats
|
||||
|
||||
def sort_categories(items, sort):
|
||||
reverse = True
|
||||
def sort_categories(items, sort, first_letter_sort=False):
|
||||
if sort == 'popularity':
|
||||
key=attrgetter('count')
|
||||
key=lambda x:(-getattr(x, 'count', 0), sort_key(x.sort or x.name))
|
||||
elif sort == 'rating':
|
||||
key=attrgetter('avg_rating')
|
||||
key=lambda x:(-getattr(x, 'avg_rating', 0.0), sort_key(x.sort or x.name))
|
||||
else:
|
||||
if first_letter_sort:
|
||||
key=lambda x:(collation_order(icu_upper(x.sort or x.name or ' ')),
|
||||
sort_key(x.sort or x.name))
|
||||
else:
|
||||
key=lambda x:sort_key(x.sort or x.name)
|
||||
reverse=False
|
||||
items.sort(key=key, reverse=reverse)
|
||||
items.sort(key=key)
|
||||
return items
|
||||
|
||||
def get_categories(dbcache, sort='name', book_ids=None, icon_map=None):
|
||||
def get_categories(dbcache, sort='name', book_ids=None, icon_map=None,
|
||||
first_letter_sort=False):
|
||||
if icon_map is not None and type(icon_map) != TagsIcons:
|
||||
raise TypeError('icon_map passed to get_categories must be of type TagIcons')
|
||||
if sort not in CATEGORY_SORTS:
|
||||
@ -170,7 +173,7 @@ def get_categories(dbcache, sort='name', book_ids=None, icon_map=None):
|
||||
cat['is_multiple'] and cat['display'].get('is_names', False)):
|
||||
for item in cats:
|
||||
item.sort = author_to_author_sort(item.sort)
|
||||
sort_categories(cats, sort)
|
||||
sort_categories(cats, sort, first_letter_sort=first_letter_sort)
|
||||
categories[category] = cats
|
||||
|
||||
# Needed for legacy databases that have multiple ratings that
|
||||
|
@ -341,6 +341,7 @@ class SearchRestrictionMixin(object):
|
||||
self.ar_menu = QMenu(_('Additional restriction'))
|
||||
self.edit_menu = QMenu(_('Edit Virtual Library'))
|
||||
self.rm_menu = QMenu(_('Remove Virtual Library'))
|
||||
self.search_restriction_list_built = False
|
||||
|
||||
def add_virtual_library(self, db, name, search):
|
||||
virt_libs = db.prefs.get('virtual_libraries', {})
|
||||
@ -498,6 +499,7 @@ class SearchRestrictionMixin(object):
|
||||
return name[0:MAX_VIRTUAL_LIBRARY_NAME_LENGTH].strip()
|
||||
|
||||
def build_search_restriction_list(self):
|
||||
self.search_restriction_list_built = True
|
||||
from calibre.gui2.ui import get_gui
|
||||
m = self.ar_menu
|
||||
m.clear()
|
||||
@ -539,6 +541,8 @@ class SearchRestrictionMixin(object):
|
||||
self.apply_search_restriction(index)
|
||||
|
||||
def apply_named_search_restriction(self, name):
|
||||
if not self.search_restriction_list_built:
|
||||
self.build_search_restriction_list()
|
||||
if not name:
|
||||
r = 0
|
||||
else:
|
||||
@ -549,6 +553,8 @@ class SearchRestrictionMixin(object):
|
||||
self.apply_search_restriction(r)
|
||||
|
||||
def apply_text_search_restriction(self, search):
|
||||
if not self.search_restriction_list_built:
|
||||
self.build_search_restriction_list()
|
||||
search = unicode(search)
|
||||
if not search:
|
||||
self.search_restriction.setCurrentIndex(0)
|
||||
@ -567,6 +573,8 @@ class SearchRestrictionMixin(object):
|
||||
self._apply_search_restriction(search, self._trim_restriction_name(s))
|
||||
|
||||
def apply_search_restriction(self, i):
|
||||
if not self.search_restriction_list_built:
|
||||
self.build_search_restriction_list()
|
||||
if i == 1:
|
||||
self.apply_text_search_restriction(unicode(self.search.currentText()))
|
||||
elif i == 2 and unicode(self.search_restriction.currentText()).startswith('*'):
|
||||
|
@ -865,16 +865,19 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
# Get the categories
|
||||
if self.db.data.get_base_restriction() or self.db.data.get_search_restriction():
|
||||
try:
|
||||
data = self.db.get_categories(sort=sort,
|
||||
data = self.db.new_api.get_categories(sort=sort,
|
||||
icon_map=self.category_icon_map,
|
||||
ids=self.db.search('', return_matches=True, sort_results=False))
|
||||
book_ids=self.db.search('', return_matches=True, sort_results=False),
|
||||
first_letter_sort = self.collapse_model == 'first letter')
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
data = self.db.get_categories(sort=sort, icon_map=self.category_icon_map)
|
||||
data = self.db.new_api.get_categories(sort=sort, icon_map=self.category_icon_map,
|
||||
first_letter_sort = self.collapse_model == 'first letter')
|
||||
self.restriction_error.emit()
|
||||
else:
|
||||
data = self.db.get_categories(sort=sort, icon_map=self.category_icon_map)
|
||||
data = self.db.new_api.get_categories(sort=sort, icon_map=self.category_icon_map,
|
||||
first_letter_sort = self.collapse_model == 'first letter')
|
||||
|
||||
# Reconstruct the user categories, putting them into metadata
|
||||
self.db.field_metadata.remove_dynamic_categories()
|
||||
|
Loading…
x
Reference in New Issue
Block a user