Avoid roundtripping image data when dragging and dropping image files

Fixes #1862440 [Cover disappear when dragging new cover into editor and dropping it on the cover space](https://bugs.launchpad.net/calibre/+bug/1862440)
This commit is contained in:
Kovid Goyal 2020-02-12 21:02:20 +05:30
parent a7a88de0f8
commit 9c6444e3b8
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 30 additions and 17 deletions

View File

@ -198,14 +198,7 @@ def dnd_has_extension(md, extensions, allow_all_extensions=False):
return bool(exts.intersection(frozenset(extensions)))
def dnd_get_image(md, image_exts=None):
'''
Get the image in the QMimeData object md.
:return: None, None if no image is found
QPixmap, None if an image is found, the pixmap is guaranteed not null
url, filename if a URL that points to an image is found
'''
def dnd_get_local_image_and_pixmap(md, image_exts=None):
if md.hasImage():
for x in md.formats():
x = unicode_type(x)
@ -214,14 +207,13 @@ def dnd_get_image(md, image_exts=None):
pmap = QPixmap()
pmap.loadFromData(cdata)
if not pmap.isNull():
return pmap, None
break
return pmap, cdata
if md.hasFormat('application/octet-stream'):
cdata = bytes(md.data('application/octet-stream'))
pmap = QPixmap()
pmap.loadFromData(cdata)
if not pmap.isNull():
return pmap, None
return pmap, cdata
if image_exts is None:
image_exts = image_extensions()
@ -229,23 +221,40 @@ def dnd_get_image(md, image_exts=None):
# No image, look for an URL pointing to an image
urls = urls_from_md(md)
paths = [path_from_qurl(u) for u in urls]
# First look for a local file
# Look for a local file
images = [xi for xi in paths if
posixpath.splitext(unquote(xi))[1][1:].lower() in
image_exts]
images = [xi for xi in images if os.path.exists(xi)]
p = QPixmap()
for path in images:
try:
with open(path, 'rb') as f:
p.loadFromData(f.read())
cdata = f.read()
except Exception:
continue
p = QPixmap()
p.loadFromData(cdata)
if not p.isNull():
return p, None
return p, cdata
# No local images, look for remote ones
return None, None
def dnd_get_image(md, image_exts=None):
'''
Get the image in the QMimeData object md.
:return: None, None if no image is found
QPixmap, None if an image is found, the pixmap is guaranteed not null
url, filename if a URL that points to an image is found
'''
if image_exts is None:
image_exts = image_extensions()
pmap, data = dnd_get_local_image_and_pixmap(md, image_exts)
if pmap is not None:
return pmap, None
# Look for a remote image
urls = urls_from_md(md)
# First, see if this is from Firefox
rurl, fname = get_firefox_rurl(md, image_exts)

View File

@ -23,7 +23,7 @@ from calibre.ebooks import BOOK_EXTENSIONS
from calibre.utils.config import prefs, XMLConfig
from calibre.gui2.progress_indicator import ProgressIndicator as _ProgressIndicator
from calibre.gui2.dnd import (dnd_has_image, dnd_get_image, dnd_get_files,
image_extensions, dnd_has_extension, DownloadDialog)
image_extensions, dnd_has_extension, dnd_get_local_image_and_pixmap, DownloadDialog)
from calibre.utils.localization import localize_user_manual_link
from polyglot.builtins import native_string_type, unicode_type, range
@ -238,6 +238,10 @@ class ImageDropMixin(object): # {{{
def dropEvent(self, event):
event.setDropAction(Qt.CopyAction)
md = event.mimeData()
pmap, data = dnd_get_local_image_and_pixmap(md)
if pmap is not None:
self.handle_image_drop(pmap, data)
return
x, y = dnd_get_image(md)
if x is not None: