From 43fd06f8ec06257cbd135b03c5e203dfcd134fd4 Mon Sep 17 00:00:00 2001 From: Arturo Espinosa Date: Fri, 12 Nov 1999 08:41:20 +0000 Subject: More table work svn path=/trunk/; revision=1383 --- widgets/ChangeLog | 14 +++ widgets/Makefile.am | 20 +++- widgets/e-table-col.c | 44 +++++++ widgets/e-table-col.h | 33 ++++++ widgets/e-table-header-item.c | 10 +- widgets/e-table-header.c | 44 +++++-- widgets/e-table-header.h | 54 +++------ widgets/e-table-model.c | 2 +- widgets/e-table-model.h | 46 ++++++++ widgets/e-table-render.c | 20 ++++ widgets/e-table-render.h | 21 ++++ widgets/e-table-simple.c | 4 +- widgets/e-table-simple.h | 4 +- widgets/e-table/ChangeLog | 14 +++ widgets/e-table/Makefile.am | 20 +++- widgets/e-table/e-table-col.c | 44 +++++++ widgets/e-table/e-table-col.h | 33 ++++++ widgets/e-table/e-table-header-item.c | 10 +- widgets/e-table/e-table-header.c | 44 +++++-- widgets/e-table/e-table-header.h | 54 +++------ widgets/e-table/e-table-model.c | 2 +- widgets/e-table/e-table-model.h | 46 ++++++++ widgets/e-table/e-table-render.c | 20 ++++ widgets/e-table/e-table-render.h | 21 ++++ widgets/e-table/e-table-simple.c | 4 +- widgets/e-table/e-table-simple.h | 4 +- widgets/e-table/sample.table | 8 ++ widgets/e-table/table-test.c | 216 ++++++++++++++++++++++++++++++++++ widgets/e-table/test.c | 17 +++ widgets/sample.table | 8 ++ widgets/table-test.c | 216 ++++++++++++++++++++++++++++++++++ widgets/table/e-table-col.c | 44 +++++++ widgets/table/e-table-col.h | 33 ++++++ widgets/table/e-table-header-item.c | 10 +- widgets/table/e-table-header.c | 44 +++++-- widgets/table/e-table-header.h | 54 +++------ widgets/table/e-table-model.c | 2 +- widgets/table/e-table-model.h | 46 ++++++++ widgets/table/e-table-render.c | 20 ++++ widgets/table/e-table-render.h | 21 ++++ widgets/table/e-table-simple.c | 4 +- widgets/table/e-table-simple.h | 4 +- widgets/table/sample.table | 8 ++ widgets/table/table-test.c | 216 ++++++++++++++++++++++++++++++++++ widgets/table/test.c | 17 +++ widgets/test.c | 17 +++ 46 files changed, 1445 insertions(+), 192 deletions(-) create mode 100644 widgets/e-table-col.c create mode 100644 widgets/e-table-col.h create mode 100644 widgets/e-table-model.h create mode 100644 widgets/e-table-render.c create mode 100644 widgets/e-table-render.h create mode 100644 widgets/e-table/e-table-col.c create mode 100644 widgets/e-table/e-table-col.h create mode 100644 widgets/e-table/e-table-model.h create mode 100644 widgets/e-table/e-table-render.c create mode 100644 widgets/e-table/e-table-render.h create mode 100644 widgets/e-table/sample.table create mode 100644 widgets/e-table/table-test.c create mode 100644 widgets/e-table/test.c create mode 100644 widgets/sample.table create mode 100644 widgets/table-test.c create mode 100644 widgets/table/e-table-col.c create mode 100644 widgets/table/e-table-col.h create mode 100644 widgets/table/e-table-model.h create mode 100644 widgets/table/e-table-render.c create mode 100644 widgets/table/e-table-render.h create mode 100644 widgets/table/sample.table create mode 100644 widgets/table/table-test.c create mode 100644 widgets/table/test.c create mode 100644 widgets/test.c (limited to 'widgets') diff --git a/widgets/ChangeLog b/widgets/ChangeLog index d0c7b288e4..48c797c007 100644 --- a/widgets/ChangeLog +++ b/widgets/ChangeLog @@ -1,3 +1,17 @@ +1999-11-11 Miguel de Icaza + + * e-table-header.c (e_table_header_add_column): Update offsets. + (eth_update_offsets): New routine. + + * e-table-col.h, e-table-col.c: New files. + + * e-table-header.h (e_table_header_get_selected_indexes): + Pretify. + + * table-test.c (main): New file; used for testing ETable package. + + * e-table-simple.h: Fix type. + 1999-11-12 Ettore Perazzoli * e-msg-composer-address-dialog.glade: Cosmetical changes. diff --git a/widgets/Makefile.am b/widgets/Makefile.am index 875e61f6b1..300f6e3017 100644 --- a/widgets/Makefile.am +++ b/widgets/Makefile.am @@ -28,9 +28,9 @@ libevolutionwidgets_la_SOURCES = \ e-msg-composer-hdrs.c \ e-msg-composer-hdrs.h \ e-msg-composer.c \ - e-msg-composer.h - -EXTRA_DIST = \ + e-msg-composer.h \ + e-table-col.c \ + e-table-col.h \ e-table-group.c \ e-table-group.h \ e-table-header.c \ @@ -39,6 +39,20 @@ EXTRA_DIST = \ e-table-header-item.h \ e-table-model.c \ e-table-model.h \ + e-table-render.c \ + e-table-render.h \ e-table-simple.c \ e-table-simple.h +noinst_PROGRAMS = \ + table-test + +table_test_SOURCES = \ + table-test.c + +table_test_LDADD = \ + $(EXTRA_GNOME_LIBS) \ + libevolutionwidgets.a + +EXTRA_DIST = \ + sample.table diff --git a/widgets/e-table-col.c b/widgets/e-table-col.c new file mode 100644 index 0000000000..8a2bfe90cf --- /dev/null +++ b/widgets/e-table-col.c @@ -0,0 +1,44 @@ +/* + * E-table-col.c: ETableCol implementation + * + * Author: + * Miguel de Icaza (miguel@gnu.org) + * + * (C) 1999 International GNOME Support + */ +#include +#include +#include +#include "e-table-col.h" + +ETableCol * +e_table_col_new (const char *id, int width, int min_width, + ETableColRenderFn render, void *render_data, + GCompareFunc compare, gboolean resizable) +{ + ETableCol *etc; + + g_return_if_fail (id != NULL); + g_return_if_fail (width >= 0); + g_return_if_fail (min_width >= 0); + g_return_if_fail (width >= min_width); + g_return_if_fail (render != NULL); + g_return_if_fail (compare != NULL); + + etc = g_new (ETableCol, 1); + + etc->id = g_strdup (id); + etc->width = width; + etc->min_width = min_width; + etc->render = render; + etc->render_data = render_data; + etc->compare = compare; + + etc->selected = 0; + etc->resizeable = 0; + + return etc; +} + + + diff --git a/widgets/e-table-col.h b/widgets/e-table-col.h new file mode 100644 index 0000000000..215df07797 --- /dev/null +++ b/widgets/e-table-col.h @@ -0,0 +1,33 @@ +#ifndef _E_TABLE_COL_H_ +#define _E_TABLE_COL_H_ + +typedef struct _ETableCol ETableCol; + +/* + * Rendering function for the column header + */ +typedef struct ERenderContext ERenderContext; + +typedef void (*ETableColRenderFn)(ERenderContext *ctxt); + +/* + * Information about a single column + */ +struct _ETableCol { + char *id; + short width; + short min_width; + short x; + ETableColRenderFn render; + GCompareFunc compare; + void *render_data; + unsigned int selected:1; + unsigned int resizeable:1; +}; + +ETableCol *e_table_col_new (const char *id, int width, int min_width, + ETableColRenderFn render, void *render_data, + GCompareFunc compare, gboolean resizable); + + +#endif /* _E_TABLE_COL_H_ */ diff --git a/widgets/e-table-header-item.c b/widgets/e-table-header-item.c index 796a2e493b..effdbb3f0b 100644 --- a/widgets/e-table-header-item.c +++ b/widgets/e-table-header-item.c @@ -136,9 +136,7 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x1, int y1, int wid GTK_STATE_NORMAL, GTK_SHADOW_OUT, x , -y1, col_width, ETHI_HEIGHT); - if (ecol->render != NULL) - (*ecol->render)(ecol, item, drawable, x1, y1, width, height, ecol->render_data); - else { + { GdkRectangle clip; GdkFont *font = GTK_WIDGET (canvas)->style->font; @@ -193,7 +191,7 @@ ethi_class_init (GtkObjectClass *object_class) item_class->point = ethi_point; item_class->event = ethi_event; - gtk_object_add_arg_type ("ETableHeaderItem::ETableColumn", GTK_TYPE_POINTER, + gtk_object_add_arg_type ("ETableHeaderItem::ETableHeader", GTK_TYPE_POINTER, GTK_ARG_WRITABLE, ARG_TABLE_HEADER); } @@ -207,7 +205,7 @@ ethi_init (GnomeCanvasItem *item) } GtkType -e_table_header_view_get_type (void) +e_table_header_item_get_type (void) { static GtkType type = 0; @@ -229,5 +227,3 @@ e_table_header_view_get_type (void) return type; } - - diff --git a/widgets/e-table-header.c b/widgets/e-table-header.c index fb493c32a0..24ae2fdd23 100644 --- a/widgets/e-table-header.c +++ b/widgets/e-table-header.c @@ -104,21 +104,36 @@ eth_do_insert (ETableHeader *eth, int pos, ETableCol *val) eth->columns [pos] = val; } +static void +eth_update_offsets (ETableHeader *eth) +{ + int i; + int x = 0; + + for (i = 0; i < eth->col_count; i++){ + ETableCol *etc = eth->columns [i]; + + etc->x = x; + x += etc->width; + } +} + void e_table_header_add_column (ETableHeader *eth, ETableCol *tc, int pos) { ETableCol **new_ptr; g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_COLUMN (eth)); + g_return_if_fail (E_IS_TABLE_HEADER (eth)); g_return_if_fail (tc != NULL); - g_return_if_fail (pos >= 0 && pos < eth->col_count); + g_return_if_fail (pos >= 0 && pos <= eth->col_count); if (pos == -1) pos = eth->col_count; eth->columns = g_realloc (eth->columns, sizeof (ETableCol *) * (eth->col_count + 1)); eth_do_insert (eth, pos, tc); eth->col_count++; + eth_update_offsets (eth); gtk_signal_emit (GTK_OBJECT (eth), eth_signals [STRUCTURE_CHANGE]); } @@ -127,7 +142,7 @@ ETableCol * e_table_header_get_column (ETableHeader *eth, int column) { g_return_val_if_fail (eth != NULL, NULL); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), NULL); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), NULL); if (column < 0) return NULL; @@ -142,7 +157,7 @@ int e_table_header_count (ETableHeader *eth) { g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), 0); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); return eth->col_count; } @@ -153,7 +168,7 @@ e_table_header_index (ETableHeader *eth, const char *identifier) int i; g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), 0); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); g_return_val_if_fail (identifier != NULL, 0); for (i = 0; i < eth->col_count; i++){ @@ -172,7 +187,7 @@ e_table_header_get_index_at (ETableHeader *eth, int x_offset) int i, total; g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), 0); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); total = 0; for (i = 0; i < eth->col_count; i++){ @@ -192,7 +207,7 @@ e_table_header_get_columns (ETableHeader *eth) int i; g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), 0); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); ret = g_new (ETableCol *, eth->col_count + 1); memcpy (ret, eth->columns, sizeof (ETableCol *) * eth->col_count); @@ -205,7 +220,7 @@ gboolean e_table_header_selection_ok (ETableHeader *eth) { g_return_val_if_fail (eth != NULL, FALSE); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), FALSE); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), FALSE); return eth->selectable; } @@ -217,7 +232,7 @@ ve_table_header_get_selected (ETableHeader *eth) int selected = 0; g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), 0); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); for (i = 0; i < eth->col_count; i++){ if (eth->columns [i]->selected) @@ -233,7 +248,7 @@ e_table_header_total_width (ETableHeader *eth) int total, i; g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), 0); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); total = 0; for (i = 0; i < eth->col_count; i++) @@ -256,7 +271,7 @@ e_table_header_move (ETableHeader *eth, int source_index, int target_index) ETableCol *old; g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_COLUMN (eth)); + g_return_if_fail (E_IS_TABLE_HEADER (eth)); g_return_if_fail (source_index >= 0); g_return_if_fail (target_index >= 0); g_return_if_fail (source_index < eth->col_count); @@ -265,6 +280,8 @@ e_table_header_move (ETableHeader *eth, int source_index, int target_index) old = eth->columns [source_index]; eth_do_remove (eth, source_index); eth_do_insert (eth, target_index, old); + eth_update_offsets (eth); + gtk_signal_emit (GTK_OBJECT (eth), eth_signals [STRUCTURE_CHANGE]); } @@ -272,7 +289,7 @@ void e_table_header_remove (ETableHeader *eth, int idx) { g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_COLUMN (eth)); + g_return_if_fail (E_IS_TABLE_HEADER (eth)); g_return_if_fail (idx >= 0); g_return_if_fail (idx < eth->col_count); @@ -289,7 +306,7 @@ void e_table_header_set_size (ETableHeader *eth, int idx, int size) { g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_COLUMN (eth)); + g_return_if_fail (E_IS_TABLE_HEADER (eth)); g_return_if_fail (idx >= 0); g_return_if_fail (idx < eth->col_count); g_return_if_fail (size > 0); @@ -297,3 +314,4 @@ e_table_header_set_size (ETableHeader *eth, int idx, int size) eth->columns [idx]->width = size; gtk_signal_emit (GTK_OBJECT (eth), eth_signals [DIMENSION_CHANGE], idx); } + diff --git a/widgets/e-table-header.h b/widgets/e-table-header.h index d8e04ea8fd..89eced0158 100644 --- a/widgets/e-table-header.h +++ b/widgets/e-table-header.h @@ -6,27 +6,6 @@ #include "e-table-col.h" typedef struct _ETableHeader ETableHeader; -typedef struct _ETableCol ETableCol; - -/* - * Rendering function for the column header - */ -typedef void (*ETableColRenderFn)( - ETableCol *etc, void *gnome_canvas_item, void *drawable, - int x, int y, int w, int h, void *data); - -/* - * Information about a single column - */ -struct _ETableCol { - const char *id; - int width; - ETableColRenderFn render; - void *render_data; - unsigned int selected:1; - int resizeable:1; - int min_size; -}; #define E_TABLE_HEADER_TYPE (e_table_header_get_type ()) #define E_TABLE_HEADER(o) (GTK_CHECK_CAST ((o), E_TABLE_HEADER_TYPE, ETableHeader)) @@ -48,34 +27,35 @@ struct _ETableHeader { typedef struct { GtkObjectClass parent_class; - void (*structure_change) (ETableHeader *etc); - void (*dimension_change) (ETableHeader *etc, int col); + void (*structure_change) (ETableHeader *eth); + void (*dimension_change) (ETableHeader *eth, int col); } ETableHeaderClass; GtkType e_table_header_get_type (void); ETableHeader *e_table_header_new (void); -void e_table_header_add_column (ETableHeader *etc, +void e_table_header_add_column (ETableHeader *eth, ETableCol *tc, int pos); -ETableCol * e_table_header_get_column (ETableHeader *etc, +ETableCol * e_table_header_get_column (ETableHeader *eth, int column); -int e_table_header_count (ETableHeader *etc); -int e_table_header_index (ETableHeader *etc, +int e_table_header_count (ETableHeader *eth); +int e_table_header_index (ETableHeader *eth, const char *identifier); -int e_table_header_get_index_at (ETableHeader *etc, +int e_table_header_get_index_at (ETableHeader *eth, int x_offset); -ETableCol **e_table_header_get_columns (ETableHeader *etc); -gboolean e_table_header_selection_ok (ETableHeader *etc); -int e_table_header_get_selected (ETableHeader *etc); -int e_table_header_total_width (ETableHeader *etc); -void e_table_header_move (ETableHeader *etc, +ETableCol **e_table_header_get_columns (ETableHeader *eth); +gboolean e_table_header_selection_ok (ETableHeader *eth); +int e_table_header_get_selected (ETableHeader *eth); +int e_table_header_total_width (ETableHeader *eth); +void e_table_header_move (ETableHeader *eth, int source_index, int target_index); -void e_table_header_remove (ETableHeader *etc, int idx); -void e_table_header_set_size (ETableHeader *etc, int idx, int size); -void e_table_header_set_selection (ETableHeader *etc, +void e_table_header_remove (ETableHeader *eth, int idx); +void e_table_header_set_size (ETableHeader *eth, int idx, int size); +void e_table_header_set_selection (ETableHeader *eth, gboolean allow_selection); -GList *e_table_header_get_selected_indexes(ETableHeader *etc); +GList *e_table_header_get_selected_indexes(ETableHeader *eth); + #endif /* _E_TABLE_HEADER_H_ */ diff --git a/widgets/e-table-model.c b/widgets/e-table-model.c index 868664cf08..646aee77bd 100644 --- a/widgets/e-table-model.c +++ b/widgets/e-table-model.c @@ -40,7 +40,7 @@ e_table_model_value_at (ETableModel *etable, int col, int row) void e_table_model_set_value_at (ETableModel *etable, int col, int row, void *data) { - return ETM_CLASS (etable)->set_value_at (etable, col, row); + return ETM_CLASS (etable)->set_value_at (etable, col, row, data); } gboolean diff --git a/widgets/e-table-model.h b/widgets/e-table-model.h new file mode 100644 index 0000000000..e32d3d55ce --- /dev/null +++ b/widgets/e-table-model.h @@ -0,0 +1,46 @@ +#ifndef _E_TABLE_MODEL_H_ +#define _E_TABLE_MODEL_H_ + +#include + +#define E_TABLE_MODEL_TYPE (e_table_model_get_type ()) +#define E_TABLE_MODEL(o) (GTK_CHECK_CAST ((o), E_TABLE_MODEL_TYPE, ETableModel)) +#define E_TABLE_MODEL_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_MODEL_TYPE, ETableModelClass)) +#define E_IS_TABLE_MODEL(o) (GTK_CHECK_TYPE ((o), E_TABLE_MODEL_TYPE)) +#define E_IS_TABLE_MODEL_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_MODEL_TYPE)) + +typedef struct { + GtkObject base; +} ETableModel; + +typedef struct { + GtkObjectClass parent_class; + + /* + * Virtual methods + */ + int (*column_count) (ETableModel *etm); + const char *(*column_name) (ETableModel *etm, int col); + int (*row_count) (ETableModel *etm); + void *(*value_at) (ETableModel *etm, int col, int row); + void (*set_value_at) (ETableModel *etm, int col, int row, void *value); + gboolean (*is_cell_editable) (ETableModel *etm, int col, int row); + int (*row_height) (ETableModel *etm, int row); +} ETableModelClass; + +GtkType e_table_model_get_type (void); + +int e_table_model_column_count (ETableModel *e_table_model); +const char *e_table_model_column_name (ETableModel *e_table_model, int col); +int e_table_model_row_count (ETableModel *e_table_model); +int e_table_model_row_height (ETableModel *e_table_model, int row); +int e_table_model_height (ETableModel *e_table_model); +void *e_table_model_value_at (ETableModel *e_table_model, int col, int row); +void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, void *data); +gboolean e_table_model_is_cell_editable (ETableModel *e_table_model, int col, int row); + +/* + * Routines for emitting signals on the e_table + */ + +#endif /* _E_TABLE_MODEL_H_ */ diff --git a/widgets/e-table-render.c b/widgets/e-table-render.c new file mode 100644 index 0000000000..8e9f1bf285 --- /dev/null +++ b/widgets/e-table-render.c @@ -0,0 +1,20 @@ +/* + * E-table-render.c: Various renderers + * + * Author: + * Miguel de Icaza (miguel@gnu.org) + * + * Copyright 1999, International GNOME Support. + */ +#include +#include "e-table-header.h" +#include "e-table-header-item.h" +#include "e-table-col.h" +#include "e-table-render.h" + +void +e_table_render_string (ERenderContext *ctxt) +{ + printf ("Rendering string: %s\n", ctxt->render_data); +} + diff --git a/widgets/e-table-render.h b/widgets/e-table-render.h new file mode 100644 index 0000000000..ebc65968f0 --- /dev/null +++ b/widgets/e-table-render.h @@ -0,0 +1,21 @@ +#ifndef E_TABLE_RENDER_H +#define E_TABLE_RENDER_H + +#include + +struct ERenderContext { + ETableCol *etc; + int row; + int base_x, base_y; + GnomeCanvasItem *gnome_canvas_item; + GdkDrawable *drawable; + int drawable_width; + int drawable_height; + void *render_data; + void *closure; +}; + +void e_table_render_string (ERenderContext *ctxt); + + +#endif diff --git a/widgets/e-table-simple.c b/widgets/e-table-simple.c index e52a9498f8..6532d6e542 100644 --- a/widgets/e-table-simple.c +++ b/widgets/e-table-simple.c @@ -45,11 +45,11 @@ simple_value_at (ETableModel *etm, int col, int row) } static void -simple_set_value_at (ETableModel *etm, int col, int row) +simple_set_value_at (ETableModel *etm, int col, int row, void *val) { ETableSimple *simple = (ETableSimple *)etm; - simple->set_value_at (etm, col, row, simple->data); + simple->set_value_at (etm, col, row, val, simple->data); } static gboolean diff --git a/widgets/e-table-simple.h b/widgets/e-table-simple.h index fc69ce19d0..d47a1cbe0b 100644 --- a/widgets/e-table-simple.h +++ b/widgets/e-table-simple.h @@ -7,7 +7,7 @@ typedef int (*ETableSimpleColumnCountFn) (ETableModel *etm, void *dat typedef const char *(*ETableSimpleColumnNameFn) (ETableModel *etm, int col, void *data); typedef int (*ETableSimpleRowCountFn) (ETableModel *etm, void *data); typedef void *(*ETableSimpleValueAtFn) (ETableModel *etm, int col, int row, void *data); -typedef void (*ETableSimpleSetValueAtFn) (ETableModel *etm, int col, int row, void *data); +typedef void (*ETableSimpleSetValueAtFn) (ETableModel *etm, int col, int row, void *val, void *data); typedef gboolean (*ETableSimpleIsCellEditableFn) (ETableModel *etm, int col, int row, void *data); typedef int (*ETableSimpleRowHeightFn) (ETableModel *etm, int row, void *data); @@ -25,7 +25,7 @@ typedef struct { } ETableSimple; typedef struct { - ETableModel parent_class; + ETableModelClass parent_class; } ETableSimpleClass; GtkType e_table_simple_get_type (void); diff --git a/widgets/e-table/ChangeLog b/widgets/e-table/ChangeLog index d0c7b288e4..48c797c007 100644 --- a/widgets/e-table/ChangeLog +++ b/widgets/e-table/ChangeLog @@ -1,3 +1,17 @@ +1999-11-11 Miguel de Icaza + + * e-table-header.c (e_table_header_add_column): Update offsets. + (eth_update_offsets): New routine. + + * e-table-col.h, e-table-col.c: New files. + + * e-table-header.h (e_table_header_get_selected_indexes): + Pretify. + + * table-test.c (main): New file; used for testing ETable package. + + * e-table-simple.h: Fix type. + 1999-11-12 Ettore Perazzoli * e-msg-composer-address-dialog.glade: Cosmetical changes. diff --git a/widgets/e-table/Makefile.am b/widgets/e-table/Makefile.am index 875e61f6b1..300f6e3017 100644 --- a/widgets/e-table/Makefile.am +++ b/widgets/e-table/Makefile.am @@ -28,9 +28,9 @@ libevolutionwidgets_la_SOURCES = \ e-msg-composer-hdrs.c \ e-msg-composer-hdrs.h \ e-msg-composer.c \ - e-msg-composer.h - -EXTRA_DIST = \ + e-msg-composer.h \ + e-table-col.c \ + e-table-col.h \ e-table-group.c \ e-table-group.h \ e-table-header.c \ @@ -39,6 +39,20 @@ EXTRA_DIST = \ e-table-header-item.h \ e-table-model.c \ e-table-model.h \ + e-table-render.c \ + e-table-render.h \ e-table-simple.c \ e-table-simple.h +noinst_PROGRAMS = \ + table-test + +table_test_SOURCES = \ + table-test.c + +table_test_LDADD = \ + $(EXTRA_GNOME_LIBS) \ + libevolutionwidgets.a + +EXTRA_DIST = \ + sample.table diff --git a/widgets/e-table/e-table-col.c b/widgets/e-table/e-table-col.c new file mode 100644 index 0000000000..8a2bfe90cf --- /dev/null +++ b/widgets/e-table/e-table-col.c @@ -0,0 +1,44 @@ +/* + * E-table-col.c: ETableCol implementation + * + * Author: + * Miguel de Icaza (miguel@gnu.org) + * + * (C) 1999 International GNOME Support + */ +#include +#include +#include +#include "e-table-col.h" + +ETableCol * +e_table_col_new (const char *id, int width, int min_width, + ETableColRenderFn render, void *render_data, + GCompareFunc compare, gboolean resizable) +{ + ETableCol *etc; + + g_return_if_fail (id != NULL); + g_return_if_fail (width >= 0); + g_return_if_fail (min_width >= 0); + g_return_if_fail (width >= min_width); + g_return_if_fail (render != NULL); + g_return_if_fail (compare != NULL); + + etc = g_new (ETableCol, 1); + + etc->id = g_strdup (id); + etc->width = width; + etc->min_width = min_width; + etc->render = render; + etc->render_data = render_data; + etc->compare = compare; + + etc->selected = 0; + etc->resizeable = 0; + + return etc; +} + + + diff --git a/widgets/e-table/e-table-col.h b/widgets/e-table/e-table-col.h new file mode 100644 index 0000000000..215df07797 --- /dev/null +++ b/widgets/e-table/e-table-col.h @@ -0,0 +1,33 @@ +#ifndef _E_TABLE_COL_H_ +#define _E_TABLE_COL_H_ + +typedef struct _ETableCol ETableCol; + +/* + * Rendering function for the column header + */ +typedef struct ERenderContext ERenderContext; + +typedef void (*ETableColRenderFn)(ERenderContext *ctxt); + +/* + * Information about a single column + */ +struct _ETableCol { + char *id; + short width; + short min_width; + short x; + ETableColRenderFn render; + GCompareFunc compare; + void *render_data; + unsigned int selected:1; + unsigned int resizeable:1; +}; + +ETableCol *e_table_col_new (const char *id, int width, int min_width, + ETableColRenderFn render, void *render_data, + GCompareFunc compare, gboolean resizable); + + +#endif /* _E_TABLE_COL_H_ */ diff --git a/widgets/e-table/e-table-header-item.c b/widgets/e-table/e-table-header-item.c index 796a2e493b..effdbb3f0b 100644 --- a/widgets/e-table/e-table-header-item.c +++ b/widgets/e-table/e-table-header-item.c @@ -136,9 +136,7 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x1, int y1, int wid GTK_STATE_NORMAL, GTK_SHADOW_OUT, x , -y1, col_width, ETHI_HEIGHT); - if (ecol->render != NULL) - (*ecol->render)(ecol, item, drawable, x1, y1, width, height, ecol->render_data); - else { + { GdkRectangle clip; GdkFont *font = GTK_WIDGET (canvas)->style->font; @@ -193,7 +191,7 @@ ethi_class_init (GtkObjectClass *object_class) item_class->point = ethi_point; item_class->event = ethi_event; - gtk_object_add_arg_type ("ETableHeaderItem::ETableColumn", GTK_TYPE_POINTER, + gtk_object_add_arg_type ("ETableHeaderItem::ETableHeader", GTK_TYPE_POINTER, GTK_ARG_WRITABLE, ARG_TABLE_HEADER); } @@ -207,7 +205,7 @@ ethi_init (GnomeCanvasItem *item) } GtkType -e_table_header_view_get_type (void) +e_table_header_item_get_type (void) { static GtkType type = 0; @@ -229,5 +227,3 @@ e_table_header_view_get_type (void) return type; } - - diff --git a/widgets/e-table/e-table-header.c b/widgets/e-table/e-table-header.c index fb493c32a0..24ae2fdd23 100644 --- a/widgets/e-table/e-table-header.c +++ b/widgets/e-table/e-table-header.c @@ -104,21 +104,36 @@ eth_do_insert (ETableHeader *eth, int pos, ETableCol *val) eth->columns [pos] = val; } +static void +eth_update_offsets (ETableHeader *eth) +{ + int i; + int x = 0; + + for (i = 0; i < eth->col_count; i++){ + ETableCol *etc = eth->columns [i]; + + etc->x = x; + x += etc->width; + } +} + void e_table_header_add_column (ETableHeader *eth, ETableCol *tc, int pos) { ETableCol **new_ptr; g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_COLUMN (eth)); + g_return_if_fail (E_IS_TABLE_HEADER (eth)); g_return_if_fail (tc != NULL); - g_return_if_fail (pos >= 0 && pos < eth->col_count); + g_return_if_fail (pos >= 0 && pos <= eth->col_count); if (pos == -1) pos = eth->col_count; eth->columns = g_realloc (eth->columns, sizeof (ETableCol *) * (eth->col_count + 1)); eth_do_insert (eth, pos, tc); eth->col_count++; + eth_update_offsets (eth); gtk_signal_emit (GTK_OBJECT (eth), eth_signals [STRUCTURE_CHANGE]); } @@ -127,7 +142,7 @@ ETableCol * e_table_header_get_column (ETableHeader *eth, int column) { g_return_val_if_fail (eth != NULL, NULL); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), NULL); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), NULL); if (column < 0) return NULL; @@ -142,7 +157,7 @@ int e_table_header_count (ETableHeader *eth) { g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), 0); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); return eth->col_count; } @@ -153,7 +168,7 @@ e_table_header_index (ETableHeader *eth, const char *identifier) int i; g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), 0); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); g_return_val_if_fail (identifier != NULL, 0); for (i = 0; i < eth->col_count; i++){ @@ -172,7 +187,7 @@ e_table_header_get_index_at (ETableHeader *eth, int x_offset) int i, total; g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), 0); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); total = 0; for (i = 0; i < eth->col_count; i++){ @@ -192,7 +207,7 @@ e_table_header_get_columns (ETableHeader *eth) int i; g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), 0); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); ret = g_new (ETableCol *, eth->col_count + 1); memcpy (ret, eth->columns, sizeof (ETableCol *) * eth->col_count); @@ -205,7 +220,7 @@ gboolean e_table_header_selection_ok (ETableHeader *eth) { g_return_val_if_fail (eth != NULL, FALSE); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), FALSE); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), FALSE); return eth->selectable; } @@ -217,7 +232,7 @@ ve_table_header_get_selected (ETableHeader *eth) int selected = 0; g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), 0); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); for (i = 0; i < eth->col_count; i++){ if (eth->columns [i]->selected) @@ -233,7 +248,7 @@ e_table_header_total_width (ETableHeader *eth) int total, i; g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), 0); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); total = 0; for (i = 0; i < eth->col_count; i++) @@ -256,7 +271,7 @@ e_table_header_move (ETableHeader *eth, int source_index, int target_index) ETableCol *old; g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_COLUMN (eth)); + g_return_if_fail (E_IS_TABLE_HEADER (eth)); g_return_if_fail (source_index >= 0); g_return_if_fail (target_index >= 0); g_return_if_fail (source_index < eth->col_count); @@ -265,6 +280,8 @@ e_table_header_move (ETableHeader *eth, int source_index, int target_index) old = eth->columns [source_index]; eth_do_remove (eth, source_index); eth_do_insert (eth, target_index, old); + eth_update_offsets (eth); + gtk_signal_emit (GTK_OBJECT (eth), eth_signals [STRUCTURE_CHANGE]); } @@ -272,7 +289,7 @@ void e_table_header_remove (ETableHeader *eth, int idx) { g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_COLUMN (eth)); + g_return_if_fail (E_IS_TABLE_HEADER (eth)); g_return_if_fail (idx >= 0); g_return_if_fail (idx < eth->col_count); @@ -289,7 +306,7 @@ void e_table_header_set_size (ETableHeader *eth, int idx, int size) { g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_COLUMN (eth)); + g_return_if_fail (E_IS_TABLE_HEADER (eth)); g_return_if_fail (idx >= 0); g_return_if_fail (idx < eth->col_count); g_return_if_fail (size > 0); @@ -297,3 +314,4 @@ e_table_header_set_size (ETableHeader *eth, int idx, int size) eth->columns [idx]->width = size; gtk_signal_emit (GTK_OBJECT (eth), eth_signals [DIMENSION_CHANGE], idx); } + diff --git a/widgets/e-table/e-table-header.h b/widgets/e-table/e-table-header.h index d8e04ea8fd..89eced0158 100644 --- a/widgets/e-table/e-table-header.h +++ b/widgets/e-table/e-table-header.h @@ -6,27 +6,6 @@ #include "e-table-col.h" typedef struct _ETableHeader ETableHeader; -typedef struct _ETableCol ETableCol; - -/* - * Rendering function for the column header - */ -typedef void (*ETableColRenderFn)( - ETableCol *etc, void *gnome_canvas_item, void *drawable, - int x, int y, int w, int h, void *data); - -/* - * Information about a single column - */ -struct _ETableCol { - const char *id; - int width; - ETableColRenderFn render; - void *render_data; - unsigned int selected:1; - int resizeable:1; - int min_size; -}; #define E_TABLE_HEADER_TYPE (e_table_header_get_type ()) #define E_TABLE_HEADER(o) (GTK_CHECK_CAST ((o), E_TABLE_HEADER_TYPE, ETableHeader)) @@ -48,34 +27,35 @@ struct _ETableHeader { typedef struct { GtkObjectClass parent_class; - void (*structure_change) (ETableHeader *etc); - void (*dimension_change) (ETableHeader *etc, int col); + void (*structure_change) (ETableHeader *eth); + void (*dimension_change) (ETableHeader *eth, int col); } ETableHeaderClass; GtkType e_table_header_get_type (void); ETableHeader *e_table_header_new (void); -void e_table_header_add_column (ETableHeader *etc, +void e_table_header_add_column (ETableHeader *eth, ETableCol *tc, int pos); -ETableCol * e_table_header_get_column (ETableHeader *etc, +ETableCol * e_table_header_get_column (ETableHeader *eth, int column); -int e_table_header_count (ETableHeader *etc); -int e_table_header_index (ETableHeader *etc, +int e_table_header_count (ETableHeader *eth); +int e_table_header_index (ETableHeader *eth, const char *identifier); -int e_table_header_get_index_at (ETableHeader *etc, +int e_table_header_get_index_at (ETableHeader *eth, int x_offset); -ETableCol **e_table_header_get_columns (ETableHeader *etc); -gboolean e_table_header_selection_ok (ETableHeader *etc); -int e_table_header_get_selected (ETableHeader *etc); -int e_table_header_total_width (ETableHeader *etc); -void e_table_header_move (ETableHeader *etc, +ETableCol **e_table_header_get_columns (ETableHeader *eth); +gboolean e_table_header_selection_ok (ETableHeader *eth); +int e_table_header_get_selected (ETableHeader *eth); +int e_table_header_total_width (ETableHeader *eth); +void e_table_header_move (ETableHeader *eth, int source_index, int target_index); -void e_table_header_remove (ETableHeader *etc, int idx); -void e_table_header_set_size (ETableHeader *etc, int idx, int size); -void e_table_header_set_selection (ETableHeader *etc, +void e_table_header_remove (ETableHeader *eth, int idx); +void e_table_header_set_size (ETableHeader *eth, int idx, int size); +void e_table_header_set_selection (ETableHeader *eth, gboolean allow_selection); -GList *e_table_header_get_selected_indexes(ETableHeader *etc); +GList *e_table_header_get_selected_indexes(ETableHeader *eth); + #endif /* _E_TABLE_HEADER_H_ */ diff --git a/widgets/e-table/e-table-model.c b/widgets/e-table/e-table-model.c index 868664cf08..646aee77bd 100644 --- a/widgets/e-table/e-table-model.c +++ b/widgets/e-table/e-table-model.c @@ -40,7 +40,7 @@ e_table_model_value_at (ETableModel *etable, int col, int row) void e_table_model_set_value_at (ETableModel *etable, int col, int row, void *data) { - return ETM_CLASS (etable)->set_value_at (etable, col, row); + return ETM_CLASS (etable)->set_value_at (etable, col, row, data); } gboolean diff --git a/widgets/e-table/e-table-model.h b/widgets/e-table/e-table-model.h new file mode 100644 index 0000000000..e32d3d55ce --- /dev/null +++ b/widgets/e-table/e-table-model.h @@ -0,0 +1,46 @@ +#ifndef _E_TABLE_MODEL_H_ +#define _E_TABLE_MODEL_H_ + +#include + +#define E_TABLE_MODEL_TYPE (e_table_model_get_type ()) +#define E_TABLE_MODEL(o) (GTK_CHECK_CAST ((o), E_TABLE_MODEL_TYPE, ETableModel)) +#define E_TABLE_MODEL_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_MODEL_TYPE, ETableModelClass)) +#define E_IS_TABLE_MODEL(o) (GTK_CHECK_TYPE ((o), E_TABLE_MODEL_TYPE)) +#define E_IS_TABLE_MODEL_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_MODEL_TYPE)) + +typedef struct { + GtkObject base; +} ETableModel; + +typedef struct { + GtkObjectClass parent_class; + + /* + * Virtual methods + */ + int (*column_count) (ETableModel *etm); + const char *(*column_name) (ETableModel *etm, int col); + int (*row_count) (ETableModel *etm); + void *(*value_at) (ETableModel *etm, int col, int row); + void (*set_value_at) (ETableModel *etm, int col, int row, void *value); + gboolean (*is_cell_editable) (ETableModel *etm, int col, int row); + int (*row_height) (ETableModel *etm, int row); +} ETableModelClass; + +GtkType e_table_model_get_type (void); + +int e_table_model_column_count (ETableModel *e_table_model); +const char *e_table_model_column_name (ETableModel *e_table_model, int col); +int e_table_model_row_count (ETableModel *e_table_model); +int e_table_model_row_height (ETableModel *e_table_model, int row); +int e_table_model_height (ETableModel *e_table_model); +void *e_table_model_value_at (ETableModel *e_table_model, int col, int row); +void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, void *data); +gboolean e_table_model_is_cell_editable (ETableModel *e_table_model, int col, int row); + +/* + * Routines for emitting signals on the e_table + */ + +#endif /* _E_TABLE_MODEL_H_ */ diff --git a/widgets/e-table/e-table-render.c b/widgets/e-table/e-table-render.c new file mode 100644 index 0000000000..8e9f1bf285 --- /dev/null +++ b/widgets/e-table/e-table-render.c @@ -0,0 +1,20 @@ +/* + * E-table-render.c: Various renderers + * + * Author: + * Miguel de Icaza (miguel@gnu.org) + * + * Copyright 1999, International GNOME Support. + */ +#include +#include "e-table-header.h" +#include "e-table-header-item.h" +#include "e-table-col.h" +#include "e-table-render.h" + +void +e_table_render_string (ERenderContext *ctxt) +{ + printf ("Rendering string: %s\n", ctxt->render_data); +} + diff --git a/widgets/e-table/e-table-render.h b/widgets/e-table/e-table-render.h new file mode 100644 index 0000000000..ebc65968f0 --- /dev/null +++ b/widgets/e-table/e-table-render.h @@ -0,0 +1,21 @@ +#ifndef E_TABLE_RENDER_H +#define E_TABLE_RENDER_H + +#include + +struct ERenderContext { + ETableCol *etc; + int row; + int base_x, base_y; + GnomeCanvasItem *gnome_canvas_item; + GdkDrawable *drawable; + int drawable_width; + int drawable_height; + void *render_data; + void *closure; +}; + +void e_table_render_string (ERenderContext *ctxt); + + +#endif diff --git a/widgets/e-table/e-table-simple.c b/widgets/e-table/e-table-simple.c index e52a9498f8..6532d6e542 100644 --- a/widgets/e-table/e-table-simple.c +++ b/widgets/e-table/e-table-simple.c @@ -45,11 +45,11 @@ simple_value_at (ETableModel *etm, int col, int row) } static void -simple_set_value_at (ETableModel *etm, int col, int row) +simple_set_value_at (ETableModel *etm, int col, int row, void *val) { ETableSimple *simple = (ETableSimple *)etm; - simple->set_value_at (etm, col, row, simple->data); + simple->set_value_at (etm, col, row, val, simple->data); } static gboolean diff --git a/widgets/e-table/e-table-simple.h b/widgets/e-table/e-table-simple.h index fc69ce19d0..d47a1cbe0b 100644 --- a/widgets/e-table/e-table-simple.h +++ b/widgets/e-table/e-table-simple.h @@ -7,7 +7,7 @@ typedef int (*ETableSimpleColumnCountFn) (ETableModel *etm, void *dat typedef const char *(*ETableSimpleColumnNameFn) (ETableModel *etm, int col, void *data); typedef int (*ETableSimpleRowCountFn) (ETableModel *etm, void *data); typedef void *(*ETableSimpleValueAtFn) (ETableModel *etm, int col, int row, void *data); -typedef void (*ETableSimpleSetValueAtFn) (ETableModel *etm, int col, int row, void *data); +typedef void (*ETableSimpleSetValueAtFn) (ETableModel *etm, int col, int row, void *val, void *data); typedef gboolean (*ETableSimpleIsCellEditableFn) (ETableModel *etm, int col, int row, void *data); typedef int (*ETableSimpleRowHeightFn) (ETableModel *etm, int row, void *data); @@ -25,7 +25,7 @@ typedef struct { } ETableSimple; typedef struct { - ETableModel parent_class; + ETableModelClass parent_class; } ETableSimpleClass; GtkType e_table_simple_get_type (void); diff --git a/widgets/e-table/sample.table b/widgets/e-table/sample.table new file mode 100644 index 0000000000..2cb09d7f1f --- /dev/null +++ b/widgets/e-table/sample.table @@ -0,0 +1,8 @@ +Col1 Col2 Address Title Dorks +c1.a c2.a a.a tit-1 DorkA +c1.b c2.b a.b tit-2 DDork +c1.c c2.c a.c tit-1 DorkB +c1.d c2.d a.d tit-2 ADork +c1.e c2.e a.e tit-1 DorkC +c1.f c2.f a.f tit-2 UDork + diff --git a/widgets/e-table/table-test.c b/widgets/e-table/table-test.c new file mode 100644 index 0000000000..27b1df7201 --- /dev/null +++ b/widgets/e-table/table-test.c @@ -0,0 +1,216 @@ +/* + * Test code for the ETable package + * + * Author: + * Miguel de Icaza (miguel@gnu.org) + */ +#include +#include +#include +#include +#include "e-table-simple.h" +#include "e-table-header.h" +#include "e-table-header-item.h" +#include "e-table-render.h" + +char buffer [1024]; +char **column_labels; +char ***table_data; +int cols = 0; +int lines = 0; +int lines_alloc = 0; + +static void +parse_headers () +{ + char *p, *s; + int in_value = 0, i; + + fgets (buffer, sizeof (buffer)-1, stdin); + + for (p = buffer; *p; p++){ + if (*p == ' ' || *p == '\t'){ + if (in_value){ + cols++; + in_value = 0; + } + } else + in_value = 1; + } + if (in_value) + cols++; + + if (!cols){ + fprintf (stderr, "No columns in first row\n"); + exit (1); + } + + column_labels = g_new0 (char *, cols); + + p = buffer; + for (i = 0; (s = strtok (p, " \t")) != NULL; i++){ + column_labels [i] = g_strdup (s); + p = NULL; + } + + printf ("%d headers:\n", cols); + for (i = 0; i < cols; i++){ + printf ("header %d: %s\n", i, column_labels [i]); + } +} + +static char ** +load_line (char *buffer, int cols) +{ + char **line = g_new0 (char *, cols); + char *p; + int i; + + for (i = 0; i < cols; i++){ + p = strtok (buffer, " \t\n"); + if (p == NULL){ + for (; i < cols; i++) + line [i] = g_strdup (""); + return line; + } else + line [i] = g_strdup (p); + buffer = NULL; + } + return line; +} + +static void +append_line (char **line) +{ + if (lines <= lines_alloc){ + lines_alloc = lines + 50; + table_data = g_renew (char **, table_data, lines_alloc); + } + table_data [lines] = line; + lines++; +} + +static void +load_data () +{ + int i; + + parse_headers (); + + while (fgets (buffer, sizeof (buffer)-1, stdin) != NULL){ + char **line; + + if (buffer [0] == '\n') + continue; + line = load_line (buffer, cols); + append_line (line); + } + + for (i = 0; i < lines; i++){ + int j; + + printf ("Line %d: ", i); + for (j = 0; j < cols; j++) + printf ("[%s] ", table_data [i][j]); + printf ("\n"); + } +} + +/* + * ETableSimple callbacks + */ +static int +col_count (ETableModel *etc, void *data) +{ + return cols; +} + +static const char * +col_name (ETableModel *etc, int col, void *data) +{ + g_assert (col < cols); + + return column_labels [col]; +} + +static int +row_count (ETableModel *etc, void *data) +{ + return lines; +} + +static void * +value_at (ETableModel *etc, int col, int row, void *data) +{ + g_assert (col < cols); + g_assert (row < lines); + + return (void *) &table_data [row][col]; +} + +static void +set_value_at (ETableModel *etc, int col, int row, void *val, void *data) +{ + g_assert (col < cols); + g_assert (row < lines); + + g_free (table_data [row][col]); + table_data [row][col] = g_strdup (val); + + printf ("Value at %d,%d set to %s\n", col, row, val); +} + +static gboolean +is_cell_editable (ETableModel *etc, int col, int row, void *data) +{ + return TRUE; +} + +int +main (int argc, char *argv []) +{ + GtkWidget *canvas, *window; + ETableModel *e_table_model; + ETableHeader *e_table_header; + int i; + + gnome_init ("TableTest", "TableTest", argc, argv); + + load_data (); + + /* + * Data model + */ + e_table_model = e_table_simple_new ( + col_count, col_name, row_count, value_at, + set_value_at, is_cell_editable, NULL); + + /* + * Header + */ + e_table_header = e_table_header_new (); + for (i = 0; i < cols; i++){ + ETableCol *ecol = e_table_col_new ( + column_labels [i], 20, 20, e_table_render_string, + NULL, g_str_equal, TRUE); + + e_table_header_add_column (e_table_header, ecol, i); + } + + /* + * Setup GUI + */ + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + canvas = gnome_canvas_new (); + + gtk_container_add (GTK_CONTAINER (window), canvas); + gtk_widget_show_all (window); + + gnome_canvas_item_new ( + gnome_canvas_root (GNOME_CANVAS (canvas)), + e_table_header_item_get_type (), + "ETableHeader", e_table_header, + NULL); + gtk_main (); + return 0; +} diff --git a/widgets/e-table/test.c b/widgets/e-table/test.c new file mode 100644 index 0000000000..0eece34467 --- /dev/null +++ b/widgets/e-table/test.c @@ -0,0 +1,17 @@ +#include +#include "e-table-simple.h" + +struct { + char *str; + int val; +} data [] = { + { "Miguel", 10 }, + { "Nat", 20 }, + { NULL, 0 }, +}; + +main () +{ + +} + diff --git a/widgets/sample.table b/widgets/sample.table new file mode 100644 index 0000000000..2cb09d7f1f --- /dev/null +++ b/widgets/sample.table @@ -0,0 +1,8 @@ +Col1 Col2 Address Title Dorks +c1.a c2.a a.a tit-1 DorkA +c1.b c2.b a.b tit-2 DDork +c1.c c2.c a.c tit-1 DorkB +c1.d c2.d a.d tit-2 ADork +c1.e c2.e a.e tit-1 DorkC +c1.f c2.f a.f tit-2 UDork + diff --git a/widgets/table-test.c b/widgets/table-test.c new file mode 100644 index 0000000000..27b1df7201 --- /dev/null +++ b/widgets/table-test.c @@ -0,0 +1,216 @@ +/* + * Test code for the ETable package + * + * Author: + * Miguel de Icaza (miguel@gnu.org) + */ +#include +#include +#include +#include +#include "e-table-simple.h" +#include "e-table-header.h" +#include "e-table-header-item.h" +#include "e-table-render.h" + +char buffer [1024]; +char **column_labels; +char ***table_data; +int cols = 0; +int lines = 0; +int lines_alloc = 0; + +static void +parse_headers () +{ + char *p, *s; + int in_value = 0, i; + + fgets (buffer, sizeof (buffer)-1, stdin); + + for (p = buffer; *p; p++){ + if (*p == ' ' || *p == '\t'){ + if (in_value){ + cols++; + in_value = 0; + } + } else + in_value = 1; + } + if (in_value) + cols++; + + if (!cols){ + fprintf (stderr, "No columns in first row\n"); + exit (1); + } + + column_labels = g_new0 (char *, cols); + + p = buffer; + for (i = 0; (s = strtok (p, " \t")) != NULL; i++){ + column_labels [i] = g_strdup (s); + p = NULL; + } + + printf ("%d headers:\n", cols); + for (i = 0; i < cols; i++){ + printf ("header %d: %s\n", i, column_labels [i]); + } +} + +static char ** +load_line (char *buffer, int cols) +{ + char **line = g_new0 (char *, cols); + char *p; + int i; + + for (i = 0; i < cols; i++){ + p = strtok (buffer, " \t\n"); + if (p == NULL){ + for (; i < cols; i++) + line [i] = g_strdup (""); + return line; + } else + line [i] = g_strdup (p); + buffer = NULL; + } + return line; +} + +static void +append_line (char **line) +{ + if (lines <= lines_alloc){ + lines_alloc = lines + 50; + table_data = g_renew (char **, table_data, lines_alloc); + } + table_data [lines] = line; + lines++; +} + +static void +load_data () +{ + int i; + + parse_headers (); + + while (fgets (buffer, sizeof (buffer)-1, stdin) != NULL){ + char **line; + + if (buffer [0] == '\n') + continue; + line = load_line (buffer, cols); + append_line (line); + } + + for (i = 0; i < lines; i++){ + int j; + + printf ("Line %d: ", i); + for (j = 0; j < cols; j++) + printf ("[%s] ", table_data [i][j]); + printf ("\n"); + } +} + +/* + * ETableSimple callbacks + */ +static int +col_count (ETableModel *etc, void *data) +{ + return cols; +} + +static const char * +col_name (ETableModel *etc, int col, void *data) +{ + g_assert (col < cols); + + return column_labels [col]; +} + +static int +row_count (ETableModel *etc, void *data) +{ + return lines; +} + +static void * +value_at (ETableModel *etc, int col, int row, void *data) +{ + g_assert (col < cols); + g_assert (row < lines); + + return (void *) &table_data [row][col]; +} + +static void +set_value_at (ETableModel *etc, int col, int row, void *val, void *data) +{ + g_assert (col < cols); + g_assert (row < lines); + + g_free (table_data [row][col]); + table_data [row][col] = g_strdup (val); + + printf ("Value at %d,%d set to %s\n", col, row, val); +} + +static gboolean +is_cell_editable (ETableModel *etc, int col, int row, void *data) +{ + return TRUE; +} + +int +main (int argc, char *argv []) +{ + GtkWidget *canvas, *window; + ETableModel *e_table_model; + ETableHeader *e_table_header; + int i; + + gnome_init ("TableTest", "TableTest", argc, argv); + + load_data (); + + /* + * Data model + */ + e_table_model = e_table_simple_new ( + col_count, col_name, row_count, value_at, + set_value_at, is_cell_editable, NULL); + + /* + * Header + */ + e_table_header = e_table_header_new (); + for (i = 0; i < cols; i++){ + ETableCol *ecol = e_table_col_new ( + column_labels [i], 20, 20, e_table_render_string, + NULL, g_str_equal, TRUE); + + e_table_header_add_column (e_table_header, ecol, i); + } + + /* + * Setup GUI + */ + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + canvas = gnome_canvas_new (); + + gtk_container_add (GTK_CONTAINER (window), canvas); + gtk_widget_show_all (window); + + gnome_canvas_item_new ( + gnome_canvas_root (GNOME_CANVAS (canvas)), + e_table_header_item_get_type (), + "ETableHeader", e_table_header, + NULL); + gtk_main (); + return 0; +} diff --git a/widgets/table/e-table-col.c b/widgets/table/e-table-col.c new file mode 100644 index 0000000000..8a2bfe90cf --- /dev/null +++ b/widgets/table/e-table-col.c @@ -0,0 +1,44 @@ +/* + * E-table-col.c: ETableCol implementation + * + * Author: + * Miguel de Icaza (miguel@gnu.org) + * + * (C) 1999 International GNOME Support + */ +#include +#include +#include +#include "e-table-col.h" + +ETableCol * +e_table_col_new (const char *id, int width, int min_width, + ETableColRenderFn render, void *render_data, + GCompareFunc compare, gboolean resizable) +{ + ETableCol *etc; + + g_return_if_fail (id != NULL); + g_return_if_fail (width >= 0); + g_return_if_fail (min_width >= 0); + g_return_if_fail (width >= min_width); + g_return_if_fail (render != NULL); + g_return_if_fail (compare != NULL); + + etc = g_new (ETableCol, 1); + + etc->id = g_strdup (id); + etc->width = width; + etc->min_width = min_width; + etc->render = render; + etc->render_data = render_data; + etc->compare = compare; + + etc->selected = 0; + etc->resizeable = 0; + + return etc; +} + + + diff --git a/widgets/table/e-table-col.h b/widgets/table/e-table-col.h new file mode 100644 index 0000000000..215df07797 --- /dev/null +++ b/widgets/table/e-table-col.h @@ -0,0 +1,33 @@ +#ifndef _E_TABLE_COL_H_ +#define _E_TABLE_COL_H_ + +typedef struct _ETableCol ETableCol; + +/* + * Rendering function for the column header + */ +typedef struct ERenderContext ERenderContext; + +typedef void (*ETableColRenderFn)(ERenderContext *ctxt); + +/* + * Information about a single column + */ +struct _ETableCol { + char *id; + short width; + short min_width; + short x; + ETableColRenderFn render; + GCompareFunc compare; + void *render_data; + unsigned int selected:1; + unsigned int resizeable:1; +}; + +ETableCol *e_table_col_new (const char *id, int width, int min_width, + ETableColRenderFn render, void *render_data, + GCompareFunc compare, gboolean resizable); + + +#endif /* _E_TABLE_COL_H_ */ diff --git a/widgets/table/e-table-header-item.c b/widgets/table/e-table-header-item.c index 796a2e493b..effdbb3f0b 100644 --- a/widgets/table/e-table-header-item.c +++ b/widgets/table/e-table-header-item.c @@ -136,9 +136,7 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x1, int y1, int wid GTK_STATE_NORMAL, GTK_SHADOW_OUT, x , -y1, col_width, ETHI_HEIGHT); - if (ecol->render != NULL) - (*ecol->render)(ecol, item, drawable, x1, y1, width, height, ecol->render_data); - else { + { GdkRectangle clip; GdkFont *font = GTK_WIDGET (canvas)->style->font; @@ -193,7 +191,7 @@ ethi_class_init (GtkObjectClass *object_class) item_class->point = ethi_point; item_class->event = ethi_event; - gtk_object_add_arg_type ("ETableHeaderItem::ETableColumn", GTK_TYPE_POINTER, + gtk_object_add_arg_type ("ETableHeaderItem::ETableHeader", GTK_TYPE_POINTER, GTK_ARG_WRITABLE, ARG_TABLE_HEADER); } @@ -207,7 +205,7 @@ ethi_init (GnomeCanvasItem *item) } GtkType -e_table_header_view_get_type (void) +e_table_header_item_get_type (void) { static GtkType type = 0; @@ -229,5 +227,3 @@ e_table_header_view_get_type (void) return type; } - - diff --git a/widgets/table/e-table-header.c b/widgets/table/e-table-header.c index fb493c32a0..24ae2fdd23 100644 --- a/widgets/table/e-table-header.c +++ b/widgets/table/e-table-header.c @@ -104,21 +104,36 @@ eth_do_insert (ETableHeader *eth, int pos, ETableCol *val) eth->columns [pos] = val; } +static void +eth_update_offsets (ETableHeader *eth) +{ + int i; + int x = 0; + + for (i = 0; i < eth->col_count; i++){ + ETableCol *etc = eth->columns [i]; + + etc->x = x; + x += etc->width; + } +} + void e_table_header_add_column (ETableHeader *eth, ETableCol *tc, int pos) { ETableCol **new_ptr; g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_COLUMN (eth)); + g_return_if_fail (E_IS_TABLE_HEADER (eth)); g_return_if_fail (tc != NULL); - g_return_if_fail (pos >= 0 && pos < eth->col_count); + g_return_if_fail (pos >= 0 && pos <= eth->col_count); if (pos == -1) pos = eth->col_count; eth->columns = g_realloc (eth->columns, sizeof (ETableCol *) * (eth->col_count + 1)); eth_do_insert (eth, pos, tc); eth->col_count++; + eth_update_offsets (eth); gtk_signal_emit (GTK_OBJECT (eth), eth_signals [STRUCTURE_CHANGE]); } @@ -127,7 +142,7 @@ ETableCol * e_table_header_get_column (ETableHeader *eth, int column) { g_return_val_if_fail (eth != NULL, NULL); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), NULL); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), NULL); if (column < 0) return NULL; @@ -142,7 +157,7 @@ int e_table_header_count (ETableHeader *eth) { g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), 0); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); return eth->col_count; } @@ -153,7 +168,7 @@ e_table_header_index (ETableHeader *eth, const char *identifier) int i; g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), 0); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); g_return_val_if_fail (identifier != NULL, 0); for (i = 0; i < eth->col_count; i++){ @@ -172,7 +187,7 @@ e_table_header_get_index_at (ETableHeader *eth, int x_offset) int i, total; g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), 0); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); total = 0; for (i = 0; i < eth->col_count; i++){ @@ -192,7 +207,7 @@ e_table_header_get_columns (ETableHeader *eth) int i; g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), 0); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); ret = g_new (ETableCol *, eth->col_count + 1); memcpy (ret, eth->columns, sizeof (ETableCol *) * eth->col_count); @@ -205,7 +220,7 @@ gboolean e_table_header_selection_ok (ETableHeader *eth) { g_return_val_if_fail (eth != NULL, FALSE); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), FALSE); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), FALSE); return eth->selectable; } @@ -217,7 +232,7 @@ ve_table_header_get_selected (ETableHeader *eth) int selected = 0; g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), 0); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); for (i = 0; i < eth->col_count; i++){ if (eth->columns [i]->selected) @@ -233,7 +248,7 @@ e_table_header_total_width (ETableHeader *eth) int total, i; g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_COLUMN (eth), 0); + g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); total = 0; for (i = 0; i < eth->col_count; i++) @@ -256,7 +271,7 @@ e_table_header_move (ETableHeader *eth, int source_index, int target_index) ETableCol *old; g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_COLUMN (eth)); + g_return_if_fail (E_IS_TABLE_HEADER (eth)); g_return_if_fail (source_index >= 0); g_return_if_fail (target_index >= 0); g_return_if_fail (source_index < eth->col_count); @@ -265,6 +280,8 @@ e_table_header_move (ETableHeader *eth, int source_index, int target_index) old = eth->columns [source_index]; eth_do_remove (eth, source_index); eth_do_insert (eth, target_index, old); + eth_update_offsets (eth); + gtk_signal_emit (GTK_OBJECT (eth), eth_signals [STRUCTURE_CHANGE]); } @@ -272,7 +289,7 @@ void e_table_header_remove (ETableHeader *eth, int idx) { g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_COLUMN (eth)); + g_return_if_fail (E_IS_TABLE_HEADER (eth)); g_return_if_fail (idx >= 0); g_return_if_fail (idx < eth->col_count); @@ -289,7 +306,7 @@ void e_table_header_set_size (ETableHeader *eth, int idx, int size) { g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_COLUMN (eth)); + g_return_if_fail (E_IS_TABLE_HEADER (eth)); g_return_if_fail (idx >= 0); g_return_if_fail (idx < eth->col_count); g_return_if_fail (size > 0); @@ -297,3 +314,4 @@ e_table_header_set_size (ETableHeader *eth, int idx, int size) eth->columns [idx]->width = size; gtk_signal_emit (GTK_OBJECT (eth), eth_signals [DIMENSION_CHANGE], idx); } + diff --git a/widgets/table/e-table-header.h b/widgets/table/e-table-header.h index d8e04ea8fd..89eced0158 100644 --- a/widgets/table/e-table-header.h +++ b/widgets/table/e-table-header.h @@ -6,27 +6,6 @@ #include "e-table-col.h" typedef struct _ETableHeader ETableHeader; -typedef struct _ETableCol ETableCol; - -/* - * Rendering function for the column header - */ -typedef void (*ETableColRenderFn)( - ETableCol *etc, void *gnome_canvas_item, void *drawable, - int x, int y, int w, int h, void *data); - -/* - * Information about a single column - */ -struct _ETableCol { - const char *id; - int width; - ETableColRenderFn render; - void *render_data; - unsigned int selected:1; - int resizeable:1; - int min_size; -}; #define E_TABLE_HEADER_TYPE (e_table_header_get_type ()) #define E_TABLE_HEADER(o) (GTK_CHECK_CAST ((o), E_TABLE_HEADER_TYPE, ETableHeader)) @@ -48,34 +27,35 @@ struct _ETableHeader { typedef struct { GtkObjectClass parent_class; - void (*structure_change) (ETableHeader *etc); - void (*dimension_change) (ETableHeader *etc, int col); + void (*structure_change) (ETableHeader *eth); + void (*dimension_change) (ETableHeader *eth, int col); } ETableHeaderClass; GtkType e_table_header_get_type (void); ETableHeader *e_table_header_new (void); -void e_table_header_add_column (ETableHeader *etc, +void e_table_header_add_column (ETableHeader *eth, ETableCol *tc, int pos); -ETableCol * e_table_header_get_column (ETableHeader *etc, +ETableCol * e_table_header_get_column (ETableHeader *eth, int column); -int e_table_header_count (ETableHeader *etc); -int e_table_header_index (ETableHeader *etc, +int e_table_header_count (ETableHeader *eth); +int e_table_header_index (ETableHeader *eth, const char *identifier); -int e_table_header_get_index_at (ETableHeader *etc, +int e_table_header_get_index_at (ETableHeader *eth, int x_offset); -ETableCol **e_table_header_get_columns (ETableHeader *etc); -gboolean e_table_header_selection_ok (ETableHeader *etc); -int e_table_header_get_selected (ETableHeader *etc); -int e_table_header_total_width (ETableHeader *etc); -void e_table_header_move (ETableHeader *etc, +ETableCol **e_table_header_get_columns (ETableHeader *eth); +gboolean e_table_header_selection_ok (ETableHeader *eth); +int e_table_header_get_selected (ETableHeader *eth); +int e_table_header_total_width (ETableHeader *eth); +void e_table_header_move (ETableHeader *eth, int source_index, int target_index); -void e_table_header_remove (ETableHeader *etc, int idx); -void e_table_header_set_size (ETableHeader *etc, int idx, int size); -void e_table_header_set_selection (ETableHeader *etc, +void e_table_header_remove (ETableHeader *eth, int idx); +void e_table_header_set_size (ETableHeader *eth, int idx, int size); +void e_table_header_set_selection (ETableHeader *eth, gboolean allow_selection); -GList *e_table_header_get_selected_indexes(ETableHeader *etc); +GList *e_table_header_get_selected_indexes(ETableHeader *eth); + #endif /* _E_TABLE_HEADER_H_ */ diff --git a/widgets/table/e-table-model.c b/widgets/table/e-table-model.c index 868664cf08..646aee77bd 100644 --- a/widgets/table/e-table-model.c +++ b/widgets/table/e-table-model.c @@ -40,7 +40,7 @@ e_table_model_value_at (ETableModel *etable, int col, int row) void e_table_model_set_value_at (ETableModel *etable, int col, int row, void *data) { - return ETM_CLASS (etable)->set_value_at (etable, col, row); + return ETM_CLASS (etable)->set_value_at (etable, col, row, data); } gboolean diff --git a/widgets/table/e-table-model.h b/widgets/table/e-table-model.h new file mode 100644 index 0000000000..e32d3d55ce --- /dev/null +++ b/widgets/table/e-table-model.h @@ -0,0 +1,46 @@ +#ifndef _E_TABLE_MODEL_H_ +#define _E_TABLE_MODEL_H_ + +#include + +#define E_TABLE_MODEL_TYPE (e_table_model_get_type ()) +#define E_TABLE_MODEL(o) (GTK_CHECK_CAST ((o), E_TABLE_MODEL_TYPE, ETableModel)) +#define E_TABLE_MODEL_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_MODEL_TYPE, ETableModelClass)) +#define E_IS_TABLE_MODEL(o) (GTK_CHECK_TYPE ((o), E_TABLE_MODEL_TYPE)) +#define E_IS_TABLE_MODEL_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_MODEL_TYPE)) + +typedef struct { + GtkObject base; +} ETableModel; + +typedef struct { + GtkObjectClass parent_class; + + /* + * Virtual methods + */ + int (*column_count) (ETableModel *etm); + const char *(*column_name) (ETableModel *etm, int col); + int (*row_count) (ETableModel *etm); + void *(*value_at) (ETableModel *etm, int col, int row); + void (*set_value_at) (ETableModel *etm, int col, int row, void *value); + gboolean (*is_cell_editable) (ETableModel *etm, int col, int row); + int (*row_height) (ETableModel *etm, int row); +} ETableModelClass; + +GtkType e_table_model_get_type (void); + +int e_table_model_column_count (ETableModel *e_table_model); +const char *e_table_model_column_name (ETableModel *e_table_model, int col); +int e_table_model_row_count (ETableModel *e_table_model); +int e_table_model_row_height (ETableModel *e_table_model, int row); +int e_table_model_height (ETableModel *e_table_model); +void *e_table_model_value_at (ETableModel *e_table_model, int col, int row); +void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, void *data); +gboolean e_table_model_is_cell_editable (ETableModel *e_table_model, int col, int row); + +/* + * Routines for emitting signals on the e_table + */ + +#endif /* _E_TABLE_MODEL_H_ */ diff --git a/widgets/table/e-table-render.c b/widgets/table/e-table-render.c new file mode 100644 index 0000000000..8e9f1bf285 --- /dev/null +++ b/widgets/table/e-table-render.c @@ -0,0 +1,20 @@ +/* + * E-table-render.c: Various renderers + * + * Author: + * Miguel de Icaza (miguel@gnu.org) + * + * Copyright 1999, International GNOME Support. + */ +#include +#include "e-table-header.h" +#include "e-table-header-item.h" +#include "e-table-col.h" +#include "e-table-render.h" + +void +e_table_render_string (ERenderContext *ctxt) +{ + printf ("Rendering string: %s\n", ctxt->render_data); +} + diff --git a/widgets/table/e-table-render.h b/widgets/table/e-table-render.h new file mode 100644 index 0000000000..ebc65968f0 --- /dev/null +++ b/widgets/table/e-table-render.h @@ -0,0 +1,21 @@ +#ifndef E_TABLE_RENDER_H +#define E_TABLE_RENDER_H + +#include + +struct ERenderContext { + ETableCol *etc; + int row; + int base_x, base_y; + GnomeCanvasItem *gnome_canvas_item; + GdkDrawable *drawable; + int drawable_width; + int drawable_height; + void *render_data; + void *closure; +}; + +void e_table_render_string (ERenderContext *ctxt); + + +#endif diff --git a/widgets/table/e-table-simple.c b/widgets/table/e-table-simple.c index e52a9498f8..6532d6e542 100644 --- a/widgets/table/e-table-simple.c +++ b/widgets/table/e-table-simple.c @@ -45,11 +45,11 @@ simple_value_at (ETableModel *etm, int col, int row) } static void -simple_set_value_at (ETableModel *etm, int col, int row) +simple_set_value_at (ETableModel *etm, int col, int row, void *val) { ETableSimple *simple = (ETableSimple *)etm; - simple->set_value_at (etm, col, row, simple->data); + simple->set_value_at (etm, col, row, val, simple->data); } static gboolean diff --git a/widgets/table/e-table-simple.h b/widgets/table/e-table-simple.h index fc69ce19d0..d47a1cbe0b 100644 --- a/widgets/table/e-table-simple.h +++ b/widgets/table/e-table-simple.h @@ -7,7 +7,7 @@ typedef int (*ETableSimpleColumnCountFn) (ETableModel *etm, void *dat typedef const char *(*ETableSimpleColumnNameFn) (ETableModel *etm, int col, void *data); typedef int (*ETableSimpleRowCountFn) (ETableModel *etm, void *data); typedef void *(*ETableSimpleValueAtFn) (ETableModel *etm, int col, int row, void *data); -typedef void (*ETableSimpleSetValueAtFn) (ETableModel *etm, int col, int row, void *data); +typedef void (*ETableSimpleSetValueAtFn) (ETableModel *etm, int col, int row, void *val, void *data); typedef gboolean (*ETableSimpleIsCellEditableFn) (ETableModel *etm, int col, int row, void *data); typedef int (*ETableSimpleRowHeightFn) (ETableModel *etm, int row, void *data); @@ -25,7 +25,7 @@ typedef struct { } ETableSimple; typedef struct { - ETableModel parent_class; + ETableModelClass parent_class; } ETableSimpleClass; GtkType e_table_simple_get_type (void); diff --git a/widgets/table/sample.table b/widgets/table/sample.table new file mode 100644 index 0000000000..2cb09d7f1f --- /dev/null +++ b/widgets/table/sample.table @@ -0,0 +1,8 @@ +Col1 Col2 Address Title Dorks +c1.a c2.a a.a tit-1 DorkA +c1.b c2.b a.b tit-2 DDork +c1.c c2.c a.c tit-1 DorkB +c1.d c2.d a.d tit-2 ADork +c1.e c2.e a.e tit-1 DorkC +c1.f c2.f a.f tit-2 UDork + diff --git a/widgets/table/table-test.c b/widgets/table/table-test.c new file mode 100644 index 0000000000..27b1df7201 --- /dev/null +++ b/widgets/table/table-test.c @@ -0,0 +1,216 @@ +/* + * Test code for the ETable package + * + * Author: + * Miguel de Icaza (miguel@gnu.org) + */ +#include +#include +#include +#include +#include "e-table-simple.h" +#include "e-table-header.h" +#include "e-table-header-item.h" +#include "e-table-render.h" + +char buffer [1024]; +char **column_labels; +char ***table_data; +int cols = 0; +int lines = 0; +int lines_alloc = 0; + +static void +parse_headers () +{ + char *p, *s; + int in_value = 0, i; + + fgets (buffer, sizeof (buffer)-1, stdin); + + for (p = buffer; *p; p++){ + if (*p == ' ' || *p == '\t'){ + if (in_value){ + cols++; + in_value = 0; + } + } else + in_value = 1; + } + if (in_value) + cols++; + + if (!cols){ + fprintf (stderr, "No columns in first row\n"); + exit (1); + } + + column_labels = g_new0 (char *, cols); + + p = buffer; + for (i = 0; (s = strtok (p, " \t")) != NULL; i++){ + column_labels [i] = g_strdup (s); + p = NULL; + } + + printf ("%d headers:\n", cols); + for (i = 0; i < cols; i++){ + printf ("header %d: %s\n", i, column_labels [i]); + } +} + +static char ** +load_line (char *buffer, int cols) +{ + char **line = g_new0 (char *, cols); + char *p; + int i; + + for (i = 0; i < cols; i++){ + p = strtok (buffer, " \t\n"); + if (p == NULL){ + for (; i < cols; i++) + line [i] = g_strdup (""); + return line; + } else + line [i] = g_strdup (p); + buffer = NULL; + } + return line; +} + +static void +append_line (char **line) +{ + if (lines <= lines_alloc){ + lines_alloc = lines + 50; + table_data = g_renew (char **, table_data, lines_alloc); + } + table_data [lines] = line; + lines++; +} + +static void +load_data () +{ + int i; + + parse_headers (); + + while (fgets (buffer, sizeof (buffer)-1, stdin) != NULL){ + char **line; + + if (buffer [0] == '\n') + continue; + line = load_line (buffer, cols); + append_line (line); + } + + for (i = 0; i < lines; i++){ + int j; + + printf ("Line %d: ", i); + for (j = 0; j < cols; j++) + printf ("[%s] ", table_data [i][j]); + printf ("\n"); + } +} + +/* + * ETableSimple callbacks + */ +static int +col_count (ETableModel *etc, void *data) +{ + return cols; +} + +static const char * +col_name (ETableModel *etc, int col, void *data) +{ + g_assert (col < cols); + + return column_labels [col]; +} + +static int +row_count (ETableModel *etc, void *data) +{ + return lines; +} + +static void * +value_at (ETableModel *etc, int col, int row, void *data) +{ + g_assert (col < cols); + g_assert (row < lines); + + return (void *) &table_data [row][col]; +} + +static void +set_value_at (ETableModel *etc, int col, int row, void *val, void *data) +{ + g_assert (col < cols); + g_assert (row < lines); + + g_free (table_data [row][col]); + table_data [row][col] = g_strdup (val); + + printf ("Value at %d,%d set to %s\n", col, row, val); +} + +static gboolean +is_cell_editable (ETableModel *etc, int col, int row, void *data) +{ + return TRUE; +} + +int +main (int argc, char *argv []) +{ + GtkWidget *canvas, *window; + ETableModel *e_table_model; + ETableHeader *e_table_header; + int i; + + gnome_init ("TableTest", "TableTest", argc, argv); + + load_data (); + + /* + * Data model + */ + e_table_model = e_table_simple_new ( + col_count, col_name, row_count, value_at, + set_value_at, is_cell_editable, NULL); + + /* + * Header + */ + e_table_header = e_table_header_new (); + for (i = 0; i < cols; i++){ + ETableCol *ecol = e_table_col_new ( + column_labels [i], 20, 20, e_table_render_string, + NULL, g_str_equal, TRUE); + + e_table_header_add_column (e_table_header, ecol, i); + } + + /* + * Setup GUI + */ + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + canvas = gnome_canvas_new (); + + gtk_container_add (GTK_CONTAINER (window), canvas); + gtk_widget_show_all (window); + + gnome_canvas_item_new ( + gnome_canvas_root (GNOME_CANVAS (canvas)), + e_table_header_item_get_type (), + "ETableHeader", e_table_header, + NULL); + gtk_main (); + return 0; +} diff --git a/widgets/table/test.c b/widgets/table/test.c new file mode 100644 index 0000000000..0eece34467 --- /dev/null +++ b/widgets/table/test.c @@ -0,0 +1,17 @@ +#include +#include "e-table-simple.h" + +struct { + char *str; + int val; +} data [] = { + { "Miguel", 10 }, + { "Nat", 20 }, + { NULL, 0 }, +}; + +main () +{ + +} + diff --git a/widgets/test.c b/widgets/test.c new file mode 100644 index 0000000000..0eece34467 --- /dev/null +++ b/widgets/test.c @@ -0,0 +1,17 @@ +#include +#include "e-table-simple.h" + +struct { + char *str; + int val; +} data [] = { + { "Miguel", 10 }, + { "Nat", 20 }, + { NULL, 0 }, +}; + +main () +{ + +} + -- cgit v1.2.3