aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/table
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2010-01-05 11:52:24 +0800
committerMatthew Barnes <mbarnes@redhat.com>2010-01-07 12:18:52 +0800
commit28b84ecaf9111f2a59e1380089dad6a92ddc848d (patch)
treec925a0966e291917ce69a596c9613ac7cee33be8 /widgets/table
parent5f1c9ff19d80bb50cd00114b8fb633d8eba3365f (diff)
downloadgsoc2013-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.c14
-rw-r--r--widgets/table/e-cell-toggle.c416
-rw-r--r--widgets/table/e-cell-toggle.h59
-rw-r--r--widgets/table/e-table-col.c108
-rw-r--r--widgets/table/e-table-col.h125
-rw-r--r--widgets/table/e-table-extras.c59
-rw-r--r--widgets/table/e-table-extras.h11
-rw-r--r--widgets/table/e-table-header-utils.c10
-rw-r--r--widgets/table/e-table-utils.c30
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;