aboutsummaryrefslogtreecommitdiffstats
path: root/widgets
diff options
context:
space:
mode:
authorChristopher James Lahey <clahey@helixcode.com>2000-06-27 08:51:06 +0800
committerChris Lahey <clahey@src.gnome.org>2000-06-27 08:51:06 +0800
commite4de45da5f6021db9a009f112c91e21493a87e1f (patch)
tree8e481cf3ba0b08eede834c97820476a3dd5e87c9 /widgets
parent9d5faecef3b9e0f8fff68a2d4ddd9dab91b2f66d (diff)
downloadgsoc2013-evolution-e4de45da5f6021db9a009f112c91e21493a87e1f.tar.gz
gsoc2013-evolution-e4de45da5f6021db9a009f112c91e21493a87e1f.tar.zst
gsoc2013-evolution-e4de45da5f6021db9a009f112c91e21493a87e1f.zip
Calculate height including if clip_height is set to -1.
2000-06-26 Christopher James Lahey <clahey@helixcode.com> * widgets/e-text/e-text.c: Calculate height including if clip_height is set to -1. From addressbook/ChangeLog: 2000-06-26 Christopher James Lahey <clahey@helixcode.com> * contact-editor/e-contact-editor-categories.c, addressbook/gui/component/e-cardlist-model.c: Added value_to_string handlers. * demo/addressbook-widget.c, demo/demo.c: Removed usage of "x" and "y" arguments. * addressbook/gui/component/addressbook.c: Activated Click To Add and set the click to add message. * addressbook/gui/component/e-addressbook-model.c: Added value_to_string and append_row handlers. * addressbook/gui/component/e-select-names.c: Added a column. From calendar/ChangeLog: 2000-06-26 Christopher James Lahey <clahey@helixcode.com> * gui/calendar-model.c: Added an #ifdefed value_to_string handler assignment. From camel/ChangeLog: 2000-06-26 Christopher James Lahey <clahey@helixcode.com> * providers/mbox/camel-mbox-summary.c: Added debugging information. From composer/ChangeLog: 2000-06-26 Christopher James Lahey <clahey@helixcode.com> * Makefile.am: Added e-msg-composer-select-file.h for make distcheck. From e-util/ChangeLog: 2000-06-26 Christopher James Lahey <clahey@helixcode.com> * Makefile.am: Added e-canvas-vbox.c and e-canvas-vbox.h. * e-canvas-vbox.c, e-canvas-vbox.h: New canvas object to act like a vbox using the reflow system. From mail/ChangeLog: 2000-06-26 Christopher James Lahey <clahey@helixcode.com> * message-list.c: Added a value_to_string handler. From shell/ChangeLog: 2000-06-26 Christopher James Lahey <clahey@helixcode.com> * glade/Makefile.am: Added EXTRA_DIST for make distcheck. From widgets/e-table/ChangeLog: 2000-06-26 Christopher James Lahey <clahey@helixcode.com> * Makefile.am: Added e-table-click-to-add.c, e-table-click-to-add.h, e-table-one.c, and e-table-one.h. * e-table-click-to-add.c, e-table-click-to-add.h: A new canvas item that represents a single row that sometimes exists. It's for adding new rows to your table. * e-table-example-1.c, e-table-example-2.c, e-table-size-test.c, test-check.c, test-cols.c, test-table.c: Added value_to_string handlers. * e-table-group-container.c: Use value_to_string to make grouping not crash for non string columns. Made some changes to work properly in an ECanvasVbox. * e-table-group-leaf.c, e-table-item.c: Made some changes to work properly in an ECanvasVbox. * e-table-model.c, e-table-model.h: Added append_row and value_to_string methods. * e-table-one.c, e-table-one.h: Given a source ETableModel, this provides a single row model that uses the initialize_value, duplicate_value, free_value, and value_is_empty methods of the original source to implement set_value and value_at (and proxies most of the other methods.) This is used for ETableClickToAdd. * e-table-simple.c, e-table-simple.h: Added append_row and value_to_string handlers. append_row uses a GtkArg instead of a parameter to e_table_simple_new. * e-table-subset.c: Added append_row and value_to_string handlers. * e-table.c, e-table.h: Use a vbox containing an ETableClickToAdd and an ETableItem instead of an ETableItem directly. Only show the ETableClickToAdd if the top level of the xml SPEC has the attribute click-to-add set to some non-zero integer. (click-to-add="1"). Add a "click_to_add_message" argument. * e-tree-model.c: Add a commented out value_to_string handler. From widgets/meeting-time-sel/ChangeLog: 2000-06-26 Christopher James Lahey <clahey@helixcode.com> * Makefile.am: Added the include path to top_srcdir. svn path=/trunk/; revision=3744
Diffstat (limited to 'widgets')
-rw-r--r--widgets/e-table/ChangeLog42
-rw-r--r--widgets/e-table/Makefile.am4
-rw-r--r--widgets/e-table/e-table-click-to-add.c410
-rw-r--r--widgets/e-table/e-table-click-to-add.h48
-rw-r--r--widgets/e-table/e-table-example-1.c8
-rw-r--r--widgets/e-table/e-table-example-2.c13
-rw-r--r--widgets/e-table/e-table-group-container.c26
-rw-r--r--widgets/e-table/e-table-group-leaf.c3
-rw-r--r--widgets/e-table/e-table-item.c1
-rw-r--r--widgets/e-table/e-table-model.c27
-rw-r--r--widgets/e-table/e-table-model.h5
-rw-r--r--widgets/e-table/e-table-one.c244
-rw-r--r--widgets/e-table/e-table-one.h30
-rw-r--r--widgets/e-table/e-table-simple.c63
-rw-r--r--widgets/e-table/e-table-simple.h21
-rw-r--r--widgets/e-table/e-table-size-test.c8
-rw-r--r--widgets/e-table/e-table-subset.c27
-rw-r--r--widgets/e-table/e-table.c82
-rw-r--r--widgets/e-table/e-table.h6
-rw-r--r--widgets/e-table/e-tree-model.c1
-rw-r--r--widgets/e-table/test-check.c10
-rw-r--r--widgets/e-table/test-cols.c10
-rw-r--r--widgets/e-table/test-table.c8
-rw-r--r--widgets/e-text/e-text.c2
-rw-r--r--widgets/meeting-time-sel/ChangeLog4
-rw-r--r--widgets/meeting-time-sel/Makefile.am1
-rw-r--r--widgets/misc/e-canvas-vbox.c323
-rw-r--r--widgets/misc/e-canvas-vbox.h86
-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
-rw-r--r--widgets/text/e-text.c2
50 files changed, 2506 insertions, 60 deletions
diff --git a/widgets/e-table/ChangeLog b/widgets/e-table/ChangeLog
index 10da7e024e..56b3ef11f0 100644
--- a/widgets/e-table/ChangeLog
+++ b/widgets/e-table/ChangeLog
@@ -1,3 +1,45 @@
+2000-06-26 Christopher James Lahey <clahey@helixcode.com>
+
+ * Makefile.am: Added e-table-click-to-add.c,
+ e-table-click-to-add.h, e-table-one.c, and e-table-one.h.
+
+ * e-table-click-to-add.c, e-table-click-to-add.h: A new canvas
+ item that represents a single row that sometimes exists. It's for
+ adding new rows to your table.
+
+ * e-table-example-1.c, e-table-example-2.c, e-table-size-test.c,
+ test-check.c, test-cols.c, test-table.c: Added value_to_string handlers.
+
+ * e-table-group-container.c: Use value_to_string to make grouping
+ not crash for non string columns. Made some changes to work
+ properly in an ECanvasVbox.
+
+ * e-table-group-leaf.c, e-table-item.c: Made some changes to work
+ properly in an ECanvasVbox.
+
+ * e-table-model.c, e-table-model.h: Added append_row and
+ value_to_string methods.
+
+ * e-table-one.c, e-table-one.h: Given a source ETableModel, this
+ provides a single row model that uses the initialize_value,
+ duplicate_value, free_value, and value_is_empty methods of the
+ original source to implement set_value and value_at (and proxies
+ most of the other methods.) This is used for ETableClickToAdd.
+
+ * e-table-simple.c, e-table-simple.h: Added append_row and
+ value_to_string handlers. append_row uses a GtkArg instead of a
+ parameter to e_table_simple_new.
+
+ * e-table-subset.c: Added append_row and value_to_string handlers.
+
+ * e-table.c, e-table.h: Use a vbox containing an ETableClickToAdd
+ and an ETableItem instead of an ETableItem directly. Only show
+ the ETableClickToAdd if the top level of the xml SPEC has the
+ attribute click-to-add set to some non-zero integer.
+ (click-to-add="1"). Add a "click_to_add_message" argument.
+
+ * e-tree-model.c: Add a commented out value_to_string handler.
+
2000-06-23 Larry Ewing <lewing@helixcode.com>
* e-cell-toggle.c (etog_draw): draw pixmaps with he right
diff --git a/widgets/e-table/Makefile.am b/widgets/e-table/Makefile.am
index 65504749ba..c8db9d9e32 100644
--- a/widgets/e-table/Makefile.am
+++ b/widgets/e-table/Makefile.am
@@ -36,6 +36,8 @@ libetable_a_SOURCES = \
e-cell-tree.h \
e-table.c \
e-table.h \
+ e-table-click-to-add.c \
+ e-table-click-to-add.h \
e-table-col-dnd.h \
e-table-col.c \
e-table-col.h \
@@ -62,6 +64,8 @@ libetable_a_SOURCES = \
e-table-item.h \
e-table-model.c \
e-table-model.h \
+ e-table-one.c \
+ e-table-one.h \
e-table-simple.c \
e-table-simple.h \
e-table-sort-info.c \
diff --git a/widgets/e-table/e-table-click-to-add.c b/widgets/e-table/e-table-click-to-add.c
new file mode 100644
index 0000000000..30bf96b42a
--- /dev/null
+++ b/widgets/e-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/e-table/e-table-click-to-add.h b/widgets/e-table/e-table-click-to-add.h
new file mode 100644
index 0000000000..db41303919
--- /dev/null
+++ b/widgets/e-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/e-table/e-table-example-1.c b/widgets/e-table/e-table-example-1.c
index 949131b597..7c289778aa 100644
--- a/widgets/e-table/e-table-example-1.c
+++ b/widgets/e-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/e-table/e-table-example-2.c b/widgets/e-table/e-table-example-2.c
index 3accba6cb8..e9d8d9ea80 100644
--- a/widgets/e-table/e-table-example-2.c
+++ b/widgets/e-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/e-table/e-table-group-container.c b/widgets/e-table/e-table-group-container.c
index b4e77cf95e..6bff77d4ad 100644
--- a/widgets/e-table/e-table-group-container.c
+++ b/widgets/e-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/e-table/e-table-group-leaf.c b/widgets/e-table/e-table-group-leaf.c
index e16a3d5d6d..0c76129101 100644
--- a/widgets/e-table/e-table-group-leaf.c
+++ b/widgets/e-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/e-table/e-table-item.c b/widgets/e-table/e-table-item.c
index b12021ae46..9df3b913db 100644
--- a/widgets/e-table/e-table-item.c
+++ b/widgets/e-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/e-table/e-table-model.c b/widgets/e-table/e-table-model.c
index 62a45d966e..5045f68b02 100644
--- a/widgets/e-table/e-table-model.c
+++ b/widgets/e-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/e-table/e-table-model.h b/widgets/e-table/e-table-model.h
index e73df7fa45..dc18d972b5 100644
--- a/widgets/e-table/e-table-model.h
+++ b/widgets/e-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/e-table/e-table-one.c b/widgets/e-table/e-table-one.c
new file mode 100644
index 0000000000..73022a5801
--- /dev/null
+++ b/widgets/e-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/e-table/e-table-one.h b/widgets/e-table/e-table-one.h
new file mode 100644
index 0000000000..933d2c7a2d
--- /dev/null
+++ b/widgets/e-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/e-table/e-table-simple.c b/widgets/e-table/e-table-simple.c
index e823e8d550..fa0a25f784 100644
--- a/widgets/e-table/e-table-simple.c
+++ b/widgets/e-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/e-table/e-table-simple.h b/widgets/e-table/e-table-simple.h
index 31ebd439f0..7fbed8d28b 100644
--- a/widgets/e-table/e-table-simple.h
+++ b/widgets/e-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/e-table/e-table-size-test.c b/widgets/e-table/e-table-size-test.c
index 12040b29d4..b3a2cbbe18 100644
--- a/widgets/e-table/e-table-size-test.c
+++ b/widgets/e-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/e-table/e-table-subset.c b/widgets/e-table/e-table-subset.c
index d2b1e37a9d..eb08ca0890 100644
--- a/widgets/e-table/e-table-subset.c
+++ b/widgets/e-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/e-table/e-table.c b/widgets/e-table/e-table.c
index c4239068fa..83d9422be6 100644
--- a/widgets/e-table/e-table.c
+++ b/widgets/e-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/e-table/e-table.h b/widgets/e-table/e-table.h
index a733d5951e..c945e48772 100644
--- a/widgets/e-table/e-table.h
+++ b/widgets/e-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/e-table/e-tree-model.c b/widgets/e-table/e-tree-model.c
index 992caf40f2..250ff4edb7 100644
--- a/widgets/e-table/e-tree-model.c
+++ b/widgets/e-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/e-table/test-check.c b/widgets/e-table/test-check.c
index c330956918..3bb022821e 100644
--- a/widgets/e-table/test-check.c
+++ b/widgets/e-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/e-table/test-cols.c b/widgets/e-table/test-cols.c
index d4372b189f..c47a1d47d7 100644
--- a/widgets/e-table/test-cols.c
+++ b/widgets/e-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/e-table/test-table.c b/widgets/e-table/test-table.c
index a12094ef19..b30b412f08 100644
--- a/widgets/e-table/test-table.c
+++ b/widgets/e-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 ();
diff --git a/widgets/e-text/e-text.c b/widgets/e-text/e-text.c
index 6b371e0ba3..5375f7c8bd 100644
--- a/widgets/e-text/e-text.c
+++ b/widgets/e-text/e-text.c
@@ -1333,7 +1333,7 @@ e_text_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
break;
case ARG_HEIGHT:
- GTK_VALUE_DOUBLE (*arg) = text->max_width / text->item.canvas->pixels_per_unit;
+ GTK_VALUE_DOUBLE (*arg) = text->clip && text->clip_height != -1 ? text->clip_height : text->height / text->item.canvas->pixels_per_unit;
break;
default:
diff --git a/widgets/meeting-time-sel/ChangeLog b/widgets/meeting-time-sel/ChangeLog
index b6f78f0725..847431e29d 100644
--- a/widgets/meeting-time-sel/ChangeLog
+++ b/widgets/meeting-time-sel/ChangeLog
@@ -1,3 +1,7 @@
+2000-06-26 Christopher James Lahey <clahey@helixcode.com>
+
+ * Makefile.am: Added the include path to top_srcdir.
+
2000-06-25 Ettore Perazzoli <ettore@helixcode.com>
* e-meeting-time-sel.c: Specify the #include path for
diff --git a/widgets/meeting-time-sel/Makefile.am b/widgets/meeting-time-sel/Makefile.am
index 013006aaed..4d443ae5b4 100644
--- a/widgets/meeting-time-sel/Makefile.am
+++ b/widgets/meeting-time-sel/Makefile.am
@@ -1,6 +1,7 @@
INCLUDES = \
$(GNOME_INCLUDEDIR) \
+ -I $(top_srcdir) \
-DG_LOG_DOMAIN=\"meeting-time-sel\"
noinst_LIBRARIES = \
diff --git a/widgets/misc/e-canvas-vbox.c b/widgets/misc/e-canvas-vbox.c
new file mode 100644
index 0000000000..f42fca4a30
--- /dev/null
+++ b/widgets/misc/e-canvas-vbox.c
@@ -0,0 +1,323 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * e-canvas-vbox.c
+ * Copyright (C) 2000 Helix Code, Inc.
+ * Author: Chris Lahey <clahey@helixcode.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <gnome.h>
+#include <math.h>
+#include "e-canvas-vbox.h"
+#include <e-util/e-canvas-utils.h>
+#include <e-util/e-canvas.h>
+#include <e-util/e-util.h>
+
+static void e_canvas_vbox_init (ECanvasVbox *CanvasVbox);
+static void e_canvas_vbox_class_init (ECanvasVboxClass *klass);
+static void e_canvas_vbox_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
+static void e_canvas_vbox_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+static void e_canvas_vbox_destroy (GtkObject *object);
+
+static gint e_canvas_vbox_event (GnomeCanvasItem *item, GdkEvent *event);
+static void e_canvas_vbox_realize (GnomeCanvasItem *item);
+
+static void e_canvas_vbox_reflow (GnomeCanvasItem *item, int flags);
+
+static void e_canvas_vbox_real_add_item(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item);
+static void e_canvas_vbox_resize_children (GnomeCanvasItem *item);
+
+static GnomeCanvasGroupClass *parent_class = NULL;
+
+/* The arguments we take */
+enum {
+ ARG_0,
+ ARG_WIDTH,
+ ARG_HEIGHT,
+ ARG_SPACING,
+};
+
+GtkType
+e_canvas_vbox_get_type (void)
+{
+ static GtkType type = 0;
+
+ if (!type)
+ {
+ static const GtkTypeInfo info =
+ {
+ "ECanvasVbox",
+ sizeof (ECanvasVbox),
+ sizeof (ECanvasVboxClass),
+ (GtkClassInitFunc) e_canvas_vbox_class_init,
+ (GtkObjectInitFunc) e_canvas_vbox_init,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
+ };
+
+ type = gtk_type_unique (gnome_canvas_group_get_type (), &info);
+ }
+
+ return type;
+}
+
+static void
+e_canvas_vbox_class_init (ECanvasVboxClass *klass)
+{
+ GtkObjectClass *object_class;
+ GnomeCanvasItemClass *item_class;
+
+ object_class = (GtkObjectClass*) klass;
+ item_class = (GnomeCanvasItemClass *) klass;
+
+ parent_class = gtk_type_class (gnome_canvas_group_get_type ());
+
+ gtk_object_add_arg_type ("ECanvasVbox::width", GTK_TYPE_DOUBLE,
+ GTK_ARG_READWRITE, ARG_WIDTH);
+ gtk_object_add_arg_type ("ECanvasVbox::height", GTK_TYPE_DOUBLE,
+ GTK_ARG_READABLE, ARG_HEIGHT);
+ gtk_object_add_arg_type ("ECanvasVbox::spacing", GTK_TYPE_DOUBLE,
+ GTK_ARG_READWRITE, ARG_SPACING);
+
+ klass->add_item = e_canvas_vbox_real_add_item;
+
+ object_class->set_arg = e_canvas_vbox_set_arg;
+ object_class->get_arg = e_canvas_vbox_get_arg;
+ object_class->destroy = e_canvas_vbox_destroy;
+
+ /* GnomeCanvasItem method overrides */
+ item_class->event = e_canvas_vbox_event;
+ item_class->realize = e_canvas_vbox_realize;
+}
+
+static void
+e_canvas_vbox_init (ECanvasVbox *vbox)
+{
+ vbox->items = NULL;
+
+ vbox->width = 10;
+ vbox->height = 10;
+ vbox->spacing = 0;
+
+ e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(vbox), e_canvas_vbox_reflow);
+}
+
+static void
+e_canvas_vbox_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ GnomeCanvasItem *item;
+ ECanvasVbox *e_canvas_vbox;
+
+ item = GNOME_CANVAS_ITEM (o);
+ e_canvas_vbox = E_CANVAS_VBOX (o);
+
+ switch (arg_id){
+ case ARG_WIDTH:
+ e_canvas_vbox->width = GTK_VALUE_DOUBLE (*arg);
+ e_canvas_vbox_resize_children(item);
+ e_canvas_item_request_reflow(item);
+ break;
+ case ARG_SPACING:
+ e_canvas_vbox->spacing = GTK_VALUE_DOUBLE (*arg);
+ e_canvas_item_request_reflow(item);
+ break;
+ }
+}
+
+static void
+e_canvas_vbox_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ ECanvasVbox *e_canvas_vbox;
+
+ e_canvas_vbox = E_CANVAS_VBOX (object);
+
+ switch (arg_id) {
+ case ARG_WIDTH:
+ GTK_VALUE_DOUBLE (*arg) = e_canvas_vbox->width;
+ break;
+ case ARG_HEIGHT:
+ GTK_VALUE_DOUBLE (*arg) = e_canvas_vbox->height;
+ break;
+ case ARG_SPACING:
+ GTK_VALUE_DOUBLE (*arg) = e_canvas_vbox->spacing;
+ break;
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ }
+}
+
+static void
+e_canvas_vbox_destroy (GtkObject *object)
+{
+ ECanvasVbox *vbox = E_CANVAS_VBOX(object);
+
+ g_list_foreach(vbox->items, (GFunc) gtk_object_unref, NULL);
+ g_list_free(vbox->items);
+ vbox->items = NULL;
+
+ GTK_OBJECT_CLASS(parent_class)->destroy (object);
+}
+
+static gint
+e_canvas_vbox_event (GnomeCanvasItem *item, GdkEvent *event)
+{
+ gint return_val = TRUE;
+
+ switch (event->type) {
+ case GDK_KEY_PRESS:
+ switch (event->key.keyval) {
+ case GDK_Tab:
+ case GDK_KP_Tab:
+ case GDK_ISO_Left_Tab:
+ case GDK_Left:
+ case GDK_KP_Left:
+ case GDK_Right:
+ case GDK_KP_Right:
+ case GDK_Down:
+ case GDK_KP_Down:
+ case GDK_Up:
+ case GDK_KP_Up:
+ case GDK_Return:
+ case GDK_KP_Enter:
+ return_val = TRUE;
+ break;
+ default:
+ return_val = FALSE;
+ break;
+ }
+ break;
+ default:
+ return_val = FALSE;
+ break;
+ }
+ if (!return_val) {
+ if (GNOME_CANVAS_ITEM_CLASS(parent_class)->event)
+ return GNOME_CANVAS_ITEM_CLASS (parent_class)->event (item, event);
+ }
+ return return_val;
+
+}
+
+static void
+e_canvas_vbox_realize (GnomeCanvasItem *item)
+{
+ if (GNOME_CANVAS_ITEM_CLASS(parent_class)->realize)
+ (* GNOME_CANVAS_ITEM_CLASS(parent_class)->realize) (item);
+
+ e_canvas_vbox_resize_children(item);
+ e_canvas_item_request_reflow(item);
+}
+
+static void
+e_canvas_vbox_remove_item (GnomeCanvasItem *item, ECanvasVbox *vbox)
+{
+ vbox->items = g_list_remove(vbox->items, item);
+ gtk_object_unref(GTK_OBJECT(vbox));
+}
+
+static void
+e_canvas_vbox_real_add_item(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item)
+{
+ e_canvas_vbox->items = g_list_append(e_canvas_vbox->items, item);
+ gtk_object_ref(GTK_OBJECT(item));
+ gtk_object_ref(GTK_OBJECT(e_canvas_vbox));
+ gtk_signal_connect(GTK_OBJECT(item), "destroy",
+ GTK_SIGNAL_FUNC(e_canvas_vbox_remove_item), e_canvas_vbox);
+ if ( GTK_OBJECT_FLAGS( e_canvas_vbox ) & GNOME_CANVAS_ITEM_REALIZED ) {
+ gnome_canvas_item_set(item,
+ "width", (double) e_canvas_vbox->width,
+ NULL);
+ e_canvas_item_request_reflow(item);
+ }
+
+}
+
+static void
+e_canvas_vbox_resize_children (GnomeCanvasItem *item)
+{
+ GList *list;
+ ECanvasVbox *e_canvas_vbox;
+
+ e_canvas_vbox = E_CANVAS_VBOX (item);
+ for ( list = e_canvas_vbox->items; list; list = list->next ) {
+ GnomeCanvasItem *child = GNOME_CANVAS_ITEM(list->data);
+ gnome_canvas_item_set(child,
+ "width", (double) e_canvas_vbox->width,
+ NULL);
+ }
+}
+
+static void
+e_canvas_vbox_reflow( GnomeCanvasItem *item, int flags )
+{
+ ECanvasVbox *e_canvas_vbox = E_CANVAS_VBOX(item);
+ if ( GTK_OBJECT_FLAGS( e_canvas_vbox ) & GNOME_CANVAS_ITEM_REALIZED ) {
+
+ gdouble old_height;
+ gdouble running_height;
+
+ old_height = e_canvas_vbox->height;
+
+ running_height = 0;
+
+ if (e_canvas_vbox->items == NULL) {
+ } else {
+ GList *list;
+ gdouble item_height;
+
+ list = e_canvas_vbox->items;
+ gtk_object_get (GTK_OBJECT(list->data),
+ "height", &item_height,
+ NULL);
+ e_canvas_item_move_absolute(GNOME_CANVAS_ITEM(list->data),
+ (double) 0,
+ (double) running_height);
+ running_height += item_height;
+ list = g_list_next(list);
+
+ for( ; list; list = g_list_next(list)) {
+ running_height += e_canvas_vbox->spacing;
+
+ gtk_object_get (GTK_OBJECT(list->data),
+ "height", &item_height,
+ NULL);
+
+ g_print ("%f\n", running_height);
+
+ e_canvas_item_move_absolute(GNOME_CANVAS_ITEM(list->data),
+ (double) 0,
+ (double) running_height);
+
+ running_height += item_height;
+ }
+
+ }
+ e_canvas_vbox->height = running_height;
+ if (old_height != e_canvas_vbox->height)
+ e_canvas_item_request_parent_reflow(item);
+ }
+}
+
+void
+e_canvas_vbox_add_item(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item)
+{
+ if (E_CANVAS_VBOX_CLASS(GTK_OBJECT(e_canvas_vbox)->klass)->add_item)
+ (E_CANVAS_VBOX_CLASS(GTK_OBJECT(e_canvas_vbox)->klass)->add_item) (e_canvas_vbox, item);
+}
diff --git a/widgets/misc/e-canvas-vbox.h b/widgets/misc/e-canvas-vbox.h
new file mode 100644
index 0000000000..c45baa0b0a
--- /dev/null
+++ b/widgets/misc/e-canvas-vbox.h
@@ -0,0 +1,86 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* e-canvas-vbox.h
+ * Copyright (C) 2000 Helix Code, Inc.
+ * Author: Chris Lahey <clahey@helixcode.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __E_CANVAS_VBOX_H__
+#define __E_CANVAS_VBOX_H__
+
+#include <gnome.h>
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus */
+
+/* ECanvasVbox - A canvas item container.
+ *
+ * The following arguments are available:
+ *
+ * name type read/write description
+ * --------------------------------------------------------------------------------
+ * width double RW width of the CanvasVbox
+ * height double R height of the CanvasVbox
+ * spacing double RW Spacing between items.
+ */
+
+#define E_CANVAS_VBOX_TYPE (e_canvas_vbox_get_type ())
+#define E_CANVAS_VBOX(obj) (GTK_CHECK_CAST ((obj), E_CANVAS_VBOX_TYPE, ECanvasVbox))
+#define E_CANVAS_VBOX_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_CANVAS_VBOX_TYPE, ECanvasVboxClass))
+#define E_IS_CANVAS_VBOX(obj) (GTK_CHECK_TYPE ((obj), E_CANVAS_VBOX_TYPE))
+#define E_IS_CANVAS_VBOX_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_CANVAS_VBOX_TYPE))
+
+
+typedef struct _ECanvasVbox ECanvasVbox;
+typedef struct _ECanvasVboxClass ECanvasVboxClass;
+
+struct _ECanvasVbox
+{
+ GnomeCanvasGroup parent;
+
+ /* item specific fields */
+ GList *items; /* Of type GnomeCanvasItem */
+
+ double width;
+ double height;
+ double spacing;
+};
+
+struct _ECanvasVboxClass
+{
+ GnomeCanvasGroupClass parent_class;
+
+ /* Virtual methods. */
+ void (* add_item) (ECanvasVbox *CanvasVbox, GnomeCanvasItem *item);
+};
+
+/*
+ * To be added to a CanvasVbox, an item must have the argument "width" as
+ * a Read/Write argument and "height" as a Read Only argument. It
+ * should also do an ECanvas parent CanvasVbox request if its size
+ * changes.
+ */
+void e_canvas_vbox_add_item(ECanvasVbox *e_canvas_vbox, GnomeCanvasItem *item);
+GtkType e_canvas_vbox_get_type (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __E_CANVAS_VBOX_H__ */
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 ();
diff --git a/widgets/text/e-text.c b/widgets/text/e-text.c
index 6b371e0ba3..5375f7c8bd 100644
--- a/widgets/text/e-text.c
+++ b/widgets/text/e-text.c
@@ -1333,7 +1333,7 @@ e_text_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
break;
case ARG_HEIGHT:
- GTK_VALUE_DOUBLE (*arg) = text->max_width / text->item.canvas->pixels_per_unit;
+ GTK_VALUE_DOUBLE (*arg) = text->clip && text->clip_height != -1 ? text->clip_height : text->height / text->item.canvas->pixels_per_unit;
break;
default: