mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Metadata download: WHen showing downloaded covers, allow right clicking on a cover to view a full size version. Fixes #1170544 ((enhancement) Zooming in on searched cover images)
This commit is contained in:
parent
5301f28eb3
commit
6031fa67b8
@ -21,7 +21,7 @@ from PyQt4.Qt import (
|
|||||||
QDialog, QVBoxLayout, QLabel, QDialogButtonBox, QStyle, QStackedWidget,
|
QDialog, QVBoxLayout, QLabel, QDialogButtonBox, QStyle, QStackedWidget,
|
||||||
QWidget, QTableView, QGridLayout, QFontInfo, QPalette, QTimer, pyqtSignal,
|
QWidget, QTableView, QGridLayout, QFontInfo, QPalette, QTimer, pyqtSignal,
|
||||||
QAbstractTableModel, QVariant, QSize, QListView, QPixmap, QModelIndex,
|
QAbstractTableModel, QVariant, QSize, QListView, QPixmap, QModelIndex,
|
||||||
QAbstractListModel, QColor, QRect, QTextBrowser, QStringListModel)
|
QAbstractListModel, QColor, QRect, QTextBrowser, QStringListModel, QMenu, QCursor)
|
||||||
from PyQt4.QtWebKit import QWebView
|
from PyQt4.QtWebKit import QWebView
|
||||||
|
|
||||||
from calibre.customize.ui import metadata_plugins
|
from calibre.customize.ui import metadata_plugins
|
||||||
@ -40,7 +40,7 @@ from calibre.utils.ipc.simple_worker import fork_job, WorkerError
|
|||||||
from calibre.ptempfile import TemporaryDirectory
|
from calibre.ptempfile import TemporaryDirectory
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class RichTextDelegate(QStyledItemDelegate): # {{{
|
class RichTextDelegate(QStyledItemDelegate): # {{{
|
||||||
|
|
||||||
def __init__(self, parent=None, max_width=160):
|
def __init__(self, parent=None, max_width=160):
|
||||||
QStyledItemDelegate.__init__(self, parent)
|
QStyledItemDelegate.__init__(self, parent)
|
||||||
@ -77,7 +77,7 @@ class RichTextDelegate(QStyledItemDelegate): # {{{
|
|||||||
painter.restore()
|
painter.restore()
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class CoverDelegate(QStyledItemDelegate): # {{{
|
class CoverDelegate(QStyledItemDelegate): # {{{
|
||||||
|
|
||||||
needs_redraw = pyqtSignal()
|
needs_redraw = pyqtSignal()
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ class CoverDelegate(QStyledItemDelegate): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class ResultsModel(QAbstractTableModel): # {{{
|
class ResultsModel(QAbstractTableModel): # {{{
|
||||||
|
|
||||||
COLUMNS = (
|
COLUMNS = (
|
||||||
'#', _('Title'), _('Published'), _('Has cover'), _('Has summary')
|
'#', _('Title'), _('Published'), _('Has cover'), _('Has summary')
|
||||||
@ -182,7 +182,6 @@ class ResultsModel(QAbstractTableModel): # {{{
|
|||||||
p = book.publisher if book.publisher else ''
|
p = book.publisher if book.publisher else ''
|
||||||
return '<b>%s</b><br><i>%s</i>' % (d, p)
|
return '<b>%s</b><br><i>%s</i>' % (d, p)
|
||||||
|
|
||||||
|
|
||||||
def data(self, index, role):
|
def data(self, index, role):
|
||||||
row, col = index.row(), index.column()
|
row, col = index.row(), index.column()
|
||||||
try:
|
try:
|
||||||
@ -233,7 +232,7 @@ class ResultsModel(QAbstractTableModel): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class ResultsView(QTableView): # {{{
|
class ResultsView(QTableView): # {{{
|
||||||
|
|
||||||
show_details_signal = pyqtSignal(object)
|
show_details_signal = pyqtSignal(object)
|
||||||
book_selected = pyqtSignal(object)
|
book_selected = pyqtSignal(object)
|
||||||
@ -316,7 +315,7 @@ class ResultsView(QTableView): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class Comments(QWebView): # {{{
|
class Comments(QWebView): # {{{
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
QWebView.__init__(self, parent)
|
QWebView.__init__(self, parent)
|
||||||
@ -384,7 +383,7 @@ class Comments(QWebView): # {{{
|
|||||||
return QSize(800, 300)
|
return QSize(800, 300)
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class IdentifyWorker(Thread): # {{{
|
class IdentifyWorker(Thread): # {{{
|
||||||
|
|
||||||
def __init__(self, log, abort, title, authors, identifiers, caches):
|
def __init__(self, log, abort, title, authors, identifiers, caches):
|
||||||
Thread.__init__(self)
|
Thread.__init__(self)
|
||||||
@ -441,7 +440,7 @@ class IdentifyWorker(Thread): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class IdentifyWidget(QWidget): # {{{
|
class IdentifyWidget(QWidget): # {{{
|
||||||
|
|
||||||
rejected = pyqtSignal()
|
rejected = pyqtSignal()
|
||||||
results_found = pyqtSignal()
|
results_found = pyqtSignal()
|
||||||
@ -552,12 +551,11 @@ class IdentifyWidget(QWidget): # {{{
|
|||||||
self.results_view.show_results(self.worker.results)
|
self.results_view.show_results(self.worker.results)
|
||||||
self.results_found.emit()
|
self.results_found.emit()
|
||||||
|
|
||||||
|
|
||||||
def cancel(self):
|
def cancel(self):
|
||||||
self.abort.set()
|
self.abort.set()
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class CoverWorker(Thread): # {{{
|
class CoverWorker(Thread): # {{{
|
||||||
|
|
||||||
def __init__(self, log, abort, title, authors, identifiers, caches):
|
def __init__(self, log, abort, title, authors, identifiers, caches):
|
||||||
Thread.__init__(self)
|
Thread.__init__(self)
|
||||||
@ -609,7 +607,8 @@ class CoverWorker(Thread): # {{{
|
|||||||
|
|
||||||
def scan_once(self, tdir, seen):
|
def scan_once(self, tdir, seen):
|
||||||
for x in list(os.listdir(tdir)):
|
for x in list(os.listdir(tdir)):
|
||||||
if x in seen: continue
|
if x in seen:
|
||||||
|
continue
|
||||||
if x.endswith('.cover') and os.path.exists(os.path.join(tdir,
|
if x.endswith('.cover') and os.path.exists(os.path.join(tdir,
|
||||||
x+'.done')):
|
x+'.done')):
|
||||||
name = x.rpartition('.')[0]
|
name = x.rpartition('.')[0]
|
||||||
@ -635,7 +634,7 @@ class CoverWorker(Thread): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class CoversModel(QAbstractListModel): # {{{
|
class CoversModel(QAbstractListModel): # {{{
|
||||||
|
|
||||||
def __init__(self, current_cover, parent=None):
|
def __init__(self, current_cover, parent=None):
|
||||||
QAbstractListModel.__init__(self, parent)
|
QAbstractListModel.__init__(self, parent)
|
||||||
@ -770,7 +769,7 @@ class CoversModel(QAbstractListModel): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class CoversView(QListView): # {{{
|
class CoversView(QListView): # {{{
|
||||||
|
|
||||||
chosen = pyqtSignal()
|
chosen = pyqtSignal()
|
||||||
|
|
||||||
@ -793,6 +792,8 @@ class CoversView(QListView): # {{{
|
|||||||
type=Qt.QueuedConnection)
|
type=Qt.QueuedConnection)
|
||||||
|
|
||||||
self.doubleClicked.connect(self.chosen, type=Qt.QueuedConnection)
|
self.doubleClicked.connect(self.chosen, type=Qt.QueuedConnection)
|
||||||
|
self.setContextMenuPolicy(Qt.CustomContextMenu)
|
||||||
|
self.customContextMenuRequested.connect(self.show_context_menu)
|
||||||
|
|
||||||
def select(self, num):
|
def select(self, num):
|
||||||
current = self.model().index(num)
|
current = self.model().index(num)
|
||||||
@ -814,9 +815,24 @@ class CoversView(QListView): # {{{
|
|||||||
else:
|
else:
|
||||||
self.select(self.m.index_from_pointer(pointer).row())
|
self.select(self.m.index_from_pointer(pointer).row())
|
||||||
|
|
||||||
|
def show_context_menu(self, point):
|
||||||
|
idx = self.currentIndex()
|
||||||
|
if idx and idx.isValid() and not idx.data(Qt.UserRole).toPyObject():
|
||||||
|
m = QMenu()
|
||||||
|
m.addAction(QIcon(I('view.png')), _('View this cover at full size'), self.show_cover)
|
||||||
|
m.exec_(QCursor.pos())
|
||||||
|
|
||||||
|
def show_cover(self):
|
||||||
|
idx = self.currentIndex()
|
||||||
|
pmap = self.model().cover_pixmap(idx)
|
||||||
|
if pmap is not None:
|
||||||
|
from calibre.gui2.viewer.image_popup import ImageView
|
||||||
|
d = ImageView(self, pmap, unicode(idx.data(Qt.DisplayRole).toString()), geom_name='metadata_download_cover_popup_geom')
|
||||||
|
d(use_exec=True)
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class CoversWidget(QWidget): # {{{
|
class CoversWidget(QWidget): # {{{
|
||||||
|
|
||||||
chosen = pyqtSignal()
|
chosen = pyqtSignal()
|
||||||
finished = pyqtSignal()
|
finished = pyqtSignal()
|
||||||
@ -922,7 +938,7 @@ class CoversWidget(QWidget): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class LogViewer(QDialog): # {{{
|
class LogViewer(QDialog): # {{{
|
||||||
|
|
||||||
def __init__(self, log, parent=None):
|
def __init__(self, log, parent=None):
|
||||||
QDialog.__init__(self, parent)
|
QDialog.__init__(self, parent)
|
||||||
@ -970,7 +986,7 @@ class LogViewer(QDialog): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class FullFetch(QDialog): # {{{
|
class FullFetch(QDialog): # {{{
|
||||||
|
|
||||||
def __init__(self, current_cover=None, parent=None):
|
def __init__(self, current_cover=None, parent=None):
|
||||||
QDialog.__init__(self, parent)
|
QDialog.__init__(self, parent)
|
||||||
@ -1085,7 +1101,7 @@ class FullFetch(QDialog): # {{{
|
|||||||
return self.exec_()
|
return self.exec_()
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class CoverFetch(QDialog): # {{{
|
class CoverFetch(QDialog): # {{{
|
||||||
|
|
||||||
def __init__(self, current_cover=None, parent=None):
|
def __init__(self, current_cover=None, parent=None):
|
||||||
QDialog.__init__(self, parent)
|
QDialog.__init__(self, parent)
|
||||||
|
@ -15,16 +15,17 @@ from calibre.gui2 import choose_save_file, gprefs
|
|||||||
|
|
||||||
class ImageView(QDialog):
|
class ImageView(QDialog):
|
||||||
|
|
||||||
def __init__(self, parent, current_img, current_url):
|
def __init__(self, parent, current_img, current_url, geom_name='viewer_image_popup_geometry'):
|
||||||
QDialog.__init__(self)
|
QDialog.__init__(self)
|
||||||
dw = QApplication.instance().desktop()
|
dw = QApplication.instance().desktop()
|
||||||
self.avail_geom = dw.availableGeometry(parent)
|
self.avail_geom = dw.availableGeometry(parent)
|
||||||
self.current_img = current_img
|
self.current_img = current_img
|
||||||
self.current_url = current_url
|
self.current_url = current_url
|
||||||
self.factor = 1.0
|
self.factor = 1.0
|
||||||
|
self.geom_name = geom_name
|
||||||
|
|
||||||
self.label = l = QLabel()
|
self.label = l = QLabel()
|
||||||
l.setBackgroundRole(QPalette.Base);
|
l.setBackgroundRole(QPalette.Base)
|
||||||
l.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
|
l.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
|
||||||
l.setScaledContents(True)
|
l.setScaledContents(True)
|
||||||
|
|
||||||
@ -88,21 +89,27 @@ class ImageView(QDialog):
|
|||||||
self.label.setPixmap(pm)
|
self.label.setPixmap(pm)
|
||||||
self.label.adjustSize()
|
self.label.adjustSize()
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self, use_exec=False):
|
||||||
geom = self.avail_geom
|
geom = self.avail_geom
|
||||||
self.label.setPixmap(self.current_img)
|
self.label.setPixmap(self.current_img)
|
||||||
self.label.adjustSize()
|
self.label.adjustSize()
|
||||||
self.resize(QSize(int(geom.width()/2.5), geom.height()-50))
|
self.resize(QSize(int(geom.width()/2.5), geom.height()-50))
|
||||||
geom = gprefs.get('viewer_image_popup_geometry', None)
|
geom = gprefs.get(self.geom_name, None)
|
||||||
if geom is not None:
|
if geom is not None:
|
||||||
self.restoreGeometry(geom)
|
self.restoreGeometry(geom)
|
||||||
self.current_image_name = unicode(self.current_url.toString()).rpartition('/')[-1]
|
try:
|
||||||
|
self.current_image_name = unicode(self.current_url.toString()).rpartition('/')[-1]
|
||||||
|
except AttributeError:
|
||||||
|
self.current_image_name = self.current_url
|
||||||
title = _('View Image: %s')%self.current_image_name
|
title = _('View Image: %s')%self.current_image_name
|
||||||
self.setWindowTitle(title)
|
self.setWindowTitle(title)
|
||||||
self.show()
|
if use_exec:
|
||||||
|
self.exec_()
|
||||||
|
else:
|
||||||
|
self.show()
|
||||||
|
|
||||||
def done(self, e):
|
def done(self, e):
|
||||||
gprefs['viewer_image_popup_geometry'] = bytearray(self.saveGeometry())
|
gprefs[self.geom_name] = bytearray(self.saveGeometry())
|
||||||
return QDialog.done(self, e)
|
return QDialog.done(self, e)
|
||||||
|
|
||||||
def wheelEvent(self, event):
|
def wheelEvent(self, event):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user