Allow reading more image formats as covers (All images will be converted to JPEG when stored). Fixes #1619993 [Request: Support for dragging TIFF files into Cover area](https://bugs.launchpad.net/calibre/+bug/1619993)

This commit is contained in:
Kovid Goyal 2016-09-04 08:29:20 +05:30
parent 72d735b41d
commit 5088a023c7
8 changed files with 32 additions and 22 deletions

View File

@ -750,9 +750,11 @@ else:
ans = ans[0]
return ans
def choose_images(window, name, title, select_only_single_file=True,
formats=('png', 'gif', 'jpg', 'jpeg', 'svg')):
def choose_images(window, name, title, select_only_single_file=True, formats=None):
mode = QFileDialog.ExistingFile if select_only_single_file else QFileDialog.ExistingFiles
if formats is None:
from calibre.gui2.dnd import image_extensions
formats = image_extensions()
fd = FileDialog(title=title, name=name,
filters=[(_('Images'), list(formats))],
parent=window, add_all_files_filter=False, mode=mode,

View File

@ -17,7 +17,6 @@ from calibre.gui2 import (error_dialog, choose_files, choose_dir,
from calibre.gui2.dialogs.add_empty_book import AddEmptyBookDialog
from calibre.gui2.dialogs.confirm_delete import confirm
from calibre.gui2.dialogs.progress import ProgressDialog
from calibre.gui2.widgets import IMAGE_EXTENSIONS
from calibre.ebooks import BOOK_EXTENSIONS
from calibre.utils.filenames import ascii_filename
from calibre.utils.icu import sort_key
@ -359,11 +358,12 @@ class AddAction(InterfaceAction):
return
cid = db.id(current_idx.row()) if cid is None else cid
formats = []
from calibre.gui2.dnd import image_extensions
for path in paths:
ext = os.path.splitext(path)[1].lower()
if ext:
ext = ext[1:]
if ext in IMAGE_EXTENSIONS:
if ext in image_extensions():
pmap = QPixmap()
pmap.load(path)
if not pmap.isNull():

View File

@ -17,7 +17,7 @@ from PyQt5.QtWebKitWidgets import QWebView
from calibre import fit_image
from calibre.gui2.dnd import (dnd_has_image, dnd_get_image, dnd_get_files,
IMAGE_EXTENSIONS, dnd_has_extension)
dnd_has_extension, image_extensions)
from calibre.ebooks import BOOK_EXTENSIONS
from calibre.ebooks.metadata.book.base import (field_metadata, Metadata)
from calibre.ebooks.metadata.book.render import mi_to_html
@ -639,11 +639,10 @@ class BookDetails(QWidget): # {{{
open_fmt_with = pyqtSignal(int, object, object)
# Drag 'n drop {{{
DROPABBLE_EXTENSIONS = IMAGE_EXTENSIONS+BOOK_EXTENSIONS
def dragEnterEvent(self, event):
md = event.mimeData()
if dnd_has_extension(md, self.DROPABBLE_EXTENSIONS, allow_all_extensions=True) or \
if dnd_has_extension(md, image_extensions() + BOOK_EXTENSIONS, allow_all_extensions=True) or \
dnd_has_image(md):
event.acceptProposedAction()

View File

@ -13,7 +13,7 @@ from threading import Thread
from Queue import Queue, Empty
from PyQt5.Qt import QPixmap, Qt, QDialog, QLabel, QVBoxLayout, \
QDialogButtonBox, QProgressBar, QTimer, QUrl
QDialogButtonBox, QProgressBar, QTimer, QUrl, QImageReader
from calibre.constants import DEBUG, iswindows
from calibre.ptempfile import PersistentTemporaryFile
@ -21,6 +21,12 @@ from calibre import browser, as_unicode, prints
from calibre.gui2 import error_dialog
from calibre.utils.imghdr import what
def image_extensions():
if not hasattr(image_extensions, 'ans'):
image_extensions.ans = [bytes(x).decode('utf-8') for x in QImageReader.supportedImageFormats()]
return image_extensions.ans
# This is present for compatibility with old plugins, do not use
IMAGE_EXTENSIONS = ['jpg', 'jpeg', 'gif', 'png', 'bmp']
class Worker(Thread): # {{{
@ -121,7 +127,7 @@ class DownloadDialog(QDialog): # {{{
def dnd_has_image(md):
# Chromium puts image data into application/octet-stream
return md.hasImage() or md.hasFormat('application/octet-stream') and what(None, bytes(md.data('application/octet-stream'))) in IMAGE_EXTENSIONS
return md.hasImage() or md.hasFormat('application/octet-stream') and what(None, bytes(md.data('application/octet-stream'))) in image_extensions()
def data_as_string(f, md):
raw = bytes(md.data(f))
@ -181,13 +187,12 @@ def dnd_has_extension(md, extensions, allow_all_extensions=False):
return bool(exts)
return bool(exts.intersection(frozenset(extensions)))
def dnd_get_image(md, image_exts=IMAGE_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
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 md.hasImage():
@ -207,6 +212,9 @@ def dnd_get_image(md, image_exts=IMAGE_EXTENSIONS):
if not pmap.isNull():
return pmap, None
if image_exts is None:
image_exts = image_extensions()
# No image, look for an URL pointing to an image
urls = urls_from_md(md)
paths = [path_from_qurl(u) for u in urls]

View File

@ -1071,8 +1071,7 @@ class Cover(ImageView): # {{{
def select_cover(self, *args):
files = choose_images(
self, 'change cover dialog', _('Choose cover for ') + self.dialog.title.current_val,
formats=('png', 'gif', 'jpg', 'jpeg'))
self, 'change cover dialog', _('Choose cover for ') + self.dialog.title.current_val)
if not files:
return
_file = files[0]

View File

@ -18,7 +18,7 @@ from PyQt5.Qt import (
from calibre import fit_image
from calibre.gui2 import error_dialog, pixmap_to_data
from calibre.gui2.dnd import (
IMAGE_EXTENSIONS, dnd_has_extension, dnd_has_image, dnd_get_image, DownloadDialog)
image_extensions, dnd_has_extension, dnd_has_image, dnd_get_image, DownloadDialog)
from calibre.gui2.tweak_book import capitalize
from calibre.utils.imghdr import identify
from calibre.utils.img import (
@ -224,11 +224,10 @@ class Canvas(QWidget):
return self.current_image is not self.original_image
# Drag 'n drop {{{
DROPABBLE_EXTENSIONS = IMAGE_EXTENSIONS
def dragEnterEvent(self, event):
md = event.mimeData()
if dnd_has_extension(md, self.DROPABBLE_EXTENSIONS) or dnd_has_image(md):
if dnd_has_extension(md, image_extensions()) or dnd_has_image(md):
event.acceptProposedAction()
def dropEvent(self, event):

View File

@ -20,7 +20,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, DownloadDialog)
from calibre.utils.localization import localize_user_manual_link
history = XMLConfig('history')
@ -215,14 +215,15 @@ class ImageDropMixin(object): # {{{
Adds support for dropping images onto widgets and a context menu for
copy/pasting images.
'''
DROPABBLE_EXTENSIONS = IMAGE_EXTENSIONS
DROPABBLE_EXTENSIONS = None
def __init__(self):
self.setAcceptDrops(True)
def dragEnterEvent(self, event):
md = event.mimeData()
if dnd_has_extension(md, self.DROPABBLE_EXTENSIONS) or \
exts = self.DROPABBLE_EXTENSIONS or image_extensions()
if dnd_has_extension(md, exts) or \
dnd_has_image(md):
event.acceptProposedAction()

View File

@ -225,8 +225,10 @@ def choose_files(window, name, title,
return ans
return None
def choose_images(window, name, title, select_only_single_file=True,
formats=('png', 'gif', 'jpg', 'jpeg', 'svg')):
def choose_images(window, name, title, select_only_single_file=True, formats=None):
if formats is None:
from calibre.gui2.dnd import image_extensions
formats = image_extensions()
file_types = [(_('Images'), list(formats))]
return choose_files(window, name, title, select_only_single_file=select_only_single_file, filters=file_types)