aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--widgets/e-table/ChangeLog12
-rw-r--r--widgets/e-table/e-cell-text.c102
-rw-r--r--widgets/e-table/e-cell-text.h8
-rw-r--r--widgets/table/e-cell-text.c102
-rw-r--r--widgets/table/e-cell-text.h8
5 files changed, 228 insertions, 4 deletions
diff --git a/widgets/e-table/ChangeLog b/widgets/e-table/ChangeLog
index 3d38e26648..8216e0df66 100644
--- a/widgets/e-table/ChangeLog
+++ b/widgets/e-table/ChangeLog
@@ -1,3 +1,15 @@
+2000-07-23 Damon Chaplin <damon@helixcode.com>
+
+ * e-cell-text.c: added a color_column where the color can be specified
+ as a string, e.g. "red" or "rgb:F/0/0".
+
+ * e-cell-text.c (ect_leave_edit): don't call unbuild_current_cell()
+ since the CellEdit struct has been freed in ect_stop_editing() and so
+ has the text.
+
+ * e-cell-text.c (unbuild_current_cell): set cell->text to NULL to make
+ sure we don't try to free it again.
+
2000-07-21 Christopher James Lahey <clahey@helixcode.com>
* e-table.h: Added some unused declarations for drag and drop
diff --git a/widgets/e-table/e-cell-text.c b/widgets/e-table/e-cell-text.c
index 23e0dabfc2..dafc8f4675 100644
--- a/widgets/e-table/e-cell-text.c
+++ b/widgets/e-table/e-cell-text.c
@@ -74,6 +74,7 @@ enum {
ARG_STRIKEOUT_COLUMN,
ARG_BOLD_COLUMN,
ARG_TEXT_FILTER,
+ ARG_COLOR_COLUMN,
};
@@ -205,6 +206,8 @@ static gboolean _blink_scroll_timeout (gpointer data);
static void build_current_cell (CurrentCell *cell, ECellTextView *text_view, int model_col, int view_col, int row);
static void unbuild_current_cell (CurrentCell *cell);
static void calc_ellipsis (ECellTextView *text_view);
+static void ect_free_color (gchar *color_spec, GdkColor *color, GdkColormap *colormap);
+static GdkColor* e_cell_text_get_color (ECellTextView *cell_view, gchar *color_spec);
static ECellClass *parent_class;
@@ -355,6 +358,8 @@ static void
ect_unrealize (ECellView *ecv)
{
ECellTextView *text_view = (ECellTextView *) ecv;
+ ECellText *ect = (ECellText*) ecv->ecell;
+ GdkColormap *colormap;
gdk_gc_unref (text_view->gc);
text_view->gc = NULL;
@@ -371,10 +376,34 @@ ect_unrealize (ECellView *ecv)
gdk_cursor_destroy (text_view->i_cursor);
+ if (ect->colors) {
+ colormap = gtk_widget_get_colormap (GTK_WIDGET (text_view->canvas));
+ g_hash_table_foreach (ect->colors, (GHFunc) ect_free_color,
+ colormap);
+ g_hash_table_destroy (ect->colors);
+ ect->colors = NULL;
+ }
+
if (parent_class->unrealize)
(* parent_class->unrealize) (ecv);
}
+static void
+ect_free_color (gchar *color_spec, GdkColor *color, GdkColormap *colormap)
+{
+
+ g_free (color_spec);
+
+ /* This frees the color. Note we don't free it if it is the special
+ value. */
+ if (color != (GdkColor*) 1) {
+ gdk_colors_free (colormap, &color->pixel, 1, 0);
+
+ /* This frees the memory for the GdkColor. */
+ gdk_color_free (color);
+ }
+}
+
/*
* ECell::draw method
*/
@@ -400,8 +429,9 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
CellEdit *edit = text_view->edit;
gboolean edit_display = FALSE;
ECellTextLineBreaks *linebreaks;
- GdkColor *background, *foreground;
+ GdkColor *background, *foreground, *cell_foreground, *cursor_color;
gboolean bold = FALSE;
+ gchar *color_spec;
if (ect->bold_column >= 0 && e_table_model_value_at(ecell_view->e_table_model, ect->bold_column, row))
bold = TRUE;
@@ -437,6 +467,18 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
background = &canvas->style->base [GTK_STATE_NORMAL];
foreground = &canvas->style->text [GTK_STATE_NORMAL];
}
+
+ cursor_color = foreground;
+
+ if (ect->color_column != -1) {
+ color_spec = e_table_model_value_at (ecell_view->e_table_model,
+ ect->color_column, row);
+ cell_foreground = e_cell_text_get_color (text_view,
+ color_spec);
+ if (cell_foreground)
+ foreground = cell_foreground;
+ }
+
gdk_gc_set_foreground (text_view->gc, background);
gdk_draw_rectangle (drawable, text_view->gc, TRUE,
rect.x, rect.y, rect.width, rect.height);
@@ -583,6 +625,7 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
edit->selection_start >= start_char &&
edit->selection_start <= end_char &&
edit->show_cursor) {
+ gdk_gc_set_foreground (text_view->gc, cursor_color);
gdk_draw_rectangle (drawable,
text_view->gc,
TRUE,
@@ -1142,7 +1185,9 @@ ect_leave_edit (ECellView *ecell_view, int model_col, int view_col, int row, voi
if (edit){
ect_accept_edits (text_view);
ect_stop_editing (text_view);
- unbuild_current_cell (CURRENT_CELL(edit));
+ /* FIXME: edit is freed in ect_stop_editing() so I've
+ commented this out - Damon. */
+ /*unbuild_current_cell (CURRENT_CELL(edit));*/
} else {
/*
* We did invoke this leave edit internally
@@ -1221,6 +1266,11 @@ ect_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
case ARG_BOLD_COLUMN:
text->bold_column = GTK_VALUE_INT (*arg);
break;
+
+ case ARG_COLOR_COLUMN:
+ text->color_column = GTK_VALUE_INT (*arg);
+ break;
+
case ARG_TEXT_FILTER:
text->filter = GTK_VALUE_POINTER (*arg);
break;
@@ -1246,6 +1296,10 @@ ect_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
GTK_VALUE_INT (*arg) = text->bold_column;
break;
+ case ARG_COLOR_COLUMN:
+ GTK_VALUE_INT (*arg) = text->color_column;
+ break;
+
case ARG_TEXT_FILTER:
GTK_VALUE_POINTER (*arg) = text->filter;
break;
@@ -1284,6 +1338,8 @@ e_cell_text_class_init (GtkObjectClass *object_class)
GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_STRIKEOUT_COLUMN);
gtk_object_add_arg_type ("ECellText::bold_column",
GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_BOLD_COLUMN);
+ gtk_object_add_arg_type ("ECellText::color_column",
+ GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_COLOR_COLUMN);
gtk_object_add_arg_type ("ECellText::text_filter",
GTK_TYPE_POINTER, GTK_ARG_READWRITE, ARG_TEXT_FILTER);
@@ -1296,6 +1352,7 @@ e_cell_text_init (ECellText *ect)
{
ect->strikeout_column = -1;
ect->bold_column = -1;
+ ect->color_column = -1;
}
E_MAKE_TYPE(e_cell_text, "ECellText", ECellText, e_cell_text_class_init, e_cell_text_init, PARENT_TYPE);
@@ -2151,5 +2208,46 @@ static void
unbuild_current_cell (CurrentCell *cell)
{
g_free(cell->text);
+ cell->text = NULL;
+}
+
+
+static GdkColor*
+e_cell_text_get_color (ECellTextView *cell_view, gchar *color_spec)
+{
+ ECellText *ect = E_CELL_TEXT (((ECellView*) cell_view)->ecell);
+ GdkColormap *colormap;
+ GdkColor *color, tmp_color;
+
+ /* If the color spec is NULL we use the default color. */
+ if (color_spec == NULL)
+ return NULL;
+
+ /* Create the hash table if we haven't already. */
+ if (!ect->colors)
+ ect->colors = g_hash_table_new (g_str_hash, g_str_equal);
+
+ /* See if we've already allocated the color. Note that we use a
+ special value of (GdkColor*) 1 in the hash to indicate that we've
+ already tried and failed to allocate the color, so we don't keep
+ trying to allocate it. */
+ color = g_hash_table_lookup (ect->colors, color_spec);
+ if (color == (GdkColor*) 1)
+ return NULL;
+ if (color)
+ return color;
+
+ /* Try to parse the color. */
+ if (gdk_color_parse (color_spec, &tmp_color)) {
+ colormap = gtk_widget_get_colormap (GTK_WIDGET (cell_view->canvas));
+
+ /* Try to allocate the color. */
+ if (gdk_color_alloc (colormap, &tmp_color))
+ color = gdk_color_copy (&tmp_color);
+ }
+
+ g_hash_table_insert (ect->colors, g_strdup (color_spec),
+ color ? color : (GdkColor*) 1);
+ return color;
}
diff --git a/widgets/e-table/e-cell-text.h b/widgets/e-table/e-cell-text.h
index f1fc55c1f7..e0296998b3 100644
--- a/widgets/e-table/e-cell-text.h
+++ b/widgets/e-table/e-cell-text.h
@@ -54,7 +54,15 @@ typedef struct {
int strikeout_column;
int bold_column;
+ /* This column in the ETable should return a string specifying a color,
+ either a color name like "red" or a color spec like "rgb:F/0/0".
+ See the XParseColor man page for the formats available. */
+ int color_column;
+
ECellTextFilter filter;
+
+ /* This stores the colors we have allocated. */
+ GHashTable *colors;
} ECellText;
typedef struct {
diff --git a/widgets/table/e-cell-text.c b/widgets/table/e-cell-text.c
index 23e0dabfc2..dafc8f4675 100644
--- a/widgets/table/e-cell-text.c
+++ b/widgets/table/e-cell-text.c
@@ -74,6 +74,7 @@ enum {
ARG_STRIKEOUT_COLUMN,
ARG_BOLD_COLUMN,
ARG_TEXT_FILTER,
+ ARG_COLOR_COLUMN,
};
@@ -205,6 +206,8 @@ static gboolean _blink_scroll_timeout (gpointer data);
static void build_current_cell (CurrentCell *cell, ECellTextView *text_view, int model_col, int view_col, int row);
static void unbuild_current_cell (CurrentCell *cell);
static void calc_ellipsis (ECellTextView *text_view);
+static void ect_free_color (gchar *color_spec, GdkColor *color, GdkColormap *colormap);
+static GdkColor* e_cell_text_get_color (ECellTextView *cell_view, gchar *color_spec);
static ECellClass *parent_class;
@@ -355,6 +358,8 @@ static void
ect_unrealize (ECellView *ecv)
{
ECellTextView *text_view = (ECellTextView *) ecv;
+ ECellText *ect = (ECellText*) ecv->ecell;
+ GdkColormap *colormap;
gdk_gc_unref (text_view->gc);
text_view->gc = NULL;
@@ -371,10 +376,34 @@ ect_unrealize (ECellView *ecv)
gdk_cursor_destroy (text_view->i_cursor);
+ if (ect->colors) {
+ colormap = gtk_widget_get_colormap (GTK_WIDGET (text_view->canvas));
+ g_hash_table_foreach (ect->colors, (GHFunc) ect_free_color,
+ colormap);
+ g_hash_table_destroy (ect->colors);
+ ect->colors = NULL;
+ }
+
if (parent_class->unrealize)
(* parent_class->unrealize) (ecv);
}
+static void
+ect_free_color (gchar *color_spec, GdkColor *color, GdkColormap *colormap)
+{
+
+ g_free (color_spec);
+
+ /* This frees the color. Note we don't free it if it is the special
+ value. */
+ if (color != (GdkColor*) 1) {
+ gdk_colors_free (colormap, &color->pixel, 1, 0);
+
+ /* This frees the memory for the GdkColor. */
+ gdk_color_free (color);
+ }
+}
+
/*
* ECell::draw method
*/
@@ -400,8 +429,9 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
CellEdit *edit = text_view->edit;
gboolean edit_display = FALSE;
ECellTextLineBreaks *linebreaks;
- GdkColor *background, *foreground;
+ GdkColor *background, *foreground, *cell_foreground, *cursor_color;
gboolean bold = FALSE;
+ gchar *color_spec;
if (ect->bold_column >= 0 && e_table_model_value_at(ecell_view->e_table_model, ect->bold_column, row))
bold = TRUE;
@@ -437,6 +467,18 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
background = &canvas->style->base [GTK_STATE_NORMAL];
foreground = &canvas->style->text [GTK_STATE_NORMAL];
}
+
+ cursor_color = foreground;
+
+ if (ect->color_column != -1) {
+ color_spec = e_table_model_value_at (ecell_view->e_table_model,
+ ect->color_column, row);
+ cell_foreground = e_cell_text_get_color (text_view,
+ color_spec);
+ if (cell_foreground)
+ foreground = cell_foreground;
+ }
+
gdk_gc_set_foreground (text_view->gc, background);
gdk_draw_rectangle (drawable, text_view->gc, TRUE,
rect.x, rect.y, rect.width, rect.height);
@@ -583,6 +625,7 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
edit->selection_start >= start_char &&
edit->selection_start <= end_char &&
edit->show_cursor) {
+ gdk_gc_set_foreground (text_view->gc, cursor_color);
gdk_draw_rectangle (drawable,
text_view->gc,
TRUE,
@@ -1142,7 +1185,9 @@ ect_leave_edit (ECellView *ecell_view, int model_col, int view_col, int row, voi
if (edit){
ect_accept_edits (text_view);
ect_stop_editing (text_view);
- unbuild_current_cell (CURRENT_CELL(edit));
+ /* FIXME: edit is freed in ect_stop_editing() so I've
+ commented this out - Damon. */
+ /*unbuild_current_cell (CURRENT_CELL(edit));*/
} else {
/*
* We did invoke this leave edit internally
@@ -1221,6 +1266,11 @@ ect_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
case ARG_BOLD_COLUMN:
text->bold_column = GTK_VALUE_INT (*arg);
break;
+
+ case ARG_COLOR_COLUMN:
+ text->color_column = GTK_VALUE_INT (*arg);
+ break;
+
case ARG_TEXT_FILTER:
text->filter = GTK_VALUE_POINTER (*arg);
break;
@@ -1246,6 +1296,10 @@ ect_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
GTK_VALUE_INT (*arg) = text->bold_column;
break;
+ case ARG_COLOR_COLUMN:
+ GTK_VALUE_INT (*arg) = text->color_column;
+ break;
+
case ARG_TEXT_FILTER:
GTK_VALUE_POINTER (*arg) = text->filter;
break;
@@ -1284,6 +1338,8 @@ e_cell_text_class_init (GtkObjectClass *object_class)
GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_STRIKEOUT_COLUMN);
gtk_object_add_arg_type ("ECellText::bold_column",
GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_BOLD_COLUMN);
+ gtk_object_add_arg_type ("ECellText::color_column",
+ GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_COLOR_COLUMN);
gtk_object_add_arg_type ("ECellText::text_filter",
GTK_TYPE_POINTER, GTK_ARG_READWRITE, ARG_TEXT_FILTER);
@@ -1296,6 +1352,7 @@ e_cell_text_init (ECellText *ect)
{
ect->strikeout_column = -1;
ect->bold_column = -1;
+ ect->color_column = -1;
}
E_MAKE_TYPE(e_cell_text, "ECellText", ECellText, e_cell_text_class_init, e_cell_text_init, PARENT_TYPE);
@@ -2151,5 +2208,46 @@ static void
unbuild_current_cell (CurrentCell *cell)
{
g_free(cell->text);
+ cell->text = NULL;
+}
+
+
+static GdkColor*
+e_cell_text_get_color (ECellTextView *cell_view, gchar *color_spec)
+{
+ ECellText *ect = E_CELL_TEXT (((ECellView*) cell_view)->ecell);
+ GdkColormap *colormap;
+ GdkColor *color, tmp_color;
+
+ /* If the color spec is NULL we use the default color. */
+ if (color_spec == NULL)
+ return NULL;
+
+ /* Create the hash table if we haven't already. */
+ if (!ect->colors)
+ ect->colors = g_hash_table_new (g_str_hash, g_str_equal);
+
+ /* See if we've already allocated the color. Note that we use a
+ special value of (GdkColor*) 1 in the hash to indicate that we've
+ already tried and failed to allocate the color, so we don't keep
+ trying to allocate it. */
+ color = g_hash_table_lookup (ect->colors, color_spec);
+ if (color == (GdkColor*) 1)
+ return NULL;
+ if (color)
+ return color;
+
+ /* Try to parse the color. */
+ if (gdk_color_parse (color_spec, &tmp_color)) {
+ colormap = gtk_widget_get_colormap (GTK_WIDGET (cell_view->canvas));
+
+ /* Try to allocate the color. */
+ if (gdk_color_alloc (colormap, &tmp_color))
+ color = gdk_color_copy (&tmp_color);
+ }
+
+ g_hash_table_insert (ect->colors, g_strdup (color_spec),
+ color ? color : (GdkColor*) 1);
+ return color;
}
diff --git a/widgets/table/e-cell-text.h b/widgets/table/e-cell-text.h
index f1fc55c1f7..e0296998b3 100644
--- a/widgets/table/e-cell-text.h
+++ b/widgets/table/e-cell-text.h
@@ -54,7 +54,15 @@ typedef struct {
int strikeout_column;
int bold_column;
+ /* This column in the ETable should return a string specifying a color,
+ either a color name like "red" or a color spec like "rgb:F/0/0".
+ See the XParseColor man page for the formats available. */
+ int color_column;
+
ECellTextFilter filter;
+
+ /* This stores the colors we have allocated. */
+ GHashTable *colors;
} ECellText;
typedef struct {