1
1
mirror of https://gitlab.gnome.org/GNOME/gimp.git synced 2025-10-06 01:12:40 +02:00

Compare commits

...

7 Commits

Author SHA1 Message Date
Hartmut Kuhse
601654beb8 plug-ins: fix showing utf-8 filenames correctly 2017-01-07 11:01:28 +01:00
Hartmut Kuhse
a2668a8fdd plug-ins: fix file mode attribute again
Both O_BINARY and O_BINARY are not defined in linux by default.
So it needs a local #define.
2017-01-05 21:39:49 +01:00
Hartmut Kuhse
faaf2ab79b plug-ins: fix file mode attribute 2017-01-05 21:29:12 +01:00
Hartmut Kuhse
eb644fc782 plug-ins: fix file creation attribute. 2017-01-05 21:15:41 +01:00
Hartmut Kuhse
e6853696f1 plug-ins: adding attributes and iptc 2017-01-05 20:19:44 +01:00
Hartmut Kuhse
502e2ca3c2 plug-ins: adding missing ui-files 2017-01-05 19:53:54 +01:00
Hartmut Kuhse
61d3c6f93f plug-in: fix loading metadata in webp-plugin 2017-01-05 19:17:36 +01:00
7 changed files with 2618 additions and 15 deletions

View File

@@ -823,11 +823,11 @@ item_set_tattoo_invoker (GimpProcedure *procedure,
static GimpValueArray *
item_get_metadata_invoker (GimpProcedure *procedure,
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GimpValueArray *args,
GError **error)
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GimpValueArray *args,
GError **error)
{
gboolean success = TRUE;
GimpValueArray *return_vals;
@@ -855,11 +855,11 @@ item_get_metadata_invoker (GimpProcedure *procedure,
static GimpValueArray *
item_set_metadata_invoker (GimpProcedure *procedure,
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GimpValueArray *args,
GError **error)
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GimpValueArray *args,
GError **error)
{
gboolean success = TRUE;
GimpItem *item;

View File

@@ -2756,9 +2756,10 @@ gimp_metadata_load_from_file (GFile *file,
if (! gexiv2_metadata_open_path (GEXIV2_METADATA (metadata), filename, error))
{
g_set_error (error, gimp_metadata_error_quark (), 0,
_("GExiv2: Can't load metadata"));
g_free (filename);
g_object_unref (metadata);
return NULL;
}
}

View File

@@ -0,0 +1,955 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* attributes.c
* Copyright (C) 2014 Hartmut Kuhse <hatti@gimp.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* additions: share/gimp/2.0/ui/plug-ins/plug-in-attributes.ui
* This plug-in reads in a (libgimpbase/gimpattributes.c) object and
* presents it:
* as GtkTreeView lists
* in a GtkNotebook.
* The GtkNotebook pages represents the type of attributes, as "exif",
* "xmp", "iptc" or more.
* The expanders of the GtkTreeView represents the IFD (Exif) or Key (XMP, IPTC).
* of the attribute.
* The list entry of the GtkTreeView represents the tag of the attribute.
*/
#include "config.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <glib/gstdio.h>
#include <gio/gio.h>
#ifndef _O_BINARY
#define _O_BINARY 0
#endif
#ifdef G_OS_WIN32
#include <io.h>
#endif
#include <gtk/gtk.h>
#include <gexiv2/gexiv2.h>
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#include <libgimpbase/gimpbase.h>
#include "libgimp/stdplugins-intl.h"
#define PLUG_IN_IMAGE_PROC "plug-in-image-attributes-viewer"
#define PLUG_IN_LAYER_PROC "plug-in-layer-attributes-viewer"
#define PLUG_IN_HELP "plug-in-attributes-viewer"
#define PLUG_IN_BINARY "attributes"
#define THUMB_SIZE 48
#define RESPONSE_EXPORT 1
#define RESPONSE_GPS 3
typedef enum
{
ATT_IMAGE,
ATT_LAYER,
ATT_CHANNEL
} AttributesSource;
enum
{
C_IFD = 0,
C_TAG,
C_VALUE,
C_SORT,
NUM_COL
};
/* local function prototypes */
static void query (void);
static void run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
static void attributes_dialog_response (GtkWidget *widget,
gint response_id,
gpointer data);
static gboolean attributes_dialog (gint32 image_id,
AttributesSource source,
GimpMetadata *metadata);
static void attributes_dialog_set_attributes (GimpMetadata *metadata,
GtkBuilder *builder);
static GtkTreeIter *attributes_get_parent (const gchar *type,
const gchar *name);
static void attributes_add_parent (const gchar *type,
const gchar *name,
GtkTreeIter *iter);
static GtkTreeStore *attributes_notebook_page_get (GtkWidget *notebook,
const gchar *name);
static GtkWidget *attributes_treeview_new (void);
static void attributes_file_export_dialog (GtkWidget *parent,
GimpMetadata *metadata);
static void attributes_export_dialog_response (GtkWidget *dlg,
gint response_id,
gpointer data);
static void attributes_show_gps (GtkWidget *parent,
GimpMetadata *metadata);
static void attributes_message_dialog (GtkMessageType type,
GtkWindow *parent,
const gchar *title,
const gchar *message);
/* local variables */
const GimpPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
static GHashTable *ifd_table = NULL;
static GHashTable *tab_table = NULL;
static gchar *item_name = NULL;
static GtkWidget *gps_button;
static gdouble gps_latitude = 0.0;
static gdouble gps_longitude = 0.0;
static gchar *gps_latitude_ref = "N";
static gchar *gps_longitude_ref = "W";
/* functions */
MAIN ()
static void
query (void)
{
static const GimpParamDef image_attribs_args[] =
{
{ GIMP_PDB_INT32, "run-mode", "Run mode { RUN-INTERACTIVE (0) }" },
{ GIMP_PDB_IMAGE, "image", "Input image" }
};
static const GimpParamDef layer_attribs_args[] =
{
{ GIMP_PDB_INT32, "run-mode", "Run mode { RUN-INTERACTIVE (0) }" },
{ GIMP_PDB_IMAGE, "image", "Input image" },
{ GIMP_PDB_LAYER, "layer", "Input layer" }
};
gimp_install_procedure (PLUG_IN_IMAGE_PROC,
N_("View image metadata (Exif, IPTC, XMP, ...)"),
"View metadata information attached to the "
"current image. This can include Exif, IPTC, "
"XMP and/or other information. Some or all of these "
"metadata will be saved in the file, depending on "
"the output file format.",
"Hartmut Kuhse",
"Hartmut Kuhse",
"2014",
N_("Image Metadata"),
"*",
GIMP_PLUGIN,
G_N_ELEMENTS (image_attribs_args), 0,
image_attribs_args, NULL);
gimp_plugin_menu_register (PLUG_IN_IMAGE_PROC, "<Image>/Image");
gimp_plugin_icon_register (PLUG_IN_IMAGE_PROC, GIMP_ICON_TYPE_ICON_NAME,
(const guint8 *) GIMP_STOCK_IMAGE_METADATA);
gimp_install_procedure (PLUG_IN_LAYER_PROC,
N_("View layer metadata (Exif, IPTC, XMP, ...)"),
"View metadata information attached to the "
"current layer. This can include Exif, IPTC, "
"XMP and/or other information.",
"Hartmut Kuhse",
"Hartmut Kuhse",
"2014",
N_("Layer Metadata"),
"*",
GIMP_PLUGIN,
G_N_ELEMENTS (layer_attribs_args), 0,
layer_attribs_args, NULL);
gimp_plugin_menu_register (PLUG_IN_LAYER_PROC, "<Layers>");
gimp_plugin_icon_register (PLUG_IN_LAYER_PROC, GIMP_ICON_TYPE_ICON_NAME,
(const guint8 *) GIMP_STOCK_IMAGE_METADATA);
}
static void
run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals)
{
GimpMetadata *metadata;
AttributesSource source;
gint32 item_ID;
static GimpParam values[1];
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
*nreturn_vals = 1;
*return_vals = values;
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
INIT_I18N();
gimp_ui_init (PLUG_IN_BINARY, TRUE);
if (! strcmp (name, PLUG_IN_IMAGE_PROC))
{
item_ID = param[1].data.d_image;
metadata = gimp_image_get_metadata (item_ID);
source = ATT_IMAGE;
status = GIMP_PDB_SUCCESS;
}
else if (! strcmp (name, PLUG_IN_LAYER_PROC))
{
item_ID = param[2].data.d_layer;
metadata = gimp_item_get_metadata (item_ID);
source = ATT_LAYER;
status = GIMP_PDB_SUCCESS;
}
else
{
status = GIMP_PDB_CALLING_ERROR;
}
if (metadata)
{
ifd_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
tab_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
attributes_dialog (item_ID, source, metadata);
}
else
{
g_message (_("This image has no attributes attached to it."));
}
if (metadata)
g_object_unref (metadata);
if (ifd_table)
g_hash_table_unref (ifd_table);
values[0].data.d_status = status;
}
static void
attributes_dialog_response (GtkWidget *widget,
gint response_id,
gpointer data)
{
GimpMetadata *metadata = (GimpMetadata *) data;
switch (response_id)
{
case RESPONSE_EXPORT:
attributes_file_export_dialog (widget, metadata);
break;
case RESPONSE_GPS:
attributes_show_gps (widget, metadata);
break;
default:
gtk_widget_destroy (widget);
break;
}
}
static gboolean
attributes_dialog (gint32 item_id,
AttributesSource source,
GimpMetadata *metadata)
{
GtkBuilder *builder;
GtkWidget *dialog;
GtkWidget *attributes_vbox;
GtkWidget *content_area;
GdkPixbuf *pixbuf;
GtkWidget *label_header;
GtkWidget *label_info;
GtkWidget *thumb_box;
gchar *header;
gchar *ui_file;
gchar *title;
gchar *role;
GError *error = NULL;
gimp_ui_init (PLUG_IN_BINARY, FALSE);
switch (source)
{
case ATT_IMAGE:
item_name = gimp_image_get_name (item_id);
header = g_strdup_printf ("Image");
role = g_strdup_printf ("gimp-image-attributes-dialog");
pixbuf = gimp_image_get_thumbnail (item_id, THUMB_SIZE, THUMB_SIZE,
GIMP_PIXBUF_SMALL_CHECKS);
break;
case ATT_LAYER:
item_name = gimp_item_get_name (item_id);
header = g_strdup_printf ("Layer");
role = g_strdup_printf ("gimp-layer-attributes-dialog");
pixbuf = gimp_drawable_get_thumbnail (item_id, THUMB_SIZE, THUMB_SIZE,
GIMP_PIXBUF_SMALL_CHECKS);
break;
default:
item_name = g_strdup_printf ("unknown");
header = g_strdup_printf ("Unknown");
role = g_strdup_printf ("gimp-attributes-dialog");
pixbuf = NULL;
break;
}
title = g_strdup_printf ("Attributes: %s", item_name);
builder = gtk_builder_new ();
ui_file = g_build_filename (gimp_data_directory (),
"ui", "plug-ins", "plug-in-attributes.ui", NULL);
if (! gtk_builder_add_from_file (builder, ui_file, &error))
{
g_printerr ("Error occured while loading UI file!\n");
g_printerr ("Message: %s\n", error->message);
g_clear_error (&error);
g_free (ui_file);
g_object_unref (builder);
return FALSE;
}
g_free (ui_file);
dialog = gimp_dialog_new (title,
role,
NULL, 0,
gimp_standard_help_func, PLUG_IN_HELP,
_("_Export XMP..."), RESPONSE_EXPORT,
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
NULL);
gps_button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Show GPS..."), RESPONSE_GPS);
gtk_widget_set_sensitive (GTK_WIDGET (gps_button), FALSE);
g_signal_connect (dialog, "response",
G_CALLBACK (attributes_dialog_response),
metadata);
g_signal_connect (dialog, "destroy",
G_CALLBACK (gtk_main_quit),
NULL);
g_free (title);
g_free (role);
gtk_window_set_default_size (GTK_WINDOW (dialog),
650,
550);
gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
RESPONSE_GPS,
RESPONSE_EXPORT,
GTK_RESPONSE_CLOSE,
-1);
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
attributes_vbox = GTK_WIDGET (gtk_builder_get_object (builder,
"attributes-vbox"));
gtk_container_set_border_width (GTK_CONTAINER (attributes_vbox), 2);
gtk_box_pack_start (GTK_BOX (content_area), attributes_vbox, TRUE, TRUE, 0);
label_header = GTK_WIDGET (gtk_builder_get_object (builder, "label-header"));
gimp_label_set_attributes (GTK_LABEL (label_header),
PANGO_ATTR_SCALE, PANGO_SCALE_LARGE,
PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD,
-1);
gtk_label_set_text (GTK_LABEL (label_header), header);
label_info = GTK_WIDGET (gtk_builder_get_object (builder, "label-info"));
gimp_label_set_attributes (GTK_LABEL (label_info),
PANGO_ATTR_SCALE, PANGO_SCALE_SMALL,
-1);
gtk_label_set_text (GTK_LABEL (label_info), item_name);
g_free (header);
if (pixbuf)
{
GtkWidget *image;
thumb_box = GTK_WIDGET (gtk_builder_get_object (builder, "thumb-box"));
if (thumb_box)
{
image = gtk_image_new_from_pixbuf (pixbuf);
gtk_box_pack_end (GTK_BOX (thumb_box), image, FALSE, FALSE, 0);
gtk_widget_show (image);
}
}
attributes_dialog_set_attributes (metadata, builder);
gtk_widget_show (GTK_WIDGET (dialog));
gtk_main ();
return TRUE;
}
/* private functions */
static void
attributes_dialog_set_attributes (GimpMetadata *metadata,
GtkBuilder *builder)
{
GtkTreeStore *exif_store;
GtkTreeStore *xmp_store;
GtkTreeStore *iptc_store;
GtkTreeView *exif_treeview;
GtkTreeView *xmp_treeview;
GtkTreeView *iptc_treeview;
GtkWidget *attributes_notebook;
GList *iter_list = NULL;
GimpAttribute *attribute = NULL;
gboolean gps_lat = FALSE;
gboolean gps_lon = FALSE;
exif_store = GTK_TREE_STORE (gtk_builder_get_object (builder,
"exif-treestore"));
xmp_store = GTK_TREE_STORE (gtk_builder_get_object (builder,
"xmp-treestore"));
iptc_store = GTK_TREE_STORE (gtk_builder_get_object (builder,
"iptc-treestore"));
exif_treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder,
"exif-treeview"));
xmp_treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder,
"xmp-treeview"));
iptc_treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder,
"iptc-treeview"));
attributes_notebook = GTK_WIDGET (gtk_builder_get_object (builder,
"attributes-notebook"));
gimp_metadata_iter_init (metadata, &iter_list);
while (gimp_metadata_iter_next (metadata, &attribute, &iter_list))
{
const gchar *name;
const gchar *type;
const gchar *ifd;
const gchar *tag;
const gchar *value;
const gchar *tag_sorted;
gchar *value_utf;
GtkTreeIter *parent = NULL;
GtkTreeIter *iter = g_slice_new (GtkTreeIter);
name = gimp_attribute_get_name (attribute);
type = gimp_attribute_get_attribute_type (attribute);
ifd = gimp_attribute_get_attribute_ifd (attribute);
tag = gimp_attribute_get_attribute_tag (attribute);
tag_sorted = gimp_attribute_get_sortable_name (attribute);
value = gimp_attribute_get_interpreted_string (attribute);
if (! g_utf8_validate (value, -1, NULL))
value_utf = g_locale_to_utf8 (value, -1, NULL, NULL, NULL);
else
value_utf = g_strdup (value);
parent = attributes_get_parent (type, ifd);
if (! g_strcmp0 (name, "Exif.GPSInfo.GPSLatitude"))
{
gps_lat = TRUE;
gps_latitude = gimp_attribute_get_gps_degree (attribute);
if (gps_latitude < 0.0 && !gps_latitude_ref)
{
gps_latitude = gps_latitude * -1.0;
gps_latitude_ref = "S";
}
}
if (! g_strcmp0 (name, "Exif.GPSInfo.GPSLatitudeRef"))
{
gps_latitude_ref = gimp_attribute_get_string (attribute);
}
if (! g_strcmp0 (name, "Exif.GPSInfo.GPSLongitude"))
{
gps_lon = TRUE;
gps_longitude = gimp_attribute_get_gps_degree (attribute);
if (gps_longitude < 0.0 && !gps_longitude_ref)
{
gps_longitude = gps_longitude * -1.0;
gps_longitude_ref = "W";
}
}
if (! g_strcmp0 (name, "Exif.GPSInfo.GPSLongitudeRef"))
{
gps_longitude_ref = gimp_attribute_get_string (attribute);
}
if (gps_lat && gps_lon)
{
gtk_widget_set_sensitive (gps_button, TRUE);
gps_lat = FALSE;
gps_lon = FALSE;
}
switch (gimp_attribute_get_tag_type (attribute))
{
case TAG_EXIF:
{
gtk_tree_store_append (exif_store, iter, parent);
if (!parent)
{
GtkTreeIter child;
gtk_tree_store_set (exif_store, iter,
C_IFD, ifd,
C_TAG, "",
C_VALUE, "",
C_SORT, "",
-1);
parent = iter;
gtk_tree_store_append (exif_store, &child, parent);
gtk_tree_store_set (exif_store, &child,
C_IFD, "",
C_TAG, tag,
C_VALUE, value_utf,
C_SORT, tag_sorted,
-1);
attributes_add_parent (type, ifd, parent);
}
else
{
gtk_tree_store_set (exif_store, iter,
C_IFD, "",
C_TAG, tag,
C_VALUE, value_utf,
C_SORT, tag_sorted,
-1);
}
}
break;
case TAG_XMP:
{
gtk_tree_store_append (xmp_store, iter, parent);
if (!parent)
{
GtkTreeIter child;
gtk_tree_store_set (xmp_store, iter,
C_IFD, ifd,
C_TAG, "",
C_VALUE, "",
C_SORT, "",
-1);
parent = iter;
gtk_tree_store_append (xmp_store, &child, parent);
gtk_tree_store_set (xmp_store, &child,
C_IFD, "",
C_TAG, tag,
C_VALUE, value_utf,
C_SORT, tag_sorted,
-1);
attributes_add_parent (type, ifd, parent);
}
else
{
gtk_tree_store_set (xmp_store, iter,
C_IFD, "",
C_TAG, tag,
C_VALUE, value_utf,
C_SORT, tag_sorted,
-1);
}
}
break;
case TAG_IPTC:
{
gtk_tree_store_append (iptc_store, iter, parent);
if (!parent)
{
GtkTreeIter child;
gtk_tree_store_set (iptc_store, iter,
C_IFD, ifd,
C_TAG, "",
C_VALUE, "",
C_SORT, "",
-1);
parent = iter;
gtk_tree_store_append (iptc_store, &child, parent);
gtk_tree_store_set (iptc_store, &child,
C_IFD, "",
C_TAG, tag,
C_VALUE, value_utf,
C_SORT, tag_sorted,
-1);
attributes_add_parent (type, ifd, parent);
}
else
{
gtk_tree_store_set (iptc_store, iter,
C_IFD, "",
C_TAG, tag,
C_VALUE, value_utf,
C_SORT, tag_sorted,
-1);
}
}
break;
default:
{
GtkTreeStore *treestore;
GtkTreeIter iter;
treestore = attributes_notebook_page_get (attributes_notebook, type);
gtk_tree_store_append (treestore, &iter, NULL);
gtk_tree_store_set (treestore, &iter,
C_IFD, "",
C_TAG, name,
C_VALUE, value_utf,
-1);
}
break;
}
}
gtk_tree_view_expand_all (exif_treeview);
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(exif_store),
C_SORT, GTK_SORT_ASCENDING);
gtk_tree_view_expand_all (xmp_treeview);
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(xmp_store),
C_SORT, GTK_SORT_ASCENDING);
gtk_tree_view_expand_all (iptc_treeview);
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(iptc_store),
C_SORT, GTK_SORT_ASCENDING);
}
static GtkTreeIter *
attributes_get_parent (const gchar *type, const gchar *name)
{
gchar *key;
gchar *lowchar;
GtkTreeIter *iter;
gpointer *data;
key = g_strdup_printf ("%s.%s", type, name);
lowchar = g_ascii_strdown (key, -1);
g_free (key);
data = g_hash_table_lookup (ifd_table, (gpointer) lowchar);
g_free (lowchar);
if (data)
{
iter = (GtkTreeIter *) data;
return iter;
}
else
{
return NULL;
}
}
static void
attributes_add_parent (const gchar *type, const gchar *name, GtkTreeIter *iter)
{
gchar *key;
gchar *lowchar;
key = g_strdup_printf ("%s.%s", type, name);
lowchar = g_ascii_strdown (key, -1);
g_free (key);
g_hash_table_insert (ifd_table, (gpointer) lowchar, (gpointer) iter);
}
static GtkTreeStore *
attributes_notebook_page_get (GtkWidget *notebook,
const gchar *name)
{
GtkWidget *scrolledwindow;
GtkWidget *treeview;
gchar *lowchar;
gpointer *data;
GtkTreeStore *treestore;
lowchar = g_ascii_strdown (name, -1);
data = g_hash_table_lookup (tab_table, (gpointer) lowchar);
if (data)
{
treestore = (GtkTreeStore *) data;
g_free (lowchar);
}
else
{
treeview = attributes_treeview_new ();
scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_show (scrolledwindow);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_SHADOW_IN);
gtk_widget_show (treeview);
gtk_container_add (GTK_CONTAINER (scrolledwindow), treeview);
gtk_tree_view_set_enable_search (GTK_TREE_VIEW (treeview), FALSE);
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
scrolledwindow,
gtk_label_new (name));
treestore = GTK_TREE_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)));
g_hash_table_insert (tab_table, (gpointer) lowchar, (gpointer) treestore);
}
return treestore;
}
static GtkWidget *
attributes_treeview_new (void)
{
GtkWidget *treeview;
GtkTreeStore *treestore;
GtkCellRenderer *ifd_renderer;
GtkCellRenderer *tag_renderer;
GtkCellRenderer *val_renderer;
GtkTreeViewColumn *ifd_column;
GtkTreeViewColumn *tag_column;
GtkTreeViewColumn *val_column;
ifd_renderer = gtk_cell_renderer_text_new ();
tag_renderer = gtk_cell_renderer_text_new ();
val_renderer = gtk_cell_renderer_text_new ();
treestore = gtk_tree_store_new (NUM_COL, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
treeview = gtk_tree_view_new ();
gtk_tree_view_set_model(GTK_TREE_VIEW (treeview), GTK_TREE_MODEL(treestore));
ifd_column = gtk_tree_view_column_new_with_attributes ("", ifd_renderer, "text", C_IFD, NULL);
tag_column = gtk_tree_view_column_new_with_attributes ("Tag", tag_renderer, "text", C_TAG, NULL);
val_column = gtk_tree_view_column_new_with_attributes ("Value", val_renderer, "text", C_VALUE, NULL);
gtk_tree_view_column_set_resizable (ifd_column, TRUE);
gtk_tree_view_column_set_resizable (tag_column, TRUE);
gtk_tree_view_column_set_resizable (val_column, TRUE);
gtk_tree_view_insert_column (GTK_TREE_VIEW (treeview), ifd_column, -1);
gtk_tree_view_insert_column (GTK_TREE_VIEW (treeview), tag_column, -1);
gtk_tree_view_insert_column (GTK_TREE_VIEW (treeview), val_column, -1);
return treeview;
}
/* select file to export */
static void
attributes_file_export_dialog (GtkWidget *parent,
GimpMetadata *metadata)
{
static GtkWidget *dlg = NULL;
gchar *suggest_file;
// GTK_WINDOW (parent),
suggest_file = g_strdup_printf ("%s.xmp", item_name);
if (! dlg)
{
dlg = gtk_file_chooser_dialog_new (_("Export XMP to File"),
GTK_WINDOW (parent),
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_OK,
NULL);
gtk_dialog_set_alternative_button_order (GTK_DIALOG (dlg),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK);
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dlg),
TRUE);
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dlg), suggest_file);
g_signal_connect (dlg, "destroy",
G_CALLBACK (gtk_widget_destroyed),
&dlg);
g_signal_connect (dlg, "response",
G_CALLBACK (attributes_export_dialog_response),
metadata);
g_free (suggest_file);
}
gtk_window_present (GTK_WINDOW (dlg));
}
/* call default browser for google maps */
static void
attributes_show_gps (GtkWidget *parent,
GimpMetadata *metadata)
{
GError *error = NULL;
gchar *uri = NULL;
gchar lat_buf[G_ASCII_DTOSTR_BUF_SIZE];
gchar lon_buf[G_ASCII_DTOSTR_BUF_SIZE];
if (!g_strcmp0 (gps_latitude_ref, "S"))
gps_latitude = gps_latitude * -1.0;
if (!g_strcmp0 (gps_longitude_ref, "W"))
gps_longitude = gps_longitude * -1.0;
g_ascii_formatd (lat_buf, G_ASCII_DTOSTR_BUF_SIZE, "%.6f",
gps_latitude);
g_ascii_formatd (lon_buf, G_ASCII_DTOSTR_BUF_SIZE, "%.6f",
gps_longitude);
uri = g_strdup_printf ("http://maps.google.com?q=%s,%s&z=15",
lat_buf,
lon_buf);
g_app_info_launch_default_for_uri (uri, NULL, &error);
if (error)
{
attributes_message_dialog (GTK_MESSAGE_ERROR, GTK_WINDOW (parent),
_("GPS failure"),
error->message);
}
}
/* save XMP metadata to a file (only XMP, nothing else) */
static void
attributes_export_dialog_response (GtkWidget *dlg,
gint response_id,
gpointer data)
{
GimpMetadata *metadata = (GimpMetadata *) data;
g_return_if_fail (metadata != NULL);
if (response_id == GTK_RESPONSE_OK)
{
GString *buffer;
const gchar *xmp_data = NULL;
gchar *filename = NULL;
int fd;
xmp_data = gimp_metadata_to_xmp_packet (metadata, "file/xmp");
if (!xmp_data)
{
attributes_message_dialog (GTK_MESSAGE_ERROR, GTK_WINDOW (dlg),
_("XMP creation failed"),
_("Cannot create xmp packet"));
return;
}
buffer = g_string_new (xmp_data);
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg));
fd = g_open (filename, O_CREAT | O_TRUNC | O_WRONLY | _O_BINARY, 0666);
if (fd < 0)
{
attributes_message_dialog (GTK_MESSAGE_ERROR, GTK_WINDOW (dlg),
_("Open failed"),
_("Cannot create file"));
g_string_free (buffer, TRUE);
g_free (filename);
return;
}
if (write (fd, buffer->str, buffer->len) < 0)
{
attributes_message_dialog (GTK_MESSAGE_ERROR, GTK_WINDOW (dlg),
_("Save failed"),
_("Some error occurred while saving"));
g_string_free (buffer, TRUE);
g_free (filename);
return;
}
if (close (fd) < 0)
{
attributes_message_dialog (GTK_MESSAGE_ERROR, GTK_WINDOW (dlg),
_("Save failed"),
_("Could not close the file"));
g_string_free (buffer, TRUE);
g_free (filename);
return;
}
g_string_free (buffer, TRUE);
g_free (filename);
}
gtk_widget_destroy (dlg); /* FIXME: destroy or unmap? */
}
/* show a transient message dialog */
static void
attributes_message_dialog (GtkMessageType type,
GtkWindow *parent,
const gchar *title,
const gchar *message)
{
GtkWidget *dlg;
dlg = gtk_message_dialog_new (parent, 0, type, GTK_BUTTONS_OK, "%s", message);
if (title)
gtk_window_set_title (GTK_WINDOW (dlg), title);
gtk_window_set_role (GTK_WINDOW (dlg), "metadata-message");
gtk_dialog_run (GTK_DIALOG (dlg));
gtk_widget_destroy (dlg);
}

467
plug-ins/common/iptc.c Normal file
View File

@@ -0,0 +1,467 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* iptc.c
* Copyright (C) 2013 Hartmut Kuhse
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include <gexiv2/gexiv2.h>
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#include "libgimp/stdplugins-intl.h"
#define PLUG_IN_IMAGE_PROC "plug-in-image-iptc-editor"
#define PLUG_IN_LAYER_PROC "plug-in-layer-iptc-editor"
#define PLUG_IN_HELP "plug-in-iptc-editor"
#define PLUG_IN_BINARY "iptc"
#define THUMB_SIZE 48
#define IPTC_PREFIX "Iptc."
typedef struct
{
gchar *tag;
gchar *mode;
} iptc_tag;
typedef enum
{
ATT_IMAGE,
ATT_LAYER,
ATT_CHANNEL
} AttributesSource;
/* local function prototypes */
static void query (void);
static void run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
static gboolean iptc_dialog (gint32 image_id,
GimpMetadata *metadata,
AttributesSource source,
GtkBuilder *builder);
static void iptc_dialog_set_iptc (GimpMetadata *metadata,
GtkBuilder *builder);
static void iptc_change_iptc (GimpMetadata *metadata,
GtkBuilder *builder);
/* local variables */
const GimpPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
static const iptc_tag const iptc_tags[] =
{
{ "Iptc.Application2.Byline", "single" },
{ "Iptc.Application2.BylineTitle", "single" },
{ "Iptc.Application2.Caption", "multi" },
{ "Iptc.Application2.Category", "single" },
{ "Iptc.Application2.City", "single" },
{ "Iptc.Application2.Copyright", "single" },
{ "Iptc.Application2.CountryName", "single" },
{ "Iptc.Application2.Credit", "single" },
{ "Iptc.Application2.Headline", "multi" },
{ "Iptc.Application2.Keywords", "multi" },
{ "Iptc.Application2.ObjectName", "single" },
{ "Iptc.Application2.ProvinceState", "single" },
{ "Iptc.Application2.Source", "single" },
{ "Iptc.Application2.SpecialInstructions", "multi" },
{ "Iptc.Application2.SubLocation", "single" },
{ "Iptc.Application2.SuppCategory", "multi" },
{ "Iptc.Application2.TransmissionReference", "single" },
{ "Iptc.Application2.Urgency", "single" },
{ "Iptc.Application2.Writer", "single" }
};
/* functions */
MAIN ()
static void
query (void)
{
static const GimpParamDef image_attribs_args[] =
{
{ GIMP_PDB_INT32, "run-mode", "Run mode { RUN-INTERACTIVE (0) }" },
{ GIMP_PDB_IMAGE, "image", "Input image" }
};
static const GimpParamDef layer_attribs_args[] =
{
{ GIMP_PDB_INT32, "run-mode", "Run mode { RUN-INTERACTIVE (0) }" },
{ GIMP_PDB_IMAGE, "image", "Input image" },
{ GIMP_PDB_LAYER, "layer", "Input layer" }
};
gimp_install_procedure (PLUG_IN_IMAGE_PROC,
N_("View and edit IPTC data"),
"View and edit IPTC information attached to the "
"current image. This iptc will be saved in the "
"file, depending on the output file format.",
"Hartmut Kuhse",
"Hartmut Kuhse",
"2014",
N_("Edit IPTC Metadata"),
"*",
GIMP_PLUGIN,
G_N_ELEMENTS (image_attribs_args), 0,
image_attribs_args, NULL);
gimp_plugin_menu_register (PLUG_IN_IMAGE_PROC, "<Image>/Image");
gimp_install_procedure (PLUG_IN_LAYER_PROC,
N_("View and edit IPTC data"),
"View and edit IPTC information attached to the "
"current layer. This iptc will be saved in the "
"xcf file.",
"Hartmut Kuhse",
"Hartmut Kuhse",
"2014",
N_("Edit layers IPTC Metadata"),
"*",
GIMP_PLUGIN,
G_N_ELEMENTS (layer_attribs_args), 0,
layer_attribs_args, NULL);
gimp_plugin_menu_register (PLUG_IN_LAYER_PROC, "<Layers>");
}
static void
run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals)
{
GimpMetadata *metadata;
GtkBuilder *builder;
AttributesSource source;
gint32 item_ID;
static GimpParam values[1];
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
*nreturn_vals = 1;
*return_vals = values;
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
INIT_I18N();
gimp_ui_init (PLUG_IN_BINARY, TRUE);
if (! strcmp (name, PLUG_IN_IMAGE_PROC))
{
item_ID = param[1].data.d_image;
metadata = gimp_image_get_metadata (item_ID);
source = ATT_IMAGE;
status = GIMP_PDB_SUCCESS;
}
else if (! strcmp (name, PLUG_IN_LAYER_PROC))
{
item_ID = param[2].data.d_layer;
metadata = gimp_item_get_metadata (item_ID);
source = ATT_LAYER;
status = GIMP_PDB_SUCCESS;
}
else
{
status = GIMP_PDB_CALLING_ERROR;
}
if (! metadata)
{
metadata = gimp_metadata_new();
}
builder = gtk_builder_new ();
if (status == GIMP_PDB_SUCCESS && iptc_dialog (item_ID, metadata, source, builder))
{
iptc_change_iptc (metadata, builder);
if (! strcmp (name, PLUG_IN_IMAGE_PROC))
{
gimp_image_set_metadata (item_ID, metadata);
}
else if (! strcmp (name, PLUG_IN_LAYER_PROC))
{
gimp_item_set_metadata (item_ID, metadata);
}
status = GIMP_PDB_SUCCESS;
}
else
{
status = GIMP_PDB_CALLING_ERROR;
}
g_object_unref (metadata);
values[0].data.d_status = status;
}
static gboolean
iptc_dialog (gint32 item_id,
GimpMetadata *metadata,
AttributesSource source,
GtkBuilder *builder)
{
GtkWidget *dialog;
GtkWidget *iptc_vbox;
GtkWidget *content_area;
GdkPixbuf *pixbuf;
GtkWidget *label_header;
GtkWidget *label_info;
GtkWidget *thumb_box;
gchar *ui_file;
gchar *title;
gchar *fname;
gchar *header;
gchar *role;
GError *error = NULL;
gboolean run;
switch (source)
{
case ATT_IMAGE:
fname = gimp_image_get_name (item_id);
header = g_strdup_printf ("Image");
title = g_strdup_printf ("Image: %s", fname);
role = g_strdup_printf ("gimp-image-iptc-dialog");
pixbuf = gimp_image_get_thumbnail (item_id, THUMB_SIZE, THUMB_SIZE,
GIMP_PIXBUF_SMALL_CHECKS);
break;
case ATT_LAYER:
fname = gimp_item_get_name (item_id);
header = g_strdup_printf ("Layer");
title = g_strdup_printf ("Layer: %s", fname);
role = g_strdup_printf ("gimp-layer-iptc-dialog");
pixbuf = gimp_drawable_get_thumbnail (item_id, THUMB_SIZE, THUMB_SIZE,
GIMP_PIXBUF_SMALL_CHECKS);
break;
default:
fname = g_strdup_printf ("unknown");
header = g_strdup_printf ("Unknown");
title = g_strdup_printf ("Metadata : %s", fname);
role = g_strdup_printf ("gimp-iptc-dialog");
pixbuf = NULL;
break;
}
ui_file = g_build_filename (gimp_data_directory (),
"ui", "plug-ins", "plug-in-iptc.ui", NULL);
if (! gtk_builder_add_from_file (builder, ui_file, &error))
{
g_printerr ("Error occured while loading UI file!\n");
g_printerr ("Message: %s\n", error->message);
g_clear_error (&error);
g_free (ui_file);
g_object_unref (builder);
return FALSE;
}
g_free (ui_file);
dialog = gimp_dialog_new (title,
role,
NULL, 0,
gimp_standard_help_func, PLUG_IN_HELP,
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
GTK_STOCK_OK, GTK_RESPONSE_OK,
NULL);
g_free (title);
g_free (role);
gtk_window_set_default_size (GTK_WINDOW (dialog),
600,
-1);
gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
GTK_RESPONSE_CLOSE,
-1);
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
iptc_vbox = GTK_WIDGET (gtk_builder_get_object (builder,
"iptc-vbox"));
gtk_container_set_border_width (GTK_CONTAINER (iptc_vbox), 2);
gtk_box_pack_start (GTK_BOX (content_area), iptc_vbox, TRUE, TRUE, 0);
label_header = GTK_WIDGET (gtk_builder_get_object (builder, "label-header"));
gimp_label_set_attributes (GTK_LABEL (label_header),
PANGO_ATTR_SCALE, PANGO_SCALE_LARGE,
PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD,
-1);
gtk_label_set_text (GTK_LABEL (label_header), header);
label_info = GTK_WIDGET (gtk_builder_get_object (builder, "label-info"));
gimp_label_set_attributes (GTK_LABEL (label_info),
PANGO_ATTR_SCALE, PANGO_SCALE_SMALL,
-1);
gtk_label_set_text (GTK_LABEL (label_info), fname);
g_free (header);
g_free (fname);
if (pixbuf)
{
GtkWidget *image;
thumb_box = GTK_WIDGET (gtk_builder_get_object (builder, "thumb-box"));
if (thumb_box)
{
image = gtk_image_new_from_pixbuf (pixbuf);
gtk_box_pack_end (GTK_BOX (thumb_box), image, FALSE, FALSE, 0);
gtk_widget_show (image);
}
}
iptc_dialog_set_iptc (metadata, builder);
run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
return run;
}
/* private functions */
static void
iptc_dialog_set_iptc (GimpMetadata *metadata,
GtkBuilder *builder)
{
gchar *value;
gint i;
for (i = 0; i < G_N_ELEMENTS (iptc_tags); i++)
{
GimpAttribute *attribute = NULL;
GtkWidget *widget = NULL;
attribute = gimp_metadata_get_attribute (metadata, iptc_tags[i].tag);
widget = GTK_WIDGET (gtk_builder_get_object (builder, iptc_tags[i].tag));
if (attribute && widget)
{
value = gimp_attribute_get_string (attribute);
if (GTK_IS_ENTRY (widget))
{
GtkEntry *entry_widget = GTK_ENTRY (widget);
gtk_entry_set_text (entry_widget, value);
}
else if (GTK_IS_TEXT_VIEW (widget))
{
GtkTextView *text_view = GTK_TEXT_VIEW (widget);
GtkTextBuffer *buffer;
buffer = gtk_text_view_get_buffer (text_view);
gtk_text_buffer_set_text (buffer, value, -1);
}
g_free (value);
}
}
}
static void
iptc_change_iptc (GimpMetadata *metadata,
GtkBuilder *builder)
{
gint i;
for (i = 0; i < G_N_ELEMENTS (iptc_tags); i++)
{
GimpAttribute *attribute;
GObject *object = gtk_builder_get_object (builder,
iptc_tags[i].tag);
if (! strcmp ("single", iptc_tags[i].mode))
{
GtkEntry *entry = GTK_ENTRY (object);
const gchar *text = gtk_entry_get_text (entry);
if (strcmp ("", text))
{
attribute = gimp_attribute_new_string (iptc_tags[i].tag, (gchar *) text, TYPE_UNICODE);
gimp_metadata_add_attribute (metadata, attribute);
}
else
{
gimp_metadata_remove_attribute (metadata, iptc_tags[i].tag);
}
}
else if (!strcmp ("multi", iptc_tags[i].mode))
{
GtkTextView *text_view = GTK_TEXT_VIEW (object);
GtkTextBuffer *buffer;
GtkTextIter start;
GtkTextIter end;
gchar *text;
buffer = gtk_text_view_get_buffer (text_view);
gtk_text_buffer_get_start_iter (buffer, &start);
gtk_text_buffer_get_end_iter (buffer, &end);
text = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
if (strcmp ("", text))
{
attribute = gimp_attribute_new_string (iptc_tags[i].tag, (gchar *) text, TYPE_MULTIPLE);
gimp_metadata_add_attribute (metadata, attribute);
}
else
{
gimp_metadata_remove_attribute (metadata, iptc_tags[i].tag);
}
g_free (text);
}
}
}

View File

@@ -39,7 +39,7 @@
#include "libgimp/stdplugins-intl.h"
static void
static gint32
create_layer (gint32 image_ID,
uint8_t *layer_data,
gint32 position,
@@ -78,6 +78,7 @@ load_image (const gchar *filename,
GError **error)
{
uint8_t *indata = NULL;
gint32 layer;
gsize indatalen;
gint width;
gint height;
@@ -146,8 +147,8 @@ load_image (const gchar *filename,
if (! outdata)
return -1;
create_layer (image_ID, outdata, 0, _("Background"),
width, height);
layer = create_layer (image_ID, outdata, 0, _("Background"),
width, height);
/* Free the image data */
free (outdata);
@@ -268,7 +269,7 @@ load_image (const gchar *filename,
file, NULL);
if (metadata)
{
gimp_image_metadata_load_finish (image_ID, "image/webp",
gimp_image_metadata_load_finish (image_ID, layer, "image/webp",
metadata, GIMP_METADATA_LOAD_ALL,
interactive);
g_object_unref (metadata);

View File

@@ -0,0 +1,400 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkTreeStore" id="exif-treestore">
<columns>
<!-- column-name c-exif-ifd -->
<column type="gchararray"/>
<!-- column-name c-exif-tag -->
<column type="gchararray"/>
<!-- column-name c-exif-value -->
<column type="gchararray"/>
<!-- column-name sortable -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkVBox" id="attributes-vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">2</property>
<child>
<object class="GtkFrame" id="frame1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">out</property>
<child>
<object class="GtkHBox" id="header-hbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">3</property>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="label-header">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">label</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-info">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">label</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="thumb-box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkNotebook" id="attributes-notebook">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="scrollable">True</property>
<child>
<object class="GtkScrolledWindow" id="exif-scroll">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="border_width">6</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="exif-treeview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">exif-treestore</property>
<property name="headers_clickable">False</property>
<property name="expander_column">exif_ifd_column</property>
<property name="rules_hint">True</property>
<property name="search_column">1</property>
<property name="enable_grid_lines">vertical</property>
<property name="enable_tree_lines">True</property>
<child>
<object class="GtkTreeViewColumn" id="exif_ifd_column">
<property name="resizable">True</property>
<property name="title" translatable="yes">Exif IFD</property>
<child>
<object class="GtkCellRendererText" id="exif_ifd_cell_renderer"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="exif_tag_column">
<property name="resizable">True</property>
<property name="title" translatable="yes">Exif Tag</property>
<property name="expand">True</property>
<child>
<object class="GtkCellRendererText" id="exif_tag_renderer_text"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="exif_value_column">
<property name="resizable">True</property>
<property name="title" translatable="yes">Value</property>
<child>
<object class="GtkCellRendererText" id="exif_value_cell_renderer"/>
<attributes>
<attribute name="text">2</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="exif_sort_column">
<property name="sizing">fixed</property>
<property name="min_width">1</property>
<property name="max_width">1</property>
<property name="visible">FALSE</property>
<property name="title" translatable="yes">Sort</property>
<property name="sort_column_id">3</property>
<child>
<object class="GtkCellRendererText" id="exif_sort_cell_renderer"/>
<attributes>
<attribute name="text">3</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="exif">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xpad">4</property>
<property name="ypad">4</property>
<property name="label" translatable="yes">Exif</property>
</object>
<packing>
<property name="tab_expand">True</property>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="xmp-scroll">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="border_width">6</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="xmp-treeview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">xmp-treestore</property>
<property name="headers_clickable">False</property>
<property name="rules_hint">True</property>
<property name="search_column">1</property>
<property name="enable_grid_lines">vertical</property>
<property name="enable_tree_lines">True</property>
<child>
<object class="GtkTreeViewColumn" id="xmp_schema_column">
<property name="resizable">True</property>
<property name="title" translatable="yes">XMP schema</property>
<child>
<object class="GtkCellRendererText" id="xmp_schema_cell_renderer"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="xmp_tag_column">
<property name="resizable">True</property>
<property name="title" translatable="yes">XMP Property</property>
<property name="expand">True</property>
<child>
<object class="GtkCellRendererText" id="xmp_tag_cell_renderer"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="xmp_value_column">
<property name="resizable">True</property>
<property name="title" translatable="yes">Value</property>
<child>
<object class="GtkCellRendererText" id="xmp_value_cell_renderer"/>
<attributes>
<attribute name="text">2</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="xmp_sort_column">
<property name="sizing">fixed</property>
<property name="min_width">1</property>
<property name="max_width">1</property>
<property name="visible">FALSE</property>
<property name="title" translatable="yes">Sort</property>
<property name="sort_column_id">3</property>
<child>
<object class="GtkCellRendererText" id="xmp_sort_cell_renderer"/>
<attributes>
<attribute name="text">3</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="xmp">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xpad">4</property>
<property name="ypad">4</property>
<property name="label" translatable="yes">XMP</property>
</object>
<packing>
<property name="position">1</property>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="iptc-scroll">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="border_width">6</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="iptc-treeview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">iptc-treestore</property>
<property name="headers_clickable">False</property>
<property name="rules_hint">True</property>
<property name="search_column">1</property>
<property name="enable_grid_lines">vertical</property>
<property name="enable_tree_lines">True</property>
<child>
<object class="GtkTreeViewColumn" id="iptc_key_column">
<property name="resizable">True</property>
<property name="title" translatable="yes">IPTC key</property>
<child>
<object class="GtkCellRendererText" id="iptc_key_cell_renderer"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="iptc_tag_column">
<property name="resizable">True</property>
<property name="title" translatable="yes">IPTC Tag</property>
<property name="expand">True</property>
<child>
<object class="GtkCellRendererText" id="iptc_tag_cell_renderer"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="iptc_value_column">
<property name="resizable">True</property>
<property name="title" translatable="yes">Value</property>
<child>
<object class="GtkCellRendererText" id="iptc_value_cell_renderer"/>
<attributes>
<attribute name="text">2</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="iptc_sort_column">
<property name="sizing">fixed</property>
<property name="min_width">1</property>
<property name="max_width">1</property>
<property name="visible">FALSE</property>
<property name="title" translatable="yes">Sort</property>
<property name="sort_column_id">3</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext1"/>
<attributes>
<attribute name="text">3</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="iptc">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xpad">4</property>
<property name="ypad">4</property>
<property name="label" translatable="yes">IPTC</property>
</object>
<packing>
<property name="position">2</property>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<object class="GtkTreeStore" id="iptc-treestore">
<columns>
<!-- column-name c-iptc-ifd -->
<column type="gchararray"/>
<!-- column-name c-iptc-tag -->
<column type="gchararray"/>
<!-- column-name c-iptc-value -->
<column type="gchararray"/>
<!-- column-name sortable -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkTreeStore" id="xmp-treestore">
<columns>
<!-- column-name c-xmp-ifd -->
<column type="gchararray"/>
<!-- column-name c-xmp-tag -->
<column type="gchararray"/>
<!-- column-name c-xmp-value -->
<column type="gchararray"/>
<!-- column-name sortable -->
<column type="gchararray"/>
</columns>
</object>
</interface>

779
plug-ins/ui/plug-in-iptc.ui Normal file
View File

@@ -0,0 +1,779 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="2.24"/>
<!-- interface-naming-policy project-wide -->
<object class="GtkVBox" id="iptc-vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkNotebook" id="iptc-notebook">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkVBox" id="box2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkTable" id="desctable">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="n_rows">8</property>
<property name="n_columns">2</property>
<property name="column_spacing">3</property>
<property name="row_spacing">3</property>
<child>
<object class="GtkLabel" id="l_title">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="xpad">3</property>
<property name="ypad">3</property>
<property name="label" translatable="yes">Title</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="l_author">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="xpad">3</property>
<property name="ypad">3</property>
<property name="label" translatable="yes">Author</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="l_authortitle">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="xpad">3</property>
<property name="ypad">3</property>
<property name="label" translatable="yes">Authortitle</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="l_copyright">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="xpad">3</property>
<property name="ypad">3</property>
<property name="label" translatable="yes">Copyright</property>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="l_caption">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="xpad">3</property>
<property name="ypad">3</property>
<property name="label" translatable="yes">Caption</property>
</object>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="l_captionwriter">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="xpad">3</property>
<property name="ypad">3</property>
<property name="label" translatable="yes">Captionwriter</property>
</object>
<packing>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="l_headline">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="xpad">3</property>
<property name="ypad">3</property>
<property name="label" translatable="yes">Headline</property>
</object>
<packing>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="l_specialinstruct">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="xpad">3</property>
<property name="ypad">3</property>
<property name="label" translatable="yes">Special
Instructions</property>
</object>
<packing>
<property name="top_attach">7</property>
<property name="bottom_attach">8</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="Iptc.Application2.ObjectName">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="Iptc.Application2.Byline">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="Iptc.Application2.BylineTitle">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="Iptc.Application2.Copyright">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="Iptc.Application2.Writer">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="caption_scroll">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTextView" id="Iptc.Application2.Caption">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="headline_scroll">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTextView" id="Iptc.Application2.Headline">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="instruct_scroll">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTextView" id="Iptc.Application2.SpecialInstructions">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">7</property>
<property name="bottom_attach">8</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="iptcdesc">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xpad">2</property>
<property name="ypad">2</property>
<property name="label" translatable="yes">Description</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="box3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkTable" id="table3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="n_rows">4</property>
<property name="n_columns">2</property>
<property name="column_spacing">3</property>
<property name="row_spacing">3</property>
<child>
<object class="GtkLabel" id="l_keywords1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="xpad">3</property>
<property name="ypad">3</property>
<property name="label" translatable="yes">Keywords</property>
</object>
<packing>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="l_category1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="xpad">3</property>
<property name="ypad">3</property>
<property name="label" translatable="yes">Category</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="l_suppcat1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="xpad">3</property>
<property name="ypad">3</property>
<property name="label" translatable="yes">Supplemental
Category</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="l_urgency1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="xpad">3</property>
<property name="ypad">3</property>
<property name="label" translatable="yes">Urgency</property>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow10">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTextView" id="Iptc.Application2.Keywords">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow12">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTextView" id="Iptc.Application2.SuppCategory">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="Iptc.Application2.Urgency">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="Iptc.Application2.Category">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="iptckeys">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xpad">2</property>
<property name="ypad">2</property>
<property name="label" translatable="yes">Keywords/Categories</property>
</object>
<packing>
<property name="position">1</property>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="box4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkTable" id="table4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="n_rows">9</property>
<property name="n_columns">2</property>
<property name="column_spacing">3</property>
<property name="row_spacing">3</property>
<child>
<object class="GtkHSeparator" id="hseparator4">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="l_credit">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="xpad">3</property>
<property name="ypad">3</property>
<property name="label" translatable="yes">Credit</property>
</object>
<packing>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="l_source">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="xpad">3</property>
<property name="ypad">3</property>
<property name="label" translatable="yes">Source</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="Iptc.Application2.Credit">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="Iptc.Application2.Source">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="l_transmission">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="xpad">3</property>
<property name="ypad">3</property>
<property name="label" translatable="yes">Transmission
reference</property>
</object>
<packing>
<property name="top_attach">8</property>
<property name="bottom_attach">9</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="Iptc.Application2.TransmissionReference">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">8</property>
<property name="bottom_attach">9</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="l_city">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="xpad">3</property>
<property name="ypad">3</property>
<property name="label" translatable="yes">City</property>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="Iptc.Application2.City">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="l_sublocation">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="xpad">3</property>
<property name="ypad">3</property>
<property name="label" translatable="yes">Sublocation</property>
</object>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="Iptc.Application2.SubLocation">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="l_province">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="xpad">3</property>
<property name="ypad">3</property>
<property name="label" translatable="yes">Province/State</property>
</object>
<packing>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="Iptc.Application2.ProvinceState">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="l_country">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Country</property>
</object>
<packing>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="Iptc.Application2.CountryName">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
</packing>
</child>
<child>
<object class="GtkHSeparator" id="hseparator2">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="right_attach">2</property>
<property name="top_attach">7</property>
<property name="bottom_attach">8</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="iptccredits">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xpad">2</property>
<property name="ypad">2</property>
<property name="label" translatable="yes">Credits/Origin</property>
</object>
<packing>
<property name="position">2</property>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</interface>