Mercurial > geeqie.yaz
changeset 1350:9d190c098b97
rewritten exif pane to support arbitrary number of entries
author | nadvornik |
---|---|
date | Sat, 28 Feb 2009 23:59:02 +0000 |
parents | 5f21db044ec4 |
children | 93fe7a68a689 |
files | src/bar.c src/bar_exif.c src/bar_exif.h src/rcfile.c |
diffstat | 4 files changed, 208 insertions(+), 279 deletions(-) [+] |
line wrap: on
line diff
--- a/src/bar.c Sat Feb 28 20:57:26 2009 +0000 +++ b/src/bar.c Sat Feb 28 23:59:02 2009 +0000 @@ -274,7 +274,7 @@ widget = bar_pane_comment_new(_("Comment"), "Xmp.dc.description", TRUE, 150); bar_add(bar, widget); - widget = bar_pane_exif_new(_("Exif"), TRUE); + widget = bar_pane_exif_new(_("Exif"), TRUE, TRUE); bar_add(bar, widget); }
--- a/src/bar_exif.c Sat Feb 28 20:57:26 2009 +0000 +++ b/src/bar_exif.c Sat Feb 28 23:59:02 2009 +0000 @@ -27,93 +27,10 @@ #include <math.h> ExifUI ExifUIList[]={ - { 0, 0, EXIF_UI_IFSET, EXIF_FORMATTED("Camera")}, - { 0, 0, EXIF_UI_IFSET, EXIF_FORMATTED("DateTime")}, - { 0, 0, EXIF_UI_IFSET, EXIF_FORMATTED("ShutterSpeed")}, - { 0, 0, EXIF_UI_IFSET, EXIF_FORMATTED("Aperture")}, - { 0, 0, EXIF_UI_IFSET, EXIF_FORMATTED("ExposureBias")}, - { 0, 0, EXIF_UI_IFSET, EXIF_FORMATTED("ISOSpeedRating")}, - { 0, 0, EXIF_UI_IFSET, EXIF_FORMATTED("FocalLength")}, - { 0, 0, EXIF_UI_IFSET, EXIF_FORMATTED("FocalLength35mmFilm")}, - { 0, 0, EXIF_UI_IFSET, EXIF_FORMATTED("Flash")}, - { 0, 0, EXIF_UI_IFSET, "Exif.Photo.ExposureProgram"}, - { 0, 0, EXIF_UI_IFSET, "Exif.Photo.MeteringMode"}, - { 0, 0, EXIF_UI_IFSET, "Exif.Photo.LightSource"}, - { 0, 0, EXIF_UI_IFSET, EXIF_FORMATTED("ColorProfile")}, - { 0, 0, EXIF_UI_IFSET, EXIF_FORMATTED("SubjectDistance")}, - { 0, 0, EXIF_UI_IFSET, EXIF_FORMATTED("Resolution")}, - { 0, 0, EXIF_UI_IFSET, "Exif.Image.Orientation"}, - { 0, 0, EXIF_UI_IFSET, EXIF_FORMATTED("GPSPosition")}, - { 0, 0, EXIF_UI_IFSET, EXIF_FORMATTED("GPSAltitude")}, - { 0, 0, EXIF_UI_IFSET, "Exif.Image.ImageDescription"}, - { 0, 0, EXIF_UI_IFSET, "Exif.Image.Copyright"}, { 0, 0, EXIF_UI_OFF, NULL} }; -/* - *------------------------------------------------------------------- - * table util - *------------------------------------------------------------------- - */ - -static void table_add_line_custom(GtkWidget *table, gint x, gint y, - const gchar *text1, const gchar *text2, - GtkWidget **label1, GtkWidget **label2, - GtkWidget **remove) -{ - GtkWidget *label; - gchar *buf; - - buf = g_strconcat((text1) ? text1 : "fixme", ":", NULL); - if (!text2) text2 = ""; - - label = gtk_label_new(buf); - gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.0); - pref_label_bold(label, TRUE, FALSE); - gtk_table_attach(GTK_TABLE(table), label, - x + 1, x + 2, y, y + 1, - GTK_FILL, GTK_FILL, - 2, 2); - *label1 = label; - - label = gtk_label_new(text2); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0); - gtk_table_attach(GTK_TABLE(table), label, - x + 2, x + 3, y, y + 1, - GTK_FILL, GTK_FILL, - 2, 2); - *label2 = label; - - if (remove) - { - *remove = gtk_check_button_new(); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(*remove), TRUE); - - gtk_table_attach(GTK_TABLE(table), *remove, - x, x + 1, y, y + 1, - GTK_FILL, GTK_FILL, - 2, 2); - } - - g_free(buf); -} - -static GtkWidget *table_add_line(GtkWidget *table, gint x, gint y, - const gchar *description, const gchar *text, - GtkWidget **keyret) -{ - GtkWidget *key; - GtkWidget *label; - - table_add_line_custom(table, x, y, description, text, &key, &label, NULL); - gtk_widget_show(key); - gtk_widget_show(label); - if (keyret) *keyret = key; - - return label; -} - /* *------------------------------------------------------------------- @@ -121,37 +38,122 @@ *------------------------------------------------------------------- */ +typedef struct _ExifEntry ExifEntry; +struct _ExifEntry +{ + GtkWidget *hbox; + GtkWidget *title_label; + GtkWidget *value_label; + + gchar *key; + gchar *title; + gboolean if_set; + gboolean auto_title; +}; + + typedef struct _PaneExifData PaneExifData; struct _PaneExifData { PaneData pane; GtkWidget *vbox; - GtkWidget *scrolled; - GtkWidget *table; - GtkWidget **keys; - GtkWidget **labels; - - GtkWidget *custom_sep; - GtkWidget *custom_name[EXIF_BAR_CUSTOM_COUNT]; - GtkWidget *custom_value[EXIF_BAR_CUSTOM_COUNT]; - GtkWidget *custom_remove[EXIF_BAR_CUSTOM_COUNT]; + GtkWidget *widget; + GtkSizeGroup *size_group; FileData *fd; - - gint allow_search; + GList *entries; }; -static void bar_pane_exif_sensitive(PaneExifData *ped, gint enable) +static void bar_pane_exif_update_entry(PaneExifData *ped, ExifEntry *ee, gboolean update_title); + +static void bar_pane_exif_entry_destroy(GtkWidget *widget, gpointer data) +{ + ExifEntry *ee = data; + + g_free(ee->key); + g_free(ee->title); + g_free(ee); +} + + +static void bar_pane_exif_add_entry(PaneExifData *ped, const gchar *key, const gchar *title, gint if_set) { - gtk_widget_set_sensitive(ped->table, enable); + ExifEntry *ee = g_new0(ExifEntry, 1); + + ee->key = g_strdup(key); + if (title && title[0]) + { + ee->title = g_strdup(title); + } + else + { + ee->title = exif_get_description_by_key(key); + ee->auto_title = TRUE; + } + + ee->if_set = if_set; + + ee->hbox = gtk_hbox_new(FALSE, 0); + g_signal_connect_after(G_OBJECT(ee->hbox), "destroy", + G_CALLBACK(bar_pane_exif_entry_destroy), ee); + + ee->title_label = gtk_label_new(NULL); + gtk_misc_set_alignment(GTK_MISC(ee->title_label), 1.0, 0.0); + gtk_size_group_add_widget(ped->size_group, ee->title_label); + gtk_box_pack_start(GTK_BOX(ee->hbox), ee->title_label, FALSE, TRUE, 0); + gtk_widget_show(ee->title_label); + + ee->value_label = gtk_label_new(NULL); +// gtk_label_set_width_chars(GTK_LABEL(ee->value_label), 20); + gtk_label_set_ellipsize(GTK_LABEL(ee->value_label), PANGO_ELLIPSIZE_END); +// gtk_widget_set_size_request(ee->value_label, 100, -1); + gtk_misc_set_alignment(GTK_MISC(ee->value_label), 0.0, 0.0); + gtk_box_pack_start(GTK_BOX(ee->hbox), ee->value_label, TRUE, TRUE, 1); + gtk_widget_show(ee->value_label); + + gtk_box_pack_start(GTK_BOX(ped->vbox), ee->hbox, TRUE, TRUE, 0); + ped->entries = g_list_append(ped->entries, ee); + bar_pane_exif_update_entry(ped, ee, TRUE); +} + +static void bar_pane_exif_entry_update_title(ExifEntry *ee) +{ + gchar *markup; + + markup = g_markup_printf_escaped("<span size='small'>%s:</span>", (ee->title) ? ee->title : "fixme"); + gtk_label_set_markup(GTK_LABEL(ee->title_label), markup); + g_free(markup); +} + +static void bar_pane_exif_update_entry(PaneExifData *ped, ExifEntry *ee, gboolean update_title) +{ + gchar *text = metadata_read_string(ped->fd, ee->key, METADATA_FORMATTED); + + if (ee->if_set && (!text || !*text)) + { + gtk_label_set_text(GTK_LABEL(ee->value_label), NULL); + gtk_widget_hide(ee->hbox); + } + else + { + gtk_label_set_text(GTK_LABEL(ee->value_label), text); +#if GTK_CHECK_VERSION(2,12,0) + gtk_widget_set_tooltip_text(ee->hbox, text); +#endif + gtk_widget_show(ee->hbox); + } + + g_free(text); + + if (update_title) bar_pane_exif_entry_update_title(ee); } static void bar_pane_exif_update(PaneExifData *ped) { + GList *work; + +#if 0 ExifData *exif; - gint i; - GList *list; - /* do we have any exif at all ? */ exif = exif_read_fd(ped->fd); @@ -167,103 +169,17 @@ exif_free_fd(ped->fd, exif); exif = NULL; } - bar_pane_exif_sensitive(ped, TRUE); - - for (i = 0; ExifUIList[i].key; i++) - { - gchar *text; +#endif - if (ExifUIList[i].current == EXIF_UI_OFF) - { - gtk_widget_hide(ped->labels[i]); - gtk_widget_hide(ped->keys[i]); - continue; - } - text = metadata_read_string(ped->fd, ExifUIList[i].key, METADATA_FORMATTED); - if (ExifUIList[i].current == EXIF_UI_IFSET - && (!text || !*text)) - { - gtk_widget_hide(ped->labels[i]); - gtk_widget_hide(ped->keys[i]); - g_free(text); - continue; - } - gtk_widget_show(ped->labels[i]); - gtk_widget_show(ped->keys[i]); - gtk_label_set_text(GTK_LABEL(ped->labels[i]), text); - g_free(text); - } - - list = g_list_last(history_list_get_by_key("exif_extras")); - if (list) + work = ped->entries; + while (work) { - gtk_widget_show(ped->custom_sep); - } - else - { - gtk_widget_hide(ped->custom_sep); - } - i = 0; - while (list && i < EXIF_BAR_CUSTOM_COUNT) - { - gchar *text; - gchar *name; - gchar *buf; - gchar *description; - - name = list->data; - list = list->prev; + ExifEntry *ee = work->data; + work = work->next; - text = metadata_read_string(ped->fd, name, METADATA_FORMATTED); - - description = exif_get_tag_description_by_key(name); - if (!description || *description == '\0') - { - g_free(description); - description = g_strdup(name); - } - buf = g_strconcat(description, ":", NULL); - g_free(description); - - gtk_label_set_text(GTK_LABEL(ped->custom_name[i]), buf); - g_free(buf); - gtk_label_set_text(GTK_LABEL(ped->custom_value[i]), text); - g_free(text); - - gtk_widget_show(ped->custom_name[i]); - gtk_widget_show(ped->custom_value[i]); - g_object_set_data(G_OBJECT(ped->custom_remove[i]), "key", name); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ped->custom_remove[i]), TRUE); - gtk_widget_show(ped->custom_remove[i]); - - i++; - } - while (i < EXIF_BAR_CUSTOM_COUNT) - { - g_object_set_data(G_OBJECT(ped->custom_remove[i]), "key", NULL); - gtk_widget_hide(ped->custom_name[i]); - gtk_widget_hide(ped->custom_value[i]); - gtk_widget_hide(ped->custom_remove[i]); - - i++; - } -} - -static void bar_pane_exif_clear(PaneExifData *ped) -{ - gint i; - - if (!GTK_WIDGET_SENSITIVE(ped->labels[0])) return; - - for (i = 0; ExifUIList[i].key; i++) - { - gtk_label_set_text(GTK_LABEL(ped->labels[i]), ""); - } - for (i = 0; i < EXIF_BAR_CUSTOM_COUNT; i++) - { - gtk_label_set_text(GTK_LABEL(ped->custom_value[i]), ""); + bar_pane_exif_update_entry(ped, ee, FALSE); } } @@ -274,18 +190,28 @@ ped = g_object_get_data(G_OBJECT(widget), "pane_data"); if (!ped) return; - /* store this, advanced view toggle needs to reload data */ file_data_unref(ped->fd); ped->fd = file_data_ref(fd); - bar_pane_exif_clear(ped); bar_pane_exif_update(ped); } +static void bar_pane_exif_entry_write_config(ExifEntry *ee, GString *outstr, gint indent) +{ + WRITE_STRING("<entry\n"); + indent++; + WRITE_CHAR(*ee, key); + if (!ee->auto_title) WRITE_CHAR(*ee, title); + WRITE_BOOL(*ee, if_set); + indent--; + WRITE_STRING("/>\n"); +} + static void bar_pane_exif_write_config(GtkWidget *pane, GString *outstr, gint indent) { PaneExifData *ped; - + GList *work; + ped = g_object_get_data(G_OBJECT(pane), "pane_data"); if (!ped) return; @@ -294,26 +220,21 @@ write_char_option(outstr, indent, "pane.title", gtk_label_get_text(GTK_LABEL(ped->pane.title))); WRITE_BOOL(*ped, pane.expanded); indent--; - WRITE_STRING("/>\n"); + WRITE_STRING(">\n"); + indent++; + work = ped->entries; + while (work) + { + ExifEntry *ee = work->data; + work = work->next; + + bar_pane_exif_entry_write_config(ee, outstr, indent); + } + indent--; + WRITE_STRING("</pane_exif>\n"); } -static void bar_pane_exif_remove_advanced_cb(GtkWidget *widget, gpointer data) -{ - PaneExifData *ped = data; - const gchar *key; - - /* continue only if the toggle was deactivated */ - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) return; - - key = g_object_get_data(G_OBJECT(widget), "key"); - if (!key) return; - - history_list_item_change("exif_extras", key, NULL); - - bar_pane_exif_update(ped); -} - void bar_pane_exif_close(GtkWidget *widget) { PaneExifData *ped; @@ -328,23 +249,15 @@ { PaneExifData *ped = data; - g_free(ped->keys); - g_free(ped->labels); + g_list_free(ped->entries); + g_object_unref(ped->size_group); file_data_unref(ped->fd); g_free(ped); } -GtkWidget *bar_pane_exif_new(const gchar *title, gboolean expanded) +GtkWidget *bar_pane_exif_new(const gchar *title, gboolean expanded, gboolean populate) { PaneExifData *ped; - GtkWidget *table; - GtkWidget *viewport; - GtkWidget *hbox; - gint i; - gint exif_len; - - for (exif_len = 0; ExifUIList[exif_len].key; exif_len++) - ; ped = g_new0(PaneExifData, 1); @@ -353,66 +266,41 @@ ped->pane.title = gtk_label_new(title); ped->pane.expanded = expanded; - ped->keys = g_new0(GtkWidget *, exif_len); - ped->labels = g_new0(GtkWidget *, exif_len); - + ped->size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); ped->vbox = gtk_vbox_new(FALSE, PREF_PAD_GAP); - g_object_set_data(G_OBJECT(ped->vbox), "pane_data", ped); - g_signal_connect_after(G_OBJECT(ped->vbox), "destroy", + ped->widget = ped->vbox; + g_object_set_data(G_OBJECT(ped->widget), "pane_data", ped); + g_signal_connect_after(G_OBJECT(ped->widget), "destroy", G_CALLBACK(bar_pane_exif_destroy), ped); - table = gtk_table_new(3, exif_len + 1 + EXIF_BAR_CUSTOM_COUNT, FALSE); - - ped->table = table; - - for (i = 0; ExifUIList[i].key; i++) - { - gchar *text; - - text = exif_get_description_by_key(ExifUIList[i].key); - ped->labels[i] = table_add_line(table, 0, i, text, NULL, - &ped->keys[i]); - g_free(text); - } - - ped->custom_sep = gtk_hseparator_new(); - gtk_table_attach(GTK_TABLE(table), ped->custom_sep, 0, 3, - exif_len, exif_len + 1, - GTK_FILL, GTK_FILL, 2, 2); - - for (i = 0; i < EXIF_BAR_CUSTOM_COUNT; i++) + if (populate) { - table_add_line_custom(table, 0, exif_len + 1 + i, - "", "", &ped->custom_name[i], &ped->custom_value[i], - &ped->custom_remove[i]); - g_signal_connect(G_OBJECT(ped->custom_remove[i]), "clicked", - G_CALLBACK(bar_pane_exif_remove_advanced_cb), ped); + bar_pane_exif_add_entry(ped, EXIF_FORMATTED("Camera"), NULL, TRUE); + bar_pane_exif_add_entry(ped, EXIF_FORMATTED("DateTime"), NULL, TRUE); + bar_pane_exif_add_entry(ped, EXIF_FORMATTED("ShutterSpeed"), NULL, TRUE); + bar_pane_exif_add_entry(ped, EXIF_FORMATTED("Aperture"), NULL, TRUE); + bar_pane_exif_add_entry(ped, EXIF_FORMATTED("ExposureBias"), NULL, TRUE); + bar_pane_exif_add_entry(ped, EXIF_FORMATTED("ISOSpeedRating"), NULL, TRUE); + bar_pane_exif_add_entry(ped, EXIF_FORMATTED("FocalLength"), NULL, TRUE); + bar_pane_exif_add_entry(ped, EXIF_FORMATTED("FocalLength35mmFilm"), NULL, TRUE); + bar_pane_exif_add_entry(ped, EXIF_FORMATTED("Flash"), NULL, TRUE); + bar_pane_exif_add_entry(ped, "Exif.Photo.ExposureProgram", NULL, TRUE); + bar_pane_exif_add_entry(ped, "Exif.Photo.MeteringMode", NULL, TRUE); + bar_pane_exif_add_entry(ped, "Exif.Photo.LightSource", NULL, TRUE); + bar_pane_exif_add_entry(ped, EXIF_FORMATTED("ColorProfile"), NULL, TRUE); + bar_pane_exif_add_entry(ped, EXIF_FORMATTED("SubjectDistance"), NULL, TRUE); + bar_pane_exif_add_entry(ped, EXIF_FORMATTED("Resolution"), NULL, TRUE); + bar_pane_exif_add_entry(ped, "Exif.Image.Orientation", NULL, TRUE); + bar_pane_exif_add_entry(ped, EXIF_FORMATTED("GPSPosition"), NULL, TRUE); + bar_pane_exif_add_entry(ped, EXIF_FORMATTED("GPSAltitude"), NULL, TRUE); + bar_pane_exif_add_entry(ped, "Exif.Image.ImageDescription", NULL, TRUE); + bar_pane_exif_add_entry(ped, "Exif.Image.Copyright", NULL, TRUE); } - - ped->scrolled = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(ped->scrolled), - GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER); + + gtk_widget_show(ped->widget); - viewport = gtk_viewport_new(NULL, NULL); - gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE); - gtk_container_add(GTK_CONTAINER(ped->scrolled), viewport); - gtk_widget_show(viewport); - - gtk_container_add(GTK_CONTAINER(viewport), table); - gtk_widget_show(table); - - gtk_box_pack_start(GTK_BOX(ped->vbox), ped->scrolled, TRUE, TRUE, 0); - - hbox = gtk_hbox_new(FALSE, PREF_PAD_SPACE); - gtk_box_pack_end(GTK_BOX(ped->vbox), hbox, FALSE, FALSE, 0); - gtk_widget_show(hbox); - - gtk_widget_show(ped->scrolled); - - gtk_widget_show(ped->vbox); - - return ped->vbox; + return ped->widget; } GtkWidget *bar_pane_exif_new_from_config(const gchar **attribute_names, const gchar **attribute_values) @@ -432,7 +320,32 @@ DEBUG_1("unknown attribute %s = %s", option, value); } - return bar_pane_exif_new(title, expanded); + return bar_pane_exif_new(title, expanded, FALSE); +} + +void bar_pane_exif_entry_add_from_config(GtkWidget *pane, const gchar **attribute_names, const gchar **attribute_values) +{ + PaneExifData *ped; + gchar *key = NULL; + gchar *title = NULL; + gboolean if_set = TRUE; + + ped = g_object_get_data(G_OBJECT(pane), "pane_data"); + if (!ped) return; + + while (*attribute_names) + { + const gchar *option = *attribute_names++; + const gchar *value = *attribute_values++; + + if (READ_CHAR_FULL("key", key)) continue; + if (READ_CHAR_FULL("title", title)) continue; + if (READ_BOOL_FULL("if_set", if_set)) continue; + + + DEBUG_1("unknown attribute %s = %s", option, value); + } + if (key && key[0]) bar_pane_exif_add_entry(ped, key, title, if_set); }
--- a/src/bar_exif.h Sat Feb 28 20:57:26 2009 +0000 +++ b/src/bar_exif.h Sat Feb 28 23:59:02 2009 +0000 @@ -30,8 +30,9 @@ #define EXIF_BAR_CUSTOM_COUNT 20 -GtkWidget *bar_pane_exif_new(const gchar *title, gboolean expanded); +GtkWidget *bar_pane_exif_new(const gchar *title, gboolean expanded, gboolean populate); GtkWidget *bar_pane_exif_new_from_config(const gchar **attribute_names, const gchar **attribute_values); +void bar_pane_exif_entry_add_from_config(GtkWidget *pane, const gchar **attribute_names, const gchar **attribute_values); /* these are exposed for when duplication of the exif bar's text is needed */
--- a/src/rcfile.c Sat Feb 28 20:57:26 2009 +0000 +++ b/src/rcfile.c Sat Feb 28 23:59:02 2009 +0000 @@ -844,6 +844,21 @@ } } +static void options_parse_pane_exif(GQParserData *parser_data, GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer data, GError **error) +{ + GtkWidget *pane = data; + if (g_ascii_strcasecmp(element_name, "entry") == 0) + { + bar_pane_exif_entry_add_from_config(pane, attribute_names, attribute_values); + options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL); + } + else + { + DEBUG_1("unexpected in <pane_exif>: <%s>", element_name); + options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL); + } +} + static void options_parse_bar(GQParserData *parser_data, GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer data, GError **error) { GtkWidget *bar = data; @@ -857,7 +872,7 @@ { GtkWidget *pane = bar_pane_exif_new_from_config(attribute_names, attribute_values); bar_add(bar, pane); - options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL); + options_parse_func_push(parser_data, options_parse_pane_exif, NULL, pane); } else if (g_ascii_strcasecmp(element_name, "pane_histogram") == 0) {