Added duplicate_value and add_value. Use the new compare functions. Made

2000-02-24  Christopher James Lahey  <clahey@helixcode.com>

        * test-table.c: Added duplicate_value and add_value.  Use the new
        compare functions.  Made it so we only create one model to better
        test model view stuff.  Changed the test to not have as many
        extra, useless, columns.

        * test-cols.c, test-check.c: Added duplicate_value and add_value.  Use the new
        compare functions.

        * e-table.c, e-table.h: Use all the new features of e-table-groups
        (sorting and grouping).  Handle on the fly reorganization of
        groups in an idle loop.  Compare functions now are to return -1 if
        the first item is greater, 0 if they are equal, or 1 if the second
        item is greater.

        * e-table-subset.c, e-table-subset.h: Made e-table-subset
        disconnect properly from its signals when it dies.

        * e-table-subset-variable.c, e-table-subset-variable.h:
        Virtualized the add and remove commands so that
        e_table_sorted_variable could override the add command to do sorting.

        * e-table-sorted.c: Fixed this to inherit properly from
        ETableSubset.

        * e-table-simple.h, e-table-simple.c: Added handling of
        duplicate_value and free_value;

        * e-table-model.c, e-table-model.h: Added duplicate_value and
        free_value for memory allocation of table elements outside the
        table.

        * e-table-item.c: Fixed a crashing bug.

        * e-table-group.c: Added sorting.  Fixed destruction to delete the
        right things.

        * e-table-group-leaf.c, e-table-group-leaf.h: Pass column and sort
        order information into the e_table_sorted_variable.  Properly
        destroy things when deleted.

        * e-table-group-container.c, e-table-group-container.h: Properly
        handle the list of subgroups.  Handle proper sorting and grouping
        of subgroups.

        * e-table-sorted-variable.c, e-table-sorted-variable.h: Files to
        do a sorted model that stays sorted as you add and remove rows.

        * Makefile.am: Added e-table-sorted-variable.c and
        e-table-sorted-variable.h.

svn path=/trunk/; revision=1930
This commit is contained in:
Christopher James Lahey
2000-02-25 04:08:59 +00:00
committed by Chris Lahey
parent 675d1c25db
commit 14bfde56c8
46 changed files with 1348 additions and 184 deletions

View File

@ -1,3 +1,55 @@
2000-02-24 Christopher James Lahey <clahey@helixcode.com>
* test-table.c: Added duplicate_value and add_value. Use the new
compare functions. Made it so we only create one model to better
test model view stuff. Changed the test to not have as many
extra, useless, columns.
* test-cols.c, test-check.c: Added duplicate_value and add_value. Use the new
compare functions.
* e-table.c, e-table.h: Use all the new features of e-table-groups
(sorting and grouping). Handle on the fly reorganization of
groups in an idle loop. Compare functions now are to return -1 if
the first item is greater, 0 if they are equal, or 1 if the second
item is greater.
* e-table-subset.c, e-table-subset.h: Made e-table-subset
disconnect properly from its signals when it dies.
* e-table-subset-variable.c, e-table-subset-variable.h:
Virtualized the add and remove commands so that
e_table_sorted_variable could override the add command to do sorting.
* e-table-sorted.c: Fixed this to inherit properly from
ETableSubset.
* e-table-simple.h, e-table-simple.c: Added handling of
duplicate_value and free_value;
* e-table-model.c, e-table-model.h: Added duplicate_value and
free_value for memory allocation of table elements outside the
table.
* e-table-item.c: Fixed a crashing bug.
* e-table-group.c: Added sorting. Fixed destruction to delete the
right things.
* e-table-group-leaf.c, e-table-group-leaf.h: Pass column and sort
order information into the e_table_sorted_variable. Properly
destroy things when deleted.
* e-table-group-container.c, e-table-group-container.h: Properly
handle the list of subgroups. Handle proper sorting and grouping
of subgroups.
* e-table-sorted-variable.c, e-table-sorted-variable.h: Files to
do a sorted model that stays sorted as you add and remove rows.
* Makefile.am: Added e-table-sorted-variable.c and
e-table-sorted-variable.h.
2000-02-24 Christopher James Lahey <clahey@helixcode.com>
* e-table-item.c: Made keyboard focus navigation work across

View File

@ -39,6 +39,8 @@ libetable_a_SOURCES = \
e-table-simple.h \
e-table-sorted.c \
e-table-sorted.h \
e-table-sorted-variable.c \
e-table-sorted-variable.h \
e-table-subset.c \
e-table-subset.h \
e-table-subset-variable.c \

View File

@ -59,15 +59,42 @@ typedef struct {
gint count;
} ETableGroupContainerChildNode;
static void
e_table_group_container_child_node_free(ETableGroupContainer *etgc, ETableGroupContainerChildNode *child_node)
{
ETableGroup *etg = E_TABLE_GROUP(etgc);
ETableGroup *child = child_node->child;
gtk_object_destroy(GTK_OBJECT(child));
e_table_model_free_value(etg->model, etgc->ecol->col_idx, child_node->key);
gtk_object_destroy(GTK_OBJECT(child_node->text));
gtk_object_destroy(GTK_OBJECT(child_node->rect));
}
static void
e_table_group_container_list_free(ETableGroupContainer *etgc)
{
ETableGroupContainerChildNode *child_node;
GList *list;
for ( list = etgc->children; list; list = g_list_next(list) ) {
child_node = (ETableGroupContainerChildNode *) list->data;
e_table_group_container_child_node_free(etgc, child_node);
}
g_list_free(etgc->children);
}
static void
etgc_destroy (GtkObject *object)
{
ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (object);
gdk_font_unref(etgc->font);
gtk_object_unref(GTK_OBJECT(etgc->ecol));
gtk_object_destroy(GTK_OBJECT(etgc->rect));
e_table_group_container_list_free(etgc);
GTK_OBJECT_CLASS (etgc_parent_class)->destroy (object);
}
#if 0
void
e_table_group_add (ETableGroup *etg, GnomeCanvasItem *item)
@ -168,11 +195,13 @@ void
e_table_group_container_construct (GnomeCanvasGroup *parent, ETableGroupContainer *etgc,
ETableHeader *full_header,
ETableHeader *header,
ETableModel *model, ETableCol *ecol, xmlNode *child_rules)
ETableModel *model, ETableCol *ecol, int ascending, xmlNode *child_rules)
{
e_table_group_construct (parent, E_TABLE_GROUP (etgc), full_header, header, model);
etgc->ecol = ecol;
gtk_object_ref(GTK_OBJECT(etgc->ecol));
etgc->child_rules = child_rules;
etgc->ascending = ascending;
etgc->font = gdk_font_load ("lucidasans-10");
#if 0
@ -217,7 +246,7 @@ e_table_group_container_construct (GnomeCanvasGroup *parent, ETableGroupContaine
ETableGroup *
e_table_group_container_new (GnomeCanvasGroup *parent, ETableHeader *full_header,
ETableHeader *header,
ETableModel *model, ETableCol *ecol, xmlNode *child_rules)
ETableModel *model, ETableCol *ecol, int ascending, xmlNode *child_rules)
{
ETableGroupContainer *etgc;
@ -227,7 +256,7 @@ e_table_group_container_new (GnomeCanvasGroup *parent, ETableHeader *full_
etgc = gtk_type_new (e_table_group_container_get_type ());
e_table_group_container_construct (parent, etgc, full_header, header,
model, ecol, child_rules);
model, ecol, ascending, child_rules);
return E_TABLE_GROUP (etgc);
}
@ -498,15 +527,21 @@ static void etgc_add (ETableGroup *etg, gint row)
GList *list = etgc->children;
ETableGroup *child;
ETableGroupContainerChildNode *child_node;
for ( ; list; list = g_list_next(list) ) {
int i = 0;
for ( ; list; list = g_list_next(list), i++ ) {
int comp_val;
child_node = (ETableGroupContainerChildNode *)(list->data);
if ( (*comp)(child_node->key, val) ) {
comp_val = (*comp)(child_node->key, val);
if ( comp_val == 0 ) {
child = child_node->child;
child_node->count ++;
e_table_group_add(child, row);
compute_text(etgc, child_node);
return;
}
if ( (comp_val > 0 && etgc->ascending) ||
(comp_val < 0 && (!etgc->ascending)) )
break;
}
child_node = g_new(ETableGroupContainerChildNode, 1);
child_node->rect = gnome_canvas_item_new(GNOME_CANVAS_GROUP(etgc),
@ -524,13 +559,17 @@ static void etgc_add (ETableGroup *etg, gint row)
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;
child_node->key = e_table_model_duplicate_value(etg->model, etgc->ecol->col_idx, 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);
if ( list ) {
etgc->children = g_list_insert(etgc->children, child_node, i);
}
else
etgc->children = g_list_append(etgc->children, child_node);
compute_text(etgc, child_node);
etgc_queue_reposition(E_TABLE_GROUP_CONTAINER(etg));
}
@ -545,8 +584,7 @@ static gboolean etgc_remove (ETableGroup *etg, gint row)
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));
e_table_group_container_child_node_free(etgc, child_node);
etgc->children = g_list_remove(etgc->children, child_node);
g_free(child_node);
} else {

View File

@ -20,6 +20,7 @@ typedef struct {
* The ETableCol used to group this set
*/
ETableCol *ecol;
gint ascending;
/*
* List of ETableGroups we stack
@ -55,11 +56,11 @@ typedef struct {
} ETableGroupContainerClass;
ETableGroup *e_table_group_container_new (GnomeCanvasGroup *parent, ETableHeader *full_header, ETableHeader *header,
ETableModel *model, ETableCol *ecol, xmlNode *child_rules);
ETableModel *model, ETableCol *ecol, int ascending, 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);
ETableModel *model, ETableCol *ecol, int ascending, xmlNode *child_rules);
GtkType e_table_group_container_get_type (void);

View File

@ -36,23 +36,31 @@ 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);
ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF(object);
gtk_object_unref(GTK_OBJECT(etgl->subset));
gtk_object_destroy(GTK_OBJECT(etgl->item));
if ( GTK_OBJECT_CLASS (etgl_parent_class)->destroy )
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)
ETableModel *model,
int col,
int ascending)
{
etgl->subset = E_TABLE_SUBSET_VARIABLE(e_table_sorted_variable_new(model, col, ascending, e_table_header_get_column(full_header, col)->compare));
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)
ETableModel *model,
int col,
int ascending)
{
ETableGroupLeaf *etgl;
@ -61,7 +69,7 @@ e_table_group_leaf_new (GnomeCanvasGroup *parent, ETableHeader *full_heade
etgl = gtk_type_new (e_table_group_leaf_get_type ());
e_table_group_leaf_construct (parent, etgl, full_header,
header, model);
header, model, col, ascending);
return E_TABLE_GROUP (etgl);
}

View File

@ -4,7 +4,7 @@
#include <libgnomeui/gnome-canvas.h>
#include "e-table-group.h"
#include "e-table-subset-variable.h"
#include "e-table-sorted-variable.h"
#include "e-table-item.h"
#define E_TABLE_GROUP_LEAF_TYPE (e_table_group_leaf_get_type ())
@ -33,7 +33,9 @@ typedef struct {
ETableGroup *e_table_group_leaf_new (GnomeCanvasGroup *parent,
ETableHeader *full_header,
ETableHeader *header,
ETableModel *model);
ETableModel *model,
int col,
int ascending);
GtkType e_table_group_leaf_get_type (void);
#endif /* _E_TABLE_GROUP_LEAF_H_ */

View File

@ -17,6 +17,7 @@
#include <libgnomeui/gnome-canvas-rect-ellipse.h>
#include <gnome-xml/parser.h>
#include "e-util/e-util.h"
#include "e-util/e-xml-utils.h"
#define TITLE_HEIGHT 16
#define GROUP_INDENT 10
@ -45,7 +46,7 @@ enum {
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);
static void etg_destroy (GtkObject *object);
#if 0
GnomeCanvasItem *
e_table_group_new (GnomeCanvasGroup *parent, ETableCol *ecol,
@ -64,6 +65,17 @@ e_table_group_new (GnomeCanvasGroup *parent, ETableCol *ecol,
}
#endif
static void
etg_destroy (GtkObject *object)
{
ETableGroup *etg = E_TABLE_GROUP(object);
gtk_object_unref(GTK_OBJECT(etg->header));
gtk_object_unref(GTK_OBJECT(etg->full_header));
gtk_object_unref(GTK_OBJECT(etg->model));
if ( GTK_OBJECT_CLASS (etg_parent_class)->destroy )
GTK_OBJECT_CLASS (etg_parent_class)->destroy (object);
}
ETableGroup *
e_table_group_new (GnomeCanvasGroup *parent,
ETableHeader *full_header,
@ -71,17 +83,22 @@ e_table_group_new (GnomeCanvasGroup *parent,
ETableModel *model,
xmlNode *rules)
{
int column;
int ascending;
g_return_val_if_fail (model != NULL, NULL);
column = e_xml_get_integer_prop_by_name(rules, "column");
ascending = e_xml_get_integer_prop_by_name(rules, "ascending");
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);
if ( column > e_table_header_count(full_header) )
return e_table_group_leaf_new(parent, full_header, header, model, column, ascending);
col = e_table_header_get_columns(full_header)[column];
return e_table_group_container_new(parent, full_header, header, model, col, ascending, rules->childs);
} else {
return e_table_group_leaf_new(parent, full_header, header, model);
return e_table_group_leaf_new(parent, full_header, header, model, column, ascending);
}
return NULL;
}
@ -93,10 +110,13 @@ e_table_group_construct (GnomeCanvasGroup *parent,
ETableHeader *header,
ETableModel *model)
{
gnome_canvas_item_constructv (GNOME_CANVAS_ITEM (etg), parent, 0, NULL);
etg->full_header = full_header;
gtk_object_ref(GTK_OBJECT(etg->full_header));
etg->header = header;
gtk_object_ref(GTK_OBJECT(etg->header));
etg->model = model;
gtk_object_ref(GTK_OBJECT(etg->model));
gnome_canvas_item_constructv (GNOME_CANVAS_ITEM (etg), parent, 0, NULL);
}
void
@ -311,6 +331,7 @@ etg_class_init (GtkObjectClass *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;

View File

@ -307,6 +307,10 @@ static void
eti_table_model_changed (ETableModel *table_model, ETableItem *eti)
{
eti->rows = e_table_model_row_count (eti->table_model);
if (eti->focused_row > eti->rows - 1) {
eti->focused_row = eti->rows - 1;
}
if (eti->cell_views)
eti_compute_height (eti);

View File

@ -13,6 +13,9 @@
#define ETM_CLASS(e) ((ETableModelClass *)((GtkObject *)e)->klass)
#define PARENT_TYPE gtk_object_get_type();
static GtkObjectClass *e_table_model_parent_class;
enum {
@ -80,6 +83,28 @@ e_table_model_is_cell_editable (ETableModel *e_table_model, int col, int row)
return ETM_CLASS (e_table_model)->is_cell_editable (e_table_model, col, row);
}
void *
e_table_model_duplicate_value (ETableModel *e_table_model, int col, const void *value)
{
g_return_val_if_fail (e_table_model != NULL, NULL);
g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), NULL);
if (ETM_CLASS (e_table_model)->duplicate_value)
return ETM_CLASS (e_table_model)->duplicate_value (e_table_model, col, value);
else
return NULL;
}
void
e_table_model_free_value (ETableModel *e_table_model, int col, void *value)
{
g_return_if_fail (e_table_model != NULL);
g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
if (ETM_CLASS (e_table_model)->free_value)
ETM_CLASS (e_table_model)->free_value (e_table_model, col, value);
}
static void
e_table_model_destroy (GtkObject *object)
{
@ -121,27 +146,30 @@ e_table_model_class_init (GtkObjectClass *object_class)
gtk_object_class_add_signals (object_class, e_table_model_signals, LAST_SIGNAL);
}
GtkType
guint
e_table_model_get_type (void)
{
static GtkType type = 0;
static guint type = 0;
if (!type){
GtkTypeInfo info = {
"ETableModel",
sizeof (ETableModel),
sizeof (ETableModelClass),
(GtkClassInitFunc) e_table_model_class_init,
(GtkObjectInitFunc) NULL,
NULL, /* reserved 1 */
NULL, /* reserved 2 */
(GtkClassInitFunc) NULL
};
if (!type)
{
GtkTypeInfo info =
{
"ETableModle",
sizeof (ETableModel),
sizeof (ETableModelClass),
(GtkClassInitFunc) e_table_model_class_init,
NULL,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL,
};
type = gtk_type_unique (gtk_object_get_type (), &info);
}
type = gtk_type_unique (gtk_object_get_type(), &info);
}
return type;
return type;
}
void

View File

@ -27,6 +27,10 @@ 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 *(*duplicate_value) (ETableModel *etm, int col, const void *value);
void (*free_value) (ETableModel *etm, int col, void *value);
void (*thaw) (ETableModel *etm);
/*
* Signals
@ -48,9 +52,12 @@ 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);
void *e_table_model_value_at (ETableModel *e_table_model, int col, int row);
void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, const void *data);
void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, const void *value);
gboolean e_table_model_is_cell_editable (ETableModel *e_table_model, int col, int row);
void *e_table_model_duplicate_value (ETableModel *e_table_model, int col, const void *value);
void e_table_model_free_value (ETableModel *e_table_model, int col, void *value);
void e_table_model_freeze (ETableModel *e_table_model);
void e_table_model_thaw (ETableModel *e_table_model);

View File

@ -55,6 +55,22 @@ simple_is_cell_editable (ETableModel *etm, int col, int row)
return simple->is_cell_editable (etm, col, row, simple->data);
}
static void *
simple_duplicate_value (ETableModel *etm, int col, const void *value)
{
ETableSimple *simple = (ETableSimple *)etm;
return simple->duplicate_value (etm, col, value, simple->data);
}
static void
simple_free_value (ETableModel *etm, int col, void *value)
{
ETableSimple *simple = (ETableSimple *)etm;
simple->free_value (etm, col, value, simple->data);
}
static void
simple_thaw (ETableModel *etm)
{
@ -73,6 +89,8 @@ 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->duplicate_value = simple_duplicate_value;
model_class->free_value = simple_free_value;
model_class->thaw = simple_thaw;
}
@ -105,6 +123,8 @@ e_table_simple_new (ETableSimpleColumnCountFn col_count,
ETableSimpleValueAtFn value_at,
ETableSimpleSetValueAtFn set_value_at,
ETableSimpleIsCellEditableFn is_cell_editable,
ETableSimpleDuplicateValueFn duplicate_value,
ETableSimpleFreeValueFn free_value,
ETableSimpleThawFn thaw,
void *data)
{
@ -118,6 +138,8 @@ e_table_simple_new (ETableSimpleColumnCountFn col_count,
et->set_value_at = set_value_at;
et->is_cell_editable = is_cell_editable;
et->thaw = thaw;
et->duplicate_value = duplicate_value;
et->free_value = free_value;
et->data = data;
return (ETableModel *) et;

View File

@ -9,6 +9,8 @@ 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 *(*ETableSimpleDuplicateValueFn) (ETableModel *etm, int col, const void *val, void *data);
typedef void (*ETableSimpleFreeValueFn) (ETableModel *etm, int col, void *val, void *data);
typedef void (*ETableSimpleThawFn) (ETableModel *etm, void *data);
typedef struct {
@ -19,6 +21,8 @@ typedef struct {
ETableSimpleValueAtFn value_at;
ETableSimpleSetValueAtFn set_value_at;
ETableSimpleIsCellEditableFn is_cell_editable;
ETableSimpleDuplicateValueFn duplicate_value;
ETableSimpleFreeValueFn free_value;
ETableSimpleThawFn thaw;
void *data;
} ETableSimple;
@ -34,6 +38,8 @@ ETableModel *e_table_simple_new (ETableSimpleColumnCountFn col_count,
ETableSimpleValueAtFn value_at,
ETableSimpleSetValueAtFn set_value_at,
ETableSimpleIsCellEditableFn is_cell_editable,
ETableSimpleDuplicateValueFn duplicate_value,
ETableSimpleFreeValueFn free_value,
ETableSimpleThawFn thaw,
void *data);

View File

@ -0,0 +1,148 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* E-table-sorted.c: Implements a table that sorts 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-sorted-variable.h"
#define PARENT_TYPE E_TABLE_SUBSET_VARIABLE_TYPE
#define INCREMENT_AMOUNT 10
static ETableSubsetVariableClass *etsv_parent_class;
static void etsv_proxy_model_changed (ETableModel *etm, ETableSortedVariable *etsv);
static void etsv_proxy_model_row_changed (ETableModel *etm, int row, ETableSortedVariable *etsv);
static void etsv_proxy_model_cell_changed (ETableModel *etm, int col, int row, ETableSortedVariable *etsv);
static void etsv_add (ETableSubsetVariable *etssv, gint row);
static void
etsv_destroy (GtkObject *object)
{
ETableSortedVariable *etsv = E_TABLE_SORTED_VARIABLE (object);
ETableSubset *etss = E_TABLE_SUBSET (object);
gtk_signal_disconnect (GTK_OBJECT (etss->source),
etsv->table_model_changed_id);
gtk_signal_disconnect (GTK_OBJECT (etss->source),
etsv->table_model_row_changed_id);
gtk_signal_disconnect (GTK_OBJECT (etss->source),
etsv->table_model_cell_changed_id);
etsv->table_model_changed_id = 0;
etsv->table_model_row_changed_id = 0;
etsv->table_model_cell_changed_id = 0;
GTK_OBJECT_CLASS (etsv_parent_class)->destroy (object);
}
static void
etsv_class_init (GtkObjectClass *object_class)
{
ETableSubsetVariableClass *etssv_class = E_TABLE_SUBSET_VARIABLE_CLASS(object_class);
etsv_parent_class = gtk_type_class (PARENT_TYPE);
object_class->destroy = etsv_destroy;
etssv_class->add = etsv_add;
}
E_MAKE_TYPE(e_table_sorted_variable, "ETableSortedVariable", ETableSortedVariable, etsv_class_init, NULL, PARENT_TYPE);
static void
etsv_add (ETableSubsetVariable *etssv,
gint row)
{
ETableModel *etm = E_TABLE_MODEL(etssv);
ETableSubset *etss = E_TABLE_SUBSET(etssv);
ETableSortedVariable *etsv = E_TABLE_SORTED_VARIABLE(etssv);
int i;
int col = etsv->sort_col;
GCompareFunc comp = etsv->compare;
gint ascending = etsv->ascending;
void *val = e_table_model_value_at(etss->source, col, row);
/* FIXME: binary search anyone? */
for ( i = 0; i < etss->n_map; i++ ) {
int comp_val = (*comp)(val, e_table_model_value_at(etss->source, col, etss->map_table[i]));
if ( (ascending && comp_val < 0) || ((!ascending) && comp_val > 0) )
break;
}
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));
etssv->n_vals_allocated += INCREMENT_AMOUNT;
}
if ( i < etss->n_map )
memmove(etss->map_table + i + 1, etss->map_table + i, (etss->n_map - i) * sizeof(int));
etss->map_table[i] = row;
etss->n_map++;
if ( !etm->frozen )
e_table_model_changed(etm);
}
ETableModel *
e_table_sorted_variable_new (ETableModel *source, int col, int ascending, GCompareFunc compare)
{
ETableSortedVariable *etsv = gtk_type_new (E_TABLE_SORTED_VARIABLE_TYPE);
ETableSubsetVariable *etssv = E_TABLE_SUBSET_VARIABLE (etsv);
if (e_table_subset_variable_construct (etssv, source) == NULL){
gtk_object_destroy (GTK_OBJECT (etsv));
return NULL;
}
etsv->sort_col = col;
etsv->ascending = ascending;
etsv->compare = compare;
etsv->table_model_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_changed",
GTK_SIGNAL_FUNC (etsv_proxy_model_changed), etsv);
etsv->table_model_row_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_row_changed",
GTK_SIGNAL_FUNC (etsv_proxy_model_row_changed), etsv);
etsv->table_model_cell_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_cell_changed",
GTK_SIGNAL_FUNC (etsv_proxy_model_cell_changed), etsv);
return E_TABLE_MODEL(etsv);
}
static void
etsv_proxy_model_changed (ETableModel *etm, ETableSortedVariable *etsv)
{
if ( !E_TABLE_MODEL(etsv)->frozen ) {
/* FIXME: do_resort(); */
}
}
static void
etsv_proxy_model_row_changed (ETableModel *etm, int row, ETableSortedVariable *etsv)
{
ETableSubsetVariable *etssv = E_TABLE_SUBSET_VARIABLE(etsv);
if ( !E_TABLE_MODEL(etsv)->frozen ) {
if(e_table_subset_variable_remove(etssv, row))
e_table_subset_variable_add(etssv, row);
}
}
static void
etsv_proxy_model_cell_changed (ETableModel *etm, int col, int row, ETableSortedVariable *etsv)
{
ETableSubsetVariable *etssv = E_TABLE_SUBSET_VARIABLE(etsv);
if ( !E_TABLE_MODEL(etsv)->frozen ) {
if ( col == etsv->sort_col ) {
if(e_table_subset_variable_remove(etssv, row))
e_table_subset_variable_add(etssv, row);
}
}
}

View File

@ -0,0 +1,34 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#ifndef _E_TABLE_SORTED_VARIABLE_H_
#define _E_TABLE_SORTED_VARIABLE_H_
#include <gtk/gtkobject.h>
#include "e-table-model.h"
#include "e-table-subset-variable.h"
#define E_TABLE_SORTED_VARIABLE_TYPE (e_table_sorted_variable_get_type ())
#define E_TABLE_SORTED_VARIABLE(o) (GTK_CHECK_CAST ((o), E_TABLE_SORTED_VARIABLE_TYPE, ETableSortedVariable))
#define E_TABLE_SORTED_VARIABLE_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_SORTED_VARIABLE_TYPE, ETableSortedVariableClass))
#define E_IS_TABLE_SORTED_VARIABLE(o) (GTK_CHECK_TYPE ((o), E_TABLE_SORTED_VARIABLE_TYPE))
#define E_IS_TABLE_SORTED_VARIABLE_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_SORTED_VARIABLE_TYPE))
typedef struct {
ETableSubsetVariable base;
short sort_col;
int ascending;
GCompareFunc compare;
int table_model_changed_id;
int table_model_row_changed_id;
int table_model_cell_changed_id;
} ETableSortedVariable;
typedef struct {
ETableSubsetVariableClass parent_class;
} ETableSortedVariableClass;
GtkType e_table_sorted_variable_get_type (void);
ETableModel *e_table_sorted_variable_new (ETableModel *etm, int col, int ascending, GCompareFunc compare);
#endif /* _E_TABLE_SORTED_VARIABLE_H_ */

View File

@ -13,7 +13,7 @@
#define PARENT_TYPE E_TABLE_SUBSET_TYPE
static ETableModelClass *ets_parent_class;
static ETableSubsetClass *ets_parent_class;
static void
ets_class_init (GtkObjectClass *klass)

View File

@ -14,16 +14,58 @@
#include "e-util/e-util.h"
#include "e-table-subset-variable.h"
#define ETSSV_CLASS(e) ((ETableSubsetVariableClass *)((GtkObject *)e)->klass)
#define PARENT_TYPE E_TABLE_SUBSET_TYPE
#define INCREMENT_AMOUNT 10
static ETableModelClass *etssv_parent_class;
static ETableSubsetClass *etssv_parent_class;
static void
etssv_class_init (GtkObjectClass *klass)
etssv_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));
etssv->n_vals_allocated += INCREMENT_AMOUNT;
}
etss->map_table[etss->n_map++] = row;
if ( !etm->frozen )
e_table_model_changed(etm);
}
static gboolean
etssv_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;
}
static void
etssv_class_init (GtkObjectClass *object_class)
{
ETableSubsetVariableClass *klass = E_TABLE_SUBSET_VARIABLE_CLASS(object_class);
etssv_parent_class = gtk_type_class (PARENT_TYPE);
klass->add = etssv_add;
klass->remove = etssv_remove;
}
E_MAKE_TYPE(e_table_subset_variable, "ETableSubsetVariable", ETableSubsetVariable, etssv_class_init, NULL, PARENT_TYPE);
@ -56,34 +98,24 @@ 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);
g_return_if_fail (etssv != NULL);
g_return_if_fail (E_IS_TABLE_SUBSET_VARIABLE(etssv));
if (ETSSV_CLASS(etssv)->add)
ETSSV_CLASS (etssv)->add (etssv, row);
}
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;
g_return_val_if_fail (etssv != NULL, FALSE);
g_return_val_if_fail (E_IS_TABLE_SUBSET_VARIABLE(etssv), FALSE);
if (ETSSV_CLASS(etssv)->remove)
return ETSSV_CLASS (etssv)->remove (etssv, row);
else
return FALSE;
}
void

View File

@ -19,6 +19,11 @@ typedef struct {
typedef struct {
ETableSubsetClass parent_class;
void (*add) (ETableSubsetVariable *ets,
gint row);
gboolean (*remove) (ETableSubsetVariable *ets,
gint row);
} ETableSubsetVariableClass;
GtkType e_table_subset_variable_get_type (void);

View File

@ -25,6 +25,17 @@ etss_destroy (GtkObject *object)
if (etss->source)
gtk_object_unref (GTK_OBJECT (etss->source));
gtk_signal_disconnect (GTK_OBJECT (etss->source),
etss->table_model_changed_id);
gtk_signal_disconnect (GTK_OBJECT (etss->source),
etss->table_model_row_changed_id);
gtk_signal_disconnect (GTK_OBJECT (etss->source),
etss->table_model_cell_changed_id);
etss->table_model_changed_id = 0;
etss->table_model_row_changed_id = 0;
etss->table_model_cell_changed_id = 0;
if (etss->map_table)
free (etss->map_table);
@ -71,6 +82,22 @@ etss_is_cell_editable (ETableModel *etm, int col, int row)
return e_table_model_is_cell_editable (etss->source, col, etss->map_table [row]);
}
static void *
etss_duplicate_value (ETableModel *etm, int col, const void *value)
{
ETableSubset *etss = (ETableSubset *)etm;
return e_table_model_duplicate_value (etss->source, col, value);
}
static void
etss_free_value (ETableModel *etm, int col, void *value)
{
ETableSubset *etss = (ETableSubset *)etm;
e_table_model_free_value (etss->source, col, value);
}
static void
etss_thaw (ETableModel *etm)
{
@ -91,6 +118,8 @@ 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->duplicate_value = etss_duplicate_value;
table_class->free_value = etss_free_value;
table_class->thaw = etss_thaw;
}
@ -155,12 +184,12 @@ e_table_subset_construct (ETableSubset *etss, ETableModel *source, int nvals)
for (i = 0; i < nvals; i++)
etss->map_table [i] = i;
gtk_signal_connect (GTK_OBJECT (source), "model_changed",
GTK_SIGNAL_FUNC (etss_proxy_model_changed), etss);
gtk_signal_connect (GTK_OBJECT (source), "model_row_changed",
GTK_SIGNAL_FUNC (etss_proxy_model_row_changed), etss);
gtk_signal_connect (GTK_OBJECT (source), "model_cell_changed",
GTK_SIGNAL_FUNC (etss_proxy_model_cell_changed), etss);
etss->table_model_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_changed",
GTK_SIGNAL_FUNC (etss_proxy_model_changed), etss);
etss->table_model_row_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_row_changed",
GTK_SIGNAL_FUNC (etss_proxy_model_row_changed), etss);
etss->table_model_cell_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_cell_changed",
GTK_SIGNAL_FUNC (etss_proxy_model_cell_changed), etss);
return E_TABLE_MODEL (etss);
}

View File

@ -17,6 +17,10 @@ typedef struct {
ETableModel *source;
int n_map;
int *map_table;
int table_model_changed_id;
int table_model_row_changed_id;
int table_model_cell_changed_id;
} ETableSubset;
typedef struct {

View File

@ -34,6 +34,8 @@
static GtkObjectClass *e_table_parent_class;
static void e_table_fill_table (ETable *e_table, ETableModel *model);
static void
et_destroy (GtkObject *object)
{
@ -42,6 +44,20 @@ et_destroy (GtkObject *object)
gtk_object_unref (GTK_OBJECT (et->model));
gtk_object_unref (GTK_OBJECT (et->full_header));
gtk_object_unref (GTK_OBJECT (et->header));
gtk_widget_destroy (GTK_WIDGET (et->header_canvas));
gtk_widget_destroy (GTK_WIDGET (et->table_canvas));
gtk_signal_disconnect (GTK_OBJECT (et->model),
et->table_model_change_id);
gtk_signal_disconnect (GTK_OBJECT (et->model),
et->table_row_change_id);
gtk_signal_disconnect (GTK_OBJECT (et->model),
et->table_cell_change_id);
if (et->rebuild_idle_id) {
g_source_remove(et->rebuild_idle_id);
et->rebuild_idle_id = 0;
}
(*e_table_parent_class->destroy)(object);
}
@ -54,6 +70,11 @@ e_table_init (GtkObject *object)
e_table->draw_grid = 1;
e_table->draw_focus = 1;
e_table->spreadsheet = 1;
e_table->need_rebuild = 0;
e_table->need_row_changes = 0;
e_table->row_changes_list = NULL;
e_table->rebuild_idle_id = 0;
}
static ETableHeader *
@ -527,6 +548,72 @@ table_canvas_size_allocate (GtkWidget *widget, GtkAllocation *alloc, ETable *e_t
NULL);
}
static void
change_row (gpointer key, gpointer value, gpointer data)
{
ETable *et = E_TABLE(data);
gint row = GPOINTER_TO_INT(key);
if ( e_table_group_remove(et->group, row) ) {
e_table_group_add(et->group, row);
}
}
static gboolean
changed_idle (gpointer data)
{
ETable *et = E_TABLE(data);
if ( et->need_rebuild ) {
gtk_object_destroy( GTK_OBJECT(et->group ) );
et->group = e_table_group_new(GNOME_CANVAS_GROUP(et->table_canvas->root),
et->full_header,
et->header,
et->model,
e_xml_get_child_by_name(xmlDocGetRootElement(et->specification), "grouping")->childs);
e_table_fill_table(et, et->model);
} else if (et->need_row_changes) {
g_hash_table_foreach(et->row_changes_list, change_row, et);
}
et->need_rebuild = 0;
et->need_row_changes = 0;
if (et->row_changes_list)
g_hash_table_destroy(et->row_changes_list);
et->row_changes_list = NULL;
et->rebuild_idle_id = 0;
return FALSE;
}
static void
et_table_model_changed (ETableModel *model, ETable *et)
{
et->need_rebuild = TRUE;
if ( !et->rebuild_idle_id ) {
et->rebuild_idle_id = g_idle_add(changed_idle, et);
}
}
static void
et_table_row_changed (ETableModel *table_model, int row, ETable *et)
{
if ( !et->need_rebuild ) {
if (!et->need_row_changes) {
et->need_row_changes = 1;
et->row_changes_list = g_hash_table_new (g_direct_hash, g_direct_equal);
}
if (!g_hash_table_lookup(et->row_changes_list, GINT_TO_POINTER(row))) {
g_hash_table_insert(et->row_changes_list, GINT_TO_POINTER(row), GINT_TO_POINTER(row + 1));
}
}
if ( !et->rebuild_idle_id ) {
et->rebuild_idle_id = g_idle_add(changed_idle, et);
}
}
static void
et_table_cell_changed (ETableModel *table_model, int view_col, int row, ETable *et)
{
et_table_row_changed(table_model, row, et);
}
static void
e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *header, ETableModel *model, xmlNode *xml_grouping)
{
@ -546,6 +633,17 @@ e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *h
model,
xml_grouping->childs);
e_table->table_model_change_id = gtk_signal_connect (
GTK_OBJECT (model), "model_changed",
GTK_SIGNAL_FUNC (et_table_model_changed), e_table);
e_table->table_row_change_id = gtk_signal_connect (
GTK_OBJECT (model), "model_row_changed",
GTK_SIGNAL_FUNC (et_table_row_changed), e_table);
e_table->table_cell_change_id = gtk_signal_connect (
GTK_OBJECT (model), "model_cell_changed",
GTK_SIGNAL_FUNC (et_table_cell_changed), e_table);
}
static void

View File

@ -26,6 +26,10 @@ typedef struct {
ETableGroup *group;
int table_model_change_id;
int table_row_change_id;
int table_cell_change_id;
GnomeCanvas *header_canvas, *table_canvas;
GnomeCanvasItem *header_item, *root;
@ -35,6 +39,12 @@ typedef struct {
guint draw_grid:1;
guint draw_focus:1;
guint spreadsheet:1;
guint need_rebuild:1;
guint need_row_changes:1;
GHashTable *row_changes_list;
gint rebuild_idle_id;
} ETable;
typedef struct {

View File

@ -14,6 +14,7 @@
#include "e-table-item.h"
#include "e-util/e-cursors.h"
#include "e-util/e-canvas-utils.h"
#include "e-util/e-util.h"
#include "e-cell-text.h"
#include "e-cell-checkbox.h"
@ -79,6 +80,24 @@ is_cell_editable (ETableModel *etc, int col, int row, void *data)
return TRUE;
}
static void *
duplicate_value (ETableModel *etc, int col, const void *value, void *data)
{
if (col == 0){
return (void *) value;
} else {
return g_strdup(value);
}
}
static void
free_value (ETableModel *etc, int col, void *value, void *data)
{
if (col != 0){
g_free(value);
}
}
static void
thaw (ETableModel *etc, void *data)
{
@ -107,7 +126,8 @@ check_test (void)
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
set_value_at, is_cell_editable, thaw, NULL);
set_value_at, is_cell_editable,
duplicate_value, free_value, thaw, NULL);
/*
* Header
@ -118,11 +138,11 @@ check_test (void)
cell_image_check = e_cell_checkbox_new ();
pixbuf = gdk_pixbuf_new_from_file("clip.png");
col_0 = e_table_col_new_with_pixbuf (0, pixbuf, 18, 18, cell_image_check, g_int_equal, TRUE);
col_0 = e_table_col_new_with_pixbuf (0, pixbuf, 18, 18, cell_image_check, g_int_compare, TRUE);
gdk_pixbuf_unref(pixbuf);
e_table_header_add_column (e_table_header, col_0, 0);
col_1 = e_table_col_new (1, "Item Name", 180, 20, cell_left_just, g_str_equal, TRUE);
col_1 = e_table_col_new (1, "Item Name", 180, 20, cell_left_just, g_str_compare, TRUE);
e_table_header_add_column (e_table_header, col_1, 1);
e_table_col_set_arrow ( col_1, E_TABLE_COL_ARROW_DOWN );

View File

@ -10,6 +10,7 @@
#include <gnome.h>
#include "e-util/e-canvas-utils.h"
#include "e-util/e-cursors.h"
#include "e-util/e-util.h"
#include "e-table-simple.h"
#include "e-table-header.h"
#include "e-table-header-item.h"
@ -79,6 +80,24 @@ is_cell_editable (ETableModel *etc, int col, int row, void *data)
return TRUE;
}
static void *
duplicate_value (ETableModel *etc, int col, const void *value, void *data)
{
if (col == 0){
return (void *)value;
} else {
return g_strdup(value);
}
}
static void
free_value (ETableModel *etc, int col, void *value, void *data)
{
if (col != 0){
g_free(value);
}
}
static void
set_canvas_size (GnomeCanvas *canvas, GtkAllocation *alloc)
{
@ -106,7 +125,9 @@ multi_cols_test (void)
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
set_value_at, is_cell_editable, thaw, NULL);
set_value_at, is_cell_editable,
duplicate_value, free_value,
thaw, NULL);
/*
* Header
@ -131,10 +152,10 @@ multi_cols_test (void)
g_free (images);
}
col_1 = e_table_col_new (1, "Item Name", 180, 20, cell_left_just, g_str_equal, TRUE);
col_1 = e_table_col_new (1, "Item Name", 180, 20, cell_left_just, g_str_compare, TRUE);
e_table_header_add_column (e_table_header, col_1, 0);
col_0 = e_table_col_new (0, "A", 48, 48, cell_image_toggle, g_int_equal, TRUE);
col_0 = e_table_col_new (0, "A", 48, 48, cell_image_toggle, g_int_compare, TRUE);
e_table_header_add_column (e_table_header, col_0, 1);
/*

View File

@ -176,6 +176,18 @@ is_cell_editable (ETableModel *etc, int col, int row, void *data)
return TRUE;
}
static void *
duplicate_value (ETableModel *etc, int col, const void *value, void *data)
{
return g_strdup(value);
}
static void
free_value (ETableModel *etc, int col, void *value, void *data)
{
g_free(value);
}
static void
thaw (ETableModel *etc, void *data)
{
@ -205,7 +217,8 @@ table_browser_test (void)
*/
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
set_value_at, is_cell_editable, thaw, NULL);
set_value_at, is_cell_editable,
duplicate_value, free_value, thaw, NULL);
/*
* Header
@ -217,7 +230,7 @@ table_browser_test (void)
ETableCol *ecol = e_table_col_new (
i, column_labels [i],
80, 20, cell_left_just,
g_str_equal, TRUE);
g_str_compare, TRUE);
e_table_header_add_column (e_table_header, ecol, i);
}
@ -263,7 +276,6 @@ static void
do_e_table_demo (const char *spec)
{
GtkWidget *e_table, *window, *frame;
ETableModel *e_table_model;
ECell *cell_left_just;
ETableHeader *full_header;
int i;
@ -271,9 +283,14 @@ do_e_table_demo (const char *spec)
/*
* Data model
*/
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
set_value_at, is_cell_editable, thaw, NULL);
static ETableModel *e_table_model = NULL;
if ( e_table_model == NULL )
e_table_model =
e_table_simple_new (col_count, row_count, value_at,
set_value_at, is_cell_editable,
duplicate_value, free_value,
thaw, NULL);
full_header = e_table_header_new ();
cell_left_just = e_cell_text_new (e_table_model, NULL, GTK_JUSTIFY_LEFT, TRUE);
@ -282,7 +299,7 @@ do_e_table_demo (const char *spec)
ETableCol *ecol = e_table_col_new (
i, column_labels [i],
80, 20, cell_left_just,
g_str_equal, TRUE);
g_str_compare, TRUE);
e_table_header_add_column (full_header, ecol, i);
}
@ -306,9 +323,9 @@ e_table_test (void)
load_data ();
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 ("<ETableSpecification> <columns-shown> <column> 0 </column> <column> 1 </column> <column> 2 </column> <column> 3 </column> <column> 4 </column> </columns-shown> <grouping> <leaf column=\"3\" ascending=\"1\"/> </grouping> </ETableSpecification>");
do_e_table_demo ("<ETableSpecification> <columns-shown> <column> 0 </column> <column> 0 </column> <column> 1 </column> <column> 2 </column> <column> 3 </column> <column> 4 </column> </columns-shown> <grouping> <group column=\"3\" ascending=\"1\"> <group column=\"4\" ascending=\"0\"> <leaf column=\"2\" ascending=\"1\"/> </group> </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=\"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>");
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\" ascending=\"1\"> <leaf column=\"2\" ascending=\"1\"/> </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\" ascending=\"1\"> <leaf column=\"2\" ascending=\"1\"/> </group> </grouping> </ETableSpecification>");
}

View File

@ -59,15 +59,42 @@ typedef struct {
gint count;
} ETableGroupContainerChildNode;
static void
e_table_group_container_child_node_free(ETableGroupContainer *etgc, ETableGroupContainerChildNode *child_node)
{
ETableGroup *etg = E_TABLE_GROUP(etgc);
ETableGroup *child = child_node->child;
gtk_object_destroy(GTK_OBJECT(child));
e_table_model_free_value(etg->model, etgc->ecol->col_idx, child_node->key);
gtk_object_destroy(GTK_OBJECT(child_node->text));
gtk_object_destroy(GTK_OBJECT(child_node->rect));
}
static void
e_table_group_container_list_free(ETableGroupContainer *etgc)
{
ETableGroupContainerChildNode *child_node;
GList *list;
for ( list = etgc->children; list; list = g_list_next(list) ) {
child_node = (ETableGroupContainerChildNode *) list->data;
e_table_group_container_child_node_free(etgc, child_node);
}
g_list_free(etgc->children);
}
static void
etgc_destroy (GtkObject *object)
{
ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (object);
gdk_font_unref(etgc->font);
gtk_object_unref(GTK_OBJECT(etgc->ecol));
gtk_object_destroy(GTK_OBJECT(etgc->rect));
e_table_group_container_list_free(etgc);
GTK_OBJECT_CLASS (etgc_parent_class)->destroy (object);
}
#if 0
void
e_table_group_add (ETableGroup *etg, GnomeCanvasItem *item)
@ -168,11 +195,13 @@ void
e_table_group_container_construct (GnomeCanvasGroup *parent, ETableGroupContainer *etgc,
ETableHeader *full_header,
ETableHeader *header,
ETableModel *model, ETableCol *ecol, xmlNode *child_rules)
ETableModel *model, ETableCol *ecol, int ascending, xmlNode *child_rules)
{
e_table_group_construct (parent, E_TABLE_GROUP (etgc), full_header, header, model);
etgc->ecol = ecol;
gtk_object_ref(GTK_OBJECT(etgc->ecol));
etgc->child_rules = child_rules;
etgc->ascending = ascending;
etgc->font = gdk_font_load ("lucidasans-10");
#if 0
@ -217,7 +246,7 @@ e_table_group_container_construct (GnomeCanvasGroup *parent, ETableGroupContaine
ETableGroup *
e_table_group_container_new (GnomeCanvasGroup *parent, ETableHeader *full_header,
ETableHeader *header,
ETableModel *model, ETableCol *ecol, xmlNode *child_rules)
ETableModel *model, ETableCol *ecol, int ascending, xmlNode *child_rules)
{
ETableGroupContainer *etgc;
@ -227,7 +256,7 @@ e_table_group_container_new (GnomeCanvasGroup *parent, ETableHeader *full_
etgc = gtk_type_new (e_table_group_container_get_type ());
e_table_group_container_construct (parent, etgc, full_header, header,
model, ecol, child_rules);
model, ecol, ascending, child_rules);
return E_TABLE_GROUP (etgc);
}
@ -498,15 +527,21 @@ static void etgc_add (ETableGroup *etg, gint row)
GList *list = etgc->children;
ETableGroup *child;
ETableGroupContainerChildNode *child_node;
for ( ; list; list = g_list_next(list) ) {
int i = 0;
for ( ; list; list = g_list_next(list), i++ ) {
int comp_val;
child_node = (ETableGroupContainerChildNode *)(list->data);
if ( (*comp)(child_node->key, val) ) {
comp_val = (*comp)(child_node->key, val);
if ( comp_val == 0 ) {
child = child_node->child;
child_node->count ++;
e_table_group_add(child, row);
compute_text(etgc, child_node);
return;
}
if ( (comp_val > 0 && etgc->ascending) ||
(comp_val < 0 && (!etgc->ascending)) )
break;
}
child_node = g_new(ETableGroupContainerChildNode, 1);
child_node->rect = gnome_canvas_item_new(GNOME_CANVAS_GROUP(etgc),
@ -524,13 +559,17 @@ static void etgc_add (ETableGroup *etg, gint row)
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;
child_node->key = e_table_model_duplicate_value(etg->model, etgc->ecol->col_idx, 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);
if ( list ) {
etgc->children = g_list_insert(etgc->children, child_node, i);
}
else
etgc->children = g_list_append(etgc->children, child_node);
compute_text(etgc, child_node);
etgc_queue_reposition(E_TABLE_GROUP_CONTAINER(etg));
}
@ -545,8 +584,7 @@ static gboolean etgc_remove (ETableGroup *etg, gint row)
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));
e_table_group_container_child_node_free(etgc, child_node);
etgc->children = g_list_remove(etgc->children, child_node);
g_free(child_node);
} else {

View File

@ -20,6 +20,7 @@ typedef struct {
* The ETableCol used to group this set
*/
ETableCol *ecol;
gint ascending;
/*
* List of ETableGroups we stack
@ -55,11 +56,11 @@ typedef struct {
} ETableGroupContainerClass;
ETableGroup *e_table_group_container_new (GnomeCanvasGroup *parent, ETableHeader *full_header, ETableHeader *header,
ETableModel *model, ETableCol *ecol, xmlNode *child_rules);
ETableModel *model, ETableCol *ecol, int ascending, 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);
ETableModel *model, ETableCol *ecol, int ascending, xmlNode *child_rules);
GtkType e_table_group_container_get_type (void);

View File

@ -36,23 +36,31 @@ 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);
ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF(object);
gtk_object_unref(GTK_OBJECT(etgl->subset));
gtk_object_destroy(GTK_OBJECT(etgl->item));
if ( GTK_OBJECT_CLASS (etgl_parent_class)->destroy )
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)
ETableModel *model,
int col,
int ascending)
{
etgl->subset = E_TABLE_SUBSET_VARIABLE(e_table_sorted_variable_new(model, col, ascending, e_table_header_get_column(full_header, col)->compare));
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)
ETableModel *model,
int col,
int ascending)
{
ETableGroupLeaf *etgl;
@ -61,7 +69,7 @@ e_table_group_leaf_new (GnomeCanvasGroup *parent, ETableHeader *full_heade
etgl = gtk_type_new (e_table_group_leaf_get_type ());
e_table_group_leaf_construct (parent, etgl, full_header,
header, model);
header, model, col, ascending);
return E_TABLE_GROUP (etgl);
}

View File

@ -4,7 +4,7 @@
#include <libgnomeui/gnome-canvas.h>
#include "e-table-group.h"
#include "e-table-subset-variable.h"
#include "e-table-sorted-variable.h"
#include "e-table-item.h"
#define E_TABLE_GROUP_LEAF_TYPE (e_table_group_leaf_get_type ())
@ -33,7 +33,9 @@ typedef struct {
ETableGroup *e_table_group_leaf_new (GnomeCanvasGroup *parent,
ETableHeader *full_header,
ETableHeader *header,
ETableModel *model);
ETableModel *model,
int col,
int ascending);
GtkType e_table_group_leaf_get_type (void);
#endif /* _E_TABLE_GROUP_LEAF_H_ */

View File

@ -17,6 +17,7 @@
#include <libgnomeui/gnome-canvas-rect-ellipse.h>
#include <gnome-xml/parser.h>
#include "e-util/e-util.h"
#include "e-util/e-xml-utils.h"
#define TITLE_HEIGHT 16
#define GROUP_INDENT 10
@ -45,7 +46,7 @@ enum {
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);
static void etg_destroy (GtkObject *object);
#if 0
GnomeCanvasItem *
e_table_group_new (GnomeCanvasGroup *parent, ETableCol *ecol,
@ -64,6 +65,17 @@ e_table_group_new (GnomeCanvasGroup *parent, ETableCol *ecol,
}
#endif
static void
etg_destroy (GtkObject *object)
{
ETableGroup *etg = E_TABLE_GROUP(object);
gtk_object_unref(GTK_OBJECT(etg->header));
gtk_object_unref(GTK_OBJECT(etg->full_header));
gtk_object_unref(GTK_OBJECT(etg->model));
if ( GTK_OBJECT_CLASS (etg_parent_class)->destroy )
GTK_OBJECT_CLASS (etg_parent_class)->destroy (object);
}
ETableGroup *
e_table_group_new (GnomeCanvasGroup *parent,
ETableHeader *full_header,
@ -71,17 +83,22 @@ e_table_group_new (GnomeCanvasGroup *parent,
ETableModel *model,
xmlNode *rules)
{
int column;
int ascending;
g_return_val_if_fail (model != NULL, NULL);
column = e_xml_get_integer_prop_by_name(rules, "column");
ascending = e_xml_get_integer_prop_by_name(rules, "ascending");
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);
if ( column > e_table_header_count(full_header) )
return e_table_group_leaf_new(parent, full_header, header, model, column, ascending);
col = e_table_header_get_columns(full_header)[column];
return e_table_group_container_new(parent, full_header, header, model, col, ascending, rules->childs);
} else {
return e_table_group_leaf_new(parent, full_header, header, model);
return e_table_group_leaf_new(parent, full_header, header, model, column, ascending);
}
return NULL;
}
@ -93,10 +110,13 @@ e_table_group_construct (GnomeCanvasGroup *parent,
ETableHeader *header,
ETableModel *model)
{
gnome_canvas_item_constructv (GNOME_CANVAS_ITEM (etg), parent, 0, NULL);
etg->full_header = full_header;
gtk_object_ref(GTK_OBJECT(etg->full_header));
etg->header = header;
gtk_object_ref(GTK_OBJECT(etg->header));
etg->model = model;
gtk_object_ref(GTK_OBJECT(etg->model));
gnome_canvas_item_constructv (GNOME_CANVAS_ITEM (etg), parent, 0, NULL);
}
void
@ -311,6 +331,7 @@ etg_class_init (GtkObjectClass *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;

View File

@ -307,6 +307,10 @@ static void
eti_table_model_changed (ETableModel *table_model, ETableItem *eti)
{
eti->rows = e_table_model_row_count (eti->table_model);
if (eti->focused_row > eti->rows - 1) {
eti->focused_row = eti->rows - 1;
}
if (eti->cell_views)
eti_compute_height (eti);

View File

@ -13,6 +13,9 @@
#define ETM_CLASS(e) ((ETableModelClass *)((GtkObject *)e)->klass)
#define PARENT_TYPE gtk_object_get_type();
static GtkObjectClass *e_table_model_parent_class;
enum {
@ -80,6 +83,28 @@ e_table_model_is_cell_editable (ETableModel *e_table_model, int col, int row)
return ETM_CLASS (e_table_model)->is_cell_editable (e_table_model, col, row);
}
void *
e_table_model_duplicate_value (ETableModel *e_table_model, int col, const void *value)
{
g_return_val_if_fail (e_table_model != NULL, NULL);
g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), NULL);
if (ETM_CLASS (e_table_model)->duplicate_value)
return ETM_CLASS (e_table_model)->duplicate_value (e_table_model, col, value);
else
return NULL;
}
void
e_table_model_free_value (ETableModel *e_table_model, int col, void *value)
{
g_return_if_fail (e_table_model != NULL);
g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
if (ETM_CLASS (e_table_model)->free_value)
ETM_CLASS (e_table_model)->free_value (e_table_model, col, value);
}
static void
e_table_model_destroy (GtkObject *object)
{
@ -121,27 +146,30 @@ e_table_model_class_init (GtkObjectClass *object_class)
gtk_object_class_add_signals (object_class, e_table_model_signals, LAST_SIGNAL);
}
GtkType
guint
e_table_model_get_type (void)
{
static GtkType type = 0;
static guint type = 0;
if (!type){
GtkTypeInfo info = {
"ETableModel",
sizeof (ETableModel),
sizeof (ETableModelClass),
(GtkClassInitFunc) e_table_model_class_init,
(GtkObjectInitFunc) NULL,
NULL, /* reserved 1 */
NULL, /* reserved 2 */
(GtkClassInitFunc) NULL
};
if (!type)
{
GtkTypeInfo info =
{
"ETableModle",
sizeof (ETableModel),
sizeof (ETableModelClass),
(GtkClassInitFunc) e_table_model_class_init,
NULL,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL,
};
type = gtk_type_unique (gtk_object_get_type (), &info);
}
type = gtk_type_unique (gtk_object_get_type(), &info);
}
return type;
return type;
}
void

View File

@ -27,6 +27,10 @@ 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 *(*duplicate_value) (ETableModel *etm, int col, const void *value);
void (*free_value) (ETableModel *etm, int col, void *value);
void (*thaw) (ETableModel *etm);
/*
* Signals
@ -48,9 +52,12 @@ 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);
void *e_table_model_value_at (ETableModel *e_table_model, int col, int row);
void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, const void *data);
void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, const void *value);
gboolean e_table_model_is_cell_editable (ETableModel *e_table_model, int col, int row);
void *e_table_model_duplicate_value (ETableModel *e_table_model, int col, const void *value);
void e_table_model_free_value (ETableModel *e_table_model, int col, void *value);
void e_table_model_freeze (ETableModel *e_table_model);
void e_table_model_thaw (ETableModel *e_table_model);

View File

@ -55,6 +55,22 @@ simple_is_cell_editable (ETableModel *etm, int col, int row)
return simple->is_cell_editable (etm, col, row, simple->data);
}
static void *
simple_duplicate_value (ETableModel *etm, int col, const void *value)
{
ETableSimple *simple = (ETableSimple *)etm;
return simple->duplicate_value (etm, col, value, simple->data);
}
static void
simple_free_value (ETableModel *etm, int col, void *value)
{
ETableSimple *simple = (ETableSimple *)etm;
simple->free_value (etm, col, value, simple->data);
}
static void
simple_thaw (ETableModel *etm)
{
@ -73,6 +89,8 @@ 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->duplicate_value = simple_duplicate_value;
model_class->free_value = simple_free_value;
model_class->thaw = simple_thaw;
}
@ -105,6 +123,8 @@ e_table_simple_new (ETableSimpleColumnCountFn col_count,
ETableSimpleValueAtFn value_at,
ETableSimpleSetValueAtFn set_value_at,
ETableSimpleIsCellEditableFn is_cell_editable,
ETableSimpleDuplicateValueFn duplicate_value,
ETableSimpleFreeValueFn free_value,
ETableSimpleThawFn thaw,
void *data)
{
@ -118,6 +138,8 @@ e_table_simple_new (ETableSimpleColumnCountFn col_count,
et->set_value_at = set_value_at;
et->is_cell_editable = is_cell_editable;
et->thaw = thaw;
et->duplicate_value = duplicate_value;
et->free_value = free_value;
et->data = data;
return (ETableModel *) et;

View File

@ -9,6 +9,8 @@ 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 *(*ETableSimpleDuplicateValueFn) (ETableModel *etm, int col, const void *val, void *data);
typedef void (*ETableSimpleFreeValueFn) (ETableModel *etm, int col, void *val, void *data);
typedef void (*ETableSimpleThawFn) (ETableModel *etm, void *data);
typedef struct {
@ -19,6 +21,8 @@ typedef struct {
ETableSimpleValueAtFn value_at;
ETableSimpleSetValueAtFn set_value_at;
ETableSimpleIsCellEditableFn is_cell_editable;
ETableSimpleDuplicateValueFn duplicate_value;
ETableSimpleFreeValueFn free_value;
ETableSimpleThawFn thaw;
void *data;
} ETableSimple;
@ -34,6 +38,8 @@ ETableModel *e_table_simple_new (ETableSimpleColumnCountFn col_count,
ETableSimpleValueAtFn value_at,
ETableSimpleSetValueAtFn set_value_at,
ETableSimpleIsCellEditableFn is_cell_editable,
ETableSimpleDuplicateValueFn duplicate_value,
ETableSimpleFreeValueFn free_value,
ETableSimpleThawFn thaw,
void *data);

View File

@ -0,0 +1,148 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* E-table-sorted.c: Implements a table that sorts 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-sorted-variable.h"
#define PARENT_TYPE E_TABLE_SUBSET_VARIABLE_TYPE
#define INCREMENT_AMOUNT 10
static ETableSubsetVariableClass *etsv_parent_class;
static void etsv_proxy_model_changed (ETableModel *etm, ETableSortedVariable *etsv);
static void etsv_proxy_model_row_changed (ETableModel *etm, int row, ETableSortedVariable *etsv);
static void etsv_proxy_model_cell_changed (ETableModel *etm, int col, int row, ETableSortedVariable *etsv);
static void etsv_add (ETableSubsetVariable *etssv, gint row);
static void
etsv_destroy (GtkObject *object)
{
ETableSortedVariable *etsv = E_TABLE_SORTED_VARIABLE (object);
ETableSubset *etss = E_TABLE_SUBSET (object);
gtk_signal_disconnect (GTK_OBJECT (etss->source),
etsv->table_model_changed_id);
gtk_signal_disconnect (GTK_OBJECT (etss->source),
etsv->table_model_row_changed_id);
gtk_signal_disconnect (GTK_OBJECT (etss->source),
etsv->table_model_cell_changed_id);
etsv->table_model_changed_id = 0;
etsv->table_model_row_changed_id = 0;
etsv->table_model_cell_changed_id = 0;
GTK_OBJECT_CLASS (etsv_parent_class)->destroy (object);
}
static void
etsv_class_init (GtkObjectClass *object_class)
{
ETableSubsetVariableClass *etssv_class = E_TABLE_SUBSET_VARIABLE_CLASS(object_class);
etsv_parent_class = gtk_type_class (PARENT_TYPE);
object_class->destroy = etsv_destroy;
etssv_class->add = etsv_add;
}
E_MAKE_TYPE(e_table_sorted_variable, "ETableSortedVariable", ETableSortedVariable, etsv_class_init, NULL, PARENT_TYPE);
static void
etsv_add (ETableSubsetVariable *etssv,
gint row)
{
ETableModel *etm = E_TABLE_MODEL(etssv);
ETableSubset *etss = E_TABLE_SUBSET(etssv);
ETableSortedVariable *etsv = E_TABLE_SORTED_VARIABLE(etssv);
int i;
int col = etsv->sort_col;
GCompareFunc comp = etsv->compare;
gint ascending = etsv->ascending;
void *val = e_table_model_value_at(etss->source, col, row);
/* FIXME: binary search anyone? */
for ( i = 0; i < etss->n_map; i++ ) {
int comp_val = (*comp)(val, e_table_model_value_at(etss->source, col, etss->map_table[i]));
if ( (ascending && comp_val < 0) || ((!ascending) && comp_val > 0) )
break;
}
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));
etssv->n_vals_allocated += INCREMENT_AMOUNT;
}
if ( i < etss->n_map )
memmove(etss->map_table + i + 1, etss->map_table + i, (etss->n_map - i) * sizeof(int));
etss->map_table[i] = row;
etss->n_map++;
if ( !etm->frozen )
e_table_model_changed(etm);
}
ETableModel *
e_table_sorted_variable_new (ETableModel *source, int col, int ascending, GCompareFunc compare)
{
ETableSortedVariable *etsv = gtk_type_new (E_TABLE_SORTED_VARIABLE_TYPE);
ETableSubsetVariable *etssv = E_TABLE_SUBSET_VARIABLE (etsv);
if (e_table_subset_variable_construct (etssv, source) == NULL){
gtk_object_destroy (GTK_OBJECT (etsv));
return NULL;
}
etsv->sort_col = col;
etsv->ascending = ascending;
etsv->compare = compare;
etsv->table_model_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_changed",
GTK_SIGNAL_FUNC (etsv_proxy_model_changed), etsv);
etsv->table_model_row_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_row_changed",
GTK_SIGNAL_FUNC (etsv_proxy_model_row_changed), etsv);
etsv->table_model_cell_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_cell_changed",
GTK_SIGNAL_FUNC (etsv_proxy_model_cell_changed), etsv);
return E_TABLE_MODEL(etsv);
}
static void
etsv_proxy_model_changed (ETableModel *etm, ETableSortedVariable *etsv)
{
if ( !E_TABLE_MODEL(etsv)->frozen ) {
/* FIXME: do_resort(); */
}
}
static void
etsv_proxy_model_row_changed (ETableModel *etm, int row, ETableSortedVariable *etsv)
{
ETableSubsetVariable *etssv = E_TABLE_SUBSET_VARIABLE(etsv);
if ( !E_TABLE_MODEL(etsv)->frozen ) {
if(e_table_subset_variable_remove(etssv, row))
e_table_subset_variable_add(etssv, row);
}
}
static void
etsv_proxy_model_cell_changed (ETableModel *etm, int col, int row, ETableSortedVariable *etsv)
{
ETableSubsetVariable *etssv = E_TABLE_SUBSET_VARIABLE(etsv);
if ( !E_TABLE_MODEL(etsv)->frozen ) {
if ( col == etsv->sort_col ) {
if(e_table_subset_variable_remove(etssv, row))
e_table_subset_variable_add(etssv, row);
}
}
}

View File

@ -0,0 +1,34 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#ifndef _E_TABLE_SORTED_VARIABLE_H_
#define _E_TABLE_SORTED_VARIABLE_H_
#include <gtk/gtkobject.h>
#include "e-table-model.h"
#include "e-table-subset-variable.h"
#define E_TABLE_SORTED_VARIABLE_TYPE (e_table_sorted_variable_get_type ())
#define E_TABLE_SORTED_VARIABLE(o) (GTK_CHECK_CAST ((o), E_TABLE_SORTED_VARIABLE_TYPE, ETableSortedVariable))
#define E_TABLE_SORTED_VARIABLE_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_SORTED_VARIABLE_TYPE, ETableSortedVariableClass))
#define E_IS_TABLE_SORTED_VARIABLE(o) (GTK_CHECK_TYPE ((o), E_TABLE_SORTED_VARIABLE_TYPE))
#define E_IS_TABLE_SORTED_VARIABLE_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_SORTED_VARIABLE_TYPE))
typedef struct {
ETableSubsetVariable base;
short sort_col;
int ascending;
GCompareFunc compare;
int table_model_changed_id;
int table_model_row_changed_id;
int table_model_cell_changed_id;
} ETableSortedVariable;
typedef struct {
ETableSubsetVariableClass parent_class;
} ETableSortedVariableClass;
GtkType e_table_sorted_variable_get_type (void);
ETableModel *e_table_sorted_variable_new (ETableModel *etm, int col, int ascending, GCompareFunc compare);
#endif /* _E_TABLE_SORTED_VARIABLE_H_ */

View File

@ -13,7 +13,7 @@
#define PARENT_TYPE E_TABLE_SUBSET_TYPE
static ETableModelClass *ets_parent_class;
static ETableSubsetClass *ets_parent_class;
static void
ets_class_init (GtkObjectClass *klass)

View File

@ -14,16 +14,58 @@
#include "e-util/e-util.h"
#include "e-table-subset-variable.h"
#define ETSSV_CLASS(e) ((ETableSubsetVariableClass *)((GtkObject *)e)->klass)
#define PARENT_TYPE E_TABLE_SUBSET_TYPE
#define INCREMENT_AMOUNT 10
static ETableModelClass *etssv_parent_class;
static ETableSubsetClass *etssv_parent_class;
static void
etssv_class_init (GtkObjectClass *klass)
etssv_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));
etssv->n_vals_allocated += INCREMENT_AMOUNT;
}
etss->map_table[etss->n_map++] = row;
if ( !etm->frozen )
e_table_model_changed(etm);
}
static gboolean
etssv_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;
}
static void
etssv_class_init (GtkObjectClass *object_class)
{
ETableSubsetVariableClass *klass = E_TABLE_SUBSET_VARIABLE_CLASS(object_class);
etssv_parent_class = gtk_type_class (PARENT_TYPE);
klass->add = etssv_add;
klass->remove = etssv_remove;
}
E_MAKE_TYPE(e_table_subset_variable, "ETableSubsetVariable", ETableSubsetVariable, etssv_class_init, NULL, PARENT_TYPE);
@ -56,34 +98,24 @@ 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);
g_return_if_fail (etssv != NULL);
g_return_if_fail (E_IS_TABLE_SUBSET_VARIABLE(etssv));
if (ETSSV_CLASS(etssv)->add)
ETSSV_CLASS (etssv)->add (etssv, row);
}
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;
g_return_val_if_fail (etssv != NULL, FALSE);
g_return_val_if_fail (E_IS_TABLE_SUBSET_VARIABLE(etssv), FALSE);
if (ETSSV_CLASS(etssv)->remove)
return ETSSV_CLASS (etssv)->remove (etssv, row);
else
return FALSE;
}
void

View File

@ -19,6 +19,11 @@ typedef struct {
typedef struct {
ETableSubsetClass parent_class;
void (*add) (ETableSubsetVariable *ets,
gint row);
gboolean (*remove) (ETableSubsetVariable *ets,
gint row);
} ETableSubsetVariableClass;
GtkType e_table_subset_variable_get_type (void);

View File

@ -25,6 +25,17 @@ etss_destroy (GtkObject *object)
if (etss->source)
gtk_object_unref (GTK_OBJECT (etss->source));
gtk_signal_disconnect (GTK_OBJECT (etss->source),
etss->table_model_changed_id);
gtk_signal_disconnect (GTK_OBJECT (etss->source),
etss->table_model_row_changed_id);
gtk_signal_disconnect (GTK_OBJECT (etss->source),
etss->table_model_cell_changed_id);
etss->table_model_changed_id = 0;
etss->table_model_row_changed_id = 0;
etss->table_model_cell_changed_id = 0;
if (etss->map_table)
free (etss->map_table);
@ -71,6 +82,22 @@ etss_is_cell_editable (ETableModel *etm, int col, int row)
return e_table_model_is_cell_editable (etss->source, col, etss->map_table [row]);
}
static void *
etss_duplicate_value (ETableModel *etm, int col, const void *value)
{
ETableSubset *etss = (ETableSubset *)etm;
return e_table_model_duplicate_value (etss->source, col, value);
}
static void
etss_free_value (ETableModel *etm, int col, void *value)
{
ETableSubset *etss = (ETableSubset *)etm;
e_table_model_free_value (etss->source, col, value);
}
static void
etss_thaw (ETableModel *etm)
{
@ -91,6 +118,8 @@ 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->duplicate_value = etss_duplicate_value;
table_class->free_value = etss_free_value;
table_class->thaw = etss_thaw;
}
@ -155,12 +184,12 @@ e_table_subset_construct (ETableSubset *etss, ETableModel *source, int nvals)
for (i = 0; i < nvals; i++)
etss->map_table [i] = i;
gtk_signal_connect (GTK_OBJECT (source), "model_changed",
GTK_SIGNAL_FUNC (etss_proxy_model_changed), etss);
gtk_signal_connect (GTK_OBJECT (source), "model_row_changed",
GTK_SIGNAL_FUNC (etss_proxy_model_row_changed), etss);
gtk_signal_connect (GTK_OBJECT (source), "model_cell_changed",
GTK_SIGNAL_FUNC (etss_proxy_model_cell_changed), etss);
etss->table_model_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_changed",
GTK_SIGNAL_FUNC (etss_proxy_model_changed), etss);
etss->table_model_row_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_row_changed",
GTK_SIGNAL_FUNC (etss_proxy_model_row_changed), etss);
etss->table_model_cell_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_cell_changed",
GTK_SIGNAL_FUNC (etss_proxy_model_cell_changed), etss);
return E_TABLE_MODEL (etss);
}

View File

@ -17,6 +17,10 @@ typedef struct {
ETableModel *source;
int n_map;
int *map_table;
int table_model_changed_id;
int table_model_row_changed_id;
int table_model_cell_changed_id;
} ETableSubset;
typedef struct {

View File

@ -34,6 +34,8 @@
static GtkObjectClass *e_table_parent_class;
static void e_table_fill_table (ETable *e_table, ETableModel *model);
static void
et_destroy (GtkObject *object)
{
@ -42,6 +44,20 @@ et_destroy (GtkObject *object)
gtk_object_unref (GTK_OBJECT (et->model));
gtk_object_unref (GTK_OBJECT (et->full_header));
gtk_object_unref (GTK_OBJECT (et->header));
gtk_widget_destroy (GTK_WIDGET (et->header_canvas));
gtk_widget_destroy (GTK_WIDGET (et->table_canvas));
gtk_signal_disconnect (GTK_OBJECT (et->model),
et->table_model_change_id);
gtk_signal_disconnect (GTK_OBJECT (et->model),
et->table_row_change_id);
gtk_signal_disconnect (GTK_OBJECT (et->model),
et->table_cell_change_id);
if (et->rebuild_idle_id) {
g_source_remove(et->rebuild_idle_id);
et->rebuild_idle_id = 0;
}
(*e_table_parent_class->destroy)(object);
}
@ -54,6 +70,11 @@ e_table_init (GtkObject *object)
e_table->draw_grid = 1;
e_table->draw_focus = 1;
e_table->spreadsheet = 1;
e_table->need_rebuild = 0;
e_table->need_row_changes = 0;
e_table->row_changes_list = NULL;
e_table->rebuild_idle_id = 0;
}
static ETableHeader *
@ -527,6 +548,72 @@ table_canvas_size_allocate (GtkWidget *widget, GtkAllocation *alloc, ETable *e_t
NULL);
}
static void
change_row (gpointer key, gpointer value, gpointer data)
{
ETable *et = E_TABLE(data);
gint row = GPOINTER_TO_INT(key);
if ( e_table_group_remove(et->group, row) ) {
e_table_group_add(et->group, row);
}
}
static gboolean
changed_idle (gpointer data)
{
ETable *et = E_TABLE(data);
if ( et->need_rebuild ) {
gtk_object_destroy( GTK_OBJECT(et->group ) );
et->group = e_table_group_new(GNOME_CANVAS_GROUP(et->table_canvas->root),
et->full_header,
et->header,
et->model,
e_xml_get_child_by_name(xmlDocGetRootElement(et->specification), "grouping")->childs);
e_table_fill_table(et, et->model);
} else if (et->need_row_changes) {
g_hash_table_foreach(et->row_changes_list, change_row, et);
}
et->need_rebuild = 0;
et->need_row_changes = 0;
if (et->row_changes_list)
g_hash_table_destroy(et->row_changes_list);
et->row_changes_list = NULL;
et->rebuild_idle_id = 0;
return FALSE;
}
static void
et_table_model_changed (ETableModel *model, ETable *et)
{
et->need_rebuild = TRUE;
if ( !et->rebuild_idle_id ) {
et->rebuild_idle_id = g_idle_add(changed_idle, et);
}
}
static void
et_table_row_changed (ETableModel *table_model, int row, ETable *et)
{
if ( !et->need_rebuild ) {
if (!et->need_row_changes) {
et->need_row_changes = 1;
et->row_changes_list = g_hash_table_new (g_direct_hash, g_direct_equal);
}
if (!g_hash_table_lookup(et->row_changes_list, GINT_TO_POINTER(row))) {
g_hash_table_insert(et->row_changes_list, GINT_TO_POINTER(row), GINT_TO_POINTER(row + 1));
}
}
if ( !et->rebuild_idle_id ) {
et->rebuild_idle_id = g_idle_add(changed_idle, et);
}
}
static void
et_table_cell_changed (ETableModel *table_model, int view_col, int row, ETable *et)
{
et_table_row_changed(table_model, row, et);
}
static void
e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *header, ETableModel *model, xmlNode *xml_grouping)
{
@ -546,6 +633,17 @@ e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *h
model,
xml_grouping->childs);
e_table->table_model_change_id = gtk_signal_connect (
GTK_OBJECT (model), "model_changed",
GTK_SIGNAL_FUNC (et_table_model_changed), e_table);
e_table->table_row_change_id = gtk_signal_connect (
GTK_OBJECT (model), "model_row_changed",
GTK_SIGNAL_FUNC (et_table_row_changed), e_table);
e_table->table_cell_change_id = gtk_signal_connect (
GTK_OBJECT (model), "model_cell_changed",
GTK_SIGNAL_FUNC (et_table_cell_changed), e_table);
}
static void

View File

@ -26,6 +26,10 @@ typedef struct {
ETableGroup *group;
int table_model_change_id;
int table_row_change_id;
int table_cell_change_id;
GnomeCanvas *header_canvas, *table_canvas;
GnomeCanvasItem *header_item, *root;
@ -35,6 +39,12 @@ typedef struct {
guint draw_grid:1;
guint draw_focus:1;
guint spreadsheet:1;
guint need_rebuild:1;
guint need_row_changes:1;
GHashTable *row_changes_list;
gint rebuild_idle_id;
} ETable;
typedef struct {

View File

@ -14,6 +14,7 @@
#include "e-table-item.h"
#include "e-util/e-cursors.h"
#include "e-util/e-canvas-utils.h"
#include "e-util/e-util.h"
#include "e-cell-text.h"
#include "e-cell-checkbox.h"
@ -79,6 +80,24 @@ is_cell_editable (ETableModel *etc, int col, int row, void *data)
return TRUE;
}
static void *
duplicate_value (ETableModel *etc, int col, const void *value, void *data)
{
if (col == 0){
return (void *) value;
} else {
return g_strdup(value);
}
}
static void
free_value (ETableModel *etc, int col, void *value, void *data)
{
if (col != 0){
g_free(value);
}
}
static void
thaw (ETableModel *etc, void *data)
{
@ -107,7 +126,8 @@ check_test (void)
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
set_value_at, is_cell_editable, thaw, NULL);
set_value_at, is_cell_editable,
duplicate_value, free_value, thaw, NULL);
/*
* Header
@ -118,11 +138,11 @@ check_test (void)
cell_image_check = e_cell_checkbox_new ();
pixbuf = gdk_pixbuf_new_from_file("clip.png");
col_0 = e_table_col_new_with_pixbuf (0, pixbuf, 18, 18, cell_image_check, g_int_equal, TRUE);
col_0 = e_table_col_new_with_pixbuf (0, pixbuf, 18, 18, cell_image_check, g_int_compare, TRUE);
gdk_pixbuf_unref(pixbuf);
e_table_header_add_column (e_table_header, col_0, 0);
col_1 = e_table_col_new (1, "Item Name", 180, 20, cell_left_just, g_str_equal, TRUE);
col_1 = e_table_col_new (1, "Item Name", 180, 20, cell_left_just, g_str_compare, TRUE);
e_table_header_add_column (e_table_header, col_1, 1);
e_table_col_set_arrow ( col_1, E_TABLE_COL_ARROW_DOWN );

View File

@ -10,6 +10,7 @@
#include <gnome.h>
#include "e-util/e-canvas-utils.h"
#include "e-util/e-cursors.h"
#include "e-util/e-util.h"
#include "e-table-simple.h"
#include "e-table-header.h"
#include "e-table-header-item.h"
@ -79,6 +80,24 @@ is_cell_editable (ETableModel *etc, int col, int row, void *data)
return TRUE;
}
static void *
duplicate_value (ETableModel *etc, int col, const void *value, void *data)
{
if (col == 0){
return (void *)value;
} else {
return g_strdup(value);
}
}
static void
free_value (ETableModel *etc, int col, void *value, void *data)
{
if (col != 0){
g_free(value);
}
}
static void
set_canvas_size (GnomeCanvas *canvas, GtkAllocation *alloc)
{
@ -106,7 +125,9 @@ multi_cols_test (void)
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
set_value_at, is_cell_editable, thaw, NULL);
set_value_at, is_cell_editable,
duplicate_value, free_value,
thaw, NULL);
/*
* Header
@ -131,10 +152,10 @@ multi_cols_test (void)
g_free (images);
}
col_1 = e_table_col_new (1, "Item Name", 180, 20, cell_left_just, g_str_equal, TRUE);
col_1 = e_table_col_new (1, "Item Name", 180, 20, cell_left_just, g_str_compare, TRUE);
e_table_header_add_column (e_table_header, col_1, 0);
col_0 = e_table_col_new (0, "A", 48, 48, cell_image_toggle, g_int_equal, TRUE);
col_0 = e_table_col_new (0, "A", 48, 48, cell_image_toggle, g_int_compare, TRUE);
e_table_header_add_column (e_table_header, col_0, 1);
/*

View File

@ -176,6 +176,18 @@ is_cell_editable (ETableModel *etc, int col, int row, void *data)
return TRUE;
}
static void *
duplicate_value (ETableModel *etc, int col, const void *value, void *data)
{
return g_strdup(value);
}
static void
free_value (ETableModel *etc, int col, void *value, void *data)
{
g_free(value);
}
static void
thaw (ETableModel *etc, void *data)
{
@ -205,7 +217,8 @@ table_browser_test (void)
*/
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
set_value_at, is_cell_editable, thaw, NULL);
set_value_at, is_cell_editable,
duplicate_value, free_value, thaw, NULL);
/*
* Header
@ -217,7 +230,7 @@ table_browser_test (void)
ETableCol *ecol = e_table_col_new (
i, column_labels [i],
80, 20, cell_left_just,
g_str_equal, TRUE);
g_str_compare, TRUE);
e_table_header_add_column (e_table_header, ecol, i);
}
@ -263,7 +276,6 @@ static void
do_e_table_demo (const char *spec)
{
GtkWidget *e_table, *window, *frame;
ETableModel *e_table_model;
ECell *cell_left_just;
ETableHeader *full_header;
int i;
@ -271,9 +283,14 @@ do_e_table_demo (const char *spec)
/*
* Data model
*/
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
set_value_at, is_cell_editable, thaw, NULL);
static ETableModel *e_table_model = NULL;
if ( e_table_model == NULL )
e_table_model =
e_table_simple_new (col_count, row_count, value_at,
set_value_at, is_cell_editable,
duplicate_value, free_value,
thaw, NULL);
full_header = e_table_header_new ();
cell_left_just = e_cell_text_new (e_table_model, NULL, GTK_JUSTIFY_LEFT, TRUE);
@ -282,7 +299,7 @@ do_e_table_demo (const char *spec)
ETableCol *ecol = e_table_col_new (
i, column_labels [i],
80, 20, cell_left_just,
g_str_equal, TRUE);
g_str_compare, TRUE);
e_table_header_add_column (full_header, ecol, i);
}
@ -306,9 +323,9 @@ e_table_test (void)
load_data ();
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 ("<ETableSpecification> <columns-shown> <column> 0 </column> <column> 1 </column> <column> 2 </column> <column> 3 </column> <column> 4 </column> </columns-shown> <grouping> <leaf column=\"3\" ascending=\"1\"/> </grouping> </ETableSpecification>");
do_e_table_demo ("<ETableSpecification> <columns-shown> <column> 0 </column> <column> 0 </column> <column> 1 </column> <column> 2 </column> <column> 3 </column> <column> 4 </column> </columns-shown> <grouping> <group column=\"3\" ascending=\"1\"> <group column=\"4\" ascending=\"0\"> <leaf column=\"2\" ascending=\"1\"/> </group> </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=\"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>");
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\" ascending=\"1\"> <leaf column=\"2\" ascending=\"1\"/> </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\" ascending=\"1\"> <leaf column=\"2\" ascending=\"1\"/> </group> </grouping> </ETableSpecification>");
}