[gthumb] Fix metadata write.



commit 140da1c098ed841a4657275089e35b00102912d6
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Tue Jun 29 16:26:32 2010 +0200

    Fix metadata write.
    
    Save the type in the metadata itself.  Use md->tagLabel() to get the description, md->value() to get the raw value and md->print() to get the interpreted value.  Use value->read() on the raw value to restore the original
    value.
    
    [bug #623071]

 extensions/exiv2_tools/exiv2-utils.cpp |  166 +++++++++++++++++++++-----------
 gthumb/gth-file-data.c                 |    2 +-
 gthumb/gth-main.c                      |    2 +-
 gthumb/gth-metadata.c                  |   26 +++++-
 gthumb/gth-metadata.h                  |    1 +
 gthumb/gth-pixbuf-list-task.c          |    3 +
 6 files changed, 139 insertions(+), 61 deletions(-)
---
diff --git a/extensions/exiv2_tools/exiv2-utils.cpp b/extensions/exiv2_tools/exiv2-utils.cpp
index 94e5c21..28e5445 100644
--- a/extensions/exiv2_tools/exiv2-utils.cpp
+++ b/extensions/exiv2_tools/exiv2-utils.cpp
@@ -203,8 +203,8 @@ set_file_info (GFileInfo  *info,
 	char            *description_utf8;
 	char            *formatted_value_utf8;
 
-	if (_g_utf8_all_spaces (formatted_value))
-		return;
+	/*if (_g_utf8_all_spaces (formatted_value))
+		return;*/
 
 	attribute = exiv2_key_to_attribute (key);
 	description_utf8 = g_locale_to_utf8 (description, -1, NULL, NULL, NULL);
@@ -239,11 +239,20 @@ set_file_info (GFileInfo  *info,
 		metadata_info = gth_main_register_metadata_info (&info);
 	}
 
+	if ((metadata_info != NULL) && (metadata_info->type == NULL) && (type_name != NULL))
+		metadata_info->type = g_strdup (type_name);
+
 	if ((metadata_info != NULL) && (metadata_info->display_name == NULL) && (description_utf8 != NULL))
 		metadata_info->display_name = g_strdup (description_utf8);
 
 	metadata = gth_metadata_new ();
-	g_object_set (metadata, "id", key, "description", description_utf8, "formatted", formatted_value_utf8, "raw", raw_value, NULL);
+	g_object_set (metadata,
+		      "id", key,
+		      "description", description_utf8,
+		      "formatted", formatted_value_utf8,
+		      "raw", raw_value,
+		      "value-type", type_name,
+		      NULL);
 	g_file_info_set_attribute_object (info, attribute, G_OBJECT (metadata));
 
 	g_object_unref (metadata);
@@ -264,6 +273,7 @@ set_attribute_from_tagset (GFileInfo  *info,
 	char    *description;
 	char    *formatted_value;
 	char    *raw_value;
+	char    *type_name;
 
 	metadata = NULL;
 	for (i = 0; tagset[i] != NULL; i++) {
@@ -280,8 +290,15 @@ set_attribute_from_tagset (GFileInfo  *info,
 		      "description", &description,
 		      "formatted", &formatted_value,
 		      "raw", &raw_value,
+		      "value-type", &type_name,
 		      NULL);
-	set_file_info (info, attribute, description, formatted_value, raw_value, NULL, NULL);
+	set_file_info (info,
+		       attribute,
+		       description,
+		       formatted_value,
+		       raw_value,
+		       NULL,
+		       type_name);
 }
 
 
@@ -360,24 +377,24 @@ exiv2_read_metadata (Exiv2::Image::AutoPtr  image,
 	if (! exifData.empty()) {
 		Exiv2::ExifData::const_iterator end = exifData.end();
 		for (Exiv2::ExifData::const_iterator md = exifData.begin(); md != end; ++md) {
-			stringstream value;
-			value << *md;
+			stringstream raw_value;
+			raw_value << md->value();
 
-			stringstream short_name;
-			if (md->ifdId () > Exiv2::ifd1Id) {
+			stringstream description;
+			if (! md->tagLabel().empty())
+				description << md->tagLabel();
+			else if (md->ifdId () > Exiv2::ifd1Id)
 				// Must be a MakerNote - include group name
-				short_name << md->groupName() << "." << md->tagName();
-			}
-			else {
+				description << md->groupName() << "." << md->tagName();
+			else
 				// Normal exif tag - just use tag name
-				short_name << md->tagName();
-			}
+				description << md->tagName();
 
 			set_file_info (info,
 				       md->key().c_str(),
-				       short_name.str().c_str(),
-				       value.str().c_str(),
-				       md->toString().c_str(),
+				       description.str().c_str(),
+				       md->print().c_str(),
+				       raw_value.str().c_str(),
 				       get_exif_default_category (*md),
 				       md->typeName());
 		}
@@ -387,17 +404,20 @@ exiv2_read_metadata (Exiv2::Image::AutoPtr  image,
 	if (! iptcData.empty()) {
 		Exiv2::IptcData::iterator end = iptcData.end();
 		for (Exiv2::IptcData::iterator md = iptcData.begin(); md != end; ++md) {
-			stringstream value;
-			value << *md;
+			stringstream raw_value;
+			raw_value << md->value();
 
-			stringstream short_name;
-			short_name << md->tagName();
+			stringstream description;
+			if (! md->tagLabel().empty())
+				description << md->tagLabel();
+			else
+				description << md->tagName();
 
 			set_file_info (info,
 				       md->key().c_str(),
-				       short_name.str().c_str(),
-				       value.str().c_str(),
-				       md->toString().c_str(),
+				       description.str().c_str(),
+				       md->print().c_str(),
+				       raw_value.str().c_str(),
 				       "Iptc",
 				       md->typeName());
 		}
@@ -407,17 +427,20 @@ exiv2_read_metadata (Exiv2::Image::AutoPtr  image,
 	if (! xmpData.empty()) {
 		Exiv2::XmpData::iterator end = xmpData.end();
 		for (Exiv2::XmpData::iterator md = xmpData.begin(); md != end; ++md) {
-			stringstream value;
-			value << *md;
+			stringstream raw_value;
+			raw_value << md->value();
 
-			stringstream short_name;
-			short_name << md->groupName() << "." << md->tagName();
+			stringstream description;
+			if (! md->tagLabel().empty())
+				description << md->tagLabel();
+			else
+				description << md->groupName() << "." << md->tagName();
 
 			set_file_info (info,
 				       md->key().c_str(),
-				       short_name.str().c_str(),
-				       value.str().c_str(),
-				       md->toString().c_str(),
+				       description.str().c_str(),
+				       md->print().c_str(),
+				       raw_value.str().c_str(),
 				       "Xmp::Embedded",
 				       md->typeName());
 		}
@@ -523,17 +546,20 @@ exiv2_read_sidecar (GFile     *file,
 		if (! xmpData.empty()) {
 			Exiv2::XmpData::iterator end = xmpData.end();
 			for (Exiv2::XmpData::iterator md = xmpData.begin(); md != end; ++md) {
-				stringstream value;
-				value << *md;
+				stringstream raw_value;
+				raw_value << md->value();
 
-				stringstream short_name;
-				short_name << md->groupName() << "." << md->tagName();
+				stringstream description;
+				if (! md->tagLabel().empty())
+					description << md->tagLabel();
+				else
+					description << md->groupName() << "." << md->tagName();
 
 				set_file_info (info,
 					       md->key().c_str(),
-					       short_name.str().c_str(),
-					       value.str().c_str(),
-					       md->toString().c_str(),
+					       description.str().c_str(),
+					       md->print().c_str(),
+					       raw_value.str().c_str(),
 					       "Xmp::Sidecar",
 					       md->typeName());
 			}
@@ -573,6 +599,28 @@ mandatory_string (Exiv2::ExifData &checkdata,
 }
 
 
+const char *
+gth_main_get_metadata_type (GthMetadata *metadata,
+			    const char  *key)
+{
+	const char      *value_type;
+	GthMetadataInfo *metadatum_info;
+
+	value_type = gth_metadata_get_value_type (metadata);
+	if (g_strcmp0 (value_type, "Undefined") == 0)
+			value_type = NULL;
+
+	if (value_type != NULL)
+		return value_type;
+
+	metadatum_info = gth_main_get_metadata_info (key);
+	if (metadatum_info != NULL)
+		value_type = metadatum_info->type;
+
+	return value_type;
+}
+
+
 static Exiv2::DataBuf
 exiv2_write_metadata_private (Exiv2::Image::AutoPtr  image,
 			      GFileInfo             *info,
@@ -598,21 +646,23 @@ exiv2_write_metadata_private (Exiv2::Image::AutoPtr  image,
 			/* If the metadatum has no value yet, a new empty value
 			 * is created. The type is taken from Exiv2's tag
 			 * lookup tables. If the tag is not found in the table,
-			 * the type defaults to Ascii.
-			 * We always create the metadatum explicilty if the
+			 * the type defaults to ASCII.
+			 * We always create the metadatum explicitly if the
 			 * type is available to avoid type errors.
 			 * See bug #610389 for more details.  The original
-			 * expanation is here:
+			 * explanation is here:
 			 * http://uk.groups.yahoo.com/group/exiv2/message/1472
 			 */
 
-			GthMetadataInfo *metadatum_info = gth_main_get_metadata_info (attributes[i]);
-			if ((metadatum_info != NULL) && (metadatum_info->type != NULL)) {
-				Exiv2::Value::AutoPtr value = Exiv2::Value::create (Exiv2::TypeInfo::typeId (metadatum_info->type));
+			const char *raw_value = gth_metadata_get_raw (metadatum);
+			const char *value_type = gth_main_get_metadata_type (metadatum, key);
+
+			if ((raw_value != NULL) && (strcmp (raw_value, "") != 0) &&  (value_type != NULL)) {
+				Exiv2::Value::AutoPtr value = Exiv2::Value::create (Exiv2::TypeInfo::typeId (value_type));
+				value->read (raw_value);
 				Exiv2::ExifKey exif_key(key);
 				ed.add (exif_key, value.get());
 			}
-			ed[key] = gth_metadata_get_raw (metadatum);
 		}
 		catch (Exiv2::AnyError& e) {
 			/* we don't care about invalid key errors */
@@ -699,14 +749,16 @@ exiv2_write_metadata_private (Exiv2::Image::AutoPtr  image,
 		char *key = exiv2_key_from_attribute (attributes[i]);
 
 		try {
-			/* See the exif data code above for an explanation. */
-			GthMetadataInfo *metadatum_info = gth_main_get_metadata_info (attributes[i]);
-			if ((metadatum_info != NULL) && (metadatum_info->type != NULL)) {
-				Exiv2::Value::AutoPtr value = Exiv2::Value::create (Exiv2::TypeInfo::typeId (metadatum_info->type));
+			const char *raw_value = gth_metadata_get_raw (metadatum);
+			const char *value_type = gth_main_get_metadata_type (metadatum, key);
+
+			if ((raw_value != NULL) && (strcmp (raw_value, "") != 0) &&  (value_type != NULL)) {
+				/* See the exif data code above for an explanation. */
+				Exiv2::Value::AutoPtr value = Exiv2::Value::create (Exiv2::TypeInfo::typeId (value_type));
+				value->read (raw_value);
 				Exiv2::IptcKey iptc_key(key);
 				id.add (iptc_key, value.get());
 			}
-			id[key] = gth_metadata_get_raw (metadatum);
 		}
 		catch (Exiv2::AnyError& e) {
 			/* we don't care about invalid key errors */
@@ -733,17 +785,15 @@ exiv2_write_metadata_private (Exiv2::Image::AutoPtr  image,
 			xd.erase (iter);
 
 		try {
-			const char *value = gth_metadata_get_raw (metadatum);
+			const char *raw_value = gth_metadata_get_raw (metadatum);
+			const char *value_type = gth_main_get_metadata_type (metadatum, key);
 
-			if ((value != NULL) && strcmp (value, "") != 0) {
+			if ((raw_value != NULL) && (strcmp (raw_value, "") != 0) &&  (value_type != NULL)) {
 				/* See the exif data code above for an explanation. */
-				GthMetadataInfo *metadatum_info = gth_main_get_metadata_info (attributes[i]);
-				if ((metadatum_info != NULL) && (metadatum_info->type != NULL)) {
-					Exiv2::Value::AutoPtr value = Exiv2::Value::create (Exiv2::TypeInfo::typeId (metadatum_info->type));
-					Exiv2::XmpKey xmp_key(key);
-					xd.add (xmp_key, value.get());
-				}
-				xd[key] = gth_metadata_get_raw (metadatum);
+				Exiv2::Value::AutoPtr value = Exiv2::Value::create (Exiv2::TypeInfo::typeId (value_type));
+				value->read (raw_value);
+				Exiv2::XmpKey xmp_key(key);
+				xd.add (xmp_key, value.get());
 			}
 		}
 		catch (Exiv2::AnyError& e) {
diff --git a/gthumb/gth-file-data.c b/gthumb/gth-file-data.c
index c3d1683..eea9200 100644
--- a/gthumb/gth-file-data.c
+++ b/gthumb/gth-file-data.c
@@ -514,7 +514,7 @@ gth_file_data_get_attribute_as_string (GthFileData *file_data,
 	case G_FILE_ATTRIBUTE_TYPE_OBJECT:
 		obj = g_file_info_get_attribute_object (file_data->info, id);
 		if (GTH_IS_METADATA (obj))
-			g_object_get (obj, "formatted", &value, NULL);
+			value = g_strdup (gth_metadata_get_formatted (GTH_METADATA (obj)));
 		else if (GTH_IS_STRING_LIST (obj))
 			value = gth_string_list_join (GTH_STRING_LIST (obj), " ");
 		else
diff --git a/gthumb/gth-main.c b/gthumb/gth-main.c
index 434db4d..ffee3a5 100644
--- a/gthumb/gth-main.c
+++ b/gthumb/gth-main.c
@@ -408,7 +408,7 @@ gth_main_register_metadata_info (GthMetadataInfo *metadata_info)
 	GthMetadataInfo *info;
 
 	if ((metadata_info->display_name != NULL) && (strstr (metadata_info->display_name, "0x") != NULL))
-		return NULL;
+		metadata_info->flags = GTH_METADATA_ALLOW_NOWHERE;
 
 	g_static_mutex_lock (&metadata_info_mutex);
 
diff --git a/gthumb/gth-metadata.c b/gthumb/gth-metadata.c
index 1720434..4efb5bb 100644
--- a/gthumb/gth-metadata.c
+++ b/gthumb/gth-metadata.c
@@ -30,7 +30,8 @@ enum  {
 	GTH_METADATA_ID,
 	GTH_METADATA_DESCRIPTION,
 	GTH_METADATA_RAW,
-	GTH_METADATA_FORMATTED
+	GTH_METADATA_FORMATTED,
+	GTH_METADATA_VALUE_TYPE
 };
 
 struct _GthMetadataPrivate {
@@ -38,6 +39,7 @@ struct _GthMetadataPrivate {
 	char *description;
 	char *raw;
 	char *formatted;
+	char *value_type;
 };
 
 static gpointer gth_metadata_parent_class = NULL;
@@ -65,6 +67,9 @@ gth_metadata_get_property (GObject    *object,
 	case GTH_METADATA_FORMATTED:
 		g_value_set_string (value, self->priv->formatted);
 		break;
+	case GTH_METADATA_VALUE_TYPE:
+		g_value_set_string (value, self->priv->value_type);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 		break;
@@ -94,6 +99,9 @@ gth_metadata_set_property (GObject      *object,
 	case GTH_METADATA_FORMATTED:
 		_g_strset (&self->priv->formatted, g_value_get_string (value));
 		break;
+	case GTH_METADATA_VALUE_TYPE:
+		_g_strset (&self->priv->value_type, g_value_get_string (value));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 		break;
@@ -112,6 +120,7 @@ gth_metadata_finalize (GObject *obj)
 	g_free (self->priv->description);
 	g_free (self->priv->raw);
 	g_free (self->priv->formatted);
+	g_free (self->priv->value_type);
 
 	G_OBJECT_CLASS (gth_metadata_parent_class)->finalize (obj);
 }
@@ -155,6 +164,13 @@ gth_metadata_class_init (GthMetadataClass *klass)
 					 		      "Metadata formatted value",
 					 		      NULL,
 					 		      G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
+	g_object_class_install_property (G_OBJECT_CLASS (klass),
+					 GTH_METADATA_VALUE_TYPE,
+					 g_param_spec_string ("value-type",
+					 		      "Type",
+					 		      "Metadata type",
+					 		      NULL,
+					 		      G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
 }
 
 
@@ -166,6 +182,7 @@ gth_metadata_instance_init (GthMetadata *self)
 	self->priv->description = NULL;
 	self->priv->raw = NULL;
 	self->priv->formatted = NULL;
+	self->priv->value_type = NULL;
 }
 
 
@@ -221,6 +238,13 @@ gth_metadata_get_formatted (GthMetadata *metadata)
 }
 
 
+const char *
+gth_metadata_get_value_type (GthMetadata *metadata)
+{
+	return metadata->priv->value_type;
+}
+
+
 GthMetadataInfo *
 gth_metadata_info_dup (GthMetadataInfo *info)
 {
diff --git a/gthumb/gth-metadata.h b/gthumb/gth-metadata.h
index 33e3d08..cc3882f 100644
--- a/gthumb/gth-metadata.h
+++ b/gthumb/gth-metadata.h
@@ -77,6 +77,7 @@ GthMetadata *     gth_metadata_new             (void);
 const char *      gth_metadata_get_id          (GthMetadata     *metadata);
 const char *      gth_metadata_get_raw         (GthMetadata     *metadata);
 const char *      gth_metadata_get_formatted   (GthMetadata     *metadata);
+const char *      gth_metadata_get_value_type  (GthMetadata     *metadata);
 GthMetadataInfo * gth_metadata_info_dup        (GthMetadataInfo *info);
 void              set_attribute_from_string    (GFileInfo       *info,
 						const char      *key,
diff --git a/gthumb/gth-pixbuf-list-task.c b/gthumb/gth-pixbuf-list-task.c
index 80acde5..451ff83 100644
--- a/gthumb/gth-pixbuf-list-task.c
+++ b/gthumb/gth-pixbuf-list-task.c
@@ -261,8 +261,10 @@ pixbuf_task_save_current_pixbuf (GthPixbufListTask *self,
 		file_data = gth_file_data_new (file, ((GthFileData *) self->priv->current->data)->info);
 	else
 		file_data = g_object_ref (self->priv->current->data);
+
 	_g_object_unref (self->priv->new_pixbuf);
 	self->priv->new_pixbuf = g_object_ref (GTH_PIXBUF_TASK (self->priv->task)->dest);
+
 	_gdk_pixbuf_save_async (self->priv->new_pixbuf,
 				file_data,
 				gth_file_data_get_mime_type (file_data),
@@ -472,6 +474,7 @@ gth_pixbuf_list_task_init (GthPixbufListTask *self)
 {
 	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_PIXBUF_LIST_TASK, GthPixbufListTaskPrivate);
 	self->priv->original_pixbuf = NULL;
+	self->priv->new_pixbuf = NULL;
 	self->priv->destination_folder = NULL;
 	self->priv->overwrite_response = GTH_OVERWRITE_RESPONSE_UNSPECIFIED;
 	self->priv->mime_type = NULL;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]