aboutsummaryrefslogtreecommitdiffstats
path: root/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'widgets')
-rw-r--r--widgets/e-minicard/e-minicard-label.c32
-rw-r--r--widgets/e-minicard/e-minicard.c27
-rw-r--r--widgets/e-minicard/e-reflow.c6
-rw-r--r--widgets/e-minicard/test-minicard-label.c2
-rw-r--r--widgets/e-minicard/test-minicard.c2
-rw-r--r--widgets/e-minicard/test-reflow.c2
-rw-r--r--widgets/e-reflow/e-reflow.c6
-rw-r--r--widgets/e-table/ChangeLog70
-rw-r--r--widgets/e-table/Makefile.am8
-rw-r--r--widgets/e-table/check-empty.xpm2
-rw-r--r--widgets/e-table/check-filled.xpm2
-rw-r--r--widgets/e-table/e-cell-text.c61
-rw-r--r--widgets/e-table/e-cell.c2
-rw-r--r--widgets/e-table/e-cell.h4
-rw-r--r--widgets/e-table/e-table-group-container.c804
-rw-r--r--widgets/e-table/e-table-group-container.h66
-rw-r--r--widgets/e-table/e-table-group-leaf.c288
-rw-r--r--widgets/e-table/e-table-group-leaf.h39
-rw-r--r--widgets/e-table/e-table-group.c419
-rw-r--r--widgets/e-table/e-table-group.h87
-rw-r--r--widgets/e-table/e-table-header-item.c7
-rw-r--r--widgets/e-table/e-table-item.c163
-rw-r--r--widgets/e-table/e-table-item.h4
-rw-r--r--widgets/e-table/e-table-model.c20
-rw-r--r--widgets/e-table/e-table-model.h8
-rw-r--r--widgets/e-table/e-table-simple.c12
-rw-r--r--widgets/e-table/e-table-simple.h4
-rw-r--r--widgets/e-table/e-table-sorted.h2
-rw-r--r--widgets/e-table/e-table-subset-variable.c112
-rw-r--r--widgets/e-table/e-table-subset-variable.h38
-rw-r--r--widgets/e-table/e-table-subset.c49
-rw-r--r--widgets/e-table/e-table-subset.h1
-rw-r--r--widgets/e-table/e-table.c115
-rw-r--r--widgets/e-table/e-table.h13
-rw-r--r--widgets/e-table/test-check.c20
-rw-r--r--widgets/e-table/test-cols.c22
-rw-r--r--widgets/e-table/test-table.c28
-rw-r--r--widgets/e-text-event-processor-emacs-like.c357
-rw-r--r--widgets/e-text-event-processor-emacs-like.h68
-rw-r--r--widgets/e-text-event-processor-types.h136
-rw-r--r--widgets/e-text-event-processor.c103
-rw-r--r--widgets/e-text-event-processor.h74
-rw-r--r--widgets/e-text.c2526
-rw-r--r--widgets/e-text.h196
-rw-r--r--widgets/e-text/e-text.c63
-rw-r--r--widgets/e-text/e-text.h1
-rw-r--r--widgets/misc/e-canvas-utils.h7
-rw-r--r--widgets/misc/e-reflow.c6
-rw-r--r--widgets/table/check-empty.xpm2
-rw-r--r--widgets/table/check-filled.xpm2
-rw-r--r--widgets/table/e-cell-text.c61
-rw-r--r--widgets/table/e-cell.c2
-rw-r--r--widgets/table/e-cell.h4
-rw-r--r--widgets/table/e-table-group-container.c804
-rw-r--r--widgets/table/e-table-group-container.h66
-rw-r--r--widgets/table/e-table-group-leaf.c288
-rw-r--r--widgets/table/e-table-group-leaf.h39
-rw-r--r--widgets/table/e-table-group.c419
-rw-r--r--widgets/table/e-table-group.h87
-rw-r--r--widgets/table/e-table-header-item.c7
-rw-r--r--widgets/table/e-table-item.c163
-rw-r--r--widgets/table/e-table-item.h4
-rw-r--r--widgets/table/e-table-model.c20
-rw-r--r--widgets/table/e-table-model.h8
-rw-r--r--widgets/table/e-table-simple.c12
-rw-r--r--widgets/table/e-table-simple.h4
-rw-r--r--widgets/table/e-table-sorted.h2
-rw-r--r--widgets/table/e-table-subset-variable.c112
-rw-r--r--widgets/table/e-table-subset-variable.h38
-rw-r--r--widgets/table/e-table-subset.c49
-rw-r--r--widgets/table/e-table-subset.h1
-rw-r--r--widgets/table/e-table.c115
-rw-r--r--widgets/table/e-table.h13
-rw-r--r--widgets/table/test-check.c20
-rw-r--r--widgets/table/test-cols.c22
-rw-r--r--widgets/table/test-table.c28
-rw-r--r--widgets/text/e-text.c63
-rw-r--r--widgets/text/e-text.h1
78 files changed, 4169 insertions, 4371 deletions
diff --git a/widgets/e-minicard/e-minicard-label.c b/widgets/e-minicard/e-minicard-label.c
index 43603f2d6d..5b528d6190 100644
--- a/widgets/e-minicard/e-minicard-label.c
+++ b/widgets/e-minicard/e-minicard-label.c
@@ -24,6 +24,7 @@
#include "e-minicard-label.h"
#include "e-text.h"
#include "e-canvas.h"
+#include "e-util.h"
static void e_minicard_label_init (EMinicardLabel *card);
static void e_minicard_label_class_init (EMinicardLabelClass *klass);
static void e_minicard_label_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
@@ -32,8 +33,8 @@ static gboolean e_minicard_label_event (GnomeCanvasItem *item, GdkEvent *event);
static void e_minicard_label_realize (GnomeCanvasItem *item);
static void e_minicard_label_unrealize (GnomeCanvasItem *item);
-static void _update_label( EMinicardLabel *minicard_label );
-static void _resize( GtkObject *object, gpointer data );
+static void update_label( EMinicardLabel *minicard_label );
+static void resize( GtkObject *object, gpointer data );
static GnomeCanvasGroupClass *parent_class = NULL;
@@ -148,11 +149,11 @@ e_minicard_label_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
switch (arg_id){
case ARG_WIDTH:
e_minicard_label->width = GTK_VALUE_DOUBLE (*arg);
- _update_label( e_minicard_label );
+ update_label( e_minicard_label );
gnome_canvas_item_request_update (item);
break;
case ARG_HAS_FOCUS:
- if (e_minicard_label->field && GTK_VALUE_BOOL(*arg))
+ if (e_minicard_label->field && (GTK_VALUE_ENUM(*arg) != E_FOCUS_NONE))
e_canvas_item_grab_focus(e_minicard_label->field);
break;
case ARG_FIELD:
@@ -186,7 +187,7 @@ e_minicard_label_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
GTK_VALUE_DOUBLE (*arg) = e_minicard_label->height;
break;
case ARG_HAS_FOCUS:
- GTK_VALUE_BOOL (*arg) = e_minicard_label->has_focus;
+ GTK_VALUE_ENUM (*arg) = e_minicard_label->has_focus ? E_FOCUS_CURRENT : E_FOCUS_NONE;
break;
case ARG_FIELD:
if ( e_minicard_label->field ) {
@@ -213,6 +214,11 @@ e_minicard_label_realize (GnomeCanvasItem *item)
{
EMinicardLabel *e_minicard_label;
GnomeCanvasGroup *group;
+ static GdkFont *font = NULL;
+
+ if ( font == NULL ) {
+ font = gdk_font_load("lucidasans-10");
+ }
e_minicard_label = E_MINICARD_LABEL (item);
group = GNOME_CANVAS_GROUP( item );
@@ -239,7 +245,7 @@ e_minicard_label_realize (GnomeCanvasItem *item)
"clip_height", (double) 1,
"clip", TRUE,
"use_ellipsis", TRUE,
- "font", "lucidasans-10",
+ "font_gdk", font,
"fill_color", "black",
NULL );
if ( e_minicard_label->fieldname_text )
@@ -251,7 +257,7 @@ e_minicard_label_realize (GnomeCanvasItem *item)
}
gtk_signal_connect(GTK_OBJECT(e_minicard_label->fieldname),
"resize",
- GTK_SIGNAL_FUNC(_resize),
+ GTK_SIGNAL_FUNC(resize),
(gpointer) e_minicard_label);
e_minicard_label->field =
@@ -264,7 +270,7 @@ e_minicard_label_realize (GnomeCanvasItem *item)
"clip_height", (double) 1,
"clip", TRUE,
"use_ellipsis", TRUE,
- "font", "lucidasans-10",
+ "font_gdk", font,
"fill_color", "black",
"editable", TRUE,
NULL );
@@ -278,10 +284,10 @@ e_minicard_label_realize (GnomeCanvasItem *item)
gtk_signal_connect(GTK_OBJECT(e_minicard_label->field),
"resize",
- GTK_SIGNAL_FUNC(_resize),
+ GTK_SIGNAL_FUNC(resize),
(gpointer) e_minicard_label);
- _update_label (e_minicard_label);
+ update_label (e_minicard_label);
if (!item->canvas->aa)
{
@@ -400,7 +406,7 @@ e_minicard_label_event (GnomeCanvasItem *item, GdkEvent *event)
}
static void
-_update_label( EMinicardLabel *e_minicard_label )
+update_label( EMinicardLabel *e_minicard_label )
{
if ( GTK_OBJECT_FLAGS( e_minicard_label ) & GNOME_CANVAS_ITEM_REALIZED )
{
@@ -450,7 +456,7 @@ _update_label( EMinicardLabel *e_minicard_label )
static void
-_resize( GtkObject *object, gpointer data )
+resize( GtkObject *object, gpointer data )
{
- _update_label(E_MINICARD_LABEL(data));
+ update_label(E_MINICARD_LABEL(data));
}
diff --git a/widgets/e-minicard/e-minicard.c b/widgets/e-minicard/e-minicard.c
index b667f1ac21..805c4e78ff 100644
--- a/widgets/e-minicard/e-minicard.c
+++ b/widgets/e-minicard/e-minicard.c
@@ -25,6 +25,7 @@
#include "e-minicard-label.h"
#include "e-text.h"
#include "e-canvas.h"
+#include "e-util.h"
static void e_minicard_init (EMinicard *card);
static void e_minicard_class_init (EMinicardClass *klass);
static void e_minicard_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
@@ -105,7 +106,7 @@ e_minicard_class_init (EMinicardClass *klass)
GTK_ARG_READWRITE, ARG_WIDTH);
gtk_object_add_arg_type ("EMinicard::height", GTK_TYPE_DOUBLE,
GTK_ARG_READABLE, ARG_HEIGHT);
- gtk_object_add_arg_type ("EMinicard::has_focus", GTK_TYPE_BOOL,
+ gtk_object_add_arg_type ("EMinicard::has_focus", GTK_TYPE_ENUM,
GTK_ARG_READWRITE, ARG_HAS_FOCUS);
gtk_object_add_arg_type ("EMinicard::card", GTK_TYPE_OBJECT,
GTK_ARG_READWRITE, ARG_CARD);
@@ -149,10 +150,18 @@ e_minicard_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
}
break;
case ARG_HAS_FOCUS:
- if (e_minicard->fields)
- gnome_canvas_item_set(GNOME_CANVAS_ITEM(e_minicard->fields->data),
- "has_focus", GTK_VALUE_BOOL(*arg),
- NULL);
+ if (e_minicard->fields) {
+ if ( GTK_VALUE_ENUM(*arg) == E_FOCUS_START ||
+ GTK_VALUE_ENUM(*arg) == E_FOCUS_CURRENT) {
+ gnome_canvas_item_set(GNOME_CANVAS_ITEM(e_minicard->fields->data),
+ "has_focus", GTK_VALUE_ENUM(*arg),
+ NULL);
+ } else if ( GTK_VALUE_ENUM(*arg) == E_FOCUS_END ) {
+ gnome_canvas_item_set(GNOME_CANVAS_ITEM(g_list_last(e_minicard->fields)->data),
+ "has_focus", GTK_VALUE_ENUM(*arg),
+ NULL);
+ }
+ }
else
e_canvas_item_grab_focus(GNOME_CANVAS_ITEM(e_minicard));
break;
@@ -179,7 +188,7 @@ e_minicard_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
GTK_VALUE_DOUBLE (*arg) = e_minicard->height;
break;
case ARG_HAS_FOCUS:
- GTK_VALUE_BOOL (*arg) = e_minicard->has_focus;
+ GTK_VALUE_ENUM (*arg) = e_minicard->has_focus ? E_FOCUS_CURRENT : E_FOCUS_NONE;
break;
case ARG_CARD:
/* GTK_VALUE_POINTER (*arg) = e_minicard->card; */
@@ -364,11 +373,11 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
GList *list;
for (list = e_minicard->fields; list; list = list->next) {
GnomeCanvasItem *item = GNOME_CANVAS_ITEM (list->data);
- gboolean has_focus;
+ EFocus has_focus;
gtk_object_get(GTK_OBJECT(item),
"has_focus", &has_focus,
NULL);
- if (has_focus) {
+ if (has_focus != E_FOCUS_NONE) {
if (event->key.state & GDK_SHIFT_MASK)
list = list->prev;
else
@@ -376,7 +385,7 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
if (list) {
item = GNOME_CANVAS_ITEM (list->data);
gnome_canvas_item_set(item,
- "has_focus", TRUE,
+ "has_focus", (event->key.state & GDK_SHIFT_MASK) ? E_FOCUS_END : E_FOCUS_START,
NULL);
return 1;
} else {
diff --git a/widgets/e-minicard/e-reflow.c b/widgets/e-minicard/e-reflow.c
index c1022f8f78..984e972f0c 100644
--- a/widgets/e-minicard/e-reflow.c
+++ b/widgets/e-minicard/e-reflow.c
@@ -24,6 +24,7 @@
#include <math.h>
#include "e-reflow.h"
#include "e-canvas-utils.h"
+#include "e-util.h"
static void e_reflow_init (EReflow *card);
static void e_reflow_class_init (EReflowClass *klass);
static void e_reflow_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
@@ -278,7 +279,7 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event)
GList *list;
for (list = e_reflow->items; list; list = list->next) {
GnomeCanvasItem *item = GNOME_CANVAS_ITEM (list->data);
- gboolean has_focus;
+ EFocus has_focus;
gtk_object_get(GTK_OBJECT(item),
"has_focus", &has_focus,
NULL);
@@ -290,7 +291,7 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event)
if (list) {
item = GNOME_CANVAS_ITEM(list->data);
gnome_canvas_item_set(item,
- "has_focus", TRUE,
+ "has_focus", (event->key.state & GDK_SHIFT_MASK) ? E_FOCUS_END : E_FOCUS_START,
NULL);
return 1;
} else {
@@ -625,7 +626,6 @@ e_reflow_point (GnomeCanvasItem *item,
double x, double y, int cx, int cy,
GnomeCanvasItem **actual_item)
{
- EReflow *e_reflow = E_REFLOW(item);
double distance = 1;
if (GNOME_CANVAS_ITEM_CLASS(parent_class)->point)
diff --git a/widgets/e-minicard/test-minicard-label.c b/widgets/e-minicard/test-minicard-label.c
index 67c17a0ace..8da34e6f22 100644
--- a/widgets/e-minicard/test-minicard-label.c
+++ b/widgets/e-minicard/test-minicard-label.c
@@ -44,6 +44,7 @@ static void allocate_callback(GtkWidget *canvas, GtkAllocation *allocation, gpoi
NULL );
}
+#if 0
static void about_callback( GtkWidget *widget, gpointer data )
{
@@ -61,6 +62,7 @@ static void about_callback( GtkWidget *widget, gpointer data )
NULL);
gtk_widget_show (about);
}
+#endif
static void button_press_callback( GtkWidget *widget, gpointer data )
{
diff --git a/widgets/e-minicard/test-minicard.c b/widgets/e-minicard/test-minicard.c
index 79077c4b2d..1ad066b3fe 100644
--- a/widgets/e-minicard/test-minicard.c
+++ b/widgets/e-minicard/test-minicard.c
@@ -43,6 +43,7 @@ static void allocate_callback(GtkWidget *canvas, GtkAllocation *allocation, gpoi
NULL );
}
+#if 0
static void about_callback( GtkWidget *widget, gpointer data )
{
@@ -60,6 +61,7 @@ static void about_callback( GtkWidget *widget, gpointer data )
NULL);
gtk_widget_show (about);
}
+#endif
int main( int argc, char *argv[] )
{
diff --git a/widgets/e-minicard/test-reflow.c b/widgets/e-minicard/test-reflow.c
index 4533e0249d..319a3f5626 100644
--- a/widgets/e-minicard/test-reflow.c
+++ b/widgets/e-minicard/test-reflow.c
@@ -69,6 +69,7 @@ static void resize(GnomeCanvasItem *item, gpointer data)
NULL );
}
+#if 0
static void about_callback( GtkWidget *widget, gpointer data )
{
@@ -86,6 +87,7 @@ static void about_callback( GtkWidget *widget, gpointer data )
NULL);
gtk_widget_show (about);
}
+#endif
int main( int argc, char *argv[] )
{
diff --git a/widgets/e-reflow/e-reflow.c b/widgets/e-reflow/e-reflow.c
index c1022f8f78..984e972f0c 100644
--- a/widgets/e-reflow/e-reflow.c
+++ b/widgets/e-reflow/e-reflow.c
@@ -24,6 +24,7 @@
#include <math.h>
#include "e-reflow.h"
#include "e-canvas-utils.h"
+#include "e-util.h"
static void e_reflow_init (EReflow *card);
static void e_reflow_class_init (EReflowClass *klass);
static void e_reflow_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
@@ -278,7 +279,7 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event)
GList *list;
for (list = e_reflow->items; list; list = list->next) {
GnomeCanvasItem *item = GNOME_CANVAS_ITEM (list->data);
- gboolean has_focus;
+ EFocus has_focus;
gtk_object_get(GTK_OBJECT(item),
"has_focus", &has_focus,
NULL);
@@ -290,7 +291,7 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event)
if (list) {
item = GNOME_CANVAS_ITEM(list->data);
gnome_canvas_item_set(item,
- "has_focus", TRUE,
+ "has_focus", (event->key.state & GDK_SHIFT_MASK) ? E_FOCUS_END : E_FOCUS_START,
NULL);
return 1;
} else {
@@ -625,7 +626,6 @@ e_reflow_point (GnomeCanvasItem *item,
double x, double y, int cx, int cy,
GnomeCanvasItem **actual_item)
{
- EReflow *e_reflow = E_REFLOW(item);
double distance = 1;
if (GNOME_CANVAS_ITEM_CLASS(parent_class)->point)
diff --git a/widgets/e-table/ChangeLog b/widgets/e-table/ChangeLog
index 88ad00e78a..5ed89f05ef 100644
--- a/widgets/e-table/ChangeLog
+++ b/widgets/e-table/ChangeLog
@@ -1,3 +1,73 @@
+2000-02-24 Christopher James Lahey <clahey@helixcode.com>
+
+ * e-table-subset-variable.c, e-table-subset-variable.h: A new
+ model which is a subset, but you can add and remove rows.
+
+ * test-table.c: Added a thaw method for use with the
+ e-table-subset (emits model_changed.) Adapted to the changes to
+ e_table_item. Properly parse headers. Adapted to the changes to
+ e_table, including creating example xml spec data.
+
+ * test-cols.c, test-check.c: Added a thaw method for use with the
+ e-table-subset (emits model_changed.) Adapted to the changes to
+ e_table_item.
+
+ * e-table.c, e-table.h: Reworked e-table to use the ETable
+ grouping system. The only difference for the interface is that
+ instead of passing in a column_spec and a grouping_spec, you pass
+ in a single string that is an xml format that includes both pieces
+ of information.
+
+ * e-table-subset.h: Added rules for emacs to do correct
+ indentation.
+
+ * e-table-subset.c: Implemented freezing. No signals are emitted
+ while frozen and "model_changed" is emitted when thawed.
+
+ * e-table-sorted.h: ETableSortedClass has ETableSubset as its
+ parent object instead of ETableSubsetClass. Fixed this.
+
+ * e-table-simple.c, e-table-simple.h: Implemented the thaw method.
+ Use of simple now requires an extra argument (the thaw method.)
+
+ * e-table-model.h, e-table-model.c: Added e_table_model_freeze and
+ e_table_model_thaw.
+
+ * e-table-item.h, e-table-item.c: Reworked this a bit to make it
+ provide some things the new group system needed and to make
+ inter-item keyboard focus work. Changed the external interface
+ only in the list of arguments it recognizes and signals it emits.
+ Instead of "x" and "y", you have to use
+ e_canvas_item_move_absolute and instead of emitting a
+ "height_changed" signal, it emits a "resize" signal. There's new
+ "has_focus", "width", and "height" arguments and a function to get
+ the currently focused column.
+
+ * e-table-header-item.c: Got rid of some warnings here. Changed
+ the
+
+ * e-table-group-leaf.h, e-table-group-leaf.c,
+ e-table-group-container.h, e-table-group-container.c: New types to
+ make e_table_group work properly.
+
+ * e-table-group.h, e-table-group.c: Completely reworked e-table
+ grouping. e-table-group now uses a hierarchical structure.
+
+ * e-cell.h: Added e_cell_print. This doesn't work yet.
+
+ * e-cell.c: Made e_cell_realize exist. (It was improperly named
+ e_cell_view_realize in the .c.)
+
+ * e-cell-text.c: Made the blinking cursor disappear properly.
+
+ * check-filled.xpm, check-empty.xpm: Made these const char *[]
+ instead of char *[] to avoid compiler warnings.
+
+ * Makefile.am: Added e-table-group-container.c,
+ e-table-group-container.h, e-table-group-leaf.c,
+ e-table-group-leaf.h, e-table-subset-variable.c,
+ e-table-subset-variable.h.
+
2000-02-18 Miguel de Icaza <miguel@nuclecu.unam.mx>
* e-table-header.c: Include <string.h>
diff --git a/widgets/e-table/Makefile.am b/widgets/e-table/Makefile.am
index 556a77bad8..0780ae7c57 100644
--- a/widgets/e-table/Makefile.am
+++ b/widgets/e-table/Makefile.am
@@ -23,6 +23,10 @@ libetable_a_SOURCES = \
e-table-col.h \
e-table-group.c \
e-table-group.h \
+ e-table-group-container.c \
+ e-table-group-container.h \
+ e-table-group-leaf.c \
+ e-table-group-leaf.h \
e-table-header.c \
e-table-header.h \
e-table-header-item.c \
@@ -36,7 +40,9 @@ libetable_a_SOURCES = \
e-table-sorted.c \
e-table-sorted.h \
e-table-subset.c \
- e-table-subset.h
+ e-table-subset.h \
+ e-table-subset-variable.c \
+ e-table-subset-variable.h
noinst_PROGRAMS = \
table-test
diff --git a/widgets/e-table/check-empty.xpm b/widgets/e-table/check-empty.xpm
index 2dd873e137..746b20234e 100644
--- a/widgets/e-table/check-empty.xpm
+++ b/widgets/e-table/check-empty.xpm
@@ -1,5 +1,5 @@
/* XPM */
-static char * check_empty_xpm[] = {
+static const char * check_empty_xpm[] = {
"16 16 2 1",
" c None",
". c #000000",
diff --git a/widgets/e-table/check-filled.xpm b/widgets/e-table/check-filled.xpm
index 689d7a7967..c0468fc25b 100644
--- a/widgets/e-table/check-filled.xpm
+++ b/widgets/e-table/check-filled.xpm
@@ -1,5 +1,5 @@
/* XPM */
-static char * check_filled_xpm[] = {
+static const char * check_filled_xpm[] = {
"16 16 2 1",
" c None",
". c #000000",
diff --git a/widgets/e-table/e-cell-text.c b/widgets/e-table/e-cell-text.c
index 8131d16384..fb33f10537 100644
--- a/widgets/e-table/e-cell-text.c
+++ b/widgets/e-table/e-cell-text.c
@@ -120,7 +120,6 @@ typedef struct {
} ECellTextView;
typedef struct _CurrentCell{
-
ECellTextView *text_view;
int width;
gchar *text;
@@ -233,6 +232,10 @@ static void
ect_stop_editing (ECellTextView *text_view)
{
CellEdit *edit = text_view->edit;
+ int row, view_col;
+
+ row = edit->cell.row;
+ view_col = edit->cell.view_col;
g_free (edit->old_text);
edit->old_text = NULL;
@@ -246,12 +249,24 @@ ect_stop_editing (ECellTextView *text_view)
g_free(edit->primary_selection);
if (edit->clipboard_selection)
g_free(edit->clipboard_selection);
+ if ( ! edit->default_cursor_shown ) {
+ gdk_window_set_cursor(GTK_WIDGET(text_view->canvas)->window, NULL);
+ edit->default_cursor_shown = TRUE;
+ }
+ if (edit->timeout_id) {
+ g_source_remove(edit->timeout_id);
+ edit->timeout_id = 0;
+ }
+ if (edit->timer) {
+ g_timer_stop(edit->timer);
+ g_timer_destroy(edit->timer);
+ edit->timer = NULL;
+ }
g_free (edit);
text_view->edit = NULL;
-
- e_table_item_leave_edit (text_view->cell_view.e_table_item_view);
+ ect_queue_redraw (text_view, view_col, row);
}
/*
@@ -260,7 +275,6 @@ ect_stop_editing (ECellTextView *text_view)
static void
ect_cancel_edit (ECellTextView *text_view)
{
- ect_queue_redraw (text_view, text_view->edit->cell.view_col, text_view->edit->cell.row);
ect_stop_editing (text_view);
}
@@ -379,9 +393,11 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
if (edit){
- if ((edit->cell.view_col == view_col) && (edit->cell.row == row))
+ if ((edit->cell.view_col == view_col) && (edit->cell.row == row)) {
edit_display = TRUE;
- fg_gc = canvas->style->fg_gc[edit->has_selection ? GTK_STATE_SELECTED : GTK_STATE_ACTIVE];
+ fg_gc = canvas->style->fg_gc[edit->has_selection ? GTK_STATE_SELECTED : GTK_STATE_ACTIVE];
+ } else
+ fg_gc = canvas->style->fg_gc[GTK_STATE_ACTIVE];
} else {
fg_gc = canvas->style->fg_gc[GTK_STATE_ACTIVE];
}
@@ -776,6 +792,8 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col,
break;
case GDK_BUTTON_PRESS: /* Fall Through */
case GDK_BUTTON_RELEASE:
+ event->button.x -= 4;
+ event->button.y -= 1;
if ((!edit_display)
&& ect->editable
&& event->type == GDK_BUTTON_RELEASE
@@ -828,6 +846,8 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col,
}
break;
case GDK_MOTION_NOTIFY:
+ event->motion.x -= 4;
+ event->motion.y -= 1;
if (edit_display) {
GdkEventMotion motion = event->motion;
e_tep_event.motion.time = motion.time;
@@ -928,15 +948,6 @@ ect_height (ECellView *ecell_view, int model_col, int view_col, int row)
}
/*
- * Callback: invoked when the user pressed "enter" on the GtkEntry
- */
-static void
-ect_entry_activate (GtkEntry *entry, ECellTextView *text_view)
-{
- e_table_item_leave_edit (text_view->cell_view.e_table_item_view);
-}
-
-/*
* ECellView::enter_edit method
*/
static void *
@@ -1011,19 +1022,6 @@ ect_leave_edit (ECellView *ecell_view, int model_col, int view_col, int row, voi
CellEdit *edit = text_view->edit;
if (edit){
- if ( ! edit->default_cursor_shown ) {
- gdk_window_set_cursor(GTK_WIDGET(text_view->canvas)->window, NULL);
- edit->default_cursor_shown = TRUE;
- }
- if (edit->timeout_id) {
- g_source_remove(edit->timeout_id);
- edit->timeout_id = 0;
- }
- if (edit->timer) {
- g_timer_stop(edit->timer);
- g_timer_destroy(edit->timer);
- edit->timer = NULL;
- }
ect_accept_edits (text_view);
ect_stop_editing (text_view);
} else {
@@ -1508,9 +1506,6 @@ e_cell_text_view_command(ETextEventProcessor *tep, ETextEventProcessorCommand *c
break;
case E_TEP_ACTIVATE:
e_table_item_leave_edit (text_view->cell_view.e_table_item_view);
- if (edit->timer) {
- g_timer_reset(edit->timer);
- }
break;
case E_TEP_SET_SELECT_BY_WORD:
edit->select_by_word = command->value;
@@ -1842,7 +1837,9 @@ calc_line_widths (CurrentCell *cell)
}
if (ect->use_ellipsis &&
- ! text_view->edit &&
+ (!(text_view->edit &&
+ cell->row == text_view->edit->cell.row &&
+ cell->view_col == text_view->edit->cell.view_col)) &&
lines->width > cell->width) {
if (font) {
lines->ellipsis_length = 0;
diff --git a/widgets/e-table/e-cell.c b/widgets/e-table/e-cell.c
index f1345e8c6b..1d87019007 100644
--- a/widgets/e-table/e-cell.c
+++ b/widgets/e-table/e-cell.c
@@ -129,7 +129,7 @@ e_cell_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view
}
void
-e_cell_view_realize (ECellView *ecell_view)
+e_cell_realize (ECellView *ecell_view)
{
return E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->realize (ecell_view);
}
diff --git a/widgets/e-table/e-cell.h b/widgets/e-table/e-cell.h
index 3c258689e4..b21653d6d1 100644
--- a/widgets/e-table/e-cell.h
+++ b/widgets/e-table/e-cell.h
@@ -2,6 +2,7 @@
#define _E_CELL_H_
#include <gdk/gdktypes.h>
+#include <libgnomeprint/gnome-print.h>
#include "e-table-model.h"
#define E_CELL_TYPE (e_cell_get_type ())
@@ -62,6 +63,9 @@ void e_cell_unrealize (ECellView *ecell_view);
void e_cell_draw (ECellView *ecell_view, GdkDrawable *dr,
int model_col, int view_col, int row, gboolean selected,
int x1, int y1, int x2, int y2);
+void e_cell_print (ECellView *ecell_view, GnomePrintContext *context,
+ int model_col, int view_col, int row,
+ double width, double height);
void e_cell_focus (ECellView *ecell_view, int model_col, int view_col, int row,
int x1, int y1, int x2, int y2);
void e_cell_unfocus (ECellView *ecell_view);
diff --git a/widgets/e-table/e-table-group-container.c b/widgets/e-table/e-table-group-container.c
new file mode 100644
index 0000000000..a9f494db04
--- /dev/null
+++ b/widgets/e-table/e-table-group-container.c
@@ -0,0 +1,804 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * E-Table-Group.c: Implements the grouping objects for elements on a table
+ *
+ * Author:
+ * Miguel de Icaza (miguel@gnu.org()
+ *
+ * Copyright 1999, Helix Code, Inc.
+ */
+
+#include <config.h>
+#include <gtk/gtksignal.h>
+#include "e-table-group-container.h"
+#include "e-table-item.h"
+#include <libgnomeui/gnome-canvas-rect-ellipse.h>
+#include "e-util/e-util.h"
+#include "e-util/e-canvas-utils.h"
+#include "widgets/e-text/e-text.h"
+
+#define TITLE_HEIGHT 16
+#define GROUP_INDENT 10
+
+#define BUTTON_HEIGHT 10
+#define BUTTON_PADDING 2
+
+#define PARENT_TYPE e_table_group_get_type ()
+
+static GnomeCanvasGroupClass *etgc_parent_class;
+
+/* The arguments we take */
+enum {
+ ARG_0,
+ ARG_HEIGHT,
+ ARG_WIDTH,
+ ARG_FROZEN
+};
+
+static void etgc_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+static void etgc_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+
+static int etgc_event (GnomeCanvasItem *item, GdkEvent *event);
+static void etgc_realize (GnomeCanvasItem *item);
+static void etgc_unrealize (GnomeCanvasItem *item);
+
+static void etgc_add (ETableGroup *etg, gint row);
+static gboolean etgc_remove (ETableGroup *etg, gint row);
+static void etgc_increment (ETableGroup *etg, gint position, gint amount);
+static void etgc_set_focus (ETableGroup *etg, EFocus direction, gint view_col);
+
+static void etgc_child_resize (GtkObject *object, gpointer data);
+
+static void etgc_queue_reposition (ETableGroupContainer *etgc);
+
+typedef struct {
+ ETableGroup *child;
+ void *key;
+ GnomeCanvasItem *text;
+ GnomeCanvasItem *rect;
+ gint count;
+} ETableGroupContainerChildNode;
+
+static void
+etgc_destroy (GtkObject *object)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (object);
+
+ gdk_font_unref(etgc->font);
+
+ GTK_OBJECT_CLASS (etgc_parent_class)->destroy (object);
+}
+#if 0
+void
+e_table_group_add (ETableGroup *etg, GnomeCanvasItem *item)
+{
+ double x1, y1, x2, y2;
+
+ g_return_if_fail (etg != NULL);
+ g_return_if_fail (item != NULL);
+ g_return_if_fail (E_IS_TABLE_GROUP (etg));
+ g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
+
+ etg->children = g_list_append (etg->children, item);
+
+ GNOME_CANVAS_ITEM_CLASS (GTK_OBJECT (etg)->klass)->bounds (etg, &x1, &y1, &x2, &y2);
+
+ if (GTK_OBJECT (etg)->flags & GNOME_CANVAS_ITEM_REALIZED){
+ GList *l;
+ int height = etg->transparent ? 0 : TITLE_HEIGHT;
+ int x = etg->transparent ? 0 : GROUP_INDENT;
+
+ for (l = etg->children; l->next; l = l->next){
+ GnomeCanvasItem *child = l->data;
+
+ height += child->y2 - child->y1;
+
+ printf ("Height\n");
+ if (E_IS_TABLE_ITEM (item)){
+ printf (" Item: ");
+ } else {
+ printf (" Group: ");
+ }
+ printf ("%d\n", child->y2-child->y1);
+ }
+
+ e_canvas_item_move_absolute ( item, x, height);
+
+
+ if (E_IS_TABLE_ITEM (item)){
+
+ printf ("Table item! ---------\n");
+ gtk_signal_connect (GTK_OBJECT (item), "resize",
+ GTK_SIGNAL_FUNC (etg_relayout), etg);
+ }
+ }
+}
+
+static void
+etg_realize (GnomeCanvasItem *item)
+{
+ ETableGroup *etg = E_TABLE_GROUP (item);
+ GList *l;
+ int height = 0;
+
+ GNOME_CANVAS_ITEM_CLASS (etg_parent_class)->realize (item);
+
+ for (l = etg->children; l; l = l->next){
+ GnomeCanvasItem *child = l->data;
+
+ printf ("During realization for child %p -> %d\n", child, height);
+ gnome_canvas_item_set (
+ child,
+ "y", (double) height,
+ NULL);
+
+ height += child->y2 - child->y1;
+ }
+}
+
+static void
+etg_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
+{
+ ETableGroup *etg = E_TABLE_GROUP (item);
+
+ GNOME_CANVAS_ITEM_CLASS (etg_parent_class)->update (item, affine, clip_path, flags);
+
+ if (!etg->transparent){
+ int current_width, current_height;
+
+ etg_dim (etg, &current_width, &current_height);
+
+ if ((current_height != etg->height) || (current_width != etg->width)){
+ etg->width = current_width;
+ etg->height = current_height;
+
+ gnome_canvas_item_set (
+ etg->rect,
+ "x1", 0.0,
+ "y1", 0.0,
+ "x2", (double) etg->width,
+ "y2", (double) etg->height,
+ NULL);
+ }
+ }
+}
+#endif
+
+void
+e_table_group_container_construct (GnomeCanvasGroup *parent, ETableGroupContainer *etgc,
+ ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model, ETableCol *ecol, xmlNode *child_rules)
+{
+ e_table_group_construct (parent, E_TABLE_GROUP (etgc), full_header, header, model);
+ etgc->ecol = ecol;
+ etgc->child_rules = child_rules;
+
+ etgc->font = gdk_font_load ("lucidasans-10");
+#if 0
+ etgc->open = open;
+ etgc->transparent = transparent;
+
+ etgc_dim (etgc, &etgc->width, &etgc->height);
+
+ if (!etgc->transparent)
+ etgc->rect = gnome_canvas_item_new (
+ GNOME_CANVAS_GROUP (etgc),
+ gnome_canvas_rect_get_type (),
+ "fill_color", "gray",
+ "outline_color", "gray20",
+ "x1", 0.0,
+ "y1", 0.0,
+ "x2", (double) etgc->width,
+ "y2", (double) etgc->height,
+ NULL);
+#endif
+
+#if 0
+ /*
+ * Reparent the child into our space.
+ */
+ gnome_canvas_item_reparent (child, GNOME_CANVAS_GROUP (etgc));
+
+ gnome_canvas_item_set (
+ child,
+ "x", (double) GROUP_INDENT,
+ "y", (double) TITLE_HEIGHT,
+ NULL);
+
+ /*
+ * Force dimension computation
+ */
+ GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->update (
+ GNOME_CANVAS_ITEM (etgc), NULL, NULL, GNOME_CANVAS_UPDATE_REQUESTED);
+#endif
+}
+
+ETableGroup *
+e_table_group_container_new (GnomeCanvasGroup *parent, ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model, ETableCol *ecol, xmlNode *child_rules)
+{
+ ETableGroupContainer *etgc;
+
+ g_return_val_if_fail (parent != NULL, NULL);
+ g_return_val_if_fail (ecol != NULL, NULL);
+
+ etgc = gtk_type_new (e_table_group_container_get_type ());
+
+ e_table_group_container_construct (parent, etgc, full_header, header,
+ model, ecol, child_rules);
+ return E_TABLE_GROUP (etgc);
+}
+
+#if 0
+static void
+etgc_relayout (GnomeCanvasItem *eti, ETableGroupContainer *etgc)
+{
+ GList *l;
+ int height = etgc->transparent ? 0 : GROUP_INDENT;
+ gboolean move = FALSE;
+
+ printf ("Relaying out\n");
+
+ for (l = etgc->children; l->next; l = l->next){
+ GnomeCanvasItem *child = l->data;
+
+ height += child->y2 - child->y1;
+
+ if (child == eti)
+ move = TRUE;
+
+ if (move){
+ printf ("Moving item %p\n", child);
+ gnome_canvas_item_set ( child,
+ "y", (double) height,
+ NULL);
+ }
+ }
+ if (height != etgc->height){
+ etgc->height = height;
+ gtk_signal_emit (GTK_OBJECT (etgc), etgc_signals [RESIZE]);
+ }
+}
+
+void
+e_table_group_container_add (ETableGroupContainer *etgc, GnomeCanvasItem *item)
+{
+ double x1, y1, x2, y2;
+
+ g_return_if_fail (etgc != NULL);
+ g_return_if_fail (item != NULL);
+ g_return_if_fail (E_IS_TABLE_GROUP (etgc));
+ g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
+
+ etgc->children = g_list_append (etgc->children, item);
+
+ GNOME_CANVAS_ITEM_CLASS (GTK_OBJECT (etgc)->klass)->bounds (etgc, &x1, &y1, &x2, &y2);
+
+ if (GTK_OBJECT (etgc)->flags & GNOME_CANVAS_ITEM_REALIZED){
+ GList *l;
+ int height = etgc->transparent ? 0 : TITLE_HEIGHT;
+ int x = etgc->transparent ? 0 : GROUP_INDENT;
+
+ for (l = etgc->children; l->next; l = l->next){
+ GnomeCanvasItem *child = l->data;
+
+ height += child->y2 - child->y1;
+
+ printf ("Height\n");
+ if (E_IS_TABLE_ITEM (item)){
+ printf (" Item: ");
+ } else {
+ printf (" Group: ");
+ }
+ printf ("%d\n", child->y2-child->y1);
+ }
+
+ e_canvas_item_move_absolute ( item, x, height);
+
+
+ if (E_IS_TABLE_ITEM (item)){
+
+ printf ("Table item! ---------\n");
+ gtk_signal_connect (GTK_OBJECT (item), "resize",
+ GTK_SIGNAL_FUNC (etgc_relayout), etgc);
+ }
+ }
+}
+
+static void
+etgc_realize (GnomeCanvasItem *item)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (item);
+ GList *l;
+ int height = 0;
+
+ GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->realize (item);
+
+ for (l = etgc->children; l; l = l->next){
+ GnomeCanvasItem *child = l->data;
+
+ printf ("During realization for child %p -> %d\n", child, height);
+ gnome_canvas_item_set (
+ child,
+ "y", (double) height,
+ NULL);
+
+ height += child->y2 - child->y1;
+ }
+}
+
+static void
+etgc_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (item);
+
+ GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->update (item, affine, clip_path, flags);
+
+ if ( etgc->need_resize ) {
+
+ if (!etgc->transparent){
+ int current_width, current_height;
+
+ etgc_dim (etgc, &current_width, &current_height);
+
+ if ((current_height != etgc->height) || (current_width != etgc->width)){
+ etgc->width = current_width;
+ etgc->height = current_height;
+
+ gnome_canvas_item_set (
+ etgc->rect,
+ "x1", 0.0,
+ "y1", 0.0,
+ "x2", (double) etgc->width,
+ "y2", (double) etgc->height,
+ NULL);
+ }
+ }
+ etgc->need_resize = FALSE;
+ }
+}
+#endif
+
+static int
+etgc_event (GnomeCanvasItem *item, GdkEvent *event)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(item);
+ gboolean return_val = TRUE;
+ gboolean change_focus = FALSE;
+ gboolean use_col = FALSE;
+ gint start_col = 0;
+ gint old_col;
+ EFocus direction = E_FOCUS_START;
+
+ switch (event->type) {
+ case GDK_KEY_PRESS:
+ if (event->key.keyval == GDK_Tab ||
+ event->key.keyval == GDK_KP_Tab ||
+ event->key.keyval == GDK_ISO_Left_Tab) {
+ change_focus = TRUE;
+ use_col = TRUE;
+ start_col = (event->key.state & GDK_SHIFT_MASK) ? -1 : 0;
+ direction = (event->key.state & GDK_SHIFT_MASK) ? E_FOCUS_END : E_FOCUS_START;
+ } else if (event->key.keyval == GDK_Left ||
+ event->key.keyval == GDK_KP_Left) {
+ change_focus = TRUE;
+ use_col = TRUE;
+ start_col = -1;
+ direction = E_FOCUS_END;
+ } else if (event->key.keyval == GDK_Right ||
+ event->key.keyval == GDK_KP_Right) {
+ change_focus = TRUE;
+ use_col = TRUE;
+ start_col = 0;
+ direction = E_FOCUS_START;
+ } else if (event->key.keyval == GDK_Down ||
+ event->key.keyval == GDK_KP_Down) {
+ change_focus = TRUE;
+ use_col = FALSE;
+ direction = E_FOCUS_START;
+ } else if (event->key.keyval == GDK_Up ||
+ event->key.keyval == GDK_KP_Up) {
+ change_focus = TRUE;
+ use_col = FALSE;
+ direction = E_FOCUS_END;
+ } else if (event->key.keyval == GDK_Return ||
+ event->key.keyval == GDK_KP_Enter) {
+ change_focus = TRUE;
+ use_col = FALSE;
+ direction = E_FOCUS_START;
+ }
+ if ( change_focus ) {
+ GList *list;
+ for (list = etgc->children; list; list = list->next) {
+ ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *)list->data;
+ ETableGroup *child = child_node->child;
+ if (e_table_group_get_focus(child)) {
+ old_col = e_table_group_get_focus_column(child);
+
+ if (direction == E_FOCUS_END)
+ list = list->prev;
+ else
+ list = list->next;
+
+ if (list) {
+ child_node = (ETableGroupContainerChildNode *)list->data;
+ child = child_node->child;
+ if (use_col)
+ e_table_group_set_focus(child, direction, start_col);
+ else {
+ e_table_group_set_focus(child, direction, old_col);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+ }
+ }
+ return_val = FALSE;
+ default:
+ return_val = FALSE;
+ }
+ if ( return_val == FALSE ) {
+ if ( GNOME_CANVAS_ITEM_CLASS(etgc_parent_class)->event )
+ return GNOME_CANVAS_ITEM_CLASS(etgc_parent_class)->event(item, event);
+ }
+ return return_val;
+
+}
+
+/* Realize handler for the text item */
+static void
+etgc_realize (GnomeCanvasItem *item)
+{
+ ETableGroupContainer *etgc;
+
+ if (GNOME_CANVAS_ITEM_CLASS(etgc_parent_class)->realize)
+ (* GNOME_CANVAS_ITEM_CLASS(etgc_parent_class)->realize) (item);
+
+ etgc = E_TABLE_GROUP_CONTAINER (item);
+}
+
+/* Unrealize handler for the etgc item */
+static void
+etgc_unrealize (GnomeCanvasItem *item)
+{
+ ETableGroupContainer *etgc;
+
+ etgc = E_TABLE_GROUP_CONTAINER (item);
+
+ etgc->font = NULL;
+
+ if (GNOME_CANVAS_ITEM_CLASS(etgc_parent_class)->unrealize)
+ (* GNOME_CANVAS_ITEM_CLASS(etgc_parent_class)->unrealize) (item);
+}
+
+static void
+compute_text (ETableGroupContainer *etgc, ETableGroupContainerChildNode *child_node)
+{
+ /* FIXME : What a hack, eh? */
+ gchar *text = g_strdup_printf("%s : %s (%d items)", etgc->ecol->text, (gchar *)child_node->key, (gint) child_node->count);
+ gnome_canvas_item_set(child_node->text,
+ "text", text,
+ NULL);
+ g_free(text);
+}
+
+static void etgc_add (ETableGroup *etg, gint row)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(etg);
+ void *val = e_table_model_value_at (etg->model, etgc->ecol->col_idx, row);
+ GCompareFunc comp = etgc->ecol->compare;
+ GList *list = etgc->children;
+ ETableGroup *child;
+ ETableGroupContainerChildNode *child_node;
+ for ( ; list; list = g_list_next(list) ) {
+ child_node = (ETableGroupContainerChildNode *)(list->data);
+ if ( (*comp)(child_node->key, val) ) {
+ child = child_node->child;
+ child_node->count ++;
+ e_table_group_add(child, row);
+ compute_text(etgc, child_node);
+ return;
+ }
+ }
+ child_node = g_new(ETableGroupContainerChildNode, 1);
+ child_node->rect = gnome_canvas_item_new(GNOME_CANVAS_GROUP(etgc),
+ gnome_canvas_rect_get_type (),
+ "fill_color", "grey70",
+ "outline_color", "grey50",
+ NULL);
+ child_node->text = gnome_canvas_item_new(GNOME_CANVAS_GROUP(etgc),
+ e_text_get_type(),
+ "font_gdk", etgc->font,
+ "anchor", GTK_ANCHOR_SW,
+ "x", (double) 0,
+ "y", (double) 0,
+ "fill_color", "black",
+ NULL);
+ child = e_table_group_new(GNOME_CANVAS_GROUP(etgc), etg->full_header, etg->header, etg->model, etgc->child_rules);
+ child_node->child = child;
+ child_node->key = val;
+
+ gtk_signal_connect(GTK_OBJECT(child), "resize",
+ etgc_child_resize, etgc);
+ child_node->count = 1;
+ e_table_group_add(child, row);
+ etgc->children = g_list_append(etgc->children, child_node);
+ compute_text(etgc, child_node);
+ etgc_queue_reposition(E_TABLE_GROUP_CONTAINER(etg));
+}
+
+static gboolean etgc_remove (ETableGroup *etg, gint row)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(etg);
+ GList *list = etgc->children;
+ for ( ; list; list = g_list_next(list) ) {
+ ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data;
+ ETableGroup *child = child_node->child;
+ if ( e_table_group_remove(child, row) ) {
+ child_node->count --;
+ if ( child_node->count == 0 ) {
+ gtk_object_unref(GTK_OBJECT(child_node->text));
+ gtk_object_unref(GTK_OBJECT(child));
+ etgc->children = g_list_remove(etgc->children, child_node);
+ g_free(child_node);
+ } else {
+ compute_text(etgc, child_node);
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+ etgc_queue_reposition(E_TABLE_GROUP_CONTAINER(etg));
+}
+
+static void etgc_increment (ETableGroup *etg, gint position, gint amount)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(etg);
+ GList *list = etgc->children;
+ for ( ; list; list = g_list_next(list) ) {
+ e_table_group_increment(((ETableGroupContainerChildNode *)list->data)->child, position, amount);
+ }
+ etgc_queue_reposition(E_TABLE_GROUP_CONTAINER(etg));
+}
+
+static void etgc_set_focus (ETableGroup *etg, EFocus direction, gint view_col)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(etg);
+ if (etgc->children) {
+ if (direction == E_FOCUS_END) {
+ e_table_group_set_focus(((ETableGroupContainerChildNode *)g_list_last(etgc->children)->data)->child, direction, view_col);
+ } else {
+ e_table_group_set_focus(((ETableGroupContainerChildNode *)etgc->children->data)->child, direction, view_col);
+ }
+ }
+ etgc_queue_reposition(E_TABLE_GROUP_CONTAINER(etg));
+}
+
+static gint
+etgc_get_focus_column (ETableGroup *etg)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(etg);
+ if (etgc->children) {
+ GList *list;
+ for (list = etgc->children; list; list = list->next) {
+ ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *)list->data;
+ ETableGroup *child = child_node->child;
+ if (e_table_group_get_focus(child)) {
+ return e_table_group_get_focus_column(child);
+ }
+ }
+ }
+ return 0;
+}
+
+static void etgc_thaw (ETableGroup *etg)
+{
+ etgc_queue_reposition(E_TABLE_GROUP_CONTAINER(etg));
+}
+
+static void
+etgc_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ ETableGroup *etg = E_TABLE_GROUP (object);
+
+ switch (arg_id) {
+ case ARG_FROZEN:
+ if ( GTK_VALUE_BOOL (*arg) )
+ etg->frozen = TRUE;
+ else {
+ etg->frozen = FALSE;
+ etgc_thaw(etg);
+ }
+ break;
+ case ARG_WIDTH:
+ if ( E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->set_width )
+ E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->set_width(etg, GTK_VALUE_DOUBLE (*arg));
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+etgc_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ ETableGroup *etg = E_TABLE_GROUP (object);
+
+ switch (arg_id) {
+ case ARG_FROZEN:
+ GTK_VALUE_BOOL (*arg) = etg->frozen;
+ break;
+ case ARG_HEIGHT:
+ if ( E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_height )
+ GTK_VALUE_DOUBLE (*arg) = E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_height(etg);
+ else
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ case ARG_WIDTH:
+ if ( E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_width )
+ GTK_VALUE_DOUBLE (*arg) = E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_width(etg);
+ else
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ }
+}
+
+static void etgc_set_width (ETableGroup *etg, gdouble width)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg);
+ GList *list = etgc->children;
+ etgc->width = width;
+
+ for ( ; list; list = g_list_next(list) ) {
+ gdouble child_width = width - GROUP_INDENT;
+ gtk_object_set(GTK_OBJECT(((ETableGroupContainerChildNode *)list->data)->child),
+ "width", child_width,
+ NULL);
+ }
+
+ etgc_queue_reposition(E_TABLE_GROUP_CONTAINER(etg));
+}
+
+static gdouble etgc_get_width (ETableGroup *etg)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg);
+ return etgc->width;
+}
+
+static gdouble etgc_get_height (ETableGroup *etg)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg);
+ return etgc->height;
+}
+
+static void
+etgc_class_init (GtkObjectClass *object_class)
+{
+ GnomeCanvasItemClass *item_class = (GnomeCanvasItemClass *) object_class;
+ ETableGroupClass *e_group_class = E_TABLE_GROUP_CLASS( object_class );
+
+ object_class->destroy = etgc_destroy;
+ object_class->set_arg = etgc_set_arg;
+ object_class->get_arg = etgc_get_arg;
+
+ item_class->event = etgc_event;
+ item_class->realize = etgc_realize;
+ item_class->unrealize = etgc_unrealize;
+
+ etgc_parent_class = gtk_type_class (PARENT_TYPE);
+
+ e_group_class->add = etgc_add;
+ e_group_class->remove = etgc_remove;
+ e_group_class->increment = etgc_increment;
+ e_group_class->set_focus = etgc_set_focus;
+ e_group_class->get_focus_column = etgc_get_focus_column;
+ e_group_class->thaw = etgc_thaw;
+
+ e_group_class->get_width = etgc_get_width;
+ e_group_class->set_width = etgc_set_width;
+ e_group_class->get_height = etgc_get_height;
+
+ 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_READWRITE, ARG_WIDTH);
+ gtk_object_add_arg_type ("ETableGroupContainer::frozen", GTK_TYPE_BOOL,
+ GTK_ARG_READWRITE, ARG_FROZEN);
+}
+
+static void
+etgc_init (GtkObject *object)
+{
+ ETableGroupContainer *container = E_TABLE_GROUP_CONTAINER(object);
+ container->children = FALSE;
+}
+
+static gboolean
+etgc_update_positioning (ETableGroupContainer *etgc, gpointer data)
+{
+ gboolean frozen;
+ gtk_object_get(GTK_OBJECT(etgc),
+ "frozen", &frozen,
+ NULL);
+ if ( frozen ) {
+ etgc->idle = 0;
+ return FALSE;
+ }
+ if ( GTK_OBJECT_FLAGS( etgc ) & GNOME_CANVAS_ITEM_REALIZED ) {
+ gdouble old_height;
+
+ old_height = etgc->height;
+ if ( etgc->children == NULL ) {
+ } else {
+ GList *list;
+ gdouble extra_height;
+ gdouble running_height;
+ gdouble item_height = 0;
+
+ extra_height = 0;
+ if (etgc->font)
+ extra_height += etgc->font->ascent + etgc->font->descent + BUTTON_PADDING * 2;
+
+ extra_height = MAX(extra_height, BUTTON_HEIGHT + BUTTON_PADDING * 2);
+
+ running_height = extra_height;
+
+ list = etgc->children;
+ for ( ; list; list = g_list_next(list) ) {
+ ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data;
+ ETableGroup *child = child_node->child;
+ gtk_object_get( GTK_OBJECT(child),
+ "height", &item_height,
+ NULL );
+
+ e_canvas_item_move_absolute(GNOME_CANVAS_ITEM(child_node->text),
+ GROUP_INDENT,
+ running_height - BUTTON_PADDING);
+
+ e_canvas_item_move_absolute(GNOME_CANVAS_ITEM(child),
+ GROUP_INDENT,
+ running_height);
+
+ gnome_canvas_item_set(GNOME_CANVAS_ITEM(child_node->rect),
+ "x1", (double) 0,
+ "x2", (double) etgc->width,
+ "y1", (double) running_height - extra_height,
+ "y2", (double) running_height + item_height,
+ NULL);
+
+ running_height += item_height + extra_height;
+ }
+ running_height -= extra_height;
+ if ( running_height != old_height) {
+ etgc->height = running_height;
+ gtk_signal_emit_by_name (GTK_OBJECT (etgc), "resize");
+ }
+ }
+ }
+ etgc->idle = 0;
+ return FALSE;
+}
+
+static void
+etgc_queue_reposition (ETableGroupContainer *etgc)
+{
+ if (etgc->idle == 0)
+ etgc->idle = g_idle_add((GSourceFunc)etgc_update_positioning, etgc);
+}
+
+static void
+etgc_child_resize (GtkObject *object, gpointer data)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(data);
+ etgc_queue_reposition (etgc);
+}
+
+E_MAKE_TYPE (e_table_group_container, "ETableGroupContainer", ETableGroupContainer, etgc_class_init, etgc_init, PARENT_TYPE);
+
diff --git a/widgets/e-table/e-table-group-container.h b/widgets/e-table/e-table-group-container.h
new file mode 100644
index 0000000000..4942f9e695
--- /dev/null
+++ b/widgets/e-table/e-table-group-container.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+#ifndef _E_TABLE_GROUP_CONTAINER_H_
+#define _E_TABLE_GROUP_CONTAINER_H_
+
+#include <libgnomeui/gnome-canvas.h>
+#include "e-table-model.h"
+#include "e-table-header.h"
+#include "e-table-group.h"
+
+#define E_TABLE_GROUP_CONTAINER_TYPE (e_table_group_container_get_type ())
+#define E_TABLE_GROUP_CONTAINER(o) (GTK_CHECK_CAST ((o), E_TABLE_GROUP_CONTAINER_TYPE, ETableGroupContainer))
+#define E_TABLE_GROUP_CONTAINER_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_GROUP_CONTAINER_TYPE, ETableGroupContainerClass))
+#define E_IS_TABLE_GROUP_CONTAINER(o) (GTK_CHECK_TYPE ((o), E_TABLE_GROUP_CONTAINER_TYPE))
+#define E_IS_TABLE_GROUP_CONTAINER_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_GROUP_CONTAINER_TYPE))
+
+typedef struct {
+ ETableGroup group;
+
+ /*
+ * The ETableCol used to group this set
+ */
+ ETableCol *ecol;
+
+ /*
+ * List of ETableGroups we stack
+ */
+ GList *children;
+
+ /*
+ * The canvas rectangle that contains the children
+ */
+ GnomeCanvasItem *rect;
+
+ GdkFont *font;
+
+ gdouble width, height;
+
+ void *child_rules;
+
+ gint idle;
+
+ /*
+ * Update booleans:
+ */
+ guint need_resize : 1;
+
+ /*
+ * State: the ETableGroup is open or closed
+ */
+ guint open:1;
+} ETableGroupContainer;
+
+typedef struct {
+ ETableGroupClass parent_class;
+} ETableGroupContainerClass;
+
+ETableGroup *e_table_group_container_new (GnomeCanvasGroup *parent, ETableHeader *full_header, ETableHeader *header,
+ ETableModel *model, ETableCol *ecol, xmlNode *child_rules);
+void e_table_group_container_construct (GnomeCanvasGroup *parent, ETableGroupContainer *etgc,
+ ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model, ETableCol *ecol, xmlNode *child_rules);
+
+GtkType e_table_group_container_get_type (void);
+
+#endif /* _E_TABLE_GROUP_CONTAINER_H_ */
diff --git a/widgets/e-table/e-table-group-leaf.c b/widgets/e-table/e-table-group-leaf.c
new file mode 100644
index 0000000000..ba73ad9886
--- /dev/null
+++ b/widgets/e-table/e-table-group-leaf.c
@@ -0,0 +1,288 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * E-Table-Group.c: Implements the grouping objects for elements on a table
+ *
+ * Author:
+ * Miguel de Icaza (miguel@gnu.org()
+ *
+ * Copyright 1999, Helix Code, Inc.
+ */
+
+#include <config.h>
+#include <gtk/gtksignal.h>
+#include "e-table-group-leaf.h"
+#include "e-table-item.h"
+#include <libgnomeui/gnome-canvas-rect-ellipse.h>
+#include "e-util/e-util.h"
+
+#define TITLE_HEIGHT 16
+#define GROUP_INDENT 10
+
+#define PARENT_TYPE e_table_group_get_type ()
+
+static GnomeCanvasGroupClass *etgl_parent_class;
+
+/* The arguments we take */
+enum {
+ ARG_0,
+ ARG_HEIGHT,
+ ARG_WIDTH,
+ ARG_FROZEN
+};
+
+static void etgl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+static void etgl_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+
+static void
+etgl_destroy (GtkObject *object)
+{
+ GTK_OBJECT_CLASS (etgl_parent_class)->destroy (object);
+}
+
+static void
+e_table_group_leaf_construct (GnomeCanvasGroup *parent, ETableGroupLeaf *etgl,
+ ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model)
+{
+ e_table_group_construct (parent, E_TABLE_GROUP (etgl), full_header, header, model);
+ etgl->subset = E_TABLE_SUBSET_VARIABLE(e_table_subset_variable_new(model));
+}
+
+ETableGroup *
+e_table_group_leaf_new (GnomeCanvasGroup *parent, ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model)
+{
+ ETableGroupLeaf *etgl;
+
+ g_return_val_if_fail (parent != NULL, NULL);
+
+ etgl = gtk_type_new (e_table_group_leaf_get_type ());
+
+ e_table_group_leaf_construct (parent, etgl, full_header,
+ header, model);
+ return E_TABLE_GROUP (etgl);
+}
+
+static void
+etgl_resize (GtkObject *object, gpointer data)
+{
+ e_table_group_resize (E_TABLE_GROUP(data));
+}
+
+static void
+etgl_realize (GnomeCanvasItem *item)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF(item);
+ gdouble height;
+
+ if ( GNOME_CANVAS_ITEM_CLASS (etgl_parent_class)->realize )
+ GNOME_CANVAS_ITEM_CLASS (etgl_parent_class)->realize (item);
+
+ etgl->item = E_TABLE_ITEM(gnome_canvas_item_new(GNOME_CANVAS_GROUP(etgl),
+ e_table_item_get_type (),
+ "ETableHeader", E_TABLE_GROUP(etgl)->header,
+ "ETableModel", etgl->subset,
+ "drawgrid", TRUE,
+ "drawfocus", TRUE,
+ "spreadsheet", TRUE,
+ "width", etgl->width,
+ NULL));
+ gtk_signal_connect(GTK_OBJECT(etgl->item),
+ "resize", etgl_resize, etgl);
+ gtk_object_get(GTK_OBJECT(etgl->item),
+ "height", &height,
+ NULL);
+ if ( height != 1 )
+ e_table_group_resize(E_TABLE_GROUP(etgl));
+}
+
+static int
+etgl_event (GnomeCanvasItem *item, GdkEvent *event)
+{
+ gboolean return_val = TRUE;
+
+ switch (event->type) {
+
+ default:
+ return_val = FALSE;
+ }
+ if ( return_val == FALSE ) {
+ if ( GNOME_CANVAS_ITEM_CLASS(etgl_parent_class)->event )
+ return GNOME_CANVAS_ITEM_CLASS(etgl_parent_class)->event(item, event);
+ }
+ return return_val;
+
+}
+
+static void
+etgl_add (ETableGroup *etg, gint row)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
+ e_table_subset_variable_add(etgl->subset, row);
+}
+
+static gboolean
+etgl_remove (ETableGroup *etg, gint row)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
+ return e_table_subset_variable_remove(etgl->subset, row);
+}
+
+static void
+etgl_increment (ETableGroup *etg, gint position, gint amount)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
+ e_table_subset_variable_increment(etgl->subset, position, amount);
+}
+
+static void
+etgl_set_focus (ETableGroup *etg, EFocus direction, gint view_col)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
+ if (direction == E_FOCUS_END) {
+ e_table_item_focus(etgl->item, view_col, e_table_model_row_count(E_TABLE_MODEL(etgl->subset)) - 1);
+ } else {
+ e_table_item_focus(etgl->item, view_col, 0);
+ }
+}
+
+static gint
+etgl_get_focus_column (ETableGroup *etg)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
+ return e_table_item_get_focused_column(etgl->item);
+}
+
+static void
+etgl_set_width (ETableGroup *etg, gdouble width)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
+ etgl->width = width;
+#if 0
+ if ( etgl->item ) {
+ gnome_canvas_item_set(GNOME_CANVAS_ITEM(etgl->item),
+ "width", width,
+ NULL);
+ }
+#endif
+}
+
+static gdouble
+etgl_get_width (ETableGroup *etg)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
+ gtk_object_get(GTK_OBJECT(etgl->item),
+ "width", &etgl->width,
+ NULL);
+ return etgl->width;
+}
+
+static gdouble
+etgl_get_height (ETableGroup *etg)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
+ gdouble height;
+ if ( etgl->item )
+ gtk_object_get(GTK_OBJECT(etgl->item),
+ "height", &height,
+ NULL);
+ else
+ height = 1;
+ return height;
+}
+
+static void
+etgl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ ETableGroup *etg = E_TABLE_GROUP (object);
+
+ switch (arg_id) {
+ case ARG_FROZEN:
+ if ( GTK_VALUE_BOOL (*arg) )
+ etg->frozen = TRUE;
+ else {
+ etg->frozen = FALSE;
+ }
+ break;
+ case ARG_WIDTH:
+ if ( E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->set_width )
+ E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->set_width(etg, GTK_VALUE_DOUBLE (*arg));
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+etgl_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ ETableGroup *etg = E_TABLE_GROUP (object);
+
+ switch (arg_id) {
+ case ARG_FROZEN:
+ GTK_VALUE_BOOL (*arg) = etg->frozen;
+ break;
+ case ARG_HEIGHT:
+ if ( E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_height )
+ GTK_VALUE_DOUBLE (*arg) = E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_height(etg);
+ else
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ case ARG_WIDTH:
+ if ( E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_width )
+ GTK_VALUE_DOUBLE (*arg) = E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_width(etg);
+ else
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ }
+}
+
+static void
+etgl_class_init (GtkObjectClass *object_class)
+{
+ GnomeCanvasItemClass *item_class = (GnomeCanvasItemClass *) object_class;
+ ETableGroupClass *e_group_class = E_TABLE_GROUP_CLASS( object_class );
+
+ object_class->destroy = etgl_destroy;
+ object_class->set_arg = etgl_set_arg;
+ object_class->get_arg = etgl_get_arg;
+
+ item_class->realize = etgl_realize;
+ item_class->event = etgl_event;
+
+ etgl_parent_class = gtk_type_class (PARENT_TYPE);
+
+ e_group_class->add = etgl_add;
+ e_group_class->remove = etgl_remove;
+ e_group_class->increment = etgl_increment;
+ e_group_class->set_focus = etgl_set_focus;
+ e_group_class->get_focus_column = etgl_get_focus_column;
+
+ e_group_class->get_width = etgl_get_width;
+ e_group_class->set_width = etgl_set_width;
+ e_group_class->get_height = etgl_get_height;
+
+ 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_READWRITE, ARG_WIDTH);
+ gtk_object_add_arg_type ("ETableGroupLeaf::frozen", GTK_TYPE_BOOL,
+ GTK_ARG_READWRITE, ARG_FROZEN);
+}
+
+static void
+etgl_init (GtkObject *object)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (object);
+
+ etgl->width = 1;
+ etgl->subset = NULL;
+ etgl->item = NULL;
+}
+
+E_MAKE_TYPE (e_table_group_leaf, "ETableGroupLeaf", ETableGroupLeaf, etgl_class_init, etgl_init, PARENT_TYPE);
diff --git a/widgets/e-table/e-table-group-leaf.h b/widgets/e-table/e-table-group-leaf.h
new file mode 100644
index 0000000000..372bf4cc70
--- /dev/null
+++ b/widgets/e-table/e-table-group-leaf.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+#ifndef _E_TABLE_GROUP_LEAF_H_
+#define _E_TABLE_GROUP_LEAF_H_
+
+#include <libgnomeui/gnome-canvas.h>
+#include "e-table-group.h"
+#include "e-table-subset-variable.h"
+#include "e-table-item.h"
+
+#define E_TABLE_GROUP_LEAF_TYPE (e_table_group_leaf_get_type ())
+#define E_TABLE_GROUP_LEAF(o) (GTK_CHECK_CAST ((o), E_TABLE_GROUP_LEAF_TYPE, ETableGroupLeaf))
+#define E_TABLE_GROUP_LEAF_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_GROUP_LEAF_TYPE, ETableGroupLeafClass))
+#define E_IS_TABLE_GROUP_LEAF(o) (GTK_CHECK_TYPE ((o), E_TABLE_GROUP_LEAF_TYPE))
+#define E_IS_TABLE_GROUP_LEAF_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_GROUP_LEAF_TYPE))
+
+typedef struct {
+ ETableGroup group;
+
+ /*
+ * Item.
+ */
+ ETableItem *item;
+
+ gdouble width;
+
+ ETableSubsetVariable *subset;
+} ETableGroupLeaf;
+
+typedef struct {
+ ETableGroupClass parent_class;
+} ETableGroupLeafClass;
+
+ETableGroup *e_table_group_leaf_new (GnomeCanvasGroup *parent,
+ ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model);
+GtkType e_table_group_leaf_get_type (void);
+
+#endif /* _E_TABLE_GROUP_LEAF_H_ */
diff --git a/widgets/e-table/e-table-group.c b/widgets/e-table/e-table-group.c
index 5652d2623f..68bc3e7abf 100644
--- a/widgets/e-table/e-table-group.c
+++ b/widgets/e-table/e-table-group.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* E-Table-Group.c: Implements the grouping objects for elements on a table
*
@@ -10,8 +11,11 @@
#include <config.h>
#include <gtk/gtksignal.h>
#include "e-table-group.h"
+#include "e-table-group-container.h"
+#include "e-table-group-leaf.h"
#include "e-table-item.h"
#include <libgnomeui/gnome-canvas-rect-ellipse.h>
+#include <gnome-xml/parser.h>
#include "e-util/e-util.h"
#define TITLE_HEIGHT 16
@@ -19,88 +23,30 @@
#define PARENT_TYPE gnome_canvas_group_get_type ()
+#define ETG_CLASS(e) (E_TABLE_GROUP_CLASS(GTK_OBJECT(e)->klass))
+
static GnomeCanvasGroupClass *etg_parent_class;
enum {
- HEIGHT_CHANGED,
+ RESIZE,
LAST_SIGNAL
};
static gint etg_signals [LAST_SIGNAL] = { 0, };
-static void
-etg_destroy (GtkObject *object)
-{
- ETableGroup *etg = E_TABLE_GROUP (object);
-
- GTK_OBJECT_CLASS (etg_parent_class)->destroy (object);
-}
-
-static void
-etg_dim (ETableGroup *etg, int *width, int *height)
-{
- GSList *l;
-
- *width = *height = 0;
-
- for (l = etg->children; l; l = l->next){
- GnomeCanvasItem *child = l->data;
-
- *height += child->y2 - child->y1;
- *width += child->x2 - child->x1;
- }
-
- if (!etg->transparent){
- *height += TITLE_HEIGHT;
- *width += GROUP_INDENT;
- }
-}
+/* The arguments we take */
+enum {
+ ARG_0,
+ ARG_HEIGHT,
+ ARG_WIDTH,
+ ARG_FROZEN
+};
-void
-e_table_group_construct (GnomeCanvasGroup *parent, ETableGroup *etg,
- ETableCol *ecol, gboolean open,
- gboolean transparent)
-{
- gnome_canvas_item_constructv (GNOME_CANVAS_ITEM (etg), parent, 0, NULL);
-
- etg->ecol = ecol;
- etg->open = open;
- etg->transparent = transparent;
-
- etg_dim (etg, &etg->width, &etg->height);
-
- if (!etg->transparent)
- etg->rect = gnome_canvas_item_new (
- GNOME_CANVAS_GROUP (etg),
- gnome_canvas_rect_get_type (),
- "fill_color", "gray",
- "outline_color", "gray20",
- "x1", 0.0,
- "y1", 0.0,
- "x2", (double) etg->width,
- "y2", (double) etg->height,
- NULL);
+static void etg_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+static void etg_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+static gboolean etg_get_focus (ETableGroup *etg);
#if 0
- /*
- * Reparent the child into our space.
- */
- gnome_canvas_item_reparent (child, GNOME_CANVAS_GROUP (etg));
-
- gnome_canvas_item_set (
- child,
- "x", (double) GROUP_INDENT,
- "y", (double) TITLE_HEIGHT,
- NULL);
-
- /*
- * Force dimension computation
- */
- GNOME_CANVAS_ITEM_CLASS (etg_parent_class)->update (
- GNOME_CANVAS_ITEM (etg), NULL, NULL, GNOME_CANVAS_UPDATE_REQUESTED);
-#endif
-}
-
GnomeCanvasItem *
e_table_group_new (GnomeCanvasGroup *parent, ETableCol *ecol,
gboolean open, gboolean transparent)
@@ -116,158 +62,275 @@ e_table_group_new (GnomeCanvasGroup *parent, ETableCol *ecol,
return GNOME_CANVAS_ITEM (etg);
}
+#endif
-static void
-etg_relayout (GnomeCanvasItem *eti, ETableGroup *etg)
+ETableGroup *
+e_table_group_new (GnomeCanvasGroup *parent,
+ ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model,
+ xmlNode *rules)
{
- GSList *l;
- int height = etg->transparent ? 0 : GROUP_INDENT;
- gboolean move = FALSE;
+ g_return_val_if_fail (model != NULL, NULL);
- printf ("Relaying out\n");
-
- for (l = etg->children; l->next; l = l->next){
- GnomeCanvasItem *child = l->data;
+ if(rules && !xmlStrcmp(rules->name, "group")) {
+ gint col_idx = atoi(xmlGetProp(rules, "column"));
+ ETableCol *col;
+ if ( col_idx > e_table_header_count(full_header) )
+ return e_table_group_leaf_new(parent, full_header, header, model);
+ col = e_table_header_get_columns(full_header)[col_idx];
+ return e_table_group_container_new(parent, full_header, header, model, col, rules->childs);
+ } else {
+ return e_table_group_leaf_new(parent, full_header, header, model);
+ }
+ return NULL;
+}
+
+void
+e_table_group_construct (GnomeCanvasGroup *parent,
+ ETableGroup *etg,
+ ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model)
+{
+ gnome_canvas_item_constructv (GNOME_CANVAS_ITEM (etg), parent, 0, NULL);
+ etg->full_header = full_header;
+ etg->header = header;
+ etg->model = model;
+}
+
+void
+e_table_group_add (ETableGroup *etg,
+ gint row)
+{
+ g_return_if_fail (etg != NULL);
+ g_return_if_fail (E_IS_TABLE_GROUP (etg));
- height += child->y2 - child->y1;
+ if ( ETG_CLASS (etg)->add )
+ ETG_CLASS (etg)->add (etg, row);
+}
- if (child == eti)
- move = TRUE;
+gboolean
+e_table_group_remove (ETableGroup *etg,
+ gint row)
+{
+ g_return_val_if_fail (etg != NULL, FALSE);
+ g_return_val_if_fail (E_IS_TABLE_GROUP (etg), FALSE);
- if (move){
- printf ("Moving item %p\n", child);
- gnome_canvas_item_set (
- child,
- "y", (double) height,
- NULL);
- }
- }
- if (height != etg->height){
- etg->height = height;
- gtk_signal_emit (GTK_OBJECT (etg), etg_signals [HEIGHT_CHANGED]);
- }
+ if ( ETG_CLASS (etg)->remove )
+ return ETG_CLASS (etg)->remove (etg, row);
+ else
+ return FALSE;
+}
+
+gint
+e_table_group_get_count (ETableGroup *etg)
+{
+ g_return_val_if_fail (etg != NULL, 0);
+ g_return_val_if_fail (E_IS_TABLE_GROUP (etg), 0);
+
+ if ( ETG_CLASS (etg)->get_count )
+ return ETG_CLASS (etg)->get_count (etg);
+ else
+ return 0;
}
void
-e_table_group_add (ETableGroup *etg, GnomeCanvasItem *item)
+e_table_group_increment (ETableGroup *etg,
+ gint position,
+ gint amount)
{
- double x1, y1, x2, y2;
-
g_return_if_fail (etg != NULL);
- g_return_if_fail (item != NULL);
g_return_if_fail (E_IS_TABLE_GROUP (etg));
- g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
-
- etg->children = g_slist_append (etg->children, item);
-
- GNOME_CANVAS_ITEM_CLASS (GTK_OBJECT (etg)->klass)->bounds (etg, &x1, &y1, &x2, &y2);
-
- if (GTK_OBJECT (etg)->flags & GNOME_CANVAS_ITEM_REALIZED){
- GSList *l;
- int height = etg->transparent ? 0 : TITLE_HEIGHT;
- int x = etg->transparent ? 0 : GROUP_INDENT;
-
- for (l = etg->children; l->next; l = l->next){
- GnomeCanvasItem *child = l->data;
-
- height += child->y2 - child->y1;
-
- printf ("Height\n");
- if (E_IS_TABLE_ITEM (item)){
- printf (" Item: ");
- } else {
- printf (" Group: ");
- }
- printf ("%d\n", child->y2-child->y1);
- }
- gnome_canvas_item_set (
- item,
- "y", (double) height,
- "x", (double) x,
- NULL);
-
-
- if (E_IS_TABLE_ITEM (item)){
-
- printf ("Table item! ---------\n");
- gtk_signal_connect (GTK_OBJECT (item), "height_changed",
- GTK_SIGNAL_FUNC (etg_relayout), etg);
- }
- }
+ if ( ETG_CLASS (etg)->increment )
+ ETG_CLASS (etg)->increment (etg, position, amount);
}
-static void
-etg_realize (GnomeCanvasItem *item)
+void
+e_table_group_set_focus (ETableGroup *etg,
+ EFocus direction,
+ gint row)
+{
+ g_return_if_fail (etg != NULL);
+ g_return_if_fail (E_IS_TABLE_GROUP (etg));
+
+ if ( ETG_CLASS (etg)->set_focus )
+ ETG_CLASS (etg)->set_focus (etg, direction, row);
+}
+
+gboolean
+e_table_group_get_focus (ETableGroup *etg)
+{
+ g_return_val_if_fail (etg != NULL, FALSE);
+ g_return_val_if_fail (E_IS_TABLE_GROUP (etg), FALSE);
+
+ if ( ETG_CLASS (etg)->get_focus )
+ return ETG_CLASS (etg)->get_focus (etg);
+ else
+ return FALSE;
+}
+
+gboolean
+e_table_group_get_focus_column (ETableGroup *etg)
+{
+ g_return_val_if_fail (etg != NULL, FALSE);
+ g_return_val_if_fail (E_IS_TABLE_GROUP (etg), FALSE);
+
+ if ( ETG_CLASS (etg)->get_focus_column )
+ return ETG_CLASS (etg)->get_focus_column (etg);
+ else
+ return FALSE;
+}
+
+ETableCol *
+e_table_group_get_ecol (ETableGroup *etg)
+{
+ g_return_val_if_fail (etg != NULL, NULL);
+ g_return_val_if_fail (E_IS_TABLE_GROUP (etg), NULL);
+
+ if ( ETG_CLASS (etg)->get_ecol )
+ return ETG_CLASS (etg)->get_ecol (etg);
+ else
+ return NULL;
+}
+
+void
+e_table_group_resize (ETableGroup *e_table_group)
+{
+ g_return_if_fail (e_table_group != NULL);
+ g_return_if_fail (E_IS_TABLE_GROUP (e_table_group));
+
+ gtk_signal_emit (GTK_OBJECT (e_table_group),
+ etg_signals [RESIZE]);
+}
+
+static int
+etg_event (GnomeCanvasItem *item, GdkEvent *event)
{
ETableGroup *etg = E_TABLE_GROUP (item);
- GSList *l;
- int height = 0;
-
- GNOME_CANVAS_ITEM_CLASS (etg_parent_class)->realize (item);
+ gboolean return_val = TRUE;
- for (l = etg->children; l; l = l->next){
- GnomeCanvasItem *child = l->data;
+ switch (event->type) {
- printf ("During realization for child %p -> %d\n", child, height);
- gnome_canvas_item_set (
- child,
- "y", (double) height,
- NULL);
+ case GDK_FOCUS_CHANGE:
+ etg->has_focus = event->focus_change.in;
+ return_val = FALSE;
- height += child->y2 - child->y1;
+ default:
+ return_val = FALSE;
}
+ if ( return_val == FALSE ) {
+ if ( GNOME_CANVAS_ITEM_CLASS(etg_parent_class)->event )
+ return GNOME_CANVAS_ITEM_CLASS(etg_parent_class)->event(item, event);
+ }
+ return return_val;
+
}
static void
-etg_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
+etg_thaw(ETableGroup *etg)
{
- ETableGroup *etg = E_TABLE_GROUP (item);
+ g_return_if_fail (etg != NULL);
+ g_return_if_fail (E_IS_TABLE_GROUP (etg));
+
+ if ( ETG_CLASS (etg)->thaw )
+ ETG_CLASS (etg)->thaw (etg);
+}
+
+static void
+etg_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ ETableGroup *etg = E_TABLE_GROUP (object);
- GNOME_CANVAS_ITEM_CLASS (etg_parent_class)->update (item, affine, clip_path, flags);
-
- if (!etg->transparent){
- int current_width, current_height;
-
- etg_dim (etg, &current_width, &current_height);
-
- if ((current_height != etg->height) || (current_width != etg->width)){
- etg->width = current_width;
- etg->height = current_height;
-
- gnome_canvas_item_set (
- etg->rect,
- "x1", 0.0,
- "y1", 0.0,
- "x2", (double) etg->width,
- "y2", (double) etg->height,
- NULL);
+ switch (arg_id) {
+ case ARG_FROZEN:
+ if ( GTK_VALUE_BOOL (*arg) )
+ etg->frozen = TRUE;
+ else {
+ etg->frozen = FALSE;
+ etg_thaw(etg);
}
+ break;
+ case ARG_WIDTH:
+ if ( ETG_CLASS(etg)->set_width )
+ ETG_CLASS(etg)->set_width(etg, GTK_VALUE_DOUBLE (*arg));
+ break;
+ default:
+ break;
}
}
static void
+etg_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ ETableGroup *etg = E_TABLE_GROUP (object);
+
+ switch (arg_id) {
+ case ARG_FROZEN:
+ GTK_VALUE_BOOL (*arg) = etg->frozen;
+ break;
+ case ARG_HEIGHT:
+ if ( ETG_CLASS(etg)->get_height )
+ GTK_VALUE_DOUBLE (*arg) = ETG_CLASS(etg)->get_height(etg);
+ else
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ case ARG_WIDTH:
+ if ( ETG_CLASS(etg)->get_width )
+ GTK_VALUE_DOUBLE (*arg) = ETG_CLASS(etg)->get_width(etg);
+ else
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ }
+}
+
+static gboolean
+etg_get_focus (ETableGroup *etg)
+{
+ return etg->has_focus;
+}
+
+static void
etg_class_init (GtkObjectClass *object_class)
{
GnomeCanvasItemClass *item_class = (GnomeCanvasItemClass *) object_class;
+ ETableGroupClass *klass = (ETableGroupClass *) object_class;
+
+ object_class->set_arg = etg_set_arg;
+ object_class->get_arg = etg_get_arg;
- object_class->destroy = etg_destroy;
+ item_class->event = etg_event;
- item_class->realize = etg_realize;
- item_class->update = etg_update;
+ klass->resize = NULL;
+
+ klass->add = NULL;
+ klass->remove = NULL;
+ klass->get_count = NULL;
+ klass->increment = NULL;
+ klass->set_focus = NULL;
+ klass->get_focus = etg_get_focus;
+ klass->get_ecol = NULL;
+
+ klass->thaw = NULL;
+ klass->get_height = NULL;
+ klass->get_width = NULL;
+ klass->set_width = NULL;
etg_parent_class = gtk_type_class (PARENT_TYPE);
- etg_signals [HEIGHT_CHANGED] =
- gtk_signal_new ("height_changed",
+ etg_signals [RESIZE] =
+ gtk_signal_new ("resize",
GTK_RUN_LAST,
object_class->type,
- GTK_SIGNAL_OFFSET (ETableGroupClass, height_changed),
+ GTK_SIGNAL_OFFSET (ETableGroupClass, resize),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
gtk_object_class_add_signals (object_class, etg_signals, LAST_SIGNAL);
-
}
E_MAKE_TYPE (e_table_group, "ETableGroup", ETableGroup, etg_class_init, NULL, PARENT_TYPE);
diff --git a/widgets/e-table/e-table-group.h b/widgets/e-table/e-table-group.h
index 468d5dd794..1b3f346290 100644
--- a/widgets/e-table/e-table-group.h
+++ b/widgets/e-table/e-table-group.h
@@ -1,9 +1,12 @@
-#ifndef _E_TABLE_TREE_H_
-#define _E_TABLE_TREE_H_
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+#ifndef _E_TABLE_GROUP_H_
+#define _E_TABLE_GROUP_H_
#include <libgnomeui/gnome-canvas.h>
+#include <gnome-xml/tree.h>
#include "e-table-model.h"
#include "e-table-header.h"
+#include "e-util/e-util.h"
#define E_TABLE_GROUP_TYPE (e_table_group_get_type ())
#define E_TABLE_GROUP(o) (GTK_CHECK_CAST ((o), E_TABLE_GROUP_TYPE, ETableGroup))
@@ -15,49 +18,75 @@ typedef struct {
GnomeCanvasGroup group;
/*
- * The ETableCol used to group this set
+ * The full header.
*/
- ETableCol *ecol;
-
- /*
- * The canvas rectangle that contains the children
- */
- GnomeCanvasItem *rect;
-
- /*
- * Dimensions of the ETableGroup
- */
- int width, height;
-
+ ETableHeader *full_header;
+ ETableHeader *header;
+
/*
- * State: the ETableGroup is open or closed
+ * The model we pull data from.
*/
- guint open:1;
+ ETableModel *model;
/*
* Whether we should add indentation and open/close markers,
* or if we just act as containers of subtables.
*/
- guint transparent:1;
+ guint transparent : 1;
- /*
- * List of GnomeCanvasItems we stack
- */
- GSList *children;
+ guint has_focus : 1;
+
+ guint frozen : 1;
} ETableGroup;
typedef struct {
GnomeCanvasGroupClass parent_class;
- void (*height_changed) (ETableGroup *etg);
+ void (*resize) (ETableGroup *etg);
+
+ void (*add) (ETableGroup *etg, gint row);
+ gboolean (*remove) (ETableGroup *etg, gint row);
+ gint (*get_count) (ETableGroup *etg);
+ void (*increment) (ETableGroup *etg, gint position, gint amount);
+ void (*set_focus) (ETableGroup *etg, EFocus direction, gint view_col);
+ gboolean (*get_focus) (ETableGroup *etg);
+ gint (*get_focus_column) (ETableGroup *etg);
+ ETableCol *(*get_ecol) (ETableGroup *etg);
+
+ void (*thaw) (ETableGroup *etg);
+ gdouble (*get_height) (ETableGroup *etg);
+ gdouble (*get_width) (ETableGroup *etg);
+ void (*set_width) (ETableGroup *etg, gdouble width);
} ETableGroupClass;
-GnomeCanvasItem *e_table_group_new (GnomeCanvasGroup *parent, ETableCol *ecol,
- gboolean open, gboolean transparent);
-void e_table_group_construct (GnomeCanvasGroup *parent, ETableGroup *etg,
- ETableCol *ecol, gboolean open, gboolean transparent);
+void e_table_group_add (ETableGroup *etg,
+ gint row);
+gboolean e_table_group_remove (ETableGroup *etg,
+ gint row);
+gint e_table_group_get_count (ETableGroup *etg);
+void e_table_group_increment (ETableGroup *etg,
+ gint position,
+ gint amount);
+void e_table_group_set_focus (ETableGroup *etg,
+ EFocus direction,
+ gint view_col);
+gboolean e_table_group_get_focus (ETableGroup *etg);
+gint e_table_group_get_focus_column (ETableGroup *etg);
+ETableCol *e_table_group_get_ecol (ETableGroup *etg);
+
+ETableGroup *e_table_group_new (GnomeCanvasGroup *parent,
+ ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model,
+ xmlNode *rules);
+void e_table_group_construct (GnomeCanvasGroup *parent,
+ ETableGroup *etg,
+ ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model);
-void e_table_group_add (ETableGroup *etg, GnomeCanvasItem *child);
+/* For emitting the signal */
+void e_table_group_resize (ETableGroup *etg);
GtkType e_table_group_get_type (void);
-#endif /* _E_TABLE_TREE_H_ */
+#endif /* _E_TABLE_GROUP_H_ */
diff --git a/widgets/e-table/e-table-header-item.c b/widgets/e-table/e-table-header-item.c
index b025664385..6b6146c938 100644
--- a/widgets/e-table/e-table-header-item.c
+++ b/widgets/e-table/e-table-header-item.c
@@ -317,7 +317,7 @@ ethi_drag_motion (GtkObject *canvas, GdkDragContext *context,
{
/* Check if it's the correct ethi */
if (ethi->drag_col == -1)
- return;
+ return FALSE;
gdk_drag_status (context, 0, time);
if (GTK_WIDGET(canvas) == gtk_drag_get_source_widget(context)) {
@@ -372,7 +372,7 @@ ethi_drag_drop (GtkWidget *canvas,
gboolean successful = FALSE;
if (ethi->drag_col == -1)
- return;
+ return FALSE;
if (GTK_WIDGET(canvas) == gtk_drag_get_source_widget(context)) {
if ((x >= ethi->x1) && (x <= (ethi->x1 + ethi->width)) &&
@@ -486,7 +486,6 @@ draw_button (ETableHeaderItem *ethi, ETableCol *col,
{
GdkRectangle clip;
int xtra;
- int arrowx;
gdk_draw_rectangle (
drawable, gc, TRUE,
@@ -541,7 +540,7 @@ draw_button (ETableHeaderItem *ethi, ETableCol *col,
gtk_paint_arrow (gtk_widget_get_style(GTK_WIDGET(GNOME_CANVAS_ITEM(ethi)->canvas)),
drawable,
GTK_STATE_NORMAL,
- GTK_SHADOW_OUT,
+ GTK_SHADOW_IN,
&clip,
GTK_WIDGET(GNOME_CANVAS_ITEM(ethi)->canvas),
"header",
diff --git a/widgets/e-table/e-table-item.c b/widgets/e-table/e-table-item.c
index 130c51a85c..d8ecdf1404 100644
--- a/widgets/e-table/e-table-item.c
+++ b/widgets/e-table/e-table-item.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* E-table-item.c: A GnomeCanvasItem that is a view of an ETableModel.
*
@@ -26,7 +27,7 @@ static GnomeCanvasItemClass *eti_parent_class;
enum {
ROW_SELECTION,
- HEIGHT_CHANGED,
+ RESIZE,
LAST_SIGNAL
};
@@ -36,12 +37,14 @@ enum {
ARG_0,
ARG_TABLE_HEADER,
ARG_TABLE_MODEL,
- ARG_TABLE_X,
- ARG_TABLE_Y,
ARG_TABLE_DRAW_GRID,
ARG_TABLE_DRAW_FOCUS,
ARG_MODE_SPREADSHEET,
- ARG_LENGHT_THRESHOLD
+ ARG_LENGHT_THRESHOLD,
+
+ ARG_WIDTH,
+ ARG_HEIGHT,
+ ARG_HAS_FOCUS
};
static gboolean
@@ -67,7 +70,7 @@ eti_realize_cell_views (ETableItem *eti)
int i;
for (i = 0; i < eti->n_cells; i++)
- e_cell_view_realize (eti->cell_views [i], eti);
+ e_cell_realize (eti->cell_views [i]);
eti->cell_views_realized = 1;
}
@@ -287,13 +290,13 @@ eti_compute_height (ETableItem *eti)
int new_height = eti_get_height (eti);
if (new_height != eti->height){
- double x1, y1, x2, y2;
+ /* double x1, y1, x2, y2;*/
printf ("Emitting!\n");
eti->height = new_height;
eti_update (GNOME_CANVAS_ITEM (eti), NULL, NULL, 0);
- gtk_signal_emit (GTK_OBJECT (eti), eti_signals [HEIGHT_CHANGED]);
+ gtk_signal_emit (GTK_OBJECT (eti), eti_signals [RESIZE]);
}
}
@@ -537,14 +540,6 @@ eti_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
eti_add_table_model (eti, GTK_VALUE_POINTER (*arg));
break;
- case ARG_TABLE_X:
- eti->x1 = GTK_VALUE_DOUBLE (*arg);
- break;
-
- case ARG_TABLE_Y:
- eti->y1 = GTK_VALUE_DOUBLE (*arg);
- break;
-
case ARG_LENGHT_THRESHOLD:
eti->length_threshold = GTK_VALUE_INT (*arg);
break;
@@ -565,6 +560,27 @@ eti_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
}
static void
+eti_get_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ GnomeCanvasItem *item;
+ ETableItem *eti;
+
+ item = GNOME_CANVAS_ITEM (o);
+ eti = E_TABLE_ITEM (o);
+
+ switch (arg_id){
+ case ARG_WIDTH:
+ GTK_VALUE_DOUBLE (*arg) = eti->width;
+ break;
+ case ARG_HEIGHT:
+ GTK_VALUE_DOUBLE (*arg) = eti->height;
+ break;
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ }
+}
+
+static void
eti_init (GnomeCanvasItem *item)
{
ETableItem *eti = E_TABLE_ITEM (item);
@@ -576,7 +592,7 @@ eti_init (GnomeCanvasItem *item)
eti->height = 0;
eti->length_threshold = -1;
- eti->renderers_can_change_size = 0;
+ eti->renderers_can_change_size = 1;
eti->selection_mode = GTK_SELECTION_SINGLE;
}
@@ -878,31 +894,34 @@ find_cell (ETableItem *eti, double x, double y, int *col_res, int *row_res, doub
}
static void
-eti_cursor_move_left (ETableItem *eti)
+eti_cursor_move (ETableItem *eti, gint row, gint column)
{
e_table_item_leave_edit (eti);
- e_table_item_focus (eti, eti->focused_col - 1, eti->focused_row);
+ e_table_item_focus (eti, column, row);
+}
+
+static void
+eti_cursor_move_left (ETableItem *eti)
+{
+ eti_cursor_move(eti, eti->focused_row, eti->focused_col - 1);
}
static void
eti_cursor_move_right (ETableItem *eti)
{
- e_table_item_leave_edit (eti);
- e_table_item_focus (eti, eti->focused_col + 1, eti->focused_row);
+ eti_cursor_move(eti, eti->focused_row, eti->focused_col + 1);
}
static void
eti_cursor_move_up (ETableItem *eti)
{
- e_table_item_leave_edit (eti);
- e_table_item_focus (eti, eti->focused_col, eti->focused_row - 1);
+ eti_cursor_move(eti, eti->focused_row - 1, eti->focused_col);
}
static void
eti_cursor_move_down (ETableItem *eti)
{
- e_table_item_leave_edit (eti);
- e_table_item_focus (eti, eti->focused_col, eti->focused_row + 1);
+ eti_cursor_move(eti, eti->focused_row + 1, eti->focused_col);
}
static int
@@ -911,6 +930,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
ETableItem *eti = E_TABLE_ITEM (item);
ECellView *ecell_view;
ETableCol *ecol;
+ gint return_val = TRUE;
switch (e->type){
case GDK_BUTTON_PRESS:
@@ -982,66 +1002,66 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
if (eti->focused_col > 0)
eti_cursor_move_left (eti);
-
- return TRUE;
-
+ break;
+
case GDK_Right:
if (!eti->mode_spreadsheet && eti_editing (eti))
break;
- if ((eti->focused_col + 1) < eti->cols)
+ if (eti->focused_col < eti->cols - 1)
eti_cursor_move_right (eti);
- return TRUE;
-
+ break;
+
case GDK_Up:
if (eti->focused_row > 0)
eti_cursor_move_up (eti);
- return TRUE;
+ else
+ return_val = FALSE;
+ break;
case GDK_Down:
if ((eti->focused_row + 1) < eti->rows)
eti_cursor_move_down (eti);
-
- return TRUE;
+ else
+ return_val = FALSE;
+ break;
case GDK_Tab:
+ case GDK_KP_Tab:
+ case GDK_ISO_Left_Tab:
if ((e->key.state & GDK_SHIFT_MASK) != 0){
/* shift tab */
if (eti->focused_col > 0)
eti_cursor_move_left (eti);
- else if (eti->focused_row > 0){
- e_table_item_leave_edit (eti);
- e_table_item_focus (eti, eti->cols - 1, eti->focused_row - 1);
- } else {
- /* FIXME: request focus leave backward */
- }
+ else if (eti->focused_row > 0)
+ eti_cursor_move(eti, eti->focused_row - 1, eti->cols - 1);
+ else
+ return_val = FALSE;
} else {
- if ((eti->focused_col + 1) < eti->cols)
+ if (eti->focused_col < eti->cols - 1)
eti_cursor_move_right (eti);
- else if ((eti->focused_row + 1) < eti->rows){
- e_table_item_leave_edit (eti);
- e_table_item_focus (eti, 0, eti->rows - 1);
- } else {
- /* FIXME: request focus leave forward */
- }
+ else if (eti->focused_row < eti->rows - 1)
+ eti_cursor_move(eti, eti->focused_row + 1, 0);
+ else
+ return_val = FALSE;
}
break;
default:
if (!eti_editing (eti)){
if ((e->key.state & (GDK_MOD1_MASK | GDK_CONTROL_MASK)) != 0)
- return 0;
+ return_val = FALSE;
if (!(e->key.keyval >= 0x20 && e->key.keyval <= 0xff))
- return 0;
+ return_val = FALSE;
}
- }
- ecol = e_table_header_get_column (eti->header, eti->focused_col);
- ecell_view = eti->cell_views [eti->focused_col];
- e_cell_event (ecell_view, e, ecol->col_idx, eti->focused_col, eti->focused_row);
+ ecol = e_table_header_get_column (eti->header, eti->focused_col);
+ ecell_view = eti->cell_views [eti->focused_col];
+ e_cell_event (ecell_view, e, ecol->col_idx, eti->focused_col, eti->focused_row);
+ }
break;
-
+
case GDK_KEY_RELEASE:
if (eti->focused_col == -1)
return FALSE;
@@ -1053,8 +1073,15 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
}
break;
+ case GDK_FOCUS_CHANGE:
+ if (e->focus_change.in) {
+ } else {
+ e_table_item_leave_edit (eti);
+ e_table_item_unfocus (eti);
+ }
+
default:
- return FALSE;
+ return_val = FALSE;
}
return TRUE;
}
@@ -1084,6 +1111,7 @@ eti_class_init (GtkObjectClass *object_class)
object_class->destroy = eti_destroy;
object_class->set_arg = eti_set_arg;
+ object_class->get_arg = eti_get_arg;
item_class->update = eti_update;
item_class->realize = eti_realize;
@@ -1099,10 +1127,6 @@ eti_class_init (GtkObjectClass *object_class)
GTK_ARG_WRITABLE, ARG_TABLE_HEADER);
gtk_object_add_arg_type ("ETableItem::ETableModel", GTK_TYPE_POINTER,
GTK_ARG_WRITABLE, ARG_TABLE_MODEL);
- gtk_object_add_arg_type ("ETableItem::x", GTK_TYPE_DOUBLE,
- GTK_ARG_WRITABLE, ARG_TABLE_X);
- gtk_object_add_arg_type ("ETableItem::y", GTK_TYPE_DOUBLE,
- GTK_ARG_WRITABLE, ARG_TABLE_Y);
gtk_object_add_arg_type ("ETableItem::drawgrid", GTK_TYPE_BOOL,
GTK_ARG_WRITABLE, ARG_TABLE_DRAW_GRID);
gtk_object_add_arg_type ("ETableItem::drawfocus", GTK_TYPE_BOOL,
@@ -1110,6 +1134,13 @@ eti_class_init (GtkObjectClass *object_class)
gtk_object_add_arg_type ("ETableItem::spreadsheet", GTK_TYPE_BOOL,
GTK_ARG_WRITABLE, ARG_MODE_SPREADSHEET);
+ gtk_object_add_arg_type ("ETableItem::width", GTK_TYPE_DOUBLE,
+ GTK_ARG_READWRITE, ARG_WIDTH);
+ gtk_object_add_arg_type ("ETableItem::height", GTK_TYPE_DOUBLE,
+ GTK_ARG_READABLE, ARG_HEIGHT);
+ gtk_object_add_arg_type ("ETableItem::has_focus", GTK_TYPE_BOOL,
+ GTK_ARG_READWRITE, ARG_HAS_FOCUS);
+
eti_signals [ROW_SELECTION] =
gtk_signal_new ("row_selection",
GTK_RUN_LAST,
@@ -1118,11 +1149,11 @@ eti_class_init (GtkObjectClass *object_class)
gtk_marshal_NONE__INT_INT,
GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
- eti_signals [HEIGHT_CHANGED] =
- gtk_signal_new ("height_changed",
+ eti_signals [RESIZE] =
+ gtk_signal_new ("resize",
GTK_RUN_LAST,
object_class->type,
- GTK_SIGNAL_OFFSET (ETableItemClass, height_changed),
+ GTK_SIGNAL_OFFSET (ETableItemClass, resize),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
@@ -1192,6 +1223,16 @@ e_table_item_unfocus (ETableItem *eti)
eti->focused_row = -1;
}
+gint
+e_table_item_get_focused_column (ETableItem *eti)
+{
+ g_return_val_if_fail (eti != NULL, -1);
+ g_return_val_if_fail (E_IS_TABLE_ITEM (eti), -1);
+
+ return eti->focused_col;
+}
+
+
const GSList *
e_table_item_get_selection (ETableItem *eti)
{
diff --git a/widgets/e-table/e-table-item.h b/widgets/e-table/e-table-item.h
index f19819f2fc..635dc76922 100644
--- a/widgets/e-table/e-table-item.h
+++ b/widgets/e-table/e-table-item.h
@@ -68,7 +68,7 @@ typedef struct {
GnomeCanvasItemClass parent_class;
void (*row_selection) (ETableItem *eti, int row, gboolean selected);
- void (*height_changed) (ETableItem *eti);
+ void (*resize) (ETableItem *eti);
} ETableItemClass;
GtkType e_table_item_get_type (void);
@@ -79,6 +79,8 @@ GtkType e_table_item_get_type (void);
void e_table_item_focus (ETableItem *eti, int col, int row);
void e_table_item_unfocus (ETableItem *eti);
+gint e_table_item_get_focused_column (ETableItem *eti);
+
/*
* Selection
*/
diff --git a/widgets/e-table/e-table-model.c b/widgets/e-table/e-table-model.c
index 9e397710ef..e84e6da4d3 100644
--- a/widgets/e-table/e-table-model.c
+++ b/widgets/e-table/e-table-model.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* e-table-model.c: a Table Model
*
@@ -173,4 +174,23 @@ e_table_model_cell_changed (ETableModel *e_table_model, int col, int row)
e_table_model_signals [MODEL_CELL_CHANGED], col, row);
}
+void
+e_table_model_freeze (ETableModel *e_table_model)
+{
+ g_return_if_fail (e_table_model != NULL);
+ g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
+
+ e_table_model->frozen = TRUE;
+ return ETM_CLASS (e_table_model)->thaw (e_table_model);
+}
+void
+e_table_model_thaw (ETableModel *e_table_model)
+{
+ g_return_if_fail (e_table_model != NULL);
+ g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
+
+ e_table_model->frozen = FALSE;
+ if (ETM_CLASS(e_table_model)->thaw)
+ ETM_CLASS (e_table_model)->thaw (e_table_model);
+}
diff --git a/widgets/e-table/e-table-model.h b/widgets/e-table/e-table-model.h
index 2d08f3744e..9f2dbbf87c 100644
--- a/widgets/e-table/e-table-model.h
+++ b/widgets/e-table/e-table-model.h
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#ifndef _E_TABLE_MODEL_H_
#define _E_TABLE_MODEL_H_
@@ -11,6 +12,8 @@
typedef struct {
GtkObject base;
+
+ guint frozen : 1;
} ETableModel;
typedef struct {
@@ -24,7 +27,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);
-
+ void (*thaw) (ETableModel *etm);
/*
* Signals
*/
@@ -48,6 +51,9 @@ void *e_table_model_value_at (ETableModel *e_table_model, int col,
void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, const void *data);
gboolean e_table_model_is_cell_editable (ETableModel *e_table_model, int col, int row);
+void e_table_model_freeze (ETableModel *e_table_model);
+void e_table_model_thaw (ETableModel *e_table_model);
+
/*
* Routines for emitting signals on the e_table
*/
diff --git a/widgets/e-table/e-table-simple.c b/widgets/e-table/e-table-simple.c
index 38e1dd8eb0..1f64d08f39 100644
--- a/widgets/e-table/e-table-simple.c
+++ b/widgets/e-table/e-table-simple.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* e-table-model.c: a simple table model implementation that uses function
* pointers to simplify the creation of new, exotic and colorful tables in
@@ -55,6 +56,14 @@ simple_is_cell_editable (ETableModel *etm, int col, int row)
}
static void
+simple_thaw (ETableModel *etm)
+{
+ ETableSimple *simple = (ETableSimple *)etm;
+
+ simple->thaw (etm, simple->data);
+}
+
+static void
e_table_simple_class_init (GtkObjectClass *object_class)
{
ETableModelClass *model_class = (ETableModelClass *) object_class;
@@ -64,6 +73,7 @@ e_table_simple_class_init (GtkObjectClass *object_class)
model_class->value_at = simple_value_at;
model_class->set_value_at = simple_set_value_at;
model_class->is_cell_editable = simple_is_cell_editable;
+ model_class->thaw = simple_thaw;
}
GtkType
@@ -95,6 +105,7 @@ e_table_simple_new (ETableSimpleColumnCountFn col_count,
ETableSimpleValueAtFn value_at,
ETableSimpleSetValueAtFn set_value_at,
ETableSimpleIsCellEditableFn is_cell_editable,
+ ETableSimpleThawFn thaw,
void *data)
{
ETableSimple *et;
@@ -106,6 +117,7 @@ e_table_simple_new (ETableSimpleColumnCountFn col_count,
et->value_at = value_at;
et->set_value_at = set_value_at;
et->is_cell_editable = is_cell_editable;
+ et->thaw = thaw;
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 d890245386..a3164eefc0 100644
--- a/widgets/e-table/e-table-simple.h
+++ b/widgets/e-table/e-table-simple.h
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#ifndef _E_TABLE_SIMPLE_H_
#define _E_TABLE_SIMPLE_H_
@@ -8,6 +9,7 @@ typedef int (*ETableSimpleRowCountFn) (ETableModel *etm, void *dat
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 void (*ETableSimpleThawFn) (ETableModel *etm, void *data);
typedef struct {
ETableModel parent;
@@ -17,6 +19,7 @@ typedef struct {
ETableSimpleValueAtFn value_at;
ETableSimpleSetValueAtFn set_value_at;
ETableSimpleIsCellEditableFn is_cell_editable;
+ ETableSimpleThawFn thaw;
void *data;
} ETableSimple;
@@ -31,6 +34,7 @@ ETableModel *e_table_simple_new (ETableSimpleColumnCountFn col_count,
ETableSimpleValueAtFn value_at,
ETableSimpleSetValueAtFn set_value_at,
ETableSimpleIsCellEditableFn is_cell_editable,
+ ETableSimpleThawFn thaw,
void *data);
#endif /* _E_TABLE_SIMPLE_H_ */
diff --git a/widgets/e-table/e-table-sorted.h b/widgets/e-table/e-table-sorted.h
index 2ec52df2e7..92bd8d1522 100644
--- a/widgets/e-table/e-table-sorted.h
+++ b/widgets/e-table/e-table-sorted.h
@@ -19,7 +19,7 @@ typedef struct {
} ETableSorted;
typedef struct {
- ETableSubset parent_class;
+ ETableSubsetClass parent_class;
} ETableSortedClass;
GtkType e_table_sorted_get_type (void);
diff --git a/widgets/e-table/e-table-subset-variable.c b/widgets/e-table/e-table-subset-variable.c
new file mode 100644
index 0000000000..76da03c44f
--- /dev/null
+++ b/widgets/e-table/e-table-subset-variable.c
@@ -0,0 +1,112 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * E-table-subset.c: Implements a table that contains a subset of another table.
+ *
+ * Author:
+ * Miguel de Icaza (miguel@gnu.org)
+ *
+ * (C) 1999 Helix Code, Inc.
+ */
+#include <config.h>
+#include <stdlib.h>
+#include <gtk/gtksignal.h>
+#include <string.h>
+#include "e-util/e-util.h"
+#include "e-table-subset-variable.h"
+
+#define PARENT_TYPE E_TABLE_SUBSET_TYPE
+
+#define INCREMENT_AMOUNT 10
+
+static ETableModelClass *etssv_parent_class;
+
+static void
+etssv_class_init (GtkObjectClass *klass)
+{
+ etssv_parent_class = gtk_type_class (PARENT_TYPE);
+}
+
+E_MAKE_TYPE(e_table_subset_variable, "ETableSubsetVariable", ETableSubsetVariable, etssv_class_init, NULL, PARENT_TYPE);
+
+ETableModel *
+e_table_subset_variable_construct (ETableSubsetVariable *etssv,
+ ETableModel *source)
+{
+ if ( e_table_subset_construct(E_TABLE_SUBSET(etssv), source, 1) == NULL )
+ return NULL;
+ E_TABLE_SUBSET(etssv)->n_map = 0;
+
+ return E_TABLE_MODEL (etssv);
+}
+
+ETableModel *
+e_table_subset_variable_new (ETableModel *source)
+{
+ ETableSubsetVariable *etssv = gtk_type_new (E_TABLE_SUBSET_VARIABLE_TYPE);
+
+ if (e_table_subset_variable_construct (etssv, source) == NULL){
+ gtk_object_destroy (GTK_OBJECT (etssv));
+ return NULL;
+ }
+
+ return (ETableModel *) etssv;
+}
+
+void
+e_table_subset_variable_add (ETableSubsetVariable *etssv,
+ gint row)
+{
+ ETableModel *etm = E_TABLE_MODEL(etssv);
+ ETableSubset *etss = E_TABLE_SUBSET(etssv);
+
+ if ( etss->n_map + 1 > etssv->n_vals_allocated )
+ etss->map_table = g_realloc(etss->map_table, (etssv->n_vals_allocated + INCREMENT_AMOUNT) * sizeof(int));
+ etss->map_table[etss->n_map++] = row;
+ if ( !etm->frozen )
+ e_table_model_changed(etm);
+}
+
+gboolean
+e_table_subset_variable_remove (ETableSubsetVariable *etssv,
+ gint row)
+{
+ ETableModel *etm = E_TABLE_MODEL(etssv);
+ ETableSubset *etss = E_TABLE_SUBSET(etssv);
+ int i;
+
+ for ( i = 0; i < etss->n_map; i++ ) {
+ if (etss->map_table[i] == row) {
+ memmove(etss->map_table + i, etss->map_table + i + 1, (etss->n_map - i - 1) * sizeof(int));
+ etss->n_map --;
+ if ( !etm->frozen )
+ e_table_model_changed(etm);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void
+e_table_subset_variable_increment (ETableSubsetVariable *etssv,
+ gint position,
+ gint amount)
+{
+ int i;
+ ETableSubset *etss = E_TABLE_SUBSET(etssv);
+ for ( i = 0; i < etss->n_map; i++ ) {
+ if ( etss->map_table[i] > position )
+ etss->map_table[i] += amount;
+ }
+}
+
+void
+e_table_subset_variable_set_allocation (ETableSubsetVariable *etssv,
+ gint total)
+{
+ ETableSubset *etss = E_TABLE_SUBSET(etssv);
+ if ( total <= 0 )
+ total = 1;
+ if ( total > etss->n_map ) {
+ etss->map_table = g_realloc(etss->map_table, total * sizeof(int));
+ }
+}
diff --git a/widgets/e-table/e-table-subset-variable.h b/widgets/e-table/e-table-subset-variable.h
new file mode 100644
index 0000000000..9755fb2477
--- /dev/null
+++ b/widgets/e-table/e-table-subset-variable.h
@@ -0,0 +1,38 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+#ifndef _E_TABLE_SUBSET_VARIABLE_H_
+#define _E_TABLE_SUBSET_VARIABLE_H_
+
+#include <gtk/gtkobject.h>
+#include "e-table-subset.h"
+
+#define E_TABLE_SUBSET_VARIABLE_TYPE (e_table_subset_variable_get_type ())
+#define E_TABLE_SUBSET_VARIABLE(o) (GTK_CHECK_CAST ((o), E_TABLE_SUBSET_VARIABLE_TYPE, ETableSubsetVariable))
+#define E_TABLE_SUBSET_VARIABLE_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_SUBSET_VARIABLE_TYPE, ETableSubsetVariableClass))
+#define E_IS_TABLE_SUBSET_VARIABLE(o) (GTK_CHECK_TYPE ((o), E_TABLE_SUBSET_VARIABLE_TYPE))
+#define E_IS_TABLE_SUBSET_VARIABLE_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_SUBSET_VARIABLE_TYPE))
+
+typedef struct {
+ ETableSubset base;
+
+ int n_vals_allocated;
+} ETableSubsetVariable;
+
+typedef struct {
+ ETableSubsetClass parent_class;
+} ETableSubsetVariableClass;
+
+GtkType e_table_subset_variable_get_type (void);
+ETableModel *e_table_subset_variable_new (ETableModel *etm);
+ETableModel *e_table_subset_variable_construct (ETableSubsetVariable *etssv,
+ ETableModel *source);
+void e_table_subset_variable_add (ETableSubsetVariable *ets,
+ gint row);
+gboolean e_table_subset_variable_remove (ETableSubsetVariable *ets,
+ gint row);
+void e_table_subset_variable_increment (ETableSubsetVariable *ets,
+ gint position,
+ gint amount);
+void e_table_subset_variable_set_allocation (ETableSubsetVariable *ets,
+ gint total);
+#endif /* _E_TABLE_SUBSET_VARIABLE_H_ */
+
diff --git a/widgets/e-table/e-table-subset.c b/widgets/e-table/e-table-subset.c
index a9e4a5c5a4..a09d221980 100644
--- a/widgets/e-table/e-table-subset.c
+++ b/widgets/e-table/e-table-subset.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* E-table-subset.c: Implements a table that contains a subset of another table.
*
@@ -71,6 +72,12 @@ etss_is_cell_editable (ETableModel *etm, int col, int row)
}
static void
+etss_thaw (ETableModel *etm)
+{
+ e_table_model_changed (etm);
+}
+
+static void
etss_class_init (GtkObjectClass *klass)
{
ETableModelClass *table_class = (ETableModelClass *) klass;
@@ -84,6 +91,7 @@ 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->thaw = etss_thaw;
}
E_MAKE_TYPE(e_table_subset, "ETableSubset", ETableSubset, etss_class_init, NULL, PARENT_TYPE);
@@ -91,20 +99,23 @@ E_MAKE_TYPE(e_table_subset, "ETableSubset", ETableSubset, etss_class_init, NULL,
static void
etss_proxy_model_changed (ETableModel *etm, ETableSubset *etss)
{
- e_table_model_changed (E_TABLE_MODEL (etss));
+ if ( !E_TABLE_MODEL(etss)->frozen )
+ e_table_model_changed (E_TABLE_MODEL (etss));
}
static void
etss_proxy_model_row_changed (ETableModel *etm, int row, ETableSubset *etss)
{
- 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] == row){
- e_table_model_row_changed (E_TABLE_MODEL (etss), i);
- return;
+ if ( !E_TABLE_MODEL(etss)->frozen ) {
+ 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] == row){
+ e_table_model_row_changed (E_TABLE_MODEL (etss), i);
+ return;
+ }
}
}
}
@@ -112,14 +123,16 @@ etss_proxy_model_row_changed (ETableModel *etm, int row, ETableSubset *etss)
static void
etss_proxy_model_cell_changed (ETableModel *etm, int col, int row, ETableSubset *etss)
{
- 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] == row){
- e_table_model_cell_changed (E_TABLE_MODEL (etss), col, i);
- return;
+ if ( !E_TABLE_MODEL(etss)->frozen ) {
+ 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] == row){
+ e_table_model_cell_changed (E_TABLE_MODEL (etss), col, i);
+ return;
+ }
}
}
}
@@ -130,7 +143,7 @@ e_table_subset_construct (ETableSubset *etss, ETableModel *source, int nvals)
unsigned int *buffer;
int i;
- buffer = (unsigned int *) malloc (sizeof (unsigned int) * nvals);
+ buffer = (unsigned int *) g_malloc (sizeof (unsigned int) * nvals);
if (buffer == NULL)
return NULL;
etss->map_table = buffer;
diff --git a/widgets/e-table/e-table-subset.h b/widgets/e-table/e-table-subset.h
index 314f28aea6..d8af1696f5 100644
--- a/widgets/e-table/e-table-subset.h
+++ b/widgets/e-table/e-table-subset.h
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#ifndef _E_TABLE_SUBSET_H_
#define _E_TABLE_SUBSET_H_
diff --git a/widgets/e-table/e-table.c b/widgets/e-table/e-table.c
index 46531113e4..551ef52227 100644
--- a/widgets/e-table/e-table.c
+++ b/widgets/e-table/e-table.c
@@ -1,5 +1,6 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * E-table-view.c: A graphical view of a Table.
+ * E-table.c: A graphical view of a Table.
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
@@ -16,7 +17,9 @@
#include <stdio.h>
#include <libgnomeui/gnome-canvas.h>
#include <gtk/gtksignal.h>
+#include <gnome-xml/parser.h>
#include "e-util/e-util.h"
+#include "e-util/e-xml-utils.h"
#include "e-table.h"
#include "e-table-header-item.h"
#include "e-table-subset.h"
@@ -40,8 +43,6 @@ et_destroy (GtkObject *object)
gtk_object_unref (GTK_OBJECT (et->full_header));
gtk_object_unref (GTK_OBJECT (et->header));
- g_free (et->group_spec);
-
(*e_table_parent_class->destroy)(object);
}
@@ -56,19 +57,16 @@ e_table_init (GtkObject *object)
}
static ETableHeader *
-e_table_make_header (ETable *e_table, ETableHeader *full_header, const char *cols)
+e_table_make_header (ETable *e_table, ETableHeader *full_header, xmlNode *xmlColumns)
{
ETableHeader *nh;
- char *copy = alloca (strlen (cols) + 1);
- char *p, *state;
+ xmlNode *column;
const int max_cols = e_table_header_count (full_header);
nh = e_table_header_new ();
- strcpy (copy, cols);
- while ((p = strtok_r (copy, ",", &state)) != NULL){
- int col = atoi (p);
+ for (column = xmlColumns->childs; column; column = column->next) {
+ int col = atoi (column->childs->content);
- copy = NULL;
if (col >= max_cols)
continue;
@@ -113,6 +111,7 @@ e_table_setup_header (ETable *e_table)
}
+#if 0
typedef struct {
void *value;
GArray *array;
@@ -201,7 +200,7 @@ e_table_make_subtables (ETableModel *model, GArray *groups)
return (ETableModel **) tables;
}
-
+#endif
typedef struct _Node Node;
struct _Node {
@@ -212,7 +211,7 @@ struct _Node {
guint is_leaf:1;
};
-
+#if 0
static Node *
leaf_new (GnomeCanvasItem *table_item, ETableModel *table_model, Node *parent)
{
@@ -335,8 +334,9 @@ e_table_create_nodes (ETable *e_table, ETableModel *model, ETableHeader *header,
groups = e_table_create_groups (model, key_col, ecol->compare);
tables = e_table_make_subtables (e_table->model, groups);
e_table_destroy_groups (groups);
-
- group_item = e_table_group_new (root, ecol, TRUE, parent == NULL);
+ group_item = gnome_canvas_item_new (root,
+ e_table_group_get_type(),
+ "columns", ecol, TRUE, parent == NULL);
group = node_new (group_item, model, parent);
for (i = 0; tables [i] != NULL; i++){
@@ -347,8 +347,9 @@ e_table_create_nodes (ETable *e_table, ETableModel *model, ETableHeader *header,
GnomeCanvasItem *item_leaf_header;
Node *leaf_header;
+ /* FIXME *//*
item_leaf_header = e_table_group_new (
- GNOME_CANVAS_GROUP (group_item), ecol, TRUE, FALSE);
+ GNOME_CANVAS_GROUP (group_item), ecol, TRUE, FALSE);*/
leaf_header = node_new (item_leaf_header, tables [i], group);
e_table_create_leaf (e_table, tables [i], leaf_header);
@@ -424,6 +425,14 @@ static GnomeCanvasClass *e_table_canvas_parent_class;
static void
e_table_canvas_realize (GtkWidget *widget)
{
+#if 0
+ GnomeCanvasItem *group_item;
+
+ group_item = gnome_canvas_item_new (root,
+ e_table_group_get_type(),
+ "header", E_TABLE, TRUE, parent == NULL);
+
+
ETableCanvas *e_table_canvas = (ETableCanvas *) widget;
ETable *e_table = e_table_canvas->e_table;
int *groups;
@@ -433,6 +442,8 @@ e_table_canvas_realize (GtkWidget *widget)
groups = group_spec_to_desc (e_table->group_spec);
+
+
leaf = e_table_create_nodes (
e_table, e_table->model,
e_table->header, GNOME_CANVAS_GROUP (e_table->root), 0, groups);
@@ -440,6 +451,7 @@ e_table_canvas_realize (GtkWidget *widget)
if (groups)
g_free (groups);
+#endif
}
static void
@@ -496,33 +508,75 @@ e_table_canvas_new (ETable *e_table)
return GNOME_CANVAS (e_table_canvas);
}
+#endif
static void
-table_canvas_size_alocate (GtkWidget *widget, GtkAllocation *alloc, ETable *e_table)
+table_canvas_size_allocate (GtkWidget *widget, GtkAllocation *alloc, ETable *e_table)
{
+ gdouble height;
+ gdouble width;
+ gtk_object_get(GTK_OBJECT(e_table->group),
+ "height", &height,
+ NULL);
gnome_canvas_set_scroll_region (
GNOME_CANVAS (e_table->table_canvas),
- 0, 0, alloc->width, alloc->height);
+ 0, 0, alloc->width, MAX(height, alloc->height));
+ width = alloc->width;
+ gtk_object_set(GTK_OBJECT(e_table->group),
+ "width", width,
+ NULL);
}
static void
-e_table_setup_table (ETable *e_table)
+e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *header, ETableModel *model, xmlNode *xml_grouping)
{
- e_table->table_canvas = e_table_canvas_new (e_table);
+ e_table->table_canvas = GNOME_CANVAS(gnome_canvas_new ());
gtk_signal_connect (
GTK_OBJECT (e_table->table_canvas), "size_allocate",
- GTK_SIGNAL_FUNC (table_canvas_size_alocate), e_table);
+ GTK_SIGNAL_FUNC (table_canvas_size_allocate), e_table);
gtk_widget_show (GTK_WIDGET (e_table->table_canvas));
gtk_table_attach (
GTK_TABLE (e_table), GTK_WIDGET (e_table->table_canvas),
0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
+
+ e_table->group = e_table_group_new(GNOME_CANVAS_GROUP(e_table->table_canvas->root),
+ full_header,
+ header,
+ model,
+ xml_grouping->childs);
+
+}
+
+static void
+e_table_fill_table (ETable *e_table, ETableModel *model)
+{
+ int count;
+ int i;
+ count = e_table_model_row_count(model);
+ gtk_object_set(GTK_OBJECT(e_table->group),
+ "frozen", TRUE,
+ NULL);
+ for ( i = 0; i < count; i++ ) {
+ e_table_group_add(e_table->group, i);
+ }
+ gtk_object_set(GTK_OBJECT(e_table->group),
+ "frozen", FALSE,
+ NULL);
}
void
e_table_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm,
- const char *cols_spec, const char *group_spec)
+ const char *spec)
{
+ xmlDoc *xmlSpec;
+ xmlNode *xmlRoot;
+ xmlNode *xmlColumns;
+ xmlNode *xmlGrouping;
+
+ char *copy;
+ copy = g_strdup(spec);
+
GTK_TABLE (e_table)->homogeneous = FALSE;
gtk_table_resize (GTK_TABLE (e_table), 1, 2);
@@ -532,24 +586,29 @@ e_table_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm,
e_table->model = etm;
gtk_object_ref (GTK_OBJECT (etm));
+
+ xmlSpec = xmlParseMemory(copy, strlen(copy) + 1);
+ e_table->specification = xmlSpec;
- e_table->header = e_table_make_header (e_table, full_header, cols_spec);
+ xmlRoot = xmlDocGetRootElement(xmlSpec);
+ xmlColumns = e_xml_get_child_by_name(xmlRoot, "columns-shown");
+ xmlGrouping = e_xml_get_child_by_name(xmlRoot, "grouping");
+
+ e_table->header = e_table_make_header (e_table, full_header, xmlColumns);
e_table_setup_header (e_table);
- e_table_setup_table (e_table);
-
- e_table->group_spec = g_strdup (group_spec);
-
+ e_table_setup_table (e_table, full_header, e_table->header, etm, xmlGrouping);
+ e_table_fill_table (e_table, etm);
}
GtkWidget *
-e_table_new (ETableHeader *full_header, ETableModel *etm, const char *cols_spec, const char *group_spec)
+e_table_new (ETableHeader *full_header, ETableModel *etm, const char *spec)
{
ETable *e_table;
e_table = gtk_type_new (e_table_get_type ());
- e_table_construct (e_table, full_header, etm, cols_spec, group_spec);
+ e_table_construct (e_table, full_header, etm, spec);
return (GtkWidget *) e_table;
}
diff --git a/widgets/e-table/e-table.h b/widgets/e-table/e-table.h
index 63c131324f..a372d8042c 100644
--- a/widgets/e-table/e-table.h
+++ b/widgets/e-table/e-table.h
@@ -1,10 +1,13 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#ifndef _E_TABLE_H_
#define _E_TABLE_H_
#include <libgnomeui/gnome-canvas.h>
#include <gtk/gtktable.h>
+#include <gnome-xml/tree.h>
#include "e-table-model.h"
#include "e-table-header.h"
+#include "e-table-group.h"
BEGIN_GNOME_DECLS
@@ -21,15 +24,17 @@ typedef struct {
ETableHeader *full_header, *header;
+ ETableGroup *group;
+
GnomeCanvas *header_canvas, *table_canvas;
GnomeCanvasItem *header_item, *root;
+
+ xmlDoc *specification;
guint draw_grid:1;
guint draw_focus:1;
guint spreadsheet:1;
-
- char *group_spec;
} ETable;
typedef struct {
@@ -38,9 +43,9 @@ typedef struct {
GtkType e_table_get_type (void);
void e_table_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm,
- const char *cols_spec, const char *group_spec);
+ const char *spec);
GtkWidget *e_table_new (ETableHeader *full_header, ETableModel *etm,
- const char *cols_spec, const char *group_spec);
+ const char *spec);
END_GNOME_DECLS
diff --git a/widgets/e-table/test-check.c b/widgets/e-table/test-check.c
index 380da8048e..a6a59788ad 100644
--- a/widgets/e-table/test-check.c
+++ b/widgets/e-table/test-check.c
@@ -13,6 +13,7 @@
#include "e-table-header-item.h"
#include "e-table-item.h"
#include "e-util/e-cursors.h"
+#include "e-util/e-canvas-utils.h"
#include "e-cell-text.h"
#include "e-cell-checkbox.h"
@@ -79,6 +80,12 @@ is_cell_editable (ETableModel *etc, int col, int row, void *data)
}
static void
+thaw (ETableModel *etc, void *data)
+{
+ e_table_model_changed(etc);
+}
+
+static void
set_canvas_size (GnomeCanvas *canvas, GtkAllocation *alloc)
{
gnome_canvas_set_scroll_region (canvas, 0, 0, alloc->width, alloc->height);
@@ -93,13 +100,14 @@ check_test (void)
ETableCol *col_0, *col_1;
ECell *cell_left_just, *cell_image_check;
GdkPixbuf *pixbuf;
+ GnomeCanvasItem *item;
gtk_widget_push_visual (gdk_rgb_get_visual ());
gtk_widget_push_colormap (gdk_rgb_get_cmap ());
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
- set_value_at, is_cell_editable, NULL);
+ set_value_at, is_cell_editable, thaw, NULL);
/*
* Header
@@ -137,21 +145,15 @@ check_test (void)
"y", 0,
NULL);
- gnome_canvas_item_new (
+ item = gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_item_get_type (),
"ETableHeader", e_table_header,
"ETableModel", e_table_model,
- "x", (double) 0,
- "y", (double) 30,
"drawgrid", TRUE,
"drawfocus", TRUE,
"spreadsheet", TRUE,
NULL);
-
+ e_canvas_item_move_absolute(item, 0, 30);
}
-
-
-
-
diff --git a/widgets/e-table/test-cols.c b/widgets/e-table/test-cols.c
index 3fe17ae555..adc9ed6c20 100644
--- a/widgets/e-table/test-cols.c
+++ b/widgets/e-table/test-cols.c
@@ -8,6 +8,7 @@
#include <stdio.h>
#include <string.h>
#include <gnome.h>
+#include "e-util/e-canvas-utils.h"
#include "e-util/e-cursors.h"
#include "e-table-simple.h"
#include "e-table-header.h"
@@ -84,6 +85,12 @@ set_canvas_size (GnomeCanvas *canvas, GtkAllocation *alloc)
gnome_canvas_set_scroll_region (canvas, 0, 0, alloc->width, alloc->height);
}
+static void
+thaw (ETableModel *etc, void *data)
+{
+ e_table_model_changed(etc);
+}
+
void
multi_cols_test (void)
{
@@ -92,13 +99,14 @@ multi_cols_test (void)
ETableHeader *e_table_header, *e_table_header_multiple;
ETableCol *col_0, *col_1;
ECell *cell_left_just, *cell_image_toggle;
+ GnomeCanvasItem *item;
gtk_widget_push_visual (gdk_rgb_get_visual ());
gtk_widget_push_colormap (gdk_rgb_get_cmap ());
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
- set_value_at, is_cell_editable, NULL);
+ set_value_at, is_cell_editable, thaw, NULL);
/*
* Header
@@ -157,17 +165,17 @@ multi_cols_test (void)
"y", 0,
NULL);
- gnome_canvas_item_new (
+ item = gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_item_get_type (),
"ETableHeader", e_table_header,
"ETableModel", e_table_model,
- "x", (double) 0,
- "y", (double) 30,
"drawgrid", TRUE,
"drawfocus", TRUE,
"spreadsheet", TRUE,
NULL);
+
+ e_canvas_item_move_absolute(item, 0, 30);
gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
@@ -176,18 +184,16 @@ multi_cols_test (void)
"x", 300,
"y", 0,
NULL);
- gnome_canvas_item_new (
+ item = gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_item_get_type (),
"ETableHeader", e_table_header_multiple,
"ETableModel", e_table_model,
- "x", (double) 300,
- "y", (double) 30,
"drawgrid", TRUE,
"drawfocus", TRUE,
"spreadsheet", TRUE,
NULL);
-
+ e_canvas_item_move_absolute(item, 300, 30);
}
diff --git a/widgets/e-table/test-table.c b/widgets/e-table/test-table.c
index 27e1ac59f1..1bd50e1479 100644
--- a/widgets/e-table/test-table.c
+++ b/widgets/e-table/test-table.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Test code for the ETable package
*
@@ -55,6 +56,8 @@ parse_headers ()
p = buffer;
for (i = 0; (s = strtok (p, " \t")) != NULL; i++){
column_labels [i] = g_strdup (s);
+ if ( strchr(column_labels [i], '\n') )
+ *strchr(column_labels [i], '\n') = 0;
p = NULL;
}
@@ -174,6 +177,12 @@ is_cell_editable (ETableModel *etc, int col, int row, void *data)
}
static void
+thaw (ETableModel *etc, void *data)
+{
+ e_table_model_changed(etc);
+}
+
+static void
set_canvas_size (GnomeCanvas *canvas, GtkAllocation *alloc)
{
gnome_canvas_set_scroll_region (canvas, 0, 0, alloc->width, alloc->height);
@@ -196,7 +205,7 @@ table_browser_test (void)
*/
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
- set_value_at, is_cell_editable, NULL);
+ set_value_at, is_cell_editable, thaw, NULL);
/*
* Header
@@ -244,8 +253,6 @@ table_browser_test (void)
e_table_item_get_type (),
"ETableHeader", e_table_header,
"ETableModel", e_table_model,
- "x", (double) 0,
- "y", (double) 0,
"drawgrid", TRUE,
"drawfocus", TRUE,
"spreadsheet", TRUE,
@@ -253,7 +260,7 @@ table_browser_test (void)
}
static void
-do_e_table_demo (const char *col_spec, const char *group_spec)
+do_e_table_demo (const char *spec)
{
GtkWidget *e_table, *window, *frame;
ETableModel *e_table_model;
@@ -266,7 +273,7 @@ do_e_table_demo (const char *col_spec, const char *group_spec)
*/
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
- set_value_at, is_cell_editable, NULL);
+ set_value_at, is_cell_editable, thaw, NULL);
full_header = e_table_header_new ();
cell_left_just = e_cell_text_new (e_table_model, NULL, GTK_JUSTIFY_LEFT, TRUE);
@@ -283,7 +290,7 @@ do_e_table_demo (const char *col_spec, const char *group_spec)
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
frame = gtk_frame_new (NULL);
- e_table = e_table_new (full_header, e_table_model, col_spec, group_spec);
+ e_table = e_table_new (full_header, e_table_model, spec);
gtk_container_add (GTK_CONTAINER (frame), e_table);
gtk_container_add (GTK_CONTAINER (window), frame);
@@ -298,9 +305,10 @@ e_table_test (void)
{
load_data ();
- if (getenv ("DO")){
- do_e_table_demo ("0,1,2,3,4", NULL);
- do_e_table_demo ("0,1,2,3,4", "3,4");
+ if (1){/*getenv ("DO")){*/
+ do_e_table_demo ("<ETableSpecification> <columns-shown> <column> 0 </column> <column> 1 </column> <column> 2 </column> <column> 3 </column> <column> 4 </column> </columns-shown> <grouping> <leaf/> </grouping> </ETableSpecification>");
+ do_e_table_demo ("<ETableSpecification> <columns-shown> <column> 0 </column> <column> 0 </column> <column> 0 </column> <column> 0 </column> <column> 0 </column> <column> 1 </column> <column> 2 </column> <column> 3 </column> <column> 4 </column> </columns-shown> <grouping> <group column=\"3\"> <group column=\"4\"> <leaf/> </group> </group> </grouping> </ETableSpecification>");
}
- do_e_table_demo ("0,1,2,3,4", "3");
+ do_e_table_demo ("<ETableSpecification> <columns-shown> <column> 0 </column> <column> 1 </column> <column> 2 </column> <column> 3 </column> <column> 4 </column> </columns-shown> <grouping> <group column=\"4\"> <leaf/> </group> </grouping> </ETableSpecification>");
+ do_e_table_demo ("<ETableSpecification> <columns-shown> <column> 0 </column> <column> 1 </column> <column> 2 </column> <column> 3 </column> <column> 4 </column> </columns-shown> <grouping> <group column=\"3\"> <leaf/> </group> </grouping> </ETableSpecification>");
}
diff --git a/widgets/e-text-event-processor-emacs-like.c b/widgets/e-text-event-processor-emacs-like.c
deleted file mode 100644
index 41bcd0c31d..0000000000
--- a/widgets/e-text-event-processor-emacs-like.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-text-event-processor.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 <gnome.h>
-#include "e-text-event-processor-emacs-like.h"
-static void e_text_event_processor_emacs_like_init (ETextEventProcessorEmacsLike *card);
-static void e_text_event_processor_emacs_like_class_init (ETextEventProcessorEmacsLikeClass *klass);
-static gint e_text_event_processor_emacs_like_event (ETextEventProcessor *tep, ETextEventProcessorEvent *event);
-
-static ETextEventProcessorClass *parent_class = NULL;
-
-/* The arguments we take */
-enum {
- ARG_0
-};
-
-static const ETextEventProcessorCommand control_keys[26] =
-{
- { E_TEP_START_OF_LINE, E_TEP_MOVE, 0, "" }, /* a */
- { E_TEP_BACKWARD_CHARACTER, E_TEP_MOVE, 0, "" }, /* b */
- { E_TEP_SELECTION, E_TEP_COPY, 0, "" }, /* c */
- { E_TEP_FORWARD_CHARACTER, E_TEP_DELETE, 0, "" }, /* d */
- { E_TEP_END_OF_LINE, E_TEP_MOVE, 0, "" }, /* e */
- { E_TEP_FORWARD_CHARACTER, E_TEP_MOVE, 0, "" }, /* f */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* g */
- { E_TEP_BACKWARD_CHARACTER, E_TEP_DELETE, 0, "" }, /* h */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* i */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* j */
- { E_TEP_END_OF_LINE, E_TEP_DELETE, 0, "" }, /* k */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* l */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* m */
- { E_TEP_FORWARD_LINE, E_TEP_MOVE, 0, "" }, /* n */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* o */
- { E_TEP_BACKWARD_LINE, E_TEP_MOVE, 0, "" }, /* p */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* q */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* r */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* s */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* t */
- { E_TEP_START_OF_LINE, E_TEP_DELETE, 0, "" }, /* u */
- { E_TEP_SELECTION, E_TEP_PASTE, 0, "" }, /* v */
- { E_TEP_BACKWARD_WORD, E_TEP_DELETE, 0, "" }, /* w */
- { E_TEP_SELECTION, E_TEP_DELETE, 0, "" }, /* x */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* y */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" } /* z */
-};
-
-static const ETextEventProcessorCommand alt_keys[26] =
-{
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* a */
- { E_TEP_BACKWARD_WORD, E_TEP_MOVE, 0, "" }, /* b */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* c */
- { E_TEP_FORWARD_WORD, E_TEP_DELETE, 0, "" }, /* d */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* e */
- { E_TEP_FORWARD_WORD, E_TEP_MOVE, 0, "" }, /* f */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* g */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* h */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* i */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* j */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* k */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* l */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* m */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* n */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* o */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* p */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* q */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* r */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* s */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* t */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* u */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* v */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* w */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* x */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" }, /* y */
- { E_TEP_SELECTION, E_TEP_NOP, 0, "" } /* z */
-
-};
-
-GtkType
-e_text_event_processor_emacs_like_get_type (void)
-{
- static GtkType text_event_processor_emacs_like_type = 0;
-
- if (!text_event_processor_emacs_like_type)
- {
- static const GtkTypeInfo text_event_processor_emacs_like_info =
- {
- "ETextEventProcessorEmacsLike",
- sizeof (ETextEventProcessorEmacsLike),
- sizeof (ETextEventProcessorEmacsLikeClass),
- (GtkClassInitFunc) e_text_event_processor_emacs_like_class_init,
- (GtkObjectInitFunc) e_text_event_processor_emacs_like_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- text_event_processor_emacs_like_type = gtk_type_unique (e_text_event_processor_get_type (), &text_event_processor_emacs_like_info);
- }
-
- return text_event_processor_emacs_like_type;
-}
-
-static void
-e_text_event_processor_emacs_like_class_init (ETextEventProcessorEmacsLikeClass *klass)
-{
- GtkObjectClass *object_class;
- ETextEventProcessorClass *processor_class;
-
- object_class = (GtkObjectClass*) klass;
- processor_class = (ETextEventProcessorClass*) klass;
-
- parent_class = gtk_type_class (e_text_event_processor_get_type ());
-
- processor_class->event = e_text_event_processor_emacs_like_event;
-}
-
-static void
-e_text_event_processor_emacs_like_init (ETextEventProcessorEmacsLike *tep)
-{
-}
-
-static gint
-e_text_event_processor_emacs_like_event (ETextEventProcessor *tep, ETextEventProcessorEvent *event)
-{
- ETextEventProcessorCommand command;
- ETextEventProcessorEmacsLike *tep_el = E_TEXT_EVENT_PROCESSOR_EMACS_LIKE(tep);
- command.action = E_TEP_NOP;
- switch (event->type) {
- case GDK_BUTTON_PRESS:
- if (event->button.button == 1) {
- command.action = E_TEP_GRAB;
- command.time = event->button.time;
- gtk_signal_emit_by_name (GTK_OBJECT (tep), "command", &command);
- if (event->button.state & GDK_SHIFT_MASK)
- command.action = E_TEP_SELECT;
- else
- command.action = E_TEP_MOVE;
- command.position = E_TEP_VALUE;
- command.value = event->button.position;
- command.time = event->button.time;
- tep_el->mouse_down = TRUE;
- }
- break;
- case GDK_BUTTON_RELEASE:
- if (event->button.button == 1) {
- command.action = E_TEP_UNGRAB;
- command.time = event->button.time;
- gtk_signal_emit_by_name (GTK_OBJECT (tep), "command", &command);
- command.time = event->button.time;
- tep_el->mouse_down = FALSE;
- } else if (event->button.button == 2) {
- command.action = E_TEP_MOVE;
- command.position = E_TEP_VALUE;
- command.value = event->button.position;
- command.time = event->button.time;
- gtk_signal_emit_by_name (GTK_OBJECT (tep), "command", &command);
-
- command.action = E_TEP_GET_SELECTION;
- command.position = E_TEP_SELECTION;
- command.value = 0;
- command.time = event->button.time;
- }
- break;
- case GDK_MOTION_NOTIFY:
- if (tep_el->mouse_down) {
- command.action = E_TEP_SELECT;
- command.position = E_TEP_VALUE;
- command.time = event->motion.time;
- command.value = event->motion.position;
- }
- break;
- case GDK_KEY_PRESS:
- {
- ETextEventProcessorEventKey key = event->key;
- command.time = event->key.time;
- if (key.state & GDK_SHIFT_MASK)
- command.action = E_TEP_SELECT;
- else
- command.action = E_TEP_MOVE;
- switch(key.keyval) {
- case GDK_Home:
- if (key.state & GDK_CONTROL_MASK)
- command.position = E_TEP_START_OF_BUFFER;
- else
- command.position = E_TEP_START_OF_LINE;
- break;
- case GDK_End:
- if (key.state & GDK_CONTROL_MASK)
- command.position = E_TEP_END_OF_BUFFER;
- else
- command.position = E_TEP_END_OF_LINE;
- break;
- case GDK_Page_Up: command.position = E_TEP_BACKWARD_PAGE; break;
- case GDK_Page_Down: command.position = E_TEP_FORWARD_PAGE; break;
- /* CUA has Ctrl-Up/Ctrl-Down as paragraph up down */
- case GDK_Up: command.position = E_TEP_BACKWARD_LINE; break;
- case GDK_Down: command.position = E_TEP_FORWARD_LINE; break;
- case GDK_Left:
- if (key.state & GDK_CONTROL_MASK)
- command.position = E_TEP_BACKWARD_WORD;
- else
- command.position = E_TEP_BACKWARD_CHARACTER;
- break;
- case GDK_Right:
- if (key.state & GDK_CONTROL_MASK)
- command.position = E_TEP_FORWARD_WORD;
- else
- command.position = E_TEP_FORWARD_CHARACTER;
- break;
-
- case GDK_BackSpace:
- command.action = E_TEP_DELETE;
- if (key.state & GDK_CONTROL_MASK)
- command.position = E_TEP_BACKWARD_WORD;
- else
- command.position = E_TEP_BACKWARD_CHARACTER;
- break;
- case GDK_Clear:
- command.action = E_TEP_DELETE;
- command.position = E_TEP_END_OF_LINE;
- break;
- case GDK_Insert:
- if (key.state & GDK_SHIFT_MASK) {
- command.action = E_TEP_PASTE;
- command.position = E_TEP_SELECTION;
- } else if (key.state & GDK_CONTROL_MASK) {
- command.action = E_TEP_COPY;
- command.position = E_TEP_SELECTION;
- } else {
- /* gtk_toggle_insert(text) -- IMPLEMENT */
- }
- break;
- case GDK_Delete:
- if (key.state & GDK_CONTROL_MASK){
- command.action = E_TEP_DELETE;
- command.position = E_TEP_FORWARD_WORD;
- } else if (key.state & GDK_SHIFT_MASK) {
- command.action = E_TEP_COPY;
- command.position = E_TEP_SELECTION;
- gtk_signal_emit_by_name (GTK_OBJECT (tep), "command", &command);
-
- command.action = E_TEP_DELETE;
- command.position = E_TEP_SELECTION;
- } else {
- command.action = E_TEP_DELETE;
- command.position = E_TEP_FORWARD_CHARACTER;
- }
- break;
- case GDK_Tab:
- /* Don't insert literally */
- command.action = E_TEP_NOP;
- command.position = E_TEP_SELECTION;
- break;
- case GDK_Return:
- if (key.state & GDK_CONTROL_MASK) {
- command.action = E_TEP_ACTIVATE;
- command.position = E_TEP_SELECTION;
- } else {
- command.action = E_TEP_INSERT;
- command.position = E_TEP_SELECTION;
- command.value = 1;
- command.string = "\n";
- }
- break;
- case GDK_Escape:
- /* Don't insert literally */
- command.action = E_TEP_NOP;
- command.position = E_TEP_SELECTION;
- break;
-
- default:
- if (key.state & GDK_CONTROL_MASK) {
- if ((key.keyval >= 'A') && (key.keyval <= 'Z'))
- key.keyval -= 'A' - 'a';
-
- if ((key.keyval >= 'a') && (key.keyval <= 'z')) {
- command.position = control_keys[(int) (key.keyval - 'a')].position;
- if (control_keys[(int) (key.keyval - 'a')].action != E_TEP_MOVE)
- command.action = control_keys[(int) (key.keyval - 'a')].action;
- command.value = control_keys[(int) (key.keyval - 'a')].value;
- command.string = control_keys[(int) (key.keyval - 'a')].string;
- }
-
- if (key.keyval == 'x') {
- command.action = E_TEP_COPY;
- command.position = E_TEP_SELECTION;
- gtk_signal_emit_by_name (GTK_OBJECT (tep), "command", &command);
-
- command.action = E_TEP_DELETE;
- command.position = E_TEP_SELECTION;
- }
-
- break;
- } else if (key.state & GDK_MOD1_MASK) {
- if ((key.keyval >= 'A') && (key.keyval <= 'Z'))
- key.keyval -= 'A' - 'a';
-
- if ((key.keyval >= 'a') && (key.keyval <= 'z')) {
- command.position = alt_keys[(int) (key.keyval - 'a')].position;
- if (alt_keys[(int) (key.keyval - 'a')].action != E_TEP_MOVE)
- command.action = alt_keys[(int) (key.keyval - 'a')].action;
- command.value = alt_keys[(int) (key.keyval - 'a')].value;
- command.string = alt_keys[(int) (key.keyval - 'a')].string;
- }
- } else if (key.length > 0) {
- command.action = E_TEP_INSERT;
- command.position = E_TEP_SELECTION;
- command.value = strlen(key.string);
- command.string = key.string;
-
- } else {
- command.action = E_TEP_NOP;
- }
- }
- break;
- case GDK_KEY_RELEASE:
- command.time = event->key.time;
- command.action = E_TEP_NOP;
- break;
- default:
- command.action = E_TEP_NOP;
- break;
- }
- }
- if (command.action != E_TEP_NOP) {
- gtk_signal_emit_by_name (GTK_OBJECT (tep), "command", &command);
- return 1;
- }
- else
- return 0;
-}
-
-ETextEventProcessor *
-e_text_event_processor_emacs_like_new (void)
-{
- ETextEventProcessorEmacsLike *retval = gtk_type_new (e_text_event_processor_emacs_like_get_type ());
- return E_TEXT_EVENT_PROCESSOR (retval);
-}
-
diff --git a/widgets/e-text-event-processor-emacs-like.h b/widgets/e-text-event-processor-emacs-like.h
deleted file mode 100644
index 651bb552b3..0000000000
--- a/widgets/e-text-event-processor-emacs-like.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-text-event-processor-emacs-like.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_TEXT_EVENT_PROCESSOR_EMACS_LIKE_H__
-#define __E_TEXT_EVENT_PROCESSOR_EMACS_LIKE_H__
-
-#include <gnome.h>
-#include "e-text-event-processor.h"
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-/* ETextEventProcessorEmacsLike - Turns events on a text widget into commands. Uses an emacs-ish interface.
- *
- */
-
-#define E_TEXT_EVENT_PROCESSOR_EMACS_LIKE_TYPE (e_text_event_processor_emacs_like_get_type ())
-#define E_TEXT_EVENT_PROCESSOR_EMACS_LIKE(obj) (GTK_CHECK_CAST ((obj), E_TEXT_EVENT_PROCESSOR_EMACS_LIKE_TYPE, ETextEventProcessorEmacsLike))
-#define E_TEXT_EVENT_PROCESSOR_EMACS_LIKE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TEXT_EVENT_PROCESSOR_EMACS_LIKE_TYPE, ETextEventProcessorEmacsLikeClass))
-#define E_IS_TEXT_EVENT_PROCESSOR_EMACS_LIKE(obj) (GTK_CHECK_TYPE ((obj), E_TEXT_EVENT_PROCESSOR_EMACS_LIKE_TYPE))
-#define E_IS_TEXT_EVENT_PROCESSOR_EMACS_LIKE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TEXT_EVENT_PROCESSOR_EMACS_LIKE_TYPE))
-
-
-typedef struct _ETextEventProcessorEmacsLike ETextEventProcessorEmacsLike;
-typedef struct _ETextEventProcessorEmacsLikeClass ETextEventProcessorEmacsLikeClass;
-
-struct _ETextEventProcessorEmacsLike
-{
- ETextEventProcessor parent;
-
- /* object specific fields */
- gboolean mouse_down;
-};
-
-struct _ETextEventProcessorEmacsLikeClass
-{
- ETextEventProcessorClass parent_class;
-};
-
-
-GtkType e_text_event_processor_emacs_like_get_type (void);
-ETextEventProcessor *e_text_event_processor_emacs_like_new (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* __E_TEXT_EVENT_PROCESSOR_EMACS_LIKE_H__ */
diff --git a/widgets/e-text-event-processor-types.h b/widgets/e-text-event-processor-types.h
deleted file mode 100644
index 32a39bf0c0..0000000000
--- a/widgets/e-text-event-processor-types.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-text-event-processor.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.
- */
-
-/*
- * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
- * file for a list of people on the GTK+ Team. See the ChangeLog
- * files for a list of changes. These files are distributed with
- * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
- */
-
-#ifndef __E_TEXT_EVENT_PROCESSOR_TYPES_H__
-#define __E_TEXT_EVENT_PROCESSOR_TYPES_H__
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#include <gdk/gdktypes.h>
-
-typedef enum _ETextEventProcessorCommandPosition ETextEventProcessorCommandPosition;
-typedef enum _ETextEventProcessorCommandAction ETextEventProcessorCommandAction;
-typedef struct _ETextEventProcessorCommand ETextEventProcessorCommand;
-
-typedef union _ETextEventProcessorEvent ETextEventProcessorEvent;
-typedef struct _ETextEventProcessorEventButton ETextEventProcessorEventButton;
-typedef struct _ETextEventProcessorEventKey ETextEventProcessorEventKey;
-typedef struct _ETextEventProcessorEventMotion ETextEventProcessorEventMotion;
-
-enum _ETextEventProcessorCommandPosition {
- E_TEP_VALUE,
- E_TEP_SELECTION,
-
- E_TEP_START_OF_BUFFER,
- E_TEP_END_OF_BUFFER,
-
- E_TEP_START_OF_LINE,
- E_TEP_END_OF_LINE,
-
- E_TEP_FORWARD_CHARACTER,
- E_TEP_BACKWARD_CHARACTER,
-
- E_TEP_FORWARD_WORD,
- E_TEP_BACKWARD_WORD,
-
- E_TEP_FORWARD_LINE,
- E_TEP_BACKWARD_LINE,
-
- E_TEP_FORWARD_PARAGRAPH,
- E_TEP_BACKWARD_PARAGRAPH,
-
- E_TEP_FORWARD_PAGE,
- E_TEP_BACKWARD_PAGE
-};
-
-enum _ETextEventProcessorCommandAction {
- E_TEP_MOVE,
- E_TEP_SELECT,
- E_TEP_DELETE,
- E_TEP_INSERT,
-
- E_TEP_COPY,
- E_TEP_PASTE,
- E_TEP_GET_SELECTION,
- E_TEP_SET_SELECT_BY_WORD,
- E_TEP_ACTIVATE,
-
- E_TEP_GRAB,
- E_TEP_UNGRAB,
-
- E_TEP_NOP
-};
-
-struct _ETextEventProcessorCommand {
- ETextEventProcessorCommandPosition position;
- ETextEventProcessorCommandAction action;
- int value;
- char *string;
- guint32 time;
-};
-
-struct _ETextEventProcessorEventButton {
- GdkEventType type;
- guint32 time;
- guint state;
- guint button;
- gint position;
-};
-
-struct _ETextEventProcessorEventKey {
- GdkEventType type;
- guint32 time;
- guint state;
- guint keyval;
- gint length;
- gchar *string;
-};
-
-struct _ETextEventProcessorEventMotion {
- GdkEventType type;
- guint32 time;
- guint state;
- gint position;
-};
-
-union _ETextEventProcessorEvent {
- GdkEventType type;
- ETextEventProcessorEventButton button;
- ETextEventProcessorEventKey key;
- ETextEventProcessorEventMotion motion;
-};
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* __E_TEXT_EVENT_PROCESSOR_TYPES_H__ */
diff --git a/widgets/e-text-event-processor.c b/widgets/e-text-event-processor.c
deleted file mode 100644
index 47f028ca62..0000000000
--- a/widgets/e-text-event-processor.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-text-event-processor.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 <gnome.h>
-#include "e-text-event-processor.h"
-static void e_text_event_processor_init (ETextEventProcessor *card);
-static void e_text_event_processor_class_init (ETextEventProcessorClass *klass);
-
-static GtkObjectClass *parent_class = NULL;
-
-/* The arguments we take */
-enum {
- ARG_0
-};
-
-enum {
- E_TEP_EVENT,
- E_TEP_LAST_SIGNAL
-};
-
-static guint e_tep_signals[E_TEP_LAST_SIGNAL] = { 0 };
-
-GtkType
-e_text_event_processor_get_type (void)
-{
- static GtkType text_event_processor_type = 0;
-
- if (!text_event_processor_type)
- {
- static const GtkTypeInfo text_event_processor_info =
- {
- "ETextEventProcessor",
- sizeof (ETextEventProcessor),
- sizeof (ETextEventProcessorClass),
- (GtkClassInitFunc) e_text_event_processor_class_init,
- (GtkObjectInitFunc) e_text_event_processor_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- text_event_processor_type = gtk_type_unique (gtk_object_get_type (), &text_event_processor_info);
- }
-
- return text_event_processor_type;
-}
-
-static void
-e_text_event_processor_class_init (ETextEventProcessorClass *klass)
-{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass*) klass;
-
- parent_class = gtk_type_class (gtk_object_get_type ());
-
- e_tep_signals[E_TEP_EVENT] =
- gtk_signal_new ("command",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (ETextEventProcessorClass, command),
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_POINTER);
-
- gtk_object_class_add_signals (object_class, e_tep_signals, E_TEP_LAST_SIGNAL);
-
- klass->event = NULL;
- klass->command = NULL;
-}
-
-static void
-e_text_event_processor_init (ETextEventProcessor *tep)
-{
-}
-
-gint
-e_text_event_processor_handle_event (ETextEventProcessor *tep, ETextEventProcessorEvent *event)
-{
- if (E_TEXT_EVENT_PROCESSOR_CLASS(GTK_OBJECT(tep)->klass)->event) {
- return E_TEXT_EVENT_PROCESSOR_CLASS(GTK_OBJECT(tep)->klass)->event(tep, event);
- } else {
- return 0;
- }
-}
diff --git a/widgets/e-text-event-processor.h b/widgets/e-text-event-processor.h
deleted file mode 100644
index 1fc79f3f70..0000000000
--- a/widgets/e-text-event-processor.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-text-event-processor.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_TEXT_EVENT_PROCESSOR_H__
-#define __E_TEXT_EVENT_PROCESSOR_H__
-
-#include <gnome.h>
-#include "e-text-event-processor-types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-/* ETextEventProcessor - Turns events on a text widget into commands.
- *
- */
-
-#define E_TEXT_EVENT_PROCESSOR_TYPE (e_text_event_processor_get_type ())
-#define E_TEXT_EVENT_PROCESSOR(obj) (GTK_CHECK_CAST ((obj), E_TEXT_EVENT_PROCESSOR_TYPE, ETextEventProcessor))
-#define E_TEXT_EVENT_PROCESSOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TEXT_EVENT_PROCESSOR_TYPE, ETextEventProcessorClass))
-#define E_IS_TEXT_EVENT_PROCESSOR(obj) (GTK_CHECK_TYPE ((obj), E_TEXT_EVENT_PROCESSOR_TYPE))
-#define E_IS_TEXT_EVENT_PROCESSOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TEXT_EVENT_PROCESSOR_TYPE))
-
-
-typedef struct _ETextEventProcessor ETextEventProcessor;
-typedef struct _ETextEventProcessorClass ETextEventProcessorClass;
-
-struct _ETextEventProcessor
-{
- GtkObject parent;
-
- /* object specific fields */
-
-};
-
-struct _ETextEventProcessorClass
-{
- GtkObjectClass parent_class;
-
- /* signals */
- void (* command) (ETextEventProcessor *tep, ETextEventProcessorCommand *command);
-
- /* virtual functions */
- gint (* event) (ETextEventProcessor *tep, ETextEventProcessorEvent *event);
-};
-
-
-GtkType e_text_event_processor_get_type (void);
-gint e_text_event_processor_handle_event (ETextEventProcessor *tep, ETextEventProcessorEvent *event);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* __E_TEXT_EVENT_PROCESSOR_H__ */
diff --git a/widgets/e-text.c b/widgets/e-text.c
deleted file mode 100644
index b33e99194d..0000000000
--- a/widgets/e-text.c
+++ /dev/null
@@ -1,2526 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* EText - Text item for evolution.
- * Copyright (C) 2000 Helix Code, Inc.
- *
- * Author: Chris Lahey <clahey@umich.edu>
- *
- * A majority of code taken from:
- *
- * Text item type for GnomeCanvas widget
- *
- * GnomeCanvas is basically a port of the Tk toolkit's most excellent
- * canvas widget. Tk is copyrighted by the Regents of the University
- * of California, Sun Microsystems, and other parties.
- *
- * Copyright (C) 1998 The Free Software Foundation
- *
- * Author: Federico Mena <federico@nuclecu.unam.mx> */
-
-#include <config.h>
-#include <math.h>
-#include <ctype.h>
-#include "e-text.h"
-#include <gdk/gdkx.h> /* for BlackPixel */
-#include <libart_lgpl/art_affine.h>
-#include <libart_lgpl/art_rgb.h>
-#include <libart_lgpl/art_rgb_bitmap_affine.h>
-#include <gtk/gtkinvisible.h>
-
-#include "e-text-event-processor-emacs-like.h"
-
-enum {
- E_TEXT_RESIZE,
- E_TEXT_CHANGE,
- E_TEXT_LAST_SIGNAL
-};
-
-static guint e_text_signals[E_TEXT_LAST_SIGNAL] = { 0 };
-
-
-
-/* This defines a line of text */
-struct line {
- char *text; /* Line's text, it is a pointer into the text->text string */
- int length; /* Line's length in characters */
- int width; /* Line's width in pixels */
- int ellipsis_length; /* Length before adding ellipsis */
-};
-
-
-
-/* Object argument IDs */
-enum {
- ARG_0,
- ARG_TEXT,
- ARG_X,
- ARG_Y,
- ARG_FONT,
- ARG_FONTSET,
- ARG_FONT_GDK,
- ARG_ANCHOR,
- ARG_JUSTIFICATION,
- ARG_CLIP_WIDTH,
- ARG_CLIP_HEIGHT,
- ARG_CLIP,
- ARG_X_OFFSET,
- ARG_Y_OFFSET,
- ARG_FILL_COLOR,
- ARG_FILL_COLOR_GDK,
- ARG_FILL_COLOR_RGBA,
- ARG_FILL_STIPPLE,
- ARG_TEXT_WIDTH,
- ARG_TEXT_HEIGHT,
- ARG_EDITABLE,
- ARG_USE_ELLIPSIS,
- ARG_ELLIPSIS,
- ARG_LINE_WRAP,
- ARG_MAX_LINES
-};
-
-
-enum {
- E_SELECTION_PRIMARY,
- E_SELECTION_CLIPBOARD
-};
-enum {
- TARGET_STRING,
- TARGET_TEXT,
- TARGET_COMPOUND_TEXT
-};
-
-static void e_text_class_init (ETextClass *class);
-static void e_text_init (EText *text);
-static void e_text_destroy (GtkObject *object);
-static void e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_text_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-
-static void e_text_update (GnomeCanvasItem *item, double *affine,
- ArtSVP *clip_path, int flags);
-static void e_text_realize (GnomeCanvasItem *item);
-static void e_text_unrealize (GnomeCanvasItem *item);
-static void e_text_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
- int x, int y, int width, int height);
-static double e_text_point (GnomeCanvasItem *item, double x, double y, int cx, int cy,
- GnomeCanvasItem **actual_item);
-static void e_text_bounds (GnomeCanvasItem *item,
- double *x1, double *y1, double *x2, double *y2);
-static void e_text_render (GnomeCanvasItem *item, GnomeCanvasBuf *buf);
-static gint e_text_event (GnomeCanvasItem *item, GdkEvent *event);
-
-static void e_text_command(ETextEventProcessor *tep, ETextEventProcessorCommand *command, gpointer data);
-
-static guint32 e_text_get_event_time (EText *text);
-
-static void e_text_get_selection(EText *text, GdkAtom selection, guint32 time);
-static void e_text_supply_selection (EText *text, guint time, GdkAtom selection, guchar *data, gint length);
-
-static GtkWidget *e_text_get_invisible(EText *text);
-static void _selection_clear_event (GtkInvisible *invisible,
- GdkEventSelection *event,
- EText *text);
-static void _selection_get (GtkInvisible *invisible,
- GtkSelectionData *selection_data,
- guint info,
- guint time_stamp,
- EText *text);
-static void _selection_received (GtkInvisible *invisible,
- GtkSelectionData *selection_data,
- guint time,
- EText *text);
-
-static ETextSuckFont *e_suck_font (GdkFont *font);
-static void e_suck_font_free (ETextSuckFont *suckfont);
-
-
-static GnomeCanvasItemClass *parent_class;
-static GdkAtom clipboard_atom = GDK_NONE;
-
-
-
-/**
- * e_text_get_type:
- * @void:
- *
- * Registers the &EText class if necessary, and returns the type ID
- * associated to it.
- *
- * Return value: The type ID of the &EText class.
- **/
-GtkType
-e_text_get_type (void)
-{
- static GtkType text_type = 0;
-
- if (!text_type) {
- GtkTypeInfo text_info = {
- "EText",
- sizeof (EText),
- sizeof (ETextClass),
- (GtkClassInitFunc) e_text_class_init,
- (GtkObjectInitFunc) e_text_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- text_type = gtk_type_unique (gnome_canvas_item_get_type (), &text_info);
- }
-
- return text_type;
-}
-
-/* Class initialization function for the text item */
-static void
-e_text_class_init (ETextClass *klass)
-{
- GtkObjectClass *object_class;
- GnomeCanvasItemClass *item_class;
-
- object_class = (GtkObjectClass *) klass;
- item_class = (GnomeCanvasItemClass *) klass;
-
- parent_class = gtk_type_class (gnome_canvas_item_get_type ());
-
- e_text_signals[E_TEXT_RESIZE] =
- gtk_signal_new ("resize",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (ETextClass, resize),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
-
- e_text_signals[E_TEXT_CHANGE] =
- gtk_signal_new ("change",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (ETextClass, change),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
-
- gtk_object_class_add_signals (object_class, e_text_signals, E_TEXT_LAST_SIGNAL);
-
- gtk_object_add_arg_type ("EText::text",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TEXT);
- gtk_object_add_arg_type ("EText::x",
- GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_X);
- gtk_object_add_arg_type ("EText::y",
- GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_Y);
- gtk_object_add_arg_type ("EText::font",
- GTK_TYPE_STRING, GTK_ARG_WRITABLE, ARG_FONT);
- gtk_object_add_arg_type ("EText::fontset",
- GTK_TYPE_STRING, GTK_ARG_WRITABLE, ARG_FONTSET);
- gtk_object_add_arg_type ("EText::font_gdk",
- GTK_TYPE_GDK_FONT, GTK_ARG_READWRITE, ARG_FONT_GDK);
- gtk_object_add_arg_type ("EText::anchor",
- GTK_TYPE_ANCHOR_TYPE, GTK_ARG_READWRITE, ARG_ANCHOR);
- gtk_object_add_arg_type ("EText::justification",
- GTK_TYPE_JUSTIFICATION, GTK_ARG_READWRITE, ARG_JUSTIFICATION);
- gtk_object_add_arg_type ("EText::clip_width",
- GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_CLIP_WIDTH);
- gtk_object_add_arg_type ("EText::clip_height",
- GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_CLIP_HEIGHT);
- gtk_object_add_arg_type ("EText::clip",
- GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_CLIP);
- gtk_object_add_arg_type ("EText::x_offset",
- GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_X_OFFSET);
- gtk_object_add_arg_type ("EText::y_offset",
- GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_Y_OFFSET);
- gtk_object_add_arg_type ("EText::fill_color",
- GTK_TYPE_STRING, GTK_ARG_WRITABLE, ARG_FILL_COLOR);
- gtk_object_add_arg_type ("EText::fill_color_gdk",
- GTK_TYPE_GDK_COLOR, GTK_ARG_READWRITE, ARG_FILL_COLOR_GDK);
- gtk_object_add_arg_type ("EText::fill_color_rgba",
- GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_FILL_COLOR_RGBA);
- gtk_object_add_arg_type ("EText::fill_stipple",
- GTK_TYPE_GDK_WINDOW, GTK_ARG_READWRITE, ARG_FILL_STIPPLE);
- gtk_object_add_arg_type ("EText::text_width",
- GTK_TYPE_DOUBLE, GTK_ARG_READABLE, ARG_TEXT_WIDTH);
- gtk_object_add_arg_type ("EText::text_height",
- GTK_TYPE_DOUBLE, GTK_ARG_READABLE, ARG_TEXT_HEIGHT);
- gtk_object_add_arg_type ("EText::editable",
- GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_EDITABLE);
- gtk_object_add_arg_type ("EText::use_ellipsis",
- GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_USE_ELLIPSIS);
- gtk_object_add_arg_type ("EText::ellipsis",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_ELLIPSIS);
- gtk_object_add_arg_type ("EText::line_wrap",
- GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_LINE_WRAP);
- gtk_object_add_arg_type ("EText::max_lines",
- GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_MAX_LINES);
-
- if (!clipboard_atom)
- clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
-
-
-
- klass->resize = NULL;
- klass->change = NULL;
-
- object_class->destroy = e_text_destroy;
- object_class->set_arg = e_text_set_arg;
- object_class->get_arg = e_text_get_arg;
-
- item_class->update = e_text_update;
- item_class->realize = e_text_realize;
- item_class->unrealize = e_text_unrealize;
- item_class->draw = e_text_draw;
- item_class->point = e_text_point;
- item_class->bounds = e_text_bounds;
- item_class->render = e_text_render;
- item_class->event = e_text_event;
-}
-
-/* Object initialization function for the text item */
-static void
-e_text_init (EText *text)
-{
- text->x = 0.0;
- text->y = 0.0;
- text->anchor = GTK_ANCHOR_CENTER;
- text->justification = GTK_JUSTIFY_LEFT;
- text->clip_width = 0.0;
- text->clip_height = 0.0;
- text->xofs = 0.0;
- text->yofs = 0.0;
-
- text->ellipsis = NULL;
- text->use_ellipsis = FALSE;
- text->ellipsis_width = 0;
-
- text->editable = FALSE;
- text->editing = FALSE;
- text->xofs_edit = 0;
-
- text->selection_start = 0;
- text->selection_end = 0;
- text->select_by_word = FALSE;
-
- text->timeout_id = 0;
- text->timer = NULL;
-
- text->lastx = 0;
- text->lasty = 0;
- text->last_state = 0;
-
- text->scroll_start = 0;
- text->show_cursor = TRUE;
- text->button_down = FALSE;
-
- text->tep = NULL;
-
- text->has_selection = FALSE;
-
- text->invisible = NULL;
- text->primary_selection = NULL;
- text->primary_length = 0;
- text->clipboard_selection = NULL;
- text->clipboard_length = 0;
-
- text->pointer_in = FALSE;
- text->default_cursor_shown = TRUE;
-
- text->line_wrap = FALSE;
- text->max_lines = -1;
-}
-
-/* Destroy handler for the text item */
-static void
-e_text_destroy (GtkObject *object)
-{
- EText *text;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (GNOME_IS_CANVAS_TEXT (object));
-
- text = E_TEXT (object);
-
- if (text->text)
- g_free (text->text);
-
- if (text->tep)
- gtk_object_unref (GTK_OBJECT(text->tep));
-
- if (text->invisible)
- gtk_object_unref (GTK_OBJECT(text->invisible));
-
- if (text->lines)
- g_free (text->lines);
-
- if (text->font)
- gdk_font_unref (text->font);
-
- if (text->suckfont)
- e_suck_font_free (text->suckfont);
-
- if (text->stipple)
- gdk_bitmap_unref (text->stipple);
-
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-static void
-get_bounds_item_relative (EText *text, double *px1, double *py1, double *px2, double *py2)
-{
- GnomeCanvasItem *item;
- double x, y;
- double clip_x, clip_y;
- int old_height;
-
- item = GNOME_CANVAS_ITEM (text);
-
- x = text->x;
- y = text->y;
-
- clip_x = x;
- clip_y = y;
-
- /* Calculate text dimensions */
-
- old_height = text->height;
-
- if (text->text && text->font)
- text->height = (text->font->ascent + text->font->descent) * text->num_lines;
- else
- text->height = 0;
-
- if (old_height != text->height)
- gtk_signal_emit_by_name (GTK_OBJECT (text), "resize");
-
- /* Anchor text */
-
- switch (text->anchor) {
- case GTK_ANCHOR_NW:
- case GTK_ANCHOR_W:
- case GTK_ANCHOR_SW:
- break;
-
- case GTK_ANCHOR_N:
- case GTK_ANCHOR_CENTER:
- case GTK_ANCHOR_S:
- x -= text->max_width / 2;
- clip_x -= text->clip_width / 2;
- break;
-
- case GTK_ANCHOR_NE:
- case GTK_ANCHOR_E:
- case GTK_ANCHOR_SE:
- x -= text->max_width;
- clip_x -= text->clip_width;
- break;
- }
-
- switch (text->anchor) {
- case GTK_ANCHOR_NW:
- case GTK_ANCHOR_N:
- case GTK_ANCHOR_NE:
- break;
-
- case GTK_ANCHOR_W:
- case GTK_ANCHOR_CENTER:
- case GTK_ANCHOR_E:
- y -= text->height / 2;
- clip_y -= text->clip_height / 2;
- break;
-
- case GTK_ANCHOR_SW:
- case GTK_ANCHOR_S:
- case GTK_ANCHOR_SE:
- y -= text->height;
- clip_y -= text->clip_height;
- break;
- }
-
- /* Bounds */
-
- if (text->clip) {
- /* maybe do bbox intersection here? */
- *px1 = clip_x;
- *py1 = clip_y;
- *px2 = clip_x + text->clip_width;
- *py2 = clip_y + text->clip_height;
- } else {
- *px1 = x;
- *py1 = y;
- *px2 = x + text->max_width;
- *py2 = y + text->height;
- }
-}
-
-static void
-get_bounds (EText *text, double *px1, double *py1, double *px2, double *py2)
-{
- GnomeCanvasItem *item;
- double wx, wy;
- int old_height;
-
- item = GNOME_CANVAS_ITEM (text);
-
- /* Get canvas pixel coordinates for text position */
-
- wx = text->x;
- wy = text->y;
- gnome_canvas_item_i2w (item, &wx, &wy);
- gnome_canvas_w2c (item->canvas, wx + text->xofs, wy + text->yofs, &text->cx, &text->cy);
-
- /* Get canvas pixel coordinates for clip rectangle position */
-
- gnome_canvas_w2c (item->canvas, wx, wy, &text->clip_cx, &text->clip_cy);
- text->clip_cwidth = text->clip_width * item->canvas->pixels_per_unit;
- text->clip_cheight = text->clip_height * item->canvas->pixels_per_unit;
-
- /* Calculate text dimensions */
-
- old_height = text->height;
-
- if (text->text && text->font)
- text->height = (text->font->ascent + text->font->descent) * text->num_lines;
- else
- text->height = 0;
-
- if (old_height != text->height)
- gtk_signal_emit_by_name (GTK_OBJECT (text), "resize");
-
- /* Anchor text */
-
- switch (text->anchor) {
- case GTK_ANCHOR_NW:
- case GTK_ANCHOR_W:
- case GTK_ANCHOR_SW:
- break;
-
- case GTK_ANCHOR_N:
- case GTK_ANCHOR_CENTER:
- case GTK_ANCHOR_S:
- text->cx -= text->max_width / 2;
- text->clip_cx -= text->clip_cwidth / 2;
- break;
-
- case GTK_ANCHOR_NE:
- case GTK_ANCHOR_E:
- case GTK_ANCHOR_SE:
- text->cx -= text->max_width;
- text->clip_cx -= text->clip_cwidth;
- break;
- }
-
- switch (text->anchor) {
- case GTK_ANCHOR_NW:
- case GTK_ANCHOR_N:
- case GTK_ANCHOR_NE:
- break;
-
- case GTK_ANCHOR_W:
- case GTK_ANCHOR_CENTER:
- case GTK_ANCHOR_E:
- text->cy -= text->height / 2;
- text->clip_cy -= text->clip_cheight / 2;
- break;
-
- case GTK_ANCHOR_SW:
- case GTK_ANCHOR_S:
- case GTK_ANCHOR_SE:
- text->cy -= text->height;
- text->clip_cy -= text->clip_cheight;
- break;
- }
-
- /* Bounds */
-
- if (text->clip) {
- *px1 = text->clip_cx;
- *py1 = text->clip_cy;
- *px2 = text->clip_cx + text->clip_cwidth;
- *py2 = text->clip_cy + text->clip_cheight;
- } else {
- *px1 = text->cx;
- *py1 = text->cy;
- *px2 = text->cx + text->max_width;
- *py2 = text->cy + text->height;
- }
-}
-
-/* Recalculates the bounding box of the text item. The bounding box is defined
- * by the text's extents if the clip rectangle is disabled. If it is enabled,
- * the bounding box is defined by the clip rectangle itself.
- */
-static void
-recalc_bounds (EText *text)
-{
- GnomeCanvasItem *item;
-
- item = GNOME_CANVAS_ITEM (text);
-
- get_bounds (text, &item->x1, &item->y1, &item->x2, &item->y2);
-
- gnome_canvas_group_child_bounds (GNOME_CANVAS_GROUP (item->parent), item);
-}
-
-static void
-calc_ellipsis (EText *text)
-{
- if (text->font)
- text->ellipsis_width =
- gdk_text_width (text->font,
- text->ellipsis ? text->ellipsis : "...",
- text->ellipsis ? strlen (text->ellipsis) : 3);
-}
-
-/* Calculates the line widths (in pixels) of the text's splitted lines */
-static void
-calc_line_widths (EText *text)
-{
- struct line *lines;
- int i;
- int j;
-
- lines = text->lines;
- text->max_width = 0;
-
- if (!lines)
- return;
-
- for (i = 0; i < text->num_lines; i++) {
- if (lines->length != 0) {
- if (text->font) {
- lines->width = gdk_text_width (text->font,
- lines->text, lines->length);
- lines->ellipsis_length = 0;
- } else {
- lines->width = 0;
- }
-
- if (text->clip &&
- text->use_ellipsis &&
- ! text->editing &&
- lines->width > text->clip_width) {
- if (text->font) {
- lines->ellipsis_length = 0;
- for (j = 0; j < lines->length; j++ ) {
- if (gdk_text_width (text->font, lines->text, j) + text->ellipsis_width <= text->clip_width)
- lines->ellipsis_length = j;
- else
- break;
- }
- }
- else
- lines->ellipsis_length = 0;
- lines->width = gdk_text_width (text->font, lines->text, lines->ellipsis_length) +
- text->ellipsis_width;
- }
- else
- lines->ellipsis_length = lines->length;
-
- if (lines->width > text->max_width)
- text->max_width = lines->width;
- }
-
- lines++;
- }
-}
-
-/* Splits the text of the text item into lines */
-static void
-split_into_lines (EText *text)
-{
- char *p;
- struct line *lines;
- int len;
- int line_num;
- char *laststart;
- char *lastend;
- char *linestart;
-
- /* Free old array of lines */
-
- if (text->lines)
- g_free (text->lines);
-
- text->lines = NULL;
- text->num_lines = 0;
-
- if (!text->text)
- return;
-
- /* First, count the number of lines */
-
- lastend = text->text;
- laststart = text->text;
- linestart = text->text;
-
- for (p = text->text; *p; p++) {
- if (text->line_wrap && (*p == ' ' || *p == '\n')) {
- if ( laststart != lastend
- && gdk_text_width(text->font,
- linestart,
- p - linestart)
- > text->clip_width ) {
- text->num_lines ++;
- linestart = laststart;
- laststart = p + 1;
- lastend = p;
- } else if (*p == ' ') {
- laststart = p + 1;
- lastend = p;
- }
- }
- if (*p == '\n') {
- text->num_lines ++;
- lastend = p + 1;
- laststart = p + 1;
- linestart = p + 1;
- }
- }
-
- if (text->line_wrap) {
- if ( laststart != lastend
- && gdk_text_width(text->font,
- linestart,
- p - linestart)
- > text->clip_width ) {
- text->num_lines ++;
- }
- }
-
- text->num_lines++;
-
- if ( (!text->editing) && text->max_lines != -1 && text->num_lines > text->max_lines ) {
- text->num_lines = text->max_lines;
- }
-
- /* Allocate array of lines and calculate split positions */
-
- text->lines = lines = g_new0 (struct line, text->num_lines);
- len = 0;
- line_num = 1;
- lastend = text->text;
- laststart = text->text;
-
- for (p = text->text; line_num < text->num_lines && *p; p++) {
- gboolean handled = FALSE;
- if (len == 0)
- lines->text = p;
- if (text->line_wrap && (*p == ' ' || *p == '\n')) {
- if ( gdk_text_width(text->font,
- lines->text,
- p - lines->text)
- > text->clip_width
- && laststart != lastend ) {
- lines->length = lastend - lines->text;
- lines++;
- line_num ++;
- len = p - laststart;
- lines->text = laststart;
- laststart = p + 1;
- lastend = p;
- } else if (*p == ' ') {
- laststart = p + 1;
- lastend = p;
- len ++;
- }
- handled = TRUE;
- }
- if ( line_num >= text->num_lines )
- break;
- if (*p == '\n') {
- lines->length = p - lines->text;
- lines++;
- line_num ++;
- len = 0;
- lastend = p + 1;
- laststart = p + 1;
- handled = TRUE;
- }
- if (!handled)
- len++;
- }
-
- if ( line_num < text->num_lines && text->line_wrap ) {
- if ( gdk_text_width(text->font,
- lines->text,
- p - lines->text)
- > text->clip_width
- && laststart != lastend ) {
- lines->length = lastend - lines->text;
- lines++;
- line_num ++;
- len = p - laststart;
- lines->text = laststart;
- laststart = p + 1;
- lastend = p;
- }
- }
-
- if (len == 0)
- lines->text = p;
- lines->length = strlen(lines->text);
-
- calc_line_widths (text);
-}
-
-/* Convenience function to set the text's GC's foreground color */
-static void
-set_text_gc_foreground (EText *text)
-{
- GdkColor c;
-
- if (!text->gc)
- return;
-
- c.pixel = text->pixel;
- gdk_gc_set_foreground (text->gc, &c);
-}
-
-/* Sets the stipple pattern for the text */
-static void
-set_stipple (EText *text, GdkBitmap *stipple, int reconfigure)
-{
- if (text->stipple && !reconfigure)
- gdk_bitmap_unref (text->stipple);
-
- text->stipple = stipple;
- if (stipple && !reconfigure)
- gdk_bitmap_ref (stipple);
-
- if (text->gc) {
- if (stipple) {
- gdk_gc_set_stipple (text->gc, stipple);
- gdk_gc_set_fill (text->gc, GDK_STIPPLED);
- } else
- gdk_gc_set_fill (text->gc, GDK_SOLID);
- }
-}
-
-/* Set_arg handler for the text item */
-static void
-e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- GnomeCanvasItem *item;
- EText *text;
- GdkColor color = { 0, 0, 0, 0, };
- GdkColor *pcolor;
- gboolean color_changed;
- int have_pixel;
-
- item = GNOME_CANVAS_ITEM (object);
- text = E_TEXT (object);
-
- color_changed = FALSE;
- have_pixel = FALSE;
-
- switch (arg_id) {
- case ARG_TEXT:
- if (text->text)
- g_free (text->text);
-
- text->text = g_strdup (GTK_VALUE_STRING (*arg));
- split_into_lines (text);
- recalc_bounds (text);
- break;
-
- case ARG_X:
- text->x = GTK_VALUE_DOUBLE (*arg);
- recalc_bounds (text);
- break;
-
- case ARG_Y:
- text->y = GTK_VALUE_DOUBLE (*arg);
- recalc_bounds (text);
- break;
-
- case ARG_FONT:
- if (text->font)
- gdk_font_unref (text->font);
-
- text->font = gdk_font_load (GTK_VALUE_STRING (*arg));
-
- if (item->canvas->aa) {
- if (text->suckfont)
- e_suck_font_free (text->suckfont);
-
- text->suckfont = e_suck_font (text->font);
- }
-
- calc_ellipsis (text);
- if ( text->line_wrap )
- split_into_lines (text);
- else
- calc_line_widths (text);
- recalc_bounds (text);
- break;
-
- case ARG_FONTSET:
- if (text->font)
- gdk_font_unref (text->font);
-
- text->font = gdk_fontset_load (GTK_VALUE_STRING (*arg));
-
- if (item->canvas->aa) {
- if (text->suckfont)
- e_suck_font_free (text->suckfont);
-
- text->suckfont = e_suck_font (text->font);
- }
-
- calc_ellipsis (text);
- if ( text->line_wrap )
- split_into_lines (text);
- else
- calc_line_widths (text);
- recalc_bounds (text);
- break;
-
- case ARG_FONT_GDK:
- if (text->font)
- gdk_font_unref (text->font);
-
- text->font = GTK_VALUE_BOXED (*arg);
- gdk_font_ref (text->font);
-
- if (item->canvas->aa) {
- if (text->suckfont)
- e_suck_font_free (text->suckfont);
-
- text->suckfont = e_suck_font (text->font);
- }
- calc_ellipsis (text);
- if ( text->line_wrap )
- split_into_lines (text);
- else
- calc_line_widths (text);
- recalc_bounds (text);
- break;
-
- case ARG_ANCHOR:
- text->anchor = GTK_VALUE_ENUM (*arg);
- recalc_bounds (text);
- break;
-
- case ARG_JUSTIFICATION:
- text->justification = GTK_VALUE_ENUM (*arg);
- break;
-
- case ARG_CLIP_WIDTH:
- text->clip_width = fabs (GTK_VALUE_DOUBLE (*arg));
- calc_ellipsis (text);
- if ( text->line_wrap )
- split_into_lines (text);
- else
- calc_line_widths (text);
- recalc_bounds (text);
- break;
-
- case ARG_CLIP_HEIGHT:
- text->clip_height = fabs (GTK_VALUE_DOUBLE (*arg));
- recalc_bounds (text);
- break;
-
- case ARG_CLIP:
- text->clip = GTK_VALUE_BOOL (*arg);
- calc_ellipsis (text);
- if ( text->line_wrap )
- split_into_lines (text);
- else
- calc_line_widths (text);
- recalc_bounds (text);
- break;
-
- case ARG_X_OFFSET:
- text->xofs = GTK_VALUE_DOUBLE (*arg);
- recalc_bounds (text);
- break;
-
- case ARG_Y_OFFSET:
- text->yofs = GTK_VALUE_DOUBLE (*arg);
- recalc_bounds (text);
- break;
-
- case ARG_FILL_COLOR:
- if (GTK_VALUE_STRING (*arg))
- gdk_color_parse (GTK_VALUE_STRING (*arg), &color);
-
- text->rgba = ((color.red & 0xff00) << 16 |
- (color.green & 0xff00) << 8 |
- (color.blue & 0xff00) |
- 0xff);
- color_changed = TRUE;
- break;
-
- case ARG_FILL_COLOR_GDK:
- pcolor = GTK_VALUE_BOXED (*arg);
- if (pcolor) {
- color = *pcolor;
- gdk_color_context_query_color (item->canvas->cc, &color);
- have_pixel = TRUE;
- }
-
- text->rgba = ((color.red & 0xff00) << 16 |
- (color.green & 0xff00) << 8 |
- (color.blue & 0xff00) |
- 0xff);
- color_changed = TRUE;
- break;
-
- case ARG_FILL_COLOR_RGBA:
- text->rgba = GTK_VALUE_UINT (*arg);
- color_changed = TRUE;
- break;
-
- case ARG_FILL_STIPPLE:
- set_stipple (text, GTK_VALUE_BOXED (*arg), FALSE);
- break;
-
- case ARG_EDITABLE:
- text->editable = GTK_VALUE_BOOL (*arg);
- break;
-
- case ARG_USE_ELLIPSIS:
- text->use_ellipsis = GTK_VALUE_BOOL (*arg);
- calc_line_widths (text);
- recalc_bounds (text);
- break;
-
- case ARG_ELLIPSIS:
- if (text->ellipsis)
- g_free (text->ellipsis);
-
- text->ellipsis = g_strdup (GTK_VALUE_STRING (*arg));
- calc_ellipsis (text);
- calc_line_widths (text);
- recalc_bounds (text);
- break;
-
- case ARG_LINE_WRAP:
- text->line_wrap = GTK_VALUE_BOOL (*arg);
- split_into_lines (text);
- recalc_bounds (text);
- break;
-
- case ARG_MAX_LINES:
- text->max_lines = GTK_VALUE_INT (*arg);
- split_into_lines (text);
- recalc_bounds (text);
- break;
-
- default:
- break;
- }
-
- if (color_changed) {
- if (have_pixel)
- text->pixel = color.pixel;
- else
- text->pixel = gnome_canvas_get_color_pixel (item->canvas, text->rgba);
-
- if (!item->canvas->aa)
- set_text_gc_foreground (text);
-
- gnome_canvas_item_request_update (item);
- }
-}
-
-/* Get_arg handler for the text item */
-static void
-e_text_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- EText *text;
- GdkColor *color;
-
- text = E_TEXT (object);
-
- switch (arg_id) {
- case ARG_TEXT:
- GTK_VALUE_STRING (*arg) = g_strdup (text->text);
- break;
-
- case ARG_X:
- GTK_VALUE_DOUBLE (*arg) = text->x;
- break;
-
- case ARG_Y:
- GTK_VALUE_DOUBLE (*arg) = text->y;
- break;
-
- case ARG_FONT_GDK:
- GTK_VALUE_BOXED (*arg) = text->font;
- break;
-
- case ARG_ANCHOR:
- GTK_VALUE_ENUM (*arg) = text->anchor;
- break;
-
- case ARG_JUSTIFICATION:
- GTK_VALUE_ENUM (*arg) = text->justification;
- break;
-
- case ARG_CLIP_WIDTH:
- GTK_VALUE_DOUBLE (*arg) = text->clip_width;
- break;
-
- case ARG_CLIP_HEIGHT:
- GTK_VALUE_DOUBLE (*arg) = text->clip_height;
- break;
-
- case ARG_CLIP:
- GTK_VALUE_BOOL (*arg) = text->clip;
- break;
-
- case ARG_X_OFFSET:
- GTK_VALUE_DOUBLE (*arg) = text->xofs;
- break;
-
- case ARG_Y_OFFSET:
- GTK_VALUE_DOUBLE (*arg) = text->yofs;
- break;
-
- case ARG_FILL_COLOR_GDK:
- color = g_new (GdkColor, 1);
- color->pixel = text->pixel;
- gdk_color_context_query_color (text->item.canvas->cc, color);
- GTK_VALUE_BOXED (*arg) = color;
- break;
-
- case ARG_FILL_COLOR_RGBA:
- GTK_VALUE_UINT (*arg) = text->rgba;
- break;
-
- case ARG_FILL_STIPPLE:
- GTK_VALUE_BOXED (*arg) = text->stipple;
- break;
-
- case ARG_TEXT_WIDTH:
- GTK_VALUE_DOUBLE (*arg) = text->max_width / text->item.canvas->pixels_per_unit;
- break;
-
- case ARG_TEXT_HEIGHT:
- GTK_VALUE_DOUBLE (*arg) = text->height / text->item.canvas->pixels_per_unit;
- break;
-
- case ARG_EDITABLE:
- GTK_VALUE_BOOL (*arg) = text->editable;
- break;
-
- case ARG_USE_ELLIPSIS:
- GTK_VALUE_BOOL (*arg) = text->use_ellipsis;
- break;
-
- case ARG_ELLIPSIS:
- GTK_VALUE_STRING (*arg) = g_strdup (text->ellipsis);
- break;
-
- case ARG_LINE_WRAP:
- GTK_VALUE_BOOL (*arg) = text->line_wrap;
- break;
-
- case ARG_MAX_LINES:
- GTK_VALUE_INT (*arg) = text->max_lines;
- break;
-
- default:
- arg->type = GTK_TYPE_INVALID;
- break;
- }
-}
-
-/* Update handler for the text item */
-static void
-e_text_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
-{
- EText *text;
- double x1, y1, x2, y2;
- ArtDRect i_bbox, c_bbox;
- int i;
-
- text = E_TEXT (item);
-
- if (parent_class->update)
- (* parent_class->update) (item, affine, clip_path, flags);
-
- if (!item->canvas->aa) {
- set_text_gc_foreground (text);
- set_stipple (text, text->stipple, TRUE);
- get_bounds (text, &x1, &y1, &x2, &y2);
-
- gnome_canvas_update_bbox (item, x1, y1, x2, y2);
- } else {
- /* aa rendering */
- for (i = 0; i < 6; i++)
- text->affine[i] = affine[i];
- get_bounds_item_relative (text, &i_bbox.x0, &i_bbox.y0, &i_bbox.x1, &i_bbox.y1);
- art_drect_affine_transform (&c_bbox, &i_bbox, affine);
- gnome_canvas_update_bbox (item, c_bbox.x0, c_bbox.y0, c_bbox.x1, c_bbox.y1);
-
- }
-}
-
-/* Realize handler for the text item */
-static void
-e_text_realize (GnomeCanvasItem *item)
-{
- EText *text;
-
- text = E_TEXT (item);
-
- if (parent_class->realize)
- (* parent_class->realize) (item);
-
- text->gc = gdk_gc_new (item->canvas->layout.bin_window);
-
- text->i_cursor = gdk_cursor_new (GDK_XTERM);
- text->default_cursor = gdk_cursor_new (GDK_LEFT_PTR);
-}
-
-/* Unrealize handler for the text item */
-static void
-e_text_unrealize (GnomeCanvasItem *item)
-{
- EText *text;
-
- text = E_TEXT (item);
-
- gdk_gc_unref (text->gc);
- text->gc = NULL;
-
- gdk_cursor_destroy (text->i_cursor);
- gdk_cursor_destroy (text->default_cursor);
-
- if (parent_class->unrealize)
- (* parent_class->unrealize) (item);
-}
-
-/* Calculates the x position of the specified line of text, based on the text's justification */
-static double
-get_line_xpos_item_relative (EText *text, struct line *line)
-{
- double x;
-
- x = text->x;
-
- switch (text->anchor) {
- case GTK_ANCHOR_NW:
- case GTK_ANCHOR_W:
- case GTK_ANCHOR_SW:
- break;
-
- case GTK_ANCHOR_N:
- case GTK_ANCHOR_CENTER:
- case GTK_ANCHOR_S:
- x -= text->max_width / 2;
- break;
-
- case GTK_ANCHOR_NE:
- case GTK_ANCHOR_E:
- case GTK_ANCHOR_SE:
- x -= text->max_width;
- break;
- }
-
- switch (text->justification) {
- case GTK_JUSTIFY_RIGHT:
- x += text->max_width - line->width;
- break;
-
- case GTK_JUSTIFY_CENTER:
- x += (text->max_width - line->width) * 0.5;
- break;
-
- default:
- /* For GTK_JUSTIFY_LEFT, we don't have to do anything. We do not support
- * GTK_JUSTIFY_FILL, yet.
- */
- break;
- }
-
- return x;
-}
-
-/* Calculates the y position of the first line of text. */
-static double
-get_line_ypos_item_relative (EText *text)
-{
- double y;
-
- y = text->y;
-
- switch (text->anchor) {
- case GTK_ANCHOR_NW:
- case GTK_ANCHOR_N:
- case GTK_ANCHOR_NE:
- break;
-
- case GTK_ANCHOR_W:
- case GTK_ANCHOR_CENTER:
- case GTK_ANCHOR_E:
- y -= text->height / 2;
- break;
-
- case GTK_ANCHOR_SW:
- case GTK_ANCHOR_S:
- case GTK_ANCHOR_SE:
- y -= text->height;
- break;
- }
-
- return y;
-}
-
-/* Calculates the x position of the specified line of text, based on the text's justification */
-static int
-get_line_xpos (EText *text, struct line *line)
-{
- int x;
-
- x = text->cx;
-
- switch (text->justification) {
- case GTK_JUSTIFY_RIGHT:
- x += text->max_width - line->width;
- break;
-
- case GTK_JUSTIFY_CENTER:
- x += (text->max_width - line->width) / 2;
- break;
-
- default:
- /* For GTK_JUSTIFY_LEFT, we don't have to do anything. We do not support
- * GTK_JUSTIFY_FILL, yet.
- */
- break;
- }
-
- return x;
-}
-
-static void
-_get_tep(EText *text)
-{
- if (!text->tep) {
- text->tep = e_text_event_processor_emacs_like_new();
- gtk_object_ref (GTK_OBJECT (text->tep));
- gtk_object_sink (GTK_OBJECT (text->tep));
- gtk_signal_connect(GTK_OBJECT(text->tep),
- "command",
- GTK_SIGNAL_FUNC(e_text_command),
- (gpointer) text);
- }
-}
-
-/* Draw handler for the text item */
-static void
-e_text_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
- int x, int y, int width, int height)
-{
- EText *text;
- GdkRectangle rect, *clip_rect;
- struct line *lines;
- int i;
- int xpos, ypos;
- int start_char, end_char;
- int sel_start, sel_end;
- GdkRectangle sel_rect;
- GdkGC *fg_gc;
- GnomeCanvas *canvas;
-
- text = E_TEXT (item);
- canvas = GNOME_CANVAS_ITEM(text)->canvas;
-
- fg_gc = GTK_WIDGET(canvas)->style->fg_gc[text->has_selection ? GTK_STATE_SELECTED : GTK_STATE_ACTIVE];
-
- if (!text->text || !text->font)
- return;
-
- clip_rect = NULL;
- if (text->clip) {
- rect.x = text->clip_cx - x;
- rect.y = text->clip_cy - y;
- rect.width = text->clip_cwidth;
- rect.height = text->clip_cheight;
-
- gdk_gc_set_clip_rectangle (text->gc, &rect);
- gdk_gc_set_clip_rectangle (fg_gc, &rect);
- clip_rect = &rect;
- }
- lines = text->lines;
- ypos = text->cy + text->font->ascent;
-
- if (text->stipple)
- gnome_canvas_set_stipple_origin (item->canvas, text->gc);
-
- for (i = 0; i < text->num_lines; i++) {
- xpos = get_line_xpos (text, lines);
- if (text->editing) {
- xpos -= text->xofs_edit;
- start_char = lines->text - text->text;
- end_char = start_char + lines->length;
- sel_start = text->selection_start;
- sel_end = text->selection_end;
- if (sel_start > sel_end ) {
- sel_start ^= sel_end;
- sel_end ^= sel_start;
- sel_start ^= sel_end;
- }
- if ( sel_start < start_char )
- sel_start = start_char;
- if ( sel_end > end_char )
- sel_end = end_char;
- if ( sel_start < sel_end ) {
- sel_rect.x = xpos - x + gdk_text_width (text->font,
- lines->text,
- sel_start - start_char);
- sel_rect.y = ypos - y - text->font->ascent;
- sel_rect.width = gdk_text_width (text->font,
- lines->text + sel_start - start_char,
- sel_end - sel_start);
- sel_rect.height = text->font->ascent + text->font->descent;
- gtk_paint_flat_box(GTK_WIDGET(item->canvas)->style,
- drawable,
- text->has_selection ?
- GTK_STATE_SELECTED :
- GTK_STATE_ACTIVE,
- GTK_SHADOW_NONE,
- clip_rect,
- GTK_WIDGET(item->canvas),
- "text",
- sel_rect.x,
- sel_rect.y,
- sel_rect.width,
- sel_rect.height);
- gdk_draw_text (drawable,
- text->font,
- text->gc,
- xpos - x,
- ypos - y,
- lines->text,
- sel_start - start_char);
- gdk_draw_text (drawable,
- text->font,
- fg_gc,
- xpos - x + gdk_text_width (text->font,
- lines->text,
- sel_start - start_char),
- ypos - y,
- lines->text + sel_start - start_char,
- sel_end - sel_start);
- gdk_draw_text (drawable,
- text->font,
- text->gc,
- xpos - x + gdk_text_width (text->font,
- lines->text,
- sel_end - start_char),
- ypos - y,
- lines->text + sel_end - start_char,
- end_char - sel_end);
- } else {
- gdk_draw_text (drawable,
- text->font,
- text->gc,
- xpos - x,
- ypos - y,
- lines->text,
- lines->length);
- }
- if (text->selection_start == text->selection_end &&
- text->selection_start >= start_char &&
- text->selection_start <= end_char &&
- text->show_cursor) {
- gdk_draw_rectangle (drawable,
- text->gc,
- TRUE,
- xpos - x + gdk_text_width (text->font,
- lines->text,
- sel_start - start_char),
- ypos - y - text->font->ascent,
- 1,
- text->font->ascent + text->font->descent);
- }
- } else {
- if ( text->clip && text->use_ellipsis && lines->ellipsis_length < lines->length) {
- gdk_draw_text (drawable,
- text->font,
- text->gc,
- xpos - x,
- ypos - y,
- lines->text,
- lines->ellipsis_length);
- gdk_draw_text (drawable,
- text->font,
- text->gc,
- xpos - x +
- lines->width - text->ellipsis_width,
- ypos - y,
- text->ellipsis ? text->ellipsis : "...",
- text->ellipsis ? strlen (text->ellipsis) : 3);
- } else
-
- gdk_draw_text (drawable,
- text->font,
- text->gc,
- xpos - x,
- ypos - y,
- lines->text,
- lines->length);
- }
-
- ypos += text->font->ascent + text->font->descent;
- lines++;
- }
-
- if (text->clip) {
- gdk_gc_set_clip_rectangle (text->gc, NULL);
- gdk_gc_set_clip_rectangle (fg_gc, NULL);
- }
-}
-
-/* Render handler for the text item */
-static void
-e_text_render (GnomeCanvasItem *item, GnomeCanvasBuf *buf)
-{
- EText *text;
- guint32 fg_color;
- double xpos, ypos;
- struct line *lines;
- int i, j;
- double affine[6];
- ETextSuckFont *suckfont;
- int dx, dy;
- ArtPoint start_i, start_c;
-
- text = E_TEXT (item);
-
- if (!text->text || !text->font || !text->suckfont)
- return;
-
- suckfont = text->suckfont;
-
- fg_color = text->rgba;
-
- gnome_canvas_buf_ensure_buf (buf);
-
- lines = text->lines;
- start_i.y = get_line_ypos_item_relative (text);
-
- art_affine_scale (affine, item->canvas->pixels_per_unit, item->canvas->pixels_per_unit);
- for (i = 0; i < 6; i++)
- affine[i] = text->affine[i];
-
- for (i = 0; i < text->num_lines; i++) {
- if (lines->length != 0) {
- start_i.x = get_line_xpos_item_relative (text, lines);
- art_affine_point (&start_c, &start_i, text->affine);
- xpos = start_c.x;
- ypos = start_c.y;
-
- for (j = 0; j < lines->length; j++) {
- ETextSuckChar *ch;
-
- ch = &suckfont->chars[(unsigned char)((lines->text)[j])];
-
- affine[4] = xpos;
- affine[5] = ypos;
- art_rgb_bitmap_affine (
- buf->buf,
- buf->rect.x0, buf->rect.y0, buf->rect.x1, buf->rect.y1,
- buf->buf_rowstride,
- suckfont->bitmap + (ch->bitmap_offset >> 3),
- ch->width,
- suckfont->bitmap_height,
- suckfont->bitmap_width >> 3,
- fg_color,
- affine,
- ART_FILTER_NEAREST, NULL);
-
- dx = ch->left_sb + ch->width + ch->right_sb;
- xpos += dx * affine[0];
- ypos += dx * affine[1];
- }
- }
-
- dy = text->font->ascent + text->font->descent;
- start_i.y += dy;
- lines++;
- }
-
- buf->is_bg = 0;
-}
-
-/* Point handler for the text item */
-static double
-e_text_point (GnomeCanvasItem *item, double x, double y,
- int cx, int cy, GnomeCanvasItem **actual_item)
-{
- EText *text;
- int i;
- struct line *lines;
- int x1, y1, x2, y2;
- int font_height;
- int dx, dy;
- double dist, best;
-
- text = E_TEXT (item);
-
- *actual_item = item;
-
- /* The idea is to build bounding rectangles for each of the lines of
- * text (clipped by the clipping rectangle, if it is activated) and see
- * whether the point is inside any of these. If it is, we are done.
- * Otherwise, calculate the distance to the nearest rectangle.
- */
-
- if (text->font)
- font_height = text->font->ascent + text->font->descent;
- else
- font_height = 0;
-
- best = 1.0e36;
-
- lines = text->lines;
-
- for (i = 0; i < text->num_lines; i++) {
- /* Compute the coordinates of rectangle for the current line,
- * clipping if appropriate.
- */
-
- x1 = get_line_xpos (text, lines);
- y1 = text->cy + i * font_height;
- x2 = x1 + lines->width;
- y2 = y1 + font_height;
-
- if (text->clip) {
- if (x1 < text->clip_cx)
- x1 = text->clip_cx;
-
- if (y1 < text->clip_cy)
- y1 = text->clip_cy;
-
- if (x2 > (text->clip_cx + text->clip_width))
- x2 = text->clip_cx + text->clip_width;
-
- if (y2 > (text->clip_cy + text->clip_height))
- y2 = text->clip_cy + text->clip_height;
-
- if ((x1 >= x2) || (y1 >= y2))
- continue;
- }
-
- /* Calculate distance from point to rectangle */
-
- if (cx < x1)
- dx = x1 - cx;
- else if (cx >= x2)
- dx = cx - x2 + 1;
- else
- dx = 0;
-
- if (cy < y1)
- dy = y1 - cy;
- else if (cy >= y2)
- dy = cy - y2 + 1;
- else
- dy = 0;
-
- if ((dx == 0) && (dy == 0))
- return 0.0;
-
- dist = sqrt (dx * dx + dy * dy);
- if (dist < best)
- best = dist;
-
- /* Next! */
-
- lines++;
- }
-
- return best / item->canvas->pixels_per_unit;
-}
-
-/* Bounds handler for the text item */
-static void
-e_text_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
-{
- EText *text;
- double width, height;
-
- text = E_TEXT (item);
-
- *x1 = text->x;
- *y1 = text->y;
-
- if (text->clip) {
- width = text->clip_width;
- height = text->clip_height;
- } else {
- width = text->max_width / item->canvas->pixels_per_unit;
- height = text->height / item->canvas->pixels_per_unit;
- }
-
- switch (text->anchor) {
- case GTK_ANCHOR_NW:
- case GTK_ANCHOR_W:
- case GTK_ANCHOR_SW:
- break;
-
- case GTK_ANCHOR_N:
- case GTK_ANCHOR_CENTER:
- case GTK_ANCHOR_S:
- *x1 -= width / 2.0;
- break;
-
- case GTK_ANCHOR_NE:
- case GTK_ANCHOR_E:
- case GTK_ANCHOR_SE:
- *x1 -= width;
- break;
- }
-
- switch (text->anchor) {
- case GTK_ANCHOR_NW:
- case GTK_ANCHOR_N:
- case GTK_ANCHOR_NE:
- break;
-
- case GTK_ANCHOR_W:
- case GTK_ANCHOR_CENTER:
- case GTK_ANCHOR_E:
- *y1 -= height / 2.0;
- break;
-
- case GTK_ANCHOR_SW:
- case GTK_ANCHOR_S:
- case GTK_ANCHOR_SE:
- *y1 -= height;
- break;
- }
-
- *x2 = *x1 + width;
- *y2 = *y1 + height;
-}
-
-static void
-_get_xy_from_position (EText *text, gint position, gint *xp, gint *yp)
-{
- if (xp || yp) {
- struct line *lines;
- int x, y;
- int j;
- x = get_line_xpos (text, lines);
- y = text->cy;
- for (j = 0, lines = text->lines; j < text->num_lines; lines++, j++) {
- if (lines->text > text->text + position)
- break;
- y += text->font->ascent + text->font->descent;
- }
- lines --;
- y -= text->font->descent;
-
- x += gdk_text_width (text->font,
- lines->text,
- position - (lines->text - text->text));
- x -= text->xofs_edit;
- if (xp)
- *xp = x;
- if (yp)
- *yp = y;
- }
-}
-
-static gint
-_get_position_from_xy (EText *text, gint x, gint y)
-{
- int i, j;
- int ypos = text->cy;
- int xpos;
- struct line *lines;
- j = 0;
- while (y > ypos) {
- ypos += text->font->ascent + text->font->descent;
- j ++;
- }
- j--;
- if (j >= text->num_lines)
- j = text->num_lines - 1;
- if (j < 0)
- j = 0;
- i = 0;
- lines = text->lines;
- lines += j;
- x += text->xofs_edit;
- xpos = get_line_xpos (text, lines);
- for(i = 0; i < lines->length; i++) {
- int charwidth = gdk_text_width(text->font,
- lines->text + i,
- 1);
- xpos += charwidth / 2;
- if (xpos > x) {
- break;
- }
- xpos += (charwidth + 1) / 2;
- }
- return lines->text + i - text->text;
-}
-
-#define SCROLL_WAIT_TIME 30000
-
-static gboolean
-_blink_scroll_timeout (gpointer data)
-{
- EText *text = E_TEXT(data);
- gulong current_time;
- gboolean scroll = FALSE;
- gboolean redraw = FALSE;
-
- g_timer_elapsed(text->timer, &current_time);
-
- if (text->scroll_start + SCROLL_WAIT_TIME > 1000000) {
- if (current_time > text->scroll_start - (1000000 - SCROLL_WAIT_TIME) &&
- current_time < text->scroll_start)
- scroll = TRUE;
- } else {
- if (current_time > text->scroll_start + SCROLL_WAIT_TIME ||
- current_time < text->scroll_start)
- scroll = TRUE;
- }
- if (scroll && text->button_down) {
- if (text->lastx - text->clip_cx > text->clip_cwidth &&
- text->xofs_edit < text->max_width - text->clip_cwidth) {
- text->xofs_edit += 4;
- if (text->xofs_edit > text->max_width - text->clip_cwidth + 1)
- text->xofs_edit = text->max_width - text->clip_cwidth + 1;
- redraw = TRUE;
- }
- if (text->lastx - text->clip_cx < 0 &&
- text->xofs_edit > 0) {
- text->xofs_edit -= 4;
- if (text->xofs_edit < 0)
- text->xofs_edit = 0;
- redraw = TRUE;
- }
- if (redraw) {
- ETextEventProcessorEvent e_tep_event;
- e_tep_event.type = GDK_MOTION_NOTIFY;
- e_tep_event.motion.state = text->last_state;
- e_tep_event.motion.time = 0;
- e_tep_event.motion.position = _get_position_from_xy(text, text->lastx, text->lasty);
- _get_tep(text);
- e_text_event_processor_handle_event (text->tep,
- &e_tep_event);
- text->scroll_start = current_time;
- }
- }
-
- if (!((current_time / 500000) % 2)) {
- if (!text->show_cursor)
- redraw = TRUE;
- text->show_cursor = TRUE;
- } else {
- if (text->show_cursor)
- redraw = TRUE;
- text->show_cursor = FALSE;
- }
- if (redraw)
- gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(text));
- return TRUE;
-}
-
-static gint
-e_text_event (GnomeCanvasItem *item, GdkEvent *event)
-{
- EText *text = E_TEXT(item);
- ETextEventProcessorEvent e_tep_event;
-
- gint return_val = 0;
-
- e_tep_event.type = event->type;
- switch (event->type) {
- case GDK_FOCUS_CHANGE:
- if (text->editable) {
- GdkEventFocus *focus_event;
- focus_event = (GdkEventFocus *) event;
- if (focus_event->in) {
- if(!text->editing) {
- text->editing = TRUE;
- if ( text->pointer_in ) {
- if ( text->default_cursor_shown ) {
- gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, text->i_cursor);
- text->default_cursor_shown = FALSE;
- }
- }
- text->selection_start = 0;
- text->selection_end = 0;
- text->select_by_word = FALSE;
- text->xofs_edit = 0;
- if (text->timeout_id == 0)
- text->timeout_id = g_timeout_add(10, _blink_scroll_timeout, text);
- text->timer = g_timer_new();
- g_timer_elapsed(text->timer, &(text->scroll_start));
- g_timer_start(text->timer);
- }
- } else {
- text->editing = FALSE;
- if ( ! text->default_cursor_shown ) {
- gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, text->default_cursor);
- text->default_cursor_shown = TRUE;
- }
- if (text->timeout_id) {
- g_source_remove(text->timeout_id);
- text->timeout_id = 0;
- }
- if (text->timer) {
- g_timer_stop(text->timer);
- g_timer_destroy(text->timer);
- text->timer = NULL;
- }
- }
- if ( text->line_wrap )
- split_into_lines (text);
- else
- calc_line_widths (text);
- recalc_bounds (text);
- }
- return_val = 0;
- break;
- case GDK_KEY_PRESS: /* Fall Through */
- case GDK_KEY_RELEASE:
- if (text->editing) {
- GdkEventKey key = event->key;
- e_tep_event.key.time = key.time;
- e_tep_event.key.state = key.state;
- e_tep_event.key.keyval = key.keyval;
- e_tep_event.key.length = key.length;
- e_tep_event.key.string = key.string;
- _get_tep(text);
- return e_text_event_processor_handle_event (text->tep,
- &e_tep_event);
- }
- else
- return 0;
- break;
- case GDK_BUTTON_PRESS: /* Fall Through */
- case GDK_BUTTON_RELEASE:
- if (text->editing) {
- GdkEventButton button = event->button;
- e_tep_event.button.time = button.time;
- e_tep_event.button.state = button.state;
- e_tep_event.button.button = button.button;
- e_tep_event.button.position = _get_position_from_xy(text, button.x, button.y);
- _get_tep(text);
- return_val = e_text_event_processor_handle_event (text->tep,
- &e_tep_event);
- if (event->button.button == 1) {
- if (event->type == GDK_BUTTON_PRESS)
- text->button_down = TRUE;
- else
- text->button_down = FALSE;
- }
- text->lastx = button.x;
- text->lasty = button.y;
- text->last_state = button.state;
- } else if (text->editable && event->type == GDK_BUTTON_RELEASE && event->button.button == 1) {
- gnome_canvas_item_grab_focus (item);
- return 1;
- }
- break;
- case GDK_MOTION_NOTIFY:
- if (text->editing) {
- GdkEventMotion motion = event->motion;
- e_tep_event.motion.time = motion.time;
- e_tep_event.motion.state = motion.state;
- e_tep_event.motion.position = _get_position_from_xy(text, motion.x, motion.y);
- _get_tep(text);
- return_val = e_text_event_processor_handle_event (text->tep,
- &e_tep_event);
- text->lastx = motion.x;
- text->lasty = motion.y;
- text->last_state = motion.state;
- }
- break;
- case GDK_ENTER_NOTIFY:
- text->pointer_in = TRUE;
- if (text->editing) {
- if ( text->default_cursor_shown ) {
- gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, text->i_cursor);
- text->default_cursor_shown = FALSE;
- }
- }
- break;
- case GDK_LEAVE_NOTIFY:
- text->pointer_in = FALSE;
- if (text->editing) {
- if ( ! text->default_cursor_shown ) {
- gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, text->default_cursor);
- text->default_cursor_shown = TRUE;
- }
- }
- break;
- default:
- break;
- }
- if (return_val)
- return return_val;
- if (GNOME_CANVAS_ITEM_CLASS(parent_class)->event)
- return GNOME_CANVAS_ITEM_CLASS(parent_class)->event(item, event);
- else
- return 0;
-}
-
-static int
-_get_position(EText *text, ETextEventProcessorCommand *command)
-{
- int i;
- int length;
- int x, y;
-
- switch (command->position) {
-
- case E_TEP_VALUE:
- return command->value;
-
- case E_TEP_SELECTION:
- return text->selection_end;
-
- case E_TEP_START_OF_BUFFER:
- return 0;
- case E_TEP_END_OF_BUFFER:
- return strlen(text->text);
-
- case E_TEP_START_OF_LINE:
- for (i = text->selection_end - 2; i > 0; i--)
- if (text->text[i] == '\n') {
- i++;
- break;
- }
- return i;
- case E_TEP_END_OF_LINE:
- length = strlen(text->text);
- for (i = text->selection_end + 1; i < length; i++)
- if (text->text[i] == '\n') {
- break;
- }
- if (i > length)
- i = length;
- return i;
-
- case E_TEP_FORWARD_CHARACTER:
- length = strlen(text->text);
- i = text->selection_end + 1;
- if (i > length)
- i = length;
- return i;
- case E_TEP_BACKWARD_CHARACTER:
- i = text->selection_end - 1;
- if (i < 0)
- i = 0;
- return i;
-
- case E_TEP_FORWARD_WORD:
- length = strlen(text->text);
- for (i = text->selection_end + 1; i < length; i++)
- if (isspace(text->text[i])) {
- break;
- }
- if (i > length)
- i = length;
- return i;
- case E_TEP_BACKWARD_WORD:
- for (i = text->selection_end - 2; i > 0; i--)
- if (isspace(text->text[i])) {
- i++;
- break;
- }
- if (i < 0)
- i = 0;
- return i;
-
- case E_TEP_FORWARD_LINE:
- _get_xy_from_position(text, text->selection_end, &x, &y);
- y += text->font->ascent + text->font->descent;
- return _get_position_from_xy(text, x, y);
- case E_TEP_BACKWARD_LINE:
- _get_xy_from_position(text, text->selection_end, &x, &y);
- y -= text->font->ascent + text->font->descent;
- return _get_position_from_xy(text, x, y);
-
- case E_TEP_FORWARD_PARAGRAPH:
- case E_TEP_BACKWARD_PARAGRAPH:
-
- case E_TEP_FORWARD_PAGE:
- case E_TEP_BACKWARD_PAGE:
- return text->selection_end;
- default:
- return text->selection_end;
- }
-}
-
-static void
-_delete_selection(EText *text)
-{
- gint length = strlen(text->text);
- if (text->selection_end == text->selection_start)
- return;
- if (text->selection_end < text->selection_start) {
- text->selection_end ^= text->selection_start;
- text->selection_start ^= text->selection_end;
- text->selection_end ^= text->selection_start;
- }
- memmove( text->text + text->selection_start,
- text->text + text->selection_end,
- length - text->selection_end + 1 );
- length -= text->selection_end - text->selection_start;
- text->selection_end = text->selection_start;
-}
-
-static void
-_insert(EText *text, char *string, int value)
-{
- if (value > 0) {
- char *temp;
- gint length = strlen(text->text);
- temp = g_new(gchar, length + value + 1);
- strncpy(temp, text->text, text->selection_start);
- strncpy(temp + text->selection_start, string, value);
- strcpy(temp + text->selection_start + value, text->text + text->selection_start);
- g_free(text->text);
- text->text = temp;
- text->selection_start += value;
- text->selection_end = text->selection_start;
- }
-}
-
-static void
-e_text_command(ETextEventProcessor *tep, ETextEventProcessorCommand *command, gpointer data)
-{
- EText *text = E_TEXT(data);
- int sel_start, sel_end;
- switch (command->action) {
- case E_TEP_MOVE:
- text->selection_start = _get_position(text, command);
- text->selection_end = text->selection_start;
- if (text->timer) {
- g_timer_reset(text->timer);
- }
- break;
- case E_TEP_SELECT:
- text->selection_end = _get_position(text, command);
- sel_start = MIN(text->selection_start, text->selection_end);
- sel_end = MAX(text->selection_start, text->selection_end);
- if (sel_start != sel_end) {
- e_text_supply_selection (text, command->time, GDK_SELECTION_PRIMARY, text->text + sel_start, sel_end - sel_start);
- } else if (text->timer) {
- g_timer_reset(text->timer);
- }
- break;
- case E_TEP_DELETE:
- if (text->selection_end == text->selection_start) {
- text->selection_end = _get_position(text, command);
- }
- _delete_selection(text);
- split_into_lines (text);
- recalc_bounds (text);
- if (text->timer) {
- g_timer_reset(text->timer);
- }
- break;
-
- case E_TEP_INSERT:
- if (text->selection_end != text->selection_start) {
- _delete_selection(text);
- }
- _insert(text, command->string, command->value);
- split_into_lines (text);
- recalc_bounds (text);
- if (text->timer) {
- g_timer_reset(text->timer);
- }
- break;
- case E_TEP_COPY:
- sel_start = MIN(text->selection_start, text->selection_end);
- sel_end = MAX(text->selection_start, text->selection_end);
- if (sel_start != sel_end) {
- e_text_supply_selection (text, command->time, clipboard_atom, text->text + sel_start, sel_end - sel_start);
- }
- if (text->timer) {
- g_timer_reset(text->timer);
- }
- break;
- case E_TEP_PASTE:
- e_text_get_selection (text, clipboard_atom, command->time);
- if (text->timer) {
- g_timer_reset(text->timer);
- }
- break;
- case E_TEP_GET_SELECTION:
- e_text_get_selection (text, GDK_SELECTION_PRIMARY, command->time);
- break;
- case E_TEP_ACTIVATE:
- if (text->timer) {
- g_timer_reset(text->timer);
- }
- break;
- case E_TEP_SET_SELECT_BY_WORD:
- text->select_by_word = command->value;
- break;
- case E_TEP_GRAB:
- gnome_canvas_item_grab (GNOME_CANVAS_ITEM(text),
- GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK,
- text->i_cursor,
- command->time);
- break;
- case E_TEP_UNGRAB:
- gnome_canvas_item_ungrab (GNOME_CANVAS_ITEM(text), command->time);
- break;
- case E_TEP_NOP:
- break;
- }
-
- if (!text->button_down) {
- int x;
- int i;
- struct line *lines = text->lines;
- for (lines = text->lines, i = 0; i < text->num_lines ; i++, lines ++) {
- if (lines->text - text->text > text->selection_end) {
- break;
- }
- }
- lines --;
- x = gdk_text_width(text->font,
- lines->text,
- text->selection_end - (lines->text - text->text));
-
-
- if (x < text->xofs_edit) {
- text->xofs_edit = x;
- }
-
- if (2 + x - text->clip_width > text->xofs_edit) {
- text->xofs_edit = 2 + x - text->clip_width;
- }
- }
-
- gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(text));
-}
-
-static void _invisible_destroy (GtkInvisible *invisible,
- EText *text)
-{
- text->invisible = NULL;
-}
-
-static GtkWidget *e_text_get_invisible(EText *text)
-{
- GtkWidget *invisible;
- if (text->invisible) {
- invisible = text->invisible;
- } else {
- invisible = gtk_invisible_new();
- text->invisible = invisible;
-
- gtk_selection_add_target (invisible,
- GDK_SELECTION_PRIMARY,
- GDK_SELECTION_TYPE_STRING,
- E_SELECTION_PRIMARY);
- gtk_selection_add_target (invisible,
- clipboard_atom,
- GDK_SELECTION_TYPE_STRING,
- E_SELECTION_CLIPBOARD);
-
- gtk_signal_connect (GTK_OBJECT(invisible), "selection_get",
- GTK_SIGNAL_FUNC (_selection_get),
- text);
- gtk_signal_connect (GTK_OBJECT(invisible), "selection_clear_event",
- GTK_SIGNAL_FUNC (_selection_clear_event),
- text);
- gtk_signal_connect (GTK_OBJECT(invisible), "selection_received",
- GTK_SIGNAL_FUNC (_selection_received),
- text);
-
- gtk_signal_connect (GTK_OBJECT(invisible), "destroy",
- GTK_SIGNAL_FUNC (_invisible_destroy),
- text);
- }
- return invisible;
-}
-
-static void
-_selection_clear_event (GtkInvisible *invisible,
- GdkEventSelection *event,
- EText *text)
-{
- if (event->selection == GDK_SELECTION_PRIMARY) {
- g_free (text->primary_selection);
- text->primary_selection = NULL;
- text->primary_length = 0;
-
- text->has_selection = FALSE;
- gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(text));
-
- } else if (event->selection == clipboard_atom) {
- g_free (text->clipboard_selection);
- text->clipboard_selection = NULL;
- text->clipboard_length = 0;
- }
-}
-
-static void
-_selection_get (GtkInvisible *invisible,
- GtkSelectionData *selection_data,
- guint info,
- guint time_stamp,
- EText *text)
-{
- switch (info) {
- case E_SELECTION_PRIMARY:
- gtk_selection_data_set (selection_data, GDK_SELECTION_TYPE_STRING,
- 8, text->primary_selection, text->primary_length);
- break;
- case E_SELECTION_CLIPBOARD:
- gtk_selection_data_set (selection_data, GDK_SELECTION_TYPE_STRING,
- 8, text->clipboard_selection, text->clipboard_length);
- break;
- }
-}
-
-static void
-_selection_received (GtkInvisible *invisible,
- GtkSelectionData *selection_data,
- guint time,
- EText *text)
-{
- if (selection_data->length < 0 || selection_data->type != GDK_SELECTION_TYPE_STRING) {
- return;
- } else {
- ETextEventProcessorCommand command;
- command.action = E_TEP_INSERT;
- command.position = E_TEP_SELECTION;
- command.string = selection_data->data;
- command.value = selection_data->length;
- command.time = time;
- e_text_command(text->tep, &command, text);
- }
-}
-
-static void e_text_supply_selection (EText *text, guint time, GdkAtom selection, guchar *data, gint length)
-{
- gboolean successful;
- GtkWidget *invisible;
-
- invisible = e_text_get_invisible(text);
-
- if (selection == GDK_SELECTION_PRIMARY ) {
- if (text->primary_selection) {
- g_free (text->primary_selection);
- }
- text->primary_selection = g_strndup(data, length);
- text->primary_length = length;
- } else if (selection == clipboard_atom) {
- if (text->clipboard_selection) {
- g_free (text->clipboard_selection);
- }
- text->clipboard_selection = g_strndup(data, length);
- text->clipboard_length = length;
- }
-
- successful = gtk_selection_owner_set (invisible,
- selection,
- time);
-
- if (selection == GDK_SELECTION_PRIMARY)
- text->has_selection = successful;
-}
-
-static void
-e_text_get_selection(EText *text, GdkAtom selection, guint32 time)
-{
- GtkWidget *invisible;
- invisible = e_text_get_invisible(text);
- gtk_selection_convert(invisible,
- selection,
- GDK_SELECTION_TYPE_STRING,
- time);
-}
-
-#if 0
-static void
-e_text_real_copy_clipboard (EText *text)
-{
- guint32 time;
- gint selection_start_pos;
- gint selection_end_pos;
-
- g_return_if_fail (text != NULL);
- g_return_if_fail (E_IS_TEXT (text));
-
- time = gtk_text_get_event_time (text);
- selection_start_pos = MIN (text->selection_start, text->selection_end);
- selection_end_pos = MAX (text->selection_start, text->selection_end);
-
- if (selection_start_pos != selection_end_pos)
- {
- if (gtk_selection_owner_set (GTK_WIDGET (text->canvas),
- clipboard_atom,
- time))
- text->clipboard_text = "";
- }
-}
-
-static void
-e_text_real_paste_clipboard (EText *text)
-{
- guint32 time;
-
- g_return_if_fail (text != NULL);
- g_return_if_fail (E_IS_TEXT (text));
-
- time = e_text_get_event_time (text);
- if (text->editable)
- gtk_selection_convert (GTK_WIDGET(text->widget),
- clipboard_atom,
- gdk_atom_intern ("COMPOUND_TEXT", FALSE), time);
-}
-#endif
-
-/* Get the timestamp of the current event. Actually, the only thing
- * we really care about below is the key event
- */
-static guint32
-e_text_get_event_time (EText *text)
-{
- GdkEvent *event;
- guint32 tm = GDK_CURRENT_TIME;
-
- event = gtk_get_current_event();
-
- if (event)
- switch (event->type)
- {
- case GDK_MOTION_NOTIFY:
- tm = event->motion.time; break;
- case GDK_BUTTON_PRESS:
- case GDK_2BUTTON_PRESS:
- case GDK_3BUTTON_PRESS:
- case GDK_BUTTON_RELEASE:
- tm = event->button.time; break;
- case GDK_KEY_PRESS:
- case GDK_KEY_RELEASE:
- tm = event->key.time; break;
- case GDK_ENTER_NOTIFY:
- case GDK_LEAVE_NOTIFY:
- tm = event->crossing.time; break;
- case GDK_PROPERTY_NOTIFY:
- tm = event->property.time; break;
- case GDK_SELECTION_CLEAR:
- case GDK_SELECTION_REQUEST:
- case GDK_SELECTION_NOTIFY:
- tm = event->selection.time; break;
- case GDK_PROXIMITY_IN:
- case GDK_PROXIMITY_OUT:
- tm = event->proximity.time; break;
- default: /* use current time */
- break;
- }
- gdk_event_free(event);
-
- return tm;
-}
-
-
-
-/* Routines for sucking fonts from the X server */
-
-static ETextSuckFont *
-e_suck_font (GdkFont *font)
-{
- ETextSuckFont *suckfont;
- int i;
- int x, y;
- char text[1];
- int lbearing, rbearing, ch_width, ascent, descent;
- GdkPixmap *pixmap;
- GdkColor black, white;
- GdkImage *image;
- GdkGC *gc;
- guchar *line;
- int width, height;
- int black_pixel, pixel;
-
- if (!font)
- return NULL;
-
- suckfont = g_new (ETextSuckFont, 1);
-
- height = font->ascent + font->descent;
- x = 0;
- for (i = 0; i < 256; i++) {
- text[0] = i;
- gdk_text_extents (font, text, 1,
- &lbearing, &rbearing, &ch_width, &ascent, &descent);
- suckfont->chars[i].left_sb = lbearing;
- suckfont->chars[i].right_sb = ch_width - rbearing;
- suckfont->chars[i].width = rbearing - lbearing;
- suckfont->chars[i].ascent = ascent;
- suckfont->chars[i].descent = descent;
- suckfont->chars[i].bitmap_offset = x;
- x += (ch_width + 31) & -32;
- }
-
- width = x;
-
- suckfont->bitmap_width = width;
- suckfont->bitmap_height = height;
- suckfont->ascent = font->ascent;
-
- pixmap = gdk_pixmap_new (NULL, suckfont->bitmap_width,
- suckfont->bitmap_height, 1);
- gc = gdk_gc_new (pixmap);
- gdk_gc_set_font (gc, font);
-
- black_pixel = BlackPixel (gdk_display, DefaultScreen (gdk_display));
- black.pixel = black_pixel;
- white.pixel = WhitePixel (gdk_display, DefaultScreen (gdk_display));
- gdk_gc_set_foreground (gc, &white);
- gdk_draw_rectangle (pixmap, gc, 1, 0, 0, width, height);
-
- gdk_gc_set_foreground (gc, &black);
- for (i = 0; i < 256; i++) {
- text[0] = i;
- gdk_draw_text (pixmap, font, gc,
- suckfont->chars[i].bitmap_offset - suckfont->chars[i].left_sb,
- font->ascent,
- text, 1);
- }
-
- /* The handling of the image leaves me with distinct unease. But this
- * is more or less copied out of gimp/app/text_tool.c, so it _ought_ to
- * work. -RLL
- */
-
- image = gdk_image_get (pixmap, 0, 0, width, height);
- suckfont->bitmap = g_malloc0 ((width >> 3) * height);
-
- line = suckfont->bitmap;
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- pixel = gdk_image_get_pixel (image, x, y);
- if (pixel == black_pixel)
- line[x >> 3] |= 128 >> (x & 7);
- }
- line += width >> 3;
- }
-
- gdk_image_destroy (image);
-
- /* free the pixmap */
- gdk_pixmap_unref (pixmap);
-
- /* free the gc */
- gdk_gc_destroy (gc);
-
- return suckfont;
-}
-
-static void
-e_suck_font_free (ETextSuckFont *suckfont)
-{
- g_free (suckfont->bitmap);
- g_free (suckfont);
-}
diff --git a/widgets/e-text.h b/widgets/e-text.h
deleted file mode 100644
index ef8da442d6..0000000000
--- a/widgets/e-text.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* EText - Text item for evolution.
- * Copyright (C) 2000 Helix Code, Inc.
- *
- * Author: Chris Lahey <clahey@umich.edu>
- *
- * A majority of code taken from:
- *
- * Text item type for GnomeCanvas widget
- *
- * GnomeCanvas is basically a port of the Tk toolkit's most excellent
- * canvas widget. Tk is copyrighted by the Regents of the University
- * of California, Sun Microsystems, and other parties.
- *
- * Copyright (C) 1998 The Free Software Foundation
- *
- * Author: Federico Mena <federico@nuclecu.unam.mx> */
-
-#ifndef E_TEXT_H
-#define E_TEXT_H
-
-#include <gnome.h>
-#include "e-text-event-processor.h"
-
-
-BEGIN_GNOME_DECLS
-
-
-/* Text item for the canvas. Text items are positioned by an anchor point and an anchor direction.
- *
- * A clipping rectangle may be specified for the text. The rectangle is anchored at the text's anchor
- * point, and is specified by clipping width and height parameters. If the clipping rectangle is
- * enabled, it will clip the text.
- *
- * In addition, x and y offset values may be specified. These specify an offset from the anchor
- * position. If used in conjunction with the clipping rectangle, these could be used to implement
- * simple scrolling of the text within the clipping rectangle.
- *
- * The following object arguments are available:
- *
- * name type read/write description
- * ------------------------------------------------------------------------------------------
- * text string RW The string of the text label
- * x double RW X coordinate of anchor point
- * y double RW Y coordinate of anchor point
- * font string W X logical font descriptor
- * fontset string W X logical fontset descriptor
- * font_gdk GdkFont* RW Pointer to a GdkFont
- * anchor GtkAnchorType RW Anchor side for the text
- * justification GtkJustification RW Justification for multiline text
- * fill_color string W X color specification for text
- * fill_color_gdk GdkColor* RW Pointer to an allocated GdkColor
- * fill_stipple GdkBitmap* RW Stipple pattern for filling the text
- * clip_width double RW Width of clip rectangle
- * clip_height double RW Height of clip rectangle
- * clip boolean RW Use clipping rectangle?
- * x_offset double RW Horizontal offset distance from anchor position
- * y_offset double RW Vertical offset distance from anchor position
- * text_width double R Used to query the width of the rendered text
- * text_height double R Used to query the rendered height of the text
- *
- * These are currently ignored in the AA version:
- * editable boolean RW Can this item be edited
- * use_ellipsis boolean RW Whether to use ellipsises if text gets cut off. Meaningless if clip == false.
- * ellipsis string RW The characters to use as ellipsis. NULL = "...".
- * line_wrap boolean RW Line wrap when not editing.
- * max_line_wrap int RW Number of lines possible when doing line wrap.
- *
- * These are not implemented yet:
- * background boolean RW Draw a background rectangle.
- * background_on_edit boolean RW Draw a background when editing.
- */
-
-#define E_TYPE_TEXT (e_text_get_type ())
-#define E_TEXT(obj) (GTK_CHECK_CAST ((obj), E_TYPE_TEXT, EText))
-#define E_TEXT_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_TEXT, ETextClass))
-#define E_IS_TEXT(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_TEXT))
-#define E_IS_TEXT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_TEXT))
-
-
-typedef struct _EText EText;
-typedef struct _ETextClass ETextClass;
-typedef struct _ETextSuckFont ETextSuckFont;
-typedef struct _ETextSuckChar ETextSuckChar;
-
-struct _ETextSuckChar {
- int left_sb;
- int right_sb;
- int width;
- int ascent;
- int descent;
- int bitmap_offset; /* in pixels */
-};
-
-struct _ETextSuckFont {
- guchar *bitmap;
- gint bitmap_width;
- gint bitmap_height;
- gint ascent;
- ETextSuckChar chars[256];
-};
-
-struct _EText {
- GnomeCanvasItem item;
-
- char *text; /* Text to display */
- gpointer lines; /* Text split into lines (private field) */
- int num_lines; /* Number of lines of text */
-
- double x, y; /* Position at anchor */
- GdkFont *font; /* Font for text */
- GtkAnchorType anchor; /* Anchor side for text */
- GtkJustification justification; /* Justification for text */
-
- double clip_width; /* Width of optional clip rectangle */
- double clip_height; /* Height of optional clip rectangle */
-
- double xofs, yofs; /* Text offset distance from anchor position */
-
- gulong pixel; /* Fill color */
- GdkBitmap *stipple; /* Stipple for text */
- GdkGC *gc; /* GC for drawing text */
-
- int cx, cy; /* Top-left canvas coordinates for text */
- int clip_cx, clip_cy; /* Top-left canvas coordinates for clip rectangle */
- int clip_cwidth, clip_cheight; /* Size of clip rectangle in pixels */
- int max_width; /* Maximum width of text lines */
- int height; /* Rendered text height in pixels */
-
- guint clip : 1; /* Use clip rectangle? */
-
- /* Antialiased specific stuff follows */
- ETextSuckFont *suckfont; /* Sucked font */
- guint32 rgba; /* RGBA color for text */
- double affine[6]; /* The item -> canvas affine */
-
- char *ellipsis; /* The ellipsis characters. NULL = "...". */
- double ellipsis_width; /* The width of the ellipsis. */
- gboolean use_ellipsis; /* Whether to use the ellipsis. */
-
- gboolean editable; /* Item is editable */
- gboolean editing; /* Item is currently being edited */
-
- int xofs_edit; /* Offset because of editing */
-
- /* This needs to be reworked a bit once we get line wrapping. */
- int selection_start; /* Start of selection */
- int selection_end; /* End of selection */
- gboolean select_by_word; /* Current selection is by word */
-
- /* This section is for drag scrolling and blinking cursor. */
- gint timeout_id; /* Current timeout id for scrolling */
- GTimer *timer; /* Timer for blinking cursor and scrolling */
-
- gint lastx, lasty; /* Last x and y motion events */
- gint last_state; /* Last state */
- gulong scroll_start; /* Starting time for scroll (microseconds) */
-
- gint show_cursor; /* Is cursor currently shown */
- gboolean button_down; /* Is mouse button 1 down */
-
- ETextEventProcessor *tep; /* Text Event Processor */
-
- GtkWidget *invisible; /* For selection handling */
- gboolean has_selection; /* TRUE if we have the selection */
- gchar *primary_selection; /* Primary selection text */
- gint primary_length; /* Primary selection text length */
- gchar *clipboard_selection; /* Clipboard selection text */
- gint clipboard_length; /* Clipboard selection text length*/
-
- guint pointer_in : 1; /* Is the pointer currently over us? */
- guint default_cursor_shown : 1; /* Is the default cursor currently shown? */
-
- guint line_wrap : 1; /* Do line wrap */
-
- gint max_lines; /* Max number of lines (-1 = infinite) */
-
- GdkCursor *default_cursor; /* Default cursor (arrow) */
- GdkCursor *i_cursor; /* I beam cursor */
-};
-
-struct _ETextClass {
- GnomeCanvasItemClass parent_class;
-
- void (* resize) (EText *text);
- void (* change) (EText *text);
-};
-
-
-/* Standard Gtk function */
-GtkType e_text_get_type (void);
-
-
-END_GNOME_DECLS
-
-#endif
diff --git a/widgets/e-text/e-text.c b/widgets/e-text/e-text.c
index 2e3e7c158a..6647531eee 100644
--- a/widgets/e-text/e-text.c
+++ b/widgets/e-text/e-text.c
@@ -109,8 +109,6 @@ static gint e_text_event (GnomeCanvasItem *item, GdkEvent *event);
static void e_text_command(ETextEventProcessor *tep, ETextEventProcessorCommand *command, gpointer data);
-static guint32 e_text_get_event_time (EText *text);
-
static void e_text_get_selection(EText *text, GdkAtom selection, guint32 time);
static void e_text_supply_selection (EText *text, guint time, GdkAtom selection, guchar *data, gint length);
@@ -1701,7 +1699,7 @@ static void
_get_xy_from_position (EText *text, gint position, gint *xp, gint *yp)
{
if (xp || yp) {
- struct line *lines;
+ struct line *lines = NULL;
int x, y;
int j;
x = get_line_xpos (text, lines);
@@ -1993,7 +1991,9 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event)
}
break;
case GDK_ENTER_NOTIFY:
- text->tooltip_timeout = gtk_timeout_add (3000, _do_tooltip, text);
+ if ( text->tooltip_count == 0 )
+ text->tooltip_timeout = gtk_timeout_add (1000, _do_tooltip, text);
+ text->tooltip_count ++;
text->pointer_in = TRUE;
if (text->editing) {
if ( text->default_cursor_shown ) {
@@ -2003,10 +2003,13 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event)
}
break;
case GDK_LEAVE_NOTIFY:
- gtk_timeout_remove (text->tooltip_timeout);
- if (text->tooltip_window) {
- gtk_widget_destroy (text->tooltip_window);
- text->tooltip_window = NULL;
+ text->tooltip_count --;
+ if ( text->tooltip_count == 0 ) {
+ gtk_timeout_remove (text->tooltip_timeout);
+ if (text->tooltip_window) {
+ gtk_widget_destroy (text->tooltip_window);
+ text->tooltip_window = NULL;
+ }
}
text->pointer_in = FALSE;
@@ -2443,50 +2446,6 @@ e_text_real_paste_clipboard (EText *text)
}
#endif
-/* Get the timestamp of the current event. Actually, the only thing
- * we really care about below is the key event
- */
-static guint32
-e_text_get_event_time (EText *text)
-{
- GdkEvent *event;
- guint32 tm = GDK_CURRENT_TIME;
-
- event = gtk_get_current_event();
-
- if (event)
- switch (event->type)
- {
- case GDK_MOTION_NOTIFY:
- tm = event->motion.time; break;
- case GDK_BUTTON_PRESS:
- case GDK_2BUTTON_PRESS:
- case GDK_3BUTTON_PRESS:
- case GDK_BUTTON_RELEASE:
- tm = event->button.time; break;
- case GDK_KEY_PRESS:
- case GDK_KEY_RELEASE:
- tm = event->key.time; break;
- case GDK_ENTER_NOTIFY:
- case GDK_LEAVE_NOTIFY:
- tm = event->crossing.time; break;
- case GDK_PROPERTY_NOTIFY:
- tm = event->property.time; break;
- case GDK_SELECTION_CLEAR:
- case GDK_SELECTION_REQUEST:
- case GDK_SELECTION_NOTIFY:
- tm = event->selection.time; break;
- case GDK_PROXIMITY_IN:
- case GDK_PROXIMITY_OUT:
- tm = event->proximity.time; break;
- default: /* use current time */
- break;
- }
- gdk_event_free(event);
-
- return tm;
-}
-
/* Routines for sucking fonts from the X server */
diff --git a/widgets/e-text/e-text.h b/widgets/e-text/e-text.h
index c44589d3ae..2f29fb189b 100644
--- a/widgets/e-text/e-text.h
+++ b/widgets/e-text/e-text.h
@@ -176,6 +176,7 @@ struct _EText {
gint tooltip_timeout; /* Timeout for the tooltip */
GtkWidget *tooltip_window; /* GtkWindow for displaying the tooltip */
+ gint tooltip_count; /* GDK_ENTER_NOTIFY count. */
};
struct _ETextClass {
diff --git a/widgets/misc/e-canvas-utils.h b/widgets/misc/e-canvas-utils.h
index 13ec43117c..9580f64f96 100644
--- a/widgets/misc/e-canvas-utils.h
+++ b/widgets/misc/e-canvas-utils.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * e-canvas-utils.c
+ * e-canvas-utils.h
* Copyright (C) 2000 Helix Code, Inc.
* Author: Chris Lahey <clahey@helixcode.com>
*
@@ -20,5 +20,10 @@
* Boston, MA 02111-1307, USA.
*/
+#ifndef __E_CANVAS_UTILS__
+#define __E_CANVAS_UTILS__
+
#include <gnome.h>
void e_canvas_item_move_absolute (GnomeCanvasItem *item, double dx, double dy);
+
+#endif /* __E_CANVAS_UTILS__ */
diff --git a/widgets/misc/e-reflow.c b/widgets/misc/e-reflow.c
index c1022f8f78..984e972f0c 100644
--- a/widgets/misc/e-reflow.c
+++ b/widgets/misc/e-reflow.c
@@ -24,6 +24,7 @@
#include <math.h>
#include "e-reflow.h"
#include "e-canvas-utils.h"
+#include "e-util.h"
static void e_reflow_init (EReflow *card);
static void e_reflow_class_init (EReflowClass *klass);
static void e_reflow_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
@@ -278,7 +279,7 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event)
GList *list;
for (list = e_reflow->items; list; list = list->next) {
GnomeCanvasItem *item = GNOME_CANVAS_ITEM (list->data);
- gboolean has_focus;
+ EFocus has_focus;
gtk_object_get(GTK_OBJECT(item),
"has_focus", &has_focus,
NULL);
@@ -290,7 +291,7 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event)
if (list) {
item = GNOME_CANVAS_ITEM(list->data);
gnome_canvas_item_set(item,
- "has_focus", TRUE,
+ "has_focus", (event->key.state & GDK_SHIFT_MASK) ? E_FOCUS_END : E_FOCUS_START,
NULL);
return 1;
} else {
@@ -625,7 +626,6 @@ e_reflow_point (GnomeCanvasItem *item,
double x, double y, int cx, int cy,
GnomeCanvasItem **actual_item)
{
- EReflow *e_reflow = E_REFLOW(item);
double distance = 1;
if (GNOME_CANVAS_ITEM_CLASS(parent_class)->point)
diff --git a/widgets/table/check-empty.xpm b/widgets/table/check-empty.xpm
index 2dd873e137..746b20234e 100644
--- a/widgets/table/check-empty.xpm
+++ b/widgets/table/check-empty.xpm
@@ -1,5 +1,5 @@
/* XPM */
-static char * check_empty_xpm[] = {
+static const char * check_empty_xpm[] = {
"16 16 2 1",
" c None",
". c #000000",
diff --git a/widgets/table/check-filled.xpm b/widgets/table/check-filled.xpm
index 689d7a7967..c0468fc25b 100644
--- a/widgets/table/check-filled.xpm
+++ b/widgets/table/check-filled.xpm
@@ -1,5 +1,5 @@
/* XPM */
-static char * check_filled_xpm[] = {
+static const char * check_filled_xpm[] = {
"16 16 2 1",
" c None",
". c #000000",
diff --git a/widgets/table/e-cell-text.c b/widgets/table/e-cell-text.c
index 8131d16384..fb33f10537 100644
--- a/widgets/table/e-cell-text.c
+++ b/widgets/table/e-cell-text.c
@@ -120,7 +120,6 @@ typedef struct {
} ECellTextView;
typedef struct _CurrentCell{
-
ECellTextView *text_view;
int width;
gchar *text;
@@ -233,6 +232,10 @@ static void
ect_stop_editing (ECellTextView *text_view)
{
CellEdit *edit = text_view->edit;
+ int row, view_col;
+
+ row = edit->cell.row;
+ view_col = edit->cell.view_col;
g_free (edit->old_text);
edit->old_text = NULL;
@@ -246,12 +249,24 @@ ect_stop_editing (ECellTextView *text_view)
g_free(edit->primary_selection);
if (edit->clipboard_selection)
g_free(edit->clipboard_selection);
+ if ( ! edit->default_cursor_shown ) {
+ gdk_window_set_cursor(GTK_WIDGET(text_view->canvas)->window, NULL);
+ edit->default_cursor_shown = TRUE;
+ }
+ if (edit->timeout_id) {
+ g_source_remove(edit->timeout_id);
+ edit->timeout_id = 0;
+ }
+ if (edit->timer) {
+ g_timer_stop(edit->timer);
+ g_timer_destroy(edit->timer);
+ edit->timer = NULL;
+ }
g_free (edit);
text_view->edit = NULL;
-
- e_table_item_leave_edit (text_view->cell_view.e_table_item_view);
+ ect_queue_redraw (text_view, view_col, row);
}
/*
@@ -260,7 +275,6 @@ ect_stop_editing (ECellTextView *text_view)
static void
ect_cancel_edit (ECellTextView *text_view)
{
- ect_queue_redraw (text_view, text_view->edit->cell.view_col, text_view->edit->cell.row);
ect_stop_editing (text_view);
}
@@ -379,9 +393,11 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
if (edit){
- if ((edit->cell.view_col == view_col) && (edit->cell.row == row))
+ if ((edit->cell.view_col == view_col) && (edit->cell.row == row)) {
edit_display = TRUE;
- fg_gc = canvas->style->fg_gc[edit->has_selection ? GTK_STATE_SELECTED : GTK_STATE_ACTIVE];
+ fg_gc = canvas->style->fg_gc[edit->has_selection ? GTK_STATE_SELECTED : GTK_STATE_ACTIVE];
+ } else
+ fg_gc = canvas->style->fg_gc[GTK_STATE_ACTIVE];
} else {
fg_gc = canvas->style->fg_gc[GTK_STATE_ACTIVE];
}
@@ -776,6 +792,8 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col,
break;
case GDK_BUTTON_PRESS: /* Fall Through */
case GDK_BUTTON_RELEASE:
+ event->button.x -= 4;
+ event->button.y -= 1;
if ((!edit_display)
&& ect->editable
&& event->type == GDK_BUTTON_RELEASE
@@ -828,6 +846,8 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col,
}
break;
case GDK_MOTION_NOTIFY:
+ event->motion.x -= 4;
+ event->motion.y -= 1;
if (edit_display) {
GdkEventMotion motion = event->motion;
e_tep_event.motion.time = motion.time;
@@ -928,15 +948,6 @@ ect_height (ECellView *ecell_view, int model_col, int view_col, int row)
}
/*
- * Callback: invoked when the user pressed "enter" on the GtkEntry
- */
-static void
-ect_entry_activate (GtkEntry *entry, ECellTextView *text_view)
-{
- e_table_item_leave_edit (text_view->cell_view.e_table_item_view);
-}
-
-/*
* ECellView::enter_edit method
*/
static void *
@@ -1011,19 +1022,6 @@ ect_leave_edit (ECellView *ecell_view, int model_col, int view_col, int row, voi
CellEdit *edit = text_view->edit;
if (edit){
- if ( ! edit->default_cursor_shown ) {
- gdk_window_set_cursor(GTK_WIDGET(text_view->canvas)->window, NULL);
- edit->default_cursor_shown = TRUE;
- }
- if (edit->timeout_id) {
- g_source_remove(edit->timeout_id);
- edit->timeout_id = 0;
- }
- if (edit->timer) {
- g_timer_stop(edit->timer);
- g_timer_destroy(edit->timer);
- edit->timer = NULL;
- }
ect_accept_edits (text_view);
ect_stop_editing (text_view);
} else {
@@ -1508,9 +1506,6 @@ e_cell_text_view_command(ETextEventProcessor *tep, ETextEventProcessorCommand *c
break;
case E_TEP_ACTIVATE:
e_table_item_leave_edit (text_view->cell_view.e_table_item_view);
- if (edit->timer) {
- g_timer_reset(edit->timer);
- }
break;
case E_TEP_SET_SELECT_BY_WORD:
edit->select_by_word = command->value;
@@ -1842,7 +1837,9 @@ calc_line_widths (CurrentCell *cell)
}
if (ect->use_ellipsis &&
- ! text_view->edit &&
+ (!(text_view->edit &&
+ cell->row == text_view->edit->cell.row &&
+ cell->view_col == text_view->edit->cell.view_col)) &&
lines->width > cell->width) {
if (font) {
lines->ellipsis_length = 0;
diff --git a/widgets/table/e-cell.c b/widgets/table/e-cell.c
index f1345e8c6b..1d87019007 100644
--- a/widgets/table/e-cell.c
+++ b/widgets/table/e-cell.c
@@ -129,7 +129,7 @@ e_cell_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view
}
void
-e_cell_view_realize (ECellView *ecell_view)
+e_cell_realize (ECellView *ecell_view)
{
return E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->realize (ecell_view);
}
diff --git a/widgets/table/e-cell.h b/widgets/table/e-cell.h
index 3c258689e4..b21653d6d1 100644
--- a/widgets/table/e-cell.h
+++ b/widgets/table/e-cell.h
@@ -2,6 +2,7 @@
#define _E_CELL_H_
#include <gdk/gdktypes.h>
+#include <libgnomeprint/gnome-print.h>
#include "e-table-model.h"
#define E_CELL_TYPE (e_cell_get_type ())
@@ -62,6 +63,9 @@ void e_cell_unrealize (ECellView *ecell_view);
void e_cell_draw (ECellView *ecell_view, GdkDrawable *dr,
int model_col, int view_col, int row, gboolean selected,
int x1, int y1, int x2, int y2);
+void e_cell_print (ECellView *ecell_view, GnomePrintContext *context,
+ int model_col, int view_col, int row,
+ double width, double height);
void e_cell_focus (ECellView *ecell_view, int model_col, int view_col, int row,
int x1, int y1, int x2, int y2);
void e_cell_unfocus (ECellView *ecell_view);
diff --git a/widgets/table/e-table-group-container.c b/widgets/table/e-table-group-container.c
new file mode 100644
index 0000000000..a9f494db04
--- /dev/null
+++ b/widgets/table/e-table-group-container.c
@@ -0,0 +1,804 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * E-Table-Group.c: Implements the grouping objects for elements on a table
+ *
+ * Author:
+ * Miguel de Icaza (miguel@gnu.org()
+ *
+ * Copyright 1999, Helix Code, Inc.
+ */
+
+#include <config.h>
+#include <gtk/gtksignal.h>
+#include "e-table-group-container.h"
+#include "e-table-item.h"
+#include <libgnomeui/gnome-canvas-rect-ellipse.h>
+#include "e-util/e-util.h"
+#include "e-util/e-canvas-utils.h"
+#include "widgets/e-text/e-text.h"
+
+#define TITLE_HEIGHT 16
+#define GROUP_INDENT 10
+
+#define BUTTON_HEIGHT 10
+#define BUTTON_PADDING 2
+
+#define PARENT_TYPE e_table_group_get_type ()
+
+static GnomeCanvasGroupClass *etgc_parent_class;
+
+/* The arguments we take */
+enum {
+ ARG_0,
+ ARG_HEIGHT,
+ ARG_WIDTH,
+ ARG_FROZEN
+};
+
+static void etgc_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+static void etgc_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+
+static int etgc_event (GnomeCanvasItem *item, GdkEvent *event);
+static void etgc_realize (GnomeCanvasItem *item);
+static void etgc_unrealize (GnomeCanvasItem *item);
+
+static void etgc_add (ETableGroup *etg, gint row);
+static gboolean etgc_remove (ETableGroup *etg, gint row);
+static void etgc_increment (ETableGroup *etg, gint position, gint amount);
+static void etgc_set_focus (ETableGroup *etg, EFocus direction, gint view_col);
+
+static void etgc_child_resize (GtkObject *object, gpointer data);
+
+static void etgc_queue_reposition (ETableGroupContainer *etgc);
+
+typedef struct {
+ ETableGroup *child;
+ void *key;
+ GnomeCanvasItem *text;
+ GnomeCanvasItem *rect;
+ gint count;
+} ETableGroupContainerChildNode;
+
+static void
+etgc_destroy (GtkObject *object)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (object);
+
+ gdk_font_unref(etgc->font);
+
+ GTK_OBJECT_CLASS (etgc_parent_class)->destroy (object);
+}
+#if 0
+void
+e_table_group_add (ETableGroup *etg, GnomeCanvasItem *item)
+{
+ double x1, y1, x2, y2;
+
+ g_return_if_fail (etg != NULL);
+ g_return_if_fail (item != NULL);
+ g_return_if_fail (E_IS_TABLE_GROUP (etg));
+ g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
+
+ etg->children = g_list_append (etg->children, item);
+
+ GNOME_CANVAS_ITEM_CLASS (GTK_OBJECT (etg)->klass)->bounds (etg, &x1, &y1, &x2, &y2);
+
+ if (GTK_OBJECT (etg)->flags & GNOME_CANVAS_ITEM_REALIZED){
+ GList *l;
+ int height = etg->transparent ? 0 : TITLE_HEIGHT;
+ int x = etg->transparent ? 0 : GROUP_INDENT;
+
+ for (l = etg->children; l->next; l = l->next){
+ GnomeCanvasItem *child = l->data;
+
+ height += child->y2 - child->y1;
+
+ printf ("Height\n");
+ if (E_IS_TABLE_ITEM (item)){
+ printf (" Item: ");
+ } else {
+ printf (" Group: ");
+ }
+ printf ("%d\n", child->y2-child->y1);
+ }
+
+ e_canvas_item_move_absolute ( item, x, height);
+
+
+ if (E_IS_TABLE_ITEM (item)){
+
+ printf ("Table item! ---------\n");
+ gtk_signal_connect (GTK_OBJECT (item), "resize",
+ GTK_SIGNAL_FUNC (etg_relayout), etg);
+ }
+ }
+}
+
+static void
+etg_realize (GnomeCanvasItem *item)
+{
+ ETableGroup *etg = E_TABLE_GROUP (item);
+ GList *l;
+ int height = 0;
+
+ GNOME_CANVAS_ITEM_CLASS (etg_parent_class)->realize (item);
+
+ for (l = etg->children; l; l = l->next){
+ GnomeCanvasItem *child = l->data;
+
+ printf ("During realization for child %p -> %d\n", child, height);
+ gnome_canvas_item_set (
+ child,
+ "y", (double) height,
+ NULL);
+
+ height += child->y2 - child->y1;
+ }
+}
+
+static void
+etg_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
+{
+ ETableGroup *etg = E_TABLE_GROUP (item);
+
+ GNOME_CANVAS_ITEM_CLASS (etg_parent_class)->update (item, affine, clip_path, flags);
+
+ if (!etg->transparent){
+ int current_width, current_height;
+
+ etg_dim (etg, &current_width, &current_height);
+
+ if ((current_height != etg->height) || (current_width != etg->width)){
+ etg->width = current_width;
+ etg->height = current_height;
+
+ gnome_canvas_item_set (
+ etg->rect,
+ "x1", 0.0,
+ "y1", 0.0,
+ "x2", (double) etg->width,
+ "y2", (double) etg->height,
+ NULL);
+ }
+ }
+}
+#endif
+
+void
+e_table_group_container_construct (GnomeCanvasGroup *parent, ETableGroupContainer *etgc,
+ ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model, ETableCol *ecol, xmlNode *child_rules)
+{
+ e_table_group_construct (parent, E_TABLE_GROUP (etgc), full_header, header, model);
+ etgc->ecol = ecol;
+ etgc->child_rules = child_rules;
+
+ etgc->font = gdk_font_load ("lucidasans-10");
+#if 0
+ etgc->open = open;
+ etgc->transparent = transparent;
+
+ etgc_dim (etgc, &etgc->width, &etgc->height);
+
+ if (!etgc->transparent)
+ etgc->rect = gnome_canvas_item_new (
+ GNOME_CANVAS_GROUP (etgc),
+ gnome_canvas_rect_get_type (),
+ "fill_color", "gray",
+ "outline_color", "gray20",
+ "x1", 0.0,
+ "y1", 0.0,
+ "x2", (double) etgc->width,
+ "y2", (double) etgc->height,
+ NULL);
+#endif
+
+#if 0
+ /*
+ * Reparent the child into our space.
+ */
+ gnome_canvas_item_reparent (child, GNOME_CANVAS_GROUP (etgc));
+
+ gnome_canvas_item_set (
+ child,
+ "x", (double) GROUP_INDENT,
+ "y", (double) TITLE_HEIGHT,
+ NULL);
+
+ /*
+ * Force dimension computation
+ */
+ GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->update (
+ GNOME_CANVAS_ITEM (etgc), NULL, NULL, GNOME_CANVAS_UPDATE_REQUESTED);
+#endif
+}
+
+ETableGroup *
+e_table_group_container_new (GnomeCanvasGroup *parent, ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model, ETableCol *ecol, xmlNode *child_rules)
+{
+ ETableGroupContainer *etgc;
+
+ g_return_val_if_fail (parent != NULL, NULL);
+ g_return_val_if_fail (ecol != NULL, NULL);
+
+ etgc = gtk_type_new (e_table_group_container_get_type ());
+
+ e_table_group_container_construct (parent, etgc, full_header, header,
+ model, ecol, child_rules);
+ return E_TABLE_GROUP (etgc);
+}
+
+#if 0
+static void
+etgc_relayout (GnomeCanvasItem *eti, ETableGroupContainer *etgc)
+{
+ GList *l;
+ int height = etgc->transparent ? 0 : GROUP_INDENT;
+ gboolean move = FALSE;
+
+ printf ("Relaying out\n");
+
+ for (l = etgc->children; l->next; l = l->next){
+ GnomeCanvasItem *child = l->data;
+
+ height += child->y2 - child->y1;
+
+ if (child == eti)
+ move = TRUE;
+
+ if (move){
+ printf ("Moving item %p\n", child);
+ gnome_canvas_item_set ( child,
+ "y", (double) height,
+ NULL);
+ }
+ }
+ if (height != etgc->height){
+ etgc->height = height;
+ gtk_signal_emit (GTK_OBJECT (etgc), etgc_signals [RESIZE]);
+ }
+}
+
+void
+e_table_group_container_add (ETableGroupContainer *etgc, GnomeCanvasItem *item)
+{
+ double x1, y1, x2, y2;
+
+ g_return_if_fail (etgc != NULL);
+ g_return_if_fail (item != NULL);
+ g_return_if_fail (E_IS_TABLE_GROUP (etgc));
+ g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
+
+ etgc->children = g_list_append (etgc->children, item);
+
+ GNOME_CANVAS_ITEM_CLASS (GTK_OBJECT (etgc)->klass)->bounds (etgc, &x1, &y1, &x2, &y2);
+
+ if (GTK_OBJECT (etgc)->flags & GNOME_CANVAS_ITEM_REALIZED){
+ GList *l;
+ int height = etgc->transparent ? 0 : TITLE_HEIGHT;
+ int x = etgc->transparent ? 0 : GROUP_INDENT;
+
+ for (l = etgc->children; l->next; l = l->next){
+ GnomeCanvasItem *child = l->data;
+
+ height += child->y2 - child->y1;
+
+ printf ("Height\n");
+ if (E_IS_TABLE_ITEM (item)){
+ printf (" Item: ");
+ } else {
+ printf (" Group: ");
+ }
+ printf ("%d\n", child->y2-child->y1);
+ }
+
+ e_canvas_item_move_absolute ( item, x, height);
+
+
+ if (E_IS_TABLE_ITEM (item)){
+
+ printf ("Table item! ---------\n");
+ gtk_signal_connect (GTK_OBJECT (item), "resize",
+ GTK_SIGNAL_FUNC (etgc_relayout), etgc);
+ }
+ }
+}
+
+static void
+etgc_realize (GnomeCanvasItem *item)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (item);
+ GList *l;
+ int height = 0;
+
+ GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->realize (item);
+
+ for (l = etgc->children; l; l = l->next){
+ GnomeCanvasItem *child = l->data;
+
+ printf ("During realization for child %p -> %d\n", child, height);
+ gnome_canvas_item_set (
+ child,
+ "y", (double) height,
+ NULL);
+
+ height += child->y2 - child->y1;
+ }
+}
+
+static void
+etgc_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (item);
+
+ GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->update (item, affine, clip_path, flags);
+
+ if ( etgc->need_resize ) {
+
+ if (!etgc->transparent){
+ int current_width, current_height;
+
+ etgc_dim (etgc, &current_width, &current_height);
+
+ if ((current_height != etgc->height) || (current_width != etgc->width)){
+ etgc->width = current_width;
+ etgc->height = current_height;
+
+ gnome_canvas_item_set (
+ etgc->rect,
+ "x1", 0.0,
+ "y1", 0.0,
+ "x2", (double) etgc->width,
+ "y2", (double) etgc->height,
+ NULL);
+ }
+ }
+ etgc->need_resize = FALSE;
+ }
+}
+#endif
+
+static int
+etgc_event (GnomeCanvasItem *item, GdkEvent *event)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(item);
+ gboolean return_val = TRUE;
+ gboolean change_focus = FALSE;
+ gboolean use_col = FALSE;
+ gint start_col = 0;
+ gint old_col;
+ EFocus direction = E_FOCUS_START;
+
+ switch (event->type) {
+ case GDK_KEY_PRESS:
+ if (event->key.keyval == GDK_Tab ||
+ event->key.keyval == GDK_KP_Tab ||
+ event->key.keyval == GDK_ISO_Left_Tab) {
+ change_focus = TRUE;
+ use_col = TRUE;
+ start_col = (event->key.state & GDK_SHIFT_MASK) ? -1 : 0;
+ direction = (event->key.state & GDK_SHIFT_MASK) ? E_FOCUS_END : E_FOCUS_START;
+ } else if (event->key.keyval == GDK_Left ||
+ event->key.keyval == GDK_KP_Left) {
+ change_focus = TRUE;
+ use_col = TRUE;
+ start_col = -1;
+ direction = E_FOCUS_END;
+ } else if (event->key.keyval == GDK_Right ||
+ event->key.keyval == GDK_KP_Right) {
+ change_focus = TRUE;
+ use_col = TRUE;
+ start_col = 0;
+ direction = E_FOCUS_START;
+ } else if (event->key.keyval == GDK_Down ||
+ event->key.keyval == GDK_KP_Down) {
+ change_focus = TRUE;
+ use_col = FALSE;
+ direction = E_FOCUS_START;
+ } else if (event->key.keyval == GDK_Up ||
+ event->key.keyval == GDK_KP_Up) {
+ change_focus = TRUE;
+ use_col = FALSE;
+ direction = E_FOCUS_END;
+ } else if (event->key.keyval == GDK_Return ||
+ event->key.keyval == GDK_KP_Enter) {
+ change_focus = TRUE;
+ use_col = FALSE;
+ direction = E_FOCUS_START;
+ }
+ if ( change_focus ) {
+ GList *list;
+ for (list = etgc->children; list; list = list->next) {
+ ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *)list->data;
+ ETableGroup *child = child_node->child;
+ if (e_table_group_get_focus(child)) {
+ old_col = e_table_group_get_focus_column(child);
+
+ if (direction == E_FOCUS_END)
+ list = list->prev;
+ else
+ list = list->next;
+
+ if (list) {
+ child_node = (ETableGroupContainerChildNode *)list->data;
+ child = child_node->child;
+ if (use_col)
+ e_table_group_set_focus(child, direction, start_col);
+ else {
+ e_table_group_set_focus(child, direction, old_col);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+ }
+ }
+ return_val = FALSE;
+ default:
+ return_val = FALSE;
+ }
+ if ( return_val == FALSE ) {
+ if ( GNOME_CANVAS_ITEM_CLASS(etgc_parent_class)->event )
+ return GNOME_CANVAS_ITEM_CLASS(etgc_parent_class)->event(item, event);
+ }
+ return return_val;
+
+}
+
+/* Realize handler for the text item */
+static void
+etgc_realize (GnomeCanvasItem *item)
+{
+ ETableGroupContainer *etgc;
+
+ if (GNOME_CANVAS_ITEM_CLASS(etgc_parent_class)->realize)
+ (* GNOME_CANVAS_ITEM_CLASS(etgc_parent_class)->realize) (item);
+
+ etgc = E_TABLE_GROUP_CONTAINER (item);
+}
+
+/* Unrealize handler for the etgc item */
+static void
+etgc_unrealize (GnomeCanvasItem *item)
+{
+ ETableGroupContainer *etgc;
+
+ etgc = E_TABLE_GROUP_CONTAINER (item);
+
+ etgc->font = NULL;
+
+ if (GNOME_CANVAS_ITEM_CLASS(etgc_parent_class)->unrealize)
+ (* GNOME_CANVAS_ITEM_CLASS(etgc_parent_class)->unrealize) (item);
+}
+
+static void
+compute_text (ETableGroupContainer *etgc, ETableGroupContainerChildNode *child_node)
+{
+ /* FIXME : What a hack, eh? */
+ gchar *text = g_strdup_printf("%s : %s (%d items)", etgc->ecol->text, (gchar *)child_node->key, (gint) child_node->count);
+ gnome_canvas_item_set(child_node->text,
+ "text", text,
+ NULL);
+ g_free(text);
+}
+
+static void etgc_add (ETableGroup *etg, gint row)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(etg);
+ void *val = e_table_model_value_at (etg->model, etgc->ecol->col_idx, row);
+ GCompareFunc comp = etgc->ecol->compare;
+ GList *list = etgc->children;
+ ETableGroup *child;
+ ETableGroupContainerChildNode *child_node;
+ for ( ; list; list = g_list_next(list) ) {
+ child_node = (ETableGroupContainerChildNode *)(list->data);
+ if ( (*comp)(child_node->key, val) ) {
+ child = child_node->child;
+ child_node->count ++;
+ e_table_group_add(child, row);
+ compute_text(etgc, child_node);
+ return;
+ }
+ }
+ child_node = g_new(ETableGroupContainerChildNode, 1);
+ child_node->rect = gnome_canvas_item_new(GNOME_CANVAS_GROUP(etgc),
+ gnome_canvas_rect_get_type (),
+ "fill_color", "grey70",
+ "outline_color", "grey50",
+ NULL);
+ child_node->text = gnome_canvas_item_new(GNOME_CANVAS_GROUP(etgc),
+ e_text_get_type(),
+ "font_gdk", etgc->font,
+ "anchor", GTK_ANCHOR_SW,
+ "x", (double) 0,
+ "y", (double) 0,
+ "fill_color", "black",
+ NULL);
+ child = e_table_group_new(GNOME_CANVAS_GROUP(etgc), etg->full_header, etg->header, etg->model, etgc->child_rules);
+ child_node->child = child;
+ child_node->key = val;
+
+ gtk_signal_connect(GTK_OBJECT(child), "resize",
+ etgc_child_resize, etgc);
+ child_node->count = 1;
+ e_table_group_add(child, row);
+ etgc->children = g_list_append(etgc->children, child_node);
+ compute_text(etgc, child_node);
+ etgc_queue_reposition(E_TABLE_GROUP_CONTAINER(etg));
+}
+
+static gboolean etgc_remove (ETableGroup *etg, gint row)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(etg);
+ GList *list = etgc->children;
+ for ( ; list; list = g_list_next(list) ) {
+ ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data;
+ ETableGroup *child = child_node->child;
+ if ( e_table_group_remove(child, row) ) {
+ child_node->count --;
+ if ( child_node->count == 0 ) {
+ gtk_object_unref(GTK_OBJECT(child_node->text));
+ gtk_object_unref(GTK_OBJECT(child));
+ etgc->children = g_list_remove(etgc->children, child_node);
+ g_free(child_node);
+ } else {
+ compute_text(etgc, child_node);
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+ etgc_queue_reposition(E_TABLE_GROUP_CONTAINER(etg));
+}
+
+static void etgc_increment (ETableGroup *etg, gint position, gint amount)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(etg);
+ GList *list = etgc->children;
+ for ( ; list; list = g_list_next(list) ) {
+ e_table_group_increment(((ETableGroupContainerChildNode *)list->data)->child, position, amount);
+ }
+ etgc_queue_reposition(E_TABLE_GROUP_CONTAINER(etg));
+}
+
+static void etgc_set_focus (ETableGroup *etg, EFocus direction, gint view_col)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(etg);
+ if (etgc->children) {
+ if (direction == E_FOCUS_END) {
+ e_table_group_set_focus(((ETableGroupContainerChildNode *)g_list_last(etgc->children)->data)->child, direction, view_col);
+ } else {
+ e_table_group_set_focus(((ETableGroupContainerChildNode *)etgc->children->data)->child, direction, view_col);
+ }
+ }
+ etgc_queue_reposition(E_TABLE_GROUP_CONTAINER(etg));
+}
+
+static gint
+etgc_get_focus_column (ETableGroup *etg)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(etg);
+ if (etgc->children) {
+ GList *list;
+ for (list = etgc->children; list; list = list->next) {
+ ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *)list->data;
+ ETableGroup *child = child_node->child;
+ if (e_table_group_get_focus(child)) {
+ return e_table_group_get_focus_column(child);
+ }
+ }
+ }
+ return 0;
+}
+
+static void etgc_thaw (ETableGroup *etg)
+{
+ etgc_queue_reposition(E_TABLE_GROUP_CONTAINER(etg));
+}
+
+static void
+etgc_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ ETableGroup *etg = E_TABLE_GROUP (object);
+
+ switch (arg_id) {
+ case ARG_FROZEN:
+ if ( GTK_VALUE_BOOL (*arg) )
+ etg->frozen = TRUE;
+ else {
+ etg->frozen = FALSE;
+ etgc_thaw(etg);
+ }
+ break;
+ case ARG_WIDTH:
+ if ( E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->set_width )
+ E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->set_width(etg, GTK_VALUE_DOUBLE (*arg));
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+etgc_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ ETableGroup *etg = E_TABLE_GROUP (object);
+
+ switch (arg_id) {
+ case ARG_FROZEN:
+ GTK_VALUE_BOOL (*arg) = etg->frozen;
+ break;
+ case ARG_HEIGHT:
+ if ( E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_height )
+ GTK_VALUE_DOUBLE (*arg) = E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_height(etg);
+ else
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ case ARG_WIDTH:
+ if ( E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_width )
+ GTK_VALUE_DOUBLE (*arg) = E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_width(etg);
+ else
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ }
+}
+
+static void etgc_set_width (ETableGroup *etg, gdouble width)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg);
+ GList *list = etgc->children;
+ etgc->width = width;
+
+ for ( ; list; list = g_list_next(list) ) {
+ gdouble child_width = width - GROUP_INDENT;
+ gtk_object_set(GTK_OBJECT(((ETableGroupContainerChildNode *)list->data)->child),
+ "width", child_width,
+ NULL);
+ }
+
+ etgc_queue_reposition(E_TABLE_GROUP_CONTAINER(etg));
+}
+
+static gdouble etgc_get_width (ETableGroup *etg)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg);
+ return etgc->width;
+}
+
+static gdouble etgc_get_height (ETableGroup *etg)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg);
+ return etgc->height;
+}
+
+static void
+etgc_class_init (GtkObjectClass *object_class)
+{
+ GnomeCanvasItemClass *item_class = (GnomeCanvasItemClass *) object_class;
+ ETableGroupClass *e_group_class = E_TABLE_GROUP_CLASS( object_class );
+
+ object_class->destroy = etgc_destroy;
+ object_class->set_arg = etgc_set_arg;
+ object_class->get_arg = etgc_get_arg;
+
+ item_class->event = etgc_event;
+ item_class->realize = etgc_realize;
+ item_class->unrealize = etgc_unrealize;
+
+ etgc_parent_class = gtk_type_class (PARENT_TYPE);
+
+ e_group_class->add = etgc_add;
+ e_group_class->remove = etgc_remove;
+ e_group_class->increment = etgc_increment;
+ e_group_class->set_focus = etgc_set_focus;
+ e_group_class->get_focus_column = etgc_get_focus_column;
+ e_group_class->thaw = etgc_thaw;
+
+ e_group_class->get_width = etgc_get_width;
+ e_group_class->set_width = etgc_set_width;
+ e_group_class->get_height = etgc_get_height;
+
+ 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_READWRITE, ARG_WIDTH);
+ gtk_object_add_arg_type ("ETableGroupContainer::frozen", GTK_TYPE_BOOL,
+ GTK_ARG_READWRITE, ARG_FROZEN);
+}
+
+static void
+etgc_init (GtkObject *object)
+{
+ ETableGroupContainer *container = E_TABLE_GROUP_CONTAINER(object);
+ container->children = FALSE;
+}
+
+static gboolean
+etgc_update_positioning (ETableGroupContainer *etgc, gpointer data)
+{
+ gboolean frozen;
+ gtk_object_get(GTK_OBJECT(etgc),
+ "frozen", &frozen,
+ NULL);
+ if ( frozen ) {
+ etgc->idle = 0;
+ return FALSE;
+ }
+ if ( GTK_OBJECT_FLAGS( etgc ) & GNOME_CANVAS_ITEM_REALIZED ) {
+ gdouble old_height;
+
+ old_height = etgc->height;
+ if ( etgc->children == NULL ) {
+ } else {
+ GList *list;
+ gdouble extra_height;
+ gdouble running_height;
+ gdouble item_height = 0;
+
+ extra_height = 0;
+ if (etgc->font)
+ extra_height += etgc->font->ascent + etgc->font->descent + BUTTON_PADDING * 2;
+
+ extra_height = MAX(extra_height, BUTTON_HEIGHT + BUTTON_PADDING * 2);
+
+ running_height = extra_height;
+
+ list = etgc->children;
+ for ( ; list; list = g_list_next(list) ) {
+ ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data;
+ ETableGroup *child = child_node->child;
+ gtk_object_get( GTK_OBJECT(child),
+ "height", &item_height,
+ NULL );
+
+ e_canvas_item_move_absolute(GNOME_CANVAS_ITEM(child_node->text),
+ GROUP_INDENT,
+ running_height - BUTTON_PADDING);
+
+ e_canvas_item_move_absolute(GNOME_CANVAS_ITEM(child),
+ GROUP_INDENT,
+ running_height);
+
+ gnome_canvas_item_set(GNOME_CANVAS_ITEM(child_node->rect),
+ "x1", (double) 0,
+ "x2", (double) etgc->width,
+ "y1", (double) running_height - extra_height,
+ "y2", (double) running_height + item_height,
+ NULL);
+
+ running_height += item_height + extra_height;
+ }
+ running_height -= extra_height;
+ if ( running_height != old_height) {
+ etgc->height = running_height;
+ gtk_signal_emit_by_name (GTK_OBJECT (etgc), "resize");
+ }
+ }
+ }
+ etgc->idle = 0;
+ return FALSE;
+}
+
+static void
+etgc_queue_reposition (ETableGroupContainer *etgc)
+{
+ if (etgc->idle == 0)
+ etgc->idle = g_idle_add((GSourceFunc)etgc_update_positioning, etgc);
+}
+
+static void
+etgc_child_resize (GtkObject *object, gpointer data)
+{
+ ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(data);
+ etgc_queue_reposition (etgc);
+}
+
+E_MAKE_TYPE (e_table_group_container, "ETableGroupContainer", ETableGroupContainer, etgc_class_init, etgc_init, PARENT_TYPE);
+
diff --git a/widgets/table/e-table-group-container.h b/widgets/table/e-table-group-container.h
new file mode 100644
index 0000000000..4942f9e695
--- /dev/null
+++ b/widgets/table/e-table-group-container.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+#ifndef _E_TABLE_GROUP_CONTAINER_H_
+#define _E_TABLE_GROUP_CONTAINER_H_
+
+#include <libgnomeui/gnome-canvas.h>
+#include "e-table-model.h"
+#include "e-table-header.h"
+#include "e-table-group.h"
+
+#define E_TABLE_GROUP_CONTAINER_TYPE (e_table_group_container_get_type ())
+#define E_TABLE_GROUP_CONTAINER(o) (GTK_CHECK_CAST ((o), E_TABLE_GROUP_CONTAINER_TYPE, ETableGroupContainer))
+#define E_TABLE_GROUP_CONTAINER_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_GROUP_CONTAINER_TYPE, ETableGroupContainerClass))
+#define E_IS_TABLE_GROUP_CONTAINER(o) (GTK_CHECK_TYPE ((o), E_TABLE_GROUP_CONTAINER_TYPE))
+#define E_IS_TABLE_GROUP_CONTAINER_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_GROUP_CONTAINER_TYPE))
+
+typedef struct {
+ ETableGroup group;
+
+ /*
+ * The ETableCol used to group this set
+ */
+ ETableCol *ecol;
+
+ /*
+ * List of ETableGroups we stack
+ */
+ GList *children;
+
+ /*
+ * The canvas rectangle that contains the children
+ */
+ GnomeCanvasItem *rect;
+
+ GdkFont *font;
+
+ gdouble width, height;
+
+ void *child_rules;
+
+ gint idle;
+
+ /*
+ * Update booleans:
+ */
+ guint need_resize : 1;
+
+ /*
+ * State: the ETableGroup is open or closed
+ */
+ guint open:1;
+} ETableGroupContainer;
+
+typedef struct {
+ ETableGroupClass parent_class;
+} ETableGroupContainerClass;
+
+ETableGroup *e_table_group_container_new (GnomeCanvasGroup *parent, ETableHeader *full_header, ETableHeader *header,
+ ETableModel *model, ETableCol *ecol, xmlNode *child_rules);
+void e_table_group_container_construct (GnomeCanvasGroup *parent, ETableGroupContainer *etgc,
+ ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model, ETableCol *ecol, xmlNode *child_rules);
+
+GtkType e_table_group_container_get_type (void);
+
+#endif /* _E_TABLE_GROUP_CONTAINER_H_ */
diff --git a/widgets/table/e-table-group-leaf.c b/widgets/table/e-table-group-leaf.c
new file mode 100644
index 0000000000..ba73ad9886
--- /dev/null
+++ b/widgets/table/e-table-group-leaf.c
@@ -0,0 +1,288 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * E-Table-Group.c: Implements the grouping objects for elements on a table
+ *
+ * Author:
+ * Miguel de Icaza (miguel@gnu.org()
+ *
+ * Copyright 1999, Helix Code, Inc.
+ */
+
+#include <config.h>
+#include <gtk/gtksignal.h>
+#include "e-table-group-leaf.h"
+#include "e-table-item.h"
+#include <libgnomeui/gnome-canvas-rect-ellipse.h>
+#include "e-util/e-util.h"
+
+#define TITLE_HEIGHT 16
+#define GROUP_INDENT 10
+
+#define PARENT_TYPE e_table_group_get_type ()
+
+static GnomeCanvasGroupClass *etgl_parent_class;
+
+/* The arguments we take */
+enum {
+ ARG_0,
+ ARG_HEIGHT,
+ ARG_WIDTH,
+ ARG_FROZEN
+};
+
+static void etgl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+static void etgl_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+
+static void
+etgl_destroy (GtkObject *object)
+{
+ GTK_OBJECT_CLASS (etgl_parent_class)->destroy (object);
+}
+
+static void
+e_table_group_leaf_construct (GnomeCanvasGroup *parent, ETableGroupLeaf *etgl,
+ ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model)
+{
+ e_table_group_construct (parent, E_TABLE_GROUP (etgl), full_header, header, model);
+ etgl->subset = E_TABLE_SUBSET_VARIABLE(e_table_subset_variable_new(model));
+}
+
+ETableGroup *
+e_table_group_leaf_new (GnomeCanvasGroup *parent, ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model)
+{
+ ETableGroupLeaf *etgl;
+
+ g_return_val_if_fail (parent != NULL, NULL);
+
+ etgl = gtk_type_new (e_table_group_leaf_get_type ());
+
+ e_table_group_leaf_construct (parent, etgl, full_header,
+ header, model);
+ return E_TABLE_GROUP (etgl);
+}
+
+static void
+etgl_resize (GtkObject *object, gpointer data)
+{
+ e_table_group_resize (E_TABLE_GROUP(data));
+}
+
+static void
+etgl_realize (GnomeCanvasItem *item)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF(item);
+ gdouble height;
+
+ if ( GNOME_CANVAS_ITEM_CLASS (etgl_parent_class)->realize )
+ GNOME_CANVAS_ITEM_CLASS (etgl_parent_class)->realize (item);
+
+ etgl->item = E_TABLE_ITEM(gnome_canvas_item_new(GNOME_CANVAS_GROUP(etgl),
+ e_table_item_get_type (),
+ "ETableHeader", E_TABLE_GROUP(etgl)->header,
+ "ETableModel", etgl->subset,
+ "drawgrid", TRUE,
+ "drawfocus", TRUE,
+ "spreadsheet", TRUE,
+ "width", etgl->width,
+ NULL));
+ gtk_signal_connect(GTK_OBJECT(etgl->item),
+ "resize", etgl_resize, etgl);
+ gtk_object_get(GTK_OBJECT(etgl->item),
+ "height", &height,
+ NULL);
+ if ( height != 1 )
+ e_table_group_resize(E_TABLE_GROUP(etgl));
+}
+
+static int
+etgl_event (GnomeCanvasItem *item, GdkEvent *event)
+{
+ gboolean return_val = TRUE;
+
+ switch (event->type) {
+
+ default:
+ return_val = FALSE;
+ }
+ if ( return_val == FALSE ) {
+ if ( GNOME_CANVAS_ITEM_CLASS(etgl_parent_class)->event )
+ return GNOME_CANVAS_ITEM_CLASS(etgl_parent_class)->event(item, event);
+ }
+ return return_val;
+
+}
+
+static void
+etgl_add (ETableGroup *etg, gint row)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
+ e_table_subset_variable_add(etgl->subset, row);
+}
+
+static gboolean
+etgl_remove (ETableGroup *etg, gint row)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
+ return e_table_subset_variable_remove(etgl->subset, row);
+}
+
+static void
+etgl_increment (ETableGroup *etg, gint position, gint amount)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
+ e_table_subset_variable_increment(etgl->subset, position, amount);
+}
+
+static void
+etgl_set_focus (ETableGroup *etg, EFocus direction, gint view_col)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
+ if (direction == E_FOCUS_END) {
+ e_table_item_focus(etgl->item, view_col, e_table_model_row_count(E_TABLE_MODEL(etgl->subset)) - 1);
+ } else {
+ e_table_item_focus(etgl->item, view_col, 0);
+ }
+}
+
+static gint
+etgl_get_focus_column (ETableGroup *etg)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
+ return e_table_item_get_focused_column(etgl->item);
+}
+
+static void
+etgl_set_width (ETableGroup *etg, gdouble width)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
+ etgl->width = width;
+#if 0
+ if ( etgl->item ) {
+ gnome_canvas_item_set(GNOME_CANVAS_ITEM(etgl->item),
+ "width", width,
+ NULL);
+ }
+#endif
+}
+
+static gdouble
+etgl_get_width (ETableGroup *etg)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
+ gtk_object_get(GTK_OBJECT(etgl->item),
+ "width", &etgl->width,
+ NULL);
+ return etgl->width;
+}
+
+static gdouble
+etgl_get_height (ETableGroup *etg)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
+ gdouble height;
+ if ( etgl->item )
+ gtk_object_get(GTK_OBJECT(etgl->item),
+ "height", &height,
+ NULL);
+ else
+ height = 1;
+ return height;
+}
+
+static void
+etgl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ ETableGroup *etg = E_TABLE_GROUP (object);
+
+ switch (arg_id) {
+ case ARG_FROZEN:
+ if ( GTK_VALUE_BOOL (*arg) )
+ etg->frozen = TRUE;
+ else {
+ etg->frozen = FALSE;
+ }
+ break;
+ case ARG_WIDTH:
+ if ( E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->set_width )
+ E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->set_width(etg, GTK_VALUE_DOUBLE (*arg));
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+etgl_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ ETableGroup *etg = E_TABLE_GROUP (object);
+
+ switch (arg_id) {
+ case ARG_FROZEN:
+ GTK_VALUE_BOOL (*arg) = etg->frozen;
+ break;
+ case ARG_HEIGHT:
+ if ( E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_height )
+ GTK_VALUE_DOUBLE (*arg) = E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_height(etg);
+ else
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ case ARG_WIDTH:
+ if ( E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_width )
+ GTK_VALUE_DOUBLE (*arg) = E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_width(etg);
+ else
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ }
+}
+
+static void
+etgl_class_init (GtkObjectClass *object_class)
+{
+ GnomeCanvasItemClass *item_class = (GnomeCanvasItemClass *) object_class;
+ ETableGroupClass *e_group_class = E_TABLE_GROUP_CLASS( object_class );
+
+ object_class->destroy = etgl_destroy;
+ object_class->set_arg = etgl_set_arg;
+ object_class->get_arg = etgl_get_arg;
+
+ item_class->realize = etgl_realize;
+ item_class->event = etgl_event;
+
+ etgl_parent_class = gtk_type_class (PARENT_TYPE);
+
+ e_group_class->add = etgl_add;
+ e_group_class->remove = etgl_remove;
+ e_group_class->increment = etgl_increment;
+ e_group_class->set_focus = etgl_set_focus;
+ e_group_class->get_focus_column = etgl_get_focus_column;
+
+ e_group_class->get_width = etgl_get_width;
+ e_group_class->set_width = etgl_set_width;
+ e_group_class->get_height = etgl_get_height;
+
+ 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_READWRITE, ARG_WIDTH);
+ gtk_object_add_arg_type ("ETableGroupLeaf::frozen", GTK_TYPE_BOOL,
+ GTK_ARG_READWRITE, ARG_FROZEN);
+}
+
+static void
+etgl_init (GtkObject *object)
+{
+ ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (object);
+
+ etgl->width = 1;
+ etgl->subset = NULL;
+ etgl->item = NULL;
+}
+
+E_MAKE_TYPE (e_table_group_leaf, "ETableGroupLeaf", ETableGroupLeaf, etgl_class_init, etgl_init, PARENT_TYPE);
diff --git a/widgets/table/e-table-group-leaf.h b/widgets/table/e-table-group-leaf.h
new file mode 100644
index 0000000000..372bf4cc70
--- /dev/null
+++ b/widgets/table/e-table-group-leaf.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+#ifndef _E_TABLE_GROUP_LEAF_H_
+#define _E_TABLE_GROUP_LEAF_H_
+
+#include <libgnomeui/gnome-canvas.h>
+#include "e-table-group.h"
+#include "e-table-subset-variable.h"
+#include "e-table-item.h"
+
+#define E_TABLE_GROUP_LEAF_TYPE (e_table_group_leaf_get_type ())
+#define E_TABLE_GROUP_LEAF(o) (GTK_CHECK_CAST ((o), E_TABLE_GROUP_LEAF_TYPE, ETableGroupLeaf))
+#define E_TABLE_GROUP_LEAF_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_GROUP_LEAF_TYPE, ETableGroupLeafClass))
+#define E_IS_TABLE_GROUP_LEAF(o) (GTK_CHECK_TYPE ((o), E_TABLE_GROUP_LEAF_TYPE))
+#define E_IS_TABLE_GROUP_LEAF_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_GROUP_LEAF_TYPE))
+
+typedef struct {
+ ETableGroup group;
+
+ /*
+ * Item.
+ */
+ ETableItem *item;
+
+ gdouble width;
+
+ ETableSubsetVariable *subset;
+} ETableGroupLeaf;
+
+typedef struct {
+ ETableGroupClass parent_class;
+} ETableGroupLeafClass;
+
+ETableGroup *e_table_group_leaf_new (GnomeCanvasGroup *parent,
+ ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model);
+GtkType e_table_group_leaf_get_type (void);
+
+#endif /* _E_TABLE_GROUP_LEAF_H_ */
diff --git a/widgets/table/e-table-group.c b/widgets/table/e-table-group.c
index 5652d2623f..68bc3e7abf 100644
--- a/widgets/table/e-table-group.c
+++ b/widgets/table/e-table-group.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* E-Table-Group.c: Implements the grouping objects for elements on a table
*
@@ -10,8 +11,11 @@
#include <config.h>
#include <gtk/gtksignal.h>
#include "e-table-group.h"
+#include "e-table-group-container.h"
+#include "e-table-group-leaf.h"
#include "e-table-item.h"
#include <libgnomeui/gnome-canvas-rect-ellipse.h>
+#include <gnome-xml/parser.h>
#include "e-util/e-util.h"
#define TITLE_HEIGHT 16
@@ -19,88 +23,30 @@
#define PARENT_TYPE gnome_canvas_group_get_type ()
+#define ETG_CLASS(e) (E_TABLE_GROUP_CLASS(GTK_OBJECT(e)->klass))
+
static GnomeCanvasGroupClass *etg_parent_class;
enum {
- HEIGHT_CHANGED,
+ RESIZE,
LAST_SIGNAL
};
static gint etg_signals [LAST_SIGNAL] = { 0, };
-static void
-etg_destroy (GtkObject *object)
-{
- ETableGroup *etg = E_TABLE_GROUP (object);
-
- GTK_OBJECT_CLASS (etg_parent_class)->destroy (object);
-}
-
-static void
-etg_dim (ETableGroup *etg, int *width, int *height)
-{
- GSList *l;
-
- *width = *height = 0;
-
- for (l = etg->children; l; l = l->next){
- GnomeCanvasItem *child = l->data;
-
- *height += child->y2 - child->y1;
- *width += child->x2 - child->x1;
- }
-
- if (!etg->transparent){
- *height += TITLE_HEIGHT;
- *width += GROUP_INDENT;
- }
-}
+/* The arguments we take */
+enum {
+ ARG_0,
+ ARG_HEIGHT,
+ ARG_WIDTH,
+ ARG_FROZEN
+};
-void
-e_table_group_construct (GnomeCanvasGroup *parent, ETableGroup *etg,
- ETableCol *ecol, gboolean open,
- gboolean transparent)
-{
- gnome_canvas_item_constructv (GNOME_CANVAS_ITEM (etg), parent, 0, NULL);
-
- etg->ecol = ecol;
- etg->open = open;
- etg->transparent = transparent;
-
- etg_dim (etg, &etg->width, &etg->height);
-
- if (!etg->transparent)
- etg->rect = gnome_canvas_item_new (
- GNOME_CANVAS_GROUP (etg),
- gnome_canvas_rect_get_type (),
- "fill_color", "gray",
- "outline_color", "gray20",
- "x1", 0.0,
- "y1", 0.0,
- "x2", (double) etg->width,
- "y2", (double) etg->height,
- NULL);
+static void etg_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+static void etg_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+static gboolean etg_get_focus (ETableGroup *etg);
#if 0
- /*
- * Reparent the child into our space.
- */
- gnome_canvas_item_reparent (child, GNOME_CANVAS_GROUP (etg));
-
- gnome_canvas_item_set (
- child,
- "x", (double) GROUP_INDENT,
- "y", (double) TITLE_HEIGHT,
- NULL);
-
- /*
- * Force dimension computation
- */
- GNOME_CANVAS_ITEM_CLASS (etg_parent_class)->update (
- GNOME_CANVAS_ITEM (etg), NULL, NULL, GNOME_CANVAS_UPDATE_REQUESTED);
-#endif
-}
-
GnomeCanvasItem *
e_table_group_new (GnomeCanvasGroup *parent, ETableCol *ecol,
gboolean open, gboolean transparent)
@@ -116,158 +62,275 @@ e_table_group_new (GnomeCanvasGroup *parent, ETableCol *ecol,
return GNOME_CANVAS_ITEM (etg);
}
+#endif
-static void
-etg_relayout (GnomeCanvasItem *eti, ETableGroup *etg)
+ETableGroup *
+e_table_group_new (GnomeCanvasGroup *parent,
+ ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model,
+ xmlNode *rules)
{
- GSList *l;
- int height = etg->transparent ? 0 : GROUP_INDENT;
- gboolean move = FALSE;
+ g_return_val_if_fail (model != NULL, NULL);
- printf ("Relaying out\n");
-
- for (l = etg->children; l->next; l = l->next){
- GnomeCanvasItem *child = l->data;
+ if(rules && !xmlStrcmp(rules->name, "group")) {
+ gint col_idx = atoi(xmlGetProp(rules, "column"));
+ ETableCol *col;
+ if ( col_idx > e_table_header_count(full_header) )
+ return e_table_group_leaf_new(parent, full_header, header, model);
+ col = e_table_header_get_columns(full_header)[col_idx];
+ return e_table_group_container_new(parent, full_header, header, model, col, rules->childs);
+ } else {
+ return e_table_group_leaf_new(parent, full_header, header, model);
+ }
+ return NULL;
+}
+
+void
+e_table_group_construct (GnomeCanvasGroup *parent,
+ ETableGroup *etg,
+ ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model)
+{
+ gnome_canvas_item_constructv (GNOME_CANVAS_ITEM (etg), parent, 0, NULL);
+ etg->full_header = full_header;
+ etg->header = header;
+ etg->model = model;
+}
+
+void
+e_table_group_add (ETableGroup *etg,
+ gint row)
+{
+ g_return_if_fail (etg != NULL);
+ g_return_if_fail (E_IS_TABLE_GROUP (etg));
- height += child->y2 - child->y1;
+ if ( ETG_CLASS (etg)->add )
+ ETG_CLASS (etg)->add (etg, row);
+}
- if (child == eti)
- move = TRUE;
+gboolean
+e_table_group_remove (ETableGroup *etg,
+ gint row)
+{
+ g_return_val_if_fail (etg != NULL, FALSE);
+ g_return_val_if_fail (E_IS_TABLE_GROUP (etg), FALSE);
- if (move){
- printf ("Moving item %p\n", child);
- gnome_canvas_item_set (
- child,
- "y", (double) height,
- NULL);
- }
- }
- if (height != etg->height){
- etg->height = height;
- gtk_signal_emit (GTK_OBJECT (etg), etg_signals [HEIGHT_CHANGED]);
- }
+ if ( ETG_CLASS (etg)->remove )
+ return ETG_CLASS (etg)->remove (etg, row);
+ else
+ return FALSE;
+}
+
+gint
+e_table_group_get_count (ETableGroup *etg)
+{
+ g_return_val_if_fail (etg != NULL, 0);
+ g_return_val_if_fail (E_IS_TABLE_GROUP (etg), 0);
+
+ if ( ETG_CLASS (etg)->get_count )
+ return ETG_CLASS (etg)->get_count (etg);
+ else
+ return 0;
}
void
-e_table_group_add (ETableGroup *etg, GnomeCanvasItem *item)
+e_table_group_increment (ETableGroup *etg,
+ gint position,
+ gint amount)
{
- double x1, y1, x2, y2;
-
g_return_if_fail (etg != NULL);
- g_return_if_fail (item != NULL);
g_return_if_fail (E_IS_TABLE_GROUP (etg));
- g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
-
- etg->children = g_slist_append (etg->children, item);
-
- GNOME_CANVAS_ITEM_CLASS (GTK_OBJECT (etg)->klass)->bounds (etg, &x1, &y1, &x2, &y2);
-
- if (GTK_OBJECT (etg)->flags & GNOME_CANVAS_ITEM_REALIZED){
- GSList *l;
- int height = etg->transparent ? 0 : TITLE_HEIGHT;
- int x = etg->transparent ? 0 : GROUP_INDENT;
-
- for (l = etg->children; l->next; l = l->next){
- GnomeCanvasItem *child = l->data;
-
- height += child->y2 - child->y1;
-
- printf ("Height\n");
- if (E_IS_TABLE_ITEM (item)){
- printf (" Item: ");
- } else {
- printf (" Group: ");
- }
- printf ("%d\n", child->y2-child->y1);
- }
- gnome_canvas_item_set (
- item,
- "y", (double) height,
- "x", (double) x,
- NULL);
-
-
- if (E_IS_TABLE_ITEM (item)){
-
- printf ("Table item! ---------\n");
- gtk_signal_connect (GTK_OBJECT (item), "height_changed",
- GTK_SIGNAL_FUNC (etg_relayout), etg);
- }
- }
+ if ( ETG_CLASS (etg)->increment )
+ ETG_CLASS (etg)->increment (etg, position, amount);
}
-static void
-etg_realize (GnomeCanvasItem *item)
+void
+e_table_group_set_focus (ETableGroup *etg,
+ EFocus direction,
+ gint row)
+{
+ g_return_if_fail (etg != NULL);
+ g_return_if_fail (E_IS_TABLE_GROUP (etg));
+
+ if ( ETG_CLASS (etg)->set_focus )
+ ETG_CLASS (etg)->set_focus (etg, direction, row);
+}
+
+gboolean
+e_table_group_get_focus (ETableGroup *etg)
+{
+ g_return_val_if_fail (etg != NULL, FALSE);
+ g_return_val_if_fail (E_IS_TABLE_GROUP (etg), FALSE);
+
+ if ( ETG_CLASS (etg)->get_focus )
+ return ETG_CLASS (etg)->get_focus (etg);
+ else
+ return FALSE;
+}
+
+gboolean
+e_table_group_get_focus_column (ETableGroup *etg)
+{
+ g_return_val_if_fail (etg != NULL, FALSE);
+ g_return_val_if_fail (E_IS_TABLE_GROUP (etg), FALSE);
+
+ if ( ETG_CLASS (etg)->get_focus_column )
+ return ETG_CLASS (etg)->get_focus_column (etg);
+ else
+ return FALSE;
+}
+
+ETableCol *
+e_table_group_get_ecol (ETableGroup *etg)
+{
+ g_return_val_if_fail (etg != NULL, NULL);
+ g_return_val_if_fail (E_IS_TABLE_GROUP (etg), NULL);
+
+ if ( ETG_CLASS (etg)->get_ecol )
+ return ETG_CLASS (etg)->get_ecol (etg);
+ else
+ return NULL;
+}
+
+void
+e_table_group_resize (ETableGroup *e_table_group)
+{
+ g_return_if_fail (e_table_group != NULL);
+ g_return_if_fail (E_IS_TABLE_GROUP (e_table_group));
+
+ gtk_signal_emit (GTK_OBJECT (e_table_group),
+ etg_signals [RESIZE]);
+}
+
+static int
+etg_event (GnomeCanvasItem *item, GdkEvent *event)
{
ETableGroup *etg = E_TABLE_GROUP (item);
- GSList *l;
- int height = 0;
-
- GNOME_CANVAS_ITEM_CLASS (etg_parent_class)->realize (item);
+ gboolean return_val = TRUE;
- for (l = etg->children; l; l = l->next){
- GnomeCanvasItem *child = l->data;
+ switch (event->type) {
- printf ("During realization for child %p -> %d\n", child, height);
- gnome_canvas_item_set (
- child,
- "y", (double) height,
- NULL);
+ case GDK_FOCUS_CHANGE:
+ etg->has_focus = event->focus_change.in;
+ return_val = FALSE;
- height += child->y2 - child->y1;
+ default:
+ return_val = FALSE;
}
+ if ( return_val == FALSE ) {
+ if ( GNOME_CANVAS_ITEM_CLASS(etg_parent_class)->event )
+ return GNOME_CANVAS_ITEM_CLASS(etg_parent_class)->event(item, event);
+ }
+ return return_val;
+
}
static void
-etg_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
+etg_thaw(ETableGroup *etg)
{
- ETableGroup *etg = E_TABLE_GROUP (item);
+ g_return_if_fail (etg != NULL);
+ g_return_if_fail (E_IS_TABLE_GROUP (etg));
+
+ if ( ETG_CLASS (etg)->thaw )
+ ETG_CLASS (etg)->thaw (etg);
+}
+
+static void
+etg_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ ETableGroup *etg = E_TABLE_GROUP (object);
- GNOME_CANVAS_ITEM_CLASS (etg_parent_class)->update (item, affine, clip_path, flags);
-
- if (!etg->transparent){
- int current_width, current_height;
-
- etg_dim (etg, &current_width, &current_height);
-
- if ((current_height != etg->height) || (current_width != etg->width)){
- etg->width = current_width;
- etg->height = current_height;
-
- gnome_canvas_item_set (
- etg->rect,
- "x1", 0.0,
- "y1", 0.0,
- "x2", (double) etg->width,
- "y2", (double) etg->height,
- NULL);
+ switch (arg_id) {
+ case ARG_FROZEN:
+ if ( GTK_VALUE_BOOL (*arg) )
+ etg->frozen = TRUE;
+ else {
+ etg->frozen = FALSE;
+ etg_thaw(etg);
}
+ break;
+ case ARG_WIDTH:
+ if ( ETG_CLASS(etg)->set_width )
+ ETG_CLASS(etg)->set_width(etg, GTK_VALUE_DOUBLE (*arg));
+ break;
+ default:
+ break;
}
}
static void
+etg_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ ETableGroup *etg = E_TABLE_GROUP (object);
+
+ switch (arg_id) {
+ case ARG_FROZEN:
+ GTK_VALUE_BOOL (*arg) = etg->frozen;
+ break;
+ case ARG_HEIGHT:
+ if ( ETG_CLASS(etg)->get_height )
+ GTK_VALUE_DOUBLE (*arg) = ETG_CLASS(etg)->get_height(etg);
+ else
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ case ARG_WIDTH:
+ if ( ETG_CLASS(etg)->get_width )
+ GTK_VALUE_DOUBLE (*arg) = ETG_CLASS(etg)->get_width(etg);
+ else
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ }
+}
+
+static gboolean
+etg_get_focus (ETableGroup *etg)
+{
+ return etg->has_focus;
+}
+
+static void
etg_class_init (GtkObjectClass *object_class)
{
GnomeCanvasItemClass *item_class = (GnomeCanvasItemClass *) object_class;
+ ETableGroupClass *klass = (ETableGroupClass *) object_class;
+
+ object_class->set_arg = etg_set_arg;
+ object_class->get_arg = etg_get_arg;
- object_class->destroy = etg_destroy;
+ item_class->event = etg_event;
- item_class->realize = etg_realize;
- item_class->update = etg_update;
+ klass->resize = NULL;
+
+ klass->add = NULL;
+ klass->remove = NULL;
+ klass->get_count = NULL;
+ klass->increment = NULL;
+ klass->set_focus = NULL;
+ klass->get_focus = etg_get_focus;
+ klass->get_ecol = NULL;
+
+ klass->thaw = NULL;
+ klass->get_height = NULL;
+ klass->get_width = NULL;
+ klass->set_width = NULL;
etg_parent_class = gtk_type_class (PARENT_TYPE);
- etg_signals [HEIGHT_CHANGED] =
- gtk_signal_new ("height_changed",
+ etg_signals [RESIZE] =
+ gtk_signal_new ("resize",
GTK_RUN_LAST,
object_class->type,
- GTK_SIGNAL_OFFSET (ETableGroupClass, height_changed),
+ GTK_SIGNAL_OFFSET (ETableGroupClass, resize),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
gtk_object_class_add_signals (object_class, etg_signals, LAST_SIGNAL);
-
}
E_MAKE_TYPE (e_table_group, "ETableGroup", ETableGroup, etg_class_init, NULL, PARENT_TYPE);
diff --git a/widgets/table/e-table-group.h b/widgets/table/e-table-group.h
index 468d5dd794..1b3f346290 100644
--- a/widgets/table/e-table-group.h
+++ b/widgets/table/e-table-group.h
@@ -1,9 +1,12 @@
-#ifndef _E_TABLE_TREE_H_
-#define _E_TABLE_TREE_H_
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+#ifndef _E_TABLE_GROUP_H_
+#define _E_TABLE_GROUP_H_
#include <libgnomeui/gnome-canvas.h>
+#include <gnome-xml/tree.h>
#include "e-table-model.h"
#include "e-table-header.h"
+#include "e-util/e-util.h"
#define E_TABLE_GROUP_TYPE (e_table_group_get_type ())
#define E_TABLE_GROUP(o) (GTK_CHECK_CAST ((o), E_TABLE_GROUP_TYPE, ETableGroup))
@@ -15,49 +18,75 @@ typedef struct {
GnomeCanvasGroup group;
/*
- * The ETableCol used to group this set
+ * The full header.
*/
- ETableCol *ecol;
-
- /*
- * The canvas rectangle that contains the children
- */
- GnomeCanvasItem *rect;
-
- /*
- * Dimensions of the ETableGroup
- */
- int width, height;
-
+ ETableHeader *full_header;
+ ETableHeader *header;
+
/*
- * State: the ETableGroup is open or closed
+ * The model we pull data from.
*/
- guint open:1;
+ ETableModel *model;
/*
* Whether we should add indentation and open/close markers,
* or if we just act as containers of subtables.
*/
- guint transparent:1;
+ guint transparent : 1;
- /*
- * List of GnomeCanvasItems we stack
- */
- GSList *children;
+ guint has_focus : 1;
+
+ guint frozen : 1;
} ETableGroup;
typedef struct {
GnomeCanvasGroupClass parent_class;
- void (*height_changed) (ETableGroup *etg);
+ void (*resize) (ETableGroup *etg);
+
+ void (*add) (ETableGroup *etg, gint row);
+ gboolean (*remove) (ETableGroup *etg, gint row);
+ gint (*get_count) (ETableGroup *etg);
+ void (*increment) (ETableGroup *etg, gint position, gint amount);
+ void (*set_focus) (ETableGroup *etg, EFocus direction, gint view_col);
+ gboolean (*get_focus) (ETableGroup *etg);
+ gint (*get_focus_column) (ETableGroup *etg);
+ ETableCol *(*get_ecol) (ETableGroup *etg);
+
+ void (*thaw) (ETableGroup *etg);
+ gdouble (*get_height) (ETableGroup *etg);
+ gdouble (*get_width) (ETableGroup *etg);
+ void (*set_width) (ETableGroup *etg, gdouble width);
} ETableGroupClass;
-GnomeCanvasItem *e_table_group_new (GnomeCanvasGroup *parent, ETableCol *ecol,
- gboolean open, gboolean transparent);
-void e_table_group_construct (GnomeCanvasGroup *parent, ETableGroup *etg,
- ETableCol *ecol, gboolean open, gboolean transparent);
+void e_table_group_add (ETableGroup *etg,
+ gint row);
+gboolean e_table_group_remove (ETableGroup *etg,
+ gint row);
+gint e_table_group_get_count (ETableGroup *etg);
+void e_table_group_increment (ETableGroup *etg,
+ gint position,
+ gint amount);
+void e_table_group_set_focus (ETableGroup *etg,
+ EFocus direction,
+ gint view_col);
+gboolean e_table_group_get_focus (ETableGroup *etg);
+gint e_table_group_get_focus_column (ETableGroup *etg);
+ETableCol *e_table_group_get_ecol (ETableGroup *etg);
+
+ETableGroup *e_table_group_new (GnomeCanvasGroup *parent,
+ ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model,
+ xmlNode *rules);
+void e_table_group_construct (GnomeCanvasGroup *parent,
+ ETableGroup *etg,
+ ETableHeader *full_header,
+ ETableHeader *header,
+ ETableModel *model);
-void e_table_group_add (ETableGroup *etg, GnomeCanvasItem *child);
+/* For emitting the signal */
+void e_table_group_resize (ETableGroup *etg);
GtkType e_table_group_get_type (void);
-#endif /* _E_TABLE_TREE_H_ */
+#endif /* _E_TABLE_GROUP_H_ */
diff --git a/widgets/table/e-table-header-item.c b/widgets/table/e-table-header-item.c
index b025664385..6b6146c938 100644
--- a/widgets/table/e-table-header-item.c
+++ b/widgets/table/e-table-header-item.c
@@ -317,7 +317,7 @@ ethi_drag_motion (GtkObject *canvas, GdkDragContext *context,
{
/* Check if it's the correct ethi */
if (ethi->drag_col == -1)
- return;
+ return FALSE;
gdk_drag_status (context, 0, time);
if (GTK_WIDGET(canvas) == gtk_drag_get_source_widget(context)) {
@@ -372,7 +372,7 @@ ethi_drag_drop (GtkWidget *canvas,
gboolean successful = FALSE;
if (ethi->drag_col == -1)
- return;
+ return FALSE;
if (GTK_WIDGET(canvas) == gtk_drag_get_source_widget(context)) {
if ((x >= ethi->x1) && (x <= (ethi->x1 + ethi->width)) &&
@@ -486,7 +486,6 @@ draw_button (ETableHeaderItem *ethi, ETableCol *col,
{
GdkRectangle clip;
int xtra;
- int arrowx;
gdk_draw_rectangle (
drawable, gc, TRUE,
@@ -541,7 +540,7 @@ draw_button (ETableHeaderItem *ethi, ETableCol *col,
gtk_paint_arrow (gtk_widget_get_style(GTK_WIDGET(GNOME_CANVAS_ITEM(ethi)->canvas)),
drawable,
GTK_STATE_NORMAL,
- GTK_SHADOW_OUT,
+ GTK_SHADOW_IN,
&clip,
GTK_WIDGET(GNOME_CANVAS_ITEM(ethi)->canvas),
"header",
diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c
index 130c51a85c..d8ecdf1404 100644
--- a/widgets/table/e-table-item.c
+++ b/widgets/table/e-table-item.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* E-table-item.c: A GnomeCanvasItem that is a view of an ETableModel.
*
@@ -26,7 +27,7 @@ static GnomeCanvasItemClass *eti_parent_class;
enum {
ROW_SELECTION,
- HEIGHT_CHANGED,
+ RESIZE,
LAST_SIGNAL
};
@@ -36,12 +37,14 @@ enum {
ARG_0,
ARG_TABLE_HEADER,
ARG_TABLE_MODEL,
- ARG_TABLE_X,
- ARG_TABLE_Y,
ARG_TABLE_DRAW_GRID,
ARG_TABLE_DRAW_FOCUS,
ARG_MODE_SPREADSHEET,
- ARG_LENGHT_THRESHOLD
+ ARG_LENGHT_THRESHOLD,
+
+ ARG_WIDTH,
+ ARG_HEIGHT,
+ ARG_HAS_FOCUS
};
static gboolean
@@ -67,7 +70,7 @@ eti_realize_cell_views (ETableItem *eti)
int i;
for (i = 0; i < eti->n_cells; i++)
- e_cell_view_realize (eti->cell_views [i], eti);
+ e_cell_realize (eti->cell_views [i]);
eti->cell_views_realized = 1;
}
@@ -287,13 +290,13 @@ eti_compute_height (ETableItem *eti)
int new_height = eti_get_height (eti);
if (new_height != eti->height){
- double x1, y1, x2, y2;
+ /* double x1, y1, x2, y2;*/
printf ("Emitting!\n");
eti->height = new_height;
eti_update (GNOME_CANVAS_ITEM (eti), NULL, NULL, 0);
- gtk_signal_emit (GTK_OBJECT (eti), eti_signals [HEIGHT_CHANGED]);
+ gtk_signal_emit (GTK_OBJECT (eti), eti_signals [RESIZE]);
}
}
@@ -537,14 +540,6 @@ eti_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
eti_add_table_model (eti, GTK_VALUE_POINTER (*arg));
break;
- case ARG_TABLE_X:
- eti->x1 = GTK_VALUE_DOUBLE (*arg);
- break;
-
- case ARG_TABLE_Y:
- eti->y1 = GTK_VALUE_DOUBLE (*arg);
- break;
-
case ARG_LENGHT_THRESHOLD:
eti->length_threshold = GTK_VALUE_INT (*arg);
break;
@@ -565,6 +560,27 @@ eti_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
}
static void
+eti_get_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ GnomeCanvasItem *item;
+ ETableItem *eti;
+
+ item = GNOME_CANVAS_ITEM (o);
+ eti = E_TABLE_ITEM (o);
+
+ switch (arg_id){
+ case ARG_WIDTH:
+ GTK_VALUE_DOUBLE (*arg) = eti->width;
+ break;
+ case ARG_HEIGHT:
+ GTK_VALUE_DOUBLE (*arg) = eti->height;
+ break;
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ }
+}
+
+static void
eti_init (GnomeCanvasItem *item)
{
ETableItem *eti = E_TABLE_ITEM (item);
@@ -576,7 +592,7 @@ eti_init (GnomeCanvasItem *item)
eti->height = 0;
eti->length_threshold = -1;
- eti->renderers_can_change_size = 0;
+ eti->renderers_can_change_size = 1;
eti->selection_mode = GTK_SELECTION_SINGLE;
}
@@ -878,31 +894,34 @@ find_cell (ETableItem *eti, double x, double y, int *col_res, int *row_res, doub
}
static void
-eti_cursor_move_left (ETableItem *eti)
+eti_cursor_move (ETableItem *eti, gint row, gint column)
{
e_table_item_leave_edit (eti);
- e_table_item_focus (eti, eti->focused_col - 1, eti->focused_row);
+ e_table_item_focus (eti, column, row);
+}
+
+static void
+eti_cursor_move_left (ETableItem *eti)
+{
+ eti_cursor_move(eti, eti->focused_row, eti->focused_col - 1);
}
static void
eti_cursor_move_right (ETableItem *eti)
{
- e_table_item_leave_edit (eti);
- e_table_item_focus (eti, eti->focused_col + 1, eti->focused_row);
+ eti_cursor_move(eti, eti->focused_row, eti->focused_col + 1);
}
static void
eti_cursor_move_up (ETableItem *eti)
{
- e_table_item_leave_edit (eti);
- e_table_item_focus (eti, eti->focused_col, eti->focused_row - 1);
+ eti_cursor_move(eti, eti->focused_row - 1, eti->focused_col);
}
static void
eti_cursor_move_down (ETableItem *eti)
{
- e_table_item_leave_edit (eti);
- e_table_item_focus (eti, eti->focused_col, eti->focused_row + 1);
+ eti_cursor_move(eti, eti->focused_row + 1, eti->focused_col);
}
static int
@@ -911,6 +930,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
ETableItem *eti = E_TABLE_ITEM (item);
ECellView *ecell_view;
ETableCol *ecol;
+ gint return_val = TRUE;
switch (e->type){
case GDK_BUTTON_PRESS:
@@ -982,66 +1002,66 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
if (eti->focused_col > 0)
eti_cursor_move_left (eti);
-
- return TRUE;
-
+ break;
+
case GDK_Right:
if (!eti->mode_spreadsheet && eti_editing (eti))
break;
- if ((eti->focused_col + 1) < eti->cols)
+ if (eti->focused_col < eti->cols - 1)
eti_cursor_move_right (eti);
- return TRUE;
-
+ break;
+
case GDK_Up:
if (eti->focused_row > 0)
eti_cursor_move_up (eti);
- return TRUE;
+ else
+ return_val = FALSE;
+ break;
case GDK_Down:
if ((eti->focused_row + 1) < eti->rows)
eti_cursor_move_down (eti);
-
- return TRUE;
+ else
+ return_val = FALSE;
+ break;
case GDK_Tab:
+ case GDK_KP_Tab:
+ case GDK_ISO_Left_Tab:
if ((e->key.state & GDK_SHIFT_MASK) != 0){
/* shift tab */
if (eti->focused_col > 0)
eti_cursor_move_left (eti);
- else if (eti->focused_row > 0){
- e_table_item_leave_edit (eti);
- e_table_item_focus (eti, eti->cols - 1, eti->focused_row - 1);
- } else {
- /* FIXME: request focus leave backward */
- }
+ else if (eti->focused_row > 0)
+ eti_cursor_move(eti, eti->focused_row - 1, eti->cols - 1);
+ else
+ return_val = FALSE;
} else {
- if ((eti->focused_col + 1) < eti->cols)
+ if (eti->focused_col < eti->cols - 1)
eti_cursor_move_right (eti);
- else if ((eti->focused_row + 1) < eti->rows){
- e_table_item_leave_edit (eti);
- e_table_item_focus (eti, 0, eti->rows - 1);
- } else {
- /* FIXME: request focus leave forward */
- }
+ else if (eti->focused_row < eti->rows - 1)
+ eti_cursor_move(eti, eti->focused_row + 1, 0);
+ else
+ return_val = FALSE;
}
break;
default:
if (!eti_editing (eti)){
if ((e->key.state & (GDK_MOD1_MASK | GDK_CONTROL_MASK)) != 0)
- return 0;
+ return_val = FALSE;
if (!(e->key.keyval >= 0x20 && e->key.keyval <= 0xff))
- return 0;
+ return_val = FALSE;
}
- }
- ecol = e_table_header_get_column (eti->header, eti->focused_col);
- ecell_view = eti->cell_views [eti->focused_col];
- e_cell_event (ecell_view, e, ecol->col_idx, eti->focused_col, eti->focused_row);
+ ecol = e_table_header_get_column (eti->header, eti->focused_col);
+ ecell_view = eti->cell_views [eti->focused_col];
+ e_cell_event (ecell_view, e, ecol->col_idx, eti->focused_col, eti->focused_row);
+ }
break;
-
+
case GDK_KEY_RELEASE:
if (eti->focused_col == -1)
return FALSE;
@@ -1053,8 +1073,15 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
}
break;
+ case GDK_FOCUS_CHANGE:
+ if (e->focus_change.in) {
+ } else {
+ e_table_item_leave_edit (eti);
+ e_table_item_unfocus (eti);
+ }
+
default:
- return FALSE;
+ return_val = FALSE;
}
return TRUE;
}
@@ -1084,6 +1111,7 @@ eti_class_init (GtkObjectClass *object_class)
object_class->destroy = eti_destroy;
object_class->set_arg = eti_set_arg;
+ object_class->get_arg = eti_get_arg;
item_class->update = eti_update;
item_class->realize = eti_realize;
@@ -1099,10 +1127,6 @@ eti_class_init (GtkObjectClass *object_class)
GTK_ARG_WRITABLE, ARG_TABLE_HEADER);
gtk_object_add_arg_type ("ETableItem::ETableModel", GTK_TYPE_POINTER,
GTK_ARG_WRITABLE, ARG_TABLE_MODEL);
- gtk_object_add_arg_type ("ETableItem::x", GTK_TYPE_DOUBLE,
- GTK_ARG_WRITABLE, ARG_TABLE_X);
- gtk_object_add_arg_type ("ETableItem::y", GTK_TYPE_DOUBLE,
- GTK_ARG_WRITABLE, ARG_TABLE_Y);
gtk_object_add_arg_type ("ETableItem::drawgrid", GTK_TYPE_BOOL,
GTK_ARG_WRITABLE, ARG_TABLE_DRAW_GRID);
gtk_object_add_arg_type ("ETableItem::drawfocus", GTK_TYPE_BOOL,
@@ -1110,6 +1134,13 @@ eti_class_init (GtkObjectClass *object_class)
gtk_object_add_arg_type ("ETableItem::spreadsheet", GTK_TYPE_BOOL,
GTK_ARG_WRITABLE, ARG_MODE_SPREADSHEET);
+ gtk_object_add_arg_type ("ETableItem::width", GTK_TYPE_DOUBLE,
+ GTK_ARG_READWRITE, ARG_WIDTH);
+ gtk_object_add_arg_type ("ETableItem::height", GTK_TYPE_DOUBLE,
+ GTK_ARG_READABLE, ARG_HEIGHT);
+ gtk_object_add_arg_type ("ETableItem::has_focus", GTK_TYPE_BOOL,
+ GTK_ARG_READWRITE, ARG_HAS_FOCUS);
+
eti_signals [ROW_SELECTION] =
gtk_signal_new ("row_selection",
GTK_RUN_LAST,
@@ -1118,11 +1149,11 @@ eti_class_init (GtkObjectClass *object_class)
gtk_marshal_NONE__INT_INT,
GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
- eti_signals [HEIGHT_CHANGED] =
- gtk_signal_new ("height_changed",
+ eti_signals [RESIZE] =
+ gtk_signal_new ("resize",
GTK_RUN_LAST,
object_class->type,
- GTK_SIGNAL_OFFSET (ETableItemClass, height_changed),
+ GTK_SIGNAL_OFFSET (ETableItemClass, resize),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
@@ -1192,6 +1223,16 @@ e_table_item_unfocus (ETableItem *eti)
eti->focused_row = -1;
}
+gint
+e_table_item_get_focused_column (ETableItem *eti)
+{
+ g_return_val_if_fail (eti != NULL, -1);
+ g_return_val_if_fail (E_IS_TABLE_ITEM (eti), -1);
+
+ return eti->focused_col;
+}
+
+
const GSList *
e_table_item_get_selection (ETableItem *eti)
{
diff --git a/widgets/table/e-table-item.h b/widgets/table/e-table-item.h
index f19819f2fc..635dc76922 100644
--- a/widgets/table/e-table-item.h
+++ b/widgets/table/e-table-item.h
@@ -68,7 +68,7 @@ typedef struct {
GnomeCanvasItemClass parent_class;
void (*row_selection) (ETableItem *eti, int row, gboolean selected);
- void (*height_changed) (ETableItem *eti);
+ void (*resize) (ETableItem *eti);
} ETableItemClass;
GtkType e_table_item_get_type (void);
@@ -79,6 +79,8 @@ GtkType e_table_item_get_type (void);
void e_table_item_focus (ETableItem *eti, int col, int row);
void e_table_item_unfocus (ETableItem *eti);
+gint e_table_item_get_focused_column (ETableItem *eti);
+
/*
* Selection
*/
diff --git a/widgets/table/e-table-model.c b/widgets/table/e-table-model.c
index 9e397710ef..e84e6da4d3 100644
--- a/widgets/table/e-table-model.c
+++ b/widgets/table/e-table-model.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* e-table-model.c: a Table Model
*
@@ -173,4 +174,23 @@ e_table_model_cell_changed (ETableModel *e_table_model, int col, int row)
e_table_model_signals [MODEL_CELL_CHANGED], col, row);
}
+void
+e_table_model_freeze (ETableModel *e_table_model)
+{
+ g_return_if_fail (e_table_model != NULL);
+ g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
+
+ e_table_model->frozen = TRUE;
+ return ETM_CLASS (e_table_model)->thaw (e_table_model);
+}
+void
+e_table_model_thaw (ETableModel *e_table_model)
+{
+ g_return_if_fail (e_table_model != NULL);
+ g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
+
+ e_table_model->frozen = FALSE;
+ if (ETM_CLASS(e_table_model)->thaw)
+ ETM_CLASS (e_table_model)->thaw (e_table_model);
+}
diff --git a/widgets/table/e-table-model.h b/widgets/table/e-table-model.h
index 2d08f3744e..9f2dbbf87c 100644
--- a/widgets/table/e-table-model.h
+++ b/widgets/table/e-table-model.h
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#ifndef _E_TABLE_MODEL_H_
#define _E_TABLE_MODEL_H_
@@ -11,6 +12,8 @@
typedef struct {
GtkObject base;
+
+ guint frozen : 1;
} ETableModel;
typedef struct {
@@ -24,7 +27,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);
-
+ void (*thaw) (ETableModel *etm);
/*
* Signals
*/
@@ -48,6 +51,9 @@ void *e_table_model_value_at (ETableModel *e_table_model, int col,
void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, const void *data);
gboolean e_table_model_is_cell_editable (ETableModel *e_table_model, int col, int row);
+void e_table_model_freeze (ETableModel *e_table_model);
+void e_table_model_thaw (ETableModel *e_table_model);
+
/*
* Routines for emitting signals on the e_table
*/
diff --git a/widgets/table/e-table-simple.c b/widgets/table/e-table-simple.c
index 38e1dd8eb0..1f64d08f39 100644
--- a/widgets/table/e-table-simple.c
+++ b/widgets/table/e-table-simple.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* e-table-model.c: a simple table model implementation that uses function
* pointers to simplify the creation of new, exotic and colorful tables in
@@ -55,6 +56,14 @@ simple_is_cell_editable (ETableModel *etm, int col, int row)
}
static void
+simple_thaw (ETableModel *etm)
+{
+ ETableSimple *simple = (ETableSimple *)etm;
+
+ simple->thaw (etm, simple->data);
+}
+
+static void
e_table_simple_class_init (GtkObjectClass *object_class)
{
ETableModelClass *model_class = (ETableModelClass *) object_class;
@@ -64,6 +73,7 @@ e_table_simple_class_init (GtkObjectClass *object_class)
model_class->value_at = simple_value_at;
model_class->set_value_at = simple_set_value_at;
model_class->is_cell_editable = simple_is_cell_editable;
+ model_class->thaw = simple_thaw;
}
GtkType
@@ -95,6 +105,7 @@ e_table_simple_new (ETableSimpleColumnCountFn col_count,
ETableSimpleValueAtFn value_at,
ETableSimpleSetValueAtFn set_value_at,
ETableSimpleIsCellEditableFn is_cell_editable,
+ ETableSimpleThawFn thaw,
void *data)
{
ETableSimple *et;
@@ -106,6 +117,7 @@ e_table_simple_new (ETableSimpleColumnCountFn col_count,
et->value_at = value_at;
et->set_value_at = set_value_at;
et->is_cell_editable = is_cell_editable;
+ et->thaw = thaw;
et->data = data;
return (ETableModel *) et;
diff --git a/widgets/table/e-table-simple.h b/widgets/table/e-table-simple.h
index d890245386..a3164eefc0 100644
--- a/widgets/table/e-table-simple.h
+++ b/widgets/table/e-table-simple.h
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#ifndef _E_TABLE_SIMPLE_H_
#define _E_TABLE_SIMPLE_H_
@@ -8,6 +9,7 @@ typedef int (*ETableSimpleRowCountFn) (ETableModel *etm, void *dat
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 void (*ETableSimpleThawFn) (ETableModel *etm, void *data);
typedef struct {
ETableModel parent;
@@ -17,6 +19,7 @@ typedef struct {
ETableSimpleValueAtFn value_at;
ETableSimpleSetValueAtFn set_value_at;
ETableSimpleIsCellEditableFn is_cell_editable;
+ ETableSimpleThawFn thaw;
void *data;
} ETableSimple;
@@ -31,6 +34,7 @@ ETableModel *e_table_simple_new (ETableSimpleColumnCountFn col_count,
ETableSimpleValueAtFn value_at,
ETableSimpleSetValueAtFn set_value_at,
ETableSimpleIsCellEditableFn is_cell_editable,
+ ETableSimpleThawFn thaw,
void *data);
#endif /* _E_TABLE_SIMPLE_H_ */
diff --git a/widgets/table/e-table-sorted.h b/widgets/table/e-table-sorted.h
index 2ec52df2e7..92bd8d1522 100644
--- a/widgets/table/e-table-sorted.h
+++ b/widgets/table/e-table-sorted.h
@@ -19,7 +19,7 @@ typedef struct {
} ETableSorted;
typedef struct {
- ETableSubset parent_class;
+ ETableSubsetClass parent_class;
} ETableSortedClass;
GtkType e_table_sorted_get_type (void);
diff --git a/widgets/table/e-table-subset-variable.c b/widgets/table/e-table-subset-variable.c
new file mode 100644
index 0000000000..76da03c44f
--- /dev/null
+++ b/widgets/table/e-table-subset-variable.c
@@ -0,0 +1,112 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * E-table-subset.c: Implements a table that contains a subset of another table.
+ *
+ * Author:
+ * Miguel de Icaza (miguel@gnu.org)
+ *
+ * (C) 1999 Helix Code, Inc.
+ */
+#include <config.h>
+#include <stdlib.h>
+#include <gtk/gtksignal.h>
+#include <string.h>
+#include "e-util/e-util.h"
+#include "e-table-subset-variable.h"
+
+#define PARENT_TYPE E_TABLE_SUBSET_TYPE
+
+#define INCREMENT_AMOUNT 10
+
+static ETableModelClass *etssv_parent_class;
+
+static void
+etssv_class_init (GtkObjectClass *klass)
+{
+ etssv_parent_class = gtk_type_class (PARENT_TYPE);
+}
+
+E_MAKE_TYPE(e_table_subset_variable, "ETableSubsetVariable", ETableSubsetVariable, etssv_class_init, NULL, PARENT_TYPE);
+
+ETableModel *
+e_table_subset_variable_construct (ETableSubsetVariable *etssv,
+ ETableModel *source)
+{
+ if ( e_table_subset_construct(E_TABLE_SUBSET(etssv), source, 1) == NULL )
+ return NULL;
+ E_TABLE_SUBSET(etssv)->n_map = 0;
+
+ return E_TABLE_MODEL (etssv);
+}
+
+ETableModel *
+e_table_subset_variable_new (ETableModel *source)
+{
+ ETableSubsetVariable *etssv = gtk_type_new (E_TABLE_SUBSET_VARIABLE_TYPE);
+
+ if (e_table_subset_variable_construct (etssv, source) == NULL){
+ gtk_object_destroy (GTK_OBJECT (etssv));
+ return NULL;
+ }
+
+ return (ETableModel *) etssv;
+}
+
+void
+e_table_subset_variable_add (ETableSubsetVariable *etssv,
+ gint row)
+{
+ ETableModel *etm = E_TABLE_MODEL(etssv);
+ ETableSubset *etss = E_TABLE_SUBSET(etssv);
+
+ if ( etss->n_map + 1 > etssv->n_vals_allocated )
+ etss->map_table = g_realloc(etss->map_table, (etssv->n_vals_allocated + INCREMENT_AMOUNT) * sizeof(int));
+ etss->map_table[etss->n_map++] = row;
+ if ( !etm->frozen )
+ e_table_model_changed(etm);
+}
+
+gboolean
+e_table_subset_variable_remove (ETableSubsetVariable *etssv,
+ gint row)
+{
+ ETableModel *etm = E_TABLE_MODEL(etssv);
+ ETableSubset *etss = E_TABLE_SUBSET(etssv);
+ int i;
+
+ for ( i = 0; i < etss->n_map; i++ ) {
+ if (etss->map_table[i] == row) {
+ memmove(etss->map_table + i, etss->map_table + i + 1, (etss->n_map - i - 1) * sizeof(int));
+ etss->n_map --;
+ if ( !etm->frozen )
+ e_table_model_changed(etm);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void
+e_table_subset_variable_increment (ETableSubsetVariable *etssv,
+ gint position,
+ gint amount)
+{
+ int i;
+ ETableSubset *etss = E_TABLE_SUBSET(etssv);
+ for ( i = 0; i < etss->n_map; i++ ) {
+ if ( etss->map_table[i] > position )
+ etss->map_table[i] += amount;
+ }
+}
+
+void
+e_table_subset_variable_set_allocation (ETableSubsetVariable *etssv,
+ gint total)
+{
+ ETableSubset *etss = E_TABLE_SUBSET(etssv);
+ if ( total <= 0 )
+ total = 1;
+ if ( total > etss->n_map ) {
+ etss->map_table = g_realloc(etss->map_table, total * sizeof(int));
+ }
+}
diff --git a/widgets/table/e-table-subset-variable.h b/widgets/table/e-table-subset-variable.h
new file mode 100644
index 0000000000..9755fb2477
--- /dev/null
+++ b/widgets/table/e-table-subset-variable.h
@@ -0,0 +1,38 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+#ifndef _E_TABLE_SUBSET_VARIABLE_H_
+#define _E_TABLE_SUBSET_VARIABLE_H_
+
+#include <gtk/gtkobject.h>
+#include "e-table-subset.h"
+
+#define E_TABLE_SUBSET_VARIABLE_TYPE (e_table_subset_variable_get_type ())
+#define E_TABLE_SUBSET_VARIABLE(o) (GTK_CHECK_CAST ((o), E_TABLE_SUBSET_VARIABLE_TYPE, ETableSubsetVariable))
+#define E_TABLE_SUBSET_VARIABLE_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_SUBSET_VARIABLE_TYPE, ETableSubsetVariableClass))
+#define E_IS_TABLE_SUBSET_VARIABLE(o) (GTK_CHECK_TYPE ((o), E_TABLE_SUBSET_VARIABLE_TYPE))
+#define E_IS_TABLE_SUBSET_VARIABLE_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_SUBSET_VARIABLE_TYPE))
+
+typedef struct {
+ ETableSubset base;
+
+ int n_vals_allocated;
+} ETableSubsetVariable;
+
+typedef struct {
+ ETableSubsetClass parent_class;
+} ETableSubsetVariableClass;
+
+GtkType e_table_subset_variable_get_type (void);
+ETableModel *e_table_subset_variable_new (ETableModel *etm);
+ETableModel *e_table_subset_variable_construct (ETableSubsetVariable *etssv,
+ ETableModel *source);
+void e_table_subset_variable_add (ETableSubsetVariable *ets,
+ gint row);
+gboolean e_table_subset_variable_remove (ETableSubsetVariable *ets,
+ gint row);
+void e_table_subset_variable_increment (ETableSubsetVariable *ets,
+ gint position,
+ gint amount);
+void e_table_subset_variable_set_allocation (ETableSubsetVariable *ets,
+ gint total);
+#endif /* _E_TABLE_SUBSET_VARIABLE_H_ */
+
diff --git a/widgets/table/e-table-subset.c b/widgets/table/e-table-subset.c
index a9e4a5c5a4..a09d221980 100644
--- a/widgets/table/e-table-subset.c
+++ b/widgets/table/e-table-subset.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* E-table-subset.c: Implements a table that contains a subset of another table.
*
@@ -71,6 +72,12 @@ etss_is_cell_editable (ETableModel *etm, int col, int row)
}
static void
+etss_thaw (ETableModel *etm)
+{
+ e_table_model_changed (etm);
+}
+
+static void
etss_class_init (GtkObjectClass *klass)
{
ETableModelClass *table_class = (ETableModelClass *) klass;
@@ -84,6 +91,7 @@ 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->thaw = etss_thaw;
}
E_MAKE_TYPE(e_table_subset, "ETableSubset", ETableSubset, etss_class_init, NULL, PARENT_TYPE);
@@ -91,20 +99,23 @@ E_MAKE_TYPE(e_table_subset, "ETableSubset", ETableSubset, etss_class_init, NULL,
static void
etss_proxy_model_changed (ETableModel *etm, ETableSubset *etss)
{
- e_table_model_changed (E_TABLE_MODEL (etss));
+ if ( !E_TABLE_MODEL(etss)->frozen )
+ e_table_model_changed (E_TABLE_MODEL (etss));
}
static void
etss_proxy_model_row_changed (ETableModel *etm, int row, ETableSubset *etss)
{
- 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] == row){
- e_table_model_row_changed (E_TABLE_MODEL (etss), i);
- return;
+ if ( !E_TABLE_MODEL(etss)->frozen ) {
+ 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] == row){
+ e_table_model_row_changed (E_TABLE_MODEL (etss), i);
+ return;
+ }
}
}
}
@@ -112,14 +123,16 @@ etss_proxy_model_row_changed (ETableModel *etm, int row, ETableSubset *etss)
static void
etss_proxy_model_cell_changed (ETableModel *etm, int col, int row, ETableSubset *etss)
{
- 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] == row){
- e_table_model_cell_changed (E_TABLE_MODEL (etss), col, i);
- return;
+ if ( !E_TABLE_MODEL(etss)->frozen ) {
+ 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] == row){
+ e_table_model_cell_changed (E_TABLE_MODEL (etss), col, i);
+ return;
+ }
}
}
}
@@ -130,7 +143,7 @@ e_table_subset_construct (ETableSubset *etss, ETableModel *source, int nvals)
unsigned int *buffer;
int i;
- buffer = (unsigned int *) malloc (sizeof (unsigned int) * nvals);
+ buffer = (unsigned int *) g_malloc (sizeof (unsigned int) * nvals);
if (buffer == NULL)
return NULL;
etss->map_table = buffer;
diff --git a/widgets/table/e-table-subset.h b/widgets/table/e-table-subset.h
index 314f28aea6..d8af1696f5 100644
--- a/widgets/table/e-table-subset.h
+++ b/widgets/table/e-table-subset.h
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#ifndef _E_TABLE_SUBSET_H_
#define _E_TABLE_SUBSET_H_
diff --git a/widgets/table/e-table.c b/widgets/table/e-table.c
index 46531113e4..551ef52227 100644
--- a/widgets/table/e-table.c
+++ b/widgets/table/e-table.c
@@ -1,5 +1,6 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * E-table-view.c: A graphical view of a Table.
+ * E-table.c: A graphical view of a Table.
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
@@ -16,7 +17,9 @@
#include <stdio.h>
#include <libgnomeui/gnome-canvas.h>
#include <gtk/gtksignal.h>
+#include <gnome-xml/parser.h>
#include "e-util/e-util.h"
+#include "e-util/e-xml-utils.h"
#include "e-table.h"
#include "e-table-header-item.h"
#include "e-table-subset.h"
@@ -40,8 +43,6 @@ et_destroy (GtkObject *object)
gtk_object_unref (GTK_OBJECT (et->full_header));
gtk_object_unref (GTK_OBJECT (et->header));
- g_free (et->group_spec);
-
(*e_table_parent_class->destroy)(object);
}
@@ -56,19 +57,16 @@ e_table_init (GtkObject *object)
}
static ETableHeader *
-e_table_make_header (ETable *e_table, ETableHeader *full_header, const char *cols)
+e_table_make_header (ETable *e_table, ETableHeader *full_header, xmlNode *xmlColumns)
{
ETableHeader *nh;
- char *copy = alloca (strlen (cols) + 1);
- char *p, *state;
+ xmlNode *column;
const int max_cols = e_table_header_count (full_header);
nh = e_table_header_new ();
- strcpy (copy, cols);
- while ((p = strtok_r (copy, ",", &state)) != NULL){
- int col = atoi (p);
+ for (column = xmlColumns->childs; column; column = column->next) {
+ int col = atoi (column->childs->content);
- copy = NULL;
if (col >= max_cols)
continue;
@@ -113,6 +111,7 @@ e_table_setup_header (ETable *e_table)
}
+#if 0
typedef struct {
void *value;
GArray *array;
@@ -201,7 +200,7 @@ e_table_make_subtables (ETableModel *model, GArray *groups)
return (ETableModel **) tables;
}
-
+#endif
typedef struct _Node Node;
struct _Node {
@@ -212,7 +211,7 @@ struct _Node {
guint is_leaf:1;
};
-
+#if 0
static Node *
leaf_new (GnomeCanvasItem *table_item, ETableModel *table_model, Node *parent)
{
@@ -335,8 +334,9 @@ e_table_create_nodes (ETable *e_table, ETableModel *model, ETableHeader *header,
groups = e_table_create_groups (model, key_col, ecol->compare);
tables = e_table_make_subtables (e_table->model, groups);
e_table_destroy_groups (groups);
-
- group_item = e_table_group_new (root, ecol, TRUE, parent == NULL);
+ group_item = gnome_canvas_item_new (root,
+ e_table_group_get_type(),
+ "columns", ecol, TRUE, parent == NULL);
group = node_new (group_item, model, parent);
for (i = 0; tables [i] != NULL; i++){
@@ -347,8 +347,9 @@ e_table_create_nodes (ETable *e_table, ETableModel *model, ETableHeader *header,
GnomeCanvasItem *item_leaf_header;
Node *leaf_header;
+ /* FIXME *//*
item_leaf_header = e_table_group_new (
- GNOME_CANVAS_GROUP (group_item), ecol, TRUE, FALSE);
+ GNOME_CANVAS_GROUP (group_item), ecol, TRUE, FALSE);*/
leaf_header = node_new (item_leaf_header, tables [i], group);
e_table_create_leaf (e_table, tables [i], leaf_header);
@@ -424,6 +425,14 @@ static GnomeCanvasClass *e_table_canvas_parent_class;
static void
e_table_canvas_realize (GtkWidget *widget)
{
+#if 0
+ GnomeCanvasItem *group_item;
+
+ group_item = gnome_canvas_item_new (root,
+ e_table_group_get_type(),
+ "header", E_TABLE, TRUE, parent == NULL);
+
+
ETableCanvas *e_table_canvas = (ETableCanvas *) widget;
ETable *e_table = e_table_canvas->e_table;
int *groups;
@@ -433,6 +442,8 @@ e_table_canvas_realize (GtkWidget *widget)
groups = group_spec_to_desc (e_table->group_spec);
+
+
leaf = e_table_create_nodes (
e_table, e_table->model,
e_table->header, GNOME_CANVAS_GROUP (e_table->root), 0, groups);
@@ -440,6 +451,7 @@ e_table_canvas_realize (GtkWidget *widget)
if (groups)
g_free (groups);
+#endif
}
static void
@@ -496,33 +508,75 @@ e_table_canvas_new (ETable *e_table)
return GNOME_CANVAS (e_table_canvas);
}
+#endif
static void
-table_canvas_size_alocate (GtkWidget *widget, GtkAllocation *alloc, ETable *e_table)
+table_canvas_size_allocate (GtkWidget *widget, GtkAllocation *alloc, ETable *e_table)
{
+ gdouble height;
+ gdouble width;
+ gtk_object_get(GTK_OBJECT(e_table->group),
+ "height", &height,
+ NULL);
gnome_canvas_set_scroll_region (
GNOME_CANVAS (e_table->table_canvas),
- 0, 0, alloc->width, alloc->height);
+ 0, 0, alloc->width, MAX(height, alloc->height));
+ width = alloc->width;
+ gtk_object_set(GTK_OBJECT(e_table->group),
+ "width", width,
+ NULL);
}
static void
-e_table_setup_table (ETable *e_table)
+e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *header, ETableModel *model, xmlNode *xml_grouping)
{
- e_table->table_canvas = e_table_canvas_new (e_table);
+ e_table->table_canvas = GNOME_CANVAS(gnome_canvas_new ());
gtk_signal_connect (
GTK_OBJECT (e_table->table_canvas), "size_allocate",
- GTK_SIGNAL_FUNC (table_canvas_size_alocate), e_table);
+ GTK_SIGNAL_FUNC (table_canvas_size_allocate), e_table);
gtk_widget_show (GTK_WIDGET (e_table->table_canvas));
gtk_table_attach (
GTK_TABLE (e_table), GTK_WIDGET (e_table->table_canvas),
0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
+
+ e_table->group = e_table_group_new(GNOME_CANVAS_GROUP(e_table->table_canvas->root),
+ full_header,
+ header,
+ model,
+ xml_grouping->childs);
+
+}
+
+static void
+e_table_fill_table (ETable *e_table, ETableModel *model)
+{
+ int count;
+ int i;
+ count = e_table_model_row_count(model);
+ gtk_object_set(GTK_OBJECT(e_table->group),
+ "frozen", TRUE,
+ NULL);
+ for ( i = 0; i < count; i++ ) {
+ e_table_group_add(e_table->group, i);
+ }
+ gtk_object_set(GTK_OBJECT(e_table->group),
+ "frozen", FALSE,
+ NULL);
}
void
e_table_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm,
- const char *cols_spec, const char *group_spec)
+ const char *spec)
{
+ xmlDoc *xmlSpec;
+ xmlNode *xmlRoot;
+ xmlNode *xmlColumns;
+ xmlNode *xmlGrouping;
+
+ char *copy;
+ copy = g_strdup(spec);
+
GTK_TABLE (e_table)->homogeneous = FALSE;
gtk_table_resize (GTK_TABLE (e_table), 1, 2);
@@ -532,24 +586,29 @@ e_table_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm,
e_table->model = etm;
gtk_object_ref (GTK_OBJECT (etm));
+
+ xmlSpec = xmlParseMemory(copy, strlen(copy) + 1);
+ e_table->specification = xmlSpec;
- e_table->header = e_table_make_header (e_table, full_header, cols_spec);
+ xmlRoot = xmlDocGetRootElement(xmlSpec);
+ xmlColumns = e_xml_get_child_by_name(xmlRoot, "columns-shown");
+ xmlGrouping = e_xml_get_child_by_name(xmlRoot, "grouping");
+
+ e_table->header = e_table_make_header (e_table, full_header, xmlColumns);
e_table_setup_header (e_table);
- e_table_setup_table (e_table);
-
- e_table->group_spec = g_strdup (group_spec);
-
+ e_table_setup_table (e_table, full_header, e_table->header, etm, xmlGrouping);
+ e_table_fill_table (e_table, etm);
}
GtkWidget *
-e_table_new (ETableHeader *full_header, ETableModel *etm, const char *cols_spec, const char *group_spec)
+e_table_new (ETableHeader *full_header, ETableModel *etm, const char *spec)
{
ETable *e_table;
e_table = gtk_type_new (e_table_get_type ());
- e_table_construct (e_table, full_header, etm, cols_spec, group_spec);
+ e_table_construct (e_table, full_header, etm, spec);
return (GtkWidget *) e_table;
}
diff --git a/widgets/table/e-table.h b/widgets/table/e-table.h
index 63c131324f..a372d8042c 100644
--- a/widgets/table/e-table.h
+++ b/widgets/table/e-table.h
@@ -1,10 +1,13 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#ifndef _E_TABLE_H_
#define _E_TABLE_H_
#include <libgnomeui/gnome-canvas.h>
#include <gtk/gtktable.h>
+#include <gnome-xml/tree.h>
#include "e-table-model.h"
#include "e-table-header.h"
+#include "e-table-group.h"
BEGIN_GNOME_DECLS
@@ -21,15 +24,17 @@ typedef struct {
ETableHeader *full_header, *header;
+ ETableGroup *group;
+
GnomeCanvas *header_canvas, *table_canvas;
GnomeCanvasItem *header_item, *root;
+
+ xmlDoc *specification;
guint draw_grid:1;
guint draw_focus:1;
guint spreadsheet:1;
-
- char *group_spec;
} ETable;
typedef struct {
@@ -38,9 +43,9 @@ typedef struct {
GtkType e_table_get_type (void);
void e_table_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm,
- const char *cols_spec, const char *group_spec);
+ const char *spec);
GtkWidget *e_table_new (ETableHeader *full_header, ETableModel *etm,
- const char *cols_spec, const char *group_spec);
+ const char *spec);
END_GNOME_DECLS
diff --git a/widgets/table/test-check.c b/widgets/table/test-check.c
index 380da8048e..a6a59788ad 100644
--- a/widgets/table/test-check.c
+++ b/widgets/table/test-check.c
@@ -13,6 +13,7 @@
#include "e-table-header-item.h"
#include "e-table-item.h"
#include "e-util/e-cursors.h"
+#include "e-util/e-canvas-utils.h"
#include "e-cell-text.h"
#include "e-cell-checkbox.h"
@@ -79,6 +80,12 @@ is_cell_editable (ETableModel *etc, int col, int row, void *data)
}
static void
+thaw (ETableModel *etc, void *data)
+{
+ e_table_model_changed(etc);
+}
+
+static void
set_canvas_size (GnomeCanvas *canvas, GtkAllocation *alloc)
{
gnome_canvas_set_scroll_region (canvas, 0, 0, alloc->width, alloc->height);
@@ -93,13 +100,14 @@ check_test (void)
ETableCol *col_0, *col_1;
ECell *cell_left_just, *cell_image_check;
GdkPixbuf *pixbuf;
+ GnomeCanvasItem *item;
gtk_widget_push_visual (gdk_rgb_get_visual ());
gtk_widget_push_colormap (gdk_rgb_get_cmap ());
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
- set_value_at, is_cell_editable, NULL);
+ set_value_at, is_cell_editable, thaw, NULL);
/*
* Header
@@ -137,21 +145,15 @@ check_test (void)
"y", 0,
NULL);
- gnome_canvas_item_new (
+ item = gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_item_get_type (),
"ETableHeader", e_table_header,
"ETableModel", e_table_model,
- "x", (double) 0,
- "y", (double) 30,
"drawgrid", TRUE,
"drawfocus", TRUE,
"spreadsheet", TRUE,
NULL);
-
+ e_canvas_item_move_absolute(item, 0, 30);
}
-
-
-
-
diff --git a/widgets/table/test-cols.c b/widgets/table/test-cols.c
index 3fe17ae555..adc9ed6c20 100644
--- a/widgets/table/test-cols.c
+++ b/widgets/table/test-cols.c
@@ -8,6 +8,7 @@
#include <stdio.h>
#include <string.h>
#include <gnome.h>
+#include "e-util/e-canvas-utils.h"
#include "e-util/e-cursors.h"
#include "e-table-simple.h"
#include "e-table-header.h"
@@ -84,6 +85,12 @@ set_canvas_size (GnomeCanvas *canvas, GtkAllocation *alloc)
gnome_canvas_set_scroll_region (canvas, 0, 0, alloc->width, alloc->height);
}
+static void
+thaw (ETableModel *etc, void *data)
+{
+ e_table_model_changed(etc);
+}
+
void
multi_cols_test (void)
{
@@ -92,13 +99,14 @@ multi_cols_test (void)
ETableHeader *e_table_header, *e_table_header_multiple;
ETableCol *col_0, *col_1;
ECell *cell_left_just, *cell_image_toggle;
+ GnomeCanvasItem *item;
gtk_widget_push_visual (gdk_rgb_get_visual ());
gtk_widget_push_colormap (gdk_rgb_get_cmap ());
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
- set_value_at, is_cell_editable, NULL);
+ set_value_at, is_cell_editable, thaw, NULL);
/*
* Header
@@ -157,17 +165,17 @@ multi_cols_test (void)
"y", 0,
NULL);
- gnome_canvas_item_new (
+ item = gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_item_get_type (),
"ETableHeader", e_table_header,
"ETableModel", e_table_model,
- "x", (double) 0,
- "y", (double) 30,
"drawgrid", TRUE,
"drawfocus", TRUE,
"spreadsheet", TRUE,
NULL);
+
+ e_canvas_item_move_absolute(item, 0, 30);
gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
@@ -176,18 +184,16 @@ multi_cols_test (void)
"x", 300,
"y", 0,
NULL);
- gnome_canvas_item_new (
+ item = gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_item_get_type (),
"ETableHeader", e_table_header_multiple,
"ETableModel", e_table_model,
- "x", (double) 300,
- "y", (double) 30,
"drawgrid", TRUE,
"drawfocus", TRUE,
"spreadsheet", TRUE,
NULL);
-
+ e_canvas_item_move_absolute(item, 300, 30);
}
diff --git a/widgets/table/test-table.c b/widgets/table/test-table.c
index 27e1ac59f1..1bd50e1479 100644
--- a/widgets/table/test-table.c
+++ b/widgets/table/test-table.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Test code for the ETable package
*
@@ -55,6 +56,8 @@ parse_headers ()
p = buffer;
for (i = 0; (s = strtok (p, " \t")) != NULL; i++){
column_labels [i] = g_strdup (s);
+ if ( strchr(column_labels [i], '\n') )
+ *strchr(column_labels [i], '\n') = 0;
p = NULL;
}
@@ -174,6 +177,12 @@ is_cell_editable (ETableModel *etc, int col, int row, void *data)
}
static void
+thaw (ETableModel *etc, void *data)
+{
+ e_table_model_changed(etc);
+}
+
+static void
set_canvas_size (GnomeCanvas *canvas, GtkAllocation *alloc)
{
gnome_canvas_set_scroll_region (canvas, 0, 0, alloc->width, alloc->height);
@@ -196,7 +205,7 @@ table_browser_test (void)
*/
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
- set_value_at, is_cell_editable, NULL);
+ set_value_at, is_cell_editable, thaw, NULL);
/*
* Header
@@ -244,8 +253,6 @@ table_browser_test (void)
e_table_item_get_type (),
"ETableHeader", e_table_header,
"ETableModel", e_table_model,
- "x", (double) 0,
- "y", (double) 0,
"drawgrid", TRUE,
"drawfocus", TRUE,
"spreadsheet", TRUE,
@@ -253,7 +260,7 @@ table_browser_test (void)
}
static void
-do_e_table_demo (const char *col_spec, const char *group_spec)
+do_e_table_demo (const char *spec)
{
GtkWidget *e_table, *window, *frame;
ETableModel *e_table_model;
@@ -266,7 +273,7 @@ do_e_table_demo (const char *col_spec, const char *group_spec)
*/
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
- set_value_at, is_cell_editable, NULL);
+ set_value_at, is_cell_editable, thaw, NULL);
full_header = e_table_header_new ();
cell_left_just = e_cell_text_new (e_table_model, NULL, GTK_JUSTIFY_LEFT, TRUE);
@@ -283,7 +290,7 @@ do_e_table_demo (const char *col_spec, const char *group_spec)
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
frame = gtk_frame_new (NULL);
- e_table = e_table_new (full_header, e_table_model, col_spec, group_spec);
+ e_table = e_table_new (full_header, e_table_model, spec);
gtk_container_add (GTK_CONTAINER (frame), e_table);
gtk_container_add (GTK_CONTAINER (window), frame);
@@ -298,9 +305,10 @@ e_table_test (void)
{
load_data ();
- if (getenv ("DO")){
- do_e_table_demo ("0,1,2,3,4", NULL);
- do_e_table_demo ("0,1,2,3,4", "3,4");
+ if (1){/*getenv ("DO")){*/
+ do_e_table_demo ("<ETableSpecification> <columns-shown> <column> 0 </column> <column> 1 </column> <column> 2 </column> <column> 3 </column> <column> 4 </column> </columns-shown> <grouping> <leaf/> </grouping> </ETableSpecification>");
+ do_e_table_demo ("<ETableSpecification> <columns-shown> <column> 0 </column> <column> 0 </column> <column> 0 </column> <column> 0 </column> <column> 0 </column> <column> 1 </column> <column> 2 </column> <column> 3 </column> <column> 4 </column> </columns-shown> <grouping> <group column=\"3\"> <group column=\"4\"> <leaf/> </group> </group> </grouping> </ETableSpecification>");
}
- do_e_table_demo ("0,1,2,3,4", "3");
+ do_e_table_demo ("<ETableSpecification> <columns-shown> <column> 0 </column> <column> 1 </column> <column> 2 </column> <column> 3 </column> <column> 4 </column> </columns-shown> <grouping> <group column=\"4\"> <leaf/> </group> </grouping> </ETableSpecification>");
+ do_e_table_demo ("<ETableSpecification> <columns-shown> <column> 0 </column> <column> 1 </column> <column> 2 </column> <column> 3 </column> <column> 4 </column> </columns-shown> <grouping> <group column=\"3\"> <leaf/> </group> </grouping> </ETableSpecification>");
}
diff --git a/widgets/text/e-text.c b/widgets/text/e-text.c
index 2e3e7c158a..6647531eee 100644
--- a/widgets/text/e-text.c
+++ b/widgets/text/e-text.c
@@ -109,8 +109,6 @@ static gint e_text_event (GnomeCanvasItem *item, GdkEvent *event);
static void e_text_command(ETextEventProcessor *tep, ETextEventProcessorCommand *command, gpointer data);
-static guint32 e_text_get_event_time (EText *text);
-
static void e_text_get_selection(EText *text, GdkAtom selection, guint32 time);
static void e_text_supply_selection (EText *text, guint time, GdkAtom selection, guchar *data, gint length);
@@ -1701,7 +1699,7 @@ static void
_get_xy_from_position (EText *text, gint position, gint *xp, gint *yp)
{
if (xp || yp) {
- struct line *lines;
+ struct line *lines = NULL;
int x, y;
int j;
x = get_line_xpos (text, lines);
@@ -1993,7 +1991,9 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event)
}
break;
case GDK_ENTER_NOTIFY:
- text->tooltip_timeout = gtk_timeout_add (3000, _do_tooltip, text);
+ if ( text->tooltip_count == 0 )
+ text->tooltip_timeout = gtk_timeout_add (1000, _do_tooltip, text);
+ text->tooltip_count ++;
text->pointer_in = TRUE;
if (text->editing) {
if ( text->default_cursor_shown ) {
@@ -2003,10 +2003,13 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event)
}
break;
case GDK_LEAVE_NOTIFY:
- gtk_timeout_remove (text->tooltip_timeout);
- if (text->tooltip_window) {
- gtk_widget_destroy (text->tooltip_window);
- text->tooltip_window = NULL;
+ text->tooltip_count --;
+ if ( text->tooltip_count == 0 ) {
+ gtk_timeout_remove (text->tooltip_timeout);
+ if (text->tooltip_window) {
+ gtk_widget_destroy (text->tooltip_window);
+ text->tooltip_window = NULL;
+ }
}
text->pointer_in = FALSE;
@@ -2443,50 +2446,6 @@ e_text_real_paste_clipboard (EText *text)
}
#endif
-/* Get the timestamp of the current event. Actually, the only thing
- * we really care about below is the key event
- */
-static guint32
-e_text_get_event_time (EText *text)
-{
- GdkEvent *event;
- guint32 tm = GDK_CURRENT_TIME;
-
- event = gtk_get_current_event();
-
- if (event)
- switch (event->type)
- {
- case GDK_MOTION_NOTIFY:
- tm = event->motion.time; break;
- case GDK_BUTTON_PRESS:
- case GDK_2BUTTON_PRESS:
- case GDK_3BUTTON_PRESS:
- case GDK_BUTTON_RELEASE:
- tm = event->button.time; break;
- case GDK_KEY_PRESS:
- case GDK_KEY_RELEASE:
- tm = event->key.time; break;
- case GDK_ENTER_NOTIFY:
- case GDK_LEAVE_NOTIFY:
- tm = event->crossing.time; break;
- case GDK_PROPERTY_NOTIFY:
- tm = event->property.time; break;
- case GDK_SELECTION_CLEAR:
- case GDK_SELECTION_REQUEST:
- case GDK_SELECTION_NOTIFY:
- tm = event->selection.time; break;
- case GDK_PROXIMITY_IN:
- case GDK_PROXIMITY_OUT:
- tm = event->proximity.time; break;
- default: /* use current time */
- break;
- }
- gdk_event_free(event);
-
- return tm;
-}
-
/* Routines for sucking fonts from the X server */
diff --git a/widgets/text/e-text.h b/widgets/text/e-text.h
index c44589d3ae..2f29fb189b 100644
--- a/widgets/text/e-text.h
+++ b/widgets/text/e-text.h
@@ -176,6 +176,7 @@ struct _EText {
gint tooltip_timeout; /* Timeout for the tooltip */
GtkWidget *tooltip_window; /* GtkWindow for displaying the tooltip */
+ gint tooltip_count; /* GDK_ENTER_NOTIFY count. */
};
struct _ETextClass {