Updated.
authorLutz Mueller <lutz.s.mueller@gmail.com>
Sat, 22 Dec 2001 00:25:12 +0000 (01:25 +0100)
committerLutz Mueller <lutz.s.mueller@gmail.com>
Sat, 22 Dec 2001 00:25:12 +0000 (01:25 +0100)
24 files changed:
libexif-gtk/gtk-exif-browser.c
libexif-gtk/gtk-exif-content-list.c
libexif-gtk/gtk-exif-content-list.h
libexif-gtk/gtk-exif-entry-ascii.c
libexif-gtk/gtk-exif-entry-date.c
libexif-gtk/gtk-exif-entry-exposure.c
libexif-gtk/gtk-exif-entry-flash.c
libexif-gtk/gtk-exif-entry-light.c
libexif-gtk/gtk-exif-entry-meter.c
libexif-gtk/gtk-exif-entry-orientation.c
libexif-gtk/gtk-exif-entry-resolution.c
libexif-gtk/gtk-exif-entry-sensing.c
libexif-gtk/gtk-exif-entry-version.c
libexif-gtk/gtk-exif-entry-ycbcrpos.c
libexif-gtk/gtk-exif-entry.c
libexif-gtk/gtk-exif-entry.h
libexif-gtk/gtk-extensions/gtk-options.c
libexif-gtk/gtk-extensions/gtk-options.h
libexif/exif-content.c
libexif/exif-content.h
libexif/exif-entry.c
libexif/exif-entry.h
libexif/exif-tag.c
libexif/exif-tag.h

index be1c5c8..fe941e4 100644 (file)
 
 #include <gtk/gtksignal.h>
 #include <gtk/gtklabel.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtkbutton.h>
 #include <gtk/gtkscrolledwindow.h>
 
+#include <libexif/exif-i18n.h>
+
+#include "gtk-exif-tag-menu.h"
 #include "gtk-exif-tree.h"
 #include "gtk-exif-content-list.h"
 #include "gtk-exif-entry-ascii.h"
 #include "gtk-exif-entry-version.h"
 #include "gtk-exif-entry-ycbcrpos.h"
 
+static void gtk_exif_browser_show_entry (GtkExifBrowser *, ExifEntry *);
+
 struct _GtkExifBrowserPrivate {
        ExifData *data;
 
        GtkExifContentList *list;
        GtkWidget *empty, *current, *info;
+
+       GtkWidget *up, *down;
+
+       GtkExifTagMenu *tag_menu;
 };
 
 #define PARENT_TYPE gtk_hpaned_get_type()
@@ -131,17 +143,70 @@ gtk_exif_browser_set_widget (GtkExifBrowser *browser, GtkWidget *w)
                                      browser->priv->current);
        gtk_box_pack_start (GTK_BOX (browser->priv->info), w, TRUE, FALSE, 0);
        browser->priv->current = w;
+
+       gtk_widget_set_sensitive (browser->priv->down,
+                                 GTK_EXIF_IS_CONTENT_LIST (w));
+}
+
+static void
+gtk_exif_browser_update_tag_menu (GtkExifBrowser *browser)
+{
+       GtkOptions *options;
+       guint i;
+
+       options = GTK_OPTIONS (browser->priv->tag_menu);
+       gtk_options_set_sensitive_all (options, TRUE);
+       for (i = 0; i < browser->priv->list->content->count; i++)
+               gtk_options_set_sensitive (options,
+                       browser->priv->list->content->entries[i]->tag, FALSE);
+}
+
+static void
+on_entry_removed (GtkExifEntry *entry, ExifEntry *e, GtkExifBrowser *browser)
+{
+        GtkCList *list = GTK_CLIST (browser->priv->list);
+        gint row;
+
+        row = gtk_clist_find_row_from_data (list, e);
+        gtk_clist_remove (list, row);
+       gtk_exif_browser_update_tag_menu (browser);
+}
+
+static void
+on_entry_changed (GtkExifEntry *entry, ExifEntry *e, GtkExifBrowser *browser)
+{
+        GtkCList *list = GTK_CLIST (browser->priv->list);
+       gint row;
+
+        row = gtk_clist_find_row_from_data (list, e);
+        gtk_clist_set_text (list, row, 1, exif_entry_get_value (e));
+}
+
+static void
+on_entry_added (GtkExifEntry *entry, ExifEntry *e, GtkExifBrowser *browser)
+{
+        GtkExifContentList *list = GTK_EXIF_CONTENT_LIST (browser->priv->list);
+
+        gtk_exif_content_list_add_entry (list, e);
+       gtk_exif_browser_show_entry (browser, e);
 }
 
 static void
 on_entry_selected (GtkExifContentList *list, ExifEntry *entry,
                   GtkExifBrowser *browser)
 {
+       gtk_exif_browser_show_entry (browser, entry);
+}
+
+static void
+gtk_exif_browser_show_entry (GtkExifBrowser *browser, ExifEntry *entry)
+{
        GtkWidget *w;
 
        switch (entry->tag) {
-       case EXIF_TAG_EXIF_OFFSET:
-       case EXIF_TAG_INTEROPERABILITY_OFFSET:
+       case EXIF_TAG_EXIF_IFD_POINTER:
+       case EXIF_TAG_INTEROPERABILITY_IFD_POINTER:
+       case EXIF_TAG_GPS_INFO_IFD_POINTER:
                w = gtk_exif_content_list_new ();
                gtk_exif_content_list_set_content (GTK_EXIF_CONTENT_LIST (w),
                                                   entry->content);
@@ -199,28 +264,115 @@ on_entry_selected (GtkExifContentList *list, ExifEntry *entry,
        }
        gtk_widget_show (w);
        gtk_exif_browser_set_widget (browser, w);
+       if (GTK_EXIF_IS_ENTRY (w)) {
+               gtk_signal_connect (GTK_OBJECT (w), "entry_added",
+                       GTK_SIGNAL_FUNC (on_entry_added), browser);
+               gtk_signal_connect (GTK_OBJECT (w), "entry_removed",
+                       GTK_SIGNAL_FUNC (on_entry_removed), browser);
+               gtk_signal_connect (GTK_OBJECT (w), "entry_changed",
+                       GTK_SIGNAL_FUNC (on_entry_changed), browser);
+       }
+}
+
+static void
+on_up_clicked (GtkButton *button, GtkExifBrowser *browser)
+{
+       gtk_exif_content_list_set_content (browser->priv->list,
+                               browser->priv->list->content->parent->parent);
+}
+
+static void
+on_down_clicked (GtkButton *button, GtkExifBrowser *browser)
+{
+       gint row;
+       GtkCList *list = GTK_CLIST (browser->priv->list);
+       ExifEntry *entry;
+
+       row = GPOINTER_TO_INT (list->selection->data);
+       entry = gtk_clist_get_row_data (list, row);
+       gtk_exif_content_list_set_content (browser->priv->list, entry->content);
+}
+
+static void
+on_tag_selected (GtkExifTagMenu *menu, ExifTag tag, GtkExifBrowser *browser)
+{
+       ExifEntry *entry;
+
+       entry = exif_entry_new ();
+       exif_entry_initialize (entry, tag);
+       exif_content_add_entry (browser->priv->list->content, entry);
+       exif_entry_unref (entry);
+       gtk_exif_content_list_add_entry (browser->priv->list, entry);
+       gtk_exif_browser_show_entry (browser, entry);
+}
+
+static void
+on_content_changed (GtkExifContentList *list, ExifContent *content,
+                   GtkExifBrowser *browser)
+{
+       gtk_widget_set_sensitive (browser->priv->up, content->parent != NULL);
+       gtk_exif_browser_set_widget (browser, browser->priv->empty);
+       gtk_exif_browser_update_tag_menu (browser);
 }
 
 GtkWidget *
 gtk_exif_browser_new (void)
 {
-       GtkWidget *et, *swin;
+       GtkWidget *et, *swin, *vbox, *menu, *hbox, *button;
        GtkExifBrowser *browser;
 
        browser = gtk_type_new (GTK_EXIF_TYPE_BROWSER);
 
-       /* Tree */
+       vbox = gtk_vbox_new (FALSE, 0);
+       gtk_widget_show (vbox);
+       gtk_paned_pack1 (GTK_PANED (browser), vbox, TRUE, TRUE);
+
+       /* Up/Down */
+       hbox = gtk_hbox_new (FALSE, 5);
+       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+       gtk_widget_show (hbox);
+       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+       button = gtk_button_new_with_label (_("Up"));
+       gtk_widget_show (button);
+       gtk_widget_set_sensitive (button, FALSE);
+       gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+       browser->priv->up = button;
+       gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                           GTK_SIGNAL_FUNC (on_up_clicked), browser);
+       button = gtk_button_new_with_label (_("Down"));
+       gtk_widget_show (button);
+       gtk_widget_set_sensitive (button, FALSE);
+       gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+       browser->priv->down = button;
+       gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                           GTK_SIGNAL_FUNC (on_down_clicked), browser);
+
+       /* List */
        swin = gtk_scrolled_window_new (NULL, NULL);
        gtk_widget_show (swin);
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
                                GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-       gtk_paned_pack1 (GTK_PANED (browser), swin, TRUE, TRUE);
+       gtk_box_pack_start (GTK_BOX (vbox), swin, TRUE, TRUE, 0);
        et = gtk_exif_content_list_new ();
        gtk_widget_show (et);
        gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (swin), et);
        browser->priv->list = GTK_EXIF_CONTENT_LIST (et);
        gtk_signal_connect (GTK_OBJECT (et), "entry_selected",
                            GTK_SIGNAL_FUNC (on_entry_selected), browser);
+       gtk_signal_connect (GTK_OBJECT (et), "content_changed",
+                           GTK_SIGNAL_FUNC (on_content_changed), browser);
+
+       /* Tag menu */
+       hbox = gtk_hbox_new (FALSE, 5);
+       gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
+       gtk_widget_show (hbox);
+       gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+       menu = gtk_exif_tag_menu_new ();
+       gtk_widget_show (menu);
+       gtk_box_pack_start (GTK_BOX (hbox), menu, FALSE, FALSE, 0);
+       browser->priv->tag_menu = GTK_EXIF_TAG_MENU (menu);
+       gtk_signal_connect (GTK_OBJECT (menu), "tag_selected",
+                           GTK_SIGNAL_FUNC (on_tag_selected), browser);
 
        /* Info */
        browser->priv->info = gtk_vbox_new (FALSE, 0);
index cc63553..f373d8d 100644 (file)
 
 static void gtk_exif_content_list_add_content (GtkExifContentList *list,
                                               ExifContent *content);
-static void gtk_exif_content_list_add_entry   (GtkExifContentList *list,
-                                              ExifEntry *entry);
 
 struct _GtkExifContentListPrivate {
-       ExifContent *content;
 };
 
 #define PARENT_TYPE GTK_TYPE_CLIST
@@ -35,6 +32,7 @@ static GtkCListClass *parent_class;
 
 enum {
        ENTRY_SELECTED,
+       CONTENT_CHANGED,
        LAST_SIGNAL
 };
 
@@ -45,9 +43,9 @@ gtk_exif_content_list_destroy (GtkObject *object)
 {
        GtkExifContentList *list = GTK_EXIF_CONTENT_LIST (object);
 
-       if (list->priv->content) {
-               exif_content_unref (list->priv->content);
-               list->priv->content = NULL;
+       if (list->content) {
+               exif_content_unref (list->content);
+               list->content = NULL;
        }
 
        GTK_OBJECT_CLASS (parent_class)->destroy (object);
@@ -76,6 +74,10 @@ gtk_exif_content_list_class_init (GtkExifContentListClass *klass)
                GTK_RUN_LAST, object_class->type,
                GTK_SIGNAL_OFFSET (GtkExifContentListClass, entry_selected),
                gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
+       signals[CONTENT_CHANGED] = gtk_signal_new ("content_changed",
+               GTK_RUN_LAST, object_class->type,
+               GTK_SIGNAL_OFFSET (GtkExifContentListClass, content_changed),
+               gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
        gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
 
        parent_class = gtk_type_class (PARENT_TYPE);
@@ -136,21 +138,7 @@ row_destroy_notify (gpointer data)
        exif_entry_unref ((ExifEntry *) data);
 }
 
-static void
-notify_entry_changed (ExifEntry *entry, void *data)
-{
-       GtkExifContentList *list;
-       gint row;
-
-       g_return_if_fail (GTK_EXIF_IS_CONTENT_LIST (data));
-       list = GTK_EXIF_CONTENT_LIST (data);
-
-       row = gtk_clist_find_row_from_data (GTK_CLIST (list), entry);
-       gtk_clist_set_text (GTK_CLIST (list), row, 1, 
-                           exif_entry_get_value (entry));
-}
-
-static void
+void
 gtk_exif_content_list_add_entry (GtkExifContentList *list, ExifEntry *entry)
 {
        gint row;
@@ -162,27 +150,8 @@ gtk_exif_content_list_add_entry (GtkExifContentList *list, ExifEntry *entry)
        exif_entry_ref (entry);
        gtk_clist_set_row_data_full (GTK_CLIST (list), row, entry,
                                     row_destroy_notify);
-       gtk_exif_content_list_add_content (list, entry->content);
-       exif_entry_add_notify (entry, EXIF_ENTRY_EVENT_CHANGED,
-                              notify_entry_changed, list);
-}
-
-static void
-on_entry_added (ExifContent *content, ExifEntry *entry, void *data)
-{
-       GtkExifContentList *list = GTK_EXIF_CONTENT_LIST (data);
-
-       gtk_exif_content_list_add_entry (list, entry);
-}
-
-static void
-on_entry_removed (ExifContent *content, ExifEntry *entry, void *data)
-{
-       GtkExifContentList *list = GTK_EXIF_CONTENT_LIST (data);
-       gint row;
-
-       row = gtk_clist_find_row_from_data (GTK_CLIST (list), entry);
-       gtk_clist_remove (GTK_CLIST (list), row);
+       gtk_signal_emit (GTK_OBJECT (list), signals[CONTENT_CHANGED],
+                        list->content);
 }
 
 static void
@@ -194,11 +163,6 @@ gtk_exif_content_list_add_content (GtkExifContentList *list,
        g_return_if_fail (GTK_EXIF_IS_CONTENT_LIST (list));
        g_return_if_fail (content != NULL);
 
-       exif_content_add_notify (content, EXIF_CONTENT_EVENT_ADD,
-                                on_entry_added, list);
-       exif_content_add_notify (content, EXIF_CONTENT_EVENT_REMOVE,
-                                on_entry_removed, list);
-
        for (i = 0; i < content->count; i++)
                gtk_exif_content_list_add_entry (list, content->entries[i]);
 }
@@ -210,9 +174,9 @@ gtk_exif_content_list_set_content (GtkExifContentList *list,
        g_return_if_fail (GTK_EXIF_IS_CONTENT_LIST (list));
        g_return_if_fail (content != NULL);
 
-       if (list->priv->content)
-               exif_content_unref (list->priv->content);
-       list->priv->content = content;
+       if (list->content)
+               exif_content_unref (list->content);
+       list->content = content;
        exif_content_ref (content);
 
        gtk_clist_clear (GTK_CLIST (list));
index 8fb8dec..3600811 100644 (file)
@@ -37,6 +37,8 @@ struct _GtkExifContentList
 {
        GtkCList parent;
 
+       ExifContent *content;
+
        GtkExifContentListPrivate *priv;
 };
 
@@ -45,12 +47,15 @@ struct _GtkExifContentListClass
        GtkCListClass parent_class;
 
        /* Signals */
-       void (* entry_selected) (GtkExifContentList *list, ExifEntry *entry);
+       void (* entry_selected)  (GtkExifContentList *list, ExifEntry *);
+       void (* content_changed) (GtkExifContentList *list, ExifContent *);
 };
 
 GtkType    gtk_exif_content_list_get_type (void);
 GtkWidget *gtk_exif_content_list_new      (void);
 
+void       gtk_exif_content_list_add_entry   (GtkExifContentList *list,
+                                             ExifEntry *entry);
 void       gtk_exif_content_list_set_content (GtkExifContentList *list,
                                              ExifContent *content);
 
index 8b44efd..f51ee89 100644 (file)
@@ -116,7 +116,8 @@ on_text_changed (GtkEditable *editable, GtkExifEntryAscii *entry)
        entry->priv->entry->data = txt;
        entry->priv->entry->size = strlen (txt) + 1;
        entry->priv->entry->components = entry->priv->entry->size;
-       exif_entry_notify (entry->priv->entry, EXIF_ENTRY_EVENT_CHANGED);
+       gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_changed",
+                                entry->priv->entry);
 }
 
 GtkWidget *
index d04649f..2f6550e 100644 (file)
@@ -155,7 +155,8 @@ gtk_exif_entry_date_save (GtkExifEntryDate *entry)
                 (gint) entry->priv->a_hour->value,
                 (gint) entry->priv->a_min->value,
                 (gint) entry->priv->a_sec->value);
-       exif_entry_notify (entry->priv->entry, EXIF_ENTRY_EVENT_CHANGED);
+       gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_changed",
+                                entry->priv->entry);
 }
 
 static void
index 9801a8a..baf8598 100644 (file)
@@ -139,7 +139,8 @@ gtk_exif_entry_exposure_save (GtkExifEntryExposure *entry)
        value = gtk_options_get (entry->priv->options);
        exif_set_short (entry->priv->entry->data, entry->priv->entry->order,
                        value);
-       exif_entry_notify (entry->priv->entry, EXIF_ENTRY_EVENT_CHANGED);
+       gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_changed",
+                                entry->priv->entry);
 }
 
 static void
index a99a08c..9faa523 100644 (file)
@@ -119,7 +119,8 @@ on_value_changed (GtkToggleButton *toggle, GtkExifEntryFlash *entry)
                entry->priv->entry->data[0] |= 0x04;
        else if (entry->priv->r3->active)
                entry->priv->entry->data[0] |= 0x06;
-       exif_entry_notify (entry->priv->entry, EXIF_ENTRY_EVENT_CHANGED);
+       gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_changed",
+                                entry->priv->entry);
 }
 
 GtkWidget *
index 1707da3..603e7e7 100644 (file)
@@ -139,7 +139,8 @@ gtk_exif_entry_light_save (GtkExifEntryLight *entry)
        value = gtk_options_get (entry->priv->options);
        exif_set_short (entry->priv->entry->data, entry->priv->entry->order,
                        value);
-       exif_entry_notify (entry->priv->entry, EXIF_ENTRY_EVENT_CHANGED);
+       gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_changed",
+                                entry->priv->entry);
 }
 
 static void
index bc6e7ad..0b4d521 100644 (file)
@@ -139,7 +139,8 @@ gtk_exif_entry_meter_save (GtkExifEntryMeter *entry)
         value = gtk_options_get (entry->priv->options);
         exif_set_short (entry->priv->entry->data, entry->priv->entry->order,
                         value);
-        exif_entry_notify (entry->priv->entry, EXIF_ENTRY_EVENT_CHANGED);
+       gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_changed",
+                                entry->priv->entry);
 }
 
 static void
index 0052d4d..8ba2e34 100644 (file)
@@ -131,7 +131,8 @@ gtk_exif_entry_orientation_save (GtkExifEntryOrientation *entry)
        value = gtk_options_get (entry->priv->options);
        exif_set_short (entry->priv->entry->data, entry->priv->entry->order,
                        value);
-       exif_entry_notify (entry->priv->entry, EXIF_ENTRY_EVENT_CHANGED);
+       gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_changed",
+                                entry->priv->entry);
 }
 
 static void
index 5e2c212..eb507d1 100644 (file)
@@ -140,7 +140,7 @@ on_inch_activate (GtkMenuItem *item, GtkExifEntryResolution *entry)
                                    entry->priv->tag_u);
        g_return_if_fail (e != NULL);
        exif_set_short (e->data, e->order, 2);
-       exif_entry_notify (e, EXIF_ENTRY_EVENT_CHANGED);
+       gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_changed", e);
 }
 
 static void
@@ -152,7 +152,7 @@ on_centimeter_activate (GtkMenuItem *item, GtkExifEntryResolution *entry)
                                    entry->priv->tag_u);
        g_return_if_fail (e != NULL);
        exif_set_short (e->data, e->order, 3);
-       exif_entry_notify (e, EXIF_ENTRY_EVENT_CHANGED);
+       gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_changed", e);
 }
 
 static void
@@ -165,7 +165,7 @@ on_wp_value_changed (GtkAdjustment *a, GtkExifEntryResolution *entry)
        g_return_if_fail (e != NULL);
        exif_set_rational (e->data, e->order, entry->priv->ox.ap->value, 
                                              entry->priv->ox.aq->value);
-       exif_entry_notify (e, EXIF_ENTRY_EVENT_CHANGED);
+       gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_changed", e);
 }
 
 static void
@@ -178,7 +178,7 @@ on_wq_value_changed (GtkAdjustment *a, GtkExifEntryResolution *entry)
        g_return_if_fail (e != NULL);
        exif_set_rational (e->data, e->order, entry->priv->ox.ap->value,
                                              entry->priv->ox.aq->value);
-       exif_entry_notify (e, EXIF_ENTRY_EVENT_CHANGED);
+       gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_changed", e);
 }
 
 static void
@@ -191,7 +191,7 @@ on_hp_value_changed (GtkAdjustment *a, GtkExifEntryResolution *entry)
        g_return_if_fail (e != NULL);
        exif_set_rational (e->data, e->order, entry->priv->oy.ap->value,
                                              entry->priv->oy.aq->value);
-       exif_entry_notify (e, EXIF_ENTRY_EVENT_CHANGED);
+       gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_changed", e);
 }
 
 static void
@@ -204,7 +204,7 @@ on_hq_value_changed (GtkAdjustment *a, GtkExifEntryResolution *entry)
        g_return_if_fail (e != NULL);
        exif_set_rational (e->data, e->order, entry->priv->oy.ap->value,
                                              entry->priv->oy.aq->value);
-       exif_entry_notify (e, EXIF_ENTRY_EVENT_CHANGED);
+       gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_changed", e);
 }
 
 static void
@@ -286,8 +286,12 @@ on_cw_toggled (GtkToggleButton *toggle, GtkExifEntryResolution *entry)
                exif_content_add_entry (entry->priv->content, e);
                gtk_exif_entry_resolution_load (entry, e);
                exif_entry_unref (e);
+               gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_added", e);
        } else if (!toggle->active && e) {
+               exif_entry_ref (e);
                exif_content_remove_entry (entry->priv->content, e);
+               gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_removed",e);
+               exif_entry_unref (e);
        }
 }
 
@@ -306,8 +310,12 @@ on_ch_toggled (GtkToggleButton *toggle, GtkExifEntryResolution *entry)
                exif_content_add_entry (entry->priv->content, e);
                gtk_exif_entry_resolution_load (entry, e);
                exif_entry_unref (e);
+               gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_added", e);
         } else if (!toggle->active && e) {
+               exif_entry_ref (e);
                exif_content_remove_entry (entry->priv->content, e);
+               gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_removed",e);
+               exif_entry_unref (e);
         }
 }
 
@@ -326,8 +334,12 @@ on_unit_toggled (GtkToggleButton *toggle, GtkExifEntryResolution *entry)
                exif_content_add_entry (entry->priv->content, e);
                gtk_exif_entry_resolution_load_unit (entry, e);
                exif_entry_unref (e);
+               gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_added", e);
        } else if (!toggle->active && e) {
+               exif_entry_ref (e);
                exif_content_remove_entry (entry->priv->content, e);
+               gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_removed",e);
+               exif_entry_unref (e);
        }
 }
 
index f2c3697..8196ffc 100644 (file)
@@ -139,7 +139,8 @@ gtk_exif_entry_sensing_save (GtkExifEntrySensing *entry)
        value = gtk_options_get (entry->priv->options);
        exif_set_short (entry->priv->entry->data, entry->priv->entry->order,
                        value);
-       exif_entry_notify (entry->priv->entry, EXIF_ENTRY_EVENT_CHANGED);
+       gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_changed",
+                                entry->priv->entry);
 }
 
 static void
index a983a99..0ad819b 100644 (file)
@@ -214,7 +214,8 @@ gtk_exif_entry_version_save (GtkExifEntryVersion *entry)
        default:
                break;
        }
-       exif_entry_notify (entry->priv->entry, EXIF_ENTRY_EVENT_CHANGED);
+       gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_changed",
+                                entry->priv->entry);
 }
 
 static void
index 0a79fe7..336388a 100644 (file)
@@ -139,7 +139,8 @@ gtk_exif_entry_ycbcrpos_save (GtkExifEntryYcbcrpos *entry)
        value = gtk_options_get (entry->priv->options);
        exif_set_short (entry->priv->entry->data, entry->priv->entry->order,
                        value);
-       exif_entry_notify (entry->priv->entry, EXIF_ENTRY_EVENT_CHANGED);
+       gtk_signal_emit_by_name (GTK_OBJECT (entry), "entry_changed",
+                                entry->priv->entry);
 }
 
 static void
index e97ed0a..1a12285 100644 (file)
@@ -34,6 +34,9 @@ struct _GtkExifEntryPrivate {
 static GtkVBoxClass *parent_class;
 
 enum {
+       ENTRY_ADDED,
+       ENTRY_REMOVED,
+       ENTRY_CHANGED,
        LAST_SIGNAL
 };
 
@@ -68,6 +71,18 @@ gtk_exif_entry_class_init (GtkExifEntryClass *klass)
        object_class->destroy  = gtk_exif_entry_destroy;
        object_class->finalize = gtk_exif_entry_finalize;
 
+       signals[ENTRY_ADDED] = gtk_signal_new ("entry_added", GTK_RUN_FIRST,
+               object_class->type,
+               GTK_SIGNAL_OFFSET (GtkExifEntryClass, entry_added),
+               gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
+       signals[ENTRY_REMOVED] = gtk_signal_new ("entry_removed",
+               GTK_RUN_FIRST, object_class->type,
+               GTK_SIGNAL_OFFSET (GtkExifEntryClass, entry_removed),
+               gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
+       signals[ENTRY_CHANGED] = gtk_signal_new ("entry_changed",
+               GTK_RUN_FIRST, object_class->type,
+               GTK_SIGNAL_OFFSET (GtkExifEntryClass, entry_changed),
+               gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
        gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
 
        parent_class = gtk_type_class (PARENT_TYPE);
index cee6940..0eda83c 100644 (file)
@@ -43,6 +43,11 @@ struct _GtkExifEntry
 struct _GtkExifEntryClass
 {
        GtkVBoxClass parent_class;
+
+       /* Signals */
+       void (* entry_changed) (GtkExifEntry *entry, ExifEntry *e);
+       void (* entry_removed) (GtkExifEntry *entry, ExifEntry *e);
+       void (* entry_added)   (GtkExifEntry *entry, ExifEntry *e);
 };
 
 GtkType    gtk_exif_entry_get_type  (void);
index 2706b5e..ad25d56 100644 (file)
@@ -49,6 +49,8 @@ struct _GtkOptionsPrivate
        guint current;
 
        GArray *array;
+
+       GPtrArray *items;
 };
 
 #define PARENT_TYPE GTK_TYPE_OPTION_MENU
@@ -71,6 +73,11 @@ gtk_options_destroy (GtkObject *object)
                options->priv->array = NULL;
        }
 
+       if (options->priv->items) {
+               g_ptr_array_free (options->priv->items, TRUE);
+               options->priv->items = NULL;
+       }
+
        GTK_OBJECT_CLASS (parent_class)->destroy (object);
 }
 
@@ -107,6 +114,7 @@ gtk_options_init (GtkOptions *options)
 {
        options->priv = g_new0 (GtkOptionsPrivate, 1);
        options->priv->array = g_array_new (FALSE, TRUE, sizeof (guint));
+       options->priv->items = g_ptr_array_new ();
 }
 
 GtkType
@@ -170,6 +178,7 @@ gtk_options_construct (GtkOptions *options, GtkOptionsList *list)
                gtk_signal_connect (GTK_OBJECT (item), "activate",
                                GTK_SIGNAL_FUNC (on_item_activate), options);
                g_array_append_val (options->priv->array, list[i].option);
+               g_ptr_array_add (options->priv->items, item);
        }
        gtk_option_menu_set_menu (GTK_OPTION_MENU (options), menu);
 }
@@ -197,3 +206,33 @@ gtk_options_get (GtkOptions *options)
 
        return (options->priv->current);
 }
+
+void
+gtk_options_set_sensitive (GtkOptions *options, guint option,
+                          gboolean sensitive)
+{
+       guint i;
+
+       g_return_if_fail (GTK_IS_OPTIONS (options));
+
+       for (i = 0; i < options->priv->array->len; i++)
+               if (g_array_index (options->priv->array, guint, i) == option)
+                       break;
+       if (i == options->priv->array->len)
+               return;
+       gtk_widget_set_sensitive (GTK_WIDGET (options->priv->items->pdata[i]),
+                                 sensitive);
+}
+
+void
+gtk_options_set_sensitive_all (GtkOptions *options, gboolean sensitive)
+{
+       guint i;
+
+       g_return_if_fail (GTK_IS_OPTIONS (options));
+
+       for (i = 0; i < options->priv->items->len; i++)
+               gtk_widget_set_sensitive (
+                       GTK_WIDGET (options->priv->items->pdata[i]), 
+                       sensitive);
+}
index 072956e..9b0612e 100644 (file)
@@ -60,4 +60,9 @@ void       gtk_options_construct (GtkOptions *options, GtkOptionsList *list);
 void       gtk_options_set       (GtkOptions *options, guint option);
 guint      gtk_options_get       (GtkOptions *options);
 
+void       gtk_options_set_sensitive_all (GtkOptions *options,
+                                         gboolean sensitive);
+void       gtk_options_set_sensitive     (GtkOptions *options, guint option,
+                                         gboolean sensitive);
+
 #endif /* __GTK_OPTIONS_H__ */
index 8142ed4..58edb4e 100644 (file)
 
 static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
 
-typedef struct _ExifContentNotifyData ExifContentNotifyData;
-struct _ExifContentNotifyData {
-       ExifContentEvent events;
-       ExifContentNotifyFunc func;
-       void *data;
-};
-
 struct _ExifContentPrivate
 {
-       ExifContentNotifyData *notifications;
-       unsigned int count;
-
        unsigned int ref_count;
 };
 
-unsigned int
-exif_content_add_notify (ExifContent *content, ExifContentEvent events,
-                        ExifContentNotifyFunc func, void *data)
-{
-       if (!content)
-               return (0);
-
-       if (!content->priv->notifications)
-               content->priv->notifications =
-                               malloc (sizeof (ExifContentNotifyData));
-       else
-               content->priv->notifications = 
-                       realloc (content->priv->notifications,
-                                sizeof (ExifContentNotifyData) *
-                                       (content->priv->count + 1));
-       content->priv->notifications[content->priv->count].events = events;
-       content->priv->notifications[content->priv->count].func = func;
-       content->priv->notifications[content->priv->count].data = data;
-       content->priv->count++;
-
-       return (content->priv->count);
-}
-
-void
-exif_content_remove_notify (ExifContent *content, unsigned int id)
-{
-       if (!content)
-               return;
-       if (id > content->priv->count)
-               return;
-
-       memmove (content->priv->notifications + id - 1,
-                content->priv->notifications + id,
-                sizeof (ExifContentNotifyData) *
-                       (content->priv->count - id));
-       content->priv->count--;
-}
-
 ExifContent *
 exif_content_new (void)
 {
@@ -177,18 +129,6 @@ exif_content_dump (ExifContent *content, unsigned int indent)
                exif_entry_dump (content->entries[i], indent + 1);
 }
 
-static void
-exif_content_notify (ExifContent *content, ExifEntry *entry,
-                    ExifContentEvent event)
-{
-       unsigned int i;
-
-       for (i = 0; i < content->priv->count; i++)
-               if (content->priv->notifications[i].events & event)
-                       content->priv->notifications[i].func (content, entry,
-                                       content->priv->notifications[i].data);
-}
-
 void
 exif_content_add_entry (ExifContent *content, ExifEntry *entry)
 {
@@ -201,8 +141,6 @@ exif_content_add_entry (ExifContent *content, ExifEntry *entry)
        content->entries[content->count] = entry;
        exif_entry_ref (entry);
        content->count++;
-
-       exif_content_notify (content, entry, EXIF_CONTENT_EVENT_ADD);
 }
 
 void
@@ -223,8 +161,6 @@ exif_content_remove_entry (ExifContent *content, ExifEntry *entry)
                 sizeof (ExifEntry) * (content->count - i - 1));
        content->count--;
 
-       exif_content_notify (content, entry, EXIF_CONTENT_EVENT_REMOVE);
-
        entry->parent = NULL;
        exif_entry_unref (entry);
 }
index 325e377..1f6aef0 100644 (file)
@@ -45,21 +45,6 @@ void         exif_content_ref   (ExifContent *content);
 void         exif_content_unref (ExifContent *content);
 void         exif_content_free  (ExifContent *content);
 
-/* Notification */
-typedef enum _ExifContentEvent ExifContentEvent;
-enum _ExifContentEvent {
-       EXIF_CONTENT_EVENT_ADD    = 1 << 0,
-       EXIF_CONTENT_EVENT_REMOVE = 1 << 1
-};
-typedef void (* ExifContentNotifyFunc)  (ExifContent *content,
-                                        ExifEntry *entry, void *data);
-unsigned int exif_content_add_notify    (ExifContent *content,
-                                        ExifContentEvent events,
-                                        ExifContentNotifyFunc func,
-                                        void *data);
-void         exif_content_remove_notify (ExifContent *content,
-                                        unsigned int id);
-
 void         exif_content_parse (ExifContent *content,
                                 const unsigned char *data,
                                 unsigned int size,
index 0f10244..d8634fb 100644 (file)
@@ -46,18 +46,8 @@ static struct {
         {0, 0}
 };
 
-typedef struct _ExifEntryNotifyData ExifEntryNotifyData;
-struct _ExifEntryNotifyData {
-       ExifEntryEvent events;
-       ExifEntryNotifyFunc func;
-       void *data;
-};
-
 struct _ExifEntryPrivate
 {
-       ExifEntryNotifyData *notifications;
-       unsigned int count;
-
        unsigned int ref_count;
 };
 
@@ -113,55 +103,6 @@ exif_entry_free (ExifEntry *entry)
 }
 
 void
-exif_entry_notify (ExifEntry *entry, ExifEntryEvent event)
-{
-       unsigned int i;
-
-       for (i = 0; i < entry->priv->count; i++)
-               if (entry->priv->notifications[i].events & event)
-                       entry->priv->notifications[i].func (entry,
-                               entry->priv->notifications[i].data);
-}
-
-void
-exif_entry_remove_notify (ExifEntry *entry, unsigned int id)
-{
-       if (!entry)
-               return;
-       if (id > entry->priv->count)
-               return;
-
-       memmove (entry->priv->notifications + id - 1,
-                entry->priv->notifications + id,
-                sizeof (ExifEntryNotifyData) *
-                       (entry->priv->count - id));
-       entry->priv->count--;
-}
-
-unsigned int
-exif_entry_add_notify (ExifEntry *entry, ExifEntryEvent events,
-                      ExifEntryNotifyFunc func, void *data)
-{
-       if (!entry)
-               return (0);
-
-       if (!entry->priv->notifications)
-               entry->priv->notifications =
-                               malloc (sizeof (ExifEntryNotifyData));
-       else
-               entry->priv->notifications = 
-                       realloc (entry->priv->notifications, 
-                                sizeof (ExifEntryNotifyData) *
-                                       (entry->priv->count + 1));
-       entry->priv->notifications[entry->priv->count].events = events;
-       entry->priv->notifications[entry->priv->count].func = func;
-       entry->priv->notifications[entry->priv->count].data = data;
-       entry->priv->count++;
-
-       return (entry->priv->count);
-}
-
-void
 exif_entry_parse (ExifEntry *entry, const unsigned char *data,
                  unsigned int size, unsigned int offset, ExifByteOrder order)
 {
@@ -188,8 +129,9 @@ exif_entry_parse (ExifEntry *entry, const unsigned char *data,
                }
        if (!s)
                return;
-       if ((s > 4) || (entry->tag == EXIF_TAG_EXIF_OFFSET) ||
-                      (entry->tag == EXIF_TAG_INTEROPERABILITY_OFFSET))
+       if ((s > 4) || (entry->tag == EXIF_TAG_EXIF_IFD_POINTER) ||
+                      (entry->tag == EXIF_TAG_GPS_INFO_IFD_POINTER) ||
+                      (entry->tag == EXIF_TAG_INTEROPERABILITY_IFD_POINTER))
                doff = exif_get_long (data + offset + 8, order);
        else
                doff = offset + 8;
@@ -204,8 +146,9 @@ exif_entry_parse (ExifEntry *entry, const unsigned char *data,
        entry->size = s;
        memcpy (entry->data, data + doff, s);
 
-       if ((entry->tag == EXIF_TAG_EXIF_OFFSET) ||
-           (entry->tag == EXIF_TAG_INTEROPERABILITY_OFFSET))
+       if ((entry->tag == EXIF_TAG_EXIF_IFD_POINTER) ||
+           (entry->tag == EXIF_TAG_GPS_INFO_IFD_POINTER) ||
+           (entry->tag == EXIF_TAG_INTEROPERABILITY_IFD_POINTER))
                exif_content_parse (entry->content, data, size, doff, order);
 }
 
index c7d53a8..23f6a23 100644 (file)
@@ -63,17 +63,6 @@ void        exif_entry_ref   (ExifEntry *entry);
 void        exif_entry_unref (ExifEntry *entry);
 void        exif_entry_free  (ExifEntry *entry);
 
-/* Notification */
-typedef enum _ExifEntryEvent ExifEntryEvent;
-enum _ExifEntryEvent {
-       EXIF_ENTRY_EVENT_CHANGED = 1 << 0
-};
-typedef void (* ExifEntryNotifyFunc)  (ExifEntry *entry, void *data);
-unsigned int exif_entry_add_notify    (ExifEntry *entry, ExifEntryEvent events,
-                                      ExifEntryNotifyFunc func, void *data);
-void         exif_entry_remove_notify (ExifEntry *entry, unsigned int id);
-void         exif_entry_notify        (ExifEntry *entry, ExifEntryEvent event);
-
 void        exif_entry_parse     (ExifEntry *entry, const unsigned char *data,
                                  unsigned int size, unsigned int offset,
                                  ExifByteOrder order);
index 6d83e2d..2f589d3 100644 (file)
@@ -244,7 +244,11 @@ static struct {
        {EXIF_TAG_FNUMBER, "FNumber", "FNumber",
         N_("The F number.")},
        {EXIF_TAG_IPTC_NAA, "IPTC/NAA", "IPTC/NAA", ""},
-       {EXIF_TAG_EXIF_OFFSET, "ExifOffset", "ExifOffset", ""},
+       {EXIF_TAG_EXIF_IFD_POINTER, "ExifIFDPointer", "ExifIFDPointer",
+        N_("A pointer to the Exif IFD. Interoperability, Exif IFD has the "
+           "same structure as that of the IFD specified in TIFF. "
+           "ordinarily, however, it does not contain image data as in "
+           "the case of TIFF.")},
        {EXIF_TAG_INTER_COLOR_PROFILE, "InterColorProfile",
         "InterColorProfile", ""},
        {EXIF_TAG_EXPOSURE_PROGRAM, "ExposureProgram", "ExposureProgram",
@@ -255,6 +259,11 @@ static struct {
         N_("Indicates the spectral sensitivity of each channel of the "
            "camera used. The tag value is an ASCII string compatible "
            "with the standard developed by the ASTM Technical committee.")},
+       {EXIF_TAG_GPS_INFO_IFD_POINTER, "GPSInfoIFDPointer", 
+        "GPSInfoIFDPointer",
+        N_("A pointer to the GPS Info IFD. The "
+           "Interoperability structure of the GPS Info IFD, like that of "
+           "Exif IFD, has no image data.")},
 #if 0
        {EXIF_TAG_GPS_VERSION_ID, "GPSVersionID", "",
         N_("Indicates the version of <GPSInfoIFD>. The version is given "
@@ -444,8 +453,16 @@ static struct {
            "NULL. When this tag is used to map audio files, the relation "
            "of the audio file to image data must also be indicated on the "
            "audio file end.")},
-       {EXIF_TAG_INTEROPERABILITY_OFFSET, "InteroperabilityOffset",
-        "InteroperabilityOffset", ""},
+       {EXIF_TAG_INTEROPERABILITY_IFD_POINTER, "InteroperabilityIFDPointer",
+        "InteroperabilityIFDPointer",
+        N_("Interoperability IFD is composed of tags which stores the "
+           "information to ensure the Interoperability and pointed "
+           "by the following tag located in Exif IFD. "
+           "The Interoperability structure of Interoperability IFD is "
+           "the same as TIFF defined IFD structure "
+           "but does not contain the "
+           "image data characteristically compared with normal TIFF "
+           "IFD.")},
        {EXIF_TAG_FLASH_ENERGY, "FlashEnergy", N_("Flash Energy"),
         N_("Indicates the strobe energy at the time the image is "
            "captured, as measured in Beam Candle Power Seconds (BCPS).")},
index 791a064..42708ff 100644 (file)
@@ -68,11 +68,11 @@ enum _ExifTag {
        EXIF_TAG_EXPOSURE_TIME                  = 0x829a,
        EXIF_TAG_FNUMBER                        = 0x829d,
        EXIF_TAG_IPTC_NAA                       = 0x83bb,
-       EXIF_TAG_EXIF_OFFSET                    = 0x8769,
+       EXIF_TAG_EXIF_IFD_POINTER               = 0x8769,
        EXIF_TAG_INTER_COLOR_PROFILE            = 0x8773,
        EXIF_TAG_EXPOSURE_PROGRAM               = 0x8822,
        EXIF_TAG_SPECTRAL_SENSITIVITY           = 0x8824,
-       EXIF_TAG_GPS_INFO                       = 0x8825,
+       EXIF_TAG_GPS_INFO_IFD_POINTER           = 0x8825,
        EXIF_TAG_ISO_SPEED_RATINGS              = 0x8827,
        EXIF_TAG_OECF                           = 0x8828,
        EXIF_TAG_EXIF_VERSION                   = 0x9000,
@@ -100,7 +100,7 @@ enum _ExifTag {
        EXIF_TAG_PIXEL_X_DIMENSION              = 0xa002,
        EXIF_TAG_PIXEL_Y_DIMENSION              = 0xa003,
        EXIF_TAG_RELATED_SOUND_FILE             = 0xa004,
-       EXIF_TAG_INTEROPERABILITY_OFFSET        = 0xa005,
+       EXIF_TAG_INTEROPERABILITY_IFD_POINTER   = 0xa005,
        EXIF_TAG_FLASH_ENERGY                   = 0xa20b,
        EXIF_TAG_SPATIAL_FREQUENCY_RESPONSE     = 0xa20c,
        EXIF_TAG_FOCAL_PLANE_X_RESOLUTION       = 0xa20e,