Fixed many errors in save, copy, clear. Added changes made by Nick Hall-- using libmetadata.
svn: r17915
This commit is contained in:
parent
a2b617201d
commit
af2cf6c331
@ -58,11 +58,13 @@ from DateHandler import parser as _dp
|
|||||||
|
|
||||||
from gen.plug import Gramplet
|
from gen.plug import Gramplet
|
||||||
|
|
||||||
|
from libmetadata import MetadataView, format_datetime
|
||||||
from gui.widgets import ValidatableMaskedEntry
|
from gui.widgets import ValidatableMaskedEntry
|
||||||
from Errors import ValidationError
|
from Errors import ValidationError
|
||||||
from QuestionDialog import WarningDialog, QuestionDialog, OptionDialog
|
from QuestionDialog import WarningDialog, QuestionDialog, OptionDialog
|
||||||
|
|
||||||
import gen.lib
|
from gen.lib import Date
|
||||||
|
|
||||||
import gen.mime
|
import gen.mime
|
||||||
import Utils
|
import Utils
|
||||||
from PlaceUtils import conv_lat_lon
|
from PlaceUtils import conv_lat_lon
|
||||||
@ -80,38 +82,16 @@ else:
|
|||||||
# version_info attribute does not exist prior to v0.2.0
|
# version_info attribute does not exist prior to v0.2.0
|
||||||
OLD_API = True
|
OLD_API = True
|
||||||
|
|
||||||
|
# define the Exiv2 command...
|
||||||
|
system_platform = os.sys.platform
|
||||||
|
if system_platform == "win32":
|
||||||
|
EXIV2_FOUND = "exiv2.exe" if Utils.search_for("exiv2.exe") else False
|
||||||
|
else:
|
||||||
|
EXIV2_FOUND = "exiv2" if Utils.search_for("exiv2") else False
|
||||||
|
|
||||||
#------------------------------------------------
|
#------------------------------------------------
|
||||||
# support functions
|
# support functions
|
||||||
#------------------------------------------------
|
#------------------------------------------------
|
||||||
def _format_datetime(tag_value):
|
|
||||||
"""
|
|
||||||
Convert a python datetime object into a string for display, using the
|
|
||||||
standard Gramps date format.
|
|
||||||
"""
|
|
||||||
if type(tag_value) is not datetime.datetime:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
date_part = gen.lib.date.Date()
|
|
||||||
date_part.set_yr_mon_day(tag_value.year, tag_value.month, tag_value.day)
|
|
||||||
date_str = _dd.display(date_part)
|
|
||||||
time_str = _('%(hr)02d:%(min)02d:%(sec)02d') % {'hr': tag_value.hour,
|
|
||||||
'min': tag_value.minute,
|
|
||||||
'sec': tag_value.second}
|
|
||||||
return _('%(date)s %(time)s') % {'date': date_str, 'time': time_str}
|
|
||||||
|
|
||||||
def _format_gps(tag_value):
|
|
||||||
"""
|
|
||||||
Convert a (degrees, minutes, seconds) tuple into a string for display.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return "%d° %02d' %05.2f\"" % (tag_value[0], tag_value[1], tag_value[2])
|
|
||||||
|
|
||||||
def _format_time(tag_value):
|
|
||||||
"""
|
|
||||||
formats a pyexiv2.Rational() list into a Time format
|
|
||||||
"""
|
|
||||||
|
|
||||||
return "%02d:%02d:%02d" % (tag_value[0], tag_value[1], tag_value[2])
|
|
||||||
|
|
||||||
def _parse_datetime(value):
|
def _parse_datetime(value):
|
||||||
"""
|
"""
|
||||||
@ -138,12 +118,13 @@ def _parse_datetime(value):
|
|||||||
|
|
||||||
date_part = _dp.parse(date_text)
|
date_part = _dp.parse(date_text)
|
||||||
try:
|
try:
|
||||||
time_part = time.strptime(time_text, "%H:%M:%S")
|
time_part = time.strptime(time_text, '%H:%M:%S')
|
||||||
except ValueError:
|
except ValueError:
|
||||||
time_part = None
|
time_part = None
|
||||||
|
|
||||||
if date_part.get_modifier() == Date.MOD_NONE and time_part is not None:
|
if (date_part.get_modifier() == Date.MOD_NONE and time_part is not None):
|
||||||
return datetime(date_part.get_year(),
|
return datetime.datetime(
|
||||||
|
date_part.get_year(),
|
||||||
date_part.get_month(),
|
date_part.get_month(),
|
||||||
date_part.get_day(),
|
date_part.get_day(),
|
||||||
time_part.tm_hour,
|
time_part.tm_hour,
|
||||||
@ -165,82 +146,6 @@ _VALIDIMAGEMAP = dict( (index, imgtype) for index, imgtype in enumerate(_vtypes)
|
|||||||
# but they are not usable in exiv2/ pyexiv2...
|
# but they are not usable in exiv2/ pyexiv2...
|
||||||
_validconvert = [_("<-- Image Types -->"), ".bmp", ".jpg", ".png", ".tiff"]
|
_validconvert = [_("<-- Image Types -->"), ".bmp", ".jpg", ".png", ".tiff"]
|
||||||
|
|
||||||
# Categories for Separating the nodes of Exif metadata tags...
|
|
||||||
DESCRIPTION = _("Description")
|
|
||||||
ORIGIN = _("Origin")
|
|
||||||
IMAGE = _('Image')
|
|
||||||
CAMERA = _('Camera')
|
|
||||||
GPS = _('GPS')
|
|
||||||
ADVANCED = _("Advanced")
|
|
||||||
|
|
||||||
# All of the exiv2 tag reference...
|
|
||||||
TAGS_ = [
|
|
||||||
# Description subclass...
|
|
||||||
(DESCRIPTION, 'Exif.Image.ImageDescription', None, None, None),
|
|
||||||
(DESCRIPTION, 'Exif.Image.Artist', None, None, None),
|
|
||||||
(DESCRIPTION, 'Exif.Image.Copyright', None, None, None),
|
|
||||||
(DESCRIPTION, 'Exif.Photo.DateTimeOriginal', None, None, _format_datetime),
|
|
||||||
(DESCRIPTION, 'Exif.Image.DateTime', None, None, _format_datetime),
|
|
||||||
(DESCRIPTION, 'Exif.Image.Rating', None, None, None),
|
|
||||||
|
|
||||||
# Origin subclass...
|
|
||||||
(ORIGIN, 'Exif.Image.Software', None, None, None),
|
|
||||||
(ORIGIN, 'Xmp.MicrosoftPhoto.DateAcquired', None, None, None),
|
|
||||||
(ORIGIN, 'Exif.Image.TimeZoneOffset', None, None, None),
|
|
||||||
(ORIGIN, 'Exif.Image.SubjectDistance', None, None, None),
|
|
||||||
|
|
||||||
# Image subclass...
|
|
||||||
(IMAGE, 'Exif.Photo.PixelXDimension', None, None, None),
|
|
||||||
(IMAGE, 'Exif.Photo.PixelYDimension', None, None, None),
|
|
||||||
(IMAGE, 'Exif.Image.Compression', None, None, None),
|
|
||||||
(IMAGE, 'Exif.Image.DocumentName', None, None, None),
|
|
||||||
(IMAGE, 'Exif.Image.Orientation', None, None, None),
|
|
||||||
(IMAGE, 'Exif.Image.ImageID', None, None, None),
|
|
||||||
(IMAGE, 'Exif.Photo.ExifVersion', None, None, None),
|
|
||||||
|
|
||||||
# Camera subclass...
|
|
||||||
(CAMERA, 'Exif.Image.Make', None, None, None),
|
|
||||||
(CAMERA, 'Exif.Image.Model', None, None, None),
|
|
||||||
(CAMERA, 'Exif.Photo.FNumber', None, None, None),
|
|
||||||
(CAMERA, 'Exif.Photo.ExposureTime', None, None, None),
|
|
||||||
(CAMERA, 'Exif.Photo.ISOSpeedRatings', None, None, None),
|
|
||||||
(CAMERA, 'Exif.Photo.FocalLength', None, None, None),
|
|
||||||
(CAMERA, 'Exif.Photo.MeteringMode', None, None, None),
|
|
||||||
(CAMERA, 'Exif.Photo.Flash', None, None, None),
|
|
||||||
(CAMERA, 'Exif.Image.SelfTimerMode', None, None, None),
|
|
||||||
(CAMERA, 'Exif.Image.CameraSerialNumber', None, None, None),
|
|
||||||
|
|
||||||
# GPS subclass...
|
|
||||||
(GPS, 'Exif.GPSInfo.GPSLatitude',
|
|
||||||
'Exif.GPSInfo.GPSLatitudeRef', None, _format_gps),
|
|
||||||
|
|
||||||
(GPS, 'Exif.GPSInfo.GPSLongitude',
|
|
||||||
'Exif.GPSInfo.GPSLongitudeRef', None, _format_gps),
|
|
||||||
|
|
||||||
(GPS, 'Exif.GPSInfo.GPSAltitude',
|
|
||||||
'Exif.GPSInfo.GPSAltitudeRef', None, None),
|
|
||||||
|
|
||||||
(GPS, 'Exif.Image.GPSTag', None, None, None),
|
|
||||||
|
|
||||||
(GPS, 'Exif.GPSInfo.GPSTimeStamp', None, None, _format_time),
|
|
||||||
|
|
||||||
(GPS, 'Exif.GPSInfo.GPSSatellites', None, None, None),
|
|
||||||
|
|
||||||
# Advanced subclass...
|
|
||||||
(ADVANCED, 'Exif.Photo.Contrast', None, _("Contrast"), None),
|
|
||||||
(ADVANCED, 'Exif.Photo.LightSource', None, _("Light Source"), None),
|
|
||||||
(ADVANCED, 'Exif.Photo.ExposureProgram', None, _("Exposure Program"), None),
|
|
||||||
(ADVANCED, 'Exif.Photo.Saturation', None, _("Saturation"), None),
|
|
||||||
(ADVANCED, 'Exif.Photo.Sharpness', None, _("Sharpness"), None),
|
|
||||||
(ADVANCED, 'Exif.Photo.WhiteBalance', None, _("White Balance"), None),
|
|
||||||
(ADVANCED, 'Exif.Image.ExifTag', None, None, None),
|
|
||||||
(ADVANCED, 'Exif.Image.BatteryLevel', None, None, None),
|
|
||||||
(ADVANCED, 'Exif.Image.XPKeywords', None, None, None),
|
|
||||||
(ADVANCED, 'Exif.Image.XPComment', None, None, None),
|
|
||||||
(ADVANCED, 'Exif.Image.XPSubject', None, None, None),
|
|
||||||
(ADVANCED, 'Exif.Photo.DateTimeDigitized', None, None, _format_datetime)
|
|
||||||
]
|
|
||||||
|
|
||||||
# set up Exif keys for Image Exif metadata keypairs...
|
# set up Exif keys for Image Exif metadata keypairs...
|
||||||
_DATAMAP = {
|
_DATAMAP = {
|
||||||
"Exif.Image.ImageDescription" : "Description",
|
"Exif.Image.ImageDescription" : "Description",
|
||||||
@ -365,28 +270,24 @@ class EditExifMetadata(Gramplet):
|
|||||||
label = self.__create_label("MediaLabel", False, False, False)
|
label = self.__create_label("MediaLabel", False, False, False)
|
||||||
medialabel.pack_start(label, expand =False)
|
medialabel.pack_start(label, expand =False)
|
||||||
main_vbox.pack_start(medialabel, expand =False, fill =True, padding =0)
|
main_vbox.pack_start(medialabel, expand =False, fill =True, padding =0)
|
||||||
label.show()
|
|
||||||
|
|
||||||
# Displays mime type information...
|
# Displays mime type information...
|
||||||
mimetype = gtk.HBox(False, 0)
|
mimetype = gtk.HBox(False, 0)
|
||||||
label = self.__create_label("MimeType", False, False, False)
|
label = self.__create_label("MimeType", False, False, False)
|
||||||
mimetype.pack_start(label, expand =False)
|
mimetype.pack_start(label, expand =False)
|
||||||
main_vbox.pack_start(mimetype, expand =False, fill =True, padding =0)
|
main_vbox.pack_start(mimetype, expand =False, fill =True, padding =0)
|
||||||
label.show()
|
|
||||||
|
|
||||||
# image dimensions...
|
# image dimensions...
|
||||||
imagesize = gtk.HBox(False, 0)
|
imagesize = gtk.HBox(False, 0)
|
||||||
label = self.__create_label("ImageSize", False, False, False)
|
label = self.__create_label("ImageSize", False, False, False)
|
||||||
imagesize.pack_start(label, expand =False, fill =False, padding =0)
|
imagesize.pack_start(label, expand =False, fill =False, padding =0)
|
||||||
main_vbox.pack_start(imagesize, expand =False, fill =True, padding =0)
|
main_vbox.pack_start(imagesize, expand =False, fill =True, padding =0)
|
||||||
label.show()
|
|
||||||
|
|
||||||
# Displays all plugin messages...
|
# Displays all plugin messages...
|
||||||
messagearea = gtk.HBox(False, 0)
|
messagearea = gtk.HBox(False, 0)
|
||||||
label = self.__create_label("MessageArea", False, False, False)
|
label = self.__create_label("MessageArea", False, False, False)
|
||||||
messagearea.pack_start(label, expand =False)
|
messagearea.pack_start(label, expand =False)
|
||||||
main_vbox.pack_start(messagearea, expand =False, fill =True, padding =0)
|
main_vbox.pack_start(messagearea, expand =False, fill =True, padding =0)
|
||||||
label.show()
|
|
||||||
|
|
||||||
# Separator line before the buttons...
|
# Separator line before the buttons...
|
||||||
main_vbox.pack_start(gtk.HSeparator(), expand =False, fill =True, padding =5)
|
main_vbox.pack_start(gtk.HSeparator(), expand =False, fill =True, padding =5)
|
||||||
@ -404,11 +305,9 @@ class EditExifMetadata(Gramplet):
|
|||||||
button = self.__create_button(
|
button = self.__create_button(
|
||||||
"Thumbnail", _("Thumbnail"), [self.thumbnail_view])
|
"Thumbnail", _("Thumbnail"), [self.thumbnail_view])
|
||||||
event_box.add(button)
|
event_box.add(button)
|
||||||
button.show()
|
|
||||||
|
|
||||||
# Image Type...
|
# Image Types...
|
||||||
event_box = gtk.EventBox()
|
event_box = gtk.EventBox()
|
||||||
## event_box.set_size_request(150, 30)
|
|
||||||
new_hbox.pack_start(event_box, expand =False, fill =True, padding =5)
|
new_hbox.pack_start(event_box, expand =False, fill =True, padding =5)
|
||||||
event_box.show()
|
event_box.show()
|
||||||
|
|
||||||
@ -428,50 +327,37 @@ class EditExifMetadata(Gramplet):
|
|||||||
button = self.__create_button(
|
button = self.__create_button(
|
||||||
"Convert", False, [self.__convert_dialog], gtk.STOCK_CONVERT)
|
"Convert", False, [self.__convert_dialog], gtk.STOCK_CONVERT)
|
||||||
event_box.add(button)
|
event_box.add(button)
|
||||||
button.show()
|
|
||||||
|
|
||||||
# Connect the changed signal to ImageType...
|
# Connect the changed signal to ImageType...
|
||||||
self.exif_widgets["ImageTypes"].connect("changed", self.changed_cb)
|
self.exif_widgets["ImageTypes"].connect("changed", self.changed_cb)
|
||||||
|
|
||||||
# Help, Edit, and Delete horizontal box
|
# Help, Edit, and Delete horizontal box
|
||||||
hed_box = gtk.HButtonBox()
|
new_hbox = gtk.HBox(False, 0)
|
||||||
hed_box.set_layout(gtk.BUTTONBOX_START)
|
main_vbox.pack_start(new_hbox, expand =False, fill =True, padding =5)
|
||||||
main_vbox.pack_start(hed_box, expand =False, fill =True, padding =5)
|
new_hbox.show()
|
||||||
|
|
||||||
# Help button...
|
for (widget, text, callback, icon, is_sensitive) in [
|
||||||
hed_box.add( self.__create_button(
|
("Help", False, [self.__help_page], gtk.STOCK_HELP, True),
|
||||||
"Help", False, [self.__help_page], gtk.STOCK_HELP, True) )
|
("Edit", False, [self.display_edit], gtk.STOCK_EDIT, False),
|
||||||
|
("Delete", False, [self.__wipe_dialog], gtk.STOCK_DELETE, False) ]:
|
||||||
|
|
||||||
# Edit button...
|
button = self.__create_button(
|
||||||
hed_box.add( self.__create_button(
|
widget, text, callback, icon, is_sensitive)
|
||||||
"Edit", False, [self.display_edit_window], gtk.STOCK_EDIT) )
|
new_hbox.pack_start(button, expand =False, fill =True, padding =5)
|
||||||
|
|
||||||
# Delete All Metadata button...
|
self.view = MetadataView()
|
||||||
hed_box.add(self.__create_button(
|
main_vbox.pack_start(self.view, expand =False, fill =True, padding =5)
|
||||||
"Delete", False, [self.__wipe_dialog], gtk.STOCK_DELETE) )
|
|
||||||
|
|
||||||
new_vbox = self.__build_shaded_gui()
|
# Separator line before the Total...
|
||||||
main_vbox.pack_start(new_vbox, expand =False, fill =False, padding =10)
|
main_vbox.pack_start(gtk.HSeparator(), expand =False, fill =True, padding =5)
|
||||||
|
|
||||||
# number of key/value pairs shown...
|
# number of key/ value pairs shown...
|
||||||
label = self.__create_label("Total", False, False, False)
|
label = self.__create_label("Total", False, False, False)
|
||||||
main_vbox.pack_start(label, expand =False, fill =False, padding =10)
|
main_vbox.pack_start(label, expand =False, fill =True, padding =5)
|
||||||
label.show()
|
|
||||||
|
|
||||||
main_vbox.show_all()
|
main_vbox.show_all()
|
||||||
return main_vbox
|
return main_vbox
|
||||||
|
|
||||||
def __build_shaded_gui(self):
|
|
||||||
"""
|
|
||||||
Build the GUI interface.
|
|
||||||
"""
|
|
||||||
|
|
||||||
top = gtk.TreeView()
|
|
||||||
titles = [(_('Key'), 1, 190),
|
|
||||||
(_('Value'), 2, 250)]
|
|
||||||
self.model = ListModel(top, titles, list_mode="tree")
|
|
||||||
return top
|
|
||||||
|
|
||||||
def db_changed(self):
|
def db_changed(self):
|
||||||
self.dbstate.db.connect('media-update', self.update)
|
self.dbstate.db.connect('media-update', self.update)
|
||||||
self.connect_signal('Media', self.update)
|
self.connect_signal('Media', self.update)
|
||||||
@ -486,7 +372,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# deactivate all buttons except Help...
|
# deactivate all buttons except Help...
|
||||||
self.deactivate_buttons(["Convert", "Edit", "ImageTypes"])
|
self.deactivate_buttons(["Convert", "Edit", "ImageTypes", "Delete"])
|
||||||
|
|
||||||
db = self.dbstate.db
|
db = self.dbstate.db
|
||||||
imgtype_format = []
|
imgtype_format = []
|
||||||
@ -498,8 +384,6 @@ class EditExifMetadata(Gramplet):
|
|||||||
# clears all labels and display area...
|
# clears all labels and display area...
|
||||||
for widget in ["MediaLabel", "MimeType", "ImageSize", "MessageArea", "Total"]:
|
for widget in ["MediaLabel", "MimeType", "ImageSize", "MessageArea", "Total"]:
|
||||||
self.exif_widgets[widget].set_text("")
|
self.exif_widgets[widget].set_text("")
|
||||||
self.model.clear()
|
|
||||||
self.sections = {}
|
|
||||||
|
|
||||||
# set Message Ares to Select...
|
# set Message Ares to Select...
|
||||||
self.exif_widgets["MessageArea"].set_text(_("Select an image to begin..."))
|
self.exif_widgets["MessageArea"].set_text(_("Select an image to begin..."))
|
||||||
@ -553,15 +437,20 @@ class EditExifMetadata(Gramplet):
|
|||||||
# offer to convert it....
|
# offer to convert it....
|
||||||
if self.extension not in _VALIDIMAGEMAP.values():
|
if self.extension not in _VALIDIMAGEMAP.values():
|
||||||
|
|
||||||
|
# Convert message...
|
||||||
|
self.exif_widgets["MessageArea"].set_text(_("Please convert this "
|
||||||
|
"image type to one of the Exiv2- compatible image types..."))
|
||||||
|
|
||||||
imgtype_format = _validconvert
|
imgtype_format = _validconvert
|
||||||
self._VCONVERTMAP = dict( (index, imgtype) for index, imgtype in enumerate(imgtype_format) )
|
self._VCONVERTMAP = dict( (index, imgtype) for index, imgtype
|
||||||
|
in enumerate(imgtype_format) )
|
||||||
|
|
||||||
for index in xrange(1, len(imgtype_format) ):
|
for index in xrange(1, len(imgtype_format) ):
|
||||||
self.exif_widgets["ImageTypes"].append_text(imgtype_format[index] )
|
self.exif_widgets["ImageTypes"].append_text(imgtype_format[index] )
|
||||||
self.exif_widgets["ImageTypes"].set_active(0)
|
self.exif_widgets["ImageTypes"].set_active(0)
|
||||||
|
|
||||||
self.activate_buttons(["ImageTypes"])
|
self.activate_buttons(["ImageTypes"])
|
||||||
|
else:
|
||||||
# determine if it is a mime image object?
|
# determine if it is a mime image object?
|
||||||
if mime_type:
|
if mime_type:
|
||||||
if mime_type.startswith("image"):
|
if mime_type.startswith("image"):
|
||||||
@ -570,6 +459,10 @@ class EditExifMetadata(Gramplet):
|
|||||||
self.plugin_image = self.setup_image(self.image_path)
|
self.plugin_image = self.setup_image(self.image_path)
|
||||||
if self.plugin_image:
|
if self.plugin_image:
|
||||||
|
|
||||||
|
# display all Exif tags for this image,
|
||||||
|
# XmpTag and IptcTag has been purposefully excluded...
|
||||||
|
self.__display_exif_tags(self.image_path)
|
||||||
|
|
||||||
if OLD_API: # prior to pyexiv2-0.2.0
|
if OLD_API: # prior to pyexiv2-0.2.0
|
||||||
try:
|
try:
|
||||||
ttype, tdata = self.plugin_image.getThumbnailData()
|
ttype, tdata = self.plugin_image.getThumbnailData()
|
||||||
@ -580,16 +473,16 @@ class EditExifMetadata(Gramplet):
|
|||||||
thumbnail = False
|
thumbnail = False
|
||||||
|
|
||||||
else: # pyexiv2-0.2.0 and above...
|
else: # pyexiv2-0.2.0 and above...
|
||||||
|
|
||||||
# get image width and height...
|
# get image width and height...
|
||||||
self.exif_widgets["ImageSize"].show()
|
self.exif_widgets["ImageSize"].show()
|
||||||
width, height = self.plugin_image.dimensions
|
width, height = self.plugin_image.dimensions
|
||||||
self.exif_widgets["ImageSize"].set_text(_("Image Size : %04d x %04d pixels") % (width, height))
|
self.exif_widgets["ImageSize"].set_text(_("Image "
|
||||||
|
"Size : %04d x %04d pixels") % (width, height) )
|
||||||
|
|
||||||
|
# look for the existence of thumbnails?
|
||||||
try:
|
try:
|
||||||
previews = self.plugin_image.previews
|
previews = self.plugin_image.previews
|
||||||
thumbnail = True
|
thumbnail = True
|
||||||
|
|
||||||
except (IOError, OSError):
|
except (IOError, OSError):
|
||||||
thumbnail = False
|
thumbnail = False
|
||||||
|
|
||||||
@ -600,9 +493,6 @@ class EditExifMetadata(Gramplet):
|
|||||||
# Activate the Edit button...
|
# Activate the Edit button...
|
||||||
self.activate_buttons(["Edit"])
|
self.activate_buttons(["Edit"])
|
||||||
|
|
||||||
# display all exif metadata...
|
|
||||||
self.__display_exif_tags(_get_exif_keypairs(self.plugin_image) )
|
|
||||||
|
|
||||||
# has mime, but not an image...
|
# has mime, but not an image...
|
||||||
else:
|
else:
|
||||||
self.exif_widgets["MessageArea"].set_text(_("Please choose a different image..."))
|
self.exif_widgets["MessageArea"].set_text(_("Please choose a different image..."))
|
||||||
@ -613,53 +503,15 @@ class EditExifMetadata(Gramplet):
|
|||||||
self.exif_widgets["MessageArea"].set_text(_("Please choose a different image..."))
|
self.exif_widgets["MessageArea"].set_text(_("Please choose a different image..."))
|
||||||
return
|
return
|
||||||
|
|
||||||
def __display_exif_tags(self, mediadatatags =None):
|
def __display_exif_tags(self, full_path =None):
|
||||||
"""
|
"""
|
||||||
Display the exif tags.
|
Display the exif tags.
|
||||||
"""
|
"""
|
||||||
|
# display exif tags in the treeview
|
||||||
mediadatatags = _get_exif_keypairs(self.plugin_image)
|
has_data = self.view.display_exif_tags(full_path =self.image_path)
|
||||||
if not mediadatatags:
|
|
||||||
self.exif_widgets["MessageArea"].set_text(_("No Exif metadata for this image..."))
|
|
||||||
self.set_has_data(False)
|
|
||||||
else:
|
|
||||||
for section, key, key2, tag_label, func in TAGS_:
|
|
||||||
if key in mediadatatags:
|
|
||||||
|
|
||||||
if section not in self.sections:
|
|
||||||
node = self.model.add([section, ''])
|
|
||||||
self.sections[section] = node
|
|
||||||
else:
|
|
||||||
node = self.sections[section]
|
|
||||||
|
|
||||||
if OLD_API: # prior to v0.2.0
|
|
||||||
label = self.plugin_image.tagDetails(key)[0]
|
|
||||||
tag_value = self.plugin_image.interpretedExifValue(key)
|
|
||||||
if func:
|
|
||||||
human_value = func(tag_value)
|
|
||||||
else:
|
|
||||||
human_value = tag_value
|
|
||||||
|
|
||||||
if key2:
|
|
||||||
human_value += ' ' + self.plugin_image.interpretedExifValue(key2)
|
|
||||||
|
|
||||||
else: # v0.2.0 and above
|
|
||||||
tag = self.plugin_image[key]
|
|
||||||
label = tag.label
|
|
||||||
if func:
|
|
||||||
human_value = func(tag.value)
|
|
||||||
else:
|
|
||||||
human_value = tag.human_value
|
|
||||||
|
|
||||||
if key2:
|
|
||||||
human_value += ' ' + self.plugin_image[key2].human_value
|
|
||||||
self.model.add((label, human_value), node =node)
|
|
||||||
|
|
||||||
# once completed displaying, open all nodes...
|
|
||||||
self.model.tree.expand_all()
|
|
||||||
|
|
||||||
# update has_data functionality...
|
# update has_data functionality...
|
||||||
self.set_has_data(self.model.count > 0)
|
self.set_has_data(has_data)
|
||||||
|
|
||||||
# activate these buttons...
|
# activate these buttons...
|
||||||
self.activate_buttons(["Delete"])
|
self.activate_buttons(["Delete"])
|
||||||
@ -731,41 +583,17 @@ class EditExifMetadata(Gramplet):
|
|||||||
"""
|
"""
|
||||||
Return True if the gramplet has data, else return False.
|
Return True if the gramplet has data, else return False.
|
||||||
"""
|
"""
|
||||||
db = self.dbstate.db
|
|
||||||
|
|
||||||
if media is None:
|
if media is None:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
full_path = Utils.media_path_full(db, media.get_path() )
|
full_path = Utils.media_path_full(self.dbstate.db, media.get_path() )
|
||||||
if not os.path.isfile(full_path):
|
return self.view.get_has_data(full_path)
|
||||||
return False
|
|
||||||
|
|
||||||
if OLD_API: # prior to pyexiv2-0.2.0
|
|
||||||
metadata = pyexiv2.Image(full_path)
|
|
||||||
try:
|
|
||||||
metadata.readMetadata()
|
|
||||||
except (IOError, OSError):
|
|
||||||
return False
|
|
||||||
|
|
||||||
else: # pyexiv2-0.2.0 and above
|
|
||||||
metadata = pyexiv2.ImageMetadata(full_path)
|
|
||||||
try:
|
|
||||||
metadata.read()
|
|
||||||
except (IOError, OSError):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# update image Exif metadata...
|
|
||||||
mediadatatags = _get_exif_keypairs(self.plugin_image)
|
|
||||||
if mediadatatags:
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
def __create_button(self, pos, text, callback =[], icon =False, sensitive =False):
|
def __create_button(self, pos, text, callback =[], icon =False, sensitive =False):
|
||||||
"""
|
"""
|
||||||
creates and returns a button for display
|
creates and returns a button for display
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if (icon and not text):
|
if (icon and not text):
|
||||||
button = gtk.Button(stock =icon)
|
button = gtk.Button(stock =icon)
|
||||||
else:
|
else:
|
||||||
@ -775,22 +603,23 @@ class EditExifMetadata(Gramplet):
|
|||||||
for call_ in callback:
|
for call_ in callback:
|
||||||
button.connect("clicked", call_)
|
button.connect("clicked", call_)
|
||||||
|
|
||||||
# attach a addon widget to the button for manipulation...
|
# attach a addon widget to the button for later manipulation...
|
||||||
self.exif_widgets[pos] = button
|
self.exif_widgets[pos] = button
|
||||||
|
|
||||||
if not sensitive:
|
if not sensitive:
|
||||||
button.set_sensitive(False)
|
button.set_sensitive(False)
|
||||||
else:
|
|
||||||
button.set_sensitive(True)
|
|
||||||
|
|
||||||
|
button.show()
|
||||||
return button
|
return button
|
||||||
|
|
||||||
def __create_label(self, widget, text, width, height, wrap =True):
|
def __create_label(self, widget, text, width, height, wrap =True):
|
||||||
"""
|
"""
|
||||||
creates a label for this addon.
|
creates a label for this addon.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
label = gtk.Label()
|
label = gtk.Label()
|
||||||
|
|
||||||
|
if text:
|
||||||
|
label.set_text(text)
|
||||||
label.set_alignment(0.0, 0.0)
|
label.set_alignment(0.0, 0.0)
|
||||||
|
|
||||||
if wrap:
|
if wrap:
|
||||||
@ -799,12 +628,10 @@ class EditExifMetadata(Gramplet):
|
|||||||
if (width and height):
|
if (width and height):
|
||||||
label.set_size_request(width, height)
|
label.set_size_request(width, height)
|
||||||
|
|
||||||
if text:
|
|
||||||
label.set_text(text)
|
|
||||||
|
|
||||||
if widget:
|
if widget:
|
||||||
self.exif_widgets[widget] = label
|
self.exif_widgets[widget] = label
|
||||||
|
|
||||||
|
label.show()
|
||||||
return label
|
return label
|
||||||
|
|
||||||
def thumbnail_view(self, object):
|
def thumbnail_view(self, object):
|
||||||
@ -1074,7 +901,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
# set Message Area to Entering Data...
|
# set Message Area to Entering Data...
|
||||||
self.exif_widgets["MessageArea"].set_text(_("Entering data..."))
|
self.exif_widgets["MessageArea"].set_text(_("Entering data..."))
|
||||||
|
|
||||||
if EXIV2_FOUND_:
|
if EXIV2_FOUND:
|
||||||
if not self.exif_widgets["Delete"].get_sensitive():
|
if not self.exif_widgets["Delete"].get_sensitive():
|
||||||
self.activate_buttons(["Delete"])
|
self.activate_buttons(["Delete"])
|
||||||
|
|
||||||
@ -1083,7 +910,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
if not self.exif_widgets["Save"].get_sensitive():
|
if not self.exif_widgets["Save"].get_sensitive():
|
||||||
self.activate_buttons(["Save"])
|
self.activate_buttons(["Save"])
|
||||||
|
|
||||||
def display_edit_window(self, object):
|
def display_edit(self, object):
|
||||||
"""
|
"""
|
||||||
creates the editing area fields.
|
creates the editing area fields.
|
||||||
"""
|
"""
|
||||||
@ -1094,16 +921,14 @@ class EditExifMetadata(Gramplet):
|
|||||||
self.edtarea = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
self.edtarea = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
||||||
self.edtarea.tooltip = tip
|
self.edtarea.tooltip = tip
|
||||||
self.edtarea.set_title( self.orig_image.get_description() )
|
self.edtarea.set_title( self.orig_image.get_description() )
|
||||||
self.edtarea.set_default_size(525, 582)
|
self.edtarea.set_default_size(525, 562)
|
||||||
self.edtarea.set_border_width(10)
|
self.edtarea.set_border_width(10)
|
||||||
self.edtarea.connect("destroy", lambda w: self.edtarea.destroy() )
|
self.edtarea.connect("destroy", lambda w: self.edtarea.destroy() )
|
||||||
|
|
||||||
# create a new scrolled window.
|
# create a new scrolled window.
|
||||||
scrollwindow = gtk.ScrolledWindow()
|
scrollwindow = gtk.ScrolledWindow()
|
||||||
scrollwindow.set_border_width(10)
|
scrollwindow.set_border_width(10)
|
||||||
# scrollwindow.set_size_request(520, 500)
|
|
||||||
scrollwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
scrollwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||||
|
|
||||||
self.edtarea.add(scrollwindow)
|
self.edtarea.add(scrollwindow)
|
||||||
scrollwindow.show()
|
scrollwindow.show()
|
||||||
|
|
||||||
@ -1140,24 +965,24 @@ class EditExifMetadata(Gramplet):
|
|||||||
self._setup_widget_tips(fields =True, buttons = True)
|
self._setup_widget_tips(fields =True, buttons = True)
|
||||||
|
|
||||||
# display all data fields and their values...
|
# display all data fields and their values...
|
||||||
self.__edit_area()
|
self.edit_area()
|
||||||
|
|
||||||
def __build_edit_gui(self):
|
def __build_edit_gui(self):
|
||||||
"""
|
"""
|
||||||
will build the edit screen ...
|
will build the edit screen ...
|
||||||
"""
|
"""
|
||||||
|
|
||||||
main_vbox = gtk.VBox()
|
main_vbox = gtk.VBox()
|
||||||
main_vbox.set_border_width(10)
|
main_vbox.set_border_width(10)
|
||||||
main_vbox.set_size_request(480, 480)
|
main_vbox.set_size_request(480, 460)
|
||||||
|
|
||||||
label = self.__create_label("Edit:Message", False, False, False)
|
label = self.__create_label("Edit:Message", False, False, False)
|
||||||
main_vbox.pack_start(label, expand =False, fill =False, padding =0)
|
main_vbox.pack_start(label, expand =False, fill =False, padding =0)
|
||||||
label.show()
|
|
||||||
|
|
||||||
# create the data fields...
|
# create the data fields...
|
||||||
# ***Label/ Title, Description, Artist, and Copyright
|
# ***Label/ Title, Description, Artist, and Copyright
|
||||||
gen_frame = gtk.Frame(_("General Data"))
|
gen_frame = gtk.Frame(_("General Data"))
|
||||||
gen_frame.set_size_request(470, 170)
|
gen_frame.set_size_request(470, 165)
|
||||||
main_vbox.pack_start(gen_frame, expand =False, fill =True, padding =10)
|
main_vbox.pack_start(gen_frame, expand =False, fill =True, padding =10)
|
||||||
gen_frame.show()
|
gen_frame.show()
|
||||||
|
|
||||||
@ -1176,7 +1001,6 @@ class EditExifMetadata(Gramplet):
|
|||||||
|
|
||||||
label = self.__create_label(False, text, width =90, height =25)
|
label = self.__create_label(False, text, width =90, height =25)
|
||||||
new_hbox.pack_start(label, expand =False, fill =False, padding =0)
|
new_hbox.pack_start(label, expand =False, fill =False, padding =0)
|
||||||
label.show()
|
|
||||||
|
|
||||||
event_box = gtk.EventBox()
|
event_box = gtk.EventBox()
|
||||||
event_box.set_size_request(360, 30)
|
event_box.set_size_request(360, 30)
|
||||||
@ -1190,7 +1014,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
|
|
||||||
# iso format: Year, Month, Day spinners...
|
# iso format: Year, Month, Day spinners...
|
||||||
datetime_frame = gtk.Frame(_("Date/ Time"))
|
datetime_frame = gtk.Frame(_("Date/ Time"))
|
||||||
datetime_frame.set_size_request(470, 110)
|
datetime_frame.set_size_request(470, 105)
|
||||||
main_vbox.pack_start(datetime_frame, expand =False, fill =False, padding =0)
|
main_vbox.pack_start(datetime_frame, expand =False, fill =False, padding =0)
|
||||||
datetime_frame.show()
|
datetime_frame.show()
|
||||||
|
|
||||||
@ -1222,7 +1046,6 @@ class EditExifMetadata(Gramplet):
|
|||||||
|
|
||||||
entry = ValidatableMaskedEntry()
|
entry = ValidatableMaskedEntry()
|
||||||
entry.connect('validate', self.validate_datetime, widget)
|
entry.connect('validate', self.validate_datetime, widget)
|
||||||
# entry.connect('content-changed', self.set_datetime, widget)
|
|
||||||
event_box.add(entry)
|
event_box.add(entry)
|
||||||
self.exif_widgets[widget] = entry
|
self.exif_widgets[widget] = entry
|
||||||
entry.show()
|
entry.show()
|
||||||
@ -1296,31 +1119,23 @@ class EditExifMetadata(Gramplet):
|
|||||||
"DMS", _("Deg., Mins., Secs."), [self.__dmsbutton], False, True) )
|
"DMS", _("Deg., Mins., Secs."), [self.__dmsbutton], False, True) )
|
||||||
|
|
||||||
# Help, Save, Clear, Copy, and Close horizontal box
|
# Help, Save, Clear, Copy, and Close horizontal box
|
||||||
hsccc_box = gtk.HButtonBox()
|
# Help, Edit, and Delete horizontal box
|
||||||
hsccc_box.set_layout(gtk.BUTTONBOX_START)
|
new_hbox = gtk.HBox(False, 0)
|
||||||
main_vbox.pack_start(hsccc_box, expand =False, fill =False, padding =10)
|
main_vbox.pack_start(new_hbox, expand =False, fill =True, padding =5)
|
||||||
hsccc_box.show()
|
new_hbox.show()
|
||||||
|
|
||||||
# Help button...
|
for (widget, text, callback, icon, is_sensitive) in [
|
||||||
hsccc_box.add(self.__create_button(
|
("Help", False, [self.__help_page], gtk.STOCK_HELP, True),
|
||||||
"Help", False, [self.__help_page], gtk.STOCK_HELP, True) )
|
("Save", False, [self.save_metadata,
|
||||||
|
self.__display_exif_tags,
|
||||||
|
self.update], gtk.STOCK_SAVE, True),
|
||||||
|
("Clear", False, [self.clear_metadata], gtk.STOCK_CLEAR, True),
|
||||||
|
("Copy", False, [self.__display_exif_tags], gtk.STOCK_COPY, True),
|
||||||
|
("Close", False, [lambda w: self.edtarea.destroy()], gtk.STOCK_CLOSE, True) ]:
|
||||||
|
|
||||||
# Save button...
|
button = self.__create_button(
|
||||||
hsccc_box.add(self.__create_button(
|
widget, text, callback, icon, is_sensitive)
|
||||||
"Save", False, [self.save_metadata, self.update, self.__display_exif_tags],
|
new_hbox.pack_start(button, expand =False, fill =True, padding =5)
|
||||||
gtk.STOCK_SAVE, True) )
|
|
||||||
|
|
||||||
# Clear button...
|
|
||||||
hsccc_box.add(self.__create_button(
|
|
||||||
"Clear", False, [self.clear_metadata], gtk.STOCK_CLEAR, True) )
|
|
||||||
|
|
||||||
# Re -display the edit area button...
|
|
||||||
hsccc_box.add(self.__create_button(
|
|
||||||
"Copy", False, [self.__edit_area], gtk.STOCK_COPY, True) )
|
|
||||||
|
|
||||||
# Close button...
|
|
||||||
hsccc_box.add(self.__create_button(
|
|
||||||
"Close", False, [lambda w: self.edtarea.destroy() ], gtk.STOCK_CLOSE, True) )
|
|
||||||
|
|
||||||
main_vbox.show_all()
|
main_vbox.show_all()
|
||||||
return main_vbox
|
return main_vbox
|
||||||
@ -1364,25 +1179,25 @@ class EditExifMetadata(Gramplet):
|
|||||||
"delete the Exif metadata from this image?"), _("Delete"),
|
"delete the Exif metadata from this image?"), _("Delete"),
|
||||||
self.strip_metadata)
|
self.strip_metadata)
|
||||||
|
|
||||||
def _get_value(self, keytag_):
|
def _get_value(self, keytag):
|
||||||
"""
|
"""
|
||||||
gets the value from the Exif Key, and returns it...
|
gets the value from the Exif Key, and returns it...
|
||||||
|
|
||||||
@param: keytag_ -- image metadata key
|
@param: keytag -- image metadata key
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if OLD_API:
|
if OLD_API:
|
||||||
keyvalue_ = self.plugin_image[keytag_]
|
keyvalu = self.plugin_image[keytag]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
valu_ = self.plugin_image.__getitem__(keytag_)
|
value = self.plugin_image.__getitem__(keytag)
|
||||||
keyvalue_ = valu_.value
|
keyvalu = value.value
|
||||||
|
|
||||||
except (KeyError, ValueError, AttributeError):
|
except (KeyError, ValueError, AttributeError):
|
||||||
keyvalue_ = False
|
keyvalu = False
|
||||||
|
|
||||||
return keyvalue_
|
return keyvalu
|
||||||
|
|
||||||
def clear_metadata(self, object):
|
def clear_metadata(self, object):
|
||||||
"""
|
"""
|
||||||
@ -1392,19 +1207,18 @@ class EditExifMetadata(Gramplet):
|
|||||||
for widget in _TOOLTIPS.keys():
|
for widget in _TOOLTIPS.keys():
|
||||||
self.exif_widgets[widget].set_text("")
|
self.exif_widgets[widget].set_text("")
|
||||||
|
|
||||||
def __edit_area(self, mediadatatags =None):
|
def edit_area(self, mediadatatags =None):
|
||||||
"""
|
"""
|
||||||
displays the image Exif metadata in the Edit Area...
|
displays the image Exif metadata in the Edit Area...
|
||||||
"""
|
"""
|
||||||
|
if mediadatatags is None:
|
||||||
mediadatatags = _get_exif_keypairs(self.plugin_image)
|
mediadatatags = _get_exif_keypairs(self.plugin_image)
|
||||||
if mediadatatags:
|
mediadatatags = [keytag for keytag in mediadatatags if keytag in _DATAMAP]
|
||||||
mediadatatags = [keytag_ for keytag_ in mediadatatags if keytag_ in _DATAMAP]
|
|
||||||
|
|
||||||
for keytag_ in mediadatatags:
|
for keytag in mediadatatags:
|
||||||
widget = _DATAMAP[keytag_]
|
widget = _DATAMAP[keytag]
|
||||||
|
|
||||||
tag_value = self._get_value(keytag_)
|
tag_value = self._get_value(keytag)
|
||||||
if tag_value:
|
if tag_value:
|
||||||
|
|
||||||
if widget in ["Description", "Artist", "Copyright"]:
|
if widget in ["Description", "Artist", "Copyright"]:
|
||||||
@ -1412,10 +1226,12 @@ class EditExifMetadata(Gramplet):
|
|||||||
|
|
||||||
# Last Changed/ Modified...
|
# Last Changed/ Modified...
|
||||||
elif widget in ["Modified", "Original"]:
|
elif widget in ["Modified", "Original"]:
|
||||||
use_date = _format_datetime(tag_value)
|
use_date = format_datetime(tag_value)
|
||||||
if use_date:
|
if use_date:
|
||||||
self.exif_widgets[widget].set_text(use_date)
|
self.exif_widgets[widget].set_text(use_date)
|
||||||
if (widget == "Modified" and tag_value):
|
|
||||||
|
# set Modified Datetime to non-editable...
|
||||||
|
if (widget == "Modified" and use_date):
|
||||||
self.exif_widgets[widget].set_editable(False)
|
self.exif_widgets[widget].set_editable(False)
|
||||||
|
|
||||||
# LatitudeRef, Latitude, LongitudeRef, Longitude...
|
# LatitudeRef, Latitude, LongitudeRef, Longitude...
|
||||||
@ -1456,38 +1272,28 @@ class EditExifMetadata(Gramplet):
|
|||||||
|
|
||||||
elif widget == "Altitude":
|
elif widget == "Altitude":
|
||||||
altitude = tag_value
|
altitude = tag_value
|
||||||
AltitudeRef = self._get_value(_DATAMAP["AltitudeRef"])
|
altref = self._get_value(_DATAMAP["AltitudeRef"])
|
||||||
|
|
||||||
if (altitude and AltitudeRef):
|
if (altitude and altref):
|
||||||
altitude = convert_value(altitude)
|
altitude = convert_value(altitude)
|
||||||
if altitude:
|
if altitude:
|
||||||
if AltitudeRef == "1":
|
if altref == "1":
|
||||||
altitude = "-" + altitude
|
altitude = "-" + altitude
|
||||||
self.exif_widgets[widget].set_text(altitude)
|
self.exif_widgets[widget].set_text(altitude)
|
||||||
|
|
||||||
else:
|
def _set_value(self, keytag, keyvalu):
|
||||||
# set Edit Message Area to None...
|
|
||||||
self.exif_widgets["Edit:Message"].set_text(_("There is NO Exif metadata for this image."))
|
|
||||||
|
|
||||||
for widget in _TOOLTIPS.keys():
|
|
||||||
|
|
||||||
# once the user types in that field,
|
|
||||||
# the Edit, Clear, and Delete buttons will become active...
|
|
||||||
self.exif_widgets[widget].connect("changed", self.active_buttons)
|
|
||||||
|
|
||||||
def _set_value(self, keytag_, keyvalue_):
|
|
||||||
"""
|
"""
|
||||||
sets the value for the metadata keytag_s
|
sets the value for the metadata keytags
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if OLD_API:
|
if OLD_API:
|
||||||
self.plugin_image[keytag_] = keyvalue_
|
self.plugin_image[keytag] = keyvalu
|
||||||
|
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
self.plugin_image.__setitem__(keytag_, keyvalue_)
|
self.plugin_image.__setitem__(keytag, keyvalu)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
self.plugin_image[keytag_] = pyexiv2.ExifTag(keytag_, keyvalue_)
|
self.plugin_image[keytag] = pyexiv2.ExifTag(keytag, keyvalu)
|
||||||
except (ValueError, AttributeError):
|
except (ValueError, AttributeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -1573,47 +1379,50 @@ class EditExifMetadata(Gramplet):
|
|||||||
|
|
||||||
return latitude, longitude
|
return latitude, longitude
|
||||||
|
|
||||||
def save_metadata(self, datatags_ =None):
|
def save_metadata(self, mediadatatags =None):
|
||||||
"""
|
"""
|
||||||
gets the information from the plugin data fields
|
gets the information from the plugin data fields
|
||||||
and sets the keytag_ = keyvalue image metadata
|
and sets the keytag = keyvalue image metadata
|
||||||
"""
|
"""
|
||||||
|
|
||||||
db = self.dbstate.db
|
db = self.dbstate.db
|
||||||
|
|
||||||
# get a copy of all the widgets...
|
# get a copy of all the widgets and their current values...
|
||||||
datatags_ = ( (widget, self.exif_widgets[widget].get_text() ) for widget in _TOOLTIPS.keys() )
|
mediadatatags = list( (widget, self.exif_widgets[widget].get_text() )
|
||||||
|
for widget in _TOOLTIPS.keys() )
|
||||||
for widget, widgetvalu in datatags_:
|
mediadatatags.sort()
|
||||||
|
for widgetname, widgetvalu in mediadatatags:
|
||||||
|
|
||||||
# Description, Artist, Copyright...
|
# Description, Artist, Copyright...
|
||||||
if widget in ["Description", "Artist", "Copyright"]:
|
if widgetname in ["Description", "Artist", "Copyright"]:
|
||||||
self._set_value(_DATAMAP[widget], widgetvalu)
|
self._set_value(_DATAMAP[widgetname], widgetvalu)
|
||||||
|
|
||||||
# Modify Date/ Time...
|
# Update dynamically updated Modified field...
|
||||||
elif widget == "Modified":
|
elif widgetname == "Modified":
|
||||||
wigetvalue_ = self.dates["Modified"] if not None else datetime.datetime.now()
|
modified = datetime.datetime.now()
|
||||||
self._set_value(_DATAMAP[widget], widgetvalu)
|
self.exif_widgets[widgetname].set_text(format_datetime(modified) )
|
||||||
|
self.set_datetime(self.exif_widgets[widgetname], widgetname)
|
||||||
# display modified date in its cell...
|
if self.dates[widgetname] is not None:
|
||||||
displayed = _format_datetime(widgetvalu)
|
self._set_value(_DATAMAP[widgetname], self.dates[widgetname] )
|
||||||
if displayed:
|
else:
|
||||||
self.exif_widgets[widget].set_text(displayed)
|
self._set_value(_DATAMAP[widgetname], widgetvalu)
|
||||||
|
|
||||||
# Original Date/ Time...
|
# Original Date/ Time...
|
||||||
elif widget == "Original":
|
elif widgetname == "Original":
|
||||||
widgetvalu = self.dates["Original"]if not None else False
|
if widgetvalu == '':
|
||||||
if widgetvalu:
|
self._set_value(_DATAMAP[widgetname], widgetvalu)
|
||||||
self._set_value(_DATAMAP[widget], widgetvalu)
|
else:
|
||||||
|
self.set_datetime(self.exif_widgets[widgetname], widgetname)
|
||||||
|
if self.dates[widgetname] is not None:
|
||||||
|
|
||||||
# modify the media object date if it is not already set?
|
# modify the media object date if it is not already set?
|
||||||
mediaobj_dt = self.orig_image.get_date_object()
|
mediaobj_date = self.orig_image.get_date_object()
|
||||||
if mediaobj_dt.is_empty():
|
if mediaobj_date.is_empty():
|
||||||
objdate_ = gen.lib.date.Date()
|
objdate_ = Date()
|
||||||
|
widgetvalu = _parse_datetime(widgetvalu)
|
||||||
try:
|
try:
|
||||||
objdate_.set_yr_mon_day(widgetvalu.get_year(),
|
objdate_.set_yr_mon_day(widgetvalu.year,
|
||||||
widgetvalu.get_month(),
|
widgetvalu.month,
|
||||||
widgetvalu.get_day() )
|
widgetvalu.day)
|
||||||
gooddate = True
|
gooddate = True
|
||||||
except ValueError:
|
except ValueError:
|
||||||
gooddate = False
|
gooddate = False
|
||||||
@ -1623,11 +1432,10 @@ class EditExifMetadata(Gramplet):
|
|||||||
with DbTxn(_("Create Date Object"), db) as trans:
|
with DbTxn(_("Create Date Object"), db) as trans:
|
||||||
self.orig_image.set_date_object(objdate_)
|
self.orig_image.set_date_object(objdate_)
|
||||||
db.commit_media_object(self.orig_image, trans)
|
db.commit_media_object(self.orig_image, trans)
|
||||||
|
|
||||||
db.request_rebuild()
|
db.request_rebuild()
|
||||||
|
|
||||||
# Latitude/ Longitude...
|
# Latitude/ Longitude...
|
||||||
elif widget == "Latitude":
|
elif widgetname == "Latitude":
|
||||||
latitude = self.exif_widgets["Latitude"].get_text()
|
latitude = self.exif_widgets["Latitude"].get_text()
|
||||||
longitude = self.exif_widgets["Longitude"].get_text()
|
longitude = self.exif_widgets["Longitude"].get_text()
|
||||||
if (latitude and longitude):
|
if (latitude and longitude):
|
||||||
@ -1666,7 +1474,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
self._set_value(_DATAMAP["Longitude"], longitude)
|
self._set_value(_DATAMAP["Longitude"], longitude)
|
||||||
|
|
||||||
# Altitude, and Altitude Reference...
|
# Altitude, and Altitude Reference...
|
||||||
elif widget == "Altitude":
|
elif widgetname == "Altitude":
|
||||||
if widgetvalu:
|
if widgetvalu:
|
||||||
if "-" in widgetvalu:
|
if "-" in widgetvalu:
|
||||||
widgetvalu= widgetvalu.replace("-", "")
|
widgetvalu= widgetvalu.replace("-", "")
|
||||||
@ -1676,14 +1484,16 @@ class EditExifMetadata(Gramplet):
|
|||||||
|
|
||||||
# convert altitude to pyexiv2.Rational for saving...
|
# convert altitude to pyexiv2.Rational for saving...
|
||||||
widgetvalu = altitude_to_rational(widgetvalu)
|
widgetvalu = altitude_to_rational(widgetvalu)
|
||||||
|
else:
|
||||||
|
altituderef = ''
|
||||||
|
|
||||||
self._set_value(_DATAMAP["AltitudeRef"], altituderef)
|
self._set_value(_DATAMAP["AltitudeRef"], altituderef)
|
||||||
self._set_value(_DATAMAP[widget], widgetvalu)
|
self._set_value(_DATAMAP[widgetname], widgetvalu)
|
||||||
|
|
||||||
# writes all Exif Metadata to image even if the fields are all empty so as to remove the value...
|
# writes all Exif Metadata to image even if the fields are all empty so as to remove the value...
|
||||||
self.write_metadata(self.plugin_image)
|
self.write_metadata(self.plugin_image)
|
||||||
|
|
||||||
if datatags_:
|
if mediadatatags:
|
||||||
# set Message Area to Saved...
|
# set Message Area to Saved...
|
||||||
self.exif_widgets["Edit:Message"].set_text(_("Saving Exif metadata to this image..."))
|
self.exif_widgets["Edit:Message"].set_text(_("Saving Exif metadata to this image..."))
|
||||||
else:
|
else:
|
||||||
@ -1697,34 +1507,27 @@ class EditExifMetadata(Gramplet):
|
|||||||
|
|
||||||
# make sure the image has Exif metadata...
|
# make sure the image has Exif metadata...
|
||||||
mediadatatags = _get_exif_keypairs(self.plugin_image)
|
mediadatatags = _get_exif_keypairs(self.plugin_image)
|
||||||
if not mediadatatags:
|
if mediadatatags:
|
||||||
return
|
|
||||||
|
|
||||||
if EXIV2_FOUND_:
|
if EXIV2_FOUND: # use exiv2 to delete the Exif metadata...
|
||||||
try:
|
try:
|
||||||
erase = subprocess.check_call( [EXIV2_FOUND_, "delete", self.image_path] )
|
erase = subprocess.check_call( [EXIV2_FOUND, "delete", self.image_path] )
|
||||||
erase_results = str(erase)
|
erase_results = str(erase)
|
||||||
|
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
erase_results = False
|
erase_results = False
|
||||||
|
|
||||||
else:
|
else: # use pyexiv2 to delete Exif metadata...
|
||||||
if mediadatatags:
|
for keytag in mediadatatags:
|
||||||
for keytag_ in mediadatatags:
|
del self.plugin_image[keytag]
|
||||||
del self.plugin_image[keytag_]
|
|
||||||
erase_results = True
|
erase_results = True
|
||||||
|
|
||||||
|
if erase_results:
|
||||||
# write wiped metadata to image...
|
# write wiped metadata to image...
|
||||||
self.write_metadata(self.plugin_image)
|
self.write_metadata(self.plugin_image)
|
||||||
|
|
||||||
if erase_results:
|
|
||||||
|
|
||||||
for widget in ["MediaLabel", "MimeType", "ImageSize", "MessageArea", "Total"]:
|
for widget in ["MediaLabel", "MimeType", "ImageSize", "MessageArea", "Total"]:
|
||||||
self.exif_widgets[widget].set_text("")
|
self.exif_widgets[widget].set_text("")
|
||||||
|
|
||||||
# Clear the Viewing Area...
|
|
||||||
self.model.clear()
|
|
||||||
|
|
||||||
self.exif_widgets["MessageArea"].set_text(_("All Exif metadata "
|
self.exif_widgets["MessageArea"].set_text(_("All Exif metadata "
|
||||||
"has been deleted from this image..."))
|
"has been deleted from this image..."))
|
||||||
self.update()
|
self.update()
|
||||||
@ -1802,6 +1605,8 @@ def convert_value(value):
|
|||||||
if isinstance(value, (Fraction, pyexiv2.Rational)):
|
if isinstance(value, (Fraction, pyexiv2.Rational)):
|
||||||
return str((Decimal(value.numerator) / Decimal(value.denominator)))
|
return str((Decimal(value.numerator) / Decimal(value.denominator)))
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
def rational_to_dms(coordinates):
|
def rational_to_dms(coordinates):
|
||||||
"""
|
"""
|
||||||
takes a rational set of coordinates and returns (degrees, minutes, seconds)
|
takes a rational set of coordinates and returns (degrees, minutes, seconds)
|
||||||
@ -1814,18 +1619,13 @@ def rational_to_dms(coordinates):
|
|||||||
# or [Fraction(38, 1), Fraction(38, 1), Fraction(318, 100)]
|
# or [Fraction(38, 1), Fraction(38, 1), Fraction(318, 100)]
|
||||||
return [convert_value(coordinate) for coordinate in coordinates]
|
return [convert_value(coordinate) for coordinate in coordinates]
|
||||||
|
|
||||||
|
|
||||||
def _get_exif_keypairs(plugin_image):
|
def _get_exif_keypairs(plugin_image):
|
||||||
"""
|
"""
|
||||||
Will be used to retrieve and update the Exif metadata from the image.
|
Will be used to retrieve and update the Exif metadata from the image.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not plugin_image:
|
if plugin_image:
|
||||||
|
return [keytag for keytag in (plugin_image.exifKeys() if OLD_API
|
||||||
|
else plugin_image.exif_keys) ]
|
||||||
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
mediadatatags = [keytag_ for keytag_ in (plugin_image.exifKeys() if OLD_API
|
|
||||||
else chain( plugin_image.exif_keys,
|
|
||||||
plugin_image.xmp_keys,
|
|
||||||
plugin_image.iptc_keys) ) ]
|
|
||||||
|
|
||||||
return mediadatatags
|
|
||||||
|
Loading…
Reference in New Issue
Block a user