mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Merge branch 'master' of https://github.com/cbhaley/calibre
This commit is contained in:
commit
9abd755ffb
@ -5,6 +5,8 @@ __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
|||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
|
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
from PyQt5.Qt import (Qt, QDialog, QTableWidgetItem, QAbstractItemView, QIcon,
|
from PyQt5.Qt import (Qt, QDialog, QTableWidgetItem, QAbstractItemView, QIcon,
|
||||||
QDialogButtonBox, QFrame, QLabel, QTimer, QMenu, QApplication,
|
QDialogButtonBox, QFrame, QLabel, QTimer, QMenu, QApplication,
|
||||||
QByteArray, QItemDelegate, QAction)
|
QByteArray, QItemDelegate, QAction)
|
||||||
@ -22,11 +24,22 @@ QT_HIDDEN_CLEAR_ACTION = '_q_qlineeditclearaction'
|
|||||||
|
|
||||||
class tableItem(QTableWidgetItem):
|
class tableItem(QTableWidgetItem):
|
||||||
|
|
||||||
|
def __init__(self, txt):
|
||||||
|
QTableWidgetItem.__init__(self, txt)
|
||||||
|
self.sort_key = sort_key(unicode_type(txt))
|
||||||
|
|
||||||
|
def setText(self, txt):
|
||||||
|
self.sort_key = sort_key(unicode_type(txt))
|
||||||
|
QTableWidgetItem.setText(self, txt)
|
||||||
|
|
||||||
|
def set_sort_key(self):
|
||||||
|
self.sort_key = sort_key(unicode_type(self.text()))
|
||||||
|
|
||||||
def __ge__(self, other):
|
def __ge__(self, other):
|
||||||
return sort_key(unicode_type(self.text())) >= sort_key(unicode_type(other.text()))
|
return self.sort_key >= other.sort_key
|
||||||
|
|
||||||
def __lt__(self, other):
|
def __lt__(self, other):
|
||||||
return sort_key(unicode_type(self.text())) < sort_key(unicode_type(other.text()))
|
return self.sort_key < other.sort_key
|
||||||
|
|
||||||
|
|
||||||
class EditColumnDelegate(QItemDelegate):
|
class EditColumnDelegate(QItemDelegate):
|
||||||
@ -146,6 +159,7 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
|
|||||||
'link': v['link']}
|
'link': v['link']}
|
||||||
|
|
||||||
self.edited_icon = QIcon(I('modified.png'))
|
self.edited_icon = QIcon(I('modified.png'))
|
||||||
|
self.empty_icon = QIcon()
|
||||||
if prefs['use_primary_find_in_search']:
|
if prefs['use_primary_find_in_search']:
|
||||||
self.string_contains = primary_contains
|
self.string_contains = primary_contains
|
||||||
else:
|
else:
|
||||||
@ -168,11 +182,13 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
|
|||||||
self.show_table(None, None, None, False)
|
self.show_table(None, None, None, False)
|
||||||
|
|
||||||
def show_table(self, id_to_select, select_sort, select_link, is_first_letter):
|
def show_table(self, id_to_select, select_sort, select_link, is_first_letter):
|
||||||
|
auts_to_show = {t[0] for t in
|
||||||
|
self.find_aut_func(use_virtual_library=self.apply_vl_checkbox.isChecked())}
|
||||||
filter_text = icu_lower(unicode_type(self.filter_box.text()))
|
filter_text = icu_lower(unicode_type(self.filter_box.text()))
|
||||||
auts_to_show = []
|
if filter_text:
|
||||||
for t in self.find_aut_func(use_virtual_library=self.apply_vl_checkbox.isChecked()):
|
auts_to_show = {id_ for id_ in auts_to_show
|
||||||
if self.string_contains(filter_text, icu_lower(t[1])):
|
if self.string_contains(filter_text, icu_lower(self.authors[id_]['name']))}
|
||||||
auts_to_show.append(t[0])
|
|
||||||
self.table.blockSignals(True)
|
self.table.blockSignals(True)
|
||||||
self.table.clear()
|
self.table.clear()
|
||||||
self.table.setColumnCount(3)
|
self.table.setColumnCount(3)
|
||||||
@ -183,22 +199,20 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
|
|||||||
if id_ not in auts_to_show:
|
if id_ not in auts_to_show:
|
||||||
continue
|
continue
|
||||||
name, sort, link = (v['name'], v['sort'], v['link'])
|
name, sort, link = (v['name'], v['sort'], v['link'])
|
||||||
orig = self.original_authors[id_]
|
|
||||||
name = name.replace('|', ',')
|
name = name.replace('|', ',')
|
||||||
|
|
||||||
name_item = tableItem(name)
|
name_item = tableItem(name)
|
||||||
name_item.setData(Qt.UserRole, id_)
|
name_item.setData(Qt.UserRole, id_)
|
||||||
if name != orig['name']:
|
|
||||||
name_item.setIcon(self.edited_icon)
|
|
||||||
sort_item = tableItem(sort)
|
sort_item = tableItem(sort)
|
||||||
if sort != orig['sort']:
|
|
||||||
sort_item.setIcon(self.edited_icon)
|
|
||||||
link_item = tableItem(link)
|
link_item = tableItem(link)
|
||||||
if link != orig['link']:
|
|
||||||
link_item.setIcon(self.edited_icon)
|
|
||||||
self.table.setItem(row, 0, name_item)
|
self.table.setItem(row, 0, name_item)
|
||||||
self.table.setItem(row, 1, sort_item)
|
self.table.setItem(row, 1, sort_item)
|
||||||
self.table.setItem(row, 2, link_item)
|
self.table.setItem(row, 2, link_item)
|
||||||
|
|
||||||
|
self.set_icon(name_item, id_)
|
||||||
|
self.set_icon(sort_item, id_)
|
||||||
|
self.set_icon(link_item, id_)
|
||||||
row += 1
|
row += 1
|
||||||
|
|
||||||
self.table.setItemDelegate(EditColumnDelegate(self.completion_data))
|
self.table.setItemDelegate(EditColumnDelegate(self.completion_data))
|
||||||
@ -219,9 +233,10 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
|
|||||||
select_item = None
|
select_item = None
|
||||||
use_as = tweaks['categories_use_field_for_author_name']
|
use_as = tweaks['categories_use_field_for_author_name']
|
||||||
for row in range(0, len(auts_to_show)):
|
for row in range(0, len(auts_to_show)):
|
||||||
name_item = self.table.item(row, 1) if use_as else self.table.item(row, 0)
|
|
||||||
if is_first_letter:
|
if is_first_letter:
|
||||||
if primary_startswith(name_item.text(), id_to_select):
|
item_txt = unicode_type(self.table.item(row, 1).text() if use_as
|
||||||
|
else self.table.item(row, 0).text())
|
||||||
|
if primary_startswith(item_txt, id_to_select):
|
||||||
select_item = self.table.item(row, 1)
|
select_item = self.table.item(row, 1)
|
||||||
break
|
break
|
||||||
elif id_to_select == self.table.item(row, 0).data(Qt.UserRole):
|
elif id_to_select == self.table.item(row, 0).data(Qt.UserRole):
|
||||||
@ -230,7 +245,8 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
|
|||||||
elif select_link:
|
elif select_link:
|
||||||
select_item = self.table.item(row, 2)
|
select_item = self.table.item(row, 2)
|
||||||
else:
|
else:
|
||||||
select_item = name_item
|
select_item = (self.table.item(row, 1) if use_as
|
||||||
|
else self.table.item(row, 0))
|
||||||
break
|
break
|
||||||
if select_item:
|
if select_item:
|
||||||
self.table.setCurrentItem(select_item)
|
self.table.setCurrentItem(select_item)
|
||||||
@ -269,6 +285,9 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
|
|||||||
self.table.setColumnWidth(c, w)
|
self.table.setColumnWidth(c, w)
|
||||||
self.save_state()
|
self.save_state()
|
||||||
|
|
||||||
|
def get_column_name(self, column):
|
||||||
|
return ['name', 'sort', 'link'][column]
|
||||||
|
|
||||||
def show_context_menu(self, point):
|
def show_context_menu(self, point):
|
||||||
self.context_item = self.table.itemAt(point)
|
self.context_item = self.table.itemAt(point)
|
||||||
case_menu = QMenu(_('Change case'))
|
case_menu = QMenu(_('Change case'))
|
||||||
@ -285,12 +304,19 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
|
|||||||
action_capitalize.triggered.connect(self.capitalize)
|
action_capitalize.triggered.connect(self.capitalize)
|
||||||
|
|
||||||
m = self.au_context_menu = QMenu()
|
m = self.au_context_menu = QMenu()
|
||||||
|
idx = self.table.indexAt(point)
|
||||||
|
id_ = int(self.table.item(idx.row(), 0).data(Qt.UserRole))
|
||||||
|
sub = self.get_column_name(idx.column())
|
||||||
|
if self.context_item.text() != self.original_authors[id_][sub]:
|
||||||
|
ca = m.addAction(_('Undo'))
|
||||||
|
ca.triggered.connect(partial(self.undo_cell,
|
||||||
|
old_value=self.original_authors[id_][sub]))
|
||||||
|
m.addSeparator()
|
||||||
ca = m.addAction(_('Copy'))
|
ca = m.addAction(_('Copy'))
|
||||||
ca.triggered.connect(self.copy_to_clipboard)
|
ca.triggered.connect(self.copy_to_clipboard)
|
||||||
ca = m.addAction(_('Paste'))
|
ca = m.addAction(_('Paste'))
|
||||||
ca.triggered.connect(self.paste_from_clipboard)
|
ca.triggered.connect(self.paste_from_clipboard)
|
||||||
m.addSeparator()
|
m.addSeparator()
|
||||||
|
|
||||||
if self.context_item is not None and self.context_item.column() == 0:
|
if self.context_item is not None and self.context_item.column() == 0:
|
||||||
ca = m.addAction(_('Copy to author sort'))
|
ca = m.addAction(_('Copy to author sort'))
|
||||||
ca.triggered.connect(self.copy_au_to_aus)
|
ca.triggered.connect(self.copy_au_to_aus)
|
||||||
@ -304,6 +330,9 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
|
|||||||
m.addMenu(case_menu)
|
m.addMenu(case_menu)
|
||||||
m.exec_(self.table.mapToGlobal(point))
|
m.exec_(self.table.mapToGlobal(point))
|
||||||
|
|
||||||
|
def undo_cell(self, old_value):
|
||||||
|
self.context_item.setText(old_value)
|
||||||
|
|
||||||
def search_in_book_list(self):
|
def search_in_book_list(self):
|
||||||
from calibre.gui2.ui import get_gui
|
from calibre.gui2.ui import get_gui
|
||||||
row = self.context_item.row()
|
row = self.context_item.row()
|
||||||
@ -416,10 +445,9 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
|
|||||||
item_aus = self.table.item(row, 1)
|
item_aus = self.table.item(row, 1)
|
||||||
# Sometimes trailing commas are left by changing between copy algs
|
# Sometimes trailing commas are left by changing between copy algs
|
||||||
aus = unicode_type(author_to_author_sort(aut)).rstrip(',')
|
aus = unicode_type(author_to_author_sort(aut)).rstrip(',')
|
||||||
if aus != self.original_authors[id_]['sort']:
|
|
||||||
item_aus.setIcon(self.edited_icon)
|
|
||||||
item_aus.setText(aus)
|
item_aus.setText(aus)
|
||||||
self.authors[id_]['sort'] = aus
|
self.authors[id_]['sort'] = aus
|
||||||
|
self.set_icon(item_aus, id_)
|
||||||
self.table.setFocus(Qt.OtherFocusReason)
|
self.table.setFocus(Qt.OtherFocusReason)
|
||||||
self.table.cellChanged.connect(self.cell_changed)
|
self.table.cellChanged.connect(self.cell_changed)
|
||||||
|
|
||||||
@ -429,18 +457,23 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
|
|||||||
aus = unicode_type(self.table.item(row, 1).text()).strip()
|
aus = unicode_type(self.table.item(row, 1).text()).strip()
|
||||||
item_aut = self.table.item(row, 0)
|
item_aut = self.table.item(row, 0)
|
||||||
id_ = int(item_aut.data(Qt.UserRole))
|
id_ = int(item_aut.data(Qt.UserRole))
|
||||||
if aus != self.original_authors[id_]['name']:
|
|
||||||
item_aut.setIcon(self.edited_icon)
|
|
||||||
item_aut.setText(aus)
|
item_aut.setText(aus)
|
||||||
self.authors[id_]['name'] = aus
|
self.authors[id_]['name'] = aus
|
||||||
|
self.set_icon(item_aut, id_)
|
||||||
self.table.setFocus(Qt.OtherFocusReason)
|
self.table.setFocus(Qt.OtherFocusReason)
|
||||||
self.table.cellChanged.connect(self.cell_changed)
|
self.table.cellChanged.connect(self.cell_changed)
|
||||||
|
|
||||||
|
def set_icon(self, item, id_):
|
||||||
|
col_name = self.get_column_name(item.column())
|
||||||
|
if unicode_type(item.text()) != self.original_authors[id_][col_name]:
|
||||||
|
item.setIcon(self.edited_icon)
|
||||||
|
else:
|
||||||
|
item.setIcon(self.empty_icon)
|
||||||
|
|
||||||
def cell_changed(self, row, col):
|
def cell_changed(self, row, col):
|
||||||
id_ = int(self.table.item(row, 0).data(Qt.UserRole))
|
id_ = int(self.table.item(row, 0).data(Qt.UserRole))
|
||||||
if col == 0:
|
if col == 0:
|
||||||
item = self.table.item(row, 0)
|
item = self.table.item(row, 0)
|
||||||
item.setIcon(self.edited_icon)
|
|
||||||
aut = unicode_type(item.text()).strip()
|
aut = unicode_type(item.text()).strip()
|
||||||
aut_list = string_to_authors(aut)
|
aut_list = string_to_authors(aut)
|
||||||
if len(aut_list) != 1:
|
if len(aut_list) != 1:
|
||||||
@ -448,18 +481,18 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
|
|||||||
_('You cannot change an author to multiple authors.')).exec_()
|
_('You cannot change an author to multiple authors.')).exec_()
|
||||||
aut = ' % '.join(aut_list)
|
aut = ' % '.join(aut_list)
|
||||||
self.table.item(row, 0).setText(aut)
|
self.table.item(row, 0).setText(aut)
|
||||||
|
item.set_sort_key()
|
||||||
self.authors[id_]['name'] = aut
|
self.authors[id_]['name'] = aut
|
||||||
|
self.set_icon(item, id_)
|
||||||
c = self.table.item(row, 1)
|
c = self.table.item(row, 1)
|
||||||
txt = author_to_author_sort(aut)
|
txt = author_to_author_sort(aut)
|
||||||
c.setText(txt)
|
|
||||||
self.authors[id_]['sort'] = txt
|
self.authors[id_]['sort'] = txt
|
||||||
|
c.setText(txt) # This triggers another cellChanged event
|
||||||
item = c
|
item = c
|
||||||
else:
|
else:
|
||||||
item = self.table.item(row, col)
|
item = self.table.item(row, col)
|
||||||
item.setIcon(self.edited_icon)
|
item.set_sort_key()
|
||||||
if col == 1:
|
self.set_icon(item, id_)
|
||||||
self.authors[id_]['sort'] = unicode_type(item.text())
|
self.authors[id_][self.get_column_name(col)] = unicode_type(item.text())
|
||||||
else:
|
|
||||||
self.authors[id_]['link'] = unicode_type(item.text())
|
|
||||||
self.table.setCurrentItem(item)
|
self.table.setCurrentItem(item)
|
||||||
self.table.scrollToItem(item)
|
self.table.scrollToItem(item)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user