Handle case change for tags and authors.

This commit is contained in:
Charles Haley 2011-02-02 18:42:03 +00:00
parent e1c90d5be0
commit e8fd598c48
4 changed files with 57 additions and 21 deletions

View File

@ -160,6 +160,7 @@ class EditMetadataAction(InterfaceAction):
break
changed.add(d.id)
changed |= d.books_to_refresh
if d.row_delta == 0:
break
current_row += d.row_delta

View File

@ -622,6 +622,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
self.original_author = unicode(self.authors.text()).strip()
self.original_title = unicode(self.title.text()).strip()
self.books_to_refresh = set()
self.show()
@ -775,7 +776,8 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
_('You have changed the tags. In order to use the tags'
' editor, you must either discard or apply these '
'changes. Apply changes?'), show_copy_button=False):
self.apply_tags(commit=True, notify=True)
self.books_to_refresh |= self.apply_tags(commit=True, notify=True,
allow_case_change=True)
self.original_tags = unicode(self.tags.text())
else:
self.tags.setText(self.original_tags)
@ -882,9 +884,9 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
break
def apply_tags(self, commit=False, notify=False):
self.db.set_tags(self.id, [x.strip() for x in
unicode(self.tags.text()).split(',')],
notify=notify, commit=commit)
return self.db.set_tags(self.id, [x.strip() for x in
unicode(self.tags.text()).split(',')],
notify=notify, commit=commit, allow_case_change=True)
def next_triggered(self, row_delta, *args):
self.row_delta = row_delta
@ -903,7 +905,10 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
self.db.set_title_sort(self.id, ts, notify=False, commit=False)
au = unicode(self.authors.text()).strip()
if au and au != self.original_author:
self.db.set_authors(self.id, string_to_authors(au), notify=False)
self.books_to_refresh |= self.db.set_authors(self.id,
string_to_authors(au),
notify=False,
allow_case_change=True)
aus = unicode(self.author_sort.text()).strip()
if aus:
self.db.set_author_sort(self.id, aus, notify=False, commit=False)
@ -913,7 +918,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
notify=False, commit=False)
self.db.set_rating(self.id, 2*self.rating.value(), notify=False,
commit=False)
self.apply_tags()
self.books_to_refresh |= self.apply_tags()
self.db.set_publisher(self.id,
unicode(self.publisher.currentText()).strip(),
notify=False, commit=False)

View File

@ -819,6 +819,7 @@ class BooksModel(QAbstractTableModel): # {{{
value.toDate() if column in ('timestamp', 'pubdate') else \
unicode(value.toString())
id = self.db.id(row)
books_to_refresh = set([id])
if column == 'rating':
val = 0 if val < 0 else 5 if val > 5 else val
val *= 2
@ -850,8 +851,9 @@ class BooksModel(QAbstractTableModel): # {{{
return False
self.db.set_pubdate(id, qt_to_dt(val, as_utc=False))
else:
self.db.set(row, column, val)
self.refresh_ids([id], row)
books_to_refresh |= self.db.set(row, column, val,
allow_case_change=True)
self.refresh_ids(list(books_to_refresh), row)
self.dataChanged.emit(index, index)
return True

View File

@ -1479,17 +1479,19 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
return float(tweaks['series_index_auto_increment'])
return 1.0
def set(self, row, column, val):
def set(self, row, column, val, allow_case_change=False):
'''
Convenience method for setting the title, authors, publisher or rating
'''
id = self.data[row][0]
col = {'title':1, 'authors':2, 'publisher':3, 'rating':4, 'tags':7}[column]
books_to_refresh = set()
self.data.set(row, col, val)
if column == 'authors':
val = string_to_authors(val)
self.set_authors(id, val, notify=False)
books_to_refresh |= self.set_authors(id, val, notify=False,
allow_case_change=allow_case_change)
elif column == 'title':
self.set_title(id, val, notify=False)
elif column == 'publisher':
@ -1497,11 +1499,13 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
elif column == 'rating':
self.set_rating(id, val, notify=False)
elif column == 'tags':
self.set_tags(id, [x.strip() for x in val.split(',') if x.strip()],
append=False, notify=False)
books_to_refresh |= \
self.set_tags(id, [x.strip() for x in val.split(',') if x.strip()],
append=False, notify=False, allow_case_change=allow_case_change)
self.data.refresh_ids(self, [id])
self.set_path(id, True)
self.notify('metadata', [id])
return books_to_refresh
def set_metadata(self, id, mi, ignore_errors=False,
set_title=True, set_authors=True, commit=True):
@ -1627,28 +1631,38 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
result.append(r)
return ' & '.join(result).replace('|', ',')
def _set_authors(self, id, authors):
def _set_authors(self, id, authors, allow_case_change=False):
if not authors:
authors = [_('Unknown')]
self.conn.execute('DELETE FROM books_authors_link WHERE book=?',(id,))
books_to_refresh = set()
for a in authors:
if not a:
continue
a = a.strip().replace(',', '|')
if not isinstance(a, unicode):
a = a.decode(preferred_encoding, 'replace')
author = self.conn.get('SELECT id from authors WHERE name=?', (a,), all=False)
if author:
aid = author
author_id, name = \
self.conn.get('SELECT id, name from authors WHERE name=?', (a,))[0]
if author_id:
aid = author_id
# Handle change of case
self.conn.execute('UPDATE authors SET name=? WHERE id=?', (a, aid))
if allow_case_change and name != a:
self.conn.execute('UPDATE authors SET name=? WHERE id=?', (a, aid))
case_change = True
else:
aid = self.conn.execute('INSERT INTO authors(name) VALUES (?)', (a,)).lastrowid
case_change = False
try:
self.conn.execute('INSERT INTO books_authors_link(book, author) VALUES (?,?)',
(id, aid))
except IntegrityError: # Sometimes books specify the same author twice in their metadata
pass
if case_change:
bks = self.conn.get('SELECT book FROM books_authors_link WHERE author=?',
(aid,))
books_to_refresh |= set([bk[0] for bk in bks])
ss = self.author_sort_from_book(id, index_is_id=True)
self.conn.execute('UPDATE books SET author_sort=? WHERE id=?',
(ss, id))
@ -1660,21 +1674,25 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
self.data.set(id, self.FIELD_MAP['au_map'],
':#:'.join([':::'.join((au.replace(',', '|'), aus)) for (au, aus) in aum]),
row_is_id=True)
return books_to_refresh
def set_authors(self, id, authors, notify=True, commit=True):
def set_authors(self, id, authors, notify=True, commit=True,
allow_case_change=False):
'''
Note that even if commit is False, the db will still be committed to
because this causes the location of files to change
:param authors: A list of authors.
'''
self._set_authors(id, authors)
books_to_refresh = self._set_authors(id, authors,
allow_case_change=allow_case_change)
self.dirtied([id], commit=False)
if commit:
self.conn.commit()
self.set_path(id, index_is_id=True)
if notify:
self.notify('metadata', [id])
return books_to_refresh
def set_title_sort(self, id, title_sort_, notify=True, commit=True):
if not title_sort_:
@ -2119,7 +2137,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
def commit(self):
self.conn.commit()
def set_tags(self, id, tags, append=False, notify=True, commit=True):
def set_tags(self, id, tags, append=False, notify=True, commit=True,
allow_case_change=False):
'''
@param tags: list of strings
@param append: If True existing tags are not removed
@ -2129,6 +2148,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
self.conn.execute('DELETE FROM tags WHERE (SELECT COUNT(id) FROM books_tags_link WHERE tag=tags.id) < 1')
otags = self.get_tags(id)
tags = self.cleanup_tags(tags)
books_to_refresh = set()
for tag in (set(tags)-otags):
tag = tag.strip()
if not tag:
@ -2144,8 +2164,11 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
if idx > -1:
etag = existing_tags[idx]
tid = self.conn.get('SELECT id FROM tags WHERE name=?', (etag,), all=False)
if etag != tag:
if allow_case_change and etag != tag:
self.conn.execute('UPDATE tags SET name=? WHERE id=?', (tag, tid))
case_changed = True
else:
case_changed = False
else:
tid = self.conn.execute('INSERT INTO tags(name) VALUES(?)', (tag,)).lastrowid
@ -2153,6 +2176,10 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
(id, tid), all=False):
self.conn.execute('INSERT INTO books_tags_link(book, tag) VALUES (?,?)',
(id, tid))
if case_changed:
bks = self.conn.get('SELECT book FROM books_tags_link WHERE tag=?',
(tid,))
books_to_refresh |= set([bk[0] for bk in bks])
self.dirtied([id], commit=False)
if commit:
self.conn.commit()
@ -2160,6 +2187,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
self.data.set(id, self.FIELD_MAP['tags'], tags, row_is_id=True)
if notify:
self.notify('metadata', [id])
return books_to_refresh
def unapply_tags(self, book_id, tags, notify=True):
for tag in tags: