mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 18:54:09 -04:00
Merge branch 'master' of https://github.com/cbhaley/calibre
Fix #1955732 [Hierarchical entries in user category may not merge correctly in tag browser](https://bugs.launchpad.net/calibre/+bug/1955732)
This commit is contained in:
commit
67cddcea52
@ -44,7 +44,8 @@ class Tag:
|
||||
|
||||
@property
|
||||
def string_representation(self):
|
||||
return '%s:%s:%s:%s:%s'%(self.name, self.count, self.id, self.state, self.category)
|
||||
return '%s:%s:%s:%s:%s:%s'%(self.name, self.count, self.id, self.state,
|
||||
self.category, self.original_categories)
|
||||
|
||||
def __str__(self):
|
||||
return self.string_representation
|
||||
@ -207,10 +208,11 @@ def get_categories(dbcache, sort='name', book_ids=None, first_letter_sort=False)
|
||||
for c in gst:
|
||||
if c not in muc:
|
||||
continue
|
||||
user_categories[c] = []
|
||||
uc = []
|
||||
for sc in gst[c]:
|
||||
for t in categories.get(sc, ()):
|
||||
user_categories[c].append([t.name, sc, 0])
|
||||
uc.append([t.name, sc, 0])
|
||||
user_categories[c] = uc
|
||||
|
||||
if user_categories:
|
||||
# We want to use same node in the user category as in the source
|
||||
|
@ -56,13 +56,14 @@ class TagTreeItem: # {{{
|
||||
file_icon_provider = None
|
||||
|
||||
def __init__(self, data=None, is_category=False, icon_map=None,
|
||||
parent=None, tooltip=None, category_key=None, temporary=False):
|
||||
parent=None, tooltip=None, category_key=None, temporary=False,
|
||||
is_gst=False):
|
||||
if self.file_icon_provider is None:
|
||||
self.file_icon_provider = TagTreeItem.file_icon_provider = file_icon_provider().icon_from_ext
|
||||
self.parent = parent
|
||||
self.children = []
|
||||
self.blank = QIcon()
|
||||
self.is_gst = False
|
||||
self.is_gst = is_gst
|
||||
self.boxed = False
|
||||
self.temporary = False
|
||||
self.can_be_edited = False
|
||||
@ -103,6 +104,12 @@ class TagTreeItem: # {{{
|
||||
del self.parent
|
||||
del self.children
|
||||
|
||||
def root_node(self):
|
||||
p = self
|
||||
while p.parent.type != self.ROOT:
|
||||
p = p.parent
|
||||
return p
|
||||
|
||||
def ensure_icon(self):
|
||||
if self.icon_state_map[0] is not None:
|
||||
return
|
||||
@ -110,6 +117,9 @@ class TagTreeItem: # {{{
|
||||
if self.tag.category == 'formats':
|
||||
fmt = self.tag.original_name.replace('ORIGINAL_', '')
|
||||
cc = self.file_icon_provider(fmt)
|
||||
else:
|
||||
if self.is_gst:
|
||||
cc = self.category_custom_icons.get(self.root_node().category_key, None)
|
||||
else:
|
||||
cc = self.category_custom_icons.get(self.tag.category, None)
|
||||
elif self.type == self.CATEGORY:
|
||||
@ -461,6 +471,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
node = self.create_node(parent=last_category_node,
|
||||
data=p[1:] if i == 0 else p,
|
||||
is_category=True,
|
||||
is_gst = is_gst,
|
||||
tooltip=tt if path == key else path,
|
||||
category_key=path,
|
||||
icon_map=self.icon_state_map)
|
||||
@ -468,7 +479,6 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
category_node_map[path] = node
|
||||
self.category_nodes.append(node)
|
||||
node.can_be_edited = (not is_gst) and (i == (len(path_parts)-1))
|
||||
node.is_gst = is_gst
|
||||
if not is_gst:
|
||||
node.tag.is_hierarchical = '5state'
|
||||
tree_root[p] = {}
|
||||
@ -481,9 +491,9 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
node = self.create_node(parent=self.root_item,
|
||||
data=self.categories[key],
|
||||
is_category=True,
|
||||
is_gst = False,
|
||||
tooltip=tt, category_key=key,
|
||||
icon_map=self.icon_state_map)
|
||||
node.is_gst = False
|
||||
category_node_map[key] = node
|
||||
last_category_node = node
|
||||
self.category_nodes.append(node)
|
||||
@ -663,10 +673,10 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
sub_cat = self.create_node(parent=category, data=name,
|
||||
tooltip=None, temporary=True,
|
||||
is_category=True,
|
||||
is_gst=is_gst,
|
||||
category_key=category.category_key,
|
||||
icon_map=self.icon_state_map)
|
||||
sub_cat.tag.is_searchable = False
|
||||
sub_cat.is_gst = is_gst
|
||||
node_parent = sub_cat
|
||||
last_idx = idx # remember where we last partitioned
|
||||
else:
|
||||
@ -678,10 +688,10 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
sub_cat = self.create_node(parent=category,
|
||||
data=collapse_letter,
|
||||
is_category=True,
|
||||
is_gst=is_gst,
|
||||
tooltip=None, temporary=True,
|
||||
category_key=category.category_key,
|
||||
icon_map=self.icon_state_map)
|
||||
sub_cat.is_gst = is_gst
|
||||
node_parent = sub_cat
|
||||
else:
|
||||
node_parent = category
|
||||
@ -698,28 +708,29 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
(fm['is_custom'] and fm['display'].get('is_names', False)) or
|
||||
not category_is_hierarchical or len(components) == 1):
|
||||
n = self.create_node(parent=node_parent, data=tag, tooltip=tt,
|
||||
icon_map=self.icon_state_map)
|
||||
is_gst=is_gst, icon_map=self.icon_state_map)
|
||||
category_child_map[tag.name, tag.category] = n
|
||||
else:
|
||||
child_key = key if is_gst else tag.category
|
||||
for i,comp in enumerate(components):
|
||||
if i == 0:
|
||||
child_map = category_child_map
|
||||
top_level_component = comp
|
||||
else:
|
||||
child_map = {(t.tag.name, t.tag.category): t
|
||||
for t in node_parent.children
|
||||
child_map = {(t.tag.name, key if is_gst else t.tag.category):
|
||||
t for t in node_parent.children
|
||||
if t.type != TagTreeItem.CATEGORY}
|
||||
if (comp,tag.category) in child_map:
|
||||
node_parent = child_map[(comp,tag.category)]
|
||||
if (comp,child_key) in child_map:
|
||||
node_parent = child_map[(comp,child_key)]
|
||||
t = node_parent.tag
|
||||
t.is_hierarchical = '5state' if tag.category != 'search' else '3state'
|
||||
if tag.id_set is not None and t.id_set is not None:
|
||||
t.id_set = t.id_set | tag.id_set
|
||||
intermediate_nodes[t.original_name, t.category] = t
|
||||
intermediate_nodes[t.original_name,child_key] = t
|
||||
else:
|
||||
if i < len(components)-1:
|
||||
original_name = '.'.join(components[:i+1])
|
||||
t = intermediate_nodes.get((original_name, tag.category), None)
|
||||
t = intermediate_nodes.get((original_name, child_key), None)
|
||||
if t is None:
|
||||
t = copy.copy(tag)
|
||||
t.original_name = original_name
|
||||
@ -730,18 +741,19 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
t.is_editable = False
|
||||
else:
|
||||
t.is_searchable = t.is_editable = False
|
||||
intermediate_nodes[original_name, tag.category] = t
|
||||
intermediate_nodes[original_name,child_key] = t
|
||||
else:
|
||||
t = tag
|
||||
if not in_uc:
|
||||
t.original_name = t.name
|
||||
intermediate_nodes[t.original_name, t.category] = t
|
||||
intermediate_nodes[t.original_name,child_key] = t
|
||||
t.is_hierarchical = \
|
||||
'5state' if t.category != 'search' else '3state'
|
||||
t.name = comp
|
||||
node_parent = self.create_node(parent=node_parent, data=t,
|
||||
tooltip=tt, icon_map=self.icon_state_map)
|
||||
child_map[(comp,tag.category)] = node_parent
|
||||
node_parent = self.create_node(parent=node_parent,
|
||||
data=t, is_gst=is_gst, tooltip=tt,
|
||||
icon_map=self.icon_state_map)
|
||||
child_map[(comp, child_key)] = node_parent
|
||||
|
||||
# Correct the average rating for the node
|
||||
total = count = 0
|
||||
|
Loading…
x
Reference in New Issue
Block a user