[gimp/gimp-attributes-wip] eek: should have added the class
- From: Hartmut Kuhse <hartmutkuhse src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-attributes-wip] eek: should have added the class
- Date: Tue, 7 Oct 2014 17:47:50 +0000 (UTC)
commit dea69ce5402b9bcbe860a5edcd33da8cc2bb6e7c
Author: Hartmut Kuhse <hk_priv gmx de>
Date: Tue Oct 7 19:47:00 2014 +0200
eek: should have added the class
plug-ins/metainfo/datapage.c | 1224 ++++++++++++++++++++++++++++++++++++++++++
plug-ins/metainfo/datapage.h | 127 +++++
2 files changed, 1351 insertions(+), 0 deletions(-)
---
diff --git a/plug-ins/metainfo/datapage.c b/plug-ins/metainfo/datapage.c
new file mode 100644
index 0000000..663c5de
--- /dev/null
+++ b/plug-ins/metainfo/datapage.c
@@ -0,0 +1,1224 @@
+/* datapage.c - user interface for the metadata editor
+ *
+ * Copyright (C) 2014, Hartmut Kuhse <hatti gimp org>
+ *
+ * This library is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+#include "config.h"
+
+#include <glib.h>
+#include <glib-object.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libgimp/gimp.h>
+#include <libgimp/gimpui.h>
+
+#include "libgimp/stdplugins-intl.h"
+
+#include "datapage.h"
+#include "metainfo-helper.h"
+
+typedef struct _CallbackData CallbackData;
+
+struct _CallbackData {
+ Datapage *datapage;
+ GtkBuilder *builder;
+ gint combo_array_nr;
+};
+
+typedef struct _DatapagePrivate DatapagePrivate;
+
+struct _DatapagePrivate {
+ GHashTable *elements_table;
+ GQueue *current_shown_structure;
+ GQueue *highest_structure;
+ GQueue *combo_signal_handlers;
+};
+
+enum {
+ DATAPAGE_DUMMY_PROPERTY
+};
+
+#define DATAPAGE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_DATAPAGE, DatapagePrivate))
+
+static Datapage* datapage_construct (GType object_type,
+ GtkBuilder *builder);
+static void datapage_set_combo_handler (Datapage *datapage,
+ gint combo_nr,
+ gulong handler_id);
+static gulong datapage_get_combo_handler (Datapage *datapage,
+ gint combo_nr);
+static void datapage_set_curr_shown_structure (Datapage *datapage,
+ gint structure,
+ gint value);
+static gint datapage_get_curr_shown_structure (Datapage *datapage,
+ gint structure);
+static void datapage_set_highest_structure (Datapage *datapage,
+ gint structure,
+ gint value);
+static gint datapage_get_highest_structure (Datapage *datapage,
+ gint structure);
+static void datapage_init_ui (Datapage *datapage,
+ GtkBuilder *builder);
+static void datapage_entry_activate_cb (GtkWidget *widget,
+ gpointer userdata);
+static gboolean datapage_entry_focus_out_cb (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer userdata);
+static void datapage_entry_combo_changed_callback (GtkWidget *combo,
+ gpointer userdata);
+static void datapage_combobox_changed_callback (GtkWidget *combo,
+ gpointer userdata);
+static gboolean datapage_store_in_hash_table (Datapage *datapage,
+ const gchar *entry_name,
+ const gchar *value,
+ gint nr);
+static void datapage_structure_add (GtkButton *button,
+ gpointer userdata);
+static void datapage_structure_remove (GtkButton *button,
+ gpointer userdata);
+static void datapage_structure_save (Datapage *datapage,
+ gint
struct_number);
+static void datapage_set_to_ui (Datapage *datapage,
+ GtkBuilder *builder,
+ gint repaint);
+static void datapage_init_combobox (Datapage *datapage,
+ GtkBuilder *builder);
+static void datapage_set_entry_sensitive (Datapage *datapage,
+ const gchar *struct_name,
+ gboolean sensitive);
+
+static gpointer datapage_parent_class = NULL;
+
+
+static Datapage*
+datapage_construct (GType object_type,
+ GtkBuilder *builder)
+{
+ Datapage *datapage = NULL;
+ datapage = (Datapage*) g_object_new (object_type, NULL);
+ datapage->builder = builder;
+ return datapage;
+}
+
+
+Datapage*
+datapage_new (GtkBuilder *builder)
+{
+ return datapage_construct (TYPE_DATAPAGE,
+ builder);
+}
+
+
+static void
+datapage_class_init (DatapageClass *klass)
+{
+ datapage_parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof(DatapagePrivate));
+}
+
+
+static void
+datapage_instance_init (Datapage *datapage)
+{
+ DatapagePrivate *private = DATAPAGE_GET_PRIVATE (datapage);
+
+ private->elements_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ private->current_shown_structure = g_queue_new ();
+ private->highest_structure = g_queue_new ();
+ private->combo_signal_handlers = g_queue_new ();
+}
+
+
+GType
+datapage_get_type (void)
+{
+ static volatile gsize datapage_type_id__volatile = 0;
+
+ if (g_once_init_enter (&datapage_type_id__volatile))
+ {
+ static const GTypeInfo g_define_type_info =
+ {
+ sizeof (DatapageClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) datapage_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (Datapage),
+ 0,
+ (GInstanceInitFunc) datapage_instance_init,
+ NULL
+ };
+
+ GType datapage_type_id;
+ datapage_type_id = g_type_register_static (G_TYPE_OBJECT,
+ "datapage",
+ &g_define_type_info,
+ 0);
+ g_once_init_leave (&datapage_type_id__volatile, datapage_type_id);
+ }
+
+ return datapage_type_id__volatile;
+}
+
+void
+datapage_set_structure_element (Datapage *datapage,
+ StructureElement *struct_elem,
+ gint structure_element_count)
+{
+ gint i;
+
+ datapage->struct_element = struct_elem;
+ datapage->structure_element_count = structure_element_count;
+
+ for (i = 0; i < structure_element_count; i++)
+ {
+ datapage_set_curr_shown_structure (datapage, i, 0);
+ datapage_set_highest_structure (datapage, i, 0);
+ }
+}
+
+void
+datapage_set_combobox_data (Datapage *datapage,
+ ComboBoxData *combobox_data,
+ gint combobox_data_count,
+ gint max_combobox_entries)
+{
+// gint i, j;
+// const gchar *val_in_combo;
+// ComboBoxData e;
+ datapage->combobox_data = combobox_data;
+ datapage->combobox_data_count = combobox_data_count;
+ datapage->max_combobox_entries = max_combobox_entries;
+
+// for (i = 0; i < combobox_data_count; i++)
+// {
+// for (j = 0; j < max_combobox_entries; j++)
+// {
+// e = combobox_data[(i * max_combobox_entries) + j];
+// val_in_combo = e.val_in_combo;
+// if ( val_in_combo)
+// g_print ("%s\n", val_in_combo);
+// }
+// }
+}
+
+void
+datapage_set_metadata_entry (Datapage *datapage,
+ MetadataEntry *metadata_entry,
+ gint metadata_entry_count)
+{
+ datapage->metadata_entry = metadata_entry;
+ datapage->metadata_entry_count = metadata_entry_count;
+}
+
+static void
+datapage_set_combo_handler (Datapage *datapage,
+ gint combo_nr,
+ gulong handler_id)
+{
+ DatapagePrivate *private = DATAPAGE_GET_PRIVATE(datapage);
+
+ g_queue_push_nth (private->combo_signal_handlers,
+ GINT_TO_POINTER (handler_id),
+ combo_nr);
+}
+
+static gulong
+datapage_get_combo_handler (Datapage *datapage,
+ gint combo_nr)
+{
+ DatapagePrivate *private = DATAPAGE_GET_PRIVATE(datapage);
+
+ return GPOINTER_TO_INT (g_queue_peek_nth (private->combo_signal_handlers,
+ combo_nr));
+}
+
+static void
+datapage_set_curr_shown_structure (Datapage *datapage,
+ gint structure,
+ gint value)
+{
+ DatapagePrivate *private = DATAPAGE_GET_PRIVATE(datapage);
+
+ g_queue_push_nth (private->current_shown_structure,
+ GINT_TO_POINTER (value),
+ structure);
+}
+
+static gint
+datapage_get_curr_shown_structure (Datapage *datapage,
+ gint structure)
+{
+ DatapagePrivate *private = DATAPAGE_GET_PRIVATE(datapage);
+
+ return GPOINTER_TO_INT (g_queue_peek_nth (private->current_shown_structure,
+ structure));
+}
+
+static void
+datapage_set_highest_structure (Datapage *datapage,
+ gint structure,
+ gint value)
+{
+ DatapagePrivate *private = DATAPAGE_GET_PRIVATE(datapage);
+
+ g_queue_push_nth (private->highest_structure,
+ GINT_TO_POINTER (value),
+ structure);
+}
+
+static gint
+datapage_get_highest_structure (Datapage *datapage,
+ gint structure)
+{
+ DatapagePrivate *private = DATAPAGE_GET_PRIVATE(datapage);
+
+ return GPOINTER_TO_INT (g_queue_peek_nth (private->highest_structure,
+ structure));
+}
+
+static void
+datapage_init_ui (Datapage *datapage,
+ GtkBuilder *builder)
+{
+ GObject *obj;
+ gint i;
+
+
+ for (i = 0; i < datapage->metadata_entry_count; i++)
+ {
+ obj = G_OBJECT (get_widget_from_label (builder, datapage->metadata_entry[i].ui_label));
+
+ gtk_label_set_text (GTK_LABEL (obj), datapage->metadata_entry[i].label);
+
+ obj = G_OBJECT (get_widget_from_label (builder, datapage->metadata_entry[i].ui_entry));
+ gtk_widget_set_name (GTK_WIDGET (obj), datapage->metadata_entry[i].ui_entry);
+
+ if (datapage->metadata_entry[i].widget_type == WIDGET_TYPE_ENTRY)
+ {
+ g_signal_connect (GTK_WIDGET (obj), "focus-out-event",
+ G_CALLBACK (datapage_entry_focus_out_cb),
+ datapage);
+ g_signal_connect (GTK_ENTRY (obj), "activate",
+ G_CALLBACK (datapage_entry_activate_cb),
+ datapage);
+ }
+ else if (datapage->metadata_entry[i].widget_type == WIDGET_TYPE_COMBOBOX)
+ {
+ gint array_nr = datapage->metadata_entry[i].number_of_comboarray;
+
+ if (array_nr >= 0)
+ {
+ gulong handler_id;
+ gint i;
+ GtkTreeIter iter;
+ GtkListStore *liststore;
+ gint array_length;
+ CallbackData *callback_data = g_slice_new (CallbackData);
+
+ callback_data->datapage = datapage;
+ callback_data->combo_array_nr = array_nr;
+ callback_data->builder = datapage->builder;
+
+ liststore = GTK_LIST_STORE(gtk_combo_box_get_model (GTK_COMBO_BOX (obj)));
+
+ array_length = datapage->max_combobox_entries;
+
+ for (i = 0; i < array_length; i++) /*get info about structure */
+ {
+ const gchar *val_in_combo = datapage->combobox_data[(array_nr *
datapage->max_combobox_entries) + i].val_in_combo;
+// const gchar *val_in_combo = combobox_data[array_nr][i].val_in_combo;
+
+ if (! val_in_combo)
+ break;
+
+ gtk_list_store_append(liststore, &iter);
+
+ gtk_list_store_set (liststore, &iter,
+ 0, val_in_combo,
+ -1);
+ }
+
+ handler_id = g_signal_connect (obj, "changed",
+ G_CALLBACK (datapage_entry_combo_changed_callback),
+ callback_data);
+ datapage_set_combo_handler (datapage, array_nr, handler_id);
+ }
+ }
+ }
+
+ for (i = 0; i < datapage->structure_element_count; i++) /*get info about structure */
+ {
+ obj = G_OBJECT (get_widget_from_label (builder, datapage->struct_element[i].add_widget));
+ gtk_widget_set_name (GTK_WIDGET (obj), datapage->struct_element[i].add_widget);
+ g_signal_connect (obj, "clicked",
+ G_CALLBACK (datapage_structure_add),
+ datapage);
+
+ obj = G_OBJECT (get_widget_from_label (builder, datapage->struct_element[i].remove_widget));
+ gtk_widget_set_name (GTK_WIDGET (obj), datapage->struct_element[i].remove_widget);
+ g_signal_connect (obj, "clicked",
+ G_CALLBACK (datapage_structure_remove),
+ datapage);
+
+ obj = G_OBJECT (get_widget_from_label (builder, datapage->struct_element[i].struct_combo_widget));
+ gtk_widget_set_name (GTK_WIDGET (obj), datapage->struct_element[i].struct_combo_widget);
+ g_signal_connect (obj, "changed",
+ G_CALLBACK (datapage_combobox_changed_callback),
+ datapage);
+ }
+}
+
+static void
+datapage_entry_activate_cb (GtkWidget *widget,
+ gpointer userdata)
+{
+ Datapage *datapage = (Datapage *) userdata;
+ const gchar *value = gtk_entry_get_text (GTK_ENTRY (widget));
+ const gchar *entry_name = gtk_widget_get_name (GTK_WIDGET (widget));
+
+ datapage_store_in_hash_table (datapage, entry_name, value, 0);
+}
+
+static gboolean
+datapage_entry_focus_out_cb (GtkWidget *widget, GdkEvent *event, gpointer userdata)
+{
+ Datapage *datapage = (Datapage *) userdata;
+ const gchar *value = gtk_entry_get_text (GTK_ENTRY (widget));
+ const gchar *entry_name = gtk_widget_get_name (GTK_WIDGET (widget));
+
+ datapage_store_in_hash_table (datapage, entry_name, value, 0);
+ set_save_attributes_button_sensitive (TRUE);
+
+ return FALSE;
+}
+
+static void
+datapage_entry_combo_changed_callback (GtkWidget *combo,
+ gpointer userdata)
+{
+ CallbackData *callback_data = (CallbackData *) userdata;
+ Datapage *datapage = callback_data->datapage;
+ gint array_nr = callback_data->combo_array_nr;
+ gint index = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
+ const gchar *widget_name;
+ const gchar *value;
+
+ value = datapage->combobox_data[(array_nr * datapage->max_combobox_entries) + index].val_in_tag;
+ widget_name = gtk_widget_get_name (GTK_WIDGET (combo));
+
+ datapage_store_in_hash_table (datapage, widget_name, value, 0);
+ set_save_attributes_button_sensitive (TRUE);
+}
+
+static void
+datapage_combobox_changed_callback (GtkWidget *combo, gpointer userdata)
+{
+ Datapage *datapage = (Datapage *) userdata;
+ GtkComboBox *combobox;
+ gint nr;
+ const gchar *widget_name;
+ gint sct;
+ gint repaint;
+
+ widget_name = gtk_widget_get_name (GTK_WIDGET (combo));
+
+ for (sct = 0; sct < datapage->structure_element_count; sct ++)
+ {
+ if (! g_strcmp0 (widget_name, datapage->struct_element[sct].struct_combo_widget))
+ {
+ datapage_structure_save (datapage, datapage->struct_element[sct].number_of_element);
+ combobox = GTK_COMBO_BOX (get_widget_from_label (datapage->builder,
datapage->struct_element[sct].struct_combo_widget));
+ repaint = datapage->struct_element[sct].number_of_element;
+ break;
+ }
+ }
+
+ nr = gtk_combo_box_get_active (combobox);
+ nr++;
+ datapage_set_curr_shown_structure (datapage, repaint, nr);
+
+ datapage_set_to_ui (datapage, datapage->builder, repaint);
+}
+
+static gboolean
+datapage_store_in_hash_table (Datapage *datapage,
+ const gchar *entry_name,
+ const gchar *value,
+ gint nr)
+{
+ gint i;
+ const gchar *o_tag;
+ gint p;
+ gint number = 0;
+ gboolean success;
+ DatapagePrivate *private;
+
+ g_return_val_if_fail (entry_name != NULL, FALSE);
+
+ private = DATAPAGE_GET_PRIVATE (datapage);
+
+ if (nr > 0)
+ number = nr;
+
+ success = FALSE;
+
+ for (i = 0; i < datapage->metadata_entry_count; i++)
+ {
+ if (! g_strcmp0 (entry_name, datapage->metadata_entry[i].ui_entry))
+ {
+ gchar *new_tag;
+ gchar *nr_string;
+
+ o_tag = datapage->metadata_entry[i].xmp_tag;
+
+ new_tag =g_strdup (o_tag);
+
+ p = string_index_of (new_tag, "[x]", 0); /* is it a structure tag? */
+
+ if (p > -1) /* yes */
+ {
+ gint sct;
+
+ if (number <= 0)
+ {
+ for (sct = 0; sct < datapage->structure_element_count; sct ++)
+ {
+ if (g_strcmp0 (o_tag, datapage->struct_element[sct].struct_tag))
+ {
+ number = datapage_get_curr_shown_structure (datapage,
datapage->struct_element[sct].number_of_element);
+ break;
+ }
+ }
+ }
+
+ nr_string = g_strdup_printf ("[%d]", number);
+ new_tag = string_replace_str (o_tag, "[x]", nr_string);
+
+ g_free (nr_string);
+ if (number <=0 )
+ {
+ g_free (new_tag);
+ return FALSE;
+ }
+ }
+
+ if (value && g_strcmp0 (value, ""))
+ {
+ if (g_hash_table_insert (private->elements_table, (gpointer) g_strdup (new_tag), (gpointer)
g_strdup (value)))
+ success = TRUE;
+ }
+ else
+ {
+ if (g_hash_table_remove (private->elements_table, (gpointer) new_tag))
+ success = TRUE;
+ }
+
+ g_free (new_tag);
+ break;
+ }
+ }
+ return success;
+}
+
+static void
+datapage_structure_add (GtkButton *button,
+ gpointer userdata)
+{
+ gint number_to_add;
+ GtkComboBox *combo;
+ Datapage *datapage = (Datapage *) userdata;
+ GtkListStore *liststore;
+ GtkTreeIter iter;
+ const gchar *widget_name;
+ gchar *line;
+ gint sct;
+ gint repaint;
+
+ widget_name = gtk_widget_get_name (GTK_WIDGET (button));
+
+ for (sct = 0; sct < datapage->structure_element_count; sct ++)
+ {
+ if (! g_strcmp0 (widget_name, datapage->struct_element[sct].add_widget))
+ {
+ datapage_structure_save (datapage, datapage->struct_element[sct].number_of_element);
+
+ number_to_add = datapage_get_highest_structure (datapage,
datapage->struct_element[sct].number_of_element);
+ datapage_set_highest_structure (datapage, datapage->struct_element[sct].number_of_element,
++number_to_add);
+ liststore = GTK_LIST_STORE (get_widget_from_label (datapage->builder,
datapage->struct_element[sct].struct_liststore_widget));
+ combo = GTK_COMBO_BOX (get_widget_from_label (datapage->builder,
datapage->struct_element[sct].struct_combo_widget));
+ line = g_strdup_printf ("%s [%d]", datapage->struct_element[sct].identifier, number_to_add);
+ datapage_set_curr_shown_structure (datapage, datapage->struct_element[sct].number_of_element,
number_to_add);
+
+ repaint = datapage->struct_element[sct].number_of_element;
+
+ g_signal_handlers_block_by_func (G_OBJECT (combo), G_CALLBACK
(datapage_combobox_changed_callback), datapage);
+
+ gtk_list_store_append(liststore, &iter);
+
+ gtk_list_store_set (liststore, &iter,
+ 0, line,
+ -1);
+
+ gtk_combo_box_set_active (combo, number_to_add-1);
+
+ if (number_to_add == 1)
+ datapage_set_entry_sensitive (datapage, datapage->struct_element[sct].struct_tag, TRUE);
+
+ g_signal_handlers_unblock_by_func(G_OBJECT (combo), G_CALLBACK
(datapage_combobox_changed_callback), datapage);
+
+ g_free (line);
+ break;
+ }
+ }
+
+ datapage_set_to_ui (datapage, datapage->builder, repaint);
+}
+
+static void
+datapage_structure_remove (GtkButton *button,
+ gpointer userdata)
+{
+ Datapage *datapage = (Datapage *) userdata;
+ DatapagePrivate *private;
+ GtkListStore *liststore;
+ GHashTableIter iter_remove;
+ gboolean found;
+ gchar *nr_string;
+ gchar *nr_string_new;
+ gpointer key, value;
+ GSList *delete_key_list = NULL;
+ GSList *list;
+ gchar *tag_prefix;
+ gchar *new_key;
+ gint number_to_delete;
+ GtkComboBox *combo;
+ GtkTreeIter combo_iter;
+ const gchar *widget_name;
+ gint sct;
+ gint repaint;
+ gint combo_to_del;
+
+ GHashTable *reorder_table;
+
+ private = DATAPAGE_GET_PRIVATE (datapage);
+
+ reorder_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
+ widget_name = gtk_widget_get_name (GTK_WIDGET (button));
+
+ for (sct = 0; sct < datapage->structure_element_count; sct ++)
+ {
+ if (! g_strcmp0 (widget_name, datapage->struct_element[sct].remove_widget))
+ {
+ gint new_highest;
+
+ number_to_delete = datapage_get_curr_shown_structure (datapage, sct);
+
+ tag_prefix = g_strdup (datapage->struct_element[sct].struct_tag);
+ liststore = GTK_LIST_STORE (get_widget_from_label (datapage->builder,
datapage->struct_element[sct].struct_liststore_widget));
+ combo = GTK_COMBO_BOX (get_widget_from_label (datapage->builder,
datapage->struct_element[sct].struct_combo_widget));
+ combo_to_del = datapage_get_highest_structure (datapage, sct) - 1;
+
+ if (number_to_delete == datapage_get_highest_structure (datapage,
datapage->struct_element[sct].number_of_element))
+ datapage_set_curr_shown_structure (datapage, datapage->struct_element[sct].number_of_element,
number_to_delete - 1);
+ else
+ datapage_set_curr_shown_structure (datapage, datapage->struct_element[sct].number_of_element,
number_to_delete);
+
+ new_highest = datapage_get_highest_structure (datapage, sct);
+ datapage_set_highest_structure (datapage, sct, --new_highest);
+
+ repaint = datapage->struct_element[sct].number_of_element;
+ break;
+ }
+ }
+
+ nr_string = g_strdup_printf ("%s[%d]", tag_prefix, number_to_delete);
+
+ /* remove entries */
+ {
+
+ g_hash_table_iter_init (&iter_remove, private->elements_table);
+ while (g_hash_table_iter_next (&iter_remove, &key, &value))
+ {
+ gchar *tag = (gchar *) key;
+ if (g_str_has_prefix (tag, nr_string))
+ {
+ delete_key_list = g_slist_prepend (delete_key_list, g_strdup (tag));
+ }
+ }
+
+ for (list = delete_key_list; list; list = list->next)
+ {
+ gchar *key = (gchar *) list->data;
+ g_hash_table_remove (private->elements_table, key);
+ }
+
+ g_slist_free_full (delete_key_list, g_free);
+
+ }
+ /* reorder entries */
+
+ found = TRUE;
+
+ {
+ while (found) /* first: element table */
+ {
+ GHashTableIter iter_reorder;
+
+ delete_key_list = NULL;
+ found = FALSE;
+
+ nr_string_new = g_strdup_printf ("%s[%d]", tag_prefix, number_to_delete + 1);
+
+ g_hash_table_iter_init (&iter_reorder, private->elements_table);
+ while (g_hash_table_iter_next (&iter_reorder, &key, &value))
+ {
+ gchar *tag = (gchar *) key;
+ gchar *tag_value = (gchar *) value;
+
+ if (g_str_has_prefix (tag, nr_string_new))
+ {
+ found = TRUE;
+ new_key = string_replace_str (tag, nr_string_new, nr_string);
+ g_hash_table_insert (reorder_table, g_strdup (new_key), g_strdup (tag_value));
+ delete_key_list = g_slist_prepend (delete_key_list, g_strdup (tag));
+ }
+ }
+
+ for (list = delete_key_list; list; list = list->next)
+ {
+ gchar *key = (gchar *) list->data;
+ g_hash_table_remove (private->elements_table, key);
+ }
+ g_slist_free_full (delete_key_list, g_free);
+
+ g_hash_table_iter_init (&iter_reorder, reorder_table);
+ while (g_hash_table_iter_next (&iter_reorder, &key, &value))
+ {
+ gchar *tag = (gchar *) key;
+ gchar *tag_value = (gchar *) value;
+
+ g_hash_table_insert (private->elements_table, g_strdup (tag), g_strdup (tag_value));
+ }
+
+ g_hash_table_remove_all (reorder_table);
+
+ nr_string = g_strdup (nr_string_new);
+ number_to_delete ++;
+ }
+
+ }
+
+ g_free (tag_prefix);
+ g_free (nr_string);
+ g_free (nr_string_new);
+ g_free (new_key);
+
+ g_hash_table_unref (reorder_table);
+
+ g_signal_handlers_block_by_func (G_OBJECT (combo), G_CALLBACK (datapage_combobox_changed_callback),
(gpointer) datapage);
+
+ gtk_combo_box_set_active (combo, combo_to_del);
+ if (gtk_combo_box_get_active_iter (combo, &combo_iter))
+ gtk_list_store_remove (liststore, &combo_iter);
+
+ if (datapage_get_curr_shown_structure (datapage, repaint) == 0)
+ datapage_set_entry_sensitive (datapage, datapage->struct_element[sct].struct_tag, FALSE);
+ else
+ gtk_combo_box_set_active (combo, datapage_get_curr_shown_structure (datapage, repaint) - 1);
+
+ g_signal_handlers_unblock_by_func(G_OBJECT (combo), G_CALLBACK (datapage_combobox_changed_callback),
(gpointer) datapage);
+
+ set_save_attributes_button_sensitive (TRUE);
+
+ datapage_set_to_ui (datapage, datapage->builder, repaint);
+}
+
+static void
+datapage_structure_save (Datapage *datapage,
+ gint struct_number)
+{
+ DatapagePrivate *private;
+ gint i;
+ const gchar *prefix = datapage->struct_element[struct_number].struct_tag;
+
+ private = DATAPAGE_GET_PRIVATE (datapage);
+
+ for (i = 0; i < datapage->metadata_entry_count; i++)
+ {
+ GObject *obj;
+ gchar *tag = NULL;
+ const gchar *o_tag;
+
+ if (datapage_get_curr_shown_structure (datapage, struct_number) > 0)
+ {
+ o_tag = datapage->metadata_entry[i].xmp_tag;
+ if (g_str_has_prefix (o_tag, prefix))
+ {
+ gchar *nr_string;
+
+ nr_string = g_strdup_printf ("[%d]", datapage_get_curr_shown_structure (datapage,
struct_number));
+ tag = string_replace_str (o_tag, "[x]", nr_string);
+
+ obj = get_widget_from_label (datapage->builder, datapage->metadata_entry[i].ui_entry);
+
+ switch (datapage->metadata_entry[i].widget_type)
+ {
+ case WIDGET_TYPE_ENTRY:
+ {
+ gchar *value;
+ value = g_strdup (gtk_entry_get_text (GTK_ENTRY (obj)));
+ if (value && g_strcmp0 (value, ""))
+ g_hash_table_insert (private->elements_table, (gpointer) g_strdup (tag), (gpointer)
g_strdup (value));
+ else
+ g_hash_table_remove (private->elements_table, (gpointer) tag);
+ }
+ break;
+ case WIDGET_TYPE_COMBOBOX:
+ break;
+ default:
+ break;
+ }
+
+ g_free (nr_string);
+ g_free (tag);
+ }
+ }
+ }
+}
+
+static void
+datapage_set_to_ui (Datapage *datapage,
+ GtkBuilder *builder,
+ gint repaint)
+{
+ gint i;
+ gint sct;
+ const gchar *prefix;
+ DatapagePrivate *private;
+
+ private = DATAPAGE_GET_PRIVATE (datapage);
+
+ if (repaint != -1)
+ prefix = datapage->struct_element[repaint].struct_tag;
+ else
+ prefix = NULL;
+
+ for (i = 0; i < datapage->metadata_entry_count; i++)
+ {
+ GObject *obj;
+ const gchar *o_tag;
+ gchar *value = NULL;
+ gchar *new_tag;
+ gint p;
+
+ o_tag = datapage->metadata_entry[i].xmp_tag;
+
+ obj = get_widget_from_label (builder, datapage->metadata_entry[i].ui_entry);
+
+ if (prefix)
+ {
+ if (! g_str_has_prefix (o_tag, prefix))
+ continue;
+ }
+
+ p = string_index_of (o_tag, "[x]", 0); /* is it a structure tag? */
+
+ if (p > -1) /* yes! */
+ {
+ gchar *nr_string;
+
+ if (repaint != -1)
+ {
+ nr_string = g_strdup_printf ("[%d]", datapage_get_curr_shown_structure (datapage, repaint));
+ }
+ else
+ {
+ for (sct = 0; sct < datapage->structure_element_count; sct ++)
+ {
+ if (g_str_has_prefix (o_tag, datapage->struct_element[sct].struct_tag))
+ {
+ nr_string = g_strdup_printf ("[%d]", datapage_get_curr_shown_structure (datapage,
sct));
+ break;
+ }
+ }
+ }
+
+ new_tag = string_replace_str (o_tag, "[x]", nr_string);
+
+ g_free (nr_string);
+ }
+ else
+ {
+ new_tag = g_strdup (o_tag);
+ }
+
+ value = (gchar *) g_hash_table_lookup (private->elements_table, new_tag);
+
+ switch (datapage->metadata_entry[i].widget_type)
+ {
+ case WIDGET_TYPE_ENTRY:
+ {
+ gtk_entry_set_text (GTK_ENTRY (obj), "");
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (value)
+ {
+ switch (datapage->metadata_entry[i].widget_type)
+ {
+ case WIDGET_TYPE_ENTRY:
+ {
+ gtk_entry_set_text (GTK_ENTRY (obj), value);
+ }
+ break;
+ case WIDGET_TYPE_COMBOBOX:
+ {
+ gint combobox_data_counter;
+ gint array_length;
+ gint number_in_comboarray = datapage->metadata_entry[i].number_of_comboarray;
+
+ array_length = datapage->max_combobox_entries;
+
+ for (combobox_data_counter = 0; combobox_data_counter < array_length;
combobox_data_counter++)
+ {
+ const gchar *val_in_tag = datapage->combobox_data[(number_in_comboarray *
datapage->max_combobox_entries) + combobox_data_counter].val_in_tag;
+ if (! val_in_tag)
+ break;
+
+ if (! g_strcmp0 (value, val_in_tag))
+ {
+ gulong handler_id = 0;
+
+ handler_id = datapage_get_combo_handler (datapage, number_in_comboarray);
+
+ g_signal_handler_block (obj,
+ handler_id);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (obj), combobox_data_counter);
+
+ g_signal_handler_unblock (obj,
+ handler_id);
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ g_free (new_tag);
+ }
+}
+
+static void
+datapage_init_combobox (Datapage *datapage,
+ GtkBuilder *builder)
+{
+ GtkListStore *liststore;
+ GtkTreeIter iter;
+ GtkComboBox *combo;
+ gint sct;
+
+ for (sct = 0; sct < datapage->structure_element_count; sct ++)
+ {
+ gchar *line;
+ gint i;
+ gint high;
+ gint active;
+
+ liststore = GTK_LIST_STORE (get_widget_from_label (builder,
datapage->struct_element[sct].struct_liststore_widget));
+ combo = GTK_COMBO_BOX (get_widget_from_label (builder,
datapage->struct_element[sct].struct_combo_widget));
+
+ high = datapage_get_highest_structure (datapage, datapage->struct_element[sct].number_of_element);
+ active = datapage_get_curr_shown_structure (datapage, datapage->struct_element[sct].number_of_element);
+
+ g_signal_handlers_block_by_func (G_OBJECT (combo), G_CALLBACK (datapage_combobox_changed_callback),
datapage);
+
+ for (i = 0; i < high; i++)
+ {
+ line = g_strdup_printf ("%s [%d]",datapage->struct_element[sct].identifier, i + 1);
+
+ gtk_list_store_append(liststore, &iter);
+
+ gtk_list_store_set (liststore, &iter,
+ 0, line,
+ -1);
+ g_free (line);
+ }
+
+ gtk_combo_box_set_active (combo, active-1);
+
+ if (active >= 1)
+ datapage_set_entry_sensitive (datapage, datapage->struct_element[sct].struct_tag, TRUE);
+ else
+ datapage_set_entry_sensitive (datapage, datapage->struct_element[sct].struct_tag, FALSE);
+
+ g_signal_handlers_unblock_by_func(G_OBJECT (combo), G_CALLBACK (datapage_combobox_changed_callback),
datapage);
+
+ }
+}
+
+static void
+datapage_set_entry_sensitive (Datapage *datapage,
+ const gchar *struct_name,
+ gboolean sensitive)
+{
+ gint i;
+
+ for (i = 0; i < datapage->metadata_entry_count; i++)
+ {
+ const gchar *tag;
+ GObject *obj;
+
+ tag = datapage->metadata_entry[i].xmp_tag;
+ if (g_str_has_prefix (tag, struct_name))
+ {
+ obj = G_OBJECT (get_widget_from_label (datapage->builder, datapage->metadata_entry[i].ui_entry));
+ gtk_widget_set_sensitive (GTK_WIDGET (obj), sensitive);
+ }
+ }
+
+}
+
+void
+datapage_read_from_attributes (Datapage *datapage,
+ GimpAttributes **attributes)
+{
+ gint i;
+ gint sct;
+ DatapagePrivate *private;
+
+ g_return_if_fail (*attributes != NULL);
+
+ private = DATAPAGE_GET_PRIVATE (datapage);
+
+ datapage_init_ui (datapage, datapage->builder);
+
+ for (i = 0; i < datapage->metadata_entry_count; i++)
+ {
+ GimpAttribute *attribute = NULL;
+ const gchar *o_tag = NULL;
+ gchar *tag = NULL;
+ gint p;
+ gint counter;
+
+ o_tag = datapage->metadata_entry[i].xmp_tag;
+
+ tag =g_strdup (o_tag);
+
+// if (g_str_has_prefix (tag, "Xmp.plus.ImageCreator"))
+// g_print ("found\n");
+//
+ p = string_index_of (tag, "[x]", 0); /* is it a structure tag? */
+
+ if (p > -1) /* yes! */
+ {
+ gint j;
+ gchar *struct_string = NULL;
+
+ /* check last number */
+
+ struct_string = string_substring (tag, 0, p); /* get structure tag */
+
+ for (j = 0; j < datapage->structure_element_count; j++) /*get info about structure */
+ {
+ if (! g_strcmp0 (struct_string, datapage->struct_element[j].struct_tag)) /* is a structure */
+ {
+ GimpAttribute *struct_attribute = NULL;
+ gint num = datapage_get_highest_structure (datapage,
datapage->struct_element[j].number_of_element);
+
+ counter = 0; /*start the loop */
+
+ while (struct_attribute ||
+ counter == 0 || /* at least once, because counter IS 0 */
+ counter < num) /* at least until the highest structure */
+ {
+ gchar *nr_string = NULL;
+ gchar *new_tag = NULL;
+ gchar *value;
+
+ counter ++;
+ nr_string = g_strdup_printf ("[%d]", counter);
+ new_tag = string_replace_str (tag, "[x]", nr_string);
+
+ struct_attribute = gimp_attributes_get_attribute (*attributes, new_tag);
+
+ if (struct_attribute)
+ {
+ gint sct;
+ value = gimp_attribute_get_string (struct_attribute);
+
+ for (sct = 0; sct < datapage->structure_element_count; sct ++)
+ {
+ if (g_str_has_prefix (new_tag, datapage->struct_element[sct].struct_tag))
+ {
+ datapage_set_highest_structure (datapage,
datapage->struct_element[sct].number_of_element, counter);
+ break;
+ }
+ }
+ g_hash_table_insert (private->elements_table,
+ (gpointer) g_strdup (new_tag),
+ (gpointer) g_strdup (value));
+
+ gimp_attributes_remove_attribute (*attributes, new_tag);
+ g_free (value);
+ }
+ g_free (nr_string);
+ g_free (new_tag);
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ attribute = gimp_attributes_get_attribute (*attributes, tag);
+ if (attribute)
+ {
+ gchar *value = gimp_attribute_get_string (attribute);
+ g_hash_table_insert (private->elements_table,
+ (gpointer) g_strdup (datapage->metadata_entry[i].xmp_tag),
+ (gpointer) g_strdup (value));
+
+ gimp_attributes_remove_attribute (*attributes, datapage->metadata_entry[i].xmp_tag);
+ g_free (value);
+ }
+ }
+ g_free (tag);
+ }
+
+ for (sct = 0; sct < datapage->structure_element_count; sct ++)
+ {
+ if (datapage_get_highest_structure (datapage, sct) > 0)
+ datapage_set_curr_shown_structure (datapage, sct, 1);
+ else
+ datapage_set_curr_shown_structure (datapage, sct, 0);
+ }
+
+ datapage_init_combobox (datapage, datapage->builder);
+
+ datapage_set_to_ui (datapage, datapage->builder,
+ -1); /* all */
+}
+
+void
+datapage_save_to_attributes (Datapage *datapage, GimpAttributes **attributes)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+ DatapagePrivate *private;
+
+ private = DATAPAGE_GET_PRIVATE (datapage);
+
+ g_hash_table_iter_init (&iter, private->elements_table);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ GimpAttribute *attribute = NULL;
+ gchar *tag = (gchar *) key;
+ gchar *value = NULL;
+ gint p;
+ gint sct;
+ gint i;
+
+ value = (gchar *) g_hash_table_lookup (private->elements_table, (gpointer) tag);
+ attribute = gimp_attribute_new_string (tag, value, TYPE_ASCII);
+
+ if (attribute)
+ {
+ p = string_index_of (tag, "[", 0); /* is it a structure tag? */
+
+ if (p > -1) /* yes! */
+ {
+
+ for (sct = 0; sct < datapage->structure_element_count; sct ++)
+ {
+ if (g_str_has_prefix (tag, datapage->struct_element[sct].struct_tag))
+ {
+ gimp_attribute_set_structure_type (attribute,
datapage->struct_element[sct].struct_type);
+ break;
+ }
+ }
+ }
+
+ for (i = 0; i < datapage->metadata_entry_count; i++)
+ {
+ gchar *t_tag;
+ gint p1;
+ gint p2;
+
+ p1 = string_index_of (tag, "[", 0); /* is it a structure tag? */
+ if (p > -1) /* yes! */
+ {
+ gchar *t1;
+ gchar *t2;
+ gint l;
+
+ p2 = string_index_of (tag, "]", p1);
+
+ l = strlen (tag);
+
+ t1 = string_substring (tag, 0, p);
+ t2 = string_substring (tag, p2 + 1, l - (p2 + 1));
+
+ t_tag = g_strdup_printf ("%s[x]%s", t1, t2);
+ }
+ else
+ {
+ t_tag = g_strdup (tag);
+ }
+
+
+ if (! g_strcmp0 (t_tag, datapage->metadata_entry[i].xmp_tag))
+ {
+ if (datapage->metadata_entry[i].number_of_comboarray > -1)
+ {
+ gint combobox_data_counter;
+ gint array_length;
+ gint number_in_comboarray = datapage->metadata_entry[i].number_of_comboarray;
+
+ array_length = datapage->max_combobox_entries;
+
+ for (combobox_data_counter = 0; combobox_data_counter < array_length;
combobox_data_counter++)
+ {
+ const gchar *val_in_tag = datapage->combobox_data[number_in_comboarray *
datapage->max_combobox_entries + combobox_data_counter].val_in_tag;
+ const gchar *interpreted_val;
+
+ if (! val_in_tag)
+ break;
+
+ if (! g_strcmp0 (value, val_in_tag))
+ {
+ interpreted_val = datapage->combobox_data[number_in_comboarray *
datapage->max_combobox_entries + combobox_data_counter].val_in_combo;
+ gimp_attribute_set_interpreted_string (attribute, interpreted_val);
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ gimp_attributes_add_attribute (*attributes, attribute);
+ }
+ }
+}
diff --git a/plug-ins/metainfo/datapage.h b/plug-ins/metainfo/datapage.h
new file mode 100644
index 0000000..d27f569
--- /dev/null
+++ b/plug-ins/metainfo/datapage.h
@@ -0,0 +1,127 @@
+/* page.h
+ *
+ * Copyright (C) 2014, Hartmut Kuhse <hatti gimp org>
+ *
+ * This library is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+// int (*arr)[8];
+
+#ifndef __PAGE_H__
+#define __PAGE_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#define TYPE_DATAPAGE (datapage_get_type ())
+#define DATAPAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_DATAPAGE, datapage))
+#define DATAPAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_DATAPAGE, datapageClass))
+#define IS_DATAPAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_DATAPAGE))
+#define IS_DATAPAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_DATAPAGE))
+#define DATAPAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_DATAPAGE, datapageClass))
+
+typedef enum
+{
+ WIDGET_TYPE_ENTRY,
+ WIDGET_TYPE_COMBOBOX
+} WidgetType;
+
+typedef enum
+{
+ LIST_TYPE_NONE,
+ LIST_TYPE_SEQ,
+ LIST_TYPE_BAG,
+ LIST_TYPE_LANGALT
+} ListType;
+
+typedef struct _ComboBoxData ComboBoxData;
+
+struct _ComboBoxData
+{
+ const gchar *val_in_combo; /* translateable - value shown in the combobox */
+ const gchar *val_in_tag; /* value saved as tag value */
+};
+
+
+typedef struct _MetadataEntry MetadataEntry;
+
+struct _MetadataEntry
+{
+ gchar *label; /* translateable - label of the widget */
+ const gchar *ui_label; /* name of the label widget in GtkBuilder ui file */
+ const gchar *ui_entry; /* name of the entry widget in GtkBuilder ui file */
+ const gchar *xmp_tag; /* xmp tag, saved in GimpAttribute.name */
+ WidgetType widget_type; /* type of entry widget in GtkBuilder ui : GtkEntry
or GtkComboBox */
+ gint number_of_comboarray; /*number of entry in ComboBoxData - array. Only valid
for combobox entries */
+};
+
+typedef struct _StructureElement StructureElement;
+
+struct _StructureElement
+{
+ gint number_of_element; /* simply the number, corresponding to
STRUCTURES_ON_PAGE */
+ const gchar *identifier; /* translateble - identifier for combobox entries */
+ const gchar *struct_tag; /* structure tag without array number */
+ GimpAttributeStructureType struct_type; /* type of structure, gexiv2 cannot get the right
list type from tag*/
+ const gchar *struct_combo_widget; /* name of the combobox widget for this structure */
+ const gchar *struct_liststore_widget; /* name of the liststore of the combobox for this
structure */
+ const gchar *add_widget; /* name of the add structure button for this
structure */
+ const gchar *remove_widget; /* name of the remove structure button for this
structure */
+};
+
+typedef struct _Datapage Datapage;
+typedef struct _DatapageClass DatapageClass;
+
+struct _Datapage {
+ GObject parent_instance;
+ StructureElement *struct_element;
+ gint structure_element_count;
+ MetadataEntry *metadata_entry;
+ gint metadata_entry_count;
+ ComboBoxData *combobox_data;
+ gint combobox_data_count;
+ gint max_combobox_entries;
+ GtkBuilder *builder;
+// GimpAttributes *attributes;
+};
+
+struct _DatapageClass {
+ GObjectClass parent_class;
+};
+
+GType datapage_get_type (void) G_GNUC_CONST;
+
+
+Datapage* datapage_new (GtkBuilder *builder);
+void datapage_set_structure_element (Datapage *datapage,
+ StructureElement *struct_elem,
+ gint structure_element_count);
+void datapage_set_combobox_data (Datapage *datapage,
+ ComboBoxData *combobox_data,
+ gint combobox_data_count,
+ gint max_combobox_entries);
+void datapage_set_metadata_entry (Datapage *datapage,
+ MetadataEntry *metadata_entry,
+ gint metadata_entry_count);
+
+void datapage_read_from_attributes (Datapage *datapage,
+ GimpAttributes **attributes);
+void datapage_save_to_attributes (Datapage *datapage,
+ GimpAttributes **attributes);
+
+G_END_DECLS
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]