diff src/bar_exif.c @ 1350:9d190c098b97

rewritten exif pane to support arbitrary number of entries
author nadvornik
date Sat, 28 Feb 2009 23:59:02 +0000
parents eebb8d0cb677
children d9197358ec5a
line wrap: on
line diff
--- 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);
 }