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
297 lines
7.5 KiB
C
297 lines
7.5 KiB
C
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
|
/*
|
|
* E-Table-Group.c: Implements the grouping objects for elements on a table
|
|
*
|
|
* Author:
|
|
* Miguel de Icaza (miguel@gnu.org()
|
|
*
|
|
* Copyright 1999, Helix Code, Inc.
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include <gtk/gtksignal.h>
|
|
#include "e-table-group-leaf.h"
|
|
#include "e-table-item.h"
|
|
#include <libgnomeui/gnome-canvas-rect-ellipse.h>
|
|
#include "e-util/e-util.h"
|
|
|
|
#define TITLE_HEIGHT 16
|
|
#define GROUP_INDENT 10
|
|
|
|
#define PARENT_TYPE e_table_group_get_type ()
|
|
|
|
static GnomeCanvasGroupClass *etgl_parent_class;
|
|
|
|
/* The arguments we take */
|
|
enum {
|
|
ARG_0,
|
|
ARG_HEIGHT,
|
|
ARG_WIDTH,
|
|
ARG_FROZEN
|
|
};
|
|
|
|
static void etgl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
|
|
static void etgl_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
|
|
|
|
static void
|
|
etgl_destroy (GtkObject *object)
|
|
{
|
|
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,
|
|
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);
|
|
}
|
|
|
|
ETableGroup *
|
|
e_table_group_leaf_new (GnomeCanvasGroup *parent, ETableHeader *full_header,
|
|
ETableHeader *header,
|
|
ETableModel *model,
|
|
int col,
|
|
int ascending)
|
|
{
|
|
ETableGroupLeaf *etgl;
|
|
|
|
g_return_val_if_fail (parent != NULL, NULL);
|
|
|
|
etgl = gtk_type_new (e_table_group_leaf_get_type ());
|
|
|
|
e_table_group_leaf_construct (parent, etgl, full_header,
|
|
header, model, col, ascending);
|
|
return E_TABLE_GROUP (etgl);
|
|
}
|
|
|
|
static void
|
|
etgl_resize (GtkObject *object, gpointer data)
|
|
{
|
|
e_table_group_resize (E_TABLE_GROUP(data));
|
|
}
|
|
|
|
static void
|
|
etgl_realize (GnomeCanvasItem *item)
|
|
{
|
|
ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF(item);
|
|
gdouble height;
|
|
|
|
if ( GNOME_CANVAS_ITEM_CLASS (etgl_parent_class)->realize )
|
|
GNOME_CANVAS_ITEM_CLASS (etgl_parent_class)->realize (item);
|
|
|
|
etgl->item = E_TABLE_ITEM(gnome_canvas_item_new(GNOME_CANVAS_GROUP(etgl),
|
|
e_table_item_get_type (),
|
|
"ETableHeader", E_TABLE_GROUP(etgl)->header,
|
|
"ETableModel", etgl->subset,
|
|
"drawgrid", TRUE,
|
|
"drawfocus", TRUE,
|
|
"spreadsheet", TRUE,
|
|
"width", etgl->width,
|
|
NULL));
|
|
gtk_signal_connect(GTK_OBJECT(etgl->item),
|
|
"resize", etgl_resize, etgl);
|
|
gtk_object_get(GTK_OBJECT(etgl->item),
|
|
"height", &height,
|
|
NULL);
|
|
if ( height != 1 )
|
|
e_table_group_resize(E_TABLE_GROUP(etgl));
|
|
}
|
|
|
|
static int
|
|
etgl_event (GnomeCanvasItem *item, GdkEvent *event)
|
|
{
|
|
gboolean return_val = TRUE;
|
|
|
|
switch (event->type) {
|
|
|
|
default:
|
|
return_val = FALSE;
|
|
}
|
|
if ( return_val == FALSE ) {
|
|
if ( GNOME_CANVAS_ITEM_CLASS(etgl_parent_class)->event )
|
|
return GNOME_CANVAS_ITEM_CLASS(etgl_parent_class)->event(item, event);
|
|
}
|
|
return return_val;
|
|
|
|
}
|
|
|
|
static void
|
|
etgl_add (ETableGroup *etg, gint row)
|
|
{
|
|
ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
|
|
e_table_subset_variable_add(etgl->subset, row);
|
|
}
|
|
|
|
static gboolean
|
|
etgl_remove (ETableGroup *etg, gint row)
|
|
{
|
|
ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
|
|
return e_table_subset_variable_remove(etgl->subset, row);
|
|
}
|
|
|
|
static void
|
|
etgl_increment (ETableGroup *etg, gint position, gint amount)
|
|
{
|
|
ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
|
|
e_table_subset_variable_increment(etgl->subset, position, amount);
|
|
}
|
|
|
|
static void
|
|
etgl_set_focus (ETableGroup *etg, EFocus direction, gint view_col)
|
|
{
|
|
ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
|
|
if (direction == E_FOCUS_END) {
|
|
e_table_item_focus(etgl->item, view_col, e_table_model_row_count(E_TABLE_MODEL(etgl->subset)) - 1);
|
|
} else {
|
|
e_table_item_focus(etgl->item, view_col, 0);
|
|
}
|
|
}
|
|
|
|
static gint
|
|
etgl_get_focus_column (ETableGroup *etg)
|
|
{
|
|
ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
|
|
return e_table_item_get_focused_column(etgl->item);
|
|
}
|
|
|
|
static void
|
|
etgl_set_width (ETableGroup *etg, gdouble width)
|
|
{
|
|
ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
|
|
etgl->width = width;
|
|
#if 0
|
|
if ( etgl->item ) {
|
|
gnome_canvas_item_set(GNOME_CANVAS_ITEM(etgl->item),
|
|
"width", width,
|
|
NULL);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
static gdouble
|
|
etgl_get_width (ETableGroup *etg)
|
|
{
|
|
ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
|
|
gtk_object_get(GTK_OBJECT(etgl->item),
|
|
"width", &etgl->width,
|
|
NULL);
|
|
return etgl->width;
|
|
}
|
|
|
|
static gdouble
|
|
etgl_get_height (ETableGroup *etg)
|
|
{
|
|
ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
|
|
gdouble height;
|
|
if ( etgl->item )
|
|
gtk_object_get(GTK_OBJECT(etgl->item),
|
|
"height", &height,
|
|
NULL);
|
|
else
|
|
height = 1;
|
|
return height;
|
|
}
|
|
|
|
static void
|
|
etgl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
|
{
|
|
ETableGroup *etg = E_TABLE_GROUP (object);
|
|
|
|
switch (arg_id) {
|
|
case ARG_FROZEN:
|
|
if ( GTK_VALUE_BOOL (*arg) )
|
|
etg->frozen = TRUE;
|
|
else {
|
|
etg->frozen = FALSE;
|
|
}
|
|
break;
|
|
case ARG_WIDTH:
|
|
if ( E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->set_width )
|
|
E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->set_width(etg, GTK_VALUE_DOUBLE (*arg));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
etgl_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
|
{
|
|
ETableGroup *etg = E_TABLE_GROUP (object);
|
|
|
|
switch (arg_id) {
|
|
case ARG_FROZEN:
|
|
GTK_VALUE_BOOL (*arg) = etg->frozen;
|
|
break;
|
|
case ARG_HEIGHT:
|
|
if ( E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_height )
|
|
GTK_VALUE_DOUBLE (*arg) = E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_height(etg);
|
|
else
|
|
arg->type = GTK_TYPE_INVALID;
|
|
break;
|
|
case ARG_WIDTH:
|
|
if ( E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_width )
|
|
GTK_VALUE_DOUBLE (*arg) = E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_width(etg);
|
|
else
|
|
arg->type = GTK_TYPE_INVALID;
|
|
break;
|
|
default:
|
|
arg->type = GTK_TYPE_INVALID;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
etgl_class_init (GtkObjectClass *object_class)
|
|
{
|
|
GnomeCanvasItemClass *item_class = (GnomeCanvasItemClass *) object_class;
|
|
ETableGroupClass *e_group_class = E_TABLE_GROUP_CLASS( object_class );
|
|
|
|
object_class->destroy = etgl_destroy;
|
|
object_class->set_arg = etgl_set_arg;
|
|
object_class->get_arg = etgl_get_arg;
|
|
|
|
item_class->realize = etgl_realize;
|
|
item_class->event = etgl_event;
|
|
|
|
etgl_parent_class = gtk_type_class (PARENT_TYPE);
|
|
|
|
e_group_class->add = etgl_add;
|
|
e_group_class->remove = etgl_remove;
|
|
e_group_class->increment = etgl_increment;
|
|
e_group_class->set_focus = etgl_set_focus;
|
|
e_group_class->get_focus_column = etgl_get_focus_column;
|
|
|
|
e_group_class->get_width = etgl_get_width;
|
|
e_group_class->set_width = etgl_set_width;
|
|
e_group_class->get_height = etgl_get_height;
|
|
|
|
gtk_object_add_arg_type ("ETableGroupLeaf::height", GTK_TYPE_DOUBLE,
|
|
GTK_ARG_READABLE, ARG_HEIGHT);
|
|
gtk_object_add_arg_type ("ETableGroupLeaf::width", GTK_TYPE_DOUBLE,
|
|
GTK_ARG_READWRITE, ARG_WIDTH);
|
|
gtk_object_add_arg_type ("ETableGroupLeaf::frozen", GTK_TYPE_BOOL,
|
|
GTK_ARG_READWRITE, ARG_FROZEN);
|
|
}
|
|
|
|
static void
|
|
etgl_init (GtkObject *object)
|
|
{
|
|
ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (object);
|
|
|
|
etgl->width = 1;
|
|
etgl->subset = NULL;
|
|
etgl->item = NULL;
|
|
}
|
|
|
|
E_MAKE_TYPE (e_table_group_leaf, "ETableGroupLeaf", ETableGroupLeaf, etgl_class_init, etgl_init, PARENT_TYPE);
|