mirror of
https://github.com/fergalmoran/picard.git
synced 2026-01-07 17:14:55 +00:00
Use CAA data when embedding images into files
This includes both the image type (for vorbis, id3 and asf files) as well as the comments (as description for vorbis, id3 and asf files). Additionally, converts the `images` attribute of picard.metadata.Metadata to a list of dicts instead of tuples for easier access.
This commit is contained in:
@@ -89,8 +89,10 @@ AMAZON_SERVER = {
|
||||
AMAZON_IMAGE_PATH = '/images/P/%s.%s.%sZZZZZZZ.jpg'
|
||||
AMAZON_ASIN_URL_REGEX = re.compile(r'^http://(?:www.)?(.*?)(?:\:[0-9]+)?/.*/([0-9B][0-9A-Z]{9})(?:[^0-9A-Z]|$)')
|
||||
|
||||
def _coverart_downloaded(album, metadata, release, try_list, imagetype, data, http, error):
|
||||
def _coverart_downloaded(album, metadata, release, try_list, imagedata, data, http, error):
|
||||
album._requests -= 1
|
||||
imagetype = imagedata["type"]
|
||||
|
||||
if error or len(data) < 1000:
|
||||
if error:
|
||||
album.log.error(str(http.errorString()))
|
||||
@@ -101,9 +103,11 @@ def _coverart_downloaded(album, metadata, release, try_list, imagetype, data, ht
|
||||
filename = None
|
||||
if imagetype != 'front' and QObject.config.setting["caa_image_type_as_filename"]:
|
||||
filename = imagetype
|
||||
metadata.add_image(mime, data, filename)
|
||||
metadata.add_image(mime, data, filename, imagedata["description"],
|
||||
imagetype)
|
||||
for track in album._new_tracks:
|
||||
track.metadata.add_image(mime, data, filename)
|
||||
track.metadata.add_image(mime, data, filename,
|
||||
imagedata["description"], imagetype)
|
||||
|
||||
# If the image already was a front image, there might still be some
|
||||
# other front images in the try_list - remove them.
|
||||
@@ -157,7 +161,7 @@ def _caa_append_image_to_trylist(try_list, imagedata):
|
||||
url = QUrl(imagedata["image"])
|
||||
else:
|
||||
url = QUrl(imagedata["thumbnails"][thumbsize])
|
||||
_try_list_append_image_url(try_list, url, imagedata["types"][0])
|
||||
_try_list_append_image_url(try_list, url, imagedata["types"][0], imagedata["comment"])
|
||||
|
||||
def coverart(album, metadata, release, try_list=None):
|
||||
""" Gets all cover art URLs from the metadata and then attempts to
|
||||
@@ -210,7 +214,7 @@ def _walk_try_list(album, metadata, release, try_list):
|
||||
album.tagger.xmlws.download(
|
||||
url['host'], url['port'], url['path'],
|
||||
partial(_coverart_downloaded, album, metadata, release,
|
||||
try_list, url['type']),
|
||||
try_list, url),
|
||||
priority=True, important=True)
|
||||
else:
|
||||
album._finalize_loading(None)
|
||||
@@ -252,7 +256,7 @@ def _process_asin_relation(try_list, relation):
|
||||
})
|
||||
|
||||
|
||||
def _try_list_append_image_url(try_list, parsedUrl, imagetype="front"):
|
||||
def _try_list_append_image_url(try_list, parsedUrl, imagetype="front", description=""):
|
||||
QObject.log.debug("Adding %s image %s", imagetype, parsedUrl)
|
||||
path = str(parsedUrl.encodedPath())
|
||||
if parsedUrl.hasQuery():
|
||||
@@ -261,6 +265,7 @@ def _try_list_append_image_url(try_list, parsedUrl, imagetype="front"):
|
||||
'host': str(parsedUrl.host()),
|
||||
'port': parsedUrl.port(80),
|
||||
'path': str(path),
|
||||
'type': imagetype.lower()
|
||||
'type': imagetype.lower(),
|
||||
'description': description,
|
||||
})
|
||||
|
||||
|
||||
@@ -329,7 +329,10 @@ class File(QtCore.QObject, Item):
|
||||
settings["cover_image_filename"], dirname, metadata, settings)
|
||||
overwrite = settings["save_images_overwrite"]
|
||||
counters = defaultdict(lambda: 0)
|
||||
for mime, data, filename in metadata.images:
|
||||
for image in metadata.images:
|
||||
filename = image["filename"]
|
||||
data = image["data"]
|
||||
mime = image["mime"]
|
||||
if filename is None:
|
||||
filename = default_filename
|
||||
else:
|
||||
|
||||
@@ -141,12 +141,13 @@ class APEv2File(File):
|
||||
for name, values in temp.items():
|
||||
tags[str(name)] = values
|
||||
if settings['save_images_to_tags']:
|
||||
for mime, data, _fname in metadata.images:
|
||||
cover_filename = 'Cover Art (Front)'
|
||||
cover_filename += mimetype.get_extension(mime, '.jpg')
|
||||
tags['Cover Art (Front)'] = cover_filename + '\0' + data
|
||||
break # can't save more than one item with the same name
|
||||
# (mp3tags does this, but it's against the specs)
|
||||
for image in metadata.images:
|
||||
if "front" == image["type"]:
|
||||
cover_filename = 'Cover Art (Front)'
|
||||
cover_filename += mimetype.get_extension(image["mime"], '.jpg')
|
||||
tags['Cover Art (Front)'] = cover_filename + '\0' + image["data"]
|
||||
break # can't save more than one item with the same name
|
||||
# (mp3tags does this, but it's against the specs)
|
||||
tags.save(encode_filename(filename))
|
||||
|
||||
class MusepackFile(APEv2File):
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
from picard.file import File
|
||||
from picard.formats.id3 import ID3_IMAGE_TYPE_MAP, ID3_REVERSE_IMAGE_TYPE_MAP
|
||||
from picard.util import encode_filename
|
||||
from picard.metadata import Metadata
|
||||
from mutagen.asf import ASF, ASFByteArrayAttribute
|
||||
@@ -47,7 +48,7 @@ def unpack_image(data):
|
||||
pos += 2
|
||||
pos += 2
|
||||
image_data = data[pos:pos+size]
|
||||
return (mime.decode("utf-16-le"), image_data, type)
|
||||
return (mime.decode("utf-16-le"), image_data, type, description.decode("utf-16-le"))
|
||||
|
||||
def pack_image(mime, data, type=3, description=""):
|
||||
"""
|
||||
@@ -128,9 +129,10 @@ class ASFFile(File):
|
||||
for name, values in file.tags.items():
|
||||
if name == 'WM/Picture':
|
||||
for image in values:
|
||||
(mime, data, type) = unpack_image(image.value)
|
||||
if type == 3: # Only cover images
|
||||
metadata.add_image(mime, data)
|
||||
(mime, data, type, description) = unpack_image(image.value)
|
||||
imagetype = ID3_REVERSE_IMAGE_TYPE_MAP.get(type, "other")
|
||||
metadata.add_image(mime, data, description=description,
|
||||
type_=imagetype)
|
||||
continue
|
||||
elif name not in self.__RTRANS:
|
||||
continue
|
||||
@@ -152,8 +154,12 @@ class ASFFile(File):
|
||||
file.tags.clear()
|
||||
if settings['save_images_to_tags']:
|
||||
cover = []
|
||||
for mime, data, _fname in metadata.images:
|
||||
tag_data = pack_image(mime, data, 3)
|
||||
for image in metadata.images:
|
||||
if self.config.setting["save_only_front_images_to_tags"] and image["type"] != "front":
|
||||
continue
|
||||
imagetype = ID3_IMAGE_TYPE_MAP.get(image["type"], 0)
|
||||
tag_data = pack_image(image["mime"], image["data"], imagetype,
|
||||
image["description"])
|
||||
cover.append(ASFByteArrayAttribute(tag_data))
|
||||
if cover:
|
||||
file.tags['WM/Picture'] = cover
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
import mutagen.apev2
|
||||
import mutagen.mp3
|
||||
import mutagen.trueaudio
|
||||
from collections import defaultdict
|
||||
from mutagen import id3
|
||||
from picard.metadata import Metadata
|
||||
from picard.file import File
|
||||
@@ -34,8 +35,7 @@ from urlparse import urlparse
|
||||
def patched_EncodedTextSpec_write(self, frame, value):
|
||||
try:
|
||||
enc, term = self._encodings[frame.encoding]
|
||||
except AttributeError:
|
||||
enc, term = self.encodings[frame.encoding]
|
||||
except AttributeError: enc, term = self.encodings[frame.encoding]
|
||||
return value.encode(enc, 'ignore') + term
|
||||
id3.EncodedTextSpec.write = patched_EncodedTextSpec_write
|
||||
|
||||
@@ -61,6 +61,20 @@ id3.MultiSpec.write = patched_MultiSpec_write
|
||||
id3.TCMP = compatid3.TCMP
|
||||
id3.TSO2 = compatid3.TSO2
|
||||
|
||||
ID3_IMAGE_TYPE_MAP = {
|
||||
"other": 0,
|
||||
"obi": 0,
|
||||
"tray": 0,
|
||||
"spine": 0,
|
||||
"sticker": 0,
|
||||
"front": 3,
|
||||
"back": 4,
|
||||
"booklet": 5,
|
||||
"medium": 6,
|
||||
"track": 6,
|
||||
}
|
||||
|
||||
ID3_REVERSE_IMAGE_TYPE_MAP = dict([(v,k) for k, v in ID3_IMAGE_TYPE_MAP.iteritems()])
|
||||
|
||||
class ID3File(File):
|
||||
"""Generic ID3-based file."""
|
||||
@@ -200,7 +214,9 @@ class ID3File(File):
|
||||
else:
|
||||
metadata['discnumber'] = value[0]
|
||||
elif frameid == 'APIC':
|
||||
metadata.add_image(frame.mime, frame.data)
|
||||
imagetype = ID3_REVERSE_IMAGE_TYPE_MAP.get(frame.type, "other")
|
||||
metadata.add_image(frame.mime, frame.data,
|
||||
description=frame.desc, type_=imagetype)
|
||||
elif frameid == 'POPM':
|
||||
# Rating in ID3 ranges from 0 to 255, normalize this to the range 0 to 5
|
||||
if frame.email == self.config.setting['rating_user_email']:
|
||||
@@ -247,8 +263,24 @@ class ID3File(File):
|
||||
tags.add(id3.TPOS(encoding=0, text=text))
|
||||
|
||||
if settings['save_images_to_tags']:
|
||||
for mime, data, _fname in metadata.images:
|
||||
tags.add(id3.APIC(encoding=0, mime=mime, type=3, desc='', data=data))
|
||||
# This is necessary because mutagens HashKey for APIC frames only
|
||||
# includes the FrameID (APIC) and description - it's basically
|
||||
# impossible to save two images, even of different types, without
|
||||
# any description.
|
||||
counters = defaultdict(lambda: 0)
|
||||
for image in metadata.images:
|
||||
desc = image["description"]
|
||||
if self.config.setting["save_only_front_images_to_tags"] and image["type"] != "front":
|
||||
continue
|
||||
type_ = ID3_IMAGE_TYPE_MAP.get(image["type"], 0)
|
||||
if counters[desc] > 0:
|
||||
if desc:
|
||||
image["description"] = "%s (%i)" % (desc, counters[desc])
|
||||
else:
|
||||
image["description"] = "(%i)" % counters[desc]
|
||||
counters[desc] += 1
|
||||
tags.add(id3.APIC(encoding=0, mime=image["mime"], type=type_,
|
||||
desc=image["description"], data=image["data"]))
|
||||
|
||||
tmcl = mutagen.id3.TMCL(encoding=encoding, people=[])
|
||||
tipl = mutagen.id3.TIPL(encoding=encoding, people=[])
|
||||
|
||||
@@ -187,11 +187,14 @@ class MP4File(File):
|
||||
|
||||
if settings['save_images_to_tags']:
|
||||
covr = []
|
||||
for mime, data, _fname in metadata.images:
|
||||
for image in metadata.images:
|
||||
if self.config.setting["save_only_front_images_to_tags"] and image["type"] != "front":
|
||||
continue
|
||||
mime = image["mime"]
|
||||
if mime == "image/jpeg":
|
||||
covr.append(MP4Cover(data, MP4Cover.FORMAT_JPEG))
|
||||
covr.append(MP4Cover(image["data"], MP4Cover.FORMAT_JPEG))
|
||||
elif mime == "image/png":
|
||||
covr.append(MP4Cover(data, MP4Cover.FORMAT_PNG))
|
||||
covr.append(MP4Cover(image["data"], MP4Cover.FORMAT_PNG))
|
||||
if covr:
|
||||
file.tags["covr"] = covr
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import mutagen.oggspeex
|
||||
import mutagen.oggtheora
|
||||
import mutagen.oggvorbis
|
||||
from picard.file import File
|
||||
from picard.formats.id3 import ID3_IMAGE_TYPE_MAP, ID3_REVERSE_IMAGE_TYPE_MAP
|
||||
from picard.metadata import Metadata
|
||||
from picard.util import encode_filename, sanitize_date
|
||||
|
||||
@@ -78,12 +79,17 @@ class VCommentFile(File):
|
||||
name = "totaldiscs"
|
||||
elif name == "metadata_block_picture":
|
||||
image = mutagen.flac.Picture(base64.standard_b64decode(value))
|
||||
metadata.add_image(image.mime, image.data)
|
||||
imagetype = ID3_REVERSE_IMAGE_TYPE_MAP.get(image.type, "other")
|
||||
metadata.add_image(image.mime, image.data,
|
||||
description=image.desc,
|
||||
type_=imagetype)
|
||||
continue
|
||||
metadata.add(name, value)
|
||||
if self._File == mutagen.flac.FLAC:
|
||||
for image in file.pictures:
|
||||
metadata.add_image(image.mime, image.data)
|
||||
imagetype = ID3_REVERSE_IMAGE_TYPE_MAP.get(image.type, "other")
|
||||
metadata.add_image(image.mime, image.data,
|
||||
description=image.desc, type_=imagetype)
|
||||
# Read the unofficial COVERART tags, for backward compatibillity only
|
||||
if not "metadata_block_picture" in file.tags:
|
||||
try:
|
||||
@@ -139,16 +145,19 @@ class VCommentFile(File):
|
||||
tags.setdefault(u"DISCTOTAL", []).append(metadata["totaldiscs"])
|
||||
|
||||
if settings['save_images_to_tags']:
|
||||
for mime, data, filename in metadata.images:
|
||||
image = mutagen.flac.Picture()
|
||||
image.type = 3 # Cover image
|
||||
image.data = data
|
||||
image.mime = mime
|
||||
for image in metadata.images:
|
||||
if self.config.setting["save_only_front_images_to_tags"] and image["type"] != "front":
|
||||
continue
|
||||
picture = mutagen.flac.Picture()
|
||||
picture.data = image["data"]
|
||||
picture.mime = image["mime"]
|
||||
picture.desc = image["description"]
|
||||
picture.type = ID3_IMAGE_TYPE_MAP.get(image["type"], 0)
|
||||
if self._File == mutagen.flac.FLAC:
|
||||
file.add_picture(image)
|
||||
file.add_picture(picture)
|
||||
else:
|
||||
tags.setdefault(u"METADATA_BLOCK_PICTURE", []).append(
|
||||
base64.standard_b64encode(image.write()))
|
||||
base64.standard_b64encode(picture.write()))
|
||||
file.tags.update(tags)
|
||||
kwargs = {}
|
||||
if self._File == mutagen.flac.FLAC and settings["remove_id3_from_flac"]:
|
||||
|
||||
@@ -42,8 +42,23 @@ class Metadata(dict):
|
||||
self.images = []
|
||||
self.length = 0
|
||||
|
||||
def add_image(self, mime, data, filename=None):
|
||||
self.images.append((mime, data, filename))
|
||||
def add_image(self, mime, data, filename=None, description="", type_="front"):
|
||||
"""Adds the image ``data`` to this Metadata object.
|
||||
|
||||
Arguments:
|
||||
mime -- The mimetype of the image
|
||||
data -- The image data
|
||||
filename -- The image filename, without an extension
|
||||
description -- A description for the image
|
||||
type_ -- The image type - this should be a lower-cased name from
|
||||
http://musicbrainz.org/doc/Cover_Art/Types
|
||||
"""
|
||||
imagedict = {'mime': mime,
|
||||
'data': data,
|
||||
'filename': filename,
|
||||
'description': description,
|
||||
'type': type_}
|
||||
self.images.append(imagedict)
|
||||
|
||||
def remove_image(self, index):
|
||||
self.images.pop(index)
|
||||
|
||||
@@ -99,7 +99,7 @@ class CoverArtBox(QtGui.QGroupBox):
|
||||
if self.data:
|
||||
if pixmap is None:
|
||||
pixmap = QtGui.QPixmap()
|
||||
pixmap.loadFromData(self.data[1])
|
||||
pixmap.loadFromData(self.data["data"])
|
||||
if not pixmap.isNull():
|
||||
cover = QtGui.QPixmap(self.shadow)
|
||||
pixmap = pixmap.scaled(121, 121, QtCore.Qt.IgnoreAspectRatio, QtCore.Qt.SmoothTransformation)
|
||||
@@ -112,7 +112,13 @@ class CoverArtBox(QtGui.QGroupBox):
|
||||
self.item = item
|
||||
data = None
|
||||
if metadata and metadata.images:
|
||||
data = metadata.images[0]
|
||||
for image in metadata.images:
|
||||
if image["type"] == "front":
|
||||
data = image
|
||||
break
|
||||
else:
|
||||
# There's no front image, choose the first one available
|
||||
data = metadata.images[0]
|
||||
self.__set_data(data)
|
||||
release = None
|
||||
if metadata:
|
||||
|
||||
@@ -69,7 +69,8 @@ class InfoDialog(QtGui.QDialog):
|
||||
text = '<br/>'.join(map(lambda i: '<b>%s</b><br/>%s' % i, info))
|
||||
self.ui.info.setText(text)
|
||||
|
||||
for mime, data, _fname in file.metadata.images:
|
||||
for image in file.metadata.images:
|
||||
data = image["data"]
|
||||
item = QtGui.QListWidgetItem()
|
||||
pixmap = QtGui.QPixmap()
|
||||
pixmap.loadFromData(data)
|
||||
|
||||
@@ -33,6 +33,7 @@ class CoverOptionsPage(OptionsPage):
|
||||
|
||||
options = [
|
||||
BoolOption("setting", "save_images_to_tags", True),
|
||||
BoolOption("setting", "save_only_front_images_to_tags", False),
|
||||
BoolOption("setting", "save_images_to_files", False),
|
||||
TextOption("setting", "cover_image_filename", "cover"),
|
||||
BoolOption("setting", "save_images_overwrite", False),
|
||||
@@ -55,6 +56,7 @@ class CoverOptionsPage(OptionsPage):
|
||||
|
||||
def load(self):
|
||||
self.ui.save_images_to_tags.setChecked(self.config.setting["save_images_to_tags"])
|
||||
self.ui.cb_embed_front_only.setChecked(self.config.setting["save_only_front_images_to_tags"])
|
||||
self.ui.save_images_to_files.setChecked(self.config.setting["save_images_to_files"])
|
||||
self.ui.cover_image_filename.setText(self.config.setting["cover_image_filename"])
|
||||
self.ui.save_images_overwrite.setChecked(self.config.setting["save_images_overwrite"])
|
||||
@@ -75,6 +77,7 @@ class CoverOptionsPage(OptionsPage):
|
||||
|
||||
def save(self):
|
||||
self.config.setting["save_images_to_tags"] = self.ui.save_images_to_tags.isChecked()
|
||||
self.config.setting["save_only_front_images_to_tags"] = self.ui.cb_embed_front_only.isChecked()
|
||||
self.config.setting["save_images_to_files"] = self.ui.save_images_to_files.isChecked()
|
||||
self.config.setting["cover_image_filename"] = unicode(self.ui.cover_image_filename.text())
|
||||
self.config.setting["ca_provider_use_amazon"] =\
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/infodialog.ui'
|
||||
#
|
||||
# Created: Tue May 29 19:44:14 2012
|
||||
# by: PyQt4 UI code generator 4.8.3
|
||||
# Created: Sat Oct 6 19:08:31 2012
|
||||
# by: PyQt4 UI code generator 4.9.4
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
@@ -43,7 +43,7 @@ class Ui_InfoDialog(object):
|
||||
self.artwork_list.setIconSize(QtCore.QSize(170, 170))
|
||||
self.artwork_list.setMovement(QtGui.QListView.Static)
|
||||
self.artwork_list.setFlow(QtGui.QListView.LeftToRight)
|
||||
self.artwork_list.setProperty(_fromUtf8("isWrapping"), False)
|
||||
self.artwork_list.setProperty("isWrapping", False)
|
||||
self.artwork_list.setResizeMode(QtGui.QListView.Fixed)
|
||||
self.artwork_list.setSpacing(10)
|
||||
self.artwork_list.setViewMode(QtGui.QListView.IconMode)
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/options_cover.ui'
|
||||
#
|
||||
# Created: Sun Sep 30 11:21:59 2012
|
||||
# by: PyQt4 UI code generator 4.8.3
|
||||
# Created: Sat Oct 6 19:08:31 2012
|
||||
# by: PyQt4 UI code generator 4.9.4
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
@@ -17,7 +17,7 @@ except AttributeError:
|
||||
class Ui_CoverOptionsPage(object):
|
||||
def setupUi(self, CoverOptionsPage):
|
||||
CoverOptionsPage.setObjectName(_fromUtf8("CoverOptionsPage"))
|
||||
CoverOptionsPage.resize(524, 502)
|
||||
CoverOptionsPage.resize(525, 526)
|
||||
self.verticalLayout = QtGui.QVBoxLayout(CoverOptionsPage)
|
||||
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
|
||||
self.rename_files = QtGui.QGroupBox(CoverOptionsPage)
|
||||
@@ -29,6 +29,9 @@ class Ui_CoverOptionsPage(object):
|
||||
self.save_images_to_tags = QtGui.QCheckBox(self.rename_files)
|
||||
self.save_images_to_tags.setObjectName(_fromUtf8("save_images_to_tags"))
|
||||
self.vboxlayout.addWidget(self.save_images_to_tags)
|
||||
self.cb_embed_front_only = QtGui.QCheckBox(self.rename_files)
|
||||
self.cb_embed_front_only.setObjectName(_fromUtf8("cb_embed_front_only"))
|
||||
self.vboxlayout.addWidget(self.cb_embed_front_only)
|
||||
self.save_images_to_files = QtGui.QCheckBox(self.rename_files)
|
||||
self.save_images_to_files.setObjectName(_fromUtf8("save_images_to_files"))
|
||||
self.vboxlayout.addWidget(self.save_images_to_files)
|
||||
@@ -111,6 +114,7 @@ class Ui_CoverOptionsPage(object):
|
||||
self.verticalLayout.addItem(spacerItem1)
|
||||
|
||||
self.retranslateUi(CoverOptionsPage)
|
||||
QtCore.QObject.connect(self.save_images_to_tags, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.cb_embed_front_only.setEnabled)
|
||||
QtCore.QMetaObject.connectSlotsByName(CoverOptionsPage)
|
||||
CoverOptionsPage.setTabOrder(self.save_images_to_tags, self.save_images_to_files)
|
||||
CoverOptionsPage.setTabOrder(self.save_images_to_files, self.cover_image_filename)
|
||||
@@ -118,6 +122,7 @@ class Ui_CoverOptionsPage(object):
|
||||
def retranslateUi(self, CoverOptionsPage):
|
||||
self.rename_files.setTitle(_("Location"))
|
||||
self.save_images_to_tags.setText(_("Embed cover images into tags"))
|
||||
self.cb_embed_front_only.setText(_("Embed only front images"))
|
||||
self.save_images_to_files.setText(_("Save cover images as separate files"))
|
||||
self.label_3.setText(_("Use the following file name for images:"))
|
||||
self.save_images_overwrite.setText(_("Overwrite the file if it already exists"))
|
||||
|
||||
906
po/picard.pot
906
po/picard.pot
File diff suppressed because it is too large
Load Diff
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>524</width>
|
||||
<height>502</height>
|
||||
<width>525</width>
|
||||
<height>526</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
@@ -30,6 +30,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cb_embed_front_only">
|
||||
<property name="text">
|
||||
<string>Embed only front images</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="save_images_to_files">
|
||||
<property name="text">
|
||||
@@ -220,5 +227,22 @@
|
||||
<tabstop>cover_image_filename</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>save_images_to_tags</sender>
|
||||
<signal>clicked(bool)</signal>
|
||||
<receiver>cb_embed_front_only</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>266</x>
|
||||
<y>44</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>266</x>
|
||||
<y>67</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
|
||||
Reference in New Issue
Block a user