mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix true/false searches dont work on device views (807262). Fix renaming of collections in device views (807256). Improved disaply of grouped search terms in Tag Browser
This commit is contained in:
commit
d7175e67bd
@ -446,9 +446,8 @@ class EditMetadataAction(InterfaceAction):
|
||||
if d.result() == d.Accepted:
|
||||
to_rename = d.to_rename # dict of new text to old ids
|
||||
to_delete = d.to_delete # list of ids
|
||||
for text in to_rename:
|
||||
for old_id in to_rename[text]:
|
||||
model.rename_collection(old_id, new_name=unicode(text))
|
||||
for old_id, new_name in to_rename.iteritems():
|
||||
model.rename_collection(old_id, new_name=unicode(new_name))
|
||||
for item in to_delete:
|
||||
model.delete_collection_using_id(item)
|
||||
self.gui.upload_collections(model.db, view=view, oncard=oncard)
|
||||
|
@ -950,11 +950,11 @@ class OnDeviceSearch(SearchQueryParser): # {{{
|
||||
for locvalue in locations:
|
||||
accessor = q[locvalue]
|
||||
if query == 'true':
|
||||
if accessor(row) is not None:
|
||||
if accessor(row):
|
||||
matches.add(index)
|
||||
continue
|
||||
if query == 'false':
|
||||
if accessor(row) is None:
|
||||
if not accessor(row):
|
||||
matches.add(index)
|
||||
continue
|
||||
if locvalue == 'inlibrary':
|
||||
|
@ -12,7 +12,7 @@ import traceback, cPickle, copy
|
||||
from itertools import repeat
|
||||
|
||||
from PyQt4.Qt import (QAbstractItemModel, QIcon, QVariant, QFont, Qt,
|
||||
QMimeData, QModelIndex, pyqtSignal)
|
||||
QMimeData, QModelIndex, pyqtSignal, QObject)
|
||||
|
||||
from calibre.gui2 import NONE, gprefs, config, error_dialog
|
||||
from calibre.library.database2 import Tag
|
||||
@ -227,6 +227,10 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
self._build_in_progress = False
|
||||
self.reread_collapse_model({}, rebuild=False)
|
||||
|
||||
@property
|
||||
def gui_parent(self):
|
||||
return QObject.parent(self)
|
||||
|
||||
def reread_collapse_model(self, state_map, rebuild=True):
|
||||
if gprefs['tags_browser_collapse_at'] == 0:
|
||||
self.collapse_model = 'disable'
|
||||
@ -315,9 +319,11 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
for i,p in enumerate(path_parts):
|
||||
path += p
|
||||
if path not in category_node_map:
|
||||
icon = self.category_icon_map['gst'] if is_gst else \
|
||||
self.category_icon_map[key]
|
||||
node = self.create_node(parent=last_category_node,
|
||||
data=p[1:] if i == 0 else p,
|
||||
category_icon=self.category_icon_map[key],
|
||||
category_icon=icon,
|
||||
tooltip=tt if path == key else path,
|
||||
category_key=path,
|
||||
icon_map=self.icon_state_map)
|
||||
@ -375,6 +381,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
collapse_letter = None
|
||||
category_node = category
|
||||
key = category_node.category_key
|
||||
is_gst = category_node.is_gst
|
||||
if key not in data:
|
||||
return
|
||||
cat_len = len(data[key])
|
||||
@ -455,6 +462,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
tooltip = None, temporary=True,
|
||||
category_key=category_node.category_key,
|
||||
icon_map=self.icon_state_map)
|
||||
sub_cat.is_gst = is_gst
|
||||
node_parent = sub_cat
|
||||
else:
|
||||
node_parent = category
|
||||
@ -722,12 +730,12 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
if (key == 'authors' and len(ids) >= 5):
|
||||
if not confirm('<p>'+_('Changing the authors for several books can '
|
||||
'take a while. Are you sure?')
|
||||
+'</p>', 'tag_browser_drop_authors', self.parent()):
|
||||
+'</p>', 'tag_browser_drop_authors', self.gui_parent):
|
||||
return
|
||||
elif len(ids) > 15:
|
||||
if not confirm('<p>'+_('Changing the metadata for that many books '
|
||||
'can take a while. Are you sure?')
|
||||
+'</p>', 'tag_browser_many_changes', self.parent()):
|
||||
+'</p>', 'tag_browser_many_changes', self.gui_parent):
|
||||
return
|
||||
|
||||
fm = self.db.metadata_for_field(key)
|
||||
@ -871,13 +879,13 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
# we position at the parent label
|
||||
val = unicode(value.toString()).strip()
|
||||
if not val:
|
||||
error_dialog(self.parent(), _('Item is blank'),
|
||||
error_dialog(self.gui_parent, _('Item is blank'),
|
||||
_('An item cannot be set to nothing. Delete it instead.')).exec_()
|
||||
return False
|
||||
item = self.get_node(index)
|
||||
if item.type == TagTreeItem.CATEGORY and item.category_key.startswith('@'):
|
||||
if val.find('.') >= 0:
|
||||
error_dialog(self.parent(), _('Rename user category'),
|
||||
error_dialog(self.gui_parent, _('Rename user category'),
|
||||
_('You cannot use periods in the name when '
|
||||
'renaming user categories'), show=True)
|
||||
return False
|
||||
@ -897,7 +905,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
if len(c) == len(ckey):
|
||||
if strcmp(ckey, nkey) != 0 and \
|
||||
nkey_lower in user_cat_keys_lower:
|
||||
error_dialog(self.parent(), _('Rename user category'),
|
||||
error_dialog(self.gui_parent, _('Rename user category'),
|
||||
_('The name %s is already used')%nkey, show=True)
|
||||
return False
|
||||
user_cats[nkey] = user_cats[ckey]
|
||||
@ -906,7 +914,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
rest = c[len(ckey):]
|
||||
if strcmp(ckey, nkey) != 0 and \
|
||||
icu_lower(nkey + rest) in user_cat_keys_lower:
|
||||
error_dialog(self.parent(), _('Rename user category'),
|
||||
error_dialog(self.gui_parent, _('Rename user category'),
|
||||
_('The name %s is already used')%(nkey+rest), show=True)
|
||||
return False
|
||||
user_cats[nkey + rest] = user_cats[ckey + rest]
|
||||
@ -921,12 +929,12 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
return False
|
||||
if key == 'authors':
|
||||
if val.find('&') >= 0:
|
||||
error_dialog(self.parent(), _('Invalid author name'),
|
||||
error_dialog(self.gui_parent, _('Invalid author name'),
|
||||
_('Author names cannot contain & characters.')).exec_()
|
||||
return False
|
||||
if key == 'search':
|
||||
if val in saved_searches().names():
|
||||
error_dialog(self.parent(), _('Duplicate search name'),
|
||||
error_dialog(self.gui_parent, _('Duplicate search name'),
|
||||
_('The saved search name %s is already used.')%val).exec_()
|
||||
return False
|
||||
saved_searches().rename(unicode(item.data(role).toString()), val)
|
||||
@ -1161,7 +1169,10 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
prefix = ' not '
|
||||
else:
|
||||
prefix = ''
|
||||
category = tag.category if key != 'news' else 'tag'
|
||||
if node.is_gst:
|
||||
category = key
|
||||
else:
|
||||
category = tag.category if key != 'news' else 'tag'
|
||||
add_colon = False
|
||||
if self.db.field_metadata[tag.category]['is_csp']:
|
||||
add_colon = True
|
||||
|
@ -218,7 +218,7 @@ class TagBrowserMixin(object): # {{{
|
||||
d = TagListEditor(self, tag_to_match=tag, data=result, key=key)
|
||||
d.exec_()
|
||||
if d.result() == d.Accepted:
|
||||
to_rename = d.to_rename # dict of new text to old id
|
||||
to_rename = d.to_rename # dict of old id to new name
|
||||
to_delete = d.to_delete # list of ids
|
||||
orig_name = d.original_names # dict of id: name
|
||||
|
||||
|
@ -7,7 +7,7 @@ __docformat__ = 'restructuredtext en'
|
||||
The database used to store ebook metadata
|
||||
'''
|
||||
import os, sys, shutil, cStringIO, glob, time, functools, traceback, re, \
|
||||
json, uuid, tempfile, hashlib
|
||||
json, uuid, tempfile, hashlib, copy
|
||||
from collections import defaultdict
|
||||
import threading, random
|
||||
from itertools import repeat
|
||||
@ -1794,10 +1794,22 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
||||
|
||||
for user_cat in sorted(user_categories.keys(), key=sort_key):
|
||||
items = []
|
||||
names_seen = {}
|
||||
for (name,label,ign) in user_categories[user_cat]:
|
||||
n = icu_lower(name)
|
||||
if label in taglist and n in taglist[label]:
|
||||
items.append(taglist[label][n])
|
||||
if user_cat in gst:
|
||||
# for gst items, make copy and consolidate the tags by name.
|
||||
if n in names_seen:
|
||||
names_seen[n].id_set |= taglist[label][n].id_set
|
||||
names_seen[n].count += taglist[label][n].count
|
||||
else:
|
||||
t = copy.copy(taglist[label][n])
|
||||
t.icon = icon_map['gst']
|
||||
names_seen[t.name] = t
|
||||
items.append(t)
|
||||
else:
|
||||
items.append(taglist[label][n])
|
||||
# else: do nothing, to not include nodes w zero counts
|
||||
cat_name = '@' + user_cat # add the '@' to avoid name collision
|
||||
# Not a problem if we accumulate entries in the icon map
|
||||
|
@ -17,7 +17,7 @@ class TagsIcons(dict):
|
||||
|
||||
category_icons = ['authors', 'series', 'formats', 'publisher', 'rating',
|
||||
'news', 'tags', 'custom:', 'user:', 'search',
|
||||
'identifiers']
|
||||
'identifiers', 'gst']
|
||||
def __init__(self, icon_dict):
|
||||
for a in self.category_icons:
|
||||
if a not in icon_dict:
|
||||
@ -35,7 +35,8 @@ category_icon_map = {
|
||||
'custom:' : 'column.png',
|
||||
'user:' : 'tb_folder.png',
|
||||
'search' : 'search.png',
|
||||
'identifiers': 'identifiers.png'
|
||||
'identifiers': 'identifiers.png',
|
||||
'gst' : 'catalog.png',
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user