mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
...
This commit is contained in:
parent
638f70b640
commit
90a5a5ad41
@ -8,6 +8,7 @@ __copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
|
|||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
from threading import Thread, Event
|
from threading import Thread, Event
|
||||||
|
from operator import attrgetter
|
||||||
|
|
||||||
from PyQt4.Qt import (QStyledItemDelegate, QTextDocument, QRectF, QIcon, Qt,
|
from PyQt4.Qt import (QStyledItemDelegate, QTextDocument, QRectF, QIcon, Qt,
|
||||||
QStyle, QApplication, QDialog, QVBoxLayout, QLabel, QDialogButtonBox,
|
QStyle, QApplication, QDialog, QVBoxLayout, QLabel, QDialogButtonBox,
|
||||||
@ -22,7 +23,7 @@ from calibre.ebooks.metadata.sources.identify import identify
|
|||||||
from calibre.ebooks.metadata.book.base import Metadata
|
from calibre.ebooks.metadata.book.base import Metadata
|
||||||
from calibre.gui2 import error_dialog, NONE
|
from calibre.gui2 import error_dialog, NONE
|
||||||
from calibre.utils.date import utcnow, fromordinal, format_date
|
from calibre.utils.date import utcnow, fromordinal, format_date
|
||||||
|
from calibre.library.comments import comments_to_html
|
||||||
|
|
||||||
class RichTextDelegate(QStyledItemDelegate): # {{{
|
class RichTextDelegate(QStyledItemDelegate): # {{{
|
||||||
|
|
||||||
@ -107,10 +108,33 @@ class ResultsModel(QAbstractTableModel):
|
|||||||
return self.yes_icon
|
return self.yes_icon
|
||||||
if col == 4 and book.comments:
|
if col == 4 and book.comments:
|
||||||
return self.yes_icon
|
return self.yes_icon
|
||||||
|
elif role == Qt.UserRole:
|
||||||
|
return book
|
||||||
return NONE
|
return NONE
|
||||||
|
|
||||||
|
def sort(self, col, order=Qt.AscendingOrder):
|
||||||
|
key = lambda x: x
|
||||||
|
if col == 0:
|
||||||
|
key = attrgetter('gui_rank')
|
||||||
|
elif col == 1:
|
||||||
|
key = attrgetter('title')
|
||||||
|
elif col == 2:
|
||||||
|
key = attrgetter('authors')
|
||||||
|
elif col == 3:
|
||||||
|
key = attrgetter('has_cached_cover_url')
|
||||||
|
elif key == 4:
|
||||||
|
key = lambda x: bool(x.comments)
|
||||||
|
|
||||||
|
self.results.sort(key=key, reverse=order==Qt.AscendingOrder)
|
||||||
|
self.reset()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ResultsView(QTableView): # {{{
|
class ResultsView(QTableView): # {{{
|
||||||
|
|
||||||
|
show_details_signal = pyqtSignal(object)
|
||||||
|
book_selected = pyqtSignal(object)
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
QTableView.__init__(self, parent)
|
QTableView.__init__(self, parent)
|
||||||
self.rt_delegate = RichTextDelegate(self)
|
self.rt_delegate = RichTextDelegate(self)
|
||||||
@ -118,6 +142,9 @@ class ResultsView(QTableView): # {{{
|
|||||||
self.setAlternatingRowColors(True)
|
self.setAlternatingRowColors(True)
|
||||||
self.setSelectionBehavior(self.SelectRows)
|
self.setSelectionBehavior(self.SelectRows)
|
||||||
self.setIconSize(QSize(24, 24))
|
self.setIconSize(QSize(24, 24))
|
||||||
|
self.clicked.connect(self.show_details)
|
||||||
|
self.doubleClicked.connect(self.select_index)
|
||||||
|
self.setSortingEnabled(True)
|
||||||
|
|
||||||
def show_results(self, results):
|
def show_results(self, results):
|
||||||
self._model = ResultsModel(results, self)
|
self._model = ResultsModel(results, self)
|
||||||
@ -126,6 +153,38 @@ class ResultsView(QTableView): # {{{
|
|||||||
self.setItemDelegateForColumn(i, self.rt_delegate)
|
self.setItemDelegateForColumn(i, self.rt_delegate)
|
||||||
self.resizeRowsToContents()
|
self.resizeRowsToContents()
|
||||||
self.resizeColumnsToContents()
|
self.resizeColumnsToContents()
|
||||||
|
self.setFocus(Qt.OtherFocusReason)
|
||||||
|
|
||||||
|
def currentChanged(self, current, previous):
|
||||||
|
ret = QTableView.currentChanged(self, current, previous)
|
||||||
|
self.show_details(current)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def show_details(self, index):
|
||||||
|
book = self.model().data(index, Qt.UserRole)
|
||||||
|
parts = [
|
||||||
|
'<center>',
|
||||||
|
'<h2>%s</h2>'%book.title,
|
||||||
|
'<div><i>%s</i></div>'%authors_to_string(book.authors),
|
||||||
|
]
|
||||||
|
if not book.is_null('rating'):
|
||||||
|
parts.append('<div>%s</div>'%('\u2605'*int(book.rating)))
|
||||||
|
parts.append('</center>')
|
||||||
|
if book.tags:
|
||||||
|
parts.append('<div>%s</div><div>\u00a0</div>'%', '.join(book.tags))
|
||||||
|
if book.comments:
|
||||||
|
parts.append(comments_to_html(book.comments))
|
||||||
|
|
||||||
|
self.show_details_signal.emit(''.join(parts))
|
||||||
|
|
||||||
|
def select_index(self, index):
|
||||||
|
if not index.isValid():
|
||||||
|
index = self.model().index(0, 0)
|
||||||
|
book = self.model().data(index, Qt.UserRole)
|
||||||
|
self.book_selected.emit(book)
|
||||||
|
|
||||||
|
def get_result(self):
|
||||||
|
self.select_index(self.currentIndex())
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
@ -224,6 +283,8 @@ class IdentifyWorker(Thread): # {{{
|
|||||||
class IdentifyWidget(QWidget): # {{{
|
class IdentifyWidget(QWidget): # {{{
|
||||||
|
|
||||||
rejected = pyqtSignal()
|
rejected = pyqtSignal()
|
||||||
|
results_found = pyqtSignal()
|
||||||
|
book_selected = pyqtSignal(object)
|
||||||
|
|
||||||
def __init__(self, log, parent=None):
|
def __init__(self, log, parent=None):
|
||||||
QWidget.__init__(self, parent)
|
QWidget.__init__(self, parent)
|
||||||
@ -241,11 +302,15 @@ class IdentifyWidget(QWidget): # {{{
|
|||||||
l.addWidget(self.top, 0, 0)
|
l.addWidget(self.top, 0, 0)
|
||||||
|
|
||||||
self.results_view = ResultsView(self)
|
self.results_view = ResultsView(self)
|
||||||
|
self.results_view.book_selected.connect(self.book_selected.emit)
|
||||||
|
self.get_result = self.results_view.get_result
|
||||||
l.addWidget(self.results_view, 1, 0)
|
l.addWidget(self.results_view, 1, 0)
|
||||||
|
|
||||||
self.comments_view = Comments(self)
|
self.comments_view = Comments(self)
|
||||||
l.addWidget(self.comments_view, 1, 1)
|
l.addWidget(self.comments_view, 1, 1)
|
||||||
|
|
||||||
|
self.results_view.show_details_signal.connect(self.comments_view.show_data)
|
||||||
|
|
||||||
self.query = QLabel('download starting...')
|
self.query = QLabel('download starting...')
|
||||||
f = self.query.font()
|
f = self.query.font()
|
||||||
f.setPointSize(f.pointSize()-2)
|
f.setPointSize(f.pointSize()-2)
|
||||||
@ -326,6 +391,8 @@ class IdentifyWidget(QWidget): # {{{
|
|||||||
<div>To see <b>details</b>, click on any result</div>''' %
|
<div>To see <b>details</b>, click on any result</div>''' %
|
||||||
len(self.worker.results))
|
len(self.worker.results))
|
||||||
|
|
||||||
|
self.results_found.emit()
|
||||||
|
|
||||||
|
|
||||||
def cancel(self):
|
def cancel(self):
|
||||||
self.abort.set()
|
self.abort.set()
|
||||||
@ -345,23 +412,46 @@ class FullFetch(QDialog): # {{{
|
|||||||
self.setLayout(l)
|
self.setLayout(l)
|
||||||
l.addWidget(self.stack)
|
l.addWidget(self.stack)
|
||||||
|
|
||||||
self.bb = QDialogButtonBox(QDialogButtonBox.Cancel)
|
self.bb = QDialogButtonBox(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)
|
||||||
l.addWidget(self.bb)
|
l.addWidget(self.bb)
|
||||||
self.bb.rejected.connect(self.reject)
|
self.bb.rejected.connect(self.reject)
|
||||||
|
self.next_button = self.bb.addButton(_('Next'), self.bb.AcceptRole)
|
||||||
|
self.next_button.setDefault(True)
|
||||||
|
self.next_button.setEnabled(False)
|
||||||
|
self.next_button.clicked.connect(self.next_clicked)
|
||||||
|
self.ok_button = self.bb.button(self.bb.Ok)
|
||||||
|
self.ok_button.setVisible(False)
|
||||||
|
self.ok_button.clicked.connect(self.ok_clicked)
|
||||||
|
|
||||||
self.identify_widget = IdentifyWidget(log, self)
|
self.identify_widget = IdentifyWidget(log, self)
|
||||||
self.identify_widget.rejected.connect(self.reject)
|
self.identify_widget.rejected.connect(self.reject)
|
||||||
|
self.identify_widget.results_found.connect(self.identify_results_found)
|
||||||
|
self.identify_widget.book_selected.connect(self.book_selected)
|
||||||
self.stack.addWidget(self.identify_widget)
|
self.stack.addWidget(self.identify_widget)
|
||||||
self.resize(850, 500)
|
self.resize(850, 500)
|
||||||
|
|
||||||
|
def book_selected(self, book):
|
||||||
|
print (book)
|
||||||
|
self.next_button.setVisible(False)
|
||||||
|
self.ok_button.setVisible(True)
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
# Prevent pressing Enter from closing the dialog
|
# Prevent the usual dialog accept mechanisms from working
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def reject(self):
|
def reject(self):
|
||||||
self.identify_widget.cancel()
|
self.identify_widget.cancel()
|
||||||
return QDialog.reject(self)
|
return QDialog.reject(self)
|
||||||
|
|
||||||
|
def identify_results_found(self):
|
||||||
|
self.next_button.setEnabled(True)
|
||||||
|
|
||||||
|
def next_clicked(self, *args):
|
||||||
|
self.identify_widget.get_result()
|
||||||
|
|
||||||
|
def ok_clicked(self, *args):
|
||||||
|
pass
|
||||||
|
|
||||||
def start(self, title=None, authors=None, identifiers={}):
|
def start(self, title=None, authors=None, identifiers={}):
|
||||||
self.identify_widget.start(title=title, authors=authors,
|
self.identify_widget.start(title=title, authors=authors,
|
||||||
identifiers=identifiers)
|
identifiers=identifiers)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user