[eog-plugins] Add new exif-display plugin



commit 9d614d3f5172fdee6bea8826f390acfa3b7ea554
Author: Emmanuel Touzery <emmanuel touzery free fr>
Date:   Tue Jun 9 17:32:56 2009 +0200

    Add new exif-display plugin
    
    This plugin displays a few selected Exif tags in the sidebar.
    Additonally an RGB histogram can be enabled as well.
    Currently only works with the 2.26.x series of eog.

 ChangeLog                                          |   11 +
 configure.ac                                       |   27 +-
 plugins/exif-display/Makefile.am                   |   39 +
 plugins/exif-display/eog-exif-display-plugin.c     |  838 ++++++++++++++++++++
 plugins/exif-display/eog-exif-display-plugin.h     |   74 ++
 plugins/exif-display/exif-display-config.ui        |  172 ++++
 .../exif-display.eog-plugin.desktop.in             |    9 +
 plugins/exif-display/exif-display.ui               |  224 ++++++
 8 files changed, 1391 insertions(+), 3 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 0eace44..9c03b98 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2009-06-12  Felix Riemann  <friemann svn gnome org>
+
+	* plugins/exif-display/Makefile.am:
+	* plugins/exif-display/eog-exif-display-plugin.c:
+	* plugins/exif-display/eog-exif-display-plugin.h:
+	* plugins/exif-display/exif-display-config.ui:
+	* plugins/exif-display/exif-display.eog-plugin.desktop.in:
+	* plugins/exif-display/exif-display.ui:
+	* configure.ac:
+	Add exif-display plugin by Emmanuel Touzery.
+
 2009-05-05  Felix Riemann  <friemann svn gnome org>
 
 	* configure.ac: Make --with-plugins parameter appear nice with a list
diff --git a/configure.ac b/configure.ac
index 441e320..4ead97e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -58,9 +58,9 @@ EOG_HAS_PYTHON=1
 
 AC_MSG_CHECKING([which plugins to build])
 
-ALL_PLUGINS="postr champlain fit-to-width"
-USEFUL_PLUGINS="postr champlain fit-to-width"
-DEFAULT_PLUGINS="postr champlain fit-to-width"
+ALL_PLUGINS="postr champlain fit-to-width exif-display"
+USEFUL_PLUGINS="postr champlain fit-to-width exif-display"
+DEFAULT_PLUGINS="postr champlain fit-to-width exif-display"
 
 PYTHON_ALL_PLUGINS="slideshowshuffle pythonconsole"
 PYTHON_USEFUL_PLUGINS="slideshowshuffle pythonconsole"
@@ -306,6 +306,26 @@ then
 	fi
 fi
 
+# ***********
+# ExifDisplay
+# ***********
+plugin_defined exif-display
+if test "$?" = 1
+then
+
+    PKG_CHECK_MODULES(EXIFDISPLAY,
+        [ libexif >= 0.6.16,
+	  eog < 2.27.1 ],
+        [],[have_exifdisplay=no])
+    AC_SUBST(EXIFDISPLAY_LIBS)
+    AC_SUBST(EXIFDISPLAY_CFLAGS)
+    if test "x$have_exifdisplay" = "xno"
+    then
+        undef_plugin exif-display "libexif was not found"
+    fi
+fi
+
+
 if test -z "$disabled_plugins"
 then
 	disabled_plugins="none"
@@ -328,6 +348,7 @@ Makefile
 plugins/Makefile
 plugins/champlain/Makefile
 plugins/fit-to-width/Makefile
+plugins/exif-display/Makefile
 plugins/slideshowshuffle/Makefile
 plugins/postr/Makefile
 plugins/pythonconsole/Makefile
diff --git a/plugins/exif-display/Makefile.am b/plugins/exif-display/Makefile.am
new file mode 100644
index 0000000..4493857
--- /dev/null
+++ b/plugins/exif-display/Makefile.am
@@ -0,0 +1,39 @@
+# ExifDisplay plugin
+plugindir = $(libdir)/eog/plugins
+
+INCLUDES = \
+	-I$(top_srcdir)/src 				\
+	$(EOG_CFLAGS) 					\
+	$(WARN_CFLAGS)					\
+	$(EXIFDISPLAY_CFLAGS)				\
+	-DEOG_LOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
+	-DEOG_PLUGINDIR=\""$(plugindir)"\"
+
+plugin_LTLIBRARIES = libexif-display.la
+
+libexif_display_la_SOURCES = \
+	eog-exif-display-plugin.h			\
+	eog-exif-display-plugin.c
+
+libexif_display_la_LDFLAGS = \
+	-avoid-version -module
+
+libexif_display_la_LIBADD = $(EOG_LIBS)			\
+	$(EXIFDISPLAY_LIBS)
+
+# Plugin Info
+
+plugin_in_files = exif-display.eog-plugin.desktop.in
+
+UI_FILES = exif-display.ui exif-display-config.ui
+ui_DATA = $(UI_FILES)
+uidir = $(plugindir)
+
+%.eog-plugin: %.eog-plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+
+plugin_DATA = $(plugin_in_files:.eog-plugin.desktop.in=.eog-plugin)
+
+EXTRA_DIST = $(plugin_in_files) $(UI_FILES)
+
+CLEANFILES = #$(plugin_DATA)
+DISTCLEANFILES = $(plugin_DATA)
diff --git a/plugins/exif-display/eog-exif-display-plugin.c b/plugins/exif-display/eog-exif-display-plugin.c
new file mode 100644
index 0000000..c04179f
--- /dev/null
+++ b/plugins/exif-display/eog-exif-display-plugin.c
@@ -0,0 +1,838 @@
+/* Exif-display -- display information about digital pictures
+ *
+ * Copyright (C) 2009 The Free Software Foundation
+ *
+ * Author: Emmanuel Touzery  <emmanuel touzery free fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include <gconf/gconf-client.h>
+
+#include <glib/gi18n-lib.h>
+#include <eog/eog-scroll-view.h>
+#include <eog/eog-image.h>
+#include <eog/eog-thumb-view.h>
+#include <eog/eog-exif-details.h>
+#include <eog/eog-exif-util.h>
+#include <eog/eog-sidebar.h>
+
+#include "eog-exif-display-plugin.h"
+
+#define EOG_EXIF_DISPLAY_CONF_UI_DISPLAY_CHANNELS_HISTOGRAM "/apps/eog/plugins/exif_display/display_channels_histogram"
+#define EOG_EXIF_DISPLAY_CONF_UI_DISPLAY_RGB_HISTOGRAM "/apps/eog/plugins/exif_display/display_rgb_histogram"
+#define EOG_EXIF_DISPLAY_CONF_UI_DISPLAY_EXIF_STATUSBAR "/apps/eog/plugins/exif_display/display_exif_in_statusbar"
+
+#define WINDOW_DATA_KEY "EogExifDisplayWindowData"
+
+/* copy-pasted from eog-preferences-dialog.c */
+#define GCONF_OBJECT_KEY	"GCONF_KEY"
+
+/* copy-pasted from eog-preferences-dialog.c */
+#define TOGGLE_INVERT_VALUE	"TOGGLE_INVERT_VALUE"
+
+static GConfClient *gconf_client = NULL;
+
+#define GTKBUILDER_FILE EOG_PLUGINDIR"/exif-display.ui"
+#define GTKBUILDER_CONFIG_FILE EOG_PLUGINDIR"/exif-display-config.ui"
+
+EOG_PLUGIN_REGISTER_TYPE(EogExifDisplayPlugin, eog_exif_display_plugin)
+
+typedef struct {
+	/* Handlers ids */
+	guint selection_changed_id;
+
+	EogThumbView *eog_thumb_view;
+	EogWindow *eog_window;
+
+	GtkWidget *statusbar_exif;
+
+	GtkBuilder *sidebar_builder;
+	GtkWidget *gtkbuilder_widget;
+	GtkDrawingArea *drawing_area;
+
+	int *histogram_values_red;
+	int *histogram_values_green;
+	int *histogram_values_blue;
+	int max_of_array_sums;
+
+	int *histogram_values_rgb;
+	int max_of_array_sums_rgb;
+} WindowData;
+
+static void
+free_window_data (WindowData *data)
+{
+	g_return_if_fail (data != NULL);
+
+	g_free (data->histogram_values_red);
+	g_free (data->histogram_values_green);
+	g_free (data->histogram_values_blue);
+	g_free (data->histogram_values_rgb);
+
+	g_object_unref (data->sidebar_builder);
+
+	g_free (data);
+}
+
+
+static void
+eog_exif_display_plugin_init (EogExifDisplayPlugin *plugin)
+{
+}
+
+/* stolen from eog-properties-dialog.c*/
+static void
+eog_exif_set_label (GtkWidget *w, ExifData *exif_data, gint tag_id)
+{
+	gchar exif_buffer[512];
+	const gchar *buf_ptr;
+	gchar *label_text = NULL;
+
+	if (exif_data) {
+		buf_ptr = eog_exif_util_get_value (exif_data, tag_id,
+						   exif_buffer, 512);
+
+		if (tag_id == EXIF_TAG_DATE_TIME_ORIGINAL && buf_ptr)
+			label_text = eog_exif_util_format_date (buf_ptr);
+		else
+			label_text = eog_util_make_valid_utf8 (buf_ptr);
+	}
+
+	gtk_label_set_text (GTK_LABEL (w), label_text);
+	g_free (label_text);
+}
+
+static void set_exif_label (ExifData *exif_data, int exif_tag,
+	       GtkBuilder *gtk_builder, const gchar *gtk_builder_label_name, gboolean tooltip)
+{
+	GtkWidget *widget = GTK_WIDGET (gtk_builder_get_object (
+					gtk_builder, gtk_builder_label_name));
+	eog_exif_set_label (widget, exif_data, exif_tag);
+
+	if (tooltip) {
+		gtk_widget_set_tooltip_text (widget, gtk_label_get_label (GTK_LABEL (widget)));
+	}
+}
+
+/* stolen from eog-properties-dialog and slightly modified
+ * you must g_free () the gchar* that I return!
+ * */
+static gchar*
+eog_exif_get_focal_length_desc (ExifData *exif_data)
+{
+	ExifEntry *entry,*entry35mm;
+	ExifByteOrder byte_order;
+	gfloat f_val = 0.0;
+	gchar *fl_text = NULL,*fl35_text = NULL;
+	gchar *result;
+
+	/* If no ExifData is supplied the label will be
+	 * cleared later as fl35_text is NULL. */
+	if (exif_data != NULL) {
+		entry = exif_data_get_entry (exif_data, EXIF_TAG_FOCAL_LENGTH);
+		entry35mm = exif_data_get_entry (exif_data,
+					    EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM);
+		byte_order = exif_data_get_byte_order (exif_data);
+	}
+
+	if (entry && G_LIKELY (entry->format == EXIF_FORMAT_RATIONAL)) {
+		ExifRational value;
+
+		/* Decode value by hand as libexif is not necessarily returning
+		 * it in the format we want it to be.
+		 */
+		value = exif_get_rational (entry->data, byte_order);
+		/* Guard against div by zero */
+		if (G_LIKELY(value.denominator != 0))
+			f_val = (gfloat)value.numerator/
+				(gfloat)value.denominator;
+
+		/* TRANSLATORS: This is the actual focal length used when
+		   the image was taken.*/
+		fl_text = g_strdup_printf (_("%.1fmm (lens)"), f_val);
+
+	}
+	if (entry35mm && G_LIKELY (entry35mm->format == EXIF_FORMAT_SHORT)) {
+		ExifShort s_val;
+
+		s_val = exif_get_short (entry35mm->data, byte_order);
+
+		/* Print as float to get a similar look as above. */
+		/* TRANSLATORS: This is the equivalent focal length assuming
+		   a 35mm film camera. */
+		fl35_text = g_strdup_printf(_("%.1fmm (35mm film)"),(float)s_val);
+	}
+	if (fl_text) {
+		if (fl35_text) {
+			result = g_strconcat (fl35_text,", ", fl_text, NULL);
+
+			g_free (fl35_text);
+			g_free (fl_text);
+
+		} else {
+			result = fl_text;
+			g_free (fl35_text);
+		}
+	} else {
+		result = fl35_text;
+		g_free (fl_text);
+	}
+
+	return result;
+}
+
+/* stolen from eog-properties-dialog and modified */
+static void
+eog_exif_set_focal_length_label (GtkWidget *w, ExifData *exif_data)
+{
+	gchar *focal_length_desc = eog_exif_get_focal_length_desc (exif_data);
+	gtk_label_set_text (GTK_LABEL (w), focal_length_desc);
+
+	g_free (focal_length_desc);
+}
+
+static void manage_exif_data (WindowData *data)
+{
+	EogImage *image;
+	ExifData *exif_data;
+	ExifEntry *exif_entry;
+	ExifByteOrder byte_order;
+
+	image = eog_thumb_view_get_first_selected_image (data->eog_thumb_view);
+	g_return_if_fail (image != NULL);
+
+	exif_data = (ExifData *)eog_image_get_exif_info (image);
+
+	byte_order = exif_data_get_byte_order (exif_data);
+
+	set_exif_label (exif_data, EXIF_TAG_DATE_TIME_ORIGINAL, data->sidebar_builder, "takenon_label", TRUE);
+
+	eog_exif_set_focal_length_label (GTK_WIDGET (gtk_builder_get_object (
+			data->sidebar_builder, "focal_length_label")), exif_data);
+
+	set_exif_label (exif_data, EXIF_TAG_EXPOSURE_BIAS_VALUE, data->sidebar_builder, "exposure_bias_label", FALSE);
+
+	set_exif_label (exif_data, EXIF_TAG_EXPOSURE_TIME,
+			data->sidebar_builder, "exposure_time_label", FALSE);
+
+	set_exif_label (exif_data, EXIF_TAG_MODEL,
+			data->sidebar_builder, "camera_model_label", FALSE);
+
+	set_exif_label (exif_data, EXIF_TAG_FNUMBER,
+			data->sidebar_builder, "aperture_label", FALSE);
+
+	set_exif_label (exif_data, EXIF_TAG_ISO_SPEED_RATINGS,
+			data->sidebar_builder, "iso_label", FALSE);
+
+	set_exif_label (exif_data, EXIF_TAG_FLASH,
+			data->sidebar_builder, "flash_label", TRUE);
+
+	set_exif_label (exif_data, EXIF_TAG_METERING_MODE,
+			data->sidebar_builder, "metering_mode_label", TRUE);
+
+	set_exif_label (exif_data, EXIF_TAG_EXPOSURE_BIAS_VALUE, data->sidebar_builder, "exposure_bias_label", FALSE);
+
+	exif_data_unref (exif_data);
+
+	g_object_unref (image);
+}
+
+static void manage_exif_data_cb (EogJob *job, gpointer data)
+{
+	if (!job->error) {
+		manage_exif_data ((WindowData *)data);
+	}
+}
+
+static gboolean
+calculate_histogram (WindowData *data, EogImage *eog_image)
+{
+	int rowstride, n_channels;
+	int width, height;
+	int row, col;
+	GdkPixbuf *image_pixbuf;
+	guchar *pixels;
+	int array_sums_elt = 0;
+
+	/* for the red when we calculate we store
+	 * the values in a temporary array.
+	 * only when everything is calculated
+	 * we copy the pointers to the real
+	 * data->histogram_values_red.
+	 * That way we'll try to display
+	 * the histogram only once it's fully
+	 * calculated.*/
+	int *histogram_values_red_temp;
+
+	if (eog_image == NULL) {
+		return FALSE;
+	}
+
+	g_free (data->histogram_values_red);
+	data->histogram_values_red = NULL;
+
+	g_free (data->histogram_values_green);
+	g_free (data->histogram_values_blue);
+	g_free (data->histogram_values_rgb);
+
+	histogram_values_red_temp = g_new0 (int, 256);
+
+	data->histogram_values_green = g_new0 (int, 256);
+	data->histogram_values_blue = g_new0 (int, 256);
+	data->max_of_array_sums = 0;
+
+	data->histogram_values_rgb = g_new0 (int, 256);
+	data->max_of_array_sums_rgb = 0;
+
+	image_pixbuf = eog_image_get_pixbuf (eog_image);
+	if (image_pixbuf == NULL) {
+		return FALSE;
+	}
+
+	if ((gdk_pixbuf_get_colorspace (image_pixbuf) != GDK_COLORSPACE_RGB)
+		|| (gdk_pixbuf_get_bits_per_sample (image_pixbuf) > 8)) {
+		g_object_unref (image_pixbuf);
+		return FALSE;
+	}
+
+	rowstride = gdk_pixbuf_get_rowstride (image_pixbuf);
+
+	width = gdk_pixbuf_get_width (image_pixbuf);
+	height = gdk_pixbuf_get_height (image_pixbuf);
+	
+	pixels = gdk_pixbuf_get_pixels (image_pixbuf);
+	
+	for (row = 0; row < height; row++) {
+		guchar *row_cur_idx = pixels + row*rowstride;
+		for (col = 0; col < width; col++) {
+			guchar red = *row_cur_idx++;
+			guchar green = *row_cur_idx++;
+			guchar blue = *row_cur_idx++;
+			
+			histogram_values_red_temp[red] += 1;
+			data->histogram_values_green[green] += 1;
+			data->histogram_values_blue[blue] += 1;
+			data->histogram_values_rgb[MAX (red, MAX (green, blue))] += 1;
+		}
+	}
+	for (array_sums_elt=0;array_sums_elt<256;array_sums_elt++) {
+		if (histogram_values_red_temp[array_sums_elt] > data->max_of_array_sums) {
+			data->max_of_array_sums = histogram_values_red_temp[array_sums_elt];
+		}
+		if (data->histogram_values_green[array_sums_elt] > data->max_of_array_sums) {
+			data->max_of_array_sums = data->histogram_values_green[array_sums_elt];
+		}
+		if (data->histogram_values_blue[array_sums_elt] > data->max_of_array_sums) {
+			data->max_of_array_sums = data->histogram_values_blue[array_sums_elt];
+		}
+	}
+
+	for (array_sums_elt=0;array_sums_elt<256;array_sums_elt++) {
+		if (data->histogram_values_rgb[array_sums_elt] > data->max_of_array_sums_rgb) {
+			data->max_of_array_sums_rgb = data->histogram_values_rgb[array_sums_elt];
+		}
+	}
+
+	data->histogram_values_red = histogram_values_red_temp;
+
+	g_object_unref (image_pixbuf);
+
+	return TRUE;
+}
+
+static void
+draw_histogram_graph (cairo_t *cr, int *histogram_values, int max_of_array_sums)
+{
+	int i;
+
+	cairo_move_to (cr, 0, 1);
+	for (i = 0; i < 256; i++) {
+		cairo_line_to (cr, ((float)i)/(256.0), 1.0 - ((float)histogram_values[i])/max_of_array_sums);
+	}
+	cairo_line_to (cr, 1, 1);
+	cairo_close_path (cr);
+	cairo_fill (cr);
+}
+
+static gboolean
+read_gconf_bool_setting (const char *gconf_key)
+{
+	gboolean result = FALSE;
+	GConfEntry *mode_entry = gconf_client_get_entry (gconf_client,
+					     gconf_key,
+					     NULL, TRUE, NULL);
+
+	if (G_LIKELY (mode_entry != NULL)) {
+		if (mode_entry->value != NULL &&
+		    mode_entry->value->type == GCONF_VALUE_BOOL) {
+			result = gconf_value_get_bool (mode_entry->value);
+		}
+		gconf_entry_unref (mode_entry);
+	}
+
+	return result;
+}
+
+static void
+drawing_area_expose (GtkDrawingArea *drawing_area, GdkEventExpose *event,
+	WindowData *data)
+{
+	int i;
+	gboolean draw_channels_histogram, draw_rgb_histogram;
+	EogImage *eog_image;
+	cairo_t *cr;
+	gint drawing_area_width, drawing_area_height;
+	int scale_factor_y;
+	GtkStyle *gtk_style;
+
+	draw_channels_histogram = read_gconf_bool_setting (
+			EOG_EXIF_DISPLAY_CONF_UI_DISPLAY_CHANNELS_HISTOGRAM);
+	draw_rgb_histogram = read_gconf_bool_setting (
+			EOG_EXIF_DISPLAY_CONF_UI_DISPLAY_RGB_HISTOGRAM);
+
+	eog_image = eog_thumb_view_get_first_selected_image (data->eog_thumb_view);
+	g_return_if_fail (eog_image != NULL);
+
+	if (data->histogram_values_red == NULL) {
+		/* when calculate_histogram was called previously,
+		 * the picture was not loaded yet.
+		 * Now it's loaded, let's ask to calculate the
+		 * histogram again... */
+		calculate_histogram (data, eog_image);
+	}
+
+	cr = gdk_cairo_create (GTK_WIDGET (drawing_area)->window);
+	gdk_drawable_get_size ((GTK_WIDGET (drawing_area)->window), 
+			&drawing_area_width, &drawing_area_height);
+
+	scale_factor_y = drawing_area_height;
+	if (scale_factor_y > drawing_area_width/2) {
+		/* histogram taller than it is wide looks ugly.
+		 * it must be wider than it is tall for aesthetics.
+		 */
+		scale_factor_y = drawing_area_width/2;
+	}
+	cairo_scale (cr, drawing_area_width, scale_factor_y);
+
+	/* clear the display */
+	gtk_style = gtk_widget_get_style (GTK_WIDGET (drawing_area));
+	gtk_style_apply_default_background (gtk_style, GTK_WIDGET (drawing_area)->window,
+		TRUE, GTK_STATE_NORMAL, NULL, 0, 0, drawing_area_width, drawing_area_height);
+
+	if (data->histogram_values_red == NULL) {
+		/* it's possible, if the image
+		 * is not loaded and histogram
+		 * can't be calculated, we go this
+		 * far to clear the display.
+		 * now exit, we won't draw any
+		 * histogram without the data.
+		 */
+		return;
+	}
+
+	if (draw_channels_histogram) {
+		cairo_set_source_rgba (cr, 1, 0, 0, 0.5);
+		draw_histogram_graph (cr, data->histogram_values_red, data->max_of_array_sums);
+	
+		cairo_set_source_rgba (cr, 0, 1, 0, 0.5);
+		draw_histogram_graph (cr, data->histogram_values_green, data->max_of_array_sums);
+	
+		cairo_set_source_rgba (cr, 0, 0, 1, 0.5);
+		draw_histogram_graph (cr, data->histogram_values_blue, data->max_of_array_sums);
+	}
+	if (draw_rgb_histogram) {
+		cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
+		draw_histogram_graph (cr, data->histogram_values_rgb, data->max_of_array_sums_rgb);
+	}
+
+        cairo_destroy (cr);
+	g_object_unref (eog_image);
+}
+
+static void calculate_histogram_cb (EogJob *job, gpointer _data)
+{
+	WindowData *data = (WindowData*)_data;
+	if (!job->error) {
+		EogImage *eog_image = 
+			eog_thumb_view_get_first_selected_image (data->eog_thumb_view);
+		calculate_histogram (data, eog_image);
+		g_object_unref (eog_image);
+		drawing_area_expose (data->drawing_area, NULL, data);
+	}
+}
+
+static void
+statusbar_update_exif_data (GtkStatusbar *statusbar, EogThumbView *view)
+{
+	EogImage *image;
+	ExifData *exif_data;
+	gchar *exif_desc = NULL;
+
+	if (eog_thumb_view_get_n_selected (view) == 0)
+		return;
+
+	image = eog_thumb_view_get_first_selected_image (view);
+
+	gtk_statusbar_pop (statusbar, 0);
+
+	if (!eog_image_has_data (image, EOG_IMAGE_DATA_EXIF)) {
+		if (!eog_image_load (image, EOG_IMAGE_DATA_EXIF, NULL, NULL)) {
+			gtk_widget_hide (GTK_WIDGET (statusbar));
+		}
+	}
+
+	exif_data = (ExifData *) eog_image_get_exif_info (image);
+	if (exif_data) {
+		ExifEntry *exif_entry;
+		gchar exposition_time[512];
+		gchar aperture[512];
+		gchar iso[512];
+		gchar *focal_length;
+
+		exposition_time[0] = 0;
+		exif_entry = exif_data_get_entry (exif_data, EXIF_TAG_EXPOSURE_TIME);
+		exif_entry_get_value (exif_entry, exposition_time, sizeof(exposition_time));
+
+		aperture[0] = 0;
+		exif_entry = exif_data_get_entry (exif_data, EXIF_TAG_FNUMBER);
+		exif_entry_get_value (exif_entry, aperture, sizeof(aperture));
+
+		iso[0] = 0;
+		exif_entry = exif_data_get_entry (exif_data, EXIF_TAG_ISO_SPEED_RATINGS);
+		exif_entry_get_value (exif_entry, iso, sizeof(iso));
+
+		focal_length = eog_exif_get_focal_length_desc (exif_data);
+
+		exif_desc = g_strdup_printf ("ISO%s  %s  %s  %s",
+				iso, exposition_time, aperture, focal_length);
+
+		g_free (focal_length);
+	
+		exif_data_unref (exif_data);
+	}
+	g_object_unref (image);
+
+	if (exif_desc) {
+		gtk_statusbar_push (statusbar, 0, exif_desc);
+		gtk_widget_show (GTK_WIDGET (statusbar));
+		g_free (exif_desc);
+	} else {
+		gtk_widget_hide (GTK_WIDGET (statusbar));
+	}
+}
+
+
+static void
+selection_changed_cb (EogThumbView *view, WindowData *data)
+{
+	EogImage *image;
+
+	if (!eog_thumb_view_get_n_selected (view)) {
+		return;
+	}
+
+	image = eog_thumb_view_get_first_selected_image (view);
+	g_return_if_fail (image != NULL);
+
+	if (read_gconf_bool_setting (EOG_EXIF_DISPLAY_CONF_UI_DISPLAY_EXIF_STATUSBAR)) {
+		statusbar_update_exif_data (GTK_STATUSBAR (data->statusbar_exif), view);
+	}
+
+	if (!eog_image_has_data (image, EOG_IMAGE_DATA_EXIF)) {
+		EogJob *job;
+
+		job = eog_job_load_new (image, EOG_IMAGE_DATA_EXIF);
+		g_signal_connect (G_OBJECT (job), "finished",
+				  G_CALLBACK (manage_exif_data_cb),
+				  data);
+		eog_job_queue_add_job (job);
+		g_object_unref (job);
+	} else {
+		manage_exif_data (data);
+	}
+
+	/* the selected image changed, the histogram must
+	 * be recalculated. */
+	if (!eog_image_has_data (image, EOG_IMAGE_DATA_IMAGE)) {
+		EogJob *job;
+
+		job = eog_job_load_new (image, EOG_IMAGE_DATA_IMAGE);
+		g_signal_connect (G_OBJECT (job), "finished",
+				  G_CALLBACK (calculate_histogram_cb),
+				  data);
+		eog_job_queue_add_job (job);
+		g_object_unref (job);
+	}
+
+	g_object_unref (image);
+}
+
+static void
+eog_display_histogram_settings_changed_cb (GConfClient *client,
+				       guint       cnxn_id,
+				       GConfEntry  *entry,
+				       gpointer    data)
+{
+	g_return_if_fail (GTK_IS_WIDGET (data));
+
+	/* redrawing the histogram will be enough to make
+	 * that the changes are applied.
+	 */
+	gtk_widget_queue_draw (GTK_WIDGET (data));
+}
+
+static void
+remove_statusbar_entry (WindowData *data)
+{
+	if (data->statusbar_exif == NULL) {
+		return;
+	}
+	GtkWidget *statusbar = eog_window_get_statusbar (data->eog_window);
+	gtk_container_remove (GTK_CONTAINER (statusbar), data->statusbar_exif);
+	data->statusbar_exif = NULL;
+}
+
+static void
+setup_statusbar_exif (WindowData *data)
+{
+	GtkWidget *statusbar = eog_window_get_statusbar (data->eog_window);
+
+	if (read_gconf_bool_setting (EOG_EXIF_DISPLAY_CONF_UI_DISPLAY_EXIF_STATUSBAR)) {
+		data->statusbar_exif = gtk_statusbar_new ();
+		gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (data->statusbar_exif),
+						   FALSE);
+		gtk_widget_set_size_request (data->statusbar_exif, 280, 10);
+		gtk_box_pack_end (GTK_BOX (statusbar),
+				  data->statusbar_exif,
+				  FALSE, FALSE, 0);
+
+		statusbar_update_exif_data (GTK_STATUSBAR (data->statusbar_exif), data->eog_thumb_view);
+	}
+	else {
+		remove_statusbar_entry (data);
+	}
+}
+
+static void
+eog_display_statusbar_settings_changed_cb (GConfClient *client,
+				       guint       cnxn_id,
+				       GConfEntry  *entry,
+				       gpointer    data)
+{
+	setup_statusbar_exif ((WindowData*)data);
+}
+
+static void
+impl_activate (EogPlugin *plugin,
+	       EogWindow *window)
+{
+	WindowData *data;
+	GtkWidget *thumbview;
+	GtkWidget *sidebar;
+	GtkWidget *statusbar = eog_window_get_statusbar (window);
+
+	gconf_client = gconf_client_get_default ();
+
+	data = g_new0(WindowData, 1);
+	g_object_set_data_full (G_OBJECT (window),
+				WINDOW_DATA_KEY,
+				data,
+				(GDestroyNotify) free_window_data);
+
+
+	thumbview = eog_window_get_thumb_view (window);
+	data->eog_window = window;
+	data->eog_thumb_view = EOG_THUMB_VIEW (eog_window_get_thumb_view (window));
+
+	data->histogram_values_red = NULL;
+	data->histogram_values_green = NULL;
+	data->histogram_values_blue = NULL;
+	data->histogram_values_rgb = NULL;
+
+	data->statusbar_exif = NULL;
+	setup_statusbar_exif (data);
+
+	data->selection_changed_id = g_signal_connect (G_OBJECT (thumbview),
+						       "selection-changed",
+						       G_CALLBACK (selection_changed_cb),
+						       data);
+	sidebar = eog_window_get_sidebar (window);
+
+	GError* error = NULL;
+	data->sidebar_builder = gtk_builder_new ();
+	if (!gtk_builder_add_from_file (data->sidebar_builder, GTKBUILDER_FILE, &error))
+	{
+		g_warning ("Couldn't load builder file: %s", error->message);
+		g_error_free (error);
+	}
+	data->gtkbuilder_widget = GTK_WIDGET (gtk_builder_get_object (data->sidebar_builder, "viewport1"));
+
+	GtkWidget *drawing_area = GTK_WIDGET (gtk_builder_get_object (data->sidebar_builder, "drawingarea1"));
+	g_signal_connect (drawing_area, "expose-event", 
+			G_CALLBACK (drawing_area_expose), data);
+	data->drawing_area = GTK_DRAWING_AREA (drawing_area);
+
+	eog_sidebar_add_page (EOG_SIDEBAR (sidebar), "Details", data->gtkbuilder_widget);
+	gtk_widget_show_all (data->gtkbuilder_widget);
+
+	/* force display of data now */
+	selection_changed_cb (data->eog_thumb_view, data);
+	if (read_gconf_bool_setting (EOG_EXIF_DISPLAY_CONF_UI_DISPLAY_EXIF_STATUSBAR)) {
+		statusbar_update_exif_data (GTK_STATUSBAR (data->statusbar_exif),
+				    EOG_THUMB_VIEW (eog_window_get_thumb_view (window)));
+	}
+
+	gconf_client_notify_add (gconf_client,
+			EOG_EXIF_DISPLAY_CONF_UI_DISPLAY_CHANNELS_HISTOGRAM,
+			eog_display_histogram_settings_changed_cb,
+			data->drawing_area, NULL, NULL);
+
+	gconf_client_notify_add (gconf_client,
+			EOG_EXIF_DISPLAY_CONF_UI_DISPLAY_RGB_HISTOGRAM,
+			eog_display_histogram_settings_changed_cb,
+			data->drawing_area, NULL, NULL);
+
+	gconf_client_notify_add (gconf_client,
+			EOG_EXIF_DISPLAY_CONF_UI_DISPLAY_EXIF_STATUSBAR,
+			eog_display_statusbar_settings_changed_cb,
+			data, NULL, NULL);
+}
+
+static void
+impl_deactivate	(EogPlugin *plugin,
+		 EogWindow *window)
+{
+	WindowData *data;
+	GtkWidget *sidebar, *thumbview;
+
+	data = (WindowData *) g_object_get_data (G_OBJECT (window),
+						 WINDOW_DATA_KEY);
+	g_return_if_fail (data != NULL);
+	
+	remove_statusbar_entry (data);
+	
+	sidebar = eog_window_get_sidebar (window);
+	eog_sidebar_remove_page(EOG_SIDEBAR (sidebar), data->gtkbuilder_widget);
+
+	thumbview = eog_window_get_thumb_view (window);
+	g_signal_handler_disconnect (thumbview, data->selection_changed_id);
+
+	g_object_set_data (G_OBJECT (window), WINDOW_DATA_KEY, NULL);
+}
+
+/* copy-pasted from eog-preferences-dialog.c */
+static void
+pd_check_toggle_cb (GtkWidget *widget, gpointer data)
+{
+	char *key = NULL;
+	gboolean invert = FALSE;
+	gboolean value;
+
+	key = g_object_get_data (G_OBJECT (widget), GCONF_OBJECT_KEY);
+	invert = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), TOGGLE_INVERT_VALUE));
+
+	value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+
+	if (key == NULL) return;
+
+	gconf_client_set_bool (GCONF_CLIENT (data),
+			       key,
+			       (invert) ? !value : value,
+			       NULL);
+}
+
+static void
+close_config_window_cb(GtkWidget *widget, gpointer _data)
+{
+	GtkWidget *data = GTK_WIDGET (_data);
+
+	gtk_widget_destroy (GTK_WIDGET (gtk_widget_get_toplevel (data)));
+}
+
+static void
+connect_checkbox_to_gconf_setting (GtkToggleButton *checkbox, char *gconf_key)
+{
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbox),
+				      gconf_client_get_bool (gconf_client,
+							     gconf_key,
+							     NULL));
+
+	g_object_set_data (G_OBJECT (checkbox),
+			   GCONF_OBJECT_KEY,
+			   gconf_key);
+
+	g_signal_connect (G_OBJECT (checkbox),
+			  "toggled",
+			  G_CALLBACK (pd_check_toggle_cb),
+			  gconf_client);
+}
+
+static GtkWidget *
+impl_create_config_dialog (EogPlugin *plugin)
+{
+	GtkBuilder *config_builder;
+	GError *error = NULL;
+	GtkWidget *display_channels_histogram_widget, *display_rgb_histogram_widget;
+	GtkWidget *close_button, *display_camera_settings_in_statusbar;
+	GtkWidget *result;
+
+	config_builder = gtk_builder_new ();
+	if (!gtk_builder_add_from_file (config_builder, GTKBUILDER_CONFIG_FILE, &error))
+	{
+		g_warning ("Couldn't load builder file: %s", error->message);
+		g_error_free (error);
+	}
+	result = GTK_WIDGET (gtk_builder_get_object (config_builder, "config_dialog"));
+	display_channels_histogram_widget = GTK_WIDGET (
+			gtk_builder_get_object (config_builder, "display_per_channel_histogram"));
+	display_rgb_histogram_widget = GTK_WIDGET (
+			gtk_builder_get_object (config_builder, "display_rgb_histogram"));
+	display_camera_settings_in_statusbar = GTK_WIDGET (
+			gtk_builder_get_object (config_builder, "display_camerasettings_statusbar"));
+	close_button = GTK_WIDGET (
+			gtk_builder_get_object (config_builder, "close_button"));
+	g_object_unref (config_builder);
+
+	connect_checkbox_to_gconf_setting (GTK_TOGGLE_BUTTON (display_channels_histogram_widget),
+			EOG_EXIF_DISPLAY_CONF_UI_DISPLAY_CHANNELS_HISTOGRAM);
+	connect_checkbox_to_gconf_setting (GTK_TOGGLE_BUTTON (display_rgb_histogram_widget),
+			EOG_EXIF_DISPLAY_CONF_UI_DISPLAY_RGB_HISTOGRAM);
+	connect_checkbox_to_gconf_setting (GTK_TOGGLE_BUTTON (display_camera_settings_in_statusbar),
+			EOG_EXIF_DISPLAY_CONF_UI_DISPLAY_EXIF_STATUSBAR);
+
+	g_signal_connect (G_OBJECT (close_button),
+			  "clicked",
+			  G_CALLBACK (close_config_window_cb),
+			  GTK_WINDOW (result));
+
+	return result;
+}
+
+static void
+eog_exif_display_plugin_class_init (EogExifDisplayPluginClass *klass)
+{
+	EogPluginClass *plugin_class = EOG_PLUGIN_CLASS (klass);
+
+	plugin_class->activate = impl_activate;
+	plugin_class->deactivate = impl_deactivate;
+	plugin_class->create_configure_dialog = impl_create_config_dialog;
+}
diff --git a/plugins/exif-display/eog-exif-display-plugin.h b/plugins/exif-display/eog-exif-display-plugin.h
new file mode 100644
index 0000000..b09b1be
--- /dev/null
+++ b/plugins/exif-display/eog-exif-display-plugin.h
@@ -0,0 +1,74 @@
+/* Exif-display -- display information about digital pictures
+ *
+ * Copyright (C) 2009 The Free Software Foundation
+ *
+ * Author: Emmanuel Touzery  <emmanuel touzery free fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EOG_EXIF_DISPLAY_PLUGIN_H__
+#define __EOG_EXIF_DISPLAY_PLUGIN_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <eog/eog-plugin.h>
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define EOG_TYPE_EXIF_DISPLAY_PLUGIN		(eog_fit_to_width_plugin_get_type ())
+#define EOG_EXIF_DISPLAY_PLUGIN(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), EOG_TYPE_EXIF_DISPLAY_PLUGIN, EogStatusbarDatePlugin))
+#define EOG_EXIF_DISPLAY_PLUGIN_CLASS(k)	G_TYPE_CHECK_CLASS_CAST((k),      EOG_TYPE_EXIF_DISPLAY_PLUGIN, EogStatusbarDatePluginClass))
+#define EOG_IS_EXIF_DISPLAY_PLUGIN(o)	        (G_TYPE_CHECK_INSTANCE_TYPE ((o), EOG_TYPE_EXIF_DISPLAY_PLUGIN))
+#define EOG_IS_EXIF_DISPLAY_PLUGIN_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k),    EOG_TYPE_EXIF_DISPLAY_PLUGIN))
+#define EOG_EXIF_DISPLAY_PLUGIN_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o),  EOG_TYPE_EXIF_DISPLAY_PLUGIN, EogStatusbarDatePluginClass))
+
+/* Private structure type */
+typedef struct _EogExifDisplayPluginPrivate	EogExifDisplayPluginPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _EogExifDisplayPlugin		EogExifDisplayPlugin;
+
+struct _EogExifDisplayPlugin
+{
+	EogPlugin parent_instance;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _EogExifDisplayPluginClass	EogExifDisplayPluginClass;
+
+struct _EogExifDisplayPluginClass
+{
+	EogPluginClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType	eog_exif_display_plugin_get_type		(void) G_GNUC_CONST;
+
+/* All the plugins must implement this function */
+G_MODULE_EXPORT GType register_eog_plugin (GTypeModule *module);
+
+G_END_DECLS
+
+#endif /* __EOG_EXIF_DISPLAY_PLUGIN_H__ */
diff --git a/plugins/exif-display/exif-display-config.ui b/plugins/exif-display/exif-display-config.ui
new file mode 100644
index 0000000..1c13e26
--- /dev/null
+++ b/plugins/exif-display/exif-display-config.ui
@@ -0,0 +1,172 @@
+<?xml version="1.0"?>
+<interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy project-wide -->
+  <object class="GtkDialog" id="config_dialog">
+    <property name="border_width">5</property>
+    <property name="type_hint">normal</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <object class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child>
+          <object class="GtkVBox" id="vbox1">
+            <property name="visible">True</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">6</property>
+            <child>
+              <object class="GtkLabel" id="label1">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;Histogram&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </object>
+              <packing>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkHBox" id="hbox1">
+                <property name="visible">True</property>
+                <child>
+                  <object class="GtkLabel" id="label2">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">    </property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkVBox" id="vbox2">
+                    <property name="visible">True</property>
+                    <property name="orientation">vertical</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkCheckButton" id="display_per_channel_histogram">
+                        <property name="label" translatable="yes">Display per-channel histogram</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkCheckButton" id="display_rgb_histogram">
+                        <property name="label" translatable="yes">Display RGB histogram</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="label3">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;General&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </object>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkVBox" id="vbox3">
+                <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">6</property>
+                <child>
+                  <object class="GtkHBox" id="hbox2">
+                    <property name="visible">True</property>
+                    <child>
+                      <object class="GtkLabel" id="label4">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">    </property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkCheckButton" id="display_camerasettings_statusbar">
+                        <property name="label" translatable="yes">Display camera settings in statusbar</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">3</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <object class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="close_button">
+                <property name="label" translatable="yes">gtk-close</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="0">close_button</action-widget>
+    </action-widgets>
+  </object>
+</interface>
diff --git a/plugins/exif-display/exif-display.eog-plugin.desktop.in b/plugins/exif-display/exif-display.eog-plugin.desktop.in
new file mode 100644
index 0000000..175e0ee
--- /dev/null
+++ b/plugins/exif-display/exif-display.eog-plugin.desktop.in
@@ -0,0 +1,9 @@
+[Eog Plugin]
+Module=exif-display
+IAge=2
+_Name=Exif display
+Icon=gtk-zoom-fit
+_Description=Displays camera settings and histogram
+Authors=Emmanuel Touzery
+Copyright=Copyright © 2009 Emmanuel Touzery
+Website=http://www.gnome.org/projects/eog
diff --git a/plugins/exif-display/exif-display.ui b/plugins/exif-display/exif-display.ui
new file mode 100644
index 0000000..9b66b83
--- /dev/null
+++ b/plugins/exif-display/exif-display.ui
@@ -0,0 +1,224 @@
+<?xml version="1.0"?>
+<interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy project-wide -->
+  <object class="GtkScrolledWindow" id="viewport1">
+    <property name="visible">True</property>
+    <property name="can_focus">True</property>
+    <property name="hscrollbar_policy">automatic</property>
+    <property name="vscrollbar_policy">automatic</property>
+    <child>
+      <object class="GtkViewport" id="viewport2">
+        <property name="visible">True</property>
+        <property name="resize_mode">queue</property>
+        <child>
+          <object class="GtkVBox" id="vbox1">
+            <property name="visible">True</property>
+            <property name="orientation">vertical</property>
+            <child>
+              <object class="GtkLabel" id="camera_model_label">
+                <property name="visible">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="padding">15</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="takenon_label">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="xpad">5</property>
+                <property name="ellipsize">end</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkTable" id="table1">
+                <property name="visible">True</property>
+                <property name="border_width">5</property>
+                <property name="n_rows">6</property>
+                <property name="n_columns">2</property>
+                <property name="column_spacing">7</property>
+                <property name="row_spacing">5</property>
+                <child>
+                  <object class="GtkLabel" id="label2">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">&lt;b&gt;ISO speed:&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="iso_label">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label3">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Expo. Time:&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                  <packing>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="exposure_time_label">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label4">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Aperture:&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                  <packing>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="aperture_label">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label5">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Zoom:&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                  <packing>
+                    <property name="top_attach">3</property>
+                    <property name="bottom_attach">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="focal_length_label">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">3</property>
+                    <property name="bottom_attach">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label1">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Metering:&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                  <packing>
+                    <property name="top_attach">4</property>
+                    <property name="bottom_attach">5</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="metering_mode_label">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="ellipsize">end</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">4</property>
+                    <property name="bottom_attach">5</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label6">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Expo. bias:&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                  <packing>
+                    <property name="top_attach">5</property>
+                    <property name="bottom_attach">6</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="exposure_bias_label">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">5</property>
+                    <property name="bottom_attach">6</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="flash_label">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="yalign">0</property>
+                <property name="xpad">5</property>
+                <property name="ellipsize">end</property>
+                <property name="max_width_chars">10</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="padding">5</property>
+                <property name="position">3</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkDrawingArea" id="drawingarea1">
+                <property name="height_request">60</property>
+                <property name="visible">True</property>
+              </object>
+              <packing>
+                <property name="position">4</property>
+              </packing>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]