aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/table
diff options
context:
space:
mode:
Diffstat (limited to 'widgets/table')
-rw-r--r--widgets/table/e-table-click-to-add.c410
-rw-r--r--widgets/table/e-table-click-to-add.h48
-rw-r--r--widgets/table/e-table-example-1.c8
-rw-r--r--widgets/table/e-table-example-2.c13
-rw-r--r--widgets/table/e-table-group-container.c26
-rw-r--r--widgets/table/e-table-group-leaf.c3
-rw-r--r--widgets/table/e-table-item.c1
-rw-r--r--widgets/table/e-table-model.c27
-rw-r--r--widgets/table/e-table-model.h5
-rw-r--r--widgets/table/e-table-one.c244
-rw-r--r--widgets/table/e-table-one.h30
-rw-r--r--widgets/table/e-table-simple.c63
-rw-r--r--widgets/table/e-table-simple.h21
-rw-r--r--widgets/table/e-table-size-test.c8
-rw-r--r--widgets/table/e-table-subset.c27
-rw-r--r--widgets/table/e-table.c82
-rw-r--r--widgets/table/e-table.h6
-rw-r--r--widgets/table/e-tree-model.c1
-rw-r--r--widgets/table/test-check.c10
-rw-r--r--widgets/table/test-cols.c10
-rw-r--r--widgets/table/test-table.c8
21 files changed, 1022 insertions, 29 deletions
diff --git a/widgets/table/e-table-click-to-add.c b/widgets/table/e-table-click-to-add.c
new file mode 100644
index 0000000000..30bf96b42a
--- /dev/null
+++ b/widgets/table/e-table-click-to-add.c
@@ -0,0 +1,410 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * e-table-click-to-add.c: A canvas item based view of the ETableColumn.
+ *
+ * Author:
+ * Miguel de Icaza (miguel@gnu.org)
+ *
+ * Copyright 1999, 2000 Helix Code, Inc.
+ */
+#include <config.h>
+#include <gtk/gtksignal.h>
+#include <libgnomeui/gnome-canvas.h>
+#include <libgnomeui/gnome-canvas-util.h>
+#include <libgnomeui/gnome-canvas-rect-ellipse.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include "e-table-header.h"
+#include "e-table-click-to-add.h"
+#include "e-table-defines.h"
+#include "e-table-one.h"
+#include "widgets/e-text/e-text.h"
+#include "e-util/e-canvas.h"
+
+enum {
+ ROW_SELECTION,
+ LAST_SIGNAL
+};
+
+static gint etcta_signals [LAST_SIGNAL] = { 0, };
+
+#define PARENT_OBJECT_TYPE gnome_canvas_group_get_type ()
+
+#define ELEMENTS(x) (sizeof (x) / sizeof (x[0]))
+
+static GnomeCanvasGroupClass *etcta_parent_class;
+
+enum {
+ ARG_0,
+ ARG_HEADER,
+ ARG_MODEL,
+ ARG_MESSAGE,
+ ARG_WIDTH,
+ ARG_HEIGHT,
+};
+
+static void
+etcta_row_selection (GtkObject *object, gint row, gboolean selected, ETableClickToAdd *etcta)
+{
+ gtk_signal_emit (GTK_OBJECT (etcta),
+ etcta_signals [ROW_SELECTION],
+ row, selected);
+}
+
+static void
+etcta_add_table_header (ETableClickToAdd *etcta, ETableHeader *header)
+{
+ etcta->eth = header;
+ if (etcta->eth)
+ gtk_object_ref (GTK_OBJECT (etcta->eth));
+ if (etcta->row)
+ gnome_canvas_item_set(GNOME_CANVAS_ITEM(etcta->row),
+ "ETableHeader", header,
+ NULL);
+}
+
+static void
+etcta_drop_table_header (ETableClickToAdd *etcta)
+{
+ GtkObject *header;
+
+ if (!etcta->eth)
+ return;
+
+ header = GTK_OBJECT (etcta->eth);
+
+ gtk_object_unref (header);
+ etcta->eth = NULL;
+}
+
+static void
+etcta_add_one (ETableClickToAdd *etcta, ETableModel *one)
+{
+ etcta->one = one;
+ if (etcta->one)
+ gtk_object_ref (GTK_OBJECT(etcta->one));
+ if (etcta->row)
+ gnome_canvas_item_set(GNOME_CANVAS_ITEM(etcta->row),
+ "ETableModel", one,
+ NULL);
+}
+
+static void
+etcta_drop_one (ETableClickToAdd *etcta)
+{
+ if (!etcta->one)
+ return;
+ gtk_object_unref (GTK_OBJECT(etcta->one));
+ etcta->one = NULL;
+}
+
+static void
+etcta_add_model (ETableClickToAdd *etcta, ETableModel *model)
+{
+ etcta->model = model;
+ if (etcta->model)
+ gtk_object_ref (GTK_OBJECT(etcta->model));
+}
+
+static void
+etcta_drop_model (ETableClickToAdd *etcta)
+{
+ etcta_drop_one (etcta);
+ if (!etcta->model)
+ return;
+ gtk_object_unref (GTK_OBJECT(etcta->model));
+ etcta->model = NULL;
+}
+
+static void
+etcta_add_message (ETableClickToAdd *etcta, char *message)
+{
+ etcta->message = g_strdup(message);
+}
+
+static void
+etcta_drop_message (ETableClickToAdd *etcta)
+{
+ g_free(etcta->message);
+ etcta->message = NULL;
+}
+
+
+static void
+etcta_destroy (GtkObject *object){
+ ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (object);
+
+ etcta_drop_table_header (etcta);
+ etcta_drop_model (etcta);
+ etcta_drop_message (etcta);
+
+ if (GTK_OBJECT_CLASS (etcta_parent_class)->destroy)
+ (*GTK_OBJECT_CLASS (etcta_parent_class)->destroy) (object);
+}
+
+static void
+etcta_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ GnomeCanvasItem *item;
+ ETableClickToAdd *etcta;
+
+ item = GNOME_CANVAS_ITEM (o);
+ etcta = E_TABLE_CLICK_TO_ADD (o);
+
+ switch (arg_id){
+ case ARG_HEADER:
+ etcta_drop_table_header (etcta);
+ etcta_add_table_header (etcta, E_TABLE_HEADER(GTK_VALUE_OBJECT (*arg)));
+ break;
+ case ARG_MODEL:
+ etcta_drop_model (etcta);
+ etcta_add_model (etcta, E_TABLE_MODEL(GTK_VALUE_OBJECT (*arg)));
+ break;
+ case ARG_MESSAGE:
+ etcta_drop_message (etcta);
+ etcta_add_message (etcta, GTK_VALUE_STRING (*arg));
+ break;
+ case ARG_WIDTH:
+ etcta->width = GTK_VALUE_DOUBLE (*arg);
+ if (etcta->row)
+ gnome_canvas_item_set(etcta->row,
+ "minimum_width", etcta->width,
+ NULL);
+ if (etcta->text)
+ gnome_canvas_item_set(etcta->text,
+ "width", etcta->width,
+ NULL);
+ break;
+ }
+ gnome_canvas_item_request_update(item);
+}
+
+static void
+etcta_get_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ ETableClickToAdd *etcta;
+
+ etcta = E_TABLE_CLICK_TO_ADD (o);
+
+ switch (arg_id){
+ case ARG_HEADER:
+ GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(etcta->eth);
+ break;
+ case ARG_MODEL:
+ GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(etcta->model);
+ break;
+ case ARG_MESSAGE:
+ GTK_VALUE_STRING (*arg) = g_strdup(etcta->message);
+ break;
+ case ARG_WIDTH:
+ GTK_VALUE_DOUBLE (*arg) = etcta->width;
+ break;
+ case ARG_HEIGHT:
+ GTK_VALUE_DOUBLE (*arg) = etcta->height;
+ break;
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ }
+}
+
+static void
+etcta_realize (GnomeCanvasItem *item)
+{
+ ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item);
+ etcta->text = gnome_canvas_item_new(GNOME_CANVAS_GROUP(item),
+ e_text_get_type(),
+ "text", etcta->message ? etcta->message : "",
+ "anchor", GTK_ANCHOR_NW,
+ "width", etcta->width,
+ NULL);
+
+ if (GNOME_CANVAS_ITEM_CLASS (etcta_parent_class)->realize)
+ (*GNOME_CANVAS_ITEM_CLASS (etcta_parent_class)->realize)(item);
+}
+
+static void
+etcta_unrealize (GnomeCanvasItem *item)
+{
+ if (GNOME_CANVAS_ITEM_CLASS (etcta_parent_class)->unrealize)
+ (*GNOME_CANVAS_ITEM_CLASS (etcta_parent_class)->unrealize)(item);
+}
+
+static double
+etcta_point (GnomeCanvasItem *item, double x, double y, int cx, int cy,
+ GnomeCanvasItem **actual_item)
+{
+ *actual_item = item;
+ return 0.0;
+}
+
+/*
+ * Handles the events on the ETableClickToAdd, particularly it creates the ETableItem and passes in some events.
+ */
+static int
+etcta_event (GnomeCanvasItem *item, GdkEvent *e)
+{
+ ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item);
+ int ret_val = TRUE;
+
+ switch (e->type){
+ case GDK_BUTTON_PRESS:
+ if (etcta->text) {
+ gtk_object_destroy(GTK_OBJECT(etcta->text));
+ etcta->text = NULL;
+ }
+ if (!etcta->row) {
+ ETableModel *one;
+
+ one = e_table_one_new(etcta->model);
+ etcta_add_one (etcta, one);
+ gtk_object_unref(GTK_OBJECT(one));
+
+ etcta->row = gnome_canvas_item_new(GNOME_CANVAS_GROUP(item),
+ e_table_item_get_type(),
+ "ETableHeader", etcta->eth,
+ "ETableModel", etcta->one,
+ "minimum_width", etcta->width,
+ "drawgrid", TRUE,
+ NULL);
+
+ gtk_signal_connect(GTK_OBJECT(etcta->row), "row_selection",
+ GTK_SIGNAL_FUNC(etcta_row_selection), etcta);
+ }
+ /* Fall through. No break; */
+ case GDK_BUTTON_RELEASE:
+ case GDK_2BUTTON_PRESS:
+ case GDK_3BUTTON_PRESS:
+ if (etcta->row) {
+ gnome_canvas_item_i2w (item, &e->button.x, &e->button.y);
+ gnome_canvas_item_w2i (etcta->row, &e->button.x, &e->button.y);
+ gtk_signal_emit_by_name(GTK_OBJECT(etcta->row), "event", e, &ret_val);
+ gnome_canvas_item_i2w (etcta->row, &e->button.x, &e->button.y);
+ gnome_canvas_item_w2i (item, &e->button.x, &e->button.y);
+ }
+ break;
+
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void
+etcta_reflow (GnomeCanvasItem *item, int flags)
+{
+ ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item);
+
+ if (etcta->text) {
+ gtk_object_get(GTK_OBJECT(etcta->text),
+ "height", &etcta->height,
+ NULL);
+ }
+ if (etcta->row) {
+ gtk_object_get(GTK_OBJECT(etcta->row),
+ "height", &etcta->height,
+ NULL);
+ }
+ e_canvas_item_request_parent_reflow(item);
+}
+
+static void
+etcta_class_init (ETableClickToAddClass *klass)
+{
+ GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS(klass);
+ GtkObjectClass *object_class = GTK_OBJECT_CLASS(klass);
+
+ etcta_parent_class = gtk_type_class (PARENT_OBJECT_TYPE);
+
+ klass->row_selection = NULL;
+
+ object_class->destroy = etcta_destroy;
+ object_class->set_arg = etcta_set_arg;
+ object_class->get_arg = etcta_get_arg;
+
+ item_class->realize = etcta_realize;
+ item_class->unrealize = etcta_unrealize;
+ item_class->point = etcta_point;
+ item_class->event = etcta_event;
+
+ gtk_object_add_arg_type ("ETableClickToAdd::header", GTK_TYPE_OBJECT,
+ GTK_ARG_READWRITE, ARG_HEADER);
+ gtk_object_add_arg_type ("ETableClickToAdd::model", GTK_TYPE_OBJECT,
+ GTK_ARG_READWRITE, ARG_MODEL);
+ gtk_object_add_arg_type ("ETableClickToAdd::message", GTK_TYPE_STRING,
+ GTK_ARG_READWRITE, ARG_MESSAGE);
+ gtk_object_add_arg_type ("ETableClickToAdd::width", GTK_TYPE_DOUBLE,
+ GTK_ARG_READWRITE, ARG_WIDTH);
+ gtk_object_add_arg_type ("ETableClickToAdd::height", GTK_TYPE_DOUBLE,
+ GTK_ARG_READABLE, ARG_HEIGHT);
+
+ etcta_signals [ROW_SELECTION] =
+ gtk_signal_new ("row_selection",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETableClickToAddClass, row_selection),
+ gtk_marshal_NONE__INT_INT,
+ GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
+
+ gtk_object_class_add_signals (object_class, etcta_signals, LAST_SIGNAL);
+}
+
+static void
+etcta_init (GnomeCanvasItem *item)
+{
+ ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item);
+
+ etcta->one = NULL;
+ etcta->model = NULL;
+ etcta->eth = NULL;
+
+ etcta->message = NULL;
+
+ etcta->row = NULL;
+ etcta->text = NULL;
+ etcta->rect = NULL;
+
+ e_canvas_item_set_reflow_callback(item, etcta_reflow);
+}
+
+GtkType
+e_table_click_to_add_get_type (void)
+{
+ static GtkType type = 0;
+
+ if (!type){
+ GtkTypeInfo info = {
+ "ETableClickToAdd",
+ sizeof (ETableClickToAdd),
+ sizeof (ETableClickToAddClass),
+ (GtkClassInitFunc) etcta_class_init,
+ (GtkObjectInitFunc) etcta_init,
+ NULL, /* reserved 1 */
+ NULL, /* reserved 2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ type = gtk_type_unique (PARENT_OBJECT_TYPE, &info);
+ }
+
+ return type;
+}
+
+void
+e_table_click_to_add_commit (ETableClickToAdd *etcta)
+{
+ if (etcta->row) {
+ e_table_one_commit(E_TABLE_ONE(etcta->one));
+ gtk_object_destroy(GTK_OBJECT(etcta->row));
+ etcta_drop_one (etcta);
+ etcta->row = NULL;
+ }
+ if (!etcta->text) {
+ etcta->text = gnome_canvas_item_new(GNOME_CANVAS_GROUP(etcta),
+ e_text_get_type(),
+ "text", etcta->message ? etcta->message : "",
+ "anchor", GTK_ANCHOR_NW,
+ "width", etcta->width,
+ NULL);
+ }
+}
diff --git a/widgets/table/e-table-click-to-add.h b/widgets/table/e-table-click-to-add.h
new file mode 100644
index 0000000000..db41303919
--- /dev/null
+++ b/widgets/table/e-table-click-to-add.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+#ifndef _E_TABLE_CLICK_TO_ADD_H_
+#define _E_TABLE_CLICK_TO_ADD_H_
+
+#include <libgnomeui/gnome-canvas.h>
+#include <gnome-xml/tree.h>
+#include "e-table-header.h"
+#include "e-table-sort-info.h"
+#include "e-table-item.h"
+
+#define E_TABLE_CLICK_TO_ADD_TYPE (e_table_click_to_add_get_type ())
+#define E_TABLE_CLICK_TO_ADD(o) (GTK_CHECK_CAST ((o), E_TABLE_CLICK_TO_ADD_TYPE, ETableClickToAdd))
+#define E_TABLE_CLICK_TO_ADD_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_CLICK_TO_ADD_TYPE, ETableClickToAddClass))
+#define E_IS_TABLE_CLICK_TO_ADD(o) (GTK_CHECK_TYPE ((o), E_TABLE_CLICK_TO_ADD_TYPE))
+#define E_IS_TABLE_CLICK_TO_ADD_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_CLICK_TO_ADD_TYPE))
+
+typedef struct {
+ GnomeCanvasGroup parent;
+
+ ETableModel *one; /* The ETableOne. */
+
+ ETableModel *model; /* The backend model. */
+ ETableHeader *eth; /* This is just to give to the ETableItem. */
+
+ char *message;
+
+ GnomeCanvasItem *row; /* If row is NULL, we're sitting with no data and a "Click here" message. */
+ GnomeCanvasItem *text; /* If text is NULL, row shouldn't be. */
+ GnomeCanvasItem *rect; /* What the heck. Why not. */
+
+ gdouble width;
+ gdouble height;
+} ETableClickToAdd;
+
+typedef struct {
+ GnomeCanvasGroupClass parent_class;
+
+ /*
+ * signals
+ */
+ void (*row_selection) (ETableClickToAdd *etcta, gint row, gboolean selected);
+} ETableClickToAddClass;
+
+GtkType e_table_click_to_add_get_type (void);
+
+void e_table_click_to_add_commit (ETableClickToAdd *etcta);
+
+#endif /* _E_TABLE_CLICK_TO_ADD_H_ */
diff --git a/widgets/table/e-table-example-1.c b/widgets/table/e-table-example-1.c
index 949131b597..7c289778aa 100644
--- a/widgets/table/e-table-example-1.c
+++ b/widgets/table/e-table-example-1.c
@@ -171,6 +171,13 @@ my_value_is_empty (ETableModel *etc, int col, const void *value, void *data)
return !(value && *(char *)value);
}
+/* This function reports if a value is empty. */
+static char *
+my_value_to_string (ETableModel *etc, int col, const void *value, void *data)
+{
+ return g_strdup(value);
+}
+
/* We create a window containing our new table. */
static void
create_table (void)
@@ -193,6 +200,7 @@ create_table (void)
my_set_value_at, my_is_cell_editable,
my_duplicate_value, my_free_value,
my_initialize_value, my_value_is_empty,
+ my_value_to_string,
NULL);
/*
* Next we create a header. The ETableHeader is used in two
diff --git a/widgets/table/e-table-example-2.c b/widgets/table/e-table-example-2.c
index 3accba6cb8..e9d8d9ea80 100644
--- a/widgets/table/e-table-example-2.c
+++ b/widgets/table/e-table-example-2.c
@@ -207,6 +207,18 @@ my_value_is_empty (ETableModel *etc, int col, const void *value, void *data)
}
}
+static char *
+my_value_to_string (ETableModel *etc, int col, const void *value, void *data)
+{
+ if (col == COLOR_COLUMN){
+ return g_strdup_printf("%d", (int) value);
+ } else if (col == IMPORTANCE_COLUMN){
+ return g_strdup_printf("%d", (int) value);
+ } else {
+ return g_strdup(value);
+ }
+}
+
/* We create a window containing our new table. */
static void
create_table ()
@@ -234,6 +246,7 @@ create_table ()
my_set_value_at, my_is_cell_editable,
my_duplicate_value, my_free_value,
my_initialize_value, my_value_is_empty,
+ my_value_to_string,
NULL);
/*
Next we create a header. The ETableHeader is used in two
diff --git a/widgets/table/e-table-group-container.c b/widgets/table/e-table-group-container.c
index b4e77cf95e..6bff77d4ad 100644
--- a/widgets/table/e-table-group-container.c
+++ b/widgets/table/e-table-group-container.c
@@ -43,6 +43,7 @@ enum {
typedef struct {
ETableGroup *child;
void *key;
+ char *string;
GnomeCanvasItem *text;
GnomeCanvasItem *rect;
gint count;
@@ -62,6 +63,7 @@ e_table_group_container_child_node_free (ETableGroupContainer *etgc,
gtk_object_destroy (GTK_OBJECT (child));
e_table_model_free_value (etg->model, etgc->ecol->col_idx,
child_node->key);
+ g_free(child_node->string);
gtk_object_destroy (GTK_OBJECT (child_node->text));
gtk_object_destroy (GTK_OBJECT (child_node->rect));
}
@@ -253,8 +255,10 @@ etgc_event (GnomeCanvasItem *item, GdkEvent *event)
}
}
return_val = FALSE;
+ break;
default:
return_val = FALSE;
+ break;
}
if (return_val == FALSE) {
if (GNOME_CANVAS_ITEM_CLASS(etgc_parent_class)->event)
@@ -293,12 +297,18 @@ etgc_unrealize (GnomeCanvasItem *item)
static void
compute_text (ETableGroupContainer *etgc, ETableGroupContainerChildNode *child_node)
{
- /* FIXME : What a hack, eh? */
- gchar *text = g_strdup_printf ("%s : %s (%d item%s)",
- etgc->ecol->text,
- (gchar *)child_node->key,
- (gint) child_node->count,
- child_node->count == 1 ? "" : "s");
+ gchar *text;
+ if (etgc->ecol->text)
+ text = g_strdup_printf ("%s : %s (%d item%s)",
+ etgc->ecol->text,
+ child_node->string,
+ (gint) child_node->count,
+ child_node->count == 1 ? "" : "s");
+ else
+ text = g_strdup_printf ("%s (%d item%s)",
+ child_node->string,
+ (gint) child_node->count,
+ child_node->count == 1 ? "" : "s");
gnome_canvas_item_set (child_node->text,
"text", text,
NULL);
@@ -399,6 +409,7 @@ etgc_add (ETableGroup *etg, gint row)
GTK_SIGNAL_FUNC (child_key_press), etgc);
child_node->child = child;
child_node->key = e_table_model_duplicate_value (etg->model, etgc->ecol->col_idx, val);
+ child_node->string = e_table_model_value_to_string (etg->model, etgc->ecol->col_idx, val);
child_node->count = 1;
e_table_group_add (child, row);
@@ -557,6 +568,7 @@ etgc_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
}
break;
case ARG_MINIMUM_WIDTH:
+ case ARG_WIDTH:
etgc->minimum_width = GTK_VALUE_DOUBLE(*arg);
for (list = etgc->children; list; list = g_list_next (list)) {
@@ -676,7 +688,7 @@ etgc_class_init (GtkObjectClass *object_class)
gtk_object_add_arg_type ("ETableGroupContainer::height", GTK_TYPE_DOUBLE,
GTK_ARG_READABLE, ARG_HEIGHT);
gtk_object_add_arg_type ("ETableGroupContainer::width", GTK_TYPE_DOUBLE,
- GTK_ARG_READABLE, ARG_WIDTH);
+ GTK_ARG_READWRITE, ARG_WIDTH);
gtk_object_add_arg_type ("ETableGroupContainer::minimum_width", GTK_TYPE_DOUBLE,
GTK_ARG_READWRITE, ARG_MINIMUM_WIDTH);
}
diff --git a/widgets/table/e-table-group-leaf.c b/widgets/table/e-table-group-leaf.c
index e16a3d5d6d..0c76129101 100644
--- a/widgets/table/e-table-group-leaf.c
+++ b/widgets/table/e-table-group-leaf.c
@@ -262,6 +262,7 @@ etgl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
}
break;
case ARG_MINIMUM_WIDTH:
+ case ARG_WIDTH:
etgl->minimum_width = GTK_VALUE_DOUBLE(*arg);
if (etgl->item) {
gnome_canvas_item_set (GNOME_CANVAS_ITEM(etgl->item),
@@ -371,7 +372,7 @@ etgl_class_init (GtkObjectClass *object_class)
gtk_object_add_arg_type ("ETableGroupLeaf::height", GTK_TYPE_DOUBLE,
GTK_ARG_READABLE, ARG_HEIGHT);
gtk_object_add_arg_type ("ETableGroupLeaf::width", GTK_TYPE_DOUBLE,
- GTK_ARG_READABLE, ARG_WIDTH);
+ GTK_ARG_READWRITE, ARG_WIDTH);
gtk_object_add_arg_type ("ETableGroupLeaf::minimum_width", GTK_TYPE_DOUBLE,
GTK_ARG_READWRITE, ARG_MINIMUM_WIDTH);
gtk_object_add_arg_type ("ETableGroupLeaf::frozen", GTK_TYPE_BOOL,
diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c
index b12021ae46..9df3b913db 100644
--- a/widgets/table/e-table-item.c
+++ b/widgets/table/e-table-item.c
@@ -816,6 +816,7 @@ eti_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
break;
case ARG_MINIMUM_WIDTH:
+ case ARG_WIDTH:
if (eti->minimum_width == eti->width && GTK_VALUE_DOUBLE (*arg) > eti->width)
e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti));
eti->minimum_width = GTK_VALUE_DOUBLE (*arg);
diff --git a/widgets/table/e-table-model.c b/widgets/table/e-table-model.c
index 62a45d966e..5045f68b02 100644
--- a/widgets/table/e-table-model.c
+++ b/widgets/table/e-table-model.c
@@ -85,6 +85,18 @@ e_table_model_is_cell_editable (ETableModel *e_table_model, int col, int row)
return ETM_CLASS (e_table_model)->is_cell_editable (e_table_model, col, row);
}
+gint
+e_table_model_append_row (ETableModel *e_table_model)
+{
+ g_return_val_if_fail (e_table_model != NULL, -1);
+ g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), -1);
+
+ if (ETM_CLASS (e_table_model)->append_row)
+ return ETM_CLASS (e_table_model)->append_row (e_table_model);
+ else
+ return -1;
+}
+
void *
e_table_model_duplicate_value (ETableModel *e_table_model, int col, const void *value)
{
@@ -131,6 +143,18 @@ e_table_model_value_is_empty (ETableModel *e_table_model, int col, const void *v
return FALSE;
}
+char *
+e_table_model_value_to_string (ETableModel *e_table_model, int col, const void *value)
+{
+ g_return_val_if_fail (e_table_model != NULL, NULL);
+ g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), NULL);
+
+ if (ETM_CLASS (e_table_model)->value_to_string)
+ return ETM_CLASS (e_table_model)->value_to_string (e_table_model, col, value);
+ else
+ return g_strdup("");
+}
+
static void
e_table_model_destroy (GtkObject *object)
{
@@ -193,10 +217,13 @@ e_table_model_class_init (GtkObjectClass *object_class)
klass->value_at = NULL;
klass->set_value_at = NULL;
klass->is_cell_editable = NULL;
+ klass->append_row = NULL;
+
klass->duplicate_value = NULL;
klass->free_value = NULL;
klass->initialize_value = NULL;
klass->value_is_empty = NULL;
+ klass->value_to_string = NULL;
klass->model_changed = NULL;
klass->model_row_changed = NULL;
klass->model_cell_changed = NULL;
diff --git a/widgets/table/e-table-model.h b/widgets/table/e-table-model.h
index e73df7fa45..dc18d972b5 100644
--- a/widgets/table/e-table-model.h
+++ b/widgets/table/e-table-model.h
@@ -25,6 +25,7 @@ typedef struct {
void *(*value_at) (ETableModel *etm, int col, int row);
void (*set_value_at) (ETableModel *etm, int col, int row, const void *value);
gboolean (*is_cell_editable) (ETableModel *etm, int col, int row);
+ gint (*append_row) (ETableModel *etm);
/* Allocate a copy of the given value. */
void *(*duplicate_value) (ETableModel *etm, int col, const void *value);
@@ -34,6 +35,8 @@ typedef struct {
void *(*initialize_value) (ETableModel *etm, int col);
/* Return TRUE if value is equivalent to an empty cell. */
gboolean (*value_is_empty) (ETableModel *etm, int col, const void *value);
+ /* Return an allocated string. */
+ char *(*value_to_string) (ETableModel *etm, int col, const void *value);
/*
* Signals
@@ -62,11 +65,13 @@ int e_table_model_row_count (ETableModel *e_table_model);
void *e_table_model_value_at (ETableModel *e_table_model, int col, int row);
void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, const void *value);
gboolean e_table_model_is_cell_editable (ETableModel *e_table_model, int col, int row);
+gint e_table_model_append_row (ETableModel *e_table_model);
void *e_table_model_duplicate_value (ETableModel *e_table_model, int col, const void *value);
void e_table_model_free_value (ETableModel *e_table_model, int col, void *value);
void *e_table_model_initialize_value (ETableModel *e_table_model, int col);
gboolean e_table_model_value_is_empty (ETableModel *e_table_model, int col, const void *value);
+char *e_table_model_value_to_string (ETableModel *e_table_model, int col, const void *value);
/*
* Routines for emitting signals on the e_table
diff --git a/widgets/table/e-table-one.c b/widgets/table/e-table-one.c
new file mode 100644
index 0000000000..73022a5801
--- /dev/null
+++ b/widgets/table/e-table-one.c
@@ -0,0 +1,244 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * e-table-model.c: a one table model implementation that uses function
+ * pointers to simplify the creation of new, exotic and colorful tables in
+ * no time.
+ *
+ * Author:
+ * Miguel de Icaza (miguel@gnu.org)
+ *
+ * (C) 1999 Helix Code, Inc.
+ */
+
+#include <config.h>
+#include "e-table-one.h"
+
+#define PARENT_TYPE e_table_model_get_type ()
+
+static int
+one_column_count (ETableModel *etm)
+{
+ ETableOne *one = E_TABLE_ONE(etm);
+
+ if (one->source)
+ return e_table_model_column_count(one->source);
+ else
+ return 0;
+}
+
+static int
+one_row_count (ETableModel *etm)
+{
+ return 1;
+}
+
+static void *
+one_value_at (ETableModel *etm, int col, int row)
+{
+ ETableOne *one = E_TABLE_ONE(etm);
+
+ if (one->data)
+ return one->data[col];
+ else
+ return NULL;
+}
+
+static void
+one_set_value_at (ETableModel *etm, int col, int row, const void *val)
+{
+ ETableOne *one = E_TABLE_ONE(etm);
+
+ if (one->data && one->source) {
+ e_table_model_free_value(one->source, col, one->data[col]);
+ one->data[col] = e_table_model_duplicate_value(one->source, col, val);
+ }
+}
+
+static gboolean
+one_is_cell_editable (ETableModel *etm, int col, int row)
+{
+ ETableOne *one = E_TABLE_ONE(etm);
+
+ if (one->source)
+ return e_table_model_is_cell_editable(one->source, 0, row);
+ else
+ return FALSE;
+}
+
+/* The default for one_duplicate_value is to return the raw value. */
+static void *
+one_duplicate_value (ETableModel *etm, int col, const void *value)
+{
+ ETableOne *one = E_TABLE_ONE(etm);
+
+ if (one->source)
+ return e_table_model_duplicate_value(one->source, col, value);
+ else
+ return (void *)value;
+}
+
+static void
+one_free_value (ETableModel *etm, int col, void *value)
+{
+ ETableOne *one = E_TABLE_ONE(etm);
+
+ if (one->source)
+ e_table_model_free_value(one->source, col, value);
+}
+
+static void *
+one_initialize_value (ETableModel *etm, int col)
+{
+ ETableOne *one = E_TABLE_ONE(etm);
+
+ if (one->source)
+ return e_table_model_initialize_value (one->source, col);
+ else
+ return NULL;
+}
+
+static gboolean
+one_value_is_empty (ETableModel *etm, int col, const void *value)
+{
+ ETableOne *one = E_TABLE_ONE(etm);
+
+ if (one->source)
+ return e_table_model_value_is_empty (one->source, col, value);
+ else
+ return FALSE;
+}
+
+static char *
+one_value_to_string (ETableModel *etm, int col, const void *value)
+{
+ ETableOne *one = E_TABLE_ONE(etm);
+
+ if (one->source)
+ return e_table_model_value_to_string (one->source, col, value);
+ else
+ return g_strdup("");
+}
+
+static void
+one_destroy (GtkObject *object)
+{
+ ETableOne *one = E_TABLE_ONE(object);
+
+ if (one->source) {
+ int i;
+ int col_count;
+
+ col_count = e_table_model_column_count(one->source);
+
+ if (one->data) {
+ for (i = 0; i < col_count; i++) {
+ e_table_model_free_value(one->source, i, one->data[i]);
+ }
+ }
+
+ gtk_object_unref(GTK_OBJECT(one->source));
+ }
+
+ g_free(one->data);
+}
+
+static void
+e_table_one_class_init (GtkObjectClass *object_class)
+{
+ ETableModelClass *model_class = (ETableModelClass *) object_class;
+
+ model_class->column_count = one_column_count;
+ model_class->row_count = one_row_count;
+ model_class->value_at = one_value_at;
+ model_class->set_value_at = one_set_value_at;
+ model_class->is_cell_editable = one_is_cell_editable;
+ model_class->duplicate_value = one_duplicate_value;
+ model_class->free_value = one_free_value;
+ model_class->initialize_value = one_initialize_value;
+ model_class->value_is_empty = one_value_is_empty;
+ model_class->value_to_string = one_value_to_string;
+
+ object_class->destroy = one_destroy;
+}
+
+static void
+e_table_one_init (GtkObject *object)
+{
+ ETableOne *one = E_TABLE_ONE(object);
+
+ one->source = NULL;
+ one->data = NULL;
+}
+
+GtkType
+e_table_one_get_type (void)
+{
+ static GtkType type = 0;
+
+ if (!type){
+ GtkTypeInfo info = {
+ "ETableOne",
+ sizeof (ETableOne),
+ sizeof (ETableOneClass),
+ (GtkClassInitFunc) e_table_one_class_init,
+ (GtkObjectInitFunc) e_table_one_init,
+ NULL, /* reserved 1 */
+ NULL, /* reserved 2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ type = gtk_type_unique (PARENT_TYPE, &info);
+ }
+
+ return type;
+}
+
+ETableModel *
+e_table_one_new (ETableModel *source)
+{
+ ETableOne *eto;
+ int col_count;
+ int i;
+
+ eto = gtk_type_new (e_table_one_get_type ());
+
+ eto->source = source;
+
+ col_count = e_table_model_column_count(source);
+ eto->data = g_new(void *, col_count);
+ for (i = 0; i < col_count; i++) {
+ eto->data[i] = e_table_model_initialize_value(source, i);
+ }
+
+ if (source)
+ gtk_object_ref(GTK_OBJECT(source));
+
+ return (ETableModel *) eto;
+}
+
+gint
+e_table_one_commit (ETableOne *one)
+{
+ if (one->source) {
+ int empty = TRUE;
+ int col;
+ int cols = e_table_model_column_count(one->source);
+ for (col = 0; col < cols; col++) {
+ if (!e_table_model_value_is_empty(one->source, col, one->data[col])) {
+ empty = FALSE;
+ break;
+ }
+ }
+
+ if (!empty) {
+ int row = e_table_model_append_row(one->source);
+ if (row != -1) {
+ for (col = 0; col < cols; col++) {
+ e_table_model_set_value_at(one->source, col, row, one->data[col]);
+ }
+ }
+ return row;
+ }
+ }
+ return -1;
+}
diff --git a/widgets/table/e-table-one.h b/widgets/table/e-table-one.h
new file mode 100644
index 0000000000..933d2c7a2d
--- /dev/null
+++ b/widgets/table/e-table-one.h
@@ -0,0 +1,30 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+#ifndef _E_TABLE_ONE_H_
+#define _E_TABLE_ONE_H_
+
+#include "e-table-model.h"
+
+#define E_TABLE_ONE_TYPE (e_table_one_get_type ())
+#define E_TABLE_ONE(o) (GTK_CHECK_CAST ((o), E_TABLE_ONE_TYPE, ETableOne))
+#define E_TABLE_ONE_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_ONE_TYPE, ETableOneClass))
+#define E_IS_TABLE_ONE(o) (GTK_CHECK_TYPE ((o), E_TABLE_ONE_TYPE))
+#define E_IS_TABLE_ONE_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_ONE_TYPE))
+
+typedef struct {
+ ETableModel parent;
+
+ ETableModel *source;
+ void **data;
+} ETableOne;
+
+typedef struct {
+ ETableModelClass parent_class;
+} ETableOneClass;
+
+GtkType e_table_one_get_type (void);
+
+ETableModel *e_table_one_new (ETableModel *source);
+gint e_table_one_commit (ETableOne *one);
+
+#endif /* _E_TABLE_ONE_H_ */
+
diff --git a/widgets/table/e-table-simple.c b/widgets/table/e-table-simple.c
index e823e8d550..fa0a25f784 100644
--- a/widgets/table/e-table-simple.c
+++ b/widgets/table/e-table-simple.c
@@ -13,6 +13,11 @@
#include <config.h>
#include "e-table-simple.h"
+enum {
+ ARG_0,
+ ARG_APPEND_ROW,
+};
+
#define PARENT_TYPE e_table_model_get_type ()
static int
@@ -111,11 +116,62 @@ simple_value_is_empty (ETableModel *etm, int col, const void *value)
return FALSE;
}
+static char *
+simple_value_to_string (ETableModel *etm, int col, const void *value)
+{
+ ETableSimple *simple = E_TABLE_SIMPLE(etm);
+
+ if (simple->value_to_string)
+ return simple->value_to_string (etm, col, value, simple->data);
+ else
+ return g_strdup ("");
+}
+
+static int
+simple_append_row (ETableModel *etm)
+{
+ ETableSimple *simple = E_TABLE_SIMPLE(etm);
+
+ if (simple->append_row)
+ return simple->append_row (etm, simple->data);
+ else
+ return -1;
+}
+
+static void
+simple_get_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ ETableSimple *simple = E_TABLE_SIMPLE (o);
+
+ switch (arg_id){
+ case ARG_APPEND_ROW:
+ GTK_VALUE_POINTER(*arg) = simple->append_row;
+ break;
+ }
+}
+
+static void
+simple_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ ETableSimple *simple = E_TABLE_SIMPLE (o);
+
+ switch (arg_id){
+ case ARG_APPEND_ROW:
+ simple->append_row = GTK_VALUE_POINTER(*arg);
+ break;
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ }
+}
+
static void
e_table_simple_class_init (GtkObjectClass *object_class)
{
ETableModelClass *model_class = (ETableModelClass *) object_class;
+ object_class->set_arg = simple_set_arg;
+ object_class->get_arg = simple_get_arg;
+
model_class->column_count = simple_column_count;
model_class->row_count = simple_row_count;
model_class->value_at = simple_value_at;
@@ -125,6 +181,11 @@ e_table_simple_class_init (GtkObjectClass *object_class)
model_class->free_value = simple_free_value;
model_class->initialize_value = simple_initialize_value;
model_class->value_is_empty = simple_value_is_empty;
+ model_class->value_to_string = simple_value_to_string;
+ model_class->append_row = simple_append_row;
+
+ gtk_object_add_arg_type ("ETableSimple::append_row", GTK_TYPE_POINTER,
+ GTK_ARG_READWRITE, ARG_APPEND_ROW);
}
GtkType
@@ -160,6 +221,7 @@ e_table_simple_new (ETableSimpleColumnCountFn col_count,
ETableSimpleFreeValueFn free_value,
ETableSimpleInitializeValueFn initialize_value,
ETableSimpleValueIsEmptyFn value_is_empty,
+ ETableSimpleValueToStringFn value_to_string,
void *data)
{
ETableSimple *et;
@@ -175,6 +237,7 @@ e_table_simple_new (ETableSimpleColumnCountFn col_count,
et->free_value = free_value;
et->initialize_value = initialize_value;
et->value_is_empty = value_is_empty;
+ et->value_to_string = value_to_string;
et->data = data;
return (ETableModel *) et;
diff --git a/widgets/table/e-table-simple.h b/widgets/table/e-table-simple.h
index 31ebd439f0..7fbed8d28b 100644
--- a/widgets/table/e-table-simple.h
+++ b/widgets/table/e-table-simple.h
@@ -15,23 +15,27 @@ typedef int (*ETableSimpleRowCountFn) (ETableModel *etm, void *da
typedef void *(*ETableSimpleValueAtFn) (ETableModel *etm, int col, int row, void *data);
typedef void (*ETableSimpleSetValueAtFn) (ETableModel *etm, int col, int row, const void *val, void *data);
typedef gboolean (*ETableSimpleIsCellEditableFn) (ETableModel *etm, int col, int row, void *data);
+typedef gint (*ETableSimpleAppendRowFn) (ETableModel *etm, void *data);
typedef void *(*ETableSimpleDuplicateValueFn) (ETableModel *etm, int col, const void *val, void *data);
typedef void (*ETableSimpleFreeValueFn) (ETableModel *etm, int col, void *val, void *data);
typedef void *(*ETableSimpleInitializeValueFn) (ETableModel *etm, int col, void *data);
typedef gboolean (*ETableSimpleValueIsEmptyFn) (ETableModel *etm, int col, const void *val, void *data);
+typedef char *(*ETableSimpleValueToStringFn) (ETableModel *etm, int col, const void *val, void *data);
typedef struct {
ETableModel parent;
- ETableSimpleColumnCountFn col_count;
- ETableSimpleRowCountFn row_count;
- ETableSimpleValueAtFn value_at;
- ETableSimpleSetValueAtFn set_value_at;
- ETableSimpleIsCellEditableFn is_cell_editable;
- ETableSimpleDuplicateValueFn duplicate_value;
- ETableSimpleFreeValueFn free_value;
+ ETableSimpleColumnCountFn col_count;
+ ETableSimpleRowCountFn row_count;
+ ETableSimpleValueAtFn value_at;
+ ETableSimpleSetValueAtFn set_value_at;
+ ETableSimpleIsCellEditableFn is_cell_editable;
+ ETableSimpleDuplicateValueFn duplicate_value;
+ ETableSimpleFreeValueFn free_value;
ETableSimpleInitializeValueFn initialize_value;
- ETableSimpleValueIsEmptyFn value_is_empty;
+ ETableSimpleValueIsEmptyFn value_is_empty;
+ ETableSimpleValueToStringFn value_to_string;
+ ETableSimpleAppendRowFn append_row;
void *data;
} ETableSimple;
@@ -50,6 +54,7 @@ ETableModel *e_table_simple_new (ETableSimpleColumnCountFn col_count,
ETableSimpleFreeValueFn free_value,
ETableSimpleInitializeValueFn initialize_value,
ETableSimpleValueIsEmptyFn value_is_empty,
+ ETableSimpleValueToStringFn value_to_string,
void *data);
#endif /* _E_TABLE_SIMPLE_H_ */
diff --git a/widgets/table/e-table-size-test.c b/widgets/table/e-table-size-test.c
index 12040b29d4..b3a2cbbe18 100644
--- a/widgets/table/e-table-size-test.c
+++ b/widgets/table/e-table-size-test.c
@@ -171,6 +171,13 @@ my_value_is_empty (ETableModel *etc, int col, const void *value, void *data)
return !(value && *(char *)value);
}
+/* This function reports if a value is empty. */
+static char *
+my_value_to_string (ETableModel *etc, int col, const void *value, void *data)
+{
+ return g_strdup(value);
+}
+
/* We create a window containing our new table. */
static void
create_table (void)
@@ -188,6 +195,7 @@ create_table (void)
my_set_value_at, my_is_cell_editable,
my_duplicate_value, my_free_value,
my_initialize_value, my_value_is_empty,
+ my_value_to_string,
NULL);
/*
* Next we create a header. The ETableHeader is used in two
diff --git a/widgets/table/e-table-subset.c b/widgets/table/e-table-subset.c
index d2b1e37a9d..eb08ca0890 100644
--- a/widgets/table/e-table-subset.c
+++ b/widgets/table/e-table-subset.c
@@ -82,6 +82,23 @@ etss_is_cell_editable (ETableModel *etm, int col, int row)
return e_table_model_is_cell_editable (etss->source, col, etss->map_table [row]);
}
+static gint
+etss_append_row (ETableModel *etm)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+ gint source_row = e_table_model_append_row (etss->source);
+ const int n = etss->n_map;
+ const int * const map_table = etss->map_table;
+ int i;
+
+ for (i = 0; i < n; i++){
+ if (map_table [i] == source_row){
+ return i;
+ }
+ }
+ return -1;
+}
+
static void *
etss_duplicate_value (ETableModel *etm, int col, const void *value)
{
@@ -114,6 +131,14 @@ etss_value_is_empty (ETableModel *etm, int col, const void *value)
return e_table_model_value_is_empty (etss->source, col, value);
}
+static char *
+etss_value_to_string (ETableModel *etm, int col, const void *value)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_value_to_string (etss->source, col, value);
+}
+
static void
etss_class_init (GtkObjectClass *klass)
{
@@ -128,10 +153,12 @@ etss_class_init (GtkObjectClass *klass)
table_class->value_at = etss_value_at;
table_class->set_value_at = etss_set_value_at;
table_class->is_cell_editable = etss_is_cell_editable;
+ table_class->append_row = etss_append_row;
table_class->duplicate_value = etss_duplicate_value;
table_class->free_value = etss_free_value;
table_class->initialize_value = etss_initialize_value;
table_class->value_is_empty = etss_value_is_empty;
+ table_class->value_to_string = etss_value_to_string;
}
E_MAKE_TYPE(e_table_subset, "ETableSubset", ETableSubset, etss_class_init, NULL, PARENT_TYPE);
diff --git a/widgets/table/e-table.c b/widgets/table/e-table.c
index c4239068fa..83d9422be6 100644
--- a/widgets/table/e-table.c
+++ b/widgets/table/e-table.c
@@ -26,12 +26,14 @@
#include "e-util/e-util.h"
#include "e-util/e-xml-utils.h"
#include "e-util/e-canvas.h"
+#include "e-util/e-canvas-vbox.h"
#include "e-table.h"
#include "e-table-header-item.h"
#include "e-table-subset.h"
#include "e-table-item.h"
#include "e-table-group.h"
#include "e-table-group-leaf.h"
+#include "e-table-click-to-add.h"
#define COLUMN_HEADER_HEIGHT 16
#define TITLE_HEIGHT 16
@@ -56,6 +58,7 @@ enum {
ARG_TABLE_DRAW_FOCUS,
ARG_CURSOR_MODE,
ARG_LENGTH_THRESHOLD,
+ ARG_CLICK_TO_ADD_MESSAGE,
};
static gint et_signals [LAST_SIGNAL] = { 0, };
@@ -99,6 +102,8 @@ et_destroy (GtkObject *object)
et->rebuild_idle_id = 0;
}
+ g_free(et->click_to_add_message);
+
(*e_table_parent_class->destroy)(object);
}
@@ -121,6 +126,8 @@ e_table_init (GtkObject *object)
e_table->need_rebuild = 0;
e_table->rebuild_idle_id = 0;
+
+ e_table->click_to_add_message = NULL;
}
static void
@@ -167,7 +174,7 @@ table_canvas_reflow_idle (ETable *e_table)
gdouble height, width;
GtkAllocation *alloc = &(GTK_WIDGET (e_table->table_canvas)->allocation);
- gtk_object_get (GTK_OBJECT (e_table->group),
+ gtk_object_get (GTK_OBJECT (e_table->canvas_vbox),
"height", &height,
"width", &width,
NULL);
@@ -186,8 +193,8 @@ table_canvas_size_allocate (GtkWidget *widget, GtkAllocation *alloc,
gdouble width;
width = alloc->width;
- gtk_object_set (GTK_OBJECT (e_table->group),
- "minimum_width", width,
+ gtk_object_set (GTK_OBJECT (e_table->canvas_vbox),
+ "width", width,
NULL);
gtk_object_set (GTK_OBJECT (e_table->header),
"width", width,
@@ -210,6 +217,10 @@ group_row_selection (ETableGroup *etg, int row, gboolean selected, ETable *et)
gtk_signal_emit (GTK_OBJECT (et),
et_signals [ROW_SELECTION],
row, selected);
+ if (et->row_selection_active && selected) {
+ e_table_click_to_add_commit (E_TABLE_CLICK_TO_ADD(et->click_to_add));
+ et->row_selection_active = FALSE;
+ }
}
static void
@@ -255,12 +266,13 @@ changed_idle (gpointer data)
if (et->need_rebuild) {
gtk_object_destroy (GTK_OBJECT (et->group));
- et->group = e_table_group_new (GNOME_CANVAS_GROUP (et->table_canvas->root),
+ et->group = e_table_group_new (GNOME_CANVAS_GROUP (et->canvas_vbox),
et->full_header,
et->header,
et->model,
et->sort_info,
0);
+ e_canvas_vbox_add_item(E_CANVAS_VBOX(et->canvas_vbox), GNOME_CANVAS_ITEM(et->group));
gnome_canvas_item_set(GNOME_CANVAS_ITEM(et->group),
"drawgrid", et->draw_grid,
"drawfocus", et->draw_focus,
@@ -279,8 +291,8 @@ changed_idle (gpointer data)
GTK_SIGNAL_FUNC (group_key_press), et);
e_table_fill_table (et, et->model);
- gtk_object_set (GTK_OBJECT (et->group),
- "minimum_width", (double) GTK_WIDGET (et->table_canvas)->allocation.width,
+ gtk_object_set (GTK_OBJECT (et->canvas_vbox),
+ "width", (double) GTK_WIDGET (et->table_canvas)->allocation.width,
NULL);
}
@@ -330,6 +342,14 @@ et_table_row_deleted (ETableModel *table_model, int row, ETable *et)
}
static void
+click_to_add_row_selection (ETableClickToAdd *etcta, int row, gboolean selected, ETable *et)
+{
+ if ((!et->row_selection_active) && selected) {
+ et->row_selection_active = TRUE;
+ }
+}
+
+static void
e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *header,
ETableModel *model)
{
@@ -342,11 +362,32 @@ e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *h
GTK_SIGNAL_FUNC (table_canvas_reflow), e_table);
gtk_widget_show (GTK_WIDGET (e_table->table_canvas));
+
+ e_table->canvas_vbox = gnome_canvas_item_new(gnome_canvas_root(e_table->table_canvas),
+ e_canvas_vbox_get_type(),
+ "spacing", 10.0,
+ NULL);
+
+ if (e_table->use_click_to_add) {
+ e_table->click_to_add = gnome_canvas_item_new (GNOME_CANVAS_GROUP(e_table->canvas_vbox),
+ e_table_click_to_add_get_type (),
+ "header", e_table->header,
+ "model", e_table->model,
+ "message", e_table->click_to_add_message,
+ NULL);
+
+ gtk_signal_connect(GTK_OBJECT(e_table->click_to_add), "row_selection",
+ GTK_SIGNAL_FUNC(click_to_add_row_selection), e_table);
+
+ e_canvas_vbox_add_item(E_CANVAS_VBOX(e_table->canvas_vbox), e_table->click_to_add);
+ }
+
e_table->group = e_table_group_new (
- GNOME_CANVAS_GROUP (e_table->table_canvas->root),
+ GNOME_CANVAS_GROUP (e_table->canvas_vbox),
full_header, header,
model, e_table->sort_info, 0);
+ e_canvas_vbox_add_item(E_CANVAS_VBOX(e_table->canvas_vbox), GNOME_CANVAS_ITEM(e_table->group));
gnome_canvas_item_set(GNOME_CANVAS_ITEM(e_table->group),
"drawgrid", e_table->draw_grid,
@@ -385,6 +426,7 @@ e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *h
e_table->table_row_deleted_id = gtk_signal_connect (
GTK_OBJECT (model), "model_row_deleted",
GTK_SIGNAL_FUNC (et_table_row_deleted), e_table);
+
}
static void
@@ -463,7 +505,7 @@ et_real_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm,
xmlNode *xmlRoot;
xmlNode *xmlColumns;
xmlNode *xmlGrouping;
- int no_header;
+ gboolean no_header;
int row = 0;
GtkWidget *internal_table;
@@ -477,6 +519,8 @@ et_real_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm,
return NULL;
no_header = e_xml_get_integer_prop_by_name(xmlRoot, "no-header");
+ e_table->use_click_to_add = e_xml_get_integer_prop_by_name(xmlRoot, "click-to-add");
+
e_table->full_header = full_header;
gtk_object_ref (GTK_OBJECT (full_header));
@@ -521,9 +565,8 @@ et_real_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm,
/*
* The header
*/
- gtk_table_attach (
- GTK_TABLE (internal_table), GTK_WIDGET (e_table->header_canvas),
- 0, 1, 0, 1,
+ gtk_table_attach (GTK_TABLE (internal_table), GTK_WIDGET (e_table->header_canvas),
+ 0, 1, 0 + row, 1 + row,
GTK_FILL | GTK_EXPAND,
GTK_FILL, 0, 0);
row ++;
@@ -732,6 +775,10 @@ et_get_arg (GtkObject *o, GtkArg *arg, guint arg_id)
case ARG_TABLE_DRAW_FOCUS:
GTK_VALUE_BOOL (*arg) = etable->draw_focus;
break;
+
+ case ARG_CLICK_TO_ADD_MESSAGE:
+ GTK_VALUE_STRING (*arg) = g_strdup (etable->click_to_add_message);
+ break;
}
}
@@ -781,6 +828,15 @@ et_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
NULL);
}
break;
+ case ARG_CLICK_TO_ADD_MESSAGE:
+ if (etable->click_to_add_message)
+ g_free(etable->click_to_add_message);
+ etable->click_to_add_message = g_strdup(GTK_VALUE_STRING (*arg));
+ if (etable->click_to_add)
+ gnome_canvas_item_set(etable->click_to_add,
+ "message", etable->click_to_add_message,
+ NULL);
+ break;
}
}
@@ -850,8 +906,8 @@ e_table_class_init (GtkObjectClass *object_class)
GTK_ARG_WRITABLE, ARG_CURSOR_MODE);
gtk_object_add_arg_type ("ETable::length_threshold", GTK_TYPE_INT,
GTK_ARG_WRITABLE, ARG_LENGTH_THRESHOLD);
-
-
+ gtk_object_add_arg_type ("ETable::click_to_add_message", GTK_TYPE_STRING,
+ GTK_ARG_READWRITE, ARG_CLICK_TO_ADD_MESSAGE);
}
E_MAKE_TYPE(e_table, "ETable", ETable, e_table_class_init, e_table_init, PARENT_TYPE);
diff --git a/widgets/table/e-table.h b/widgets/table/e-table.h
index a733d5951e..c945e48772 100644
--- a/widgets/table/e-table.h
+++ b/widgets/table/e-table.h
@@ -27,6 +27,7 @@ typedef struct {
ETableHeader *full_header, *header;
+ GnomeCanvasItem *canvas_vbox;
ETableGroup *group;
ETableSortInfo *sort_info;
@@ -55,6 +56,11 @@ typedef struct {
*/
guint draw_grid : 1;
guint draw_focus : 1;
+ guint row_selection_active : 1;
+
+ char *click_to_add_message;
+ GnomeCanvasItem *click_to_add;
+ gboolean use_click_to_add;
ETableCursorMode cursor_mode;
} ETable;
diff --git a/widgets/table/e-tree-model.c b/widgets/table/e-tree-model.c
index 992caf40f2..250ff4edb7 100644
--- a/widgets/table/e-tree-model.c
+++ b/widgets/table/e-tree-model.c
@@ -334,6 +334,7 @@ e_tree_model_class_init (GtkObjectClass *klass)
table_class->free_value = etable_free_value;
table_class->initialize_value = etable_initialize_value;
table_class->value_is_empty = etable_value_is_empty;
+ table_class->value_to_string = etable_value_to_string;
table_class->thaw = etable_thaw;
#endif
diff --git a/widgets/table/test-check.c b/widgets/table/test-check.c
index c330956918..3bb022821e 100644
--- a/widgets/table/test-check.c
+++ b/widgets/table/test-check.c
@@ -118,6 +118,15 @@ value_is_empty (ETableModel *etc, int col, const void *value, void *data)
return !(value && *(char *)value);
}
+static char *
+value_to_string (ETableModel *etc, int col, const void *value, void *data)
+{
+ if (col == 0)
+ return g_strdup_printf("%d", (int) value);
+ else
+ return g_strdup(value);
+}
+
static void
set_canvas_size (GnomeCanvas *canvas, GtkAllocation *alloc)
{
@@ -143,6 +152,7 @@ check_test (void)
set_value_at, is_cell_editable,
duplicate_value, free_value,
initialize_value, value_is_empty,
+ value_to_string,
NULL);
/*
diff --git a/widgets/table/test-cols.c b/widgets/table/test-cols.c
index d4372b189f..c47a1d47d7 100644
--- a/widgets/table/test-cols.c
+++ b/widgets/table/test-cols.c
@@ -118,6 +118,15 @@ value_is_empty (ETableModel *etc, int col, const void *value, void *data)
return !(value && *(char *)value);
}
+static char *
+value_to_string (ETableModel *etc, int col, const void *value, void *data)
+{
+ if (col == 0)
+ return g_strdup_printf("%d", (int) value);
+ else
+ return g_strdup(value);
+}
+
static void
set_canvas_size (GnomeCanvas *canvas, GtkAllocation *alloc)
{
@@ -142,6 +151,7 @@ multi_cols_test (void)
set_value_at, is_cell_editable,
duplicate_value, free_value,
initialize_value, value_is_empty,
+ value_to_string,
NULL);
/*
diff --git a/widgets/table/test-table.c b/widgets/table/test-table.c
index a12094ef19..b30b412f08 100644
--- a/widgets/table/test-table.c
+++ b/widgets/table/test-table.c
@@ -202,6 +202,12 @@ value_is_empty (ETableModel *etc, int col, const void *value, void *data)
return !(value && *(char *)value);
}
+static char *
+value_to_string (ETableModel *etc, int col, const void *value, void *data)
+{
+ return g_strdup(value);
+}
+
static void
set_canvas_size (GnomeCanvas *canvas, GtkAllocation *alloc)
{
@@ -228,6 +234,7 @@ table_browser_test (void)
set_value_at, is_cell_editable,
duplicate_value, free_value,
initialize_value, value_is_empty,
+ value_to_string,
NULL);
/*
@@ -325,6 +332,7 @@ do_e_table_demo (const char *spec)
set_value_at, is_cell_editable,
duplicate_value, free_value,
initialize_value, value_is_empty,
+ value_to_string,
NULL);
full_header = e_table_header_new ();