mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
enums now always have None. Significant speed increasing when recomputing author sort values
This commit is contained in:
commit
3be66119d0
@ -318,16 +318,14 @@ class Enumeration(Base):
|
||||
QComboBox(parent)]
|
||||
w = self.widgets[1]
|
||||
vals = self.col_metadata['display']['enum_values']
|
||||
w.addItem('')
|
||||
for v in vals:
|
||||
w.addItem(v)
|
||||
|
||||
def initialize(self, book_id):
|
||||
val = self.db.get_custom(book_id, num=self.col_id, index_is_id=True)
|
||||
if val is None:
|
||||
# This really shouldn't happen
|
||||
val = self.col_metadata['display']['enum_values'][0]
|
||||
self.initial_val = val
|
||||
val = self.normalize_db_val(val)
|
||||
self.initial_val = val
|
||||
idx = self.widgets[1].findText(val)
|
||||
if idx < 0:
|
||||
error_dialog(self.parent, '',
|
||||
@ -340,13 +338,21 @@ class Enumeration(Base):
|
||||
self.widgets[1].setCurrentIndex(idx)
|
||||
|
||||
def setter(self, val):
|
||||
if val is None:
|
||||
val = ''
|
||||
self.widgets[1].setCurrentIndex(self.widgets[1].findText(val))
|
||||
|
||||
def getter(self):
|
||||
return unicode(self.widgets[1].currentText())
|
||||
|
||||
def normalize_db_val(self, val):
|
||||
if val is None:
|
||||
val = ''
|
||||
return val
|
||||
|
||||
def normalize_ui_val(self, val):
|
||||
if not val:
|
||||
val = None
|
||||
return val
|
||||
|
||||
widgets = {
|
||||
'bool' : Bool,
|
||||
'rating' : Rating,
|
||||
@ -597,7 +603,7 @@ class BulkEnumeration(BulkBase, Enumeration):
|
||||
dialog_shown = False
|
||||
for book_id in book_ids:
|
||||
val = self.db.get_custom(book_id, num=self.col_id, index_is_id=True)
|
||||
if val not in self.col_metadata['display']['enum_values']:
|
||||
if val and val not in self.col_metadata['display']['enum_values']:
|
||||
if not dialog_shown:
|
||||
error_dialog(self.parent, '',
|
||||
_('The enumeration "{0}" contains invalid values '
|
||||
@ -620,6 +626,7 @@ class BulkEnumeration(BulkBase, Enumeration):
|
||||
w = self.widgets[1]
|
||||
vals = self.col_metadata['display']['enum_values']
|
||||
w.addItem('Do Not Change')
|
||||
w.addItem('')
|
||||
for v in vals:
|
||||
w.addItem(v)
|
||||
|
||||
@ -631,6 +638,9 @@ class BulkEnumeration(BulkBase, Enumeration):
|
||||
def setter(self, val):
|
||||
if val == ' nochange ':
|
||||
self.widgets[1].setCurrentIndex(0)
|
||||
else:
|
||||
if val is None:
|
||||
self.widgets[1].setCurrentIndex(1)
|
||||
else:
|
||||
self.widgets[1].setCurrentIndex(self.widgets[1].findText(val))
|
||||
|
||||
@ -640,12 +650,6 @@ class BulkEnumeration(BulkBase, Enumeration):
|
||||
if val != self.initial_val and val != ' nochange ':
|
||||
self.db.set_custom_bulk(book_ids, val, num=self.col_id, notify=notify)
|
||||
|
||||
def normalize_db_val(self, val):
|
||||
if val is None:
|
||||
# this really shouldn't happen
|
||||
val = self.col_metadata['display']['enum_values'][0]
|
||||
return val
|
||||
|
||||
class RemoveTags(QWidget):
|
||||
|
||||
def __init__(self, parent, values):
|
||||
|
@ -263,28 +263,22 @@ class CcEnumDelegate(QStyledItemDelegate): # {{{
|
||||
m = index.model()
|
||||
col = m.column_map[index.column()]
|
||||
editor = QComboBox(parent)
|
||||
editor.addItem('')
|
||||
for v in m.custom_columns[col]['display']['enum_values']:
|
||||
editor.addItem(v)
|
||||
return editor
|
||||
|
||||
def setModelData(self, editor, model, index):
|
||||
val = unicode(editor.currentText())
|
||||
m = index.model()
|
||||
col = m.column_map[index.column()]
|
||||
if val not in m.custom_columns[col]['display']['enum_values']:
|
||||
# This shouldn't happen ...
|
||||
print 'shouldnt happen'
|
||||
val = m.custom_columns[col]['display']['enum_values'][0]
|
||||
if not val:
|
||||
val = None
|
||||
model.setData(index, QVariant(val), Qt.EditRole)
|
||||
|
||||
def setEditorData(self, editor, index):
|
||||
m = index.model()
|
||||
val = m.db.data[index.row()][m.custom_columns[m.column_map[index.column()]]['rec_index']]
|
||||
if val is None:
|
||||
# This shouldn't happen
|
||||
m = index.model()
|
||||
col = m.column_map[index.column()]
|
||||
val = m.custom_columns[col]['display']['enum_values'][0]
|
||||
val = ''
|
||||
idx = editor.findText(val)
|
||||
if idx < 0:
|
||||
editor.setCurrentIndex(0)
|
||||
|
@ -724,6 +724,8 @@ class BooksModel(QAbstractTableModel): # {{{
|
||||
val = val if val else None
|
||||
elif typ == 'enumeration':
|
||||
val = unicode(value.toString()).strip()
|
||||
if not val:
|
||||
val = None
|
||||
elif typ == 'bool':
|
||||
val = value.toPyObject()
|
||||
elif typ == 'rating':
|
||||
@ -732,7 +734,7 @@ class BooksModel(QAbstractTableModel): # {{{
|
||||
val *= 2
|
||||
elif typ in ('int', 'float'):
|
||||
val = unicode(value.toString()).strip()
|
||||
if val is None or not val:
|
||||
if not val:
|
||||
val = None
|
||||
elif typ == 'datetime':
|
||||
val = value.toDate()
|
||||
|
@ -167,6 +167,10 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
|
||||
return self.simple_error('', _('You must enter at least one'
|
||||
' value for enumeration columns'))
|
||||
l = [v.strip() for v in unicode(self.enum_box.text()).split(',')]
|
||||
for v in l:
|
||||
if not v:
|
||||
return self.simple_error('', _('You cannot provide the empty '
|
||||
'value, as it is included by default'))
|
||||
for i in range(0, len(l)-1):
|
||||
if l[i] in l[i+1:]:
|
||||
return self.simple_error('', _('The value "{0}" is in the '
|
||||
|
@ -212,10 +212,9 @@
|
||||
<item>
|
||||
<widget class="QLineEdit" name="enum_box">
|
||||
<property name="toolTip">
|
||||
<string>A comma-separated list of permitted values. You can specify
|
||||
empty values by entering only the comma. For example, the list
|
||||
',one,two,three' has 4 valid values, one of them empty. The first
|
||||
value in the list is the default.</string>
|
||||
<string>A comma-separated list of permitted values. The empty value is always
|
||||
included, and is the default. For example, the list 'one,two,three' has
|
||||
four values, the first of them being the empty value.</string>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
@ -231,7 +230,7 @@ value in the list is the default.</string>
|
||||
<string>Default: (nothing)</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The first value entered will be the default value for this enumeration</string>
|
||||
<string>The empty string is always the first value</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -106,9 +106,12 @@ class TagsView(QTreeView): # {{{
|
||||
self.refresh_required.connect(self.recount, type=Qt.QueuedConnection)
|
||||
self.sort_by.currentIndexChanged.connect(self.sort_changed)
|
||||
self.made_connections = True
|
||||
self.refresh_signal_processed = True
|
||||
db.add_listener(self.database_changed)
|
||||
|
||||
def database_changed(self, event, ids):
|
||||
if self.refresh_signal_processed:
|
||||
self.refresh_signal_processed = False
|
||||
self.refresh_required.emit()
|
||||
|
||||
@property
|
||||
@ -295,6 +298,7 @@ class TagsView(QTreeView): # {{{
|
||||
return self.isExpanded(idx)
|
||||
|
||||
def recount(self, *args):
|
||||
self.refresh_signal_processed = True
|
||||
ci = self.currentIndex()
|
||||
if not ci.isValid():
|
||||
ci = self.indexAt(QPoint(10, 10))
|
||||
@ -937,7 +941,9 @@ class TagBrowserMixin(object): # {{{
|
||||
if old_author != new_author:
|
||||
# The id might change if the new author already exists
|
||||
id = db.rename_author(id, new_author)
|
||||
db.set_sort_field_for_author(id, unicode(new_sort))
|
||||
db.set_sort_field_for_author(id, unicode(new_sort),
|
||||
commit=False, notify=False)
|
||||
db.commit()
|
||||
self.library_view.model().refresh()
|
||||
self.tags_view.recount()
|
||||
|
||||
|
@ -254,12 +254,6 @@ class ResultCache(SearchQueryParser): # {{{
|
||||
if field_metadata[key]['datatype'] == 'composite':
|
||||
self.composites.append((key, field_metadata[key]['rec_index']))
|
||||
|
||||
self.enumerations = []
|
||||
for key in field_metadata:
|
||||
if field_metadata[key]['datatype'] == 'enumeration':
|
||||
self.enumerations.append((field_metadata[key]['display']['enum_values'][0],
|
||||
field_metadata[key]['rec_index']))
|
||||
|
||||
def __getitem__(self, row):
|
||||
return self._data[self._map_filtered[row]]
|
||||
|
||||
@ -697,10 +691,6 @@ class ResultCache(SearchQueryParser): # {{{
|
||||
mi = db.get_metadata(id, index_is_id=True)
|
||||
for k,c in self.composites:
|
||||
self._data[id][c] = mi.get(k, None)
|
||||
if len(self.enumerations) > 0:
|
||||
for v,c in self.enumerations:
|
||||
if self._data[id][c] is None:
|
||||
self._data[id][c] = v
|
||||
except IndexError:
|
||||
return None
|
||||
try:
|
||||
@ -721,10 +711,6 @@ class ResultCache(SearchQueryParser): # {{{
|
||||
mi = db.get_metadata(id, index_is_id=True)
|
||||
for k,c in self.composites:
|
||||
self._data[id][c] = mi.get(k)
|
||||
if len(self.enumerations) > 0:
|
||||
for v,c in self.self._data[id][c]:
|
||||
if self._data[id][c] is None:
|
||||
self._data[id][c] = v
|
||||
self._map[0:0] = ids
|
||||
self._map_filtered[0:0] = ids
|
||||
|
||||
@ -754,10 +740,6 @@ class ResultCache(SearchQueryParser): # {{{
|
||||
mi = db.get_metadata(item[0], index_is_id=True)
|
||||
for k,c in self.composites:
|
||||
item[c] = mi.get(k)
|
||||
if len(self.enumerations) > 0:
|
||||
for v,c in self.enumerations:
|
||||
if item[c] is None:
|
||||
item[c] = v
|
||||
|
||||
self._map = [i[0] for i in self._data if i is not None]
|
||||
if field is not None:
|
||||
|
@ -136,6 +136,12 @@ class CustomColumns(object):
|
||||
x = bool(int(x))
|
||||
return x
|
||||
|
||||
def adapt_enum(x, d):
|
||||
v = adapt_text(x, d)
|
||||
if not v:
|
||||
v = None
|
||||
return v
|
||||
|
||||
self.custom_data_adapters = {
|
||||
'float': lambda x,d : x if x is None else float(x),
|
||||
'int': lambda x,d : x if x is None else int(x),
|
||||
@ -145,7 +151,7 @@ class CustomColumns(object):
|
||||
'datetime' : adapt_datetime,
|
||||
'text':adapt_text,
|
||||
'series':adapt_text,
|
||||
'enumeration': adapt_text
|
||||
'enumeration': adapt_enum
|
||||
}
|
||||
|
||||
# Create Tag Browser categories for custom columns
|
||||
@ -177,8 +183,6 @@ class CustomColumns(object):
|
||||
ans = ans.split('|') if ans else []
|
||||
if data['display'].get('sort_alpha', False):
|
||||
ans.sort(cmp=lambda x,y:cmp(x.lower(), y.lower()))
|
||||
elif data['datatype'] == 'enumeration' and ans is None:
|
||||
ans = data['display']['enum_values'][0]
|
||||
return ans
|
||||
|
||||
def get_custom_extra(self, idx, label=None, num=None, index_is_id=False):
|
||||
@ -442,8 +446,8 @@ class CustomColumns(object):
|
||||
val = self.custom_data_adapters[data['datatype']](val, data)
|
||||
|
||||
if data['normalized']:
|
||||
if data['datatype'] == 'enumeration' and \
|
||||
val not in data['display']['enum_values']:
|
||||
if data['datatype'] == 'enumeration' and (
|
||||
val and val not in data['display']['enum_values']):
|
||||
return None
|
||||
if not append or not data['is_multiple']:
|
||||
self.conn.execute('DELETE FROM %s WHERE book=?'%lt, (id_,))
|
||||
|
@ -1639,15 +1639,16 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
||||
return []
|
||||
return result
|
||||
|
||||
def set_sort_field_for_author(self, old_id, new_sort):
|
||||
def set_sort_field_for_author(self, old_id, new_sort, commit=True, notify=False):
|
||||
self.conn.execute('UPDATE authors SET sort=? WHERE id=?', \
|
||||
(new_sort.strip(), old_id))
|
||||
if commit:
|
||||
self.conn.commit()
|
||||
# Now change all the author_sort fields in books by this author
|
||||
bks = self.conn.get('SELECT book from books_authors_link WHERE author=?', (old_id,))
|
||||
for (book_id,) in bks:
|
||||
ss = self.author_sort_from_book(book_id, index_is_id=True)
|
||||
self.set_author_sort(book_id, ss)
|
||||
self.set_author_sort(book_id, ss, notify=notify, commit=commit)
|
||||
|
||||
def rename_author(self, old_id, new_name):
|
||||
# Make sure that any commas in new_name are changed to '|'!
|
||||
|
Loading…
x
Reference in New Issue
Block a user