enums now always have None. Significant speed increasing when recomputing author sort values

This commit is contained in:
Kovid Goyal 2010-12-03 09:30:51 -07:00
commit 3be66119d0
9 changed files with 54 additions and 58 deletions

View File

@ -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)
@ -632,7 +639,10 @@ class BulkEnumeration(BulkBase, Enumeration):
if val == ' nochange ':
self.widgets[1].setCurrentIndex(0)
else:
self.widgets[1].setCurrentIndex(self.widgets[1].findText(val))
if val is None:
self.widgets[1].setCurrentIndex(1)
else:
self.widgets[1].setCurrentIndex(self.widgets[1].findText(val))
def commit(self, book_ids, notify=False):
val = self.gui_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):

View File

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

View File

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

View File

@ -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 '

View File

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

View File

@ -106,10 +106,13 @@ 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):
self.refresh_required.emit()
if self.refresh_signal_processed:
self.refresh_signal_processed = False
self.refresh_required.emit()
@property
def match_all(self):
@ -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()

View File

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

View File

@ -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_,))

View File

@ -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))
self.conn.commit()
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 '|'!