[evolution] Teach ETable to prefer themed icon names over pixbufs.



commit 28b84ecaf9111f2a59e1380089dad6a92ddc848d
Author: Matthew Barnes <mbarnes redhat com>
Date:   Mon Jan 4 22:52:24 2010 -0500

    Teach ETable to prefer themed icon names over pixbufs.

 calendar/gui/e-memo-table.c          |   14 +-
 calendar/gui/e-task-table.c          |   21 +--
 mail/message-list.c                  |  132 +++++------
 widgets/table/e-cell-checkbox.c      |   14 +-
 widgets/table/e-cell-toggle.c        |  416 +++++++++++++++++++++------------
 widgets/table/e-cell-toggle.h        |   59 +++--
 widgets/table/e-table-col.c          |  108 ++++------
 widgets/table/e-table-col.h          |  125 ++++++-----
 widgets/table/e-table-extras.c       |   59 +++---
 widgets/table/e-table-extras.h       |   11 +-
 widgets/table/e-table-header-utils.c |   10 +-
 widgets/table/e-table-utils.c        |   30 ++-
 12 files changed, 539 insertions(+), 460 deletions(-)
---
diff --git a/calendar/gui/e-memo-table.c b/calendar/gui/e-memo-table.c
index ee67baa..62c0b99 100644
--- a/calendar/gui/e-memo-table.c
+++ b/calendar/gui/e-memo-table.c
@@ -87,12 +87,10 @@ static gpointer parent_class;
 static guint signals[LAST_SIGNAL];
 
 /* The icons to represent the task. */
-#define NUM_ICONS 2
-static const gchar *icon_names[NUM_ICONS] = {
+static const gchar *icon_names[] = {
 	"stock_notes",
 	"stock_insert-note"
 };
-static GdkPixbuf *icon_pixbufs[NUM_ICONS] = { NULL };
 
 static void
 memo_table_emit_open_component (EMemoTable *memo_table,
@@ -347,7 +345,6 @@ memo_table_constructed (GObject *object)
 	ECalModel *model;
 	ECell *cell, *popup_cell;
 	ETableExtras *extras;
-	gint i;
 	AtkObject *a11y;
 	gchar *etspecfile;
 
@@ -400,14 +397,9 @@ memo_table_constructed (GObject *object)
 
 	/* Create pixmaps */
 
-	if (!icon_pixbufs[0])
-		for (i = 0; i < NUM_ICONS; i++) {
-			icon_pixbufs[i] = e_icon_factory_get_icon (icon_names[i], GTK_ICON_SIZE_MENU);
-		}
-
-	cell = e_cell_toggle_new (0, NUM_ICONS, icon_pixbufs);
+	cell = e_cell_toggle_new (icon_names, G_N_ELEMENTS (icon_names));
 	e_table_extras_add_cell (extras, "icon", cell);
-	e_table_extras_add_pixbuf (extras, "icon", icon_pixbufs[0]);
+	e_table_extras_add_icon_name (extras, "icon", "stock_notes");
 
 	/* set proper format component for a default 'date' cell renderer */
 	cell = e_table_extras_get_cell (extras, "date");
diff --git a/calendar/gui/e-task-table.c b/calendar/gui/e-task-table.c
index c4d364a..5136a56 100644
--- a/calendar/gui/e-task-table.c
+++ b/calendar/gui/e-task-table.c
@@ -91,14 +91,12 @@ static gpointer parent_class;
 static guint signals[LAST_SIGNAL];
 
 /* The icons to represent the task. */
-#define NUM_ICONS 4
-static const gchar *icon_names[NUM_ICONS] = {
+static const gchar *icon_names[] = {
 	"stock_task",
 	"stock_task-recurring",
 	"stock_task-assigned",
 	"stock_task-assigned-to"
 };
-static GdkPixbuf *icon_pixbufs[NUM_ICONS] = { NULL };
 
 static void
 task_table_emit_open_component (ETaskTable *task_table,
@@ -384,8 +382,6 @@ task_table_constructed (GObject *object)
 	ECalModel *model;
 	ECell *cell, *popup_cell;
 	ETableExtras *extras;
-	gint i;
-	GdkPixbuf *pixbuf;
 	GList *strings;
 	AtkObject *a11y;
 	gchar *etspecfile;
@@ -575,18 +571,11 @@ task_table_constructed (GObject *object)
 
 	/* Create pixmaps */
 
-	if (!icon_pixbufs[0])
-		for (i = 0; i < NUM_ICONS; i++) {
-			icon_pixbufs[i] = e_icon_factory_get_icon (icon_names[i], GTK_ICON_SIZE_MENU);
-		}
-
-	cell = e_cell_toggle_new (0, NUM_ICONS, icon_pixbufs);
-	e_table_extras_add_cell(extras, "icon", cell);
-	e_table_extras_add_pixbuf(extras, "icon", icon_pixbufs[0]);
+	cell = e_cell_toggle_new (icon_names, G_N_ELEMENTS (icon_names));
+	e_table_extras_add_cell (extras, "icon", cell);
+	e_table_extras_add_icon_name (extras, "icon", "stock_task");
 
-	pixbuf = e_icon_factory_get_icon ("stock_check-filled", GTK_ICON_SIZE_MENU);
-	e_table_extras_add_pixbuf(extras, "complete", pixbuf);
-	g_object_unref(pixbuf);
+	e_table_extras_add_icon_name (extras, "complete", "stock_check-filled");
 
 	/* set proper format component for a default 'date' cell renderer */
 	cell = e_table_extras_get_cell (extras, "date");
diff --git a/mail/message-list.c b/mail/message-list.c
index 014e60c..288b4a5 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -77,8 +77,6 @@
 #include "mail-tools.h"
 #include "message-list.h"
 
-#include "art/empty.xpm"
-
 /*#define TIMEIT */
 
 #ifdef TIMEIT
@@ -225,29 +223,40 @@ enum {
 
 static guint message_list_signals [LAST_SIGNAL] = {0, };
 
-static struct {
-	const gchar *icon_name;
-	GdkPixbuf *pixbuf;
-} states_pixmaps[] = {
-	{ "mail-unread",                       NULL },
-	{ "mail-read",                         NULL },
-	{ "mail-replied",                      NULL },
-	{ "mail-forward",                      NULL },
-	{ "stock_mail-unread-multiple",        NULL },
-	{ "stock_mail-open-multiple",          NULL },
-	{ NULL,                                NULL },
-	{ "mail-attachment",                   NULL },
-	{ "emblem-important",                  NULL },
-	{ "stock_score-lowest",                NULL },
-	{ "stock_score-lower",                 NULL },
-	{ "stock_score-low",                   NULL },
-	{ "stock_score-normal",                NULL },
-	{ "stock_score-high",                  NULL },
-	{ "stock_score-higher",                NULL },
-	{ "stock_score-highest",               NULL },
-	{ "stock_mail-flag-for-followup",      NULL },
-	{ "stock_mail-flag-for-followup-done", NULL },
-	{ "stock_new-meeting",                 NULL }
+static const gchar *status_icons[] = {
+	"mail-unread",
+	"mail-read",
+	"mail-replied",
+	"mail-forward",
+	"stock_mail-unread-multiple",
+	"stock_mail-open-multiple"
+};
+
+static const gchar *score_icons[] = {
+	"stock_score-lowest",
+	"stock_score-lower",
+	"stock_score-low",
+	"stock_score-normal",
+	"stock_score-high",
+	"stock_score-higher",
+	"stock_score-highest"
+};
+
+static const gchar *attachment_icons[] = {
+	NULL,  /* empty icon */
+	"mail-attachment",
+	"stock_new-meeting"
+};
+
+static const gchar *flagged_icons[] = {
+	NULL,  /* empty icon */
+	"emblem-important"
+};
+
+static const gchar *followup_icons[] = {
+	NULL,  /* empty icon */
+	"stock_mail-flag-for-followup",
+	"stock_mail-flag-for-followup-done"
 };
 
 /* FIXME: junk prefs */
@@ -1721,25 +1730,6 @@ ml_tree_is_cell_editable (ETreeModel *etm, ETreePath path, gint col, gpointer mo
 	return FALSE;
 }
 
-static void
-message_list_init_images (void)
-{
-	gint i;
-
-	/*
-	 * Only load once, and share
-	 */
-	if (states_pixmaps[0].pixbuf)
-		return;
-
-	for (i = 0; i < G_N_ELEMENTS (states_pixmaps); i++) {
-		if (states_pixmaps[i].icon_name)
-			states_pixmaps[i].pixbuf = e_icon_factory_get_icon (states_pixmaps[i].icon_name, GTK_ICON_SIZE_MENU);
-		else
-			states_pixmaps[i].pixbuf = gdk_pixbuf_new_from_xpm_data ((const gchar **) empty_xpm);
-	}
-}
-
 static gchar *
 filter_date (time_t date)
 {
@@ -1805,11 +1795,9 @@ filter_date (time_t date)
 static ECell * create_composite_cell (gint col)
 {
 	ECell *cell_vbox, *cell_hbox, *cell_sub, *cell_date, *cell_from, *cell_tree, *cell_attach;
-	GdkPixbuf *images [7];
 	GConfClient *gconf;
 	gchar *fixed_name = NULL;
 	gboolean show_email;
-	gint i;
 	gint alt_col = (col == COL_FROM) ? COL_SENDER : COL_RECIPIENTS;
 	gboolean same_font = FALSE;
 
@@ -1823,9 +1811,8 @@ static ECell * create_composite_cell (gint col)
 
 	cell_hbox = e_cell_hbox_new ();
 
-	for (i = 0; i < 2; i++)
-		images [i] = states_pixmaps [i + 6].pixbuf;
-	cell_attach = e_cell_toggle_new (0, 2, images);
+	/* Exclude the meeting icon. */
+	cell_attach = e_cell_toggle_new (attachment_icons, 2);
 
 	cell_date = e_cell_date_new (NULL, GTK_JUSTIFY_RIGHT);
 	e_cell_date_set_format_component (E_CELL_DATE (cell_date), "mail");
@@ -1872,42 +1859,37 @@ composite_cell_set_strike_col (ECell *cell, gint col)
 static ETableExtras *
 message_list_create_extras (void)
 {
-	gint i;
-	GdkPixbuf *images [7];
 	ETableExtras *extras;
 	ECell *cell;
 
 	extras = e_table_extras_new ();
-	e_table_extras_add_pixbuf (extras, "status", states_pixmaps [0].pixbuf);
-	e_table_extras_add_pixbuf (extras, "score", states_pixmaps [14].pixbuf);
-	e_table_extras_add_pixbuf (extras, "attachment", states_pixmaps [7].pixbuf);
-	e_table_extras_add_pixbuf (extras, "flagged", states_pixmaps [8].pixbuf);
-	e_table_extras_add_pixbuf (extras, "followup", states_pixmaps [16].pixbuf);
+	e_table_extras_add_icon_name (extras, "status", "mail-unread");
+	e_table_extras_add_icon_name (extras, "score", "stock_score-higher");
+	e_table_extras_add_icon_name (extras, "attachment", "mail-attachment");
+	e_table_extras_add_icon_name (extras, "flagged", "emblem-important");
+	e_table_extras_add_icon_name (extras, "followup", "stock_mail-flag-for-followup");
 
 	e_table_extras_add_compare (extras, "address_compare", address_compare);
 
-	for (i = 0; i < 6; i++)
-		images [i] = states_pixmaps [i].pixbuf;
-
-	e_table_extras_add_cell (extras, "render_message_status", e_cell_toggle_new (0, 6, images));
+	cell = e_cell_toggle_new (
+		status_icons, G_N_ELEMENTS (status_icons));
+	e_table_extras_add_cell (extras, "render_message_status", cell);
 
-	for (i = 0; i < 2; i++)
-		images [i] = states_pixmaps [i + 6].pixbuf;
-	images [2] = states_pixmaps [18].pixbuf;
+	cell = e_cell_toggle_new (
+		attachment_icons, G_N_ELEMENTS (attachment_icons));
+	e_table_extras_add_cell (extras, "render_attachment", cell);
 
-	e_table_extras_add_cell (extras, "render_attachment", e_cell_toggle_new (0, 3, images));
+	cell = e_cell_toggle_new (
+		flagged_icons, G_N_ELEMENTS (flagged_icons));
+	e_table_extras_add_cell (extras, "render_flagged", cell);
 
-	images [1] = states_pixmaps [8].pixbuf;
-	e_table_extras_add_cell (extras, "render_flagged", e_cell_toggle_new (0, 2, images));
+	cell = e_cell_toggle_new (
+		followup_icons, G_N_ELEMENTS (followup_icons));
+	e_table_extras_add_cell (extras, "render_flag_status", cell);
 
-	images[1] = states_pixmaps [16].pixbuf;
-	images[2] = states_pixmaps [17].pixbuf;
-	e_table_extras_add_cell (extras, "render_flag_status", e_cell_toggle_new (0, 3, images));
-
-	for (i = 0; i < 7; i++)
-		images[i] = states_pixmaps [i + 8].pixbuf;
-
-	e_table_extras_add_cell (extras, "render_score", e_cell_toggle_new (0, 7, images));
+	cell = e_cell_toggle_new (
+		score_icons, G_N_ELEMENTS (score_icons));
+	e_table_extras_add_cell (extras, "render_score", cell);
 
 	/* date cell */
 	cell = e_cell_date_new (NULL, GTK_JUSTIFY_LEFT);
@@ -2581,8 +2563,6 @@ message_list_class_init (MessageListClass *class)
 			      NULL,
 			      g_cclosure_marshal_VOID__VOID,
 			      G_TYPE_NONE, 0);
-
-	message_list_init_images ();
 }
 
 static void
diff --git a/widgets/table/e-cell-checkbox.c b/widgets/table/e-cell-checkbox.c
index 583793e..b01e6c1 100644
--- a/widgets/table/e-cell-checkbox.c
+++ b/widgets/table/e-cell-checkbox.c
@@ -35,7 +35,7 @@
 #include "check-empty.xpm"
 #include "check-filled.xpm"
 
-G_DEFINE_TYPE (ECellCheckbox, e_cell_checkbox, E_CELL_TOGGLE_TYPE)
+G_DEFINE_TYPE (ECellCheckbox, e_cell_checkbox, E_TYPE_CELL_TOGGLE)
 
 static GdkPixbuf *checks [2];
 
@@ -73,6 +73,12 @@ e_cell_checkbox_class_init (ECellCheckboxClass *klass)
 static void
 e_cell_checkbox_init (ECellCheckbox *eccb)
 {
+	GPtrArray *pixbufs;
+
+	pixbufs = e_cell_toggle_get_pixbufs (E_CELL_TOGGLE (eccb));
+
+	g_ptr_array_add (pixbufs, g_object_ref (checks[0]));
+	g_ptr_array_add (pixbufs, g_object_ref (checks[1]));
 }
 
 /**
@@ -87,9 +93,5 @@ e_cell_checkbox_init (ECellCheckbox *eccb)
 ECell *
 e_cell_checkbox_new (void)
 {
-	ECellCheckbox *eccb = g_object_new (E_CELL_CHECKBOX_TYPE, NULL);
-
-	e_cell_toggle_construct (E_CELL_TOGGLE (eccb), 2, 2, checks);
-
-	return (ECell *) eccb;
+	return g_object_new (E_CELL_CHECKBOX_TYPE, NULL);
 }
diff --git a/widgets/table/e-cell-toggle.c b/widgets/table/e-cell-toggle.c
index db047f1..4903602 100644
--- a/widgets/table/e-cell-toggle.c
+++ b/widgets/table/e-cell-toggle.c
@@ -28,6 +28,8 @@
 #include <gtk/gtk.h>
 #include <libgnomecanvas/gnome-canvas.h>
 
+#include "art/empty.xpm"
+
 #include "gal-a11y-e-cell-toggle.h"
 #include "gal-a11y-e-cell-registry.h"
 #include "e-util/e-util.h"
@@ -36,21 +38,107 @@
 #include "e-cell-toggle.h"
 #include "e-table-item.h"
 
+#define E_CELL_TOGGLE_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_CELL_TOGGLE, ECellTogglePrivate))
+
+struct _ECellTogglePrivate {
+	gchar **icon_names;
+	guint n_icon_names;
+
+	GdkPixbuf *empty;
+	GPtrArray *pixbufs;
+	gint height;
+};
+
 G_DEFINE_TYPE (ECellToggle, e_cell_toggle, E_CELL_TYPE)
 
 typedef struct {
-	ECellView     cell_view;
-	GdkGC        *gc;
-	GnomeCanvas  *canvas;
+	ECellView cell_view;
+	GdkGC *gc;
+	GnomeCanvas *canvas;
 } ECellToggleView;
 
-#define CACHE_SEQ_COUNT 6
+static void
+cell_toggle_load_icons (ECellToggle *cell_toggle)
+{
+	GtkIconTheme *icon_theme;
+	gint width, height;
+	gint max_height = 0;
+	guint ii;
+	GError *error = NULL;
+
+	icon_theme = gtk_icon_theme_get_default ();
+	gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height);
+
+	g_ptr_array_set_size (cell_toggle->priv->pixbufs, 0);
+
+	for (ii = 0; ii < cell_toggle->priv->n_icon_names; ii++) {
+		const gchar *icon_name = cell_toggle->priv->icon_names[ii];
+		GdkPixbuf *pixbuf = NULL;
+
+		if (icon_name != NULL)
+			pixbuf = gtk_icon_theme_load_icon (
+				icon_theme, icon_name, height, 0, &error);
+
+		if (error != NULL) {
+			g_warning ("%s", error->message);
+			g_clear_error (&error);
+		}
+
+		if (pixbuf == NULL)
+			pixbuf = g_object_ref (cell_toggle->priv->empty);
+
+		g_ptr_array_add (cell_toggle->priv->pixbufs, pixbuf);
+		max_height = MAX (max_height, gdk_pixbuf_get_height (pixbuf));
+	}
+
+	cell_toggle->priv->height = max_height;
+}
+
+static void
+cell_toggle_dispose (GObject *object)
+{
+	ECellTogglePrivate *priv;
+
+	priv = E_CELL_TOGGLE_GET_PRIVATE (object);
+
+	if (priv->empty != NULL) {
+		g_object_unref (priv->empty);
+		priv->empty = NULL;
+	}
+
+	/* This unrefs all the elements. */
+	g_ptr_array_set_size (priv->pixbufs, 0);
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (e_cell_toggle_parent_class)->dispose (object);
+}
+
+static void
+cell_toggle_finalize (GObject *object)
+{
+	ECellTogglePrivate *priv;
+	guint ii;
+
+	priv = E_CELL_TOGGLE_GET_PRIVATE (object);
+
+	/* The array is not NULL-terminated,
+	 * so g_strfreev() will not work. */
+	for (ii = 0; ii < priv->n_icon_names; ii++)
+		g_free (priv->icon_names[ii]);
+	g_free (priv->icon_names);
+
+	g_ptr_array_free (priv->pixbufs, TRUE);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (e_cell_toggle_parent_class)->finalize (object);
+}
 
-/*
- * ECell::realize method
- */
 static ECellView *
-etog_new_view (ECell *ecell, ETableModel *table_model, gpointer e_table_item_view)
+cell_toggle_new_view (ECell *ecell,
+                      ETableModel *table_model,
+                      gpointer e_table_item_view)
 {
 	ECellToggleView *toggle_view = g_new0 (ECellToggleView, 1);
 	ETableItem *eti = E_TABLE_ITEM (e_table_item_view);
@@ -59,61 +147,59 @@ etog_new_view (ECell *ecell, ETableModel *table_model, gpointer e_table_item_vie
 	toggle_view->cell_view.ecell = ecell;
 	toggle_view->cell_view.e_table_model = table_model;
 	toggle_view->cell_view.e_table_item_view = e_table_item_view;
-        toggle_view->cell_view.kill_view_cb = NULL;
-        toggle_view->cell_view.kill_view_cb_data = NULL;
+	toggle_view->cell_view.kill_view_cb = NULL;
+	toggle_view->cell_view.kill_view_cb_data = NULL;
 	toggle_view->canvas = canvas;
 
 	return (ECellView *) toggle_view;
 }
 
 static void
-etog_kill_view (ECellView *ecell_view)
+cell_toggle_kill_view (ECellView *ecell_view)
 {
 	ECellToggleView *toggle_view = (ECellToggleView *) ecell_view;
 
-        if (toggle_view->cell_view.kill_view_cb)
-            (toggle_view->cell_view.kill_view_cb)(ecell_view, toggle_view->cell_view.kill_view_cb_data);
+	if (toggle_view->cell_view.kill_view_cb)
+		toggle_view->cell_view.kill_view_cb (
+			ecell_view, toggle_view->cell_view.kill_view_cb_data);
 
-        if (toggle_view->cell_view.kill_view_cb_data)
-            g_list_free(toggle_view->cell_view.kill_view_cb_data);
+	if (toggle_view->cell_view.kill_view_cb_data)
+		g_list_free (toggle_view->cell_view.kill_view_cb_data);
 
 	g_free (ecell_view);
 }
 
 static void
-etog_realize (ECellView *ecell_view)
+cell_toggle_realize (ECellView *ecell_view)
 {
 	ECellToggleView *toggle_view = (ECellToggleView *) ecell_view;
 
 	toggle_view->gc = gdk_gc_new (GTK_WIDGET (toggle_view->canvas)->window);
 }
 
-/*
- * ECell::unrealize method
- */
 static void
-etog_unrealize (ECellView *ecv)
+cell_toggle_unrealize (ECellView *ecell_view)
 {
-	ECellToggleView *toggle_view = (ECellToggleView *) ecv;
+	ECellToggleView *toggle_view = (ECellToggleView *) ecell_view;
 
 	g_object_unref (toggle_view->gc);
 	toggle_view->gc = NULL;
 }
 
-#define RGB_COLOR(color) (((color).red & 0xff00) << 8 | \
-			   ((color).green & 0xff00) | \
-			   ((color).blue & 0xff00) >> 8)
-
-/*
- * ECell::draw method
- */
 static void
-etog_draw (ECellView *ecell_view, GdkDrawable *drawable,
-	  gint model_col, gint view_col, gint row, ECellFlags flags,
-	  gint x1, gint y1, gint x2, gint y2)
+cell_toggle_draw (ECellView *ecell_view,
+                  GdkDrawable *drawable,
+                  gint model_col,
+                  gint view_col,
+                  gint row,
+                  ECellFlags flags,
+                  gint x1,
+                  gint y1,
+                  gint x2,
+                  gint y2)
 {
-	ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell);
-	ECellToggleView *toggle_view = (ECellToggleView *) ecell_view;
+	ECellTogglePrivate *priv;
+	ECellToggleView *toggle_view;
 	GdkPixbuf *image;
 	gint x, y, width, height;
 	gint cache_seq;
@@ -122,9 +208,12 @@ etog_draw (ECellView *ecell_view, GdkDrawable *drawable,
 	const gint value = GPOINTER_TO_INT (
 		 e_table_model_value_at (ecell_view->e_table_model, model_col, row));
 
-	if (value < 0 || value >= toggle->n_states) {
+	toggle_view = (ECellToggleView *) ecell_view;
+	priv = E_CELL_TOGGLE_GET_PRIVATE (ecell_view->ecell);
+
+	if (value < 0 || value >= priv->pixbufs->len) {
 		g_warning ("Value from the table model is %d, the states we support are [0..%d)\n",
-			   value, toggle->n_states);
+			   value, priv->pixbufs->len);
 		return;
 	}
 
@@ -139,7 +228,7 @@ etog_draw (ECellView *ecell_view, GdkDrawable *drawable,
 	if (E_TABLE_ITEM (ecell_view->e_table_item_view)->alternating_row_colors && (row % 2) == 0)
 		cache_seq += 3;
 
-	image = toggle->images[value];
+	image = g_ptr_array_index (priv->pixbufs, value);
 
 	if ((x2 - x1) < gdk_pixbuf_get_width (image)) {
 		x = x1;
@@ -167,33 +256,37 @@ etog_draw (ECellView *ecell_view, GdkDrawable *drawable,
 }
 
 static void
-etog_set_value (ECellToggleView *toggle_view, gint model_col, gint view_col, gint row, gint value)
+etog_set_value (ECellToggleView *toggle_view,
+                gint model_col,
+                gint view_col,
+                gint row,
+                gint value)
 {
-	ECell *ecell = toggle_view->cell_view.ecell;
-	ECellToggle *toggle = E_CELL_TOGGLE (ecell);
+	ECellTogglePrivate *priv;
+
+	priv = E_CELL_TOGGLE_GET_PRIVATE (toggle_view->cell_view.ecell);
 
-	if (value >= toggle->n_states)
+	if (value >= priv->pixbufs->len)
 		value = 0;
 
-	e_table_model_set_value_at (toggle_view->cell_view.e_table_model,
-				    model_col, row, GINT_TO_POINTER (value));
+	e_table_model_set_value_at (
+		toggle_view->cell_view.e_table_model,
+		model_col, row, GINT_TO_POINTER (value));
 }
 
-/*
- * ECell::event method
- */
 static gint
-etog_event (ECellView *ecell_view, GdkEvent *event, gint model_col, gint view_col, gint row, ECellFlags flags, ECellActions *actions)
+cell_toggle_event (ECellView *ecell_view,
+                   GdkEvent *event,
+                   gint model_col,
+                   gint view_col,
+                   gint row,
+                   ECellFlags flags,
+                   ECellActions *actions)
 {
 	ECellToggleView *toggle_view = (ECellToggleView *) ecell_view;
 	gpointer _value = e_table_model_value_at (ecell_view->e_table_model, model_col, row);
 	const gint value = GPOINTER_TO_INT (_value);
 
-#if 0
-	if (!(flags & E_CELL_EDITING))
-		return FALSE;
-#endif
-
 	switch (event->type) {
 	case GDK_KEY_PRESS:
 		if (event->key.keyval != GDK_space)
@@ -211,39 +304,45 @@ etog_event (ECellView *ecell_view, GdkEvent *event, gint model_col, gint view_co
 	}
 }
 
-/*
- * ECell::height method
- */
 static gint
-etog_height (ECellView *ecell_view, gint model_col, gint view_col, gint row)
+cell_toggle_height (ECellView *ecell_view,
+                    gint model_col,
+                    gint view_col,
+                    gint row)
 {
-	ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell);
+	ECellTogglePrivate *priv;
+
+	priv = E_CELL_TOGGLE_GET_PRIVATE (ecell_view->ecell);
 
-	return toggle->height;
+	return priv->height;
 }
 
-/*
- * ECell::print method
- */
 static void
-etog_print (ECellView *ecell_view, GtkPrintContext *context,
-	    gint model_col, gint view_col, gint row,
-	    double width, double height)
+cell_toggle_print (ECellView *ecell_view,
+                   GtkPrintContext *context,
+                   gint model_col,
+                   gint view_col,
+                   gint row,
+                   gdouble width,
+                   gdouble height)
 {
-	ECellToggle *toggle = E_CELL_TOGGLE(ecell_view->ecell);
+	ECellTogglePrivate *priv;
 	GdkPixbuf *image;
-	double image_width, image_height;
+	gdouble image_width, image_height;
 	const gint value = GPOINTER_TO_INT (
 			e_table_model_value_at (ecell_view->e_table_model, model_col, row));
 
 	cairo_t *cr;
-	if (value >= toggle->n_states) {
+
+	priv = E_CELL_TOGGLE_GET_PRIVATE (ecell_view->ecell);
+
+	if (value >= priv->pixbufs->len) {
 		g_warning ("Value from the table model is %d, the states we support are [0..%d)\n",
-				value, toggle->n_states);
+				value, priv->pixbufs->len);
 		return;
 	}
 
-	image = toggle->images[value];
+	image = g_ptr_array_index (priv->pixbufs, value);
 	if (image) {
 		cr = gtk_print_context_get_cairo_context (context);
 		cairo_save(cr);
@@ -262,137 +361,152 @@ etog_print (ECellView *ecell_view, GtkPrintContext *context,
 }
 
 static gdouble
-etog_print_height (ECellView *ecell_view, GtkPrintContext *context,
-		   gint model_col, gint view_col, gint row,
-		   double width)
+cell_toggle_print_height (ECellView *ecell_view,
+                          GtkPrintContext *context,
+                          gint model_col,
+                          gint view_col,
+                          gint row,
+                          gdouble width)
 {
-	ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell);
+	ECellTogglePrivate *priv;
+
+	priv = E_CELL_TOGGLE_GET_PRIVATE (ecell_view->ecell);
 
-	return toggle->height;
+	return priv->height;
 }
 
-/*
- * ECell::max_width method
- */
 static gint
-etog_max_width (ECellView *ecell_view, gint model_col, gint view_col)
+cell_toggle_max_width (ECellView *ecell_view,
+                       gint model_col,
+                       gint view_col)
 {
-	ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell);
+	ECellTogglePrivate *priv;
 	gint max_width = 0;
 	gint number_of_rows;
 	gint row;
 
+	priv = E_CELL_TOGGLE_GET_PRIVATE (ecell_view->ecell);
+
 	number_of_rows = e_table_model_row_count (ecell_view->e_table_model);
 	for (row = 0; row < number_of_rows; row++) {
-		gpointer value = e_table_model_value_at (ecell_view->e_table_model,
-						      model_col, row);
-		max_width = MAX (max_width, gdk_pixbuf_get_width (toggle->images[GPOINTER_TO_INT (value)]));
+		GdkPixbuf *pixbuf;
+		gpointer value;
+
+		value = e_table_model_value_at (
+			ecell_view->e_table_model, model_col, row);
+		pixbuf = g_ptr_array_index (
+			priv->pixbufs, GPOINTER_TO_INT (value));
+
+		max_width = MAX (max_width, gdk_pixbuf_get_width (pixbuf));
 	}
 
 	return max_width;
 }
 
 static void
-etog_finalize (GObject *object)
+e_cell_toggle_class_init (ECellToggleClass *class)
 {
-	ECellToggle *etog = E_CELL_TOGGLE (object);
-	gint i;
-
-	for (i = 0; i < etog->n_states; i++)
-		g_object_unref (etog->images [i]);
-
-	g_free (etog->images);
-
-	etog->images = NULL;
-	etog->n_states = 0;
-
-	G_OBJECT_CLASS (e_cell_toggle_parent_class)->finalize (object);
+	GObjectClass *object_class;
+	ECellClass *cell_class;
+
+	g_type_class_add_private (class, sizeof (ECellTogglePrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->dispose = cell_toggle_dispose;
+	object_class->finalize = cell_toggle_finalize;
+
+	cell_class = E_CELL_CLASS (class);
+	cell_class->new_view = cell_toggle_new_view;
+	cell_class->kill_view = cell_toggle_kill_view;
+	cell_class->realize = cell_toggle_realize;
+	cell_class->unrealize = cell_toggle_unrealize;
+	cell_class->draw = cell_toggle_draw;
+	cell_class->event = cell_toggle_event;
+	cell_class->height = cell_toggle_height;
+	cell_class->print = cell_toggle_print;
+	cell_class->print_height = cell_toggle_print_height;
+	cell_class->max_width = cell_toggle_max_width;
+
+	gal_a11y_e_cell_registry_add_cell_type (
+		NULL, E_TYPE_CELL_TOGGLE, gal_a11y_e_cell_toggle_new);
 }
 
 static void
-e_cell_toggle_class_init (ECellToggleClass *klass)
+e_cell_toggle_init (ECellToggle *cell_toggle)
 {
-	ECellClass *ecc = E_CELL_CLASS (klass);
-
-	G_OBJECT_CLASS (klass)->finalize = etog_finalize;
-
-	ecc->new_view   = etog_new_view;
-	ecc->kill_view  = etog_kill_view;
-	ecc->realize    = etog_realize;
-	ecc->unrealize  = etog_unrealize;
-	ecc->draw       = etog_draw;
-	ecc->event      = etog_event;
-	ecc->height     = etog_height;
-	ecc->print      = etog_print;
-	ecc->print_height = etog_print_height;
-	ecc->max_width  = etog_max_width;
-
-	gal_a11y_e_cell_registry_add_cell_type (NULL,
-						 E_CELL_TOGGLE_TYPE,
-                                                gal_a11y_e_cell_toggle_new);
-}
+	cell_toggle->priv = E_CELL_TOGGLE_GET_PRIVATE (cell_toggle);
 
-static void
-e_cell_toggle_init (ECellToggle *etog)
-{
-	etog->images = NULL;
-	etog->n_states = 0;
+	cell_toggle->priv->empty =
+		gdk_pixbuf_new_from_xpm_data (empty_xpm);
+
+	cell_toggle->priv->pixbufs =
+		g_ptr_array_new_with_free_func (g_object_unref);
 }
 
 /**
  * e_cell_toggle_construct:
- * @etog: a fresh ECellToggle object
- * @border: number of pixels used as a border
- * @n_states: number of states the toggle will have
- * @images: a collection of @n_states images, one for each state.
+ * @cell_toggle: a fresh ECellToggle object
+ * @icon_names: array of icon names, some of which may be %NULL
+ * @n_icon_names: length of the @icon_names array
  *
- * Constructs the @etog object with the @border, @n_staes, and @images
+ * Constructs the @cell_toggle object with the @icon_names and @n_icon_names
  * arguments.
  */
 void
-e_cell_toggle_construct (ECellToggle *etog, gint border, gint n_states, GdkPixbuf **images)
+e_cell_toggle_construct (ECellToggle *cell_toggle,
+                         const gchar **icon_names,
+                         guint n_icon_names)
 {
-	gint max_height =  0;
-	gint i;
+	guint ii;
 
-	etog->border = border;
-	etog->n_states = n_states;
+	g_return_if_fail (E_IS_CELL_TOGGLE (cell_toggle));
+	g_return_if_fail (icon_names != NULL);
+	g_return_if_fail (n_icon_names > 0);
 
-	etog->images = g_new (GdkPixbuf *, n_states);
+	cell_toggle->priv->icon_names = g_new (gchar *, n_icon_names);
+	cell_toggle->priv->n_icon_names = n_icon_names;
 
-	for (i = 0; i < n_states; i++) {
-		etog->images [i] = images [i];
-		if (images[i]) {
-		g_object_ref (images [i]);
+	for (ii = 0; ii < n_icon_names; ii++)
+		cell_toggle->priv->icon_names[ii] = g_strdup (icon_names[ii]);
 
-		if (gdk_pixbuf_get_height (images [i]) > max_height)
-			max_height = gdk_pixbuf_get_height (images [i]);
-		}
-	}
-
-	etog->height = max_height;
+	cell_toggle_load_icons (cell_toggle);
 }
 
 /**
- * e_cell_checkbox_new:
- * @border: number of pixels used as a border
- * @n_states: number of states the toggle will have
- * @images: a collection of @n_states images, one for each state.
+ * e_cell_toggle_new:
+ * @icon_names: array of icon names, some of which may be %NULL
+ * @n_icon_names: length of the @icon_names array
  *
  * Creates a new ECell renderer that can be used to render toggle
- * buttons with the images specified in @images.  The value returned
- * by ETableModel::get_value is typecase into an integer and clamped
- * to the [0..n_states) range.  That will select the image rendered.
+ * buttons with the icons specified in @icon_names.  The value returned
+ * by ETableModel::get_value is typecast into an integer and clamped
+ * to the [0..n_icon_names) range.  That will select the image rendered.
+ *
+ * %NULL elements in @icon_names will show no icon for the corresponding
+ * integer value.
  *
  * Returns: an ECell object that can be used to render multi-state
  * toggle cells.
  */
 ECell *
-e_cell_toggle_new (gint border, gint n_states, GdkPixbuf **images)
+e_cell_toggle_new (const gchar **icon_names,
+                   guint n_icon_names)
 {
-	ECellToggle *etog = g_object_new (E_CELL_TOGGLE_TYPE, NULL);
+	ECellToggle *cell_toggle;
 
-	e_cell_toggle_construct (etog, border, n_states, images);
+	g_return_val_if_fail (icon_names != NULL, NULL);
+	g_return_val_if_fail (n_icon_names > 0, NULL);
+
+	cell_toggle = g_object_new (E_TYPE_CELL_TOGGLE, NULL);
+	e_cell_toggle_construct (cell_toggle, icon_names, n_icon_names);
+
+	return (ECell *) cell_toggle;
+}
+
+GPtrArray *
+e_cell_toggle_get_pixbufs (ECellToggle *cell_toggle)
+{
+	g_return_val_if_fail (E_IS_CELL_TOGGLE (cell_toggle), NULL);
 
-	return (ECell *) etog;
+	return cell_toggle->priv->pixbufs;
 }
diff --git a/widgets/table/e-cell-toggle.h b/widgets/table/e-cell-toggle.h
index 09b458f..dee110b 100644
--- a/widgets/table/e-cell-toggle.h
+++ b/widgets/table/e-cell-toggle.h
@@ -23,41 +23,56 @@
  *
  */
 
-#ifndef _E_CELL_TOGGLE_H_
-#define _E_CELL_TOGGLE_H_
+#ifndef E_CELL_TOGGLE_H
+#define E_CELL_TOGGLE_H
 
 #include <libgnomecanvas/gnome-canvas.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <table/e-cell.h>
 
+/* Standard GObject macros */
+#define E_TYPE_CELL_TOGGLE \
+	(e_cell_toggle_get_type ())
+#define E_CELL_TOGGLE(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_CELL_TOGGLE, ECellToggle))
+#define E_CELL_TOGGLE_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_CELL_TOGGLE, ECellToggleClass))
+#define E_IS_CELL_TOGGLE(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_CELL_TOGGLE))
+#define E_IS_CELL_TOGGLE_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_CELL_TOGGLE))
+#define E_CELL_TOGGLE_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_CELL_TOGGLE, ECellToggleClass))
+
 G_BEGIN_DECLS
 
-#define E_CELL_TOGGLE_TYPE        (e_cell_toggle_get_type ())
-#define E_CELL_TOGGLE(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), E_CELL_TOGGLE_TYPE, ECellToggle))
-#define E_CELL_TOGGLE_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), E_CELL_TOGGLE_TYPE, ECellToggleClass))
-#define E_IS_CELL_TOGGLE(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_CELL_TOGGLE_TYPE))
-#define E_IS_CELL_TOGGLE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_CELL_TOGGLE_TYPE))
+typedef struct _ECellToggle ECellToggle;
+typedef struct _ECellToggleClass ECellToggleClass;
+typedef struct _ECellTogglePrivate ECellTogglePrivate;
 
-typedef struct {
+struct _ECellToggle {
 	ECell parent;
+	ECellTogglePrivate *priv;
+};
 
-	gint        border;
-	gint        n_states;
-	GdkPixbuf **images;
-
-	gint        height;
-} ECellToggle;
-
-typedef struct {
+struct _ECellToggleClass {
 	ECellClass parent_class;
-} ECellToggleClass;
+};
 
-GType      e_cell_toggle_get_type  (void);
-ECell     *e_cell_toggle_new       (gint border, gint n_states, GdkPixbuf **images);
-void       e_cell_toggle_construct (ECellToggle *etog, gint border,
-				    gint n_states, GdkPixbuf **images);
+GType		e_cell_toggle_get_type		(void);
+ECell *		e_cell_toggle_new		(const gchar **icon_names,
+						 guint n_icon_names);
+void		e_cell_toggle_construct		(ECellToggle *cell_toggle,
+						 const gchar **icon_names,
+						 guint n_icon_names);
+GPtrArray *	e_cell_toggle_get_pixbufs	(ECellToggle *cell_toggle);
 
 G_END_DECLS
 
-#endif /* _E_CELL_TOGGLE_H_ */
+#endif /* E_CELL_TOGGLE_H */
 
diff --git a/widgets/table/e-table-col.c b/widgets/table/e-table-col.c
index de1cc48..3befb53 100644
--- a/widgets/table/e-table-col.c
+++ b/widgets/table/e-table-col.c
@@ -35,6 +35,27 @@ enum {
 };
 
 static void
+etc_load_icon (ETableCol *etc)
+{
+	/* FIXME This ignores theme changes. */
+
+	GtkIconTheme *icon_theme;
+	gint width, height;
+	GError *error = NULL;
+
+	icon_theme = gtk_icon_theme_get_default ();
+	gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height);
+
+	etc->pixbuf = gtk_icon_theme_load_icon (
+		icon_theme, etc->icon_name, height, 0, &error);
+
+	if (error != NULL) {
+		g_warning ("%s", error->message);
+		g_error_free (error);
+	}
+}
+
+static void
 etc_dispose (GObject *object)
 {
 	ETableCol *etc = E_TABLE_COL (object);
@@ -47,10 +68,12 @@ etc_dispose (GObject *object)
 		g_object_unref (etc->pixbuf);
 	etc->pixbuf = NULL;
 
-	if (etc->text)
-		g_free (etc->text);
+	g_free (etc->text);
 	etc->text = NULL;
 
+	g_free (etc->icon_name);
+	etc->icon_name = NULL;
+
 	if (G_OBJECT_CLASS (e_table_col_parent_class)->dispose)
 		G_OBJECT_CLASS (e_table_col_parent_class)->dispose (object);
 }
@@ -115,6 +138,7 @@ e_table_col_init (ETableCol *etc)
  * e_table_col_new:
  * @col_idx: the column we represent in the model
  * @text: a title for this column
+ * @icon_name: name of the icon to be used for the header, or %NULL
  * @expansion: FIXME
  * @min_width: minimum width in pixels for this column
  * @ecell: the renderer to be used for this column
@@ -139,8 +163,16 @@ e_table_col_init (ETableCol *etc)
  * Returns: the newly created ETableCol object.
  */
 ETableCol *
-e_table_col_new (gint col_idx, const gchar *text, double expansion, gint min_width,
-		 ECell *ecell, GCompareFunc compare, gboolean resizable, gboolean disabled, gint priority)
+e_table_col_new (gint col_idx,
+                 const gchar *text,
+                 const gchar *icon_name,
+                 double expansion,
+                 gint min_width,
+                 ECell *ecell,
+                 GCompareFunc compare,
+                 gboolean resizable,
+                 gboolean disabled,
+                 gint priority)
 {
 	ETableCol *etc;
 
@@ -150,13 +182,12 @@ e_table_col_new (gint col_idx, const gchar *text, double expansion, gint min_wid
 	g_return_val_if_fail (compare != NULL, NULL);
 	g_return_val_if_fail (text != NULL, NULL);
 
-	etc = g_object_new (E_TABLE_COL_TYPE, NULL);
-
-	etc->is_pixbuf = FALSE;
+	etc = g_object_new (E_TYPE_TABLE_COL, NULL);
 
 	etc->col_idx = col_idx;
 	etc->compare_col = col_idx;
 	etc->text = g_strdup (text);
+	etc->icon_name = g_strdup (icon_name);
 	etc->pixbuf = NULL;
 	etc->expansion = expansion;
 	etc->min_width = min_width;
@@ -170,67 +201,8 @@ e_table_col_new (gint col_idx, const gchar *text, double expansion, gint min_wid
 
 	g_object_ref (etc->ecell);
 
-	return etc;
-}
-
-/**
- * e_table_col_new_with_pixbuf:
- * @col_idx: the column we represent in the model
- * @pixbuf: the image to be used for the header
- * @expansion: FIXME
- * @min_width: minimum width in pixels for this column
- * @ecell: the renderer to be used for this column
- * @compare: comparision function for the elements stored in this column
- * @resizable: whether the column can be resized interactively by the user
- *
- * The ETableCol represents a column to be used inside an ETable.  The
- * ETableCol objects are inserted inside an ETableHeader (which is just a collection
- * of ETableCols).  The ETableHeader is the definition of the order in which
- * columns are shown to the user.
- *
- * The @text argument is the the text that will be shown as a header to the
- * user. @col_idx reflects where the data for this ETableCol object will
- * be fetch from an ETableModel.  So even if the user changes the order
- * of the columns being viewed (the ETableCols in the ETableHeader), the
- * column will always point to the same column inside the ETableModel.
- *
- * The @ecell argument is an ECell object that needs to know how to render the
- * data in the ETableModel for this specific row.
- *
- * Returns: the newly created ETableCol object.
- */
-ETableCol *
-e_table_col_new_with_pixbuf (gint col_idx, const gchar *text, GdkPixbuf *pixbuf, double expansion, gint min_width,
-			     ECell *ecell, GCompareFunc compare, gboolean resizable, gboolean disabled, gint priority)
-{
-	ETableCol *etc;
-
-	g_return_val_if_fail (expansion >= 0, NULL);
-	g_return_val_if_fail (min_width >= 0, NULL);
-	g_return_val_if_fail (ecell != NULL, NULL);
-	g_return_val_if_fail (compare != NULL, NULL);
-	g_return_val_if_fail (pixbuf != NULL, NULL);
-
-	etc = g_object_new (E_TABLE_COL_TYPE, NULL);
-
-	etc->is_pixbuf = TRUE;
-
-	etc->col_idx = col_idx;
-	etc->compare_col = col_idx;
-	etc->text = g_strdup(text);
-	etc->pixbuf = pixbuf;
-	etc->expansion = expansion;
-	etc->min_width = min_width;
-	etc->ecell = ecell;
-	etc->compare = compare;
-	etc->disabled = disabled;
-	etc->priority = priority;
-
-	etc->selected = 0;
-	etc->resizable = resizable;
-
-	g_object_ref (etc->ecell);
-	g_object_ref (etc->pixbuf);
+	if (etc->icon_name != NULL)
+		etc_load_icon (etc);
 
 	return etc;
 }
diff --git a/widgets/table/e-table-col.h b/widgets/table/e-table-col.h
index 8e51467..0a3add4 100644
--- a/widgets/table/e-table-col.h
+++ b/widgets/table/e-table-col.h
@@ -21,20 +21,32 @@
  *
  */
 
-#ifndef _E_TABLE_COL_H_
-#define _E_TABLE_COL_H_
+#ifndef E_TABLE_COL_H
+#define E_TABLE_COL_H
 
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <table/e-cell.h>
 
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define E_TYPE_TABLE_COL \
+	(e_table_col_get_type ())
+#define E_TABLE_COL(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_TABLE_COL, ETableCol))
+#define E_TABLE_COL_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_TABLE_COL, ETableColClass))
+#define E_IS_TABLE_COL(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_TABLE_COL))
+#define E_IS_TABLE_COL_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_TABLE_COL))
+#define E_TABLE_COL_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_TABLE_COL, ETableColClass))
 
-#define E_TABLE_COL_TYPE        (e_table_col_get_type ())
-#define E_TABLE_COL(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TABLE_COL_TYPE, ETableCol))
-#define E_TABLE_COL_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), E_TABLE_COL_TYPE, ETableColClass))
-#define E_IS_TABLE_COL(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TABLE_COL_TYPE))
-#define E_IS_TABLE_COL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TABLE_COL_TYPE))
-#define E_TABLE_COL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), E_TABLE_COL_TYPE, ETableColClass))
+G_BEGIN_DECLS
 
 typedef enum {
 	E_TABLE_COL_ARROW_NONE = 0,
@@ -42,60 +54,57 @@ typedef enum {
 	E_TABLE_COL_ARROW_DOWN
 } ETableColArrow;
 
+typedef struct _ETableCol ETableCol;
+typedef struct _ETableColClass ETableColClass;
+
 /*
  * Information about a single column
  */
-typedef struct {
-	GObject         base;
-	gchar             *text;
-	GdkPixbuf        *pixbuf;
-	gint               min_width;
-	gint               width;
-	double            expansion;
-	short             x;
-	GCompareFunc      compare;
-	ETableSearchFunc  search;
-	guint      is_pixbuf:1;
-	guint      selected:1;
-	guint      resizable:1;
-	guint      disabled:1;
-	guint      sortable:1;
-	guint      groupable:1;
-	gint               col_idx;
-	gint               compare_col;
-	gint               priority;
-
-	GtkJustification  justification;
-
-	ECell            *ecell;
-} ETableCol;
-
-typedef struct {
+struct _ETableCol {
+	GObject parent;
+
+	gchar *text;
+	gchar *icon_name;
+	GdkPixbuf *pixbuf;
+	gint min_width;
+	gint width;
+	gdouble expansion;
+	gshort x;
+	GCompareFunc compare;
+	ETableSearchFunc search;
+
+	guint selected:1;
+	guint resizable:1;
+	guint disabled:1;
+	guint sortable:1;
+	guint groupable:1;
+
+	gint col_idx;
+	gint compare_col;
+	gint priority;
+
+	GtkJustification justification;
+
+	ECell *ecell;
+};
+
+struct _ETableColClass {
 	GObjectClass parent_class;
-} ETableColClass;
-
-GType      e_table_col_get_type         (void);
-ETableCol *e_table_col_new              (gint           col_idx,
-					 const gchar   *text,
-					 double        expansion,
-					 gint           min_width,
-					 ECell        *ecell,
-					 GCompareFunc  compare,
-					 gboolean      resizable,
-					 gboolean      disabled,
-					 gint           priority);
-ETableCol *e_table_col_new_with_pixbuf  (gint           col_idx,
-					 const gchar   *text,
-					 GdkPixbuf    *pixbuf,
-					 double        expansion,
-					 gint           min_width,
-					 ECell        *ecell,
-					 GCompareFunc  compare,
-					 gboolean      resizable,
-					 gboolean      disabled,
-					 gint           priority);
+};
+
+GType		e_table_col_get_type		(void);
+ETableCol *	e_table_col_new			(gint col_idx,
+						 const gchar *text,
+						 const gchar *icon_name,
+						 double expansion,
+						 gint min_width,
+						 ECell *ecell,
+						 GCompareFunc compare,
+						 gboolean resizable,
+						 gboolean disabled,
+						 gint priority);
 
 G_END_DECLS
 
-#endif /* _E_TABLE_COL_H_ */
+#endif /* E_TABLE_COL_H */
 
diff --git a/widgets/table/e-table-extras.c b/widgets/table/e-table-extras.c
index a02ac45..eee1af9 100644
--- a/widgets/table/e-table-extras.c
+++ b/widgets/table/e-table-extras.c
@@ -47,7 +47,7 @@
 struct _ETableExtrasPrivate {
 	GHashTable *cells;
 	GHashTable *compares;
-	GHashTable *pixbufs;
+	GHashTable *icon_names;
 	GHashTable *searches;
 };
 
@@ -58,26 +58,28 @@ G_DEFINE_TYPE (ETableExtras, ete, G_TYPE_OBJECT)
 static void
 ete_finalize (GObject *object)
 {
-	ETableExtras *ete = E_TABLE_EXTRAS (object);
+	ETableExtrasPrivate *priv;
 
-	if (ete->cells) {
-		g_hash_table_destroy (ete->cells);
-		ete->cells = NULL;
+	priv = E_TABLE_EXTRAS_GET_PRIVATE (object);
+
+	if (priv->cells) {
+		g_hash_table_destroy (priv->cells);
+		priv->cells = NULL;
 	}
 
-	if (ete->compares) {
-		g_hash_table_destroy (ete->compares);
-		ete->compares = NULL;
+	if (priv->compares) {
+		g_hash_table_destroy (priv->compares);
+		priv->compares = NULL;
 	}
 
-	if (ete->searches) {
-		g_hash_table_destroy (ete->searches);
-		ete->searches = NULL;
+	if (priv->searches) {
+		g_hash_table_destroy (priv->searches);
+		priv->searches = NULL;
 	}
 
-	if (ete->pixbufs) {
-		g_hash_table_destroy (ete->pixbufs);
-		ete->pixbufs = NULL;
+	if (priv->icon_names) {
+		g_hash_table_destroy (priv->icon_names);
+		priv->icon_names = NULL;
 	}
 
 	G_OBJECT_CLASS (ete_parent_class)->finalize (object);
@@ -177,15 +179,15 @@ ete_init (ETableExtras *extras)
 		(GDestroyNotify) g_free,
 		(GDestroyNotify) NULL);
 
-	extras->priv->searches = g_hash_table_new_full (
+	extras->priv->icon_names = g_hash_table_new_full (
 		g_str_hash, g_str_equal,
 		(GDestroyNotify) g_free,
-		(GDestroyNotify) NULL);
+		(GDestroyNotify) g_free);
 
-	extras->priv->pixbufs = g_hash_table_new_full (
+	extras->priv->searches = g_hash_table_new_full (
 		g_str_hash, g_str_equal,
 		(GDestroyNotify) g_free,
-		(GDestroyNotify) safe_unref);
+		(GDestroyNotify) NULL);
 
 	e_table_extras_add_compare(extras, "string", e_str_compare);
 	e_table_extras_add_compare(extras, "stringcase", e_str_case_compare);
@@ -295,25 +297,24 @@ e_table_extras_get_search (ETableExtras *extras,
 }
 
 void
-e_table_extras_add_pixbuf (ETableExtras *extras,
-                           const gchar *id,
-                           GdkPixbuf *pixbuf)
+e_table_extras_add_icon_name (ETableExtras *extras,
+                              const gchar *id,
+                              const gchar *icon_name)
 {
 	g_return_if_fail (E_IS_TABLE_EXTRAS (extras));
 	g_return_if_fail (id != NULL);
 
-	if (pixbuf != NULL)
-		g_object_ref (pixbuf);
-
-	g_hash_table_insert (extras->priv->pixbufs, g_strdup (id), pixbuf);
+	g_hash_table_insert (
+		extras->priv->icon_names,
+		g_strdup (id), g_strdup (icon_name));
 }
 
-GdkPixbuf *
-e_table_extras_get_pixbuf (ETableExtras *extras,
-                           const gchar *id)
+const gchar *
+e_table_extras_get_icon_name (ETableExtras *extras,
+                              const gchar *id)
 {
 	g_return_val_if_fail (E_IS_TABLE_EXTRAS (extras), NULL);
 	g_return_val_if_fail (id != NULL, NULL);
 
-	return g_hash_table_lookup (extras->priv->pixbufs, id);
+	return g_hash_table_lookup (extras->priv->icon_names, id);
 }
diff --git a/widgets/table/e-table-extras.h b/widgets/table/e-table-extras.h
index b01af32..1f4488b 100644
--- a/widgets/table/e-table-extras.h
+++ b/widgets/table/e-table-extras.h
@@ -54,11 +54,6 @@ typedef struct _ETableExtrasPrivate ETableExtrasPrivate;
 struct _ETableExtras {
 	GObject parent;
 	ETableExtrasPrivate *priv;
-
-	GHashTable *cells;
-	GHashTable *compares;
-	GHashTable *pixbufs;
-	GHashTable *searches;
 };
 
 struct _ETableExtrasClass {
@@ -83,10 +78,10 @@ void		e_table_extras_add_search	(ETableExtras *extras,
 ETableSearchFunc
 		e_table_extras_get_search	(ETableExtras *extras,
 						 const gchar *id);
-void		e_table_extras_add_pixbuf	(ETableExtras *extras,
+void		e_table_extras_add_icon_name	(ETableExtras *extras,
 						 const gchar *id,
-						 GdkPixbuf *pixbuf);
-GdkPixbuf *	e_table_extras_get_pixbuf	(ETableExtras *extras,
+						 const gchar *icon_name);
+const gchar *	e_table_extras_get_icon_name	(ETableExtras *extras,
 						 const gchar *id);
 
 G_END_DECLS
diff --git a/widgets/table/e-table-header-utils.c b/widgets/table/e-table-header-utils.c
index a5b0aac..c6e694d 100644
--- a/widgets/table/e-table-header-utils.c
+++ b/widgets/table/e-table-header-utils.c
@@ -84,7 +84,7 @@ e_table_header_compute_height (ETableCol *ecol, GtkWidget *widget)
 
 	pango_layout_get_pixel_size (layout, NULL, &height);
 
-	if (ecol->is_pixbuf) {
+	if (ecol->icon_name != NULL) {
 		g_return_val_if_fail (ecol->pixbuf != NULL, -1);
 		height = MAX (height, gdk_pixbuf_get_height (ecol->pixbuf));
 	}
@@ -389,7 +389,7 @@ e_table_header_draw_button (GdkDrawable *drawable, ETableCol *ecol,
 		arrow_width = MIN (MIN_ARROW_SIZE, inner_width);
 		arrow_height = MIN (MIN_ARROW_SIZE, inner_height);
 
-		if (!ecol->is_pixbuf)
+		if (ecol->icon_name == NULL)
 			inner_width -= arrow_width + HEADER_PADDING;
 		break;
 	default:
@@ -402,7 +402,7 @@ e_table_header_draw_button (GdkDrawable *drawable, ETableCol *ecol,
 	layout = build_header_layout (widget, ecol->text);
 
 	/* Pixbuf or label */
-	if (ecol->is_pixbuf) {
+	if (ecol->icon_name != NULL) {
 		gint pwidth, pheight;
 		gint clip_width, clip_height;
 		gint xpos;
@@ -462,13 +462,13 @@ e_table_header_draw_button (GdkDrawable *drawable, ETableCol *ecol,
 
 	case E_TABLE_COL_ARROW_UP:
 	case E_TABLE_COL_ARROW_DOWN: {
-		if (!ecol->is_pixbuf)
+		if (ecol->icon_name == NULL)
 			inner_width += arrow_width + HEADER_PADDING;
 
 		gtk_paint_arrow (style, drawable, state,
 				 GTK_SHADOW_NONE, NULL, widget, "header",
 				 (arrow == E_TABLE_COL_ARROW_UP) ? GTK_ARROW_UP : GTK_ARROW_DOWN,
-				 !ecol->is_pixbuf,
+				 (ecol->icon_name == NULL),
 				 inner_x + inner_width - arrow_width,
 				 inner_y + (inner_height - arrow_height) / 2,
 				 arrow_width, arrow_height);
diff --git a/widgets/table/e-table-utils.c b/widgets/table/e-table-utils.c
index 03c8e17..8d8b0ba 100644
--- a/widgets/table/e-table-utils.c
+++ b/widgets/table/e-table-utils.c
@@ -95,24 +95,34 @@ et_col_spec_to_col (ETableColumnSpecification *col_spec,
 		title = g_strdup (title);
 
 		if (col_spec->pixbuf && *col_spec->pixbuf) {
-			GdkPixbuf *pixbuf;
+			const gchar *icon_name;
 
-			pixbuf = e_table_extras_get_pixbuf(
+			icon_name = e_table_extras_get_icon_name (
 				ete, col_spec->pixbuf);
-			if (pixbuf) {
-				col = e_table_col_new_with_pixbuf (
-					col_spec->model_col, title,
-					pixbuf, col_spec->expansion,
+			if (icon_name != NULL) {
+				col = e_table_col_new (
+					col_spec->model_col,
+					title, icon_name,
+					col_spec->expansion,
 					col_spec->minimum_width,
-					cell, compare, col_spec->resizable, col_spec->disabled, col_spec->priority);
+					cell, compare,
+					col_spec->resizable,
+					col_spec->disabled,
+					col_spec->priority);
 			}
 		}
+
 		if (col == NULL && col_spec->title && *col_spec->title) {
 			col = e_table_col_new (
-				col_spec->model_col, title,
-				col_spec->expansion, col_spec->minimum_width,
-				cell, compare, col_spec->resizable, col_spec->disabled, col_spec->priority);
+				col_spec->model_col, title, NULL,
+				col_spec->expansion,
+				col_spec->minimum_width,
+				cell, compare,
+				col_spec->resizable,
+				col_spec->disabled,
+				col_spec->priority);
 		}
+
 		col->search = search;
 		if (col_spec->sortable && !strcmp(col_spec->sortable, "false"))
 			col->sortable = FALSE;



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