Fixes for user categories having names with leading or trailing dots or empty names.

This commit is contained in:
Charles Haley 2011-02-25 15:10:01 +00:00
parent 238a2b4839
commit 1228886b1c
3 changed files with 41 additions and 5 deletions

View File

@ -171,6 +171,13 @@ class TagCategories(QDialog, Ui_TagCategories):
cat_name = unicode(self.input_box.text()).strip() cat_name = unicode(self.input_box.text()).strip()
if cat_name == '': if cat_name == '':
return False return False
comps = [c.strip() for c in cat_name.split('.') if c.strip()]
if len(comps) == 0 or '.'.join(comps) != cat_name:
error_dialog(self, _('Invalid name'),
_('That name contains leading or trailing periods, '
'multiple periods in a row or spaces before '
'or after periods.')).exec_()
return False
for c in self.categories: for c in self.categories:
if strcmp(c, cat_name) == 0: if strcmp(c, cat_name) == 0:
error_dialog(self, _('Name already used'), error_dialog(self, _('Name already used'),
@ -193,6 +200,14 @@ class TagCategories(QDialog, Ui_TagCategories):
return False return False
if not self.current_cat_name: if not self.current_cat_name:
return False return False
comps = [c.strip() for c in cat_name.split('.') if c.strip()]
if len(comps) == 0 or '.'.join(comps) != cat_name:
error_dialog(self, _('Invalid name'),
_('That name contains leading or trailing periods, '
'multiple periods in a row or spaces before '
'or after periods.')).exec_()
return False
for c in self.categories: for c in self.categories:
if strcmp(c, cat_name) == 0: if strcmp(c, cat_name) == 0:
error_dialog(self, _('Name already used'), error_dialog(self, _('Name already used'),

View File

@ -685,7 +685,9 @@ class TagsModel(QAbstractItemModel): # {{{
self.filter_categories_by = filter_categories_by self.filter_categories_by = filter_categories_by
self.collapse_model = collapse_model self.collapse_model = collapse_model
# get_node_tree cannot return None here, because row_map is empty # get_node_tree cannot return None here, because row_map is empty. Note
# that get_node_tree can indirectly change the user_categories dict.
data = self.get_node_tree(config['sort_tags_by']) data = self.get_node_tree(config['sort_tags_by'])
gst = db.prefs.get('grouped_search_terms', {}) gst = db.prefs.get('grouped_search_terms', {})
self.root_item = TagTreeItem() self.root_item = TagTreeItem()
@ -707,7 +709,7 @@ class TagsModel(QAbstractItemModel): # {{{
tt = _(u'The lookup/search name is "{0}"').format(r) tt = _(u'The lookup/search name is "{0}"').format(r)
if r.startswith('@'): if r.startswith('@'):
path_parts = [p.strip() for p in r.split('.') if p.strip()] path_parts = [p for p in r.split('.')]
path = '' path = ''
last_category_node = self.root_item last_category_node = self.root_item
tree_root = self.category_node_tree tree_root = self.category_node_tree
@ -1178,7 +1180,10 @@ class TagsModel(QAbstractItemModel): # {{{
# category display order is important here. The following works # category display order is important here. The following works
# only of all the non-user categories are displayed before the # only of all the non-user categories are displayed before the
# user categories # user categories
components = [t for t in original_name(tag).split('.')] components = [t.strip() for t in original_name(tag).split('.')
if t.strip()]
if len(components) == 0 or '.'.join(components) != original_name(tag):
components = [original_name(tag)]
in_uc = fm['kind'] == 'user' in_uc = fm['kind'] == 'user'
if (not tag.is_hierarchical) and (in_uc or if (not tag.is_hierarchical) and (in_uc or
key in ['authors', 'publisher', 'news', 'formats', 'rating'] or key in ['authors', 'publisher', 'news', 'formats', 'rating'] or
@ -1264,7 +1269,7 @@ class TagsModel(QAbstractItemModel): # {{{
# working with the last item and that item is deleted, in which case # working with the last item and that item is deleted, in which case
# we position at the parent label # we position at the parent label
path = index.model().path_for_index(index) path = index.model().path_for_index(index)
val = unicode(value.toString()) val = unicode(value.toString()).strip()
if not val: if not val:
error_dialog(self.tags_view, _('Item is blank'), error_dialog(self.tags_view, _('Item is blank'),
_('An item cannot be set to nothing. Delete it instead.')).exec_() _('An item cannot be set to nothing. Delete it instead.')).exec_()

View File

@ -1181,6 +1181,22 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
return 'n=%s s=%s c=%d rt=%d rc=%d id=%s'%\ return 'n=%s s=%s c=%d rt=%d rc=%d id=%s'%\
(self.n, self.s, self.c, self.rt, self.rc, self.id) (self.n, self.s, self.c, self.rt, self.rc, self.id)
def clean_user_categories(self):
user_cats = self.prefs.get('user_categories', {})
new_cats = {}
for k in user_cats:
comps = [c.strip() for c in k.split('.') if c.strip()]
if len(comps) == 0:
i = 1
while True:
if unicode(i) not in user_cats:
new_cats[unicode(i)] = user_cats[k]
break
i += 1
else:
new_cats['.'.join(comps)] = user_cats[k]
self.prefs.set('user_categories', new_cats)
return new_cats
def get_categories(self, sort='name', ids=None, icon_map=None): def get_categories(self, sort='name', ids=None, icon_map=None):
#start = last = time.clock() #start = last = time.clock()
@ -1421,7 +1437,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
categories['formats'].sort(key = lambda x:x.name) categories['formats'].sort(key = lambda x:x.name)
#### Now do the user-defined categories. #### #### Now do the user-defined categories. ####
user_categories = dict.copy(self.prefs['user_categories']) user_categories = dict.copy(self.clean_user_categories())
# We want to use same node in the user category as in the source # We want to use same node in the user category as in the source
# category. To do that, we need to find the original Tag node. There is # category. To do that, we need to find the original Tag node. There is