aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/table
diff options
context:
space:
mode:
Diffstat (limited to 'widgets/table')
-rw-r--r--widgets/table/e-table-group-container.c38
-rw-r--r--widgets/table/e-table-group-container.h7
-rw-r--r--widgets/table/e-table-group-leaf.c10
-rw-r--r--widgets/table/e-table-group-leaf.h3
-rw-r--r--widgets/table/e-table-group.c23
-rw-r--r--widgets/table/e-table-group.h5
-rw-r--r--widgets/table/e-table-header-item.c127
-rw-r--r--widgets/table/e-table-header-item.h2
-rw-r--r--widgets/table/e-table-sort-info.c198
-rw-r--r--widgets/table/e-table-sort-info.h43
-rw-r--r--widgets/table/e-table-sorted-variable.c50
-rw-r--r--widgets/table/e-table-sorted-variable.h10
-rw-r--r--widgets/table/e-table.c59
-rw-r--r--widgets/table/e-table.h1
-rw-r--r--widgets/table/test-cols.c1
-rw-r--r--widgets/table/test-table.c3
16 files changed, 408 insertions, 172 deletions
diff --git a/widgets/table/e-table-group-container.c b/widgets/table/e-table-group-container.c
index d5de4cf847..f660cd01c3 100644
--- a/widgets/table/e-table-group-container.c
+++ b/widgets/table/e-table-group-container.c
@@ -3,7 +3,7 @@
* E-Table-Group.c: Implements the grouping objects for elements on a table
*
* Author:
- * Chris Lahey (clahey@helixcode.com)
+ * Chris Lahey <clahey@helixcode.com>
* Miguel de Icaza (miguel@gnu.org)
*
* Copyright 1999, 2000 Helix Code, Inc.
@@ -88,6 +88,9 @@ etgc_destroy (GtkObject *object)
if (etgc->ecol){
gtk_object_unref (GTK_OBJECT(etgc->ecol));
}
+ if (etgc->sort_info){
+ gtk_object_unref (GTK_OBJECT(etgc->sort_info));
+ }
if (etgc->rect){
gtk_object_destroy (GTK_OBJECT(etgc->rect));
}
@@ -196,13 +199,24 @@ void
e_table_group_container_construct (GnomeCanvasGroup *parent, ETableGroupContainer *etgc,
ETableHeader *full_header,
ETableHeader *header,
- ETableModel *model, ETableCol *ecol, int ascending, xmlNode *child_rules)
+ ETableModel *model, ETableSortInfo *sort_info, int n)
{
+ ETableCol *col;
+ ETableSortColumn column = e_table_sort_info_grouping_get_nth(sort_info, n);
+
+ if (column.column > e_table_header_count (full_header))
+ col = e_table_header_get_columns (full_header)[e_table_header_count (full_header) - 1];
+ else
+ col = e_table_header_get_columns (full_header)[column.column];
+
e_table_group_construct (parent, E_TABLE_GROUP (etgc), full_header, header, model);
- etgc->ecol = ecol;
+ etgc->ecol = col;
gtk_object_ref (GTK_OBJECT(etgc->ecol));
- etgc->child_rules = child_rules;
- etgc->ascending = ascending;
+ etgc->sort_info = sort_info;
+ gtk_object_ref (GTK_OBJECT(etgc->sort_info));
+ etgc->n = n;
+ etgc->ascending = column.ascending;
+
etgc->font = gdk_font_load ("lucidasans-10");
if (!etgc->font){
@@ -252,18 +266,16 @@ 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,
- int ascending, xmlNode *child_rules)
+ ETableModel *model, ETableSortInfo *sort_info, int n)
{
ETableGroupContainer *etgc;
g_return_val_if_fail (parent != NULL, NULL);
- g_return_val_if_fail (ecol != NULL, NULL);
etgc = gtk_type_new (e_table_group_container_get_type ());
e_table_group_container_construct (parent, etgc, full_header, header,
- model, ecol, ascending, child_rules);
+ model, sort_info, n);
return E_TABLE_GROUP (etgc);
}
@@ -581,7 +593,7 @@ etgc_add (ETableGroup *etg, gint row)
"fill_color", "black",
NULL);
child = e_table_group_new (GNOME_CANVAS_GROUP (etgc), etg->full_header,
- etg->header, etg->model, etgc->child_rules);
+ etg->header, etg->model, etgc->sort_info, etgc->n + 1);
gtk_signal_connect (GTK_OBJECT (child), "row_selection",
GTK_SIGNAL_FUNC (child_row_selection), etgc);
child_node->child = child;
@@ -795,8 +807,10 @@ etgc_reflow (GnomeCanvasItem *item, gint flags)
ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(item);
gboolean frozen;
- gtk_object_get (GTK_OBJECT(etgc), "frozen", &frozen, NULL);
-
+ gtk_object_get (GTK_OBJECT(etgc),
+ "frozen", &frozen,
+ NULL);
+
if (frozen){
etgc->idle = 0;
return;
diff --git a/widgets/table/e-table-group-container.h b/widgets/table/e-table-group-container.h
index 4070624456..50424009f2 100644
--- a/widgets/table/e-table-group-container.h
+++ b/widgets/table/e-table-group-container.h
@@ -36,7 +36,8 @@ typedef struct {
gdouble width, height;
- void *child_rules;
+ ETableSortInfo *sort_info;
+ int n;
gint idle;
@@ -51,11 +52,11 @@ typedef struct {
} ETableGroupContainerClass;
ETableGroup *e_table_group_container_new (GnomeCanvasGroup *parent, ETableHeader *full_header, ETableHeader *header,
- ETableModel *model, ETableCol *ecol, int ascending, xmlNode *child_rules);
+ ETableModel *model, ETableSortInfo *sort_info, int n);
void e_table_group_container_construct (GnomeCanvasGroup *parent, ETableGroupContainer *etgc,
ETableHeader *full_header,
ETableHeader *header,
- ETableModel *model, ETableCol *ecol, int ascending, xmlNode *child_rules);
+ ETableModel *model, ETableSortInfo *sort_info, int n);
GtkType e_table_group_container_get_type (void);
diff --git a/widgets/table/e-table-group-leaf.c b/widgets/table/e-table-group-leaf.c
index 0c14129031..dcb606d3b8 100644
--- a/widgets/table/e-table-group-leaf.c
+++ b/widgets/table/e-table-group-leaf.c
@@ -51,10 +51,9 @@ e_table_group_leaf_construct (GnomeCanvasGroup *parent, ETableGroupLeaf *etgl,
ETableHeader *full_header,
ETableHeader *header,
ETableModel *model,
- int col,
- int ascending)
+ ETableSortInfo *sort_info)
{
- etgl->subset = E_TABLE_SUBSET_VARIABLE(e_table_sorted_variable_new (model, col, ascending, e_table_header_get_column(full_header, col)->compare));
+ etgl->subset = E_TABLE_SUBSET_VARIABLE(e_table_sorted_variable_new (model, full_header, sort_info));
e_table_group_construct (parent, E_TABLE_GROUP (etgl), full_header, header, model);
}
@@ -62,8 +61,7 @@ ETableGroup *
e_table_group_leaf_new (GnomeCanvasGroup *parent, ETableHeader *full_header,
ETableHeader *header,
ETableModel *model,
- int col,
- int ascending)
+ ETableSortInfo *sort_info)
{
ETableGroupLeaf *etgl;
@@ -72,7 +70,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, col, ascending);
+ header, model, sort_info);
return E_TABLE_GROUP (etgl);
}
diff --git a/widgets/table/e-table-group-leaf.h b/widgets/table/e-table-group-leaf.h
index 6ffd9066d1..1be5969af4 100644
--- a/widgets/table/e-table-group-leaf.h
+++ b/widgets/table/e-table-group-leaf.h
@@ -34,8 +34,7 @@ ETableGroup *e_table_group_leaf_new (GnomeCanvasGroup *parent,
ETableHeader *full_header,
ETableHeader *header,
ETableModel *model,
- int col,
- int ascending);
+ ETableSortInfo *sort_info);
GtkType e_table_group_leaf_get_type (void);
#endif /* _E_TABLE_GROUP_LEAF_H_ */
diff --git a/widgets/table/e-table-group.c b/widgets/table/e-table-group.c
index 9d4b899dc2..a829d83546 100644
--- a/widgets/table/e-table-group.c
+++ b/widgets/table/e-table-group.c
@@ -15,9 +15,7 @@
#include "e-table-group-leaf.h"
#include "e-table-item.h"
#include <libgnomeui/gnome-canvas-rect-ellipse.h>
-#include <gnome-xml/parser.h>
#include "e-util/e-util.h"
-#include "e-util/e-xml-utils.h"
#define TITLE_HEIGHT 16
#define GROUP_INDENT 10
@@ -84,24 +82,15 @@ e_table_group_new (GnomeCanvasGroup *parent,
ETableHeader *full_header,
ETableHeader *header,
ETableModel *model,
- xmlNode *rules)
+ ETableSortInfo *sort_info,
+ int n)
{
- 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")) {
- ETableCol *col;
- 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);
+
+ if (n < e_table_sort_info_grouping_get_count(sort_info)) {
+ return e_table_group_container_new (parent, full_header, header, model, sort_info, n);
} else {
- return e_table_group_leaf_new (parent, full_header, header, model, column, ascending);
+ return e_table_group_leaf_new (parent, full_header, header, model, sort_info);
}
return NULL;
}
diff --git a/widgets/table/e-table-group.h b/widgets/table/e-table-group.h
index 35b3069b20..877f38cf3f 100644
--- a/widgets/table/e-table-group.h
+++ b/widgets/table/e-table-group.h
@@ -3,9 +3,9 @@
#define _E_TABLE_GROUP_H_
#include <libgnomeui/gnome-canvas.h>
-#include <gnome-xml/tree.h>
#include "e-table-model.h"
#include "e-table-header.h"
+#include "e-table-sort-info.h"
#include "e-util/e-util.h"
#define E_TABLE_GROUP_TYPE (e_table_group_get_type ())
@@ -78,7 +78,8 @@ ETableGroup *e_table_group_new (GnomeCanvasGroup *parent,
ETableHeader *full_header,
ETableHeader *header,
ETableModel *model,
- xmlNode *rules);
+ ETableSortInfo *sort_info,
+ int n);
void e_table_group_construct (GnomeCanvasGroup *parent,
ETableGroup *etg,
ETableHeader *full_header,
diff --git a/widgets/table/e-table-header-item.c b/widgets/table/e-table-header-item.c
index 77ed032999..966ad257ad 100644
--- a/widgets/table/e-table-header-item.c
+++ b/widgets/table/e-table-header-item.c
@@ -79,6 +79,8 @@ ethi_destroy (GtkObject *object){
if (ethi->sort_info){
if (ethi->sort_info_changed_id)
gtk_signal_disconnect (GTK_OBJECT(ethi->sort_info), ethi->sort_info_changed_id);
+ if (ethi->group_info_changed_id)
+ gtk_signal_disconnect (GTK_OBJECT(ethi->sort_info), ethi->group_info_changed_id);
gtk_object_unref (GTK_OBJECT(ethi->sort_info));
}
@@ -210,12 +212,16 @@ ethi_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
if (ethi->sort_info){
if (ethi->sort_info_changed_id)
gtk_signal_disconnect (GTK_OBJECT(ethi->sort_info), ethi->sort_info_changed_id);
+ if (ethi->group_info_changed_id)
+ gtk_signal_disconnect (GTK_OBJECT(ethi->sort_info), ethi->group_info_changed_id);
gtk_object_unref (GTK_OBJECT(ethi->sort_info));
}
ethi->sort_info = GTK_VALUE_POINTER (*arg);
gtk_object_ref (GTK_OBJECT(ethi->sort_info));
ethi->sort_info_changed_id = gtk_signal_connect (GTK_OBJECT(ethi->sort_info), "sort_info_changed",
- GTK_SIGNAL_FUNC(ethi_sort_info_changed), ethi);
+ GTK_SIGNAL_FUNC(ethi_sort_info_changed), ethi);
+ ethi->group_info_changed_id = gtk_signal_connect (GTK_OBJECT(ethi->sort_info), "group_info_changed",
+ GTK_SIGNAL_FUNC(ethi_sort_info_changed), ethi);
break;
}
@@ -603,7 +609,6 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width
int x1, x2;
int col;
GHashTable *arrows = g_hash_table_new (NULL, NULL);
- xmlNode *node;
gint group_indent = 0;
#if 0
@@ -612,24 +617,26 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width
#endif
if (ethi->sort_info) {
- xmlNode *grouping;
- gtk_object_get (GTK_OBJECT(ethi->sort_info),
- "grouping", &grouping,
- NULL);
- for (node = grouping->childs; node && strcmp (node->name, "leaf"); node = node->childs) {
+ int length = e_table_sort_info_grouping_get_count(ethi->sort_info);
+ int i;
+ for (i = 0; i < length; i++) {
+ ETableSortColumn column = e_table_sort_info_grouping_get_nth(ethi->sort_info, i);
group_indent ++;
g_hash_table_insert (arrows,
- (gpointer) e_xml_get_integer_prop_by_name (node, "column"),
- (gpointer) (e_xml_get_integer_prop_by_name (node, "ascending") ?
- E_TABLE_COL_ARROW_DOWN :
- E_TABLE_COL_ARROW_UP));
+ (gpointer) column.column,
+ (gpointer) (column.ascending ?
+ E_TABLE_COL_ARROW_DOWN :
+ E_TABLE_COL_ARROW_UP));
}
- if (node)
+ length = e_table_sort_info_sorting_get_count(ethi->sort_info);
+ for (i = 0; i < length; i++) {
+ ETableSortColumn column = e_table_sort_info_sorting_get_nth(ethi->sort_info, i);
g_hash_table_insert (arrows,
- (gpointer) e_xml_get_integer_prop_by_name (node, "column"),
- (gpointer) (e_xml_get_integer_prop_by_name (node, "ascending") ?
- E_TABLE_COL_ARROW_DOWN :
- E_TABLE_COL_ARROW_UP));
+ (gpointer) column.column,
+ (gpointer) (column.ascending ?
+ E_TABLE_COL_ARROW_DOWN :
+ E_TABLE_COL_ARROW_UP));
+ }
}
ethi->group_indent_width = group_indent * GROUP_INDENT;
@@ -767,8 +774,8 @@ ethi_start_drag (ETableHeaderItem *ethi, GdkEvent *event)
int col_width;
GdkPixmap *pixmap;
GdkGC *gc;
+ int group_indent = 0;
GHashTable *arrows = g_hash_table_new (NULL, NULL);
- xmlNode *node;
ethi->drag_col = ethi_find_col_by_x (ethi, event->motion.x);
if (ethi->drag_col < ethi->eth->frozen_count && ethi->drag_col >= 0){
@@ -780,23 +787,26 @@ ethi_start_drag (ETableHeaderItem *ethi, GdkEvent *event)
if (ethi->sort_info) {
- xmlNode *grouping;
- gtk_object_get (GTK_OBJECT(ethi->sort_info),
- "grouping", &grouping,
- NULL);
- for (node = grouping->childs; node && strcmp (node->name, "leaf"); node = node->childs) {
+ int length = e_table_sort_info_grouping_get_count(ethi->sort_info);
+ int i;
+ for (i = 0; i < length; i++) {
+ ETableSortColumn column = e_table_sort_info_grouping_get_nth(ethi->sort_info, i);
+ group_indent ++;
g_hash_table_insert (arrows,
- (gpointer) e_xml_get_integer_prop_by_name (node, "column"),
- (gpointer) (e_xml_get_integer_prop_by_name (node, "ascending") ?
- E_TABLE_COL_ARROW_DOWN :
- E_TABLE_COL_ARROW_UP));
+ (gpointer) column.column,
+ (gpointer) (column.ascending ?
+ E_TABLE_COL_ARROW_DOWN :
+ E_TABLE_COL_ARROW_UP));
}
- if (node)
+ length = e_table_sort_info_sorting_get_count(ethi->sort_info);
+ for (i = 0; i < length; i++) {
+ ETableSortColumn column = e_table_sort_info_sorting_get_nth(ethi->sort_info, i);
g_hash_table_insert (arrows,
- (gpointer) e_xml_get_integer_prop_by_name (node, "column"),
- (gpointer) (e_xml_get_integer_prop_by_name (node, "ascending") ?
- E_TABLE_COL_ARROW_DOWN :
- E_TABLE_COL_ARROW_UP));
+ (gpointer) column.column,
+ (gpointer) (column.ascending ?
+ E_TABLE_COL_ARROW_DOWN :
+ E_TABLE_COL_ARROW_UP));
+ }
}
list = gtk_target_list_new (ethi_drag_types, ELEMENTS (ethi_drag_types));
@@ -927,36 +937,46 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
} else if (ethi->maybe_drag && ethi->sort_info) {
ETableCol *col;
int model_col;
- xmlNode *node;
- xmlNode *grouping;
-
- gtk_object_get (GTK_OBJECT(ethi->sort_info),
- "grouping", &grouping,
- NULL);
+ int length;
+ int i;
+ int found = FALSE;
col = e_table_header_get_column (ethi->eth, ethi_find_col_by_x (ethi, e->button.x));
model_col = col->col_idx;
- for (node = grouping->childs; node->childs && strcmp (node->name, "leaf"); node = node->childs) {
- if (model_col == e_xml_get_integer_prop_by_name (node, "column")){
- int ascending = e_xml_get_integer_prop_by_name (node, "ascending");
+
+ length = e_table_sort_info_grouping_get_count(ethi->sort_info);
+ for (i = 0; i < length; i++) {
+ ETableSortColumn column = e_table_sort_info_grouping_get_nth(ethi->sort_info, i);
+ if (model_col == column.column){
+ int ascending = column.ascending;
ascending = ! ascending;
- e_xml_set_integer_prop_by_name (node, "ascending", ascending);
+ column.ascending = ascending;
+ e_table_sort_info_grouping_set_nth(ethi->sort_info, i, column);
+ found = 1;
break;
}
}
- if (!node){
- }
- if (node && !strcmp (node->name, "leaf")){
- if (model_col == e_xml_get_integer_prop_by_name (node, "column")){
- int ascending = e_xml_get_integer_prop_by_name (node, "ascending");
- ascending = ! ascending;
- e_xml_set_integer_prop_by_name (node, "ascending", ascending);
- } else {
- e_xml_set_integer_prop_by_name (node, "ascending", 1);
- e_xml_set_integer_prop_by_name (node, "column", model_col);
+ if (!found) {
+ length = e_table_sort_info_sorting_get_count(ethi->sort_info);
+ for (i = 0; i < length; i++) {
+ ETableSortColumn column = e_table_sort_info_sorting_get_nth(ethi->sort_info, i);
+ if (model_col == column.column){
+ int ascending = column.ascending;
+ ascending = ! ascending;
+ column.ascending = ascending;
+ e_table_sort_info_sorting_set_nth(ethi->sort_info, i, column);
+ found = 1;
+ break;
+ }
}
}
- e_table_sort_info_changed (ethi->sort_info);
+ if (!found) {
+ ETableSortColumn column = { model_col, 1 };
+ length = e_table_sort_info_sorting_get_count(ethi->sort_info);
+ if (length == 0)
+ length++;
+ e_table_sort_info_sorting_set_nth(ethi->sort_info, length - 1, column);
+ }
}
if (needs_ungrab)
gnome_canvas_item_ungrab (item, e->button.time);
@@ -996,7 +1016,7 @@ ethi_class_init (GtkObjectClass *object_class)
GTK_ARG_WRITABLE, ARG_TABLE_Y);
gtk_object_add_arg_type ("ETableHeaderItem::fontset", GTK_TYPE_STRING,
GTK_ARG_WRITABLE, ARG_TABLE_FONTSET);
- gtk_object_add_arg_type ("ETableHeaderItem::sort_info", GTK_TYPE_POINTER,
+ gtk_object_add_arg_type ("ETableHeaderItem::sort_info", GTK_TYPE_OBJECT,
GTK_ARG_WRITABLE, ARG_SORT_INFO);
/*
@@ -1030,6 +1050,7 @@ ethi_init (GnomeCanvasItem *item)
ethi->sort_info = NULL;
ethi->sort_info_changed_id = 0;
+ ethi->group_info_changed_id = 0;
ethi->group_indent_width = 0;
}
diff --git a/widgets/table/e-table-header-item.h b/widgets/table/e-table-header-item.h
index add488d2f7..6aeefa885d 100644
--- a/widgets/table/e-table-header-item.h
+++ b/widgets/table/e-table-header-item.h
@@ -48,7 +48,7 @@ typedef struct {
int click_x, click_y;
int drag_col, drag_mark;
guint drag_motion_id, drag_end_id, drag_leave_id, drag_drop_id;
- guint sort_info_changed_id;
+ guint sort_info_changed_id, group_info_changed_id;
GnomeCanvasItem *drag_mark_item, *remove_item;
GdkBitmap *stipple;
diff --git a/widgets/table/e-table-sort-info.c b/widgets/table/e-table-sort-info.c
index bf90a13602..b33784c140 100644
--- a/widgets/table/e-table-sort-info.c
+++ b/widgets/table/e-table-sort-info.c
@@ -9,7 +9,6 @@
*/
#include <config.h>
#include <gtk/gtksignal.h>
-#include <gnome-xml/tree.h>
#include "e-table-sort-info.h"
#include "e-util/e-util.h"
@@ -22,51 +21,47 @@ static GtkObjectClass *e_table_sort_info_parent_class;
enum {
SORT_INFO_CHANGED,
+ GROUP_INFO_CHANGED,
LAST_SIGNAL
};
static guint e_table_sort_info_signals [LAST_SIGNAL] = { 0, };
-enum {
- ARG_0,
- ARG_GROUPING
-};
-
static void
-etsi_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+etsi_destroy (GtkObject *object)
{
ETableSortInfo *etsi;
- etsi = E_TABLE_SORT_INFO (o);
-
- switch (arg_id){
- case ARG_GROUPING:
- etsi->grouping = GTK_VALUE_POINTER (*arg);
- break;
- }
+ etsi = E_TABLE_SORT_INFO (object);
+
+ if (etsi->groupings)
+ g_free(etsi->groupings);
+ if (etsi->sortings)
+ g_free(etsi->sortings);
}
static void
-etsi_get_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+e_table_sort_info_init (ETableSortInfo *info)
{
- ETableSortInfo *etsi;
-
- etsi = E_TABLE_SORT_INFO (o);
-
- switch (arg_id){
- case ARG_GROUPING:
- GTK_VALUE_POINTER (*arg) = etsi->grouping;
- break;
- }
+ info->group_count = 0;
+ info->groupings = NULL;
+ info->sort_count = 0;
+ info->sortings = NULL;
+ info->frozen = 0;
+ info->sort_info_changed = 0;
+ info->group_info_changed = 0;
}
static void
-e_table_sort_info_class_init (GtkObjectClass *object_class)
+e_table_sort_info_class_init (ETableSortInfoClass *klass)
{
+ GtkObjectClass *object_class;
+
e_table_sort_info_parent_class = gtk_type_class (gtk_object_get_type ());
+
+ object_class = GTK_OBJECT_CLASS(klass);
- object_class->set_arg = etsi_set_arg;
- object_class->get_arg = etsi_get_arg;
+ object_class->destroy = etsi_destroy;
e_table_sort_info_signals [SORT_INFO_CHANGED] =
gtk_signal_new ("sort_info_changed",
@@ -76,25 +71,154 @@ e_table_sort_info_class_init (GtkObjectClass *object_class)
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
- gtk_object_class_add_signals (object_class, e_table_sort_info_signals, LAST_SIGNAL);
+ e_table_sort_info_signals [GROUP_INFO_CHANGED] =
+ gtk_signal_new ("group_info_changed",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETableSortInfoClass, group_info_changed),
+ gtk_marshal_NONE__NONE,
+ GTK_TYPE_NONE, 0);
- gtk_object_add_arg_type ("ETableSortInfo::grouping", GTK_TYPE_POINTER,
- GTK_ARG_READWRITE, ARG_GROUPING);
+ klass->sort_info_changed = NULL;
+ klass->group_info_changed = NULL;
+
+ gtk_object_class_add_signals (object_class, e_table_sort_info_signals, LAST_SIGNAL);
}
E_MAKE_TYPE(e_table_sort_info, "ETableSortInfo", ETableSortInfo,
- e_table_sort_info_class_init, NULL, PARENT_TYPE);
+ e_table_sort_info_class_init, e_table_sort_info_init, PARENT_TYPE);
-void
-e_table_sort_info_changed (ETableSortInfo *e_table_sort_info)
+static void
+e_table_sort_info_sort_info_changed (ETableSortInfo *info)
+{
+ g_return_if_fail (info != NULL);
+ g_return_if_fail (E_IS_TABLE_SORT_INFO (info));
+
+ if (info->frozen) {
+ info->sort_info_changed = 1;
+ } else {
+ gtk_signal_emit (GTK_OBJECT (info),
+ e_table_sort_info_signals [SORT_INFO_CHANGED]);
+ }
+}
+
+static void
+e_table_sort_info_group_info_changed (ETableSortInfo *info)
{
- g_return_if_fail (e_table_sort_info != NULL);
- g_return_if_fail (E_IS_TABLE_SORT_INFO (e_table_sort_info));
+ g_return_if_fail (info != NULL);
+ g_return_if_fail (E_IS_TABLE_SORT_INFO (info));
- gtk_signal_emit (GTK_OBJECT (e_table_sort_info),
- e_table_sort_info_signals [SORT_INFO_CHANGED]);
+ if (info->frozen) {
+ info->group_info_changed = 1;
+ } else {
+ gtk_signal_emit (GTK_OBJECT (info),
+ e_table_sort_info_signals [GROUP_INFO_CHANGED]);
+ }
+}
+
+void
+e_table_sort_info_freeze (ETableSortInfo *info)
+{
+ info->frozen = 1;
+}
+
+void
+e_table_sort_info_thaw (ETableSortInfo *info)
+{
+ info->frozen = 0;
+ if (info->sort_info_changed) {
+ info->sort_info_changed = 0;
+ e_table_sort_info_sort_info_changed(info);
+ }
+ if (info->group_info_changed) {
+ info->group_info_changed = 0;
+ e_table_sort_info_group_info_changed(info);
+ }
+}
+
+
+guint
+e_table_sort_info_grouping_get_count (ETableSortInfo *info)
+{
+ return info->group_count;
+}
+
+void
+e_table_sort_info_grouping_truncate (ETableSortInfo *info, int length)
+{
+ if (length < info->group_count) {
+ info->group_count = length;
+ }
+ if (length > info->group_count) {
+ info->groupings = g_realloc(info->groupings, length * sizeof(ETableSortColumn));
+ info->group_count = length;
+ }
+ e_table_sort_info_group_info_changed(info);
+}
+
+ETableSortColumn
+e_table_sort_info_grouping_get_nth (ETableSortInfo *info, int n)
+{
+ if (n < info->group_count) {
+ return info->groupings[n];
+ } else {
+ ETableSortColumn fake = {0, 0};
+ return fake;
+ }
+}
+
+void
+e_table_sort_info_grouping_set_nth (ETableSortInfo *info, int n, ETableSortColumn column)
+{
+ if (n >= info->group_count) {
+ e_table_sort_info_grouping_truncate(info, n + 1);
+ }
+ info->groupings[n] = column;
+ e_table_sort_info_group_info_changed(info);
+}
+
+
+guint
+e_table_sort_info_sorting_get_count (ETableSortInfo *info)
+{
+ return info->sort_count;
+}
+
+void
+e_table_sort_info_sorting_truncate (ETableSortInfo *info, int length)
+{
+ if (length < info->sort_count) {
+ info->sort_count = length;
+ }
+ if (length > info->sort_count) {
+ info->sortings = g_realloc(info->sortings, length * sizeof(ETableSortColumn));
+ info->sort_count = length;
+ }
+ e_table_sort_info_sort_info_changed(info);
}
+ETableSortColumn
+e_table_sort_info_sorting_get_nth (ETableSortInfo *info, int n)
+{
+ if (n < info->sort_count) {
+ return info->sortings[n];
+ } else {
+ ETableSortColumn fake = {0, 0};
+ return fake;
+ }
+}
+
+void
+e_table_sort_info_sorting_set_nth (ETableSortInfo *info, int n, ETableSortColumn column)
+{
+ if (n >= info->sort_count) {
+ e_table_sort_info_sorting_truncate(info, n + 1);
+ }
+ info->sortings[n] = column;
+ e_table_sort_info_sort_info_changed(info);
+}
+
+
ETableSortInfo *
e_table_sort_info_new (void)
{
diff --git a/widgets/table/e-table-sort-info.h b/widgets/table/e-table-sort-info.h
index 0fc4cd52ef..6446230116 100644
--- a/widgets/table/e-table-sort-info.h
+++ b/widgets/table/e-table-sort-info.h
@@ -1,4 +1,3 @@
-
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#ifndef _E_TABLE_SORT_INFO_H_
#define _E_TABLE_SORT_INFO_H_
@@ -11,10 +10,24 @@
#define E_IS_TABLE_SORT_INFO(o) (GTK_CHECK_TYPE ((o), E_TABLE_SORT_INFO_TYPE))
#define E_IS_TABLE_SORT_INFO_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_SORT_INFO_TYPE))
+typedef struct _ETableSortColumn ETableSortColumn;
+
+struct _ETableSortColumn {
+ guint column : 31;
+ guint ascending : 1;
+};
+
typedef struct {
GtkObject base;
-
- xmlNode *grouping;
+
+ gint group_count;
+ ETableSortColumn *groupings;
+ gint sort_count;
+ ETableSortColumn *sortings;
+
+ guint frozen : 1;
+ guint sort_info_changed : 1;
+ guint group_info_changed : 1;
} ETableSortInfo;
typedef struct {
@@ -23,15 +36,25 @@ typedef struct {
/*
* Signals
*/
- void (*sort_info_changed) (ETableSortInfo *etm);
+ void (*sort_info_changed) (ETableSortInfo *info);
+ void (*group_info_changed) (ETableSortInfo *info);
} ETableSortInfoClass;
-GtkType e_table_sort_info_get_type (void);
+GtkType e_table_sort_info_get_type (void);
+
+void e_table_sort_info_freeze (ETableSortInfo *info);
+void e_table_sort_info_thaw (ETableSortInfo *info);
+
+guint e_table_sort_info_grouping_get_count (ETableSortInfo *info);
+void e_table_sort_info_grouping_truncate (ETableSortInfo *info, int length);
+ETableSortColumn e_table_sort_info_grouping_get_nth (ETableSortInfo *info, int n);
+void e_table_sort_info_grouping_set_nth (ETableSortInfo *info, int n, ETableSortColumn column);
+
+guint e_table_sort_info_sorting_get_count (ETableSortInfo *info);
+void e_table_sort_info_sorting_truncate (ETableSortInfo *info, int length);
+ETableSortColumn e_table_sort_info_sorting_get_nth (ETableSortInfo *info, int n);
+void e_table_sort_info_sorting_set_nth (ETableSortInfo *info, int n, ETableSortColumn column);
-/*
- * Routines for emitting signals on the e_table
- */
-void e_table_sort_info_changed (ETableSortInfo *e_table_sort_info);
-ETableSortInfo *e_table_sort_info_new (void);
+ETableSortInfo *e_table_sort_info_new (void);
#endif /* _E_TABLE_SORT_INFO_H_ */
diff --git a/widgets/table/e-table-sorted-variable.c b/widgets/table/e-table-sorted-variable.c
index 153295fc78..a1a9a35a09 100644
--- a/widgets/table/e-table-sorted-variable.c
+++ b/widgets/table/e-table-sorted-variable.c
@@ -41,6 +41,11 @@ etsv_destroy (GtkObject *object)
etsv->table_model_changed_id = 0;
etsv->table_model_row_changed_id = 0;
etsv->table_model_cell_changed_id = 0;
+
+ if (etsv->sort_info)
+ gtk_object_unref(GTK_OBJECT(etsv->sort_info));
+ if (etsv->full_header)
+ gtk_object_unref(GTK_OBJECT(etsv->full_header));
GTK_OBJECT_CLASS (etsv_parent_class)->destroy (object);
}
@@ -67,17 +72,33 @@ etsv_add (ETableSubsetVariable *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;
+ ETableCol *last_col = NULL;
+ void *val = NULL;
- 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))
+ int j;
+ int sort_count = e_table_sort_info_sorting_get_count(etsv->sort_info);
+ int comp_val = 0;
+ int ascending = 1;
+ for (j = 0; j < sort_count; j++) {
+ ETableSortColumn column = e_table_sort_info_sorting_get_nth(etsv->sort_info, j);
+ ETableCol *col;
+ if (column.column > e_table_header_count (etsv->full_header))
+ col = e_table_header_get_columns (etsv->full_header)[e_table_header_count (etsv->full_header) - 1];
+ else
+ col = e_table_header_get_columns (etsv->full_header)[column.column];
+ if (last_col != col)
+ val = e_table_model_value_at (etss->source, col->col_idx, row);
+ last_col = col;
+ comp_val = (*col->compare)(val, e_table_model_value_at (etss->source, col->col_idx, etss->map_table[i]));
+ ascending = column.ascending;
+ if (comp_val != 0)
+ break;
+ }
+ if (((ascending && comp_val < 0) || ((!ascending) && comp_val > 0)))
break;
+
if (comp_val == 0)
if ((ascending && row < etss->map_table[i]) || ((!ascending) && row > etss->map_table[i]))
break;
@@ -95,7 +116,7 @@ etsv_add (ETableSubsetVariable *etssv,
}
ETableModel *
-e_table_sorted_variable_new (ETableModel *source, int col, int ascending, GCompareFunc compare)
+e_table_sorted_variable_new (ETableModel *source, ETableHeader *full_header, ETableSortInfo *sort_info)
{
ETableSortedVariable *etsv = gtk_type_new (E_TABLE_SORTED_VARIABLE_TYPE);
ETableSubsetVariable *etssv = E_TABLE_SUBSET_VARIABLE (etsv);
@@ -105,9 +126,10 @@ e_table_sorted_variable_new (ETableModel *source, int col, int ascending, GCompa
return NULL;
}
- etsv->sort_col = col;
- etsv->ascending = ascending;
- etsv->compare = compare;
+ etsv->sort_info = sort_info;
+ gtk_object_ref(GTK_OBJECT(etsv->sort_info));
+ etsv->full_header = full_header;
+ gtk_object_ref(GTK_OBJECT(etsv->full_header));
etsv->table_model_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_changed",
GTK_SIGNAL_FUNC (etsv_proxy_model_changed), etsv);
@@ -142,10 +164,8 @@ etsv_proxy_model_cell_changed (ETableModel *etm, int col, int row, ETableSortedV
{
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);
- }
+ if (e_table_subset_variable_remove(etssv, row))
+ e_table_subset_variable_add (etssv, row);
}
}
diff --git a/widgets/table/e-table-sorted-variable.h b/widgets/table/e-table-sorted-variable.h
index cf188acd4a..1a22679040 100644
--- a/widgets/table/e-table-sorted-variable.h
+++ b/widgets/table/e-table-sorted-variable.h
@@ -5,6 +5,8 @@
#include <gtk/gtkobject.h>
#include "e-table-model.h"
#include "e-table-subset-variable.h"
+#include "e-table-sort-info.h"
+#include "e-table-header.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))
@@ -15,9 +17,9 @@
typedef struct {
ETableSubsetVariable base;
- short sort_col;
- int ascending;
- GCompareFunc compare;
+ ETableSortInfo *sort_info;
+
+ ETableHeader *full_header;
int table_model_changed_id;
int table_model_row_changed_id;
@@ -29,6 +31,6 @@ typedef struct {
} ETableSortedVariableClass;
GtkType e_table_sorted_variable_get_type (void);
-ETableModel *e_table_sorted_variable_new (ETableModel *etm, int col, int ascending, GCompareFunc compare);
+ETableModel *e_table_sorted_variable_new (ETableModel *etm, ETableHeader *header, ETableSortInfo *sort_info);
#endif /* _E_TABLE_SORTED_VARIABLE_H_ */
diff --git a/widgets/table/e-table.c b/widgets/table/e-table.c
index 7360666d06..1dc931474d 100644
--- a/widgets/table/e-table.c
+++ b/widgets/table/e-table.c
@@ -60,6 +60,9 @@ et_destroy (GtkObject *object)
if (et->sort_info_change_id)
gtk_signal_disconnect (GTK_OBJECT (et->sort_info),
et->sort_info_change_id);
+ if (et->group_info_change_id)
+ gtk_signal_disconnect (GTK_OBJECT (et->sort_info),
+ et->group_info_change_id);
gtk_object_unref (GTK_OBJECT (et->model));
gtk_object_unref (GTK_OBJECT (et->full_header));
@@ -85,6 +88,7 @@ e_table_init (GtkObject *object)
e_table->sort_info = NULL;
e_table->sort_info_change_id = 0;
+ e_table->group_info_change_id = 0;
e_table->draw_grid = 1;
e_table->draw_focus = 1;
@@ -140,6 +144,7 @@ e_table_setup_header (ETable *e_table)
{
xmlNode *root;
xmlNode *grouping;
+ int i;
e_table->header_canvas = GNOME_CANVAS (e_canvas_new ());
gtk_widget_show (GTK_WIDGET (e_table->header_canvas));
@@ -152,13 +157,27 @@ e_table_setup_header (ETable *e_table)
gtk_object_ref (GTK_OBJECT (e_table->sort_info));
gtk_object_sink (GTK_OBJECT (e_table->sort_info));
- gtk_object_set (GTK_OBJECT (e_table->sort_info),
- "grouping", grouping,
- NULL);
+ i = 0;
+ for (grouping = grouping->childs; grouping && strcmp (grouping->name, "leaf"); grouping = grouping->childs) {
+ ETableSortColumn column;
+ column.column = e_xml_get_integer_prop_by_name (grouping, "column");
+ column.ascending = e_xml_get_integer_prop_by_name (grouping, "ascending");
+ e_table_sort_info_grouping_set_nth(e_table->sort_info, i++, column);
+ }
+ i = 0;
+ for (; grouping; grouping = grouping->childs) {
+ ETableSortColumn column;
+ column.column = e_xml_get_integer_prop_by_name (grouping, "column");
+ column.ascending = e_xml_get_integer_prop_by_name (grouping, "ascending");
+ e_table_sort_info_sorting_set_nth(e_table->sort_info, i++, column);
+ }
e_table->sort_info_change_id =
gtk_signal_connect (GTK_OBJECT (e_table->sort_info), "sort_info_changed",
GTK_SIGNAL_FUNC (sort_info_changed), e_table);
+ e_table->group_info_change_id =
+ gtk_signal_connect (GTK_OBJECT (e_table->sort_info), "group_info_changed",
+ GTK_SIGNAL_FUNC (sort_info_changed), e_table);
e_table->header_item = gnome_canvas_item_new (
gnome_canvas_root (e_table->header_canvas),
@@ -631,8 +650,8 @@ changed_idle (gpointer data)
et->full_header,
et->header,
et->model,
- e_xml_get_child_by_name (xmlDocGetRootElement (et->specification),
- "grouping")->childs);
+ et->sort_info,
+ 0);
gtk_signal_connect (GTK_OBJECT (et->group), "row_selection",
GTK_SIGNAL_FUNC (group_row_selection), et);
e_table_fill_table (et, et->model);
@@ -687,7 +706,7 @@ et_table_cell_changed (ETableModel *table_model, int view_col, int row, ETable *
static void
e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *header,
- ETableModel *model, xmlNode *xml_grouping)
+ ETableModel *model)
{
e_table->table_canvas = GNOME_CANVAS (e_canvas_new ());
gtk_signal_connect (
@@ -703,7 +722,8 @@ e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *h
full_header,
header,
model,
- xml_grouping->childs);
+ e_table->sort_info,
+ 0);
gtk_signal_connect (GTK_OBJECT(e_table->group), "row_selection",
GTK_SIGNAL_FUNC(group_row_selection), e_table);
@@ -763,7 +783,7 @@ et_real_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm,
e_table->header = e_table_make_header (e_table, full_header, xmlColumns);
e_table_setup_header (e_table);
- e_table_setup_table (e_table, full_header, e_table->header, etm, xmlGrouping);
+ e_table_setup_table (e_table, full_header, e_table->header, etm);
e_table_fill_table (e_table, etm);
vbox = gtk_vbox_new (FALSE, 0);
@@ -853,11 +873,32 @@ et_build_column_spec (ETable *e_table)
static xmlNode *
et_build_grouping_spec (ETable *e_table)
{
+ xmlNode *node;
xmlNode *grouping;
xmlNode *root;
+ int i;
+ int length;
root = xmlDocGetRootElement (e_table->specification);
- grouping = xmlCopyNode (e_xml_get_child_by_name(root, "grouping"), TRUE);
+ xmlCopyNode (e_xml_get_child_by_name(root, "grouping"), TRUE);
+ grouping = xmlNewNode (NULL, "grouping");
+ node = grouping;
+ length = e_table_sort_info_grouping_get_count(e_table->sort_info);
+ for (i = 0; i < length; i++) {
+ ETableSortColumn column = e_table_sort_info_grouping_get_nth(e_table->sort_info, i);
+ xmlNode *new_node = xmlNewChild(node, NULL, "group", NULL);
+ e_xml_set_integer_prop_by_name (new_node, "column", column.column);
+ e_xml_set_integer_prop_by_name (new_node, "ascending", column.ascending);
+ node = new_node;
+ }
+ length = e_table_sort_info_sorting_get_count(e_table->sort_info);
+ for (i = 0; i < length; i++) {
+ ETableSortColumn column = e_table_sort_info_sorting_get_nth(e_table->sort_info, i);
+ xmlNode *new_node = xmlNewChild(node, NULL, "leaf", NULL);
+ e_xml_set_integer_prop_by_name (new_node, "column", column.column);
+ e_xml_set_integer_prop_by_name (new_node, "ascending", column.ascending);
+ node = new_node;
+ }
return grouping;
}
diff --git a/widgets/table/e-table.h b/widgets/table/e-table.h
index 3cca3422b3..39333f159a 100644
--- a/widgets/table/e-table.h
+++ b/widgets/table/e-table.h
@@ -34,6 +34,7 @@ typedef struct {
int table_cell_change_id;
int sort_info_change_id;
+ int group_info_change_id;
GnomeCanvas *header_canvas, *table_canvas;
diff --git a/widgets/table/test-cols.c b/widgets/table/test-cols.c
index 15e07d94da..f60d22d915 100644
--- a/widgets/table/test-cols.c
+++ b/widgets/table/test-cols.c
@@ -9,6 +9,7 @@
#include <string.h>
#include <gnome.h>
#include "e-util/e-canvas-utils.h"
+#include "e-util/e-canvas.h"
#include "e-util/e-cursors.h"
#include "e-util/e-util.h"
#include "e-table-simple.h"
diff --git a/widgets/table/test-table.c b/widgets/table/test-table.c
index 0fd086681c..2ff657c863 100644
--- a/widgets/table/test-table.c
+++ b/widgets/table/test-table.c
@@ -17,6 +17,7 @@
#include "e-table-item.h"
#include "e-cell-text.h"
#include "e-table.h"
+#include "e-table-config.h"
#include "table-test.h"
@@ -346,7 +347,7 @@ do_e_table_demo (const char *spec)
gtk_widget_show (window);
if (getenv ("TEST")){
- e_table_do_gui_config (NULL, e_table);
+ e_table_do_gui_config (NULL, E_TABLE(e_table));
}
}