diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2010-01-05 11:52:24 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2010-01-07 12:18:52 +0800 |
commit | 28b84ecaf9111f2a59e1380089dad6a92ddc848d (patch) | |
tree | c925a0966e291917ce69a596c9613ac7cee33be8 /widgets/table | |
parent | 5f1c9ff19d80bb50cd00114b8fb633d8eba3365f (diff) | |
download | gsoc2013-evolution-28b84ecaf9111f2a59e1380089dad6a92ddc848d.tar.gz gsoc2013-evolution-28b84ecaf9111f2a59e1380089dad6a92ddc848d.tar.zst gsoc2013-evolution-28b84ecaf9111f2a59e1380089dad6a92ddc848d.zip |
Teach ETable to prefer themed icon names over pixbufs.
Diffstat (limited to 'widgets/table')
-rw-r--r-- | widgets/table/e-cell-checkbox.c | 14 | ||||
-rw-r--r-- | widgets/table/e-cell-toggle.c | 416 | ||||
-rw-r--r-- | widgets/table/e-cell-toggle.h | 59 | ||||
-rw-r--r-- | widgets/table/e-table-col.c | 108 | ||||
-rw-r--r-- | widgets/table/e-table-col.h | 125 | ||||
-rw-r--r-- | widgets/table/e-table-extras.c | 59 | ||||
-rw-r--r-- | widgets/table/e-table-extras.h | 11 | ||||
-rw-r--r-- | widgets/table/e-table-header-utils.c | 10 | ||||
-rw-r--r-- | widgets/table/e-table-utils.c | 30 |
9 files changed, 475 insertions, 357 deletions
diff --git a/widgets/table/e-cell-checkbox.c b/widgets/table/e-cell-checkbox.c index 583793e85f..b01e6c11bc 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 db047f1220..4903602763 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 09b458f43c..dee110bc34 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 de1cc48b18..3befb53bb4 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 8e514675d5..0a3add445a 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 a02ac45e42..eee1af9014 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 b01af32b32..1f4488b6de 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 a5b0aac0af..c6e694da2e 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 03c8e17a33..8d8b0ba09f 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; |