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:
Charles Haley 2015-11-21 11:29:08 +01:00
parent c68b9b7d64
commit 3fe3e66880
2 changed files with 44 additions and 26 deletions

View File

@ -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):

View File

@ -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):