mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Edit authors works.
This commit is contained in:
parent
5f4a828efe
commit
f4854022a0
@ -6,7 +6,7 @@ __license__ = 'GPL v3'
|
|||||||
from PyQt4.Qt import Qt, QDialog, QTableWidgetItem, QAbstractItemView
|
from PyQt4.Qt import Qt, QDialog, QTableWidgetItem, QAbstractItemView
|
||||||
|
|
||||||
from calibre.ebooks.metadata import author_to_author_sort
|
from calibre.ebooks.metadata import author_to_author_sort
|
||||||
from calibre.gui2.dialogs.sort_field_dialog_ui import Ui_SortFieldDialog
|
from calibre.gui2.dialogs.edit_authors_dialog_ui import Ui_EditAuthorsDialog
|
||||||
|
|
||||||
class tableItem(QTableWidgetItem):
|
class tableItem(QTableWidgetItem):
|
||||||
def __ge__(self, other):
|
def __ge__(self, other):
|
||||||
@ -15,11 +15,11 @@ class tableItem(QTableWidgetItem):
|
|||||||
def __lt__(self, other):
|
def __lt__(self, other):
|
||||||
return unicode(self.text()).lower() < unicode(other.text()).lower()
|
return unicode(self.text()).lower() < unicode(other.text()).lower()
|
||||||
|
|
||||||
class SortFieldDialog(QDialog, Ui_SortFieldDialog):
|
class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
|
||||||
|
|
||||||
def __init__(self, parent, db, id_to_select):
|
def __init__(self, parent, db, id_to_select):
|
||||||
QDialog.__init__(self, parent)
|
QDialog.__init__(self, parent)
|
||||||
Ui_SortFieldDialog.__init__(self)
|
Ui_EditAuthorsDialog.__init__(self)
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
|
|
||||||
self.buttonBox.accepted.connect(self.accepted)
|
self.buttonBox.accepted.connect(self.accepted)
|
||||||
@ -42,22 +42,21 @@ class SortFieldDialog(QDialog, Ui_SortFieldDialog):
|
|||||||
self.table.setItem(row, 0, aut)
|
self.table.setItem(row, 0, aut)
|
||||||
self.table.setItem(row, 1, sort)
|
self.table.setItem(row, 1, sort)
|
||||||
if id == id_to_select:
|
if id == id_to_select:
|
||||||
select_item = aut
|
select_item = sort
|
||||||
|
|
||||||
if select_item is not None:
|
if select_item is not None:
|
||||||
self.table.setCurrentItem(select_item)
|
self.table.setCurrentItem(select_item)
|
||||||
|
self.table.editItem(select_item)
|
||||||
self.table.resizeColumnsToContents()
|
self.table.resizeColumnsToContents()
|
||||||
self.table.setSortingEnabled(True)
|
self.table.setSortingEnabled(True)
|
||||||
self.table.sortByColumn(1, Qt.AscendingOrder)
|
self.table.sortByColumn(1, Qt.AscendingOrder)
|
||||||
|
|
||||||
def accepted(self):
|
def accepted(self):
|
||||||
print 'accepted!'
|
|
||||||
self.result = []
|
self.result = []
|
||||||
for row in range(0,self.table.rowCount()):
|
for row in range(0,self.table.rowCount()):
|
||||||
id = self.table.item(row, 0).data(Qt.UserRole).toInt()[0]
|
id = self.table.item(row, 0).data(Qt.UserRole).toInt()[0]
|
||||||
aut = unicode(self.table.item(row, 0).text())
|
aut = unicode(self.table.item(row, 0).text())
|
||||||
sort = unicode(self.table.item(row, 1).text())
|
sort = unicode(self.table.item(row, 1).text())
|
||||||
print id, aut, sort
|
|
||||||
orig_aut,orig_sort = self.authors[id]
|
orig_aut,orig_sort = self.authors[id]
|
||||||
if orig_aut != aut or orig_sort != sort:
|
if orig_aut != aut or orig_sort != sort:
|
||||||
self.result.append((id, orig_aut, aut, sort))
|
self.result.append((id, orig_aut, aut, sort))
|
||||||
@ -68,3 +67,4 @@ class SortFieldDialog(QDialog, Ui_SortFieldDialog):
|
|||||||
c = self.table.item(row, 1)
|
c = self.table.item(row, 1)
|
||||||
if c is not None:
|
if c is not None:
|
||||||
c.setText(author_to_author_sort(aut))
|
c.setText(author_to_author_sort(aut))
|
||||||
|
self.table.setCurrentItem(c)
|
89
src/calibre/gui2/dialogs/edit_authors_dialog.ui
Normal file
89
src/calibre/gui2/dialogs/edit_authors_dialog.ui
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>EditAuthorsDialog</class>
|
||||||
|
<widget class="QDialog" name="EditAuthorsDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>410</width>
|
||||||
|
<height>239</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Manage authors</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QTableWidget" name="table">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="columnCount">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
<property name="centerButtons">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
<zorder>buttonBox</zorder>
|
||||||
|
<zorder>table</zorder>
|
||||||
|
<zorder>buttonBox</zorder>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>EditAuthorsDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>229</x>
|
||||||
|
<y>211</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>234</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>EditAuthorsDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>297</x>
|
||||||
|
<y>217</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>234</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
@ -1,87 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>SortFieldDialog</class>
|
|
||||||
<widget class="QDialog" name="SortFieldDialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>518</width>
|
|
||||||
<height>262</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Edit sort field</string>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="verticalLayoutWidget">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>10</x>
|
|
||||||
<y>10</y>
|
|
||||||
<width>501</width>
|
|
||||||
<height>231</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QTableWidget" name="table">
|
|
||||||
<property name="columnCount">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="standardButtons">
|
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>accepted()</signal>
|
|
||||||
<receiver>SortFieldDialog</receiver>
|
|
||||||
<slot>accept()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>229</x>
|
|
||||||
<y>211</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>157</x>
|
|
||||||
<y>234</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>rejected()</signal>
|
|
||||||
<receiver>SortFieldDialog</receiver>
|
|
||||||
<slot>reject()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>297</x>
|
|
||||||
<y>217</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>286</x>
|
|
||||||
<y>234</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
|
||||||
</ui>
|
|
@ -121,6 +121,9 @@
|
|||||||
<property name="standardButtons">
|
<property name="standardButtons">
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="centerButtons">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -23,7 +23,7 @@ from calibre.utils.search_query_parser import saved_searches
|
|||||||
from calibre.gui2 import error_dialog
|
from calibre.gui2 import error_dialog
|
||||||
from calibre.gui2.dialogs.tag_categories import TagCategories
|
from calibre.gui2.dialogs.tag_categories import TagCategories
|
||||||
from calibre.gui2.dialogs.tag_list_editor import TagListEditor
|
from calibre.gui2.dialogs.tag_list_editor import TagListEditor
|
||||||
from calibre.gui2.dialogs.sort_field_dialog import SortFieldDialog
|
from calibre.gui2.dialogs.edit_authors_dialog import EditAuthorsDialog
|
||||||
|
|
||||||
class TagDelegate(QItemDelegate):
|
class TagDelegate(QItemDelegate):
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ class TagsView(QTreeView): # {{{
|
|||||||
user_category_edit = pyqtSignal(object)
|
user_category_edit = pyqtSignal(object)
|
||||||
tag_list_edit = pyqtSignal(object, object)
|
tag_list_edit = pyqtSignal(object, object)
|
||||||
saved_search_edit = pyqtSignal(object)
|
saved_search_edit = pyqtSignal(object)
|
||||||
author_sort_edit = pyqtSignal(object, object, object)
|
author_sort_edit = pyqtSignal(object, object)
|
||||||
tag_item_renamed = pyqtSignal()
|
tag_item_renamed = pyqtSignal()
|
||||||
search_item_renamed = pyqtSignal()
|
search_item_renamed = pyqtSignal()
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ class TagsView(QTreeView): # {{{
|
|||||||
self.saved_search_edit.emit(category)
|
self.saved_search_edit.emit(category)
|
||||||
return
|
return
|
||||||
if action == 'edit_author_sort':
|
if action == 'edit_author_sort':
|
||||||
self.author_sort_edit.emit(self, category, index)
|
self.author_sort_edit.emit(self, index)
|
||||||
return
|
return
|
||||||
if action == 'hide':
|
if action == 'hide':
|
||||||
self.hidden_categories.add(category)
|
self.hidden_categories.add(category)
|
||||||
@ -199,7 +199,6 @@ class TagsView(QTreeView): # {{{
|
|||||||
tag_item = item
|
tag_item = item
|
||||||
tag_name = item.tag.name
|
tag_name = item.tag.name
|
||||||
tag_id = item.tag.id
|
tag_id = item.tag.id
|
||||||
tag_sort = item.tag.sort
|
|
||||||
item = item.parent
|
item = item.parent
|
||||||
if item.type == TagTreeItem.CATEGORY:
|
if item.type == TagTreeItem.CATEGORY:
|
||||||
category = unicode(item.name.toString())
|
category = unicode(item.name.toString())
|
||||||
@ -215,13 +214,13 @@ class TagsView(QTreeView): # {{{
|
|||||||
(key in ['authors', 'tags', 'series', 'publisher', 'search'] or \
|
(key in ['authors', 'tags', 'series', 'publisher', 'search'] or \
|
||||||
self.db.field_metadata[key]['is_custom'] and \
|
self.db.field_metadata[key]['is_custom'] and \
|
||||||
self.db.field_metadata[key]['datatype'] != 'rating'):
|
self.db.field_metadata[key]['datatype'] != 'rating'):
|
||||||
self.context_menu.addAction(_('Rename') + " '" + tag_name + "'",
|
self.context_menu.addAction(_('Rename \'%s\'')%tag_name,
|
||||||
partial(self.context_menu_handler, action='edit_item',
|
partial(self.context_menu_handler, action='edit_item',
|
||||||
category=tag_item, index=index))
|
category=tag_item, index=index))
|
||||||
if key == 'authors':
|
if key == 'authors':
|
||||||
self.context_menu.addAction(_('Edit sort for') + " '" + tag_name + "'",
|
self.context_menu.addAction(_('Edit sort for \'%s\'')%tag_name,
|
||||||
partial(self.context_menu_handler, action='edit_author_sort',
|
partial(self.context_menu_handler,
|
||||||
category=tag_sort, index=tag_id))
|
action='edit_author_sort', index=tag_id))
|
||||||
self.context_menu.addSeparator()
|
self.context_menu.addSeparator()
|
||||||
# Hide/Show/Restore categories
|
# Hide/Show/Restore categories
|
||||||
self.context_menu.addAction(_('Hide category %s') % category,
|
self.context_menu.addAction(_('Hide category %s') % category,
|
||||||
@ -238,9 +237,12 @@ class TagsView(QTreeView): # {{{
|
|||||||
self.context_menu.addSeparator()
|
self.context_menu.addSeparator()
|
||||||
if key in ['tags', 'publisher', 'series'] or \
|
if key in ['tags', 'publisher', 'series'] or \
|
||||||
self.db.field_metadata[key]['is_custom']:
|
self.db.field_metadata[key]['is_custom']:
|
||||||
self.context_menu.addAction(_('Manage ') + category,
|
self.context_menu.addAction(_('Manage %s')%category,
|
||||||
partial(self.context_menu_handler, action='open_editor',
|
partial(self.context_menu_handler, action='open_editor',
|
||||||
category=tag_name, key=key))
|
category=tag_name, key=key))
|
||||||
|
elif key == 'authors':
|
||||||
|
self.context_menu.addAction(_('Manage %s')%category,
|
||||||
|
partial(self.context_menu_handler, action='edit_author_sort'))
|
||||||
elif key == 'search':
|
elif key == 'search':
|
||||||
self.context_menu.addAction(_('Manage Saved Searches'),
|
self.context_menu.addAction(_('Manage Saved Searches'),
|
||||||
partial(self.context_menu_handler, action='manage_searches',
|
partial(self.context_menu_handler, action='manage_searches',
|
||||||
@ -725,16 +727,17 @@ class TagBrowserMixin(object): # {{{
|
|||||||
self.saved_search.clear_to_help()
|
self.saved_search.clear_to_help()
|
||||||
self.search.clear_to_help()
|
self.search.clear_to_help()
|
||||||
|
|
||||||
def do_author_sort_edit(self, parent, text, id):
|
def do_author_sort_edit(self, parent, id):
|
||||||
editor = SortFieldDialog(parent, self.library_view.model().db, id)
|
db = self.library_view.model().db
|
||||||
|
editor = EditAuthorsDialog(parent, db, id)
|
||||||
d = editor.exec_()
|
d = editor.exec_()
|
||||||
if d:
|
if d:
|
||||||
print editor.result
|
|
||||||
for (id, old_author, new_author, new_sort) in editor.result:
|
for (id, old_author, new_author, new_sort) in editor.result:
|
||||||
if old_author != new_author:
|
if old_author != new_author:
|
||||||
self.library_view.model().db.rename_author(id, new_author)
|
# The id might change if the new author already exists
|
||||||
self.library_view.model().db.set_sort_field_for_author \
|
id = db.rename_author(id, new_author)
|
||||||
(id, unicode(new_sort))
|
db.set_sort_field_for_author(id, unicode(new_sort))
|
||||||
|
self.library_view.model().refresh()
|
||||||
self.tags_view.recount()
|
self.tags_view.recount()
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
@ -1160,6 +1160,11 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
self.conn.execute('UPDATE authors SET sort=? WHERE id=?', \
|
self.conn.execute('UPDATE authors SET sort=? WHERE id=?', \
|
||||||
(new_sort, old_id))
|
(new_sort, old_id))
|
||||||
self.conn.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)
|
||||||
|
|
||||||
def rename_author(self, old_id, new_name):
|
def rename_author(self, old_id, new_name):
|
||||||
# Make sure that any commas in new_name are changed to '|'!
|
# Make sure that any commas in new_name are changed to '|'!
|
||||||
@ -1186,7 +1191,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
self.conn.execute('UPDATE authors SET name=? WHERE id=?',
|
self.conn.execute('UPDATE authors SET name=? WHERE id=?',
|
||||||
(new_name, old_id))
|
(new_name, old_id))
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
return
|
return new_id
|
||||||
# Author exists. To fix this, we must replace all the authors
|
# Author exists. To fix this, we must replace all the authors
|
||||||
# instead of replacing the one. Reason: db integrity checks can stop
|
# instead of replacing the one. Reason: db integrity checks can stop
|
||||||
# the rename process, which would leave everything half-done. We
|
# the rename process, which would leave everything half-done. We
|
||||||
@ -1233,6 +1238,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
self.set_author_sort(book_id, ss)
|
self.set_author_sort(book_id, ss)
|
||||||
# the caller will do a general refresh, so we don't need to
|
# the caller will do a general refresh, so we don't need to
|
||||||
# do one here
|
# do one here
|
||||||
|
return new_id
|
||||||
|
|
||||||
# end convenience methods
|
# end convenience methods
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user