diff --git a/src/calibre/gui2/metadata/single_download.py b/src/calibre/gui2/metadata/single_download.py
index 456edde638..6e1a00e862 100644
--- a/src/calibre/gui2/metadata/single_download.py
+++ b/src/calibre/gui2/metadata/single_download.py
@@ -637,7 +637,7 @@ class CoversModel(QAbstractListModel): # {{{
current_cover = QPixmap(I('default_cover.png'))
current_cover.setDevicePixelRatio(QApplication.instance().devicePixelRatio())
- self.blank = QPixmap(I('blank.png')).scaled(*CoverDelegate.ICON_SIZE)
+ self.blank = QIcon(I('blank.png')).pixmap(*CoverDelegate.ICON_SIZE)
self.cc = current_cover
self.reset_covers(do_reset=False)
diff --git a/src/calibre/gui2/proceed.py b/src/calibre/gui2/proceed.py
index 00e7a1f782..6163fe0ae7 100644
--- a/src/calibre/gui2/proceed.py
+++ b/src/calibre/gui2/proceed.py
@@ -10,9 +10,9 @@ __docformat__ = 'restructuredtext en'
from collections import namedtuple
from PyQt5.Qt import (
- QWidget, Qt, QLabel, QVBoxLayout, QPixmap, QDialogButtonBox, QApplication, QTimer,
+ QWidget, Qt, QLabel, QVBoxLayout, QDialogButtonBox, QApplication, QTimer, QPixmap,
QSize, pyqtSignal, QIcon, QPlainTextEdit, QCheckBox, QPainter, QHBoxLayout, QFontMetrics,
- QPainterPath, QRectF, pyqtProperty, QPropertyAnimation, QEasingCurve, QSizePolicy)
+ QPainterPath, QRectF, pyqtProperty, QPropertyAnimation, QEasingCurve, QSizePolicy, QImage)
from calibre.constants import __version__
from calibre.gui2.dialogs.message_box import ViewLog
@@ -58,7 +58,7 @@ class Icon(QWidget):
elif icon is None:
self.icon = self.default_icon
else:
- self.icon = QPixmap(I(icon)).scaled(self.sizeHint(), transformMode=Qt.SmoothTransformation)
+ self.icon = QIcon(I(icon)).pixmap(self.sizeHint())
self.update()
def sizeHint(self):
@@ -263,9 +263,11 @@ class ProceedQuestion(QWidget):
if self.rendered_pixmap is not None:
return
- p = QPixmap(self.size())
+ dpr = getattr(self, 'devicePixelRatioF', self.devicePixelRatio)()
+ p = QImage(dpr * self.size(), QImage.Format_ARGB32_Premultiplied)
+ p.setDevicePixelRatio(dpr)
self.render(p)
- self.rendered_pixmap = p
+ self.rendered_pixmap = QPixmap.fromImage(p)
self.original_visibility = v = []
for child in self.findChildren(QWidget):
if child.isVisible():
@@ -412,4 +414,3 @@ def main():
if __name__ == '__main__':
main()
-
diff --git a/src/calibre/gui2/store/search/download_thread.py b/src/calibre/gui2/store/search/download_thread.py
index 90e760af4c..a4dfba7fdc 100644
--- a/src/calibre/gui2/store/search/download_thread.py
+++ b/src/calibre/gui2/store/search/download_thread.py
@@ -166,7 +166,7 @@ class CoverThread(Thread):
else:
with closing(self.br.open(result.cover_url, timeout=timeout)) as f:
result.cover_data = f.read()
- result.cover_data = scale_image(result.cover_data, 64, 64)[2]
+ result.cover_data = scale_image(result.cover_data, 256, 256)[2]
callback()
self.tasks.task_done()
except:
diff --git a/src/calibre/gui2/store/search/models.py b/src/calibre/gui2/store/search/models.py
index 7088452292..83ebb976e2 100644
--- a/src/calibre/gui2/store/search/models.py
+++ b/src/calibre/gui2/store/search/models.py
@@ -10,7 +10,7 @@ import re, string
from operator import attrgetter
from PyQt5.Qt import (Qt, QAbstractItemModel, QPixmap, QModelIndex, QSize,
- pyqtSignal)
+ pyqtSignal, QIcon, QApplication)
from calibre import force_unicode
from calibre.gui2 import FunctionDispatcher
@@ -39,20 +39,16 @@ class Matches(QAbstractItemModel):
HEADERS = [_('Cover'), _('Title'), _('Price'), _('DRM'), _('Store'), _('Download'), _('Affiliate')]
HTML_COLS = (1, 4)
+ IMG_COLS = (0, 3, 5, 6)
def __init__(self, cover_thread_count=2, detail_thread_count=4):
QAbstractItemModel.__init__(self)
- self.DRM_LOCKED_ICON = QPixmap(I('drm-locked.png')).scaledToHeight(64,
- Qt.SmoothTransformation)
- self.DRM_UNLOCKED_ICON = QPixmap(I('drm-unlocked.png')).scaledToHeight(64,
- Qt.SmoothTransformation)
- self.DRM_UNKNOWN_ICON = QPixmap(I('dialog_question.png')).scaledToHeight(64,
- Qt.SmoothTransformation)
- self.DONATE_ICON = QPixmap(I('donate.png')).scaledToHeight(16,
- Qt.SmoothTransformation)
- self.DOWNLOAD_ICON = QPixmap(I('arrow-down.png')).scaledToHeight(16,
- Qt.SmoothTransformation)
+ self.DRM_LOCKED_ICON = QIcon(I('drm-locked.png'))
+ self.DRM_UNLOCKED_ICON = QIcon(I('drm-unlocked.png'))
+ self.DRM_UNKNOWN_ICON = QIcon(I('dialog_question.png'))
+ self.DONATE_ICON = QIcon(I('donate.png'))
+ self.DOWNLOAD_ICON = QIcon(I('arrow-down.png'))
# All matches. Used to determine the order to display
# self.matches because the SearchFilter returns
@@ -206,13 +202,14 @@ class Matches(QAbstractItemModel):
elif col == 2:
return (result.price)
elif col == 4:
- return ('%s
%s' % (result.store_name, result.formats))
+ return ('%s
%s' % (result.store_name, result.formats))
return None
elif role == Qt.DecorationRole:
if col == 0 and result.cover_data:
p = QPixmap()
p.loadFromData(result.cover_data)
- return (p)
+ p.setDevicePixelRatio(QApplication.instance().devicePixelRatio())
+ return p
if col == 3:
if result.drm == SearchResult.DRM_LOCKED:
return (self.DRM_LOCKED_ICON)
diff --git a/src/calibre/gui2/store/search/results_view.py b/src/calibre/gui2/store/search/results_view.py
index d03a313310..6a20d894f5 100644
--- a/src/calibre/gui2/store/search/results_view.py
+++ b/src/calibre/gui2/store/search/results_view.py
@@ -8,11 +8,34 @@ __docformat__ = 'restructuredtext en'
from functools import partial
-from PyQt5.Qt import (pyqtSignal, QMenu, QTreeView)
+from PyQt5.Qt import (
+ pyqtSignal, QMenu, QTreeView, QStyledItemDelegate, QModelIndex, Qt, QIcon)
+from calibre import fit_image
from calibre.gui2.metadata.single_download import RichTextDelegate
from calibre.gui2.store.search.models import Matches
+class ImageDelegate(QStyledItemDelegate):
+
+ def paint(self, painter, option, index):
+ QStyledItemDelegate.paint(self, painter, option, QModelIndex())
+ img = index.data(Qt.DecorationRole)
+ if img:
+ h = option.rect.height() - 4
+ w = option.rect.width()
+ if isinstance(img, QIcon):
+ img = img.pixmap(h - 4, h - 4)
+ dpr = img.devicePixelRatio()
+ else:
+ dpr = img.devicePixelRatio()
+ scaled, nw, nh = fit_image(img.width(), img.height(), w, h)
+ if scaled:
+ img = img.scaled(nw*dpr, nh*dpr, Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
+ iw, ih = int(img.width()/dpr), int(img.height()/dpr)
+ dx, dy = (option.rect.width() - iw) // 2, (option.rect.height() - ih) // 2
+ painter.drawPixmap(option.rect.adjusted(dx, dy, -dx, -dy), img)
+
+
class ResultsView(QTreeView):
download_requested = pyqtSignal(object)
@@ -25,9 +48,12 @@ class ResultsView(QTreeView):
self.setModel(self._model)
self.rt_delegate = RichTextDelegate(self)
+ self.img_delegate = ImageDelegate(self)
for i in self._model.HTML_COLS:
self.setItemDelegateForColumn(i, self.rt_delegate)
+ for i in self._model.IMG_COLS:
+ self.setItemDelegateForColumn(i, self.img_delegate)
def contextMenuEvent(self, event):
index = self.indexAt(event.pos())
diff --git a/src/calibre/gui2/update.py b/src/calibre/gui2/update.py
index 81ea15776b..04d2319b32 100644
--- a/src/calibre/gui2/update.py
+++ b/src/calibre/gui2/update.py
@@ -6,7 +6,7 @@ from future_builtins import map
from threading import Thread, Event
from PyQt5.Qt import (QObject, pyqtSignal, Qt, QUrl, QDialog, QGridLayout,
- QLabel, QCheckBox, QDialogButtonBox, QIcon, QPixmap)
+ QLabel, QCheckBox, QDialogButtonBox, QIcon)
from calibre.constants import (__appname__, __version__, iswindows, isosx,
isportable, is64bit, numeric_version)
@@ -105,8 +105,7 @@ class UpdateNotification(QDialog):
self.setLayout(self.l)
self.logo = QLabel()
self.logo.setMaximumWidth(110)
- self.logo.setPixmap(QPixmap(I('lt.png')).scaled(100, 100,
- Qt.IgnoreAspectRatio, Qt.SmoothTransformation))
+ self.logo.setPixmap(QIcon(I('lt.png')).pixmap(100, 100))
ver = calibre_version
if ver.endswith('.0'):
ver = ver[:-2]