mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Build the node tree in the tag browser in the necessary order (user categories last), then hide and reorder the tree as needed.
This commit is contained in:
parent
c68b9b7d64
commit
3fe3e66880
@ -9,6 +9,7 @@ __copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
|
|||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
import traceback, cPickle, copy, os
|
import traceback, cPickle, copy, os
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
from PyQt5.Qt import (QAbstractItemModel, QIcon, QFont, Qt,
|
from PyQt5.Qt import (QAbstractItemModel, QIcon, QFont, Qt,
|
||||||
QMimeData, QModelIndex, pyqtSignal, QObject)
|
QMimeData, QModelIndex, pyqtSignal, QObject)
|
||||||
@ -312,17 +313,12 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
|
|
||||||
last_category_node = None
|
last_category_node = None
|
||||||
category_node_map = {}
|
category_node_map = {}
|
||||||
self.category_node_tree = {}
|
self.user_category_node_tree = {}
|
||||||
for i, key in enumerate(self.row_map):
|
|
||||||
if self.hidden_categories:
|
# We build the node tree including categories that might later not be
|
||||||
if key in self.hidden_categories:
|
# displayed because their items might be in user categories. The resulting
|
||||||
continue
|
# nodes will be reordered later.
|
||||||
found = False
|
for i, key in enumerate(self.categories):
|
||||||
for cat in self.hidden_categories:
|
|
||||||
if cat.startswith('@') and key.startswith(cat + '.'):
|
|
||||||
found = True
|
|
||||||
if found:
|
|
||||||
continue
|
|
||||||
is_gst = False
|
is_gst = False
|
||||||
if key.startswith('@') and key[1:] in gst:
|
if key.startswith('@') and key[1:] in gst:
|
||||||
tt = _(u'The grouped search term name is "{0}"').format(key)
|
tt = _(u'The grouped search term name is "{0}"').format(key)
|
||||||
@ -347,7 +343,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
path_parts = [p for p in key.split('.')]
|
path_parts = [p for p in key.split('.')]
|
||||||
path = ''
|
path = ''
|
||||||
last_category_node = self.root_item
|
last_category_node = self.root_item
|
||||||
tree_root = self.category_node_tree
|
tree_root = self.user_category_node_tree
|
||||||
for i,p in enumerate(path_parts):
|
for i,p in enumerate(path_parts):
|
||||||
path += p
|
path += p
|
||||||
if path not in category_node_map:
|
if path not in category_node_map:
|
||||||
@ -414,9 +410,8 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
|
|
||||||
def process_one_node(category, collapse_model, state_map): # {{{
|
def process_one_node(category, collapse_model, state_map): # {{{
|
||||||
collapse_letter = None
|
collapse_letter = None
|
||||||
category_node = category
|
key = category.category_key
|
||||||
key = category_node.category_key
|
is_gst = category.is_gst
|
||||||
is_gst = category_node.is_gst
|
|
||||||
if key not in data:
|
if key not in data:
|
||||||
return
|
return
|
||||||
if key in gprefs['tag_browser_dont_collapse']:
|
if key in gprefs['tag_browser_dont_collapse']:
|
||||||
@ -503,8 +498,8 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
else:
|
else:
|
||||||
sub_cat = self.create_node(parent=category, data=name,
|
sub_cat = self.create_node(parent=category, data=name,
|
||||||
tooltip=None, temporary=True,
|
tooltip=None, temporary=True,
|
||||||
category_icon=category_node.icon,
|
category_icon=category.icon,
|
||||||
category_key=category_node.category_key,
|
category_key=category.category_key,
|
||||||
icon_map=self.icon_state_map)
|
icon_map=self.icon_state_map)
|
||||||
sub_cat.tag.is_searchable = False
|
sub_cat.tag.is_searchable = False
|
||||||
sub_cat.is_gst = is_gst
|
sub_cat.is_gst = is_gst
|
||||||
@ -518,9 +513,9 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
collapse_letter = cl
|
collapse_letter = cl
|
||||||
sub_cat = self.create_node(parent=category,
|
sub_cat = self.create_node(parent=category,
|
||||||
data=collapse_letter,
|
data=collapse_letter,
|
||||||
category_icon=category_node.icon,
|
category_icon=category.icon,
|
||||||
tooltip=None, temporary=True,
|
tooltip=None, temporary=True,
|
||||||
category_key=category_node.category_key,
|
category_key=category.category_key,
|
||||||
icon_map=self.icon_state_map)
|
icon_map=self.icon_state_map)
|
||||||
sub_cat.is_gst = is_gst
|
sub_cat.is_gst = is_gst
|
||||||
node_parent = sub_cat
|
node_parent = sub_cat
|
||||||
@ -590,10 +585,31 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
return
|
return
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
# Build the entire node tree. Note that category_nodes is in field
|
||||||
|
# metadata order so the user categories will be at the end
|
||||||
for category in self.category_nodes:
|
for category in self.category_nodes:
|
||||||
process_one_node(category, collapse_model,
|
process_one_node(category, collapse_model,
|
||||||
state_map.get(category.category_key, {}))
|
state_map.get(category.category_key, {}))
|
||||||
|
|
||||||
|
# Fix up the node tree, reordering as needed and deleting undisplayed nodes
|
||||||
|
new_children = []
|
||||||
|
for node in self.root_item.children:
|
||||||
|
key = node.category_key
|
||||||
|
if key in self.row_map:
|
||||||
|
if self.hidden_categories:
|
||||||
|
if key in self.hidden_categories:
|
||||||
|
continue
|
||||||
|
found = False
|
||||||
|
for cat in self.hidden_categories:
|
||||||
|
if cat.startswith('@') and key.startswith(cat + '.'):
|
||||||
|
found = True
|
||||||
|
if found:
|
||||||
|
continue
|
||||||
|
new_children.append(node)
|
||||||
|
self.root_item.children = new_children
|
||||||
|
self.root_item.children.sort(key = lambda x: self.row_map.index(x.category_key))
|
||||||
|
|
||||||
|
|
||||||
def get_category_editor_data(self, category):
|
def get_category_editor_data(self, category):
|
||||||
for cat in self.root_item.children:
|
for cat in self.root_item.children:
|
||||||
if cat.category_key == category:
|
if cat.category_key == category:
|
||||||
@ -865,7 +881,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
Called by __init__. Do not directly call this method.
|
Called by __init__. Do not directly call this method.
|
||||||
'''
|
'''
|
||||||
self.row_map = []
|
self.row_map = []
|
||||||
self.categories = {}
|
self.categories = OrderedDict()
|
||||||
|
|
||||||
# Get the categories
|
# Get the categories
|
||||||
try:
|
try:
|
||||||
@ -885,14 +901,16 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
data[category] = [t for t in data[category]
|
data[category] = [t for t in data[category]
|
||||||
if lower(t.name).find(self.filter_categories_by) >= 0]
|
if lower(t.name).find(self.filter_categories_by) >= 0]
|
||||||
|
|
||||||
|
# Build a dict of the keys that have data
|
||||||
tb_categories = self.db.field_metadata
|
tb_categories = self.db.field_metadata
|
||||||
|
for category in tb_categories:
|
||||||
|
if category in data: # The search category can come and go
|
||||||
|
self.categories[category] = tb_categories[category]['name']
|
||||||
|
|
||||||
|
# Now build the list of fields in display order
|
||||||
order = tweaks['tag_browser_category_order']
|
order = tweaks['tag_browser_category_order']
|
||||||
defvalue = order.get('*', 100)
|
defvalue = order.get('*', 100)
|
||||||
tb_keys = sorted(tb_categories.keys(), key=lambda x: order.get(x, defvalue))
|
self.row_map = sorted(self.categories, key=lambda x: order.get(x, defvalue))
|
||||||
for category in tb_keys:
|
|
||||||
if category in data: # The search category can come and go
|
|
||||||
self.row_map.append(category)
|
|
||||||
self.categories[category] = tb_categories[category]['name']
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def set_categories_filter(self, txt):
|
def set_categories_filter(self, txt):
|
||||||
|
@ -491,7 +491,7 @@ class TagsView(QTreeView): # {{{
|
|||||||
# to a user category'
|
# to a user category'
|
||||||
m = self.context_menu.addMenu(self.user_category_icon,
|
m = self.context_menu.addMenu(self.user_category_icon,
|
||||||
_('Add %s to user category')%display_name(tag))
|
_('Add %s to user category')%display_name(tag))
|
||||||
nt = self.model().category_node_tree
|
nt = self.model().user_category_node_tree
|
||||||
def add_node_tree(tree_dict, m, path):
|
def add_node_tree(tree_dict, m, path):
|
||||||
p = path[:]
|
p = path[:]
|
||||||
for k in sorted(tree_dict.keys(), key=sort_key):
|
for k in sorted(tree_dict.keys(), key=sort_key):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user