mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix bugs #5751 and #5752. Also distinguish between the delete warning dialogs for the library and the device
This commit is contained in:
parent
bef59a3a3c
commit
6364ea1d39
@ -3,6 +3,7 @@ __copyright__ = '2010, Kovid Goyal <kovid at kovidgoyal.net>'
|
|||||||
|
|
||||||
'''Dialog to create a new custom column'''
|
'''Dialog to create a new custom column'''
|
||||||
|
|
||||||
|
import re
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from PyQt4.QtCore import SIGNAL
|
from PyQt4.QtCore import SIGNAL
|
||||||
@ -94,8 +95,8 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
|
|||||||
col = unicode(self.column_name_box.text()).lower()
|
col = unicode(self.column_name_box.text()).lower()
|
||||||
if not col:
|
if not col:
|
||||||
return self.simple_error('', _('No lookup name was provided'))
|
return self.simple_error('', _('No lookup name was provided'))
|
||||||
if not col.isalnum() or not col[0].isalpha():
|
if re.match('^\w*$', col) is None or not col[0].isalpha():
|
||||||
return self.simple_error('', _('The label must contain only letters and digits, and start with a letter'))
|
return self.simple_error('', _('The label must contain only letters, digits and underscores, and start with a letter'))
|
||||||
col_heading = unicode(self.column_heading_box.text())
|
col_heading = unicode(self.column_heading_box.text())
|
||||||
col_type = self.column_types[self.column_type_box.currentIndex()]['datatype']
|
col_type = self.column_types[self.column_type_box.currentIndex()]['datatype']
|
||||||
if col_type == '*text':
|
if col_type == '*text':
|
||||||
|
@ -63,8 +63,7 @@ class TagsView(QTreeView): # {{{
|
|||||||
|
|
||||||
def sort_changed(self, state):
|
def sort_changed(self, state):
|
||||||
config.set('sort_by_popularity', state == Qt.Checked)
|
config.set('sort_by_popularity', state == Qt.Checked)
|
||||||
self.model().refresh()
|
self.recount()
|
||||||
# self.search_restriction_set()
|
|
||||||
|
|
||||||
def set_search_restriction(self, s):
|
def set_search_restriction(self, s):
|
||||||
if s:
|
if s:
|
||||||
@ -197,7 +196,9 @@ class TagsView(QTreeView): # {{{
|
|||||||
ci = self.indexAt(QPoint(10, 10))
|
ci = self.indexAt(QPoint(10, 10))
|
||||||
path = self.model().path_for_index(ci) if self.is_visible(ci) else None
|
path = self.model().path_for_index(ci) if self.is_visible(ci) else None
|
||||||
try:
|
try:
|
||||||
self.model().refresh()
|
if not self.model().refresh(): # categories changed!
|
||||||
|
self.set_new_model()
|
||||||
|
path = None
|
||||||
except: #Database connection could be closed if an integrity check is happening
|
except: #Database connection could be closed if an integrity check is happening
|
||||||
pass
|
pass
|
||||||
if path:
|
if path:
|
||||||
@ -210,10 +211,16 @@ class TagsView(QTreeView): # {{{
|
|||||||
# gone, or if columns have been hidden or restored, we must rebuild the
|
# gone, or if columns have been hidden or restored, we must rebuild the
|
||||||
# model. Reason: it is much easier than reconstructing the browser tree.
|
# model. Reason: it is much easier than reconstructing the browser tree.
|
||||||
def set_new_model(self):
|
def set_new_model(self):
|
||||||
self._model = TagsModel(self.db, parent=self,
|
try:
|
||||||
hidden_categories=self.hidden_categories,
|
self._model = TagsModel(self.db, parent=self,
|
||||||
search_restriction=self.search_restriction)
|
hidden_categories=self.hidden_categories,
|
||||||
self.setModel(self._model)
|
search_restriction=self.search_restriction)
|
||||||
|
self.setModel(self._model)
|
||||||
|
except:
|
||||||
|
# The DB must be gone. Set the model to None and hope that someone
|
||||||
|
# will call set_database later. I don't know if this in fact works
|
||||||
|
self._model = None
|
||||||
|
self.setModel(None)
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class TagTreeItem(object): # {{{
|
class TagTreeItem(object): # {{{
|
||||||
@ -323,18 +330,9 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
self.tags_view = parent
|
self.tags_view = parent
|
||||||
self.hidden_categories = hidden_categories
|
self.hidden_categories = hidden_categories
|
||||||
self.search_restriction = search_restriction
|
self.search_restriction = search_restriction
|
||||||
|
self.row_map = []
|
||||||
|
|
||||||
# Reconstruct the user categories, putting them into metadata
|
# get_node_tree cannot return None here, because row_map is empty
|
||||||
tb_cats = self.db.field_metadata
|
|
||||||
for k in tb_cats.keys():
|
|
||||||
if tb_cats[k]['kind'] in ['user', 'search']:
|
|
||||||
del tb_cats[k]
|
|
||||||
for user_cat in sorted(prefs['user_categories'].keys()):
|
|
||||||
cat_name = user_cat+':' # add the ':' to avoid name collision
|
|
||||||
tb_cats.add_user_category(label=cat_name, name=user_cat)
|
|
||||||
if len(saved_searches.names()):
|
|
||||||
tb_cats.add_search_category(label='search', name=_('Searches'))
|
|
||||||
|
|
||||||
data = self.get_node_tree(config['sort_by_popularity'])
|
data = self.get_node_tree(config['sort_by_popularity'])
|
||||||
self.root_item = TagTreeItem()
|
self.root_item = TagTreeItem()
|
||||||
for i, r in enumerate(self.row_map):
|
for i, r in enumerate(self.row_map):
|
||||||
@ -355,9 +353,22 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
self.search_restriction = s
|
self.search_restriction = s
|
||||||
|
|
||||||
def get_node_tree(self, sort):
|
def get_node_tree(self, sort):
|
||||||
|
old_row_map = self.row_map[:]
|
||||||
self.row_map = []
|
self.row_map = []
|
||||||
self.categories = []
|
self.categories = []
|
||||||
|
|
||||||
|
# Reconstruct the user categories, putting them into metadata
|
||||||
|
tb_cats = self.db.field_metadata
|
||||||
|
for k in tb_cats.keys():
|
||||||
|
if tb_cats[k]['kind'] in ['user', 'search']:
|
||||||
|
del tb_cats[k]
|
||||||
|
for user_cat in sorted(prefs['user_categories'].keys()):
|
||||||
|
cat_name = user_cat+':' # add the ':' to avoid name collision
|
||||||
|
tb_cats.add_user_category(label=cat_name, name=user_cat)
|
||||||
|
if len(saved_searches.names()):
|
||||||
|
tb_cats.add_search_category(label='search', name=_('Searches'))
|
||||||
|
|
||||||
|
# Now get the categories
|
||||||
if self.search_restriction:
|
if self.search_restriction:
|
||||||
data = self.db.get_categories(sort_on_count=sort,
|
data = self.db.get_categories(sort_on_count=sort,
|
||||||
icon_map=self.category_icon_map,
|
icon_map=self.category_icon_map,
|
||||||
@ -367,13 +378,19 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
|
|
||||||
tb_categories = self.db.field_metadata
|
tb_categories = self.db.field_metadata
|
||||||
for category in tb_categories:
|
for category in tb_categories:
|
||||||
if category in data: # They should always be there, but ...
|
if category in data: # The search category can come and go
|
||||||
self.row_map.append(category)
|
self.row_map.append(category)
|
||||||
self.categories.append(tb_categories[category]['name'])
|
self.categories.append(tb_categories[category]['name'])
|
||||||
|
if len(old_row_map) != 0 and len(old_row_map) != len(self.row_map):
|
||||||
|
# A category has been added or removed. We must force a rebuild of
|
||||||
|
# the model
|
||||||
|
return None
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def refresh(self):
|
def refresh(self):
|
||||||
data = self.get_node_tree(config['sort_by_popularity']) # get category data
|
data = self.get_node_tree(config['sort_by_popularity']) # get category data
|
||||||
|
if data is None:
|
||||||
|
return False
|
||||||
row_index = -1
|
row_index = -1
|
||||||
for i, r in enumerate(self.row_map):
|
for i, r in enumerate(self.row_map):
|
||||||
if self.hidden_categories and self.categories[i] in self.hidden_categories:
|
if self.hidden_categories and self.categories[i] in self.hidden_categories:
|
||||||
@ -395,6 +412,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
tag.state = state_map.get(tag.name, 0)
|
tag.state = state_map.get(tag.name, 0)
|
||||||
t = TagTreeItem(parent=category, data=tag, icon_map=self.icon_state_map)
|
t = TagTreeItem(parent=category, data=tag, icon_map=self.icon_state_map)
|
||||||
self.endInsertRows()
|
self.endInsertRows()
|
||||||
|
return True
|
||||||
|
|
||||||
def columnCount(self, parent):
|
def columnCount(self, parent):
|
||||||
return 1
|
return 1
|
||||||
@ -439,7 +457,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
label=self.db.field_metadata[key]['label'])
|
label=self.db.field_metadata[key]['label'])
|
||||||
self.tags_view.tag_item_renamed.emit()
|
self.tags_view.tag_item_renamed.emit()
|
||||||
item.tag.name = val
|
item.tag.name = val
|
||||||
self.refresh()
|
self.refresh() # Should work, because no categories can have disappeared
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def headerData(self, *args):
|
def headerData(self, *args):
|
||||||
|
@ -854,7 +854,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
|
|||||||
r = unicode(r)
|
r = unicode(r)
|
||||||
if r is not None and r != '':
|
if r is not None and r != '':
|
||||||
self.restriction_in_effect = True
|
self.restriction_in_effect = True
|
||||||
restriction = "search:%s"%(r)
|
restriction = 'search:"%s"'%(r)
|
||||||
else:
|
else:
|
||||||
self.restriction_in_effect = False
|
self.restriction_in_effect = False
|
||||||
restriction = ''
|
restriction = ''
|
||||||
@ -1557,7 +1557,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
|
|||||||
if not confirm('<p>'+_('The selected books will be '
|
if not confirm('<p>'+_('The selected books will be '
|
||||||
'<b>permanently deleted</b> '
|
'<b>permanently deleted</b> '
|
||||||
'from your device. Are you sure?')
|
'from your device. Are you sure?')
|
||||||
+'</p>', 'library_delete_books', self):
|
+'</p>', 'device_delete_books', self):
|
||||||
return
|
return
|
||||||
if self.stack.currentIndex() == 1:
|
if self.stack.currentIndex() == 1:
|
||||||
view = self.memory_view
|
view = self.memory_view
|
||||||
|
Loading…
x
Reference in New Issue
Block a user