#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()
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);
}
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);
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
enum {
ENTRY_SELECTED,
+ CONTENT_CHANGED,
LAST_SIGNAL
};
{
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);
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);
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;
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
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]);
}
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));
{
GtkCList parent;
+ ExifContent *content;
+
GtkExifContentListPrivate *priv;
};
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);
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 *
(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
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
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 *
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
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
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
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
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
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
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
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
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
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);
}
}
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);
}
}
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);
}
}
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
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
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
static GtkVBoxClass *parent_class;
enum {
+ ENTRY_ADDED,
+ ENTRY_REMOVED,
+ ENTRY_CHANGED,
LAST_SIGNAL
};
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);
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);
guint current;
GArray *array;
+
+ GPtrArray *items;
};
#define PARENT_TYPE GTK_TYPE_OPTION_MENU
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);
}
{
options->priv = g_new0 (GtkOptionsPrivate, 1);
options->priv->array = g_array_new (FALSE, TRUE, sizeof (guint));
+ options->priv->items = g_ptr_array_new ();
}
GtkType
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);
}
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);
+}
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__ */
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)
{
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)
{
content->entries[content->count] = entry;
exif_entry_ref (entry);
content->count++;
-
- exif_content_notify (content, entry, EXIF_CONTENT_EVENT_ADD);
}
void
sizeof (ExifEntry) * (content->count - i - 1));
content->count--;
- exif_content_notify (content, entry, EXIF_CONTENT_EVENT_REMOVE);
-
entry->parent = NULL;
exif_entry_unref (entry);
}
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,
{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;
};
}
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)
{
}
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;
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);
}
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);
{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",
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 "
"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).")},
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,
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,