aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/e-table
diff options
context:
space:
mode:
authorChristopher James Lahey <clahey@helixcode.com>2000-02-24 14:51:23 +0800
committerChris Lahey <clahey@src.gnome.org>2000-02-24 14:51:23 +0800
commit7699b8996aa2d9ae3fea0e94981637c98e89a273 (patch)
treef4321790cd8c8619babfac9e2d4f38ca621d7e2d /widgets/e-table
parent6b338ae8ecd1332f574e33620e0765a16aab03a3 (diff)
downloadgsoc2013-evolution-7699b8996aa2d9ae3fea0e94981637c98e89a273.tar.gz
gsoc2013-evolution-7699b8996aa2d9ae3fea0e94981637c98e89a273.tar.zst
gsoc2013-evolution-7699b8996aa2d9ae3fea0e94981637c98e89a273.zip
This were moved to widgets/e-text/ a while ago but never removed. They
2000-02-24 Christopher James Lahey <clahey@helixcode.com> * widgets/e-text.c, widgets/e-text.h, e-text-event-processor.c, e-text-event-processor.h, e-text-event-processor-emacs-like.c, e-text-event-processor-emacs-like.h, e-text-event-processor-types.h: This were moved to widgets/e-text/ a while ago but never removed. They have now been removed. * widgets/e-text/e-text.c, widgets/e-text/e-text.h: Removed some warnings from this file. Made tooltips disappear when you're finished with them. * widgets/e-minicard/test-reflow.c, widgets/e-minicard/test-minicard.c, widgets/e-minicard/test-minicard-label.c: Commented out unused about_callback functions. * widgets/e-minicard/e-reflow.c: Made e-reflow pass an EFocus to its e-minicard children. * widgets/e-minicard/e-minicard.c: Made e-minicard take and return an EFocus for its "has_focus" argument. This makes shift-tab work properly. * widgets/e-minicard/e-minicard-label.c: Made e-minicard-label take and return an EFocus for its "has_focus" argument. Made the font that e-minicard-label uses only be allocated once. * e-util/e-canvas-utils.h: Fixed the comment at the top and added #ifndef __E_CANVAS_UTILS__. * e-util/Makefile.am: Added e-xml-utils.c and e-xml-utils.h. * e-util/e-xml-utils.h, e-util/e-xml-utils.c: Added files for some xml utilities. * e-util/e-util.h: Added type EFocus which describes which direction the focus will be coming from. in mail: 2000-02-24 Christopher James Lahey <clahey@helixcode.com> * message-list.c: Changed this to not use the "x" and "y" arguments to e-table-item. in widgets/e-table: 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. svn path=/trunk/; revision=1915
Diffstat (limited to 'widgets/e-table')
-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
30 files changed, 2082 insertions, 388 deletions
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>");
}