Drag & drop on the tag browser

This commit is contained in:
Charles Haley 2010-10-04 15:21:36 +01:00
parent 7be5e77580
commit f89c43148c
2 changed files with 67 additions and 22 deletions

View File

@ -66,6 +66,7 @@ class TagsView(QTreeView): # {{{
author_sort_edit = pyqtSignal(object, object) author_sort_edit = pyqtSignal(object, object)
tag_item_renamed = pyqtSignal() tag_item_renamed = pyqtSignal()
search_item_renamed = pyqtSignal() search_item_renamed = pyqtSignal()
drag_drop_finished = pyqtSignal(object)
def __init__(self, parent=None): def __init__(self, parent=None):
QTreeView.__init__(self, parent=None) QTreeView.__init__(self, parent=None)
@ -121,10 +122,12 @@ class TagsView(QTreeView): # {{{
p = m.parent(idx) p = m.parent(idx)
if idx.isValid() and p.isValid(): if idx.isValid() and p.isValid():
item = m.data(p, Qt.UserRole) item = m.data(p, Qt.UserRole)
if item.type == TagTreeItem.CATEGORY and \ fm = self.db.metadata_for_field(item.category_key)
item.category_key in \ if item.category_key in \
('tags', 'series', 'authors', 'rating', 'publisher'): ('tags', 'series', 'authors', 'rating', 'publisher') or\
allowed = True (fm['is_custom'] and \
(fm['datatype'] == 'text' or fm['datatype'] == 'rating')):
allowed = True
if allowed: if allowed:
event.acceptProposedAction() event.acceptProposedAction()
else: else:
@ -136,18 +139,54 @@ class TagsView(QTreeView): # {{{
p = m.parent(idx) p = m.parent(idx)
if idx.isValid() and p.isValid(): if idx.isValid() and p.isValid():
item = m.data(p, Qt.UserRole) item = m.data(p, Qt.UserRole)
if item.type == TagTreeItem.CATEGORY and \ if item.type == TagTreeItem.CATEGORY:
item.category_key in \ fm = self.db.metadata_for_field(item.category_key)
('tags', 'series', 'authors', 'rating', 'publisher'): if item.category_key in \
child = m.data(idx, Qt.UserRole) ('tags', 'series', 'authors', 'rating', 'publisher') or\
md = event.mimeData() (fm['is_custom'] and \
mime = 'application/calibre+from_library' (fm['datatype'] == 'text' or fm['datatype'] == 'rating')):
ids = list(map(int, str(md.data(mime)).split())) child = m.data(idx, Qt.UserRole)
self.handle_drop(item, child, ids) md = event.mimeData()
event.accept() mime = 'application/calibre+from_library'
ids = list(map(int, str(md.data(mime)).split()))
self.handle_drop(item, child, ids)
event.accept()
def handle_drop(self, parent, child, ids): def handle_drop(self, parent, child, ids):
print 'Dropped ids:', ids # print 'Dropped ids:', ids, parent.category_key, child.tag.name
key = parent.category_key
fm = self.db.metadata_for_field(key)
is_multiple = fm['is_multiple']
val = child.tag.name
for id in ids:
mi = self.db.get_metadata(id, index_is_id=True)
# Prepare to ignore the author, unless it is changed. Title is
# always ignored -- see the call to set_metadata
set_authors = False
# Author_sort cannot change explicitly. Changing the author might
# change it.
mi.author_sort = None # Never will change by itself.
if key == 'authors':
mi.authors = [val]
set_authors=True
elif fm['datatype'] == 'rating':
mi.set(key, len(val) * 2)
elif is_multiple:
new_val = mi.get(key, [])
if val in new_val:
# Fortunately, only one field can change, so the continue
# won't break anything
continue
new_val.append(val)
mi.set(key, new_val)
else:
mi.set(key, val)
self.db.set_metadata(id, mi, set_title=False,
set_authors=set_authors)
self.drag_drop_finished.emit(ids)
@property @property
def match_all(self): def match_all(self):
@ -729,6 +768,7 @@ class TagBrowserMixin(object): # {{{
self.tags_view.author_sort_edit.connect(self.do_author_sort_edit) self.tags_view.author_sort_edit.connect(self.do_author_sort_edit)
self.tags_view.tag_item_renamed.connect(self.do_tag_item_renamed) self.tags_view.tag_item_renamed.connect(self.do_tag_item_renamed)
self.tags_view.search_item_renamed.connect(self.saved_searches_changed) self.tags_view.search_item_renamed.connect(self.saved_searches_changed)
self.tags_view.drag_drop_finished.connect(self.drag_drop_finished)
self.edit_categories.clicked.connect(lambda x: self.edit_categories.clicked.connect(lambda x:
self.do_user_categories_edit()) self.do_user_categories_edit())
@ -810,6 +850,9 @@ class TagBrowserMixin(object): # {{{
self.library_view.model().refresh() self.library_view.model().refresh()
self.tags_view.recount() self.tags_view.recount()
def drag_drop_finished(self, ids):
self.library_view.model().refresh_ids(ids)
# }}} # }}}
class TagBrowserWidget(QWidget): # {{{ class TagBrowserWidget(QWidget): # {{{

View File

@ -1247,7 +1247,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
self.set_path(id, True) self.set_path(id, True)
self.notify('metadata', [id]) self.notify('metadata', [id])
def set_metadata(self, id, mi, ignore_errors=False): def set_metadata(self, id, mi, ignore_errors=False,
set_title=True, set_authors=True):
''' '''
Set metadata for the book `id` from the `Metadata` object `mi` Set metadata for the book `id` from the `Metadata` object `mi`
''' '''
@ -1259,14 +1260,15 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
traceback.print_exc() traceback.print_exc()
else: else:
raise raise
if mi.title: if set_title and mi.title:
self.set_title(id, mi.title, commit=False) self.set_title(id, mi.title, commit=False)
if not mi.authors: if set_authors:
mi.authors = [_('Unknown')] if not mi.authors:
authors = [] mi.authors = [_('Unknown')]
for a in mi.authors: authors = []
authors += string_to_authors(a) for a in mi.authors:
self.set_authors(id, authors, notify=False, commit=False) authors += string_to_authors(a)
self.set_authors(id, authors, notify=False, commit=False)
if mi.author_sort: if mi.author_sort:
doit(self.set_author_sort, id, mi.author_sort, notify=False, doit(self.set_author_sort, id, mi.author_sort, notify=False,
commit=False) commit=False)