changeset 95:eb9bb29cbd65

Fri Nov 3 11:40:48 2006 John Ellis <johne@verizon.net> * bar_exif.[ch]: Make list of general exif tags available to rest of application. * pan-view.c: Add option to display exif information in info popup. Clean up the info popup text alignment. Make displaying the full size image below the info popup optional (off by default). * pixbuf-renderer.c (pr_source_tile_changed): Guard against width/height less than 1. * pibuf_util.c (pixbuf_draw_layout): Guard against width/height less than 1.
author gqview
date Fri, 03 Nov 2006 16:49:29 +0000
parents 50dc5a14d37b
children 8c0bec943cdc
files ChangeLog src/bar_exif.c src/bar_exif.h src/pan-view.c src/pixbuf-renderer.c src/pixbuf_util.c
diffstat 6 files changed, 291 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Nov 02 23:27:03 2006 +0000
+++ b/ChangeLog	Fri Nov 03 16:49:29 2006 +0000
@@ -1,3 +1,15 @@
+Fri Nov  3 11:40:48 2006  John Ellis  <johne@verizon.net>
+
+	* bar_exif.[ch]: Make list of general exif tags available to rest of
+	application.
+	* pan-view.c: Add option to display exif information in info popup.
+	Clean up the info popup text alignment. Make displaying the full size
+	image below the info popup optional (off by default).
+	* pixbuf-renderer.c (pr_source_tile_changed): Guard against
+	width/height less than 1.
+	* pibuf_util.c (pixbuf_draw_layout): Guard against width/height less
+	than 1.
+
 Thu Nov  2 17:51:31 2006  John Ellis  <johne@verizon.net>
 
 	* collect.c, img-view.c: Make [Shift]+P printing shortcut work for
--- a/src/bar_exif.c	Thu Nov 02 23:27:03 2006 +0000
+++ b/src/bar_exif.c	Fri Nov 03 16:49:29 2006 +0000
@@ -26,7 +26,7 @@
 
 #define BAR_EXIF_DATA_COLUMN_WIDTH 250
 
-static const gchar *bar_exif_key_list[] = {
+static const gchar *bar_exif_key_list_real[] = {
 	"fCamera",
 	"fDateTime",
 	"fShutterSpeed",
@@ -45,7 +45,8 @@
 	"Copyright"
 };
 
-#define bar_exif_key_count (sizeof(bar_exif_key_list) / sizeof(gchar *))
+const gchar **bar_exif_key_list = bar_exif_key_list_real;
+const gint bar_exif_key_count = (sizeof(bar_exif_key_list_real) / sizeof(gchar *));
 
 
 /*
@@ -134,7 +135,7 @@
 	EXIF_ADVCOL_COUNT
 };
 
-static gchar *bar_exif_validate_text(gchar *text)
+gchar *bar_exif_validate_text(gchar *text)
 {
 	if (text && !g_utf8_validate(text, strlen(text), NULL))
 		{
--- a/src/bar_exif.h	Thu Nov 02 23:27:03 2006 +0000
+++ b/src/bar_exif.h	Fri Nov 03 16:49:29 2006 +0000
@@ -22,5 +22,13 @@
 gint bar_exif_is_advanced(GtkWidget *bar);
 
 
+/* these are exposed for when duplication of the exif bar's text is needed */
+
+const gchar **bar_exif_key_list;
+const gint bar_exif_key_count;
+
+gchar *bar_exif_validate_text(gchar *text);
+
+
 #endif
 
--- a/src/pan-view.c	Thu Nov 02 23:27:03 2006 +0000
+++ b/src/pan-view.c	Fri Nov 03 16:49:29 2006 +0000
@@ -13,10 +13,12 @@
 #include "gqview.h"
 #include "pan-view.h"
 
+#include "bar_exif.h"
 #include "cache.h"
 #include "cache-loader.h"
 #include "dnd.h"
 #include "editors.h"
+#include "exif.h"
 #include "filelist.h"
 #include "fullscreen.h"
 #include "image.h"
@@ -123,9 +125,11 @@
 #define ZOOM_LABEL_WIDTH 64
 
 
-#define PAN_PREF_GROUP "pan_view_options"
-#define PAN_PREF_HIDE_WARNING "hide_performance_warning"
-#define PAN_PREF_EXIF_DATE "use_exif_date"
+#define PAN_PREF_GROUP		"pan_view_options"
+#define PAN_PREF_HIDE_WARNING	"hide_performance_warning"
+#define PAN_PREF_EXIF_DATE	"use_exif_date"
+#define PAN_PREF_INFO_IMAGE	"info_includes_image"
+#define PAN_PREF_INFO_EXIF	"info_includes_exif"
 
 
 typedef enum {
@@ -240,6 +244,9 @@
 	gint image_size;
 	gint exif_date_enable;
 
+	gint info_includes_image;
+	gint info_includes_exif;
+
 	gint ignore_symlinks;
 
 	GList *list;
@@ -955,11 +962,12 @@
 	pango_layout_get_pixel_size(layout, &pi->width, &pi->height);
 	g_object_unref(G_OBJECT(layout));
 
-	pi->width += PAN_TEXT_BORDER_SIZE * 2;
-	pi->height += PAN_TEXT_BORDER_SIZE * 2;
+	pi->width += pi->border * 2;
+	pi->height += pi->border * 2;
 }
 
 static PanItem *pan_item_new_text(PanWindow *pw, gint x, gint y, const gchar *text, TextAttrType attr,
+				  gint border,
 				  guint8 r, guint8 g, guint8 b, guint8 a)
 {
 	PanItem *pi;
@@ -976,6 +984,8 @@
 	pi->color_b = b;
 	pi->color_a = a;
 
+	pi->border = border;
+
 	pan_item_text_compute_size(pi, pw->imd->pr);
 
 	pw->list = g_list_prepend(pw->list, pi);
@@ -1637,6 +1647,7 @@
 	d = filelist_sort(d, SORT_NAME, TRUE);
 
 	pi_box = pan_item_new_text(pw, x, y, path, TEXT_ATTR_NONE,
+				   PAN_TEXT_BORDER_SIZE,
 				   PAN_TEXT_COLOR, 255);
 
 	y += pi_box->height;
@@ -1782,6 +1793,7 @@
 	*x = PAN_FOLDER_BOX_BORDER + ((*level) * MAX(PAN_FOLDER_BOX_BORDER, PAN_THUMB_GAP));
 
 	pi_box = pan_item_new_text(pw, *x, *y, path, TEXT_ATTR_NONE,
+				   PAN_TEXT_BORDER_SIZE,
 				   PAN_TEXT_COLOR, 255);
 
 	*y += pi_box->height;
@@ -1940,6 +1952,7 @@
 
 		buf = date_value_string(pi_day->fd->date, DATE_LENGTH_WEEK);
 		plabel = pan_item_new_text(pw, x, y, buf, TEXT_ATTR_BOLD | TEXT_ATTR_HEADING,
+					   PAN_TEXT_BORDER_SIZE,
 					   PAN_CAL_POPUP_TEXT_COLOR, 255);
 		pan_item_set_key(plabel, "day_bubble");
 		g_free(buf);
@@ -2116,8 +2129,9 @@
 					    PAN_CAL_MONTH_BORDER_COLOR, PAN_CAL_MONTH_ALPHA);
 		buf = date_value_string(dt, DATE_LENGTH_MONTH);
 		pi_text = pan_item_new_text(pw, x, y, buf,
-					     TEXT_ATTR_BOLD | TEXT_ATTR_HEADING,
-					     PAN_CAL_MONTH_TEXT_COLOR, 255);
+					    TEXT_ATTR_BOLD | TEXT_ATTR_HEADING,
+					    PAN_TEXT_BORDER_SIZE,
+					    PAN_CAL_MONTH_TEXT_COLOR, 255);
 		g_free(buf);
 		pi_text->x = pi_month->x + (pi_month->width - pi_text->width) / 2;
 
@@ -2187,6 +2201,7 @@
 
 				buf = g_strdup_printf("( %d )", n);
 				pi = pan_item_new_text(pw, x, y, buf, TEXT_ATTR_NONE,
+						       PAN_TEXT_BORDER_SIZE,
 						       PAN_CAL_DAY_TEXT_COLOR, 255);
 				g_free(buf);
 
@@ -2196,6 +2211,7 @@
 
 			buf = g_strdup_printf("%d", day);
 			pan_item_new_text(pw, x + 4, y + 4, buf, TEXT_ATTR_BOLD | TEXT_ATTR_HEADING,
+					  PAN_TEXT_BORDER_SIZE,
 					  PAN_CAL_DAY_TEXT_COLOR, 255);
 			g_free(buf);
 
@@ -2304,6 +2320,7 @@
 				buf = date_value_string(fd->date, DATE_LENGTH_MONTH);
 				pi = pan_item_new_text(pw, x, y, buf,
 						       TEXT_ATTR_BOLD | TEXT_ATTR_HEADING,
+						       PAN_TEXT_BORDER_SIZE,
 						       PAN_TEXT_COLOR, 255);
 				g_free(buf);
 				y += pi->height;
@@ -2344,6 +2361,7 @@
 
 			buf = date_value_string(fd->date, DATE_LENGTH_WEEK);
 			pi = pan_item_new_text(pw, x, y, buf, TEXT_ATTR_NONE,
+					       PAN_TEXT_BORDER_SIZE,
 					       PAN_TEXT_COLOR, 255);
 			g_free(buf);
 
@@ -3085,7 +3103,7 @@
 
 			layout = pan_item_text_layout(pi, (GtkWidget *)pr);
 			pixbuf_draw_layout(pixbuf, layout, (GtkWidget *)pr,
-					   pi->x - x + PAN_TEXT_BORDER_SIZE, pi->y - y + PAN_TEXT_BORDER_SIZE,
+					   pi->x - x + pi->border, pi->y - y + pi->border,
 					   pi->color_r, pi->color_g, pi->color_b, pi->color_a);
 			g_object_unref(G_OBJECT(layout));
 			}
@@ -3651,10 +3669,198 @@
  *-----------------------------------------------------------------------------
  */
 
+typedef struct _PanTextAlignment PanTextAlignment;
+struct _PanTextAlignment {
+	PanWindow *pw;
+
+	GList *column1;
+	GList *column2;
+
+	gint x;
+	gint y;
+	gchar *key;
+};
+
+
+static PanTextAlignment *pan_text_alignment_new(PanWindow *pw, gint x, gint y, const gchar *key)
+{
+	PanTextAlignment *ta;
+
+	ta = g_new0(PanTextAlignment, 1);
+
+	ta->pw = pw;
+	ta->column1 = NULL;
+	ta->column2 = NULL;
+	ta->x = x;
+	ta->y = y;
+	ta->key = g_strdup(key);
+
+	return ta;
+}
+
+static PanItem *pan_text_alignment_add(PanTextAlignment *ta,
+				       const gchar *label, const gchar *text)
+{
+	PanItem *item;
+
+	if (label)
+		{
+		item = pan_item_new_text(ta->pw, ta->x, ta->y, label,
+					 TEXT_ATTR_BOLD, 0,
+					 PAN_POPUP_TEXT_COLOR, 255);
+		pan_item_set_key(item, ta->key);
+		}
+	else
+		{
+		item = NULL;
+		}
+	ta->column1 = g_list_append(ta->column1, item);
+
+	if (text)
+		{
+		item = pan_item_new_text(ta->pw, ta->x, ta->y, text,
+					 TEXT_ATTR_NONE, 0,
+					 PAN_POPUP_TEXT_COLOR, 255);
+		pan_item_set_key(item, ta->key);
+		}
+	else
+		{
+		item = NULL;
+		}
+	ta->column2 = g_list_append(ta->column2, item);
+
+	return item;
+}
+
+static void pan_text_alignment_calc(PanTextAlignment *ta, PanItem *box)
+{
+	gint cw1, cw2;
+	gint x, y;
+	GList *work1;
+	GList *work2;
+
+	cw1 = 0;
+	cw2 = 0;
+
+	work1 = ta->column1;
+	while (work1)
+		{
+		PanItem *p;
+
+		p = work1->data;
+		work1 = work1->next;
+
+		if (p && p->width > cw1) cw1 = p->width;
+		}
+
+	work2 = ta->column2;
+	while (work2)
+		{
+		PanItem *p;
+
+		p = work2->data;
+		work2 = work2->next;
+
+		if (p && p->width > cw2) cw2 = p->width;
+		}
+
+	x = ta->x;
+	y = ta->y;
+	work1 = ta->column1;
+	work2 = ta->column2;
+	while (work1 && work2)
+		{
+		PanItem *p1;
+		PanItem *p2;
+		gint height = 0;
+
+		p1 = work1->data;
+		p2 = work2->data;
+		work1 = work1->next;
+		work2 = work2->next;
+
+		if (p1)
+			{
+			p1->x = x;
+			p1->y = y;
+			pan_item_size_by_item(box, p1, PREF_PAD_BORDER);
+			height = p1->height;
+			}
+		if (p2)
+			{
+			p2->x = x + cw1 + PREF_PAD_SPACE;
+			p2->y = y;
+			pan_item_size_by_item(box, p2, PREF_PAD_BORDER);
+			if (height < p2->height) height = p2->height;
+			}
+
+		if (!p1 && !p2) height = PREF_PAD_GROUP;
+
+		y += height;
+		}
+}
+
+static void pan_text_alignment_free(PanTextAlignment *ta)
+{
+	if (!ta) return;
+
+	g_list_free(ta->column1);
+	g_list_free(ta->column2);
+	g_free(ta->key);
+	g_free(ta);
+}
+
+static void pan_info_add_exif(PanTextAlignment *ta, FileData *fd)
+{
+	ExifData *exif;
+	GList *work;
+	gint i;
+
+	if (!fd) return;
+	exif = exif_read(fd->path);
+	if (!exif) return;
+
+	pan_text_alignment_add(ta, NULL, NULL);
+
+	for (i = 0; i < bar_exif_key_count; i++)
+		{
+		gchar *label;
+		gchar *text;
+
+		label = g_strdup_printf("%s:", exif_get_description_by_key(bar_exif_key_list[i]));
+		text = exif_get_data_as_text(exif, bar_exif_key_list[i]);
+		text = bar_exif_validate_text(text);
+		pan_text_alignment_add(ta, label, text);
+		g_free(label);
+		g_free(text);
+		}
+
+	work = g_list_last(history_list_get_by_key("exif_extras"));
+	if (work) pan_text_alignment_add(ta, "---", NULL);
+	while (work)
+		{
+		const gchar *name;
+		gchar *label;
+		gchar *text;
+
+		name = work->data;
+		work = work->prev;
+
+		label = g_strdup_printf("%s:", name);
+		text = exif_get_data_as_text(exif, name);
+		text = bar_exif_validate_text(text);
+		pan_text_alignment_add(ta, label, text);
+		g_free(label);
+		g_free(text);
+		}
+
+	exif_free(exif);
+}
+
 static void pan_info_update(PanWindow *pw, PanItem *pi)
 {
+	PanTextAlignment *ta;
 	PanItem *pbox;
-	PanItem *plabel;
 	PanItem *p;
 	gchar *buf;
 	gint x1, y1, x2, y2, x3, y3;
@@ -3704,42 +3910,26 @@
 	pan_item_set_key(p, "info");
 	pan_item_added(pw, p);
 
-	plabel = pan_item_new_text(pw, pbox->x, pbox->y,
-				   _("Filename:"), TEXT_ATTR_BOLD,
-				   PAN_POPUP_TEXT_COLOR, 255);
-	pan_item_set_key(plabel, "info");
-	p = pan_item_new_text(pw, plabel->x + plabel->width, plabel->y,
-			      pi->fd->name, TEXT_ATTR_NONE,
-			      PAN_POPUP_TEXT_COLOR, 255);
-	pan_item_set_key(p, "info");
-	pan_item_size_by_item(pbox, p, 0);
-
-	plabel = pan_item_new_text(pw, plabel->x, plabel->y + plabel->height,
-				   _("Date:"), TEXT_ATTR_BOLD,
-				   PAN_POPUP_TEXT_COLOR, 255);
-	pan_item_set_key(plabel, "info");
-	p = pan_item_new_text(pw, plabel->x + plabel->width, plabel->y,
-			      text_from_time(pi->fd->date), TEXT_ATTR_NONE,
-			      PAN_POPUP_TEXT_COLOR, 255);
-	pan_item_set_key(p, "info");
-	pan_item_size_by_item(pbox, p, 0);
-
-	plabel = pan_item_new_text(pw, plabel->x, plabel->y + plabel->height,
-				   _("Size:"), TEXT_ATTR_BOLD,
-				   PAN_POPUP_TEXT_COLOR, 255);
-	pan_item_set_key(plabel, "info");
+	ta = pan_text_alignment_new(pw, pbox->x + PREF_PAD_BORDER, pbox->y + PREF_PAD_BORDER, "info");
+
+	pan_text_alignment_add(ta, _("Filename:"), pi->fd->name);
+	pan_text_alignment_add(ta, _("Date:"), text_from_time(pi->fd->date));
 	buf = text_from_size(pi->fd->size);
-	p = pan_item_new_text(pw, plabel->x + plabel->width, plabel->y,
-			      buf, TEXT_ATTR_NONE,
-			      PAN_POPUP_TEXT_COLOR, 255);
+	pan_text_alignment_add(ta, _("Size:"), buf);
 	g_free(buf);
-	pan_item_set_key(p, "info");
-	pan_item_size_by_item(pbox, p, 0);
+
+	if (pw->info_includes_exif)
+		{
+		pan_info_add_exif(ta, pi->fd);
+		}
+
+	pan_text_alignment_calc(ta, pbox);
+	pan_text_alignment_free(ta);
 
 	pan_item_box_shadow(pbox, PAN_SHADOW_OFFSET * 2, PAN_SHADOW_FADE * 2);
 	pan_item_added(pw, pbox);
 
-	if (TRUE)
+	if (pw->info_includes_image)
 		{
 		gint iw, ih;
 		if (image_load_dimensions(pi->fd->path, &iw, &ih))
@@ -3751,9 +3941,9 @@
 			pan_item_set_key(pbox, "info");
 
 			p = pan_item_new_image(pw, file_data_new_simple(pi->fd->path),
-					       pbox->x + 8, pbox->y + 8, iw, ih);
+					       pbox->x + PREF_PAD_BORDER, pbox->y + PREF_PAD_BORDER, iw, ih);
 			pan_item_set_key(p, "info");
-			pan_item_size_by_item(pbox, p, 8);
+			pan_item_size_by_item(pbox, p, PREF_PAD_BORDER);
 
 			pan_item_box_shadow(pbox, PAN_SHADOW_OFFSET * 2, PAN_SHADOW_FADE * 2);
 			pan_item_added(pw, pbox);
@@ -4408,6 +4598,8 @@
 	pan_window_list = g_list_remove(pan_window_list, pw);
 
 	pref_list_int_set(PAN_PREF_GROUP, PAN_PREF_EXIF_DATE, pw->exif_date_enable);
+	pref_list_int_set(PAN_PREF_GROUP, PAN_PREF_INFO_IMAGE, pw->info_includes_image);
+	pref_list_int_set(PAN_PREF_GROUP, PAN_PREF_INFO_EXIF, pw->info_includes_exif);
 
 	if (pw->idle_id != -1)
 		{
@@ -4456,6 +4648,14 @@
 		{
 		pw->exif_date_enable = FALSE;
 		}
+	if (!pref_list_int_get(PAN_PREF_GROUP, PAN_PREF_INFO_IMAGE, &pw->info_includes_image))
+		{
+		pw->info_includes_image = FALSE;
+		}
+	if (!pref_list_int_get(PAN_PREF_GROUP, PAN_PREF_INFO_EXIF, &pw->info_includes_exif))
+		{
+		pw->info_includes_exif = TRUE;
+		}
 
 	pw->ignore_symlinks = TRUE;
 
@@ -4849,6 +5049,22 @@
 	pan_window_layout_update(pw);
 }
 
+static void pan_info_toggle_exif_cb(GtkWidget *widget, gpointer data)
+{
+	PanWindow *pw = data;
+
+	pw->info_includes_exif = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
+	/* fixme: sync info now */
+}
+
+static void pan_info_toggle_image_cb(GtkWidget *widget, gpointer data)
+{
+	PanWindow *pw = data;
+
+	pw->info_includes_image = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
+	/* fixme: sync info now */
+}
+
 static void pan_fullscreen_cb(GtkWidget *widget, gpointer data)
 {
 	PanWindow *pw = data;
@@ -4906,6 +5122,12 @@
 	gtk_widget_set_sensitive(item, (pw->layout == LAYOUT_TIMELINE || pw->layout == LAYOUT_CALENDAR));
 
 	menu_item_add_divider(menu);
+	menu_item_add_check(menu, _("Show EXIF information"), pw->info_includes_exif,
+			    G_CALLBACK(pan_info_toggle_exif_cb), pw);
+	menu_item_add_check(menu, _("Show full size image"), pw->info_includes_image,
+			    G_CALLBACK(pan_info_toggle_image_cb), pw);
+
+	menu_item_add_divider(menu);
 
 	if (pw->fs)
 		{
--- a/src/pixbuf-renderer.c	Thu Nov 02 23:27:03 2006 +0000
+++ b/src/pixbuf-renderer.c	Fri Nov 03 16:49:29 2006 +0000
@@ -1399,6 +1399,8 @@
 {
 	GList *work;
 
+	if (width < 1 || height < 1) return;
+
 	work = pr->source_tiles;
 	while (work)
 		{
--- a/src/pixbuf_util.c	Thu Nov 02 23:27:03 2006 +0000
+++ b/src/pixbuf_util.c	Fri Nov 03 16:49:29 2006 +0000
@@ -616,6 +616,8 @@
 	if (!widget || !widget->window) return;
 
 	pango_layout_get_pixel_size(layout, &w, &h);
+	if (w < 1 || h < 1) return;
+
 	pixmap = gdk_pixmap_new(widget->window, w, h, -1);
 
 	gc = gdk_gc_new(widget->window);