diff options
Diffstat (limited to 'widgets/table')
-rw-r--r-- | widgets/table/e-cell-tree.c | 8 | ||||
-rw-r--r-- | widgets/table/e-table-column-specification.c | 108 | ||||
-rw-r--r-- | widgets/table/e-table-column-specification.h | 41 | ||||
-rw-r--r-- | widgets/table/e-table-config.c | 2 | ||||
-rw-r--r-- | widgets/table/e-table-defines.h | 7 | ||||
-rw-r--r-- | widgets/table/e-table-extras.c | 164 | ||||
-rw-r--r-- | widgets/table/e-table-extras.h | 48 | ||||
-rw-r--r-- | widgets/table/e-table-item.h | 7 | ||||
-rw-r--r-- | widgets/table/e-table-scrolled.c | 119 | ||||
-rw-r--r-- | widgets/table/e-table-scrolled.h | 66 | ||||
-rw-r--r-- | widgets/table/e-table-sort-info.c | 59 | ||||
-rw-r--r-- | widgets/table/e-table-sort-info.h | 37 | ||||
-rw-r--r-- | widgets/table/e-table-specification.c | 196 | ||||
-rw-r--r-- | widgets/table/e-table-specification.h | 52 | ||||
-rw-r--r-- | widgets/table/e-table-state.c | 161 | ||||
-rw-r--r-- | widgets/table/e-table-state.h | 43 | ||||
-rw-r--r-- | widgets/table/e-table.c | 317 | ||||
-rw-r--r-- | widgets/table/e-table.h | 164 | ||||
-rw-r--r-- | widgets/table/e-tree-model.c | 1 |
19 files changed, 1292 insertions, 308 deletions
diff --git a/widgets/table/e-cell-tree.c b/widgets/table/e-cell-tree.c index bae0ecaa8d..1602d11eb3 100644 --- a/widgets/table/e-cell-tree.c +++ b/widgets/table/e-cell-tree.c @@ -573,7 +573,9 @@ ect_destroy (GtkObject *object) ECellTree *ect = E_CELL_TREE (object); /* destroy our subcell */ - gtk_object_destroy (GTK_OBJECT (ect->subcell)); + if (ect->subcell) + gtk_object_unref (GTK_OBJECT (ect->subcell)); + ect->subcell = NULL; gdk_pixbuf_unref (ect->open_pixbuf); gdk_pixbuf_unref (ect->closed_pixbuf); @@ -615,6 +617,10 @@ e_cell_tree_construct (ECellTree *ect, ECell *subcell) { ect->subcell = subcell; + if (subcell) { + gtk_object_ref (GTK_OBJECT (subcell)); + gtk_object_sink (GTK_OBJECT (subcell)); + } if (open_pixbuf) ect->open_pixbuf = open_pixbuf; else diff --git a/widgets/table/e-table-column-specification.c b/widgets/table/e-table-column-specification.c new file mode 100644 index 0000000000..1b16fdf170 --- /dev/null +++ b/widgets/table/e-table-column-specification.c @@ -0,0 +1,108 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * E-table-column-specification.c: Savable specification of a column. + * + * Author: + * Chris Lahey <clahey@helixcode.com> + * + * (C) 2000 Helix Code, Inc. + */ +#include <config.h> +#include <stdlib.h> +#include <gtk/gtksignal.h> +#include <gnome-xml/parser.h> +#include <gnome-xml/xmlmemory.h> +#include "gal/util/e-xml-utils.h" +#include "gal/util/e-util.h" +#include "e-table-column-specification.h" + +#define PARENT_TYPE (gtk_object_get_type()) + +static GtkObjectClass *etcs_parent_class; + +static void +etcs_destroy (GtkObject *object) +{ + ETableColumnSpecification *etcs = E_TABLE_COLUMN_SPECIFICATION (object); + + g_free(etcs->title_); + g_free(etcs->pixbuf); + g_free(etcs->cell); + g_free(etcs->compare); + + GTK_OBJECT_CLASS (etcs_parent_class)->destroy (object); +} + +static void +etcs_class_init (GtkObjectClass *klass) +{ + etcs_parent_class = gtk_type_class (PARENT_TYPE); + + klass->destroy = etcs_destroy; +} + +static void +etcs_init (ETableColumnSpecification *specification) +{ + specification->model_col = 0; + specification->title_ = NULL; + specification->pixbuf = NULL; + + specification->expansion = 0; + specification->minimum_width = 0; + specification->resizable = FALSE; + + specification->cell = NULL; + specification->compare = NULL; +} + +E_MAKE_TYPE(e_table_column_specification, "ETableColumnSpecification", ETableColumnSpecification, etcs_class_init, etcs_init, PARENT_TYPE); + +ETableColumnSpecification * +e_table_column_specification_new (void) +{ + ETableColumnSpecification *etcs = gtk_type_new (E_TABLE_COLUMN_SPECIFICATION_TYPE); + + return (ETableColumnSpecification *) etcs; +} + +void +e_table_column_specification_load_from_node (ETableColumnSpecification *specification, + const xmlNode *node) +{ + specification->model_col = e_xml_get_integer_prop_by_name(node, "model_col"); + specification->title_ = e_xml_get_translated_string_prop_by_name(node, "_title"); + specification->pixbuf = e_xml_get_translated_string_prop_by_name(node, "pixbuf"); + + specification->expansion = e_xml_get_double_prop_by_name(node, "expansion"); + specification->minimum_width = e_xml_get_integer_prop_by_name(node, "minimum_width"); + specification->resizable = e_xml_get_bool_prop_by_name(node, "resizable"); + + specification->cell = e_xml_get_string_prop_by_name(node, "cell"); + specification->compare = e_xml_get_string_prop_by_name(node, "compare"); +} + +xmlNode * +e_table_column_specification_save_to_node (ETableColumnSpecification *specification, + xmlNode *parent) +{ + xmlNode *node; + if (parent) + node = xmlNewChild(parent, NULL, "ETableColumn", NULL); + else + node = xmlNewNode(NULL, "ETableColumn"); + + e_xml_set_integer_prop_by_name(node, "model_col", specification->model_col); + e_xml_set_string_prop_by_name(node, "_title", specification->title_); + e_xml_set_string_prop_by_name(node, "pixbuf", specification->pixbuf); + + e_xml_set_double_prop_by_name(node, "expansion", specification->expansion); + e_xml_set_integer_prop_by_name(node, "minimum_width", specification->minimum_width); + e_xml_set_bool_prop_by_name(node, "resizable", specification->resizable); + + e_xml_set_string_prop_by_name(node, "cell", specification->cell); + e_xml_set_string_prop_by_name(node, "compare", specification->compare); + + return node; +} + diff --git a/widgets/table/e-table-column-specification.h b/widgets/table/e-table-column-specification.h new file mode 100644 index 0000000000..4004e3eb8b --- /dev/null +++ b/widgets/table/e-table-column-specification.h @@ -0,0 +1,41 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +#ifndef _E_TABLE_COLUMN_SPECIFICATION_H_ +#define _E_TABLE_COLUMN_SPECIFICATION_H_ + +#include <gtk/gtkobject.h> +#include <gnome-xml/tree.h> + +#define E_TABLE_COLUMN_SPECIFICATION_TYPE (e_table_column_specification_get_type ()) +#define E_TABLE_COLUMN_SPECIFICATION(o) (GTK_CHECK_CAST ((o), E_TABLE_COLUMN_SPECIFICATION_TYPE, ETableColumnSpecification)) +#define E_TABLE_COLUMN_SPECIFICATION_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_COLUMN_SPECIFICATION_TYPE, ETableColumnSpecificationClass)) +#define E_IS_TABLE_COLUMN_SPECIFICATION(o) (GTK_CHECK_TYPE ((o), E_TABLE_COLUMN_SPECIFICATION_TYPE)) +#define E_IS_TABLE_COLUMN_SPECIFICATION_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_COLUMN_SPECIFICATION_TYPE)) + +typedef struct { + GtkObject base; + int model_col; + char *title_; + char *pixbuf; + + double expansion; + int minimum_width; + guint resizable : 1; + + char *cell; + char *compare; +} ETableColumnSpecification; + +typedef struct { + GtkObjectClass parent_class; +} ETableColumnSpecificationClass; + +GtkType e_table_column_specification_get_type (void); + +ETableColumnSpecification *e_table_column_specification_new (void); + +void e_table_column_specification_load_from_node (ETableColumnSpecification *state, + const xmlNode *node); +xmlNode *e_table_column_specification_save_to_node (ETableColumnSpecification *state, + xmlNode *parent); + +#endif /* _E_TABLE_COLUMN_SPECIFICATION_H_ */ diff --git a/widgets/table/e-table-config.c b/widgets/table/e-table-config.c index ee3027e5d3..a2831da73a 100644 --- a/widgets/table/e-table-config.c +++ b/widgets/table/e-table-config.c @@ -178,7 +178,7 @@ e_table_gui_config (ETable *etable) config_data = g_new (ConfigData, 1); config_data->gui = gui; - config_data->old_spec = e_table_get_specification (etable); + config_data->old_spec = e_table_get_state (etable); gtk_object_set_data ( GTK_OBJECT (dialog), "config-data", diff --git a/widgets/table/e-table-defines.h b/widgets/table/e-table-defines.h index 9bb9e107ac..ba87a8e560 100644 --- a/widgets/table/e-table-defines.h +++ b/widgets/table/e-table-defines.h @@ -13,4 +13,11 @@ typedef void (*ETableForeachFunc) (int model_row, gpointer closure); +/* list selection modes */ +typedef enum +{ + E_TABLE_CURSOR_LINE, + E_TABLE_CURSOR_SIMPLE, +} ETableCursorMode; + #endif diff --git a/widgets/table/e-table-extras.c b/widgets/table/e-table-extras.c new file mode 100644 index 0000000000..c9d6545d97 --- /dev/null +++ b/widgets/table/e-table-extras.c @@ -0,0 +1,164 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * E-table-extras.c: Pair of hash table sort of thingies. + * + * Author: + * Chris Lahey <clahey@helixcode.com> + * + * (C) 2000 Helix Code, Inc. + */ +#include <config.h> +#include <stdlib.h> +#include <gtk/gtksignal.h> +#include "gal/util/e-util.h" +#include "gal/e-table/e-cell-text.h" +#include "gal/e-table/e-cell-checkbox.h" +#include "e-table-extras.h" + +#define PARENT_TYPE (gtk_object_get_type()) + +static GtkObjectClass *ete_parent_class; + +static void +cell_hash_free(gchar *key, + ECell *cell, + gpointer user_data) +{ + g_free(key); + if (cell) + gtk_object_unref( GTK_OBJECT (cell)); +} + +static void +pixbuf_hash_free(gchar *key, + GdkPixbuf *pixbuf, + gpointer user_data) +{ + g_free(key); + if (pixbuf) + gdk_pixbuf_unref(pixbuf); +} + +static void +ete_destroy (GtkObject *object) +{ + ETableExtras *ete = E_TABLE_EXTRAS (object); + + g_hash_table_foreach (ete->cells, (GHFunc) cell_hash_free, NULL); + g_hash_table_foreach (ete->compares, (GHFunc) g_free, NULL); + g_hash_table_foreach (ete->pixbufs, (GHFunc) pixbuf_hash_free, NULL); + + g_hash_table_destroy (ete->cells); + g_hash_table_destroy (ete->compares); + g_hash_table_destroy (ete->pixbufs); + + ete->cells = NULL; + ete->compares = NULL; + ete->pixbufs = NULL; + + GTK_OBJECT_CLASS (ete_parent_class)->destroy (object); +} + +static void +ete_class_init (GtkObjectClass *klass) +{ + ete_parent_class = gtk_type_class (PARENT_TYPE); + + klass->destroy = ete_destroy; +} + +static void +ete_init (ETableExtras *extras) +{ + extras->cells = g_hash_table_new(g_str_hash, g_str_equal); + extras->compares = g_hash_table_new(g_str_hash, g_str_equal); + extras->pixbufs = g_hash_table_new(g_str_hash, g_str_equal); + + e_table_extras_add_compare(extras, "string", g_str_compare); +} + +E_MAKE_TYPE(e_table_extras, "ETableExtras", ETableExtras, ete_class_init, ete_init, PARENT_TYPE); + +ETableExtras * +e_table_extras_new (void) +{ + ETableExtras *ete = gtk_type_new (E_TABLE_EXTRAS_TYPE); + + return (ETableExtras *) ete; +} + +void +e_table_extras_add_cell (ETableExtras *extras, + char *id, + ECell *cell) +{ + gchar *old_key; + ECell *old_cell; + + if (g_hash_table_lookup_extended (extras->cells, id, (gpointer *)&old_key, (gpointer *)&old_cell)) { + g_free (old_key); + if (old_cell) + gtk_object_unref (GTK_OBJECT(old_cell)); + } + + if (cell) { + gtk_object_ref (GTK_OBJECT (cell)); + gtk_object_sink (GTK_OBJECT (cell)); + } + g_hash_table_insert (extras->cells, g_strdup(id), cell); +} + +ECell * +e_table_extras_get_cell (ETableExtras *extras, + char *id) +{ + return g_hash_table_lookup(extras->cells, id); +} + +void +e_table_extras_add_compare (ETableExtras *extras, + char *id, + GCompareFunc compare) +{ + gchar *old_key; + GCompareFunc old_compare; + + if (g_hash_table_lookup_extended (extras->cells, id, (gpointer *)&old_key, (gpointer *)&old_compare)) { + g_free (old_key); + } + + g_hash_table_insert(extras->compares, g_strdup(id), compare); +} + +GCompareFunc +e_table_extras_get_compare (ETableExtras *extras, + char *id) +{ + return g_hash_table_lookup(extras->compares, id); +} + +void +e_table_extras_add_pixbuf (ETableExtras *extras, + char *id, + GdkPixbuf *pixbuf) +{ + gchar *old_key; + GdkPixbuf *old_pixbuf; + + if (g_hash_table_lookup_extended (extras->pixbufs, id, (gpointer *)&old_key, (gpointer *)&old_pixbuf)) { + g_free (old_key); + if (old_pixbuf) + gdk_pixbuf_unref (old_pixbuf); + } + + if (pixbuf) + gdk_pixbuf_ref(pixbuf); + g_hash_table_insert (extras->pixbufs, g_strdup(id), pixbuf); +} + +GdkPixbuf * +e_table_extras_get_pixbuf (ETableExtras *extras, + char *id) +{ + return g_hash_table_lookup(extras->pixbufs, id); +} diff --git a/widgets/table/e-table-extras.h b/widgets/table/e-table-extras.h new file mode 100644 index 0000000000..65b2fb18a5 --- /dev/null +++ b/widgets/table/e-table-extras.h @@ -0,0 +1,48 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +#ifndef _E_TABLE_EXTRAS_H_ +#define _E_TABLE_EXTRAS_H_ + +#include <gtk/gtkobject.h> +#include <gal/e-table/e-cell.h> +#include <gdk-pixbuf/gdk-pixbuf.h> + +#define E_TABLE_EXTRAS_TYPE (e_table_extras_get_type ()) +#define E_TABLE_EXTRAS(o) (GTK_CHECK_CAST ((o), E_TABLE_EXTRAS_TYPE, ETableExtras)) +#define E_TABLE_EXTRAS_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_EXTRAS_TYPE, ETableExtrasClass)) +#define E_IS_TABLE_EXTRAS(o) (GTK_CHECK_TYPE ((o), E_TABLE_EXTRAS_TYPE)) +#define E_IS_TABLE_EXTRAS_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_EXTRAS_TYPE)) + +typedef struct { + GtkObject base; + + GHashTable *cells; + GHashTable *compares; + GHashTable *pixbufs; +} ETableExtras; + +typedef struct { + GtkObjectClass parent_class; +} ETableExtrasClass; + +GtkType e_table_extras_get_type (void); +ETableExtras *e_table_extras_new (void); + +void e_table_extras_add_cell (ETableExtras *extras, + char *id, + ECell *cell); +ECell *e_table_extras_get_cell (ETableExtras *extras, + char *id); + +void e_table_extras_add_compare (ETableExtras *extras, + char *id, + GCompareFunc compare); +GCompareFunc e_table_extras_get_compare (ETableExtras *extras, + char *id); + +void e_table_extras_add_pixbuf (ETableExtras *extras, + char *id, + GdkPixbuf *pixbuf); +GdkPixbuf *e_table_extras_get_pixbuf (ETableExtras *extras, + char *id); + +#endif /* _E_TABLE_EXTRAS_H_ */ diff --git a/widgets/table/e-table-item.h b/widgets/table/e-table-item.h index 58efb63abc..9ce5cba637 100644 --- a/widgets/table/e-table-item.h +++ b/widgets/table/e-table-item.h @@ -16,13 +16,6 @@ #define E_IS_TABLE_ITEM(o) (GTK_CHECK_TYPE ((o), E_TABLE_ITEM_TYPE)) #define E_IS_TABLE_ITEM_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_ITEM_TYPE)) -/* list selection modes */ -typedef enum -{ - E_TABLE_CURSOR_LINE, - E_TABLE_CURSOR_SIMPLE, -} ETableCursorMode; - typedef struct { GnomeCanvasItem parent; ETableModel *table_model; diff --git a/widgets/table/e-table-scrolled.c b/widgets/table/e-table-scrolled.c index 16a99bbcb0..8946f25c25 100644 --- a/widgets/table/e-table-scrolled.c +++ b/widgets/table/e-table-scrolled.c @@ -120,120 +120,123 @@ e_table_scrolled_real_construct (ETableScrolled *ets) gtk_widget_show(GTK_WIDGET(ets->table)); } -ETableScrolled * -e_table_scrolled_construct (ETableScrolled *ets, ETableHeader *full_header, - ETableModel *etm, const char *spec) +ETableScrolled *e_table_scrolled_construct (ETableScrolled *ets, + ETableModel *etm, + ETableExtras *ete, + const char *spec, + const char *state) { g_return_val_if_fail(ets != NULL, NULL); g_return_val_if_fail(E_IS_TABLE_SCROLLED(ets), NULL); - g_return_val_if_fail(full_header != NULL, NULL); - g_return_val_if_fail(E_IS_TABLE_HEADER(full_header), NULL); g_return_val_if_fail(etm != NULL, NULL); g_return_val_if_fail(E_IS_TABLE_MODEL(etm), NULL); + g_return_val_if_fail(ete == NULL || E_IS_TABLE_EXTRAS(ete), NULL); g_return_val_if_fail(spec != NULL, NULL); - - e_table_construct(ets->table, full_header, etm, spec); - - e_table_scrolled_real_construct(ets); - - return ets; -} -ETableScrolled * -e_table_scrolled_construct_from_spec_file (ETableScrolled *ets, ETableHeader *full_header, ETableModel *etm, - const char *filename) -{ - g_return_val_if_fail(ets != NULL, NULL); - g_return_val_if_fail(E_IS_TABLE_SCROLLED(ets), NULL); - g_return_val_if_fail(full_header != NULL, NULL); - g_return_val_if_fail(E_IS_TABLE_HEADER(full_header), NULL); - g_return_val_if_fail(etm != NULL, NULL); - g_return_val_if_fail(E_IS_TABLE_MODEL(etm), NULL); - g_return_val_if_fail(filename != NULL, NULL); - - e_table_construct_from_spec_file(ets->table, full_header, etm, filename); + e_table_construct(ets->table, etm, ete, spec, state); e_table_scrolled_real_construct(ets); return ets; } -GtkWidget * -e_table_scrolled_new (ETableHeader *full_header, ETableModel *etm, const char *spec) +GtkWidget *e_table_scrolled_new (ETableModel *etm, + ETableExtras *ete, + const char *spec, + const char *state) { ETableScrolled *ets; - g_return_val_if_fail(full_header != NULL, NULL); - g_return_val_if_fail(E_IS_TABLE_HEADER(full_header), NULL); g_return_val_if_fail(etm != NULL, NULL); g_return_val_if_fail(E_IS_TABLE_MODEL(etm), NULL); - g_return_val_if_fail(spec != NULL, NULL); + g_return_val_if_fail(ete == NULL || E_IS_TABLE_EXTRAS(ete), NULL); + g_return_val_if_fail(spec != NULL, NULL); ets = E_TABLE_SCROLLED (gtk_widget_new (e_table_scrolled_get_type (), "hadjustment", NULL, "vadjustment", NULL, NULL)); - ets = e_table_scrolled_construct (ets, full_header, etm, spec); - + ets = e_table_scrolled_construct (ets, etm, ete, spec, state); + return GTK_WIDGET (ets); } -GtkWidget * -e_table_scrolled_new_from_spec_file (ETableHeader *full_header, ETableModel *etm, const char *filename) +ETableScrolled *e_table_scrolled_construct_from_spec_file (ETableScrolled *ets, + ETableModel *etm, + ETableExtras *ete, + const char *spec_fn, + const char *state_fn) +{ + g_return_val_if_fail(ets != NULL, NULL); + g_return_val_if_fail(E_IS_TABLE_SCROLLED(ets), NULL); + g_return_val_if_fail(etm != NULL, NULL); + g_return_val_if_fail(E_IS_TABLE_MODEL(etm), NULL); + g_return_val_if_fail(ete == NULL || E_IS_TABLE_EXTRAS(ete), NULL); + g_return_val_if_fail(spec_fn != NULL, NULL); + + e_table_construct_from_spec_file(ets->table, etm, ete, spec_fn, state_fn); + + e_table_scrolled_real_construct(ets); + + return ets; +} + +GtkWidget *e_table_scrolled_new_from_spec_file (ETableModel *etm, + ETableExtras *ete, + const char *spec_fn, + const char *state_fn) { ETableScrolled *ets; - g_return_val_if_fail(full_header != NULL, NULL); - g_return_val_if_fail(E_IS_TABLE_HEADER(full_header), NULL); g_return_val_if_fail(etm != NULL, NULL); g_return_val_if_fail(E_IS_TABLE_MODEL(etm), NULL); - g_return_val_if_fail(filename != NULL, NULL); - + g_return_val_if_fail(ete == NULL || E_IS_TABLE_EXTRAS(ete), NULL); + g_return_val_if_fail(spec_fn != NULL, NULL); + ets = gtk_type_new (e_table_scrolled_get_type ()); - ets = e_table_scrolled_construct_from_spec_file (ets, full_header, etm, filename); - + ets = e_table_scrolled_construct_from_spec_file (ets, etm, ete, spec_fn, state_fn); + return GTK_WIDGET (ets); } -gchar * -e_table_scrolled_get_specification (ETableScrolled *ets) +gchar *e_table_scrolled_get_state (ETableScrolled *ets) { g_return_val_if_fail(ets != NULL, NULL); g_return_val_if_fail(E_IS_TABLE_SCROLLED(ets), NULL); - return e_table_get_specification(ets->table); + return e_table_get_state(ets->table); } -void -e_table_scrolled_save_specification (ETableScrolled *ets, gchar *filename) +void e_table_scrolled_save_state (ETableScrolled *ets, + const gchar *filename) { g_return_if_fail(ets != NULL); g_return_if_fail(E_IS_TABLE_SCROLLED(ets)); g_return_if_fail(filename != NULL); - e_table_save_specification(ets->table, filename); + e_table_save_state(ets->table, filename); } -int -e_table_scrolled_set_specification(ETableScrolled *ets, const char *spec) +void +e_table_scrolled_set_state(ETableScrolled *ets, const char *state) { - g_return_val_if_fail(ets != NULL, -1); - g_return_val_if_fail(E_IS_TABLE_SCROLLED(ets), -1); - g_return_val_if_fail(spec != NULL, -1); + g_return_if_fail(ets != NULL); + g_return_if_fail(E_IS_TABLE_SCROLLED(ets)); + g_return_if_fail(state != NULL); - return e_table_set_specification(ets->table, spec); + e_table_set_state(ets->table, state); } -int -e_table_scrolled_load_specification(ETableScrolled *ets, gchar *filename) +void +e_table_scrolled_load_state(ETableScrolled *ets, const gchar *filename) { - g_return_val_if_fail(ets != NULL, -1); - g_return_val_if_fail(E_IS_TABLE_SCROLLED(ets), -1); - g_return_val_if_fail(filename != NULL, -1); + g_return_if_fail(ets != NULL); + g_return_if_fail(E_IS_TABLE_SCROLLED(ets)); + g_return_if_fail(filename != NULL); - return e_table_load_specification(ets->table, filename); + e_table_load_state(ets->table, filename); } void diff --git a/widgets/table/e-table-scrolled.h b/widgets/table/e-table-scrolled.h index 8543f59d2f..4cce278a49 100644 --- a/widgets/table/e-table-scrolled.h +++ b/widgets/table/e-table-scrolled.h @@ -31,34 +31,46 @@ typedef struct { gint (*key_press) (ETableScrolled *est, int row, int col, GdkEvent *event); } ETableScrolledClass; -GtkType e_table_scrolled_get_type (void); - -ETableScrolled *e_table_scrolled_construct (ETableScrolled *ets, ETableHeader *full_header, ETableModel *etm, - const char *spec); -GtkWidget *e_table_scrolled_new (ETableHeader *full_header, ETableModel *etm, - const char *spec); - -ETableScrolled *e_table_scrolled_construct_from_spec_file (ETableScrolled *e_table_scrolled, - ETableHeader *full_header, - ETableModel *etm, - const char *filename); -GtkWidget *e_table_scrolled_new_from_spec_file (ETableHeader *full_header, - ETableModel *etm, - const char *filename); - -gchar *e_table_scrolled_get_specification (ETableScrolled *e_table_scrolled); -void e_table_scrolled_save_specification (ETableScrolled *e_table_scrolled, gchar *filename); -int e_table_scrolled_set_specification (ETableScrolled *e_table_scrolled, const char *spec); -int e_table_scrolled_load_specification (ETableScrolled *e_table_scrolled, gchar *filename); - -void e_table_scrolled_set_cursor_row (ETableScrolled *e_table_scrolled, - int row); +GtkType e_table_scrolled_get_type (void); + +ETableScrolled *e_table_scrolled_construct (ETableScrolled *ets, + ETableModel *etm, + ETableExtras *ete, + const char *spec, + const char *state); +GtkWidget *e_table_scrolled_new (ETableModel *etm, + ETableExtras *ete, + const char *spec, + const char *state); + +ETableScrolled *e_table_scrolled_construct_from_spec_file (ETableScrolled *ets, + ETableModel *etm, + ETableExtras *ete, + const char *spec_fn, + const char *state_fn); +GtkWidget *e_table_scrolled_new_from_spec_file (ETableModel *etm, + ETableExtras *ete, + const char *spec_fn, + const char *state_fn); + +gchar *e_table_scrolled_get_state (ETableScrolled *ets); +void e_table_scrolled_save_state (ETableScrolled *ets, + const gchar *filename); + +/* note that it is more efficient to provide the state at creation time */ +void e_table_scrolled_set_state (ETableScrolled *ets, + const gchar *state); +void e_table_scrolled_load_state (ETableScrolled *ets, + const gchar *filename); + +void e_table_scrolled_set_cursor_row (ETableScrolled *ets, + int row); /* -1 means we don't have the cursor. */ -int e_table_scrolled_get_cursor_row (ETableScrolled *e_table_scrolled); -void e_table_scrolled_selected_row_foreach (ETableScrolled *e_table_scrolled, - ETableForeachFunc callback, - gpointer closure); -EPrintable *e_table_scrolled_get_printable (ETableScrolled *e_table_scrolled); +int e_table_scrolled_get_cursor_row (ETableScrolled *ets); +void e_table_scrolled_selected_row_foreach (ETableScrolled *ets, + ETableForeachFunc callback, + gpointer closure); +EPrintable *e_table_scrolled_get_printable (ETableScrolled *ets); END_GNOME_DECLS diff --git a/widgets/table/e-table-sort-info.c b/widgets/table/e-table-sort-info.c index 87fa818163..aebda2c207 100644 --- a/widgets/table/e-table-sort-info.c +++ b/widgets/table/e-table-sort-info.c @@ -11,6 +11,7 @@ #include <gtk/gtksignal.h> #include "e-table-sort-info.h" #include "gal/util/e-util.h" +#include "gal/util/e-xml-utils.h" #define ETM_CLASS(e) ((ETableSortInfoClass *)((GtkObject *)e)->klass) @@ -236,3 +237,61 @@ e_table_sort_info_new (void) { return gtk_type_new (e_table_sort_info_get_type ()); } + +void +e_table_sort_info_load_from_node (ETableSortInfo *info, + xmlNode *node) +{ + int i; + xmlNode *grouping; + + i = 0; + for (grouping = node->childs; grouping && !strcmp (grouping->name, "group"); 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(info, i++, column); + } + i = 0; + for (; 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_sorting_set_nth(info, i++, column); + } +} + +xmlNode * +e_table_sort_info_save_to_node (ETableSortInfo *info, + xmlNode *parent) +{ + xmlNode *grouping; + xmlNode *node; + int i; + const int sort_count = e_table_sort_info_sorting_get_count (info); + const int group_count = e_table_sort_info_grouping_get_count (info); + + grouping = xmlNewChild (parent, NULL, "grouping", NULL); + node = grouping; + + for (i = 0; i < group_count; i++) { + ETableSortColumn column = e_table_sort_info_grouping_get_nth(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; + } + + for (i = 0; i < sort_count; i++) { + ETableSortColumn column = e_table_sort_info_sorting_get_nth(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-sort-info.h b/widgets/table/e-table-sort-info.h index 6446230116..78ecbed29f 100644 --- a/widgets/table/e-table-sort-info.h +++ b/widgets/table/e-table-sort-info.h @@ -3,6 +3,7 @@ #define _E_TABLE_SORT_INFO_H_ #include <gtk/gtkobject.h> +#include <gnome-xml/tree.h> #define E_TABLE_SORT_INFO_TYPE (e_table_sort_info_get_type ()) #define E_TABLE_SORT_INFO(o) (GTK_CHECK_CAST ((o), E_TABLE_SORT_INFO_TYPE, ETableSortInfo)) @@ -40,21 +41,33 @@ typedef struct { 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); +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_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); +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); -ETableSortInfo *e_table_sort_info_new (void); +ETableSortInfo *e_table_sort_info_new (void); +void e_table_sort_info_load_from_node (ETableSortInfo *info, + xmlNode *node); +xmlNode *e_table_sort_info_save_to_node (ETableSortInfo *info, + xmlNode *parent); #endif /* _E_TABLE_SORT_INFO_H_ */ diff --git a/widgets/table/e-table-specification.c b/widgets/table/e-table-specification.c new file mode 100644 index 0000000000..d95c5147c8 --- /dev/null +++ b/widgets/table/e-table-specification.c @@ -0,0 +1,196 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * E-table-specification.c: Implements a savable description of the inital state of a table. + * + * Author: + * Chris Lahey <clahey@helixcode.com> + * + * (C) 2000 Helix Code, Inc. + */ +#include <config.h> +#include <stdlib.h> +#include <gtk/gtksignal.h> +#include <gnome-xml/parser.h> +#include <gnome-xml/xmlmemory.h> +#include "gal/util/e-util.h" +#include "gal/util/e-xml-utils.h" +#include "e-table-specification.h" + +#define PARENT_TYPE (gtk_object_get_type()) + +static GtkObjectClass *etsp_parent_class; + +static void +etsp_destroy (GtkObject *object) +{ + ETableSpecification *etsp = E_TABLE_SPECIFICATION (object); + int i; + + if (etsp->columns) { + for (i = 0; etsp->columns[i]; i++) { + gtk_object_unref (GTK_OBJECT (etsp->columns[i])); + } + g_free(etsp->columns); + } + + if (etsp->state) + gtk_object_unref(GTK_OBJECT(etsp->state)); + g_free(etsp->click_to_add_message_); + + etsp->columns = NULL; + etsp->state = NULL; + etsp->click_to_add_message_ = NULL; + + GTK_OBJECT_CLASS (etsp_parent_class)->destroy (object); +} + +static void +etsp_class_init (GtkObjectClass *klass) +{ + etsp_parent_class = gtk_type_class (PARENT_TYPE); + + klass->destroy = etsp_destroy; +} + +static void +etsp_init (ETableSpecification *etsp) +{ + etsp->columns = NULL; + etsp->state = NULL; + + etsp->no_headers = FALSE; + etsp->click_to_add = FALSE; + etsp->draw_grid = FALSE; + etsp->cursor_mode = E_TABLE_CURSOR_SIMPLE; + + etsp->click_to_add_message_ = NULL; +} + +E_MAKE_TYPE(e_table_specification, "ETableSpecification", ETableSpecification, etsp_class_init, etsp_init, PARENT_TYPE); + +ETableSpecification * +e_table_specification_new (void) +{ + ETableSpecification *etsp = gtk_type_new (E_TABLE_SPECIFICATION_TYPE); + + return (ETableSpecification *) etsp; +} + +gboolean +e_table_specification_load_from_file (ETableSpecification *specification, + const char *filename) +{ + xmlDoc *doc; + doc = xmlParseFile (filename); + if (doc) { + xmlNode *node = xmlDocGetRootElement(doc); + e_table_specification_load_from_node(specification, node); + xmlFreeDoc(doc); + return TRUE; + } + return FALSE; +} + +void +e_table_specification_load_from_string (ETableSpecification *specification, + const char *xml) +{ + xmlDoc *doc; + doc = xmlParseMemory ((char *) xml, strlen(xml)); + if (doc) { + xmlNode *node = xmlDocGetRootElement(doc); + e_table_specification_load_from_node(specification, node); + xmlFreeDoc(doc); + } +} + +void +e_table_specification_load_from_node (ETableSpecification *specification, + const xmlNode *node) +{ + char *temp; + xmlNode *children; + GList *list = NULL, *list2; + int i; + + specification->no_headers = e_xml_get_bool_prop_by_name(node, "no-headers"); + specification->click_to_add = e_xml_get_bool_prop_by_name(node, "click-to-add"); + specification->draw_grid = e_xml_get_bool_prop_by_name(node, "draw-grid"); + + specification->cursor_mode = E_TABLE_CURSOR_SIMPLE; + temp = e_xml_get_string_prop_by_name(node, "cursor-mode"); + if (temp && strcasecmp(temp, "line")) { + specification->cursor_mode = E_TABLE_CURSOR_LINE; + } + g_free(temp); + + g_free(specification->click_to_add_message_); + + specification->click_to_add_message_ = e_xml_get_translated_string_prop_by_name(node, "_click-to-add-message"); + + if (specification->state) + gtk_object_unref(GTK_OBJECT(specification->state)); + specification->state = NULL; + if (specification->columns) { + for (i = 0; specification->columns[i]; i++) { + gtk_object_unref(GTK_OBJECT(specification->columns[i])); + } + g_free(specification->columns); + } + specification->columns = NULL; + + for (children = node->xmlChildrenNode; children; children = children->next) { + if (!strcmp(children->name, "ETableColumn")) { + ETableColumnSpecification *col_spec = e_table_column_specification_new(); + + e_table_column_specification_load_from_node(col_spec, children); + list = g_list_append(list, col_spec); + } else if (specification->state == NULL && !strcmp(children->name, "ETableState")) { + specification->state = e_table_state_new(); + e_table_state_load_from_node(specification->state, children); + } + } + + specification->columns = g_new(ETableColumnSpecification *, g_list_length(list) + 1); + for (list2 = list, i = 0; list2; list2 = g_list_next(list2), i++) { + specification->columns[i] = list2->data; + } + specification->columns[i] = NULL; + g_list_free(list); +} + +#if 0 +void +e_table_specification_save_to_file (ETableSpecification *specification, + const char *filename) +{ + xmlDoc *doc; + doc = xmlNewDoc(NULL); + xmlDocSetRootElement(doc, e_table_specification_save_to_node(specification, doc)); + xmlSaveFile(filename, doc); +} + +char * +e_table_specification_save_to_string (ETableSpecification *specification) +{ + char *ret_val; + xmlChar *string; + int length; + xmlDoc *doc; + + doc = xmlNewDoc(NULL); + xmlDocSetRootElement(doc, e_table_specification_save_to_node(specification, doc)); + xmlDocDumpMemory(doc, &string, &length); + + ret_val = g_strdup(string); + xmlFree(string); + return ret_val; +} + +xmlNode * +e_table_specification_save_to_node (ETableSpecification *specification, + xmlDoc *doc) +{ + return NULL; +} +#endif diff --git a/widgets/table/e-table-specification.h b/widgets/table/e-table-specification.h new file mode 100644 index 0000000000..51adc0d66e --- /dev/null +++ b/widgets/table/e-table-specification.h @@ -0,0 +1,52 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +#ifndef _E_TABLE_SPECIFICATION_H_ +#define _E_TABLE_SPECIFICATION_H_ + +#include <gtk/gtkobject.h> +#include <gnome-xml/tree.h> +#include <gal/e-table/e-table-state.h> +#include <gal/e-table/e-table-column-specification.h> +#include <gal/e-table/e-table-defines.h> + +#define E_TABLE_SPECIFICATION_TYPE (e_table_specification_get_type ()) +#define E_TABLE_SPECIFICATION(o) (GTK_CHECK_CAST ((o), E_TABLE_SPECIFICATION_TYPE, ETableSpecification)) +#define E_TABLE_SPECIFICATION_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_SPECIFICATION_TYPE, ETableSpecificationClass)) +#define E_IS_TABLE_SPECIFICATION(o) (GTK_CHECK_TYPE ((o), E_TABLE_SPECIFICATION_TYPE)) +#define E_IS_TABLE_SPECIFICATION_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_SPECIFICATION_TYPE)) + +typedef struct { + GtkObject base; + + ETableColumnSpecification **columns; + ETableState *state; + + guint no_headers : 1; + guint click_to_add : 1; + guint draw_grid : 1; + ETableCursorMode cursor_mode; + char *click_to_add_message_; +} ETableSpecification; + +typedef struct { + GtkObjectClass parent_class; +} ETableSpecificationClass; + +GtkType e_table_specification_get_type (void); +ETableSpecification *e_table_specification_new (void); + +gboolean e_table_specification_load_from_file (ETableSpecification *specification, + const char *filename); +void e_table_specification_load_from_string (ETableSpecification *specification, + const char *xml); +void e_table_specification_load_from_node (ETableSpecification *specification, + const xmlNode *node); + +#if 0 +void e_table_specification_save_to_file (ETableSpecification *specification, + const char *filename); +char *e_table_specification_save_to_string (ETableSpecification *specification); +xmlNode *e_table_specification_save_to_node (ETableSpecification *specification, + xmlDoc *doc); +#endif + +#endif /* _E_TABLE_SPECIFICATION_H_ */ diff --git a/widgets/table/e-table-state.c b/widgets/table/e-table-state.c new file mode 100644 index 0000000000..1912dd1ce8 --- /dev/null +++ b/widgets/table/e-table-state.c @@ -0,0 +1,161 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * E-table-state.c: Savable state of a table. + * + * Author: + * Chris Lahey <clahey@helixcode.com> + * + * (C) 2000 Helix Code, Inc. + */ +#include <config.h> +#include <stdlib.h> +#include <gtk/gtksignal.h> +#include <gnome-xml/parser.h> +#include <gnome-xml/xmlmemory.h> +#include "gal/util/e-util.h" +#include "gal/util/e-xml-utils.h" +#include "e-table-state.h" + +#define PARENT_TYPE (gtk_object_get_type()) + +static GtkObjectClass *etst_parent_class; + +static void +etst_destroy (GtkObject *object) +{ +#if 0 + ETableState *etst = E_TABLE_STATE (object); +#endif + + GTK_OBJECT_CLASS (etst_parent_class)->destroy (object); +} + +static void +etst_class_init (GtkObjectClass *klass) +{ + etst_parent_class = gtk_type_class (PARENT_TYPE); + + klass->destroy = etst_destroy; +} + +E_MAKE_TYPE(e_table_state, "ETableState", ETableState, etst_class_init, NULL, PARENT_TYPE); + +ETableState * +e_table_state_new (void) +{ + ETableState *etst = gtk_type_new (E_TABLE_STATE_TYPE); + + return (ETableState *) etst; +} + +gboolean +e_table_state_load_from_file (ETableState *state, + const char *filename) +{ + xmlDoc *doc; + doc = xmlParseFile (filename); + if (doc) { + xmlNode *node = xmlDocGetRootElement(doc); + e_table_state_load_from_node(state, node); + xmlFreeDoc(doc); + return TRUE; + } + return FALSE; +} + +void +e_table_state_load_from_string (ETableState *state, + const char *xml) +{ + xmlDoc *doc; + doc = xmlParseMemory ((char *) xml, strlen(xml)); + if (doc) { + xmlNode *node = xmlDocGetRootElement(doc); + e_table_state_load_from_node(state, node); + xmlFreeDoc(doc); + } +} + +void +e_table_state_load_from_node (ETableState *state, + const xmlNode *node) +{ + xmlNode *children; + GList *list = NULL, *iterator; + int i; + + if (state->sort_info) + gtk_object_unref(GTK_OBJECT(state->sort_info)); + state->sort_info = NULL; + for (children = node->xmlChildrenNode; children; children = children->next) { + if (!strcmp(children->name, "column")) { + int *column = g_new(int, 1); + + *column = e_xml_get_integer_prop_by_name(children, "source"); + + list = g_list_append(list, column); + } else if (state->sort_info == NULL && !strcmp(children->name, "grouping")) { + state->sort_info = e_table_sort_info_new(); + e_table_sort_info_load_from_node(state->sort_info, children); + } + } + g_free(state->columns); + state->col_count = g_list_length(list); + state->columns = g_new(int, state->col_count); + for (iterator = list, i = 0; iterator; iterator = g_list_next(iterator), i++) { + state->columns[i] = *(int *)iterator->data; + g_free(iterator->data); + } + g_list_free(list); +} + +void +e_table_state_save_to_file (ETableState *state, + const char *filename) +{ + xmlDoc *doc; + doc = xmlNewDoc(NULL); + xmlDocSetRootElement(doc, e_table_state_save_to_node(state, NULL)); + xmlSaveFile(filename, doc); +} + +char * +e_table_state_save_to_string (ETableState *state) +{ + char *ret_val; + xmlChar *string; + int length; + xmlDoc *doc; + + doc = xmlNewDoc(NULL); + xmlDocSetRootElement(doc, e_table_state_save_to_node(state, NULL)); + xmlDocDumpMemory(doc, &string, &length); + + ret_val = g_strdup(string); + xmlFree(string); + return ret_val; +} + +xmlNode * +e_table_state_save_to_node (ETableState *state, + xmlNode *parent) +{ + int i; + xmlNode *node; + if (parent) + node = xmlNewChild (parent, NULL, "ETableState", NULL); + else + node = xmlNewNode (NULL, "ETableState"); + + for (i = 0; i < state->col_count; i++) { + int column = state->columns[i]; + xmlNode *new_node; + + new_node = xmlNewChild(node, NULL, "column", NULL); + e_xml_set_integer_prop_by_name (new_node, "source", column); + } + + e_table_sort_info_save_to_node(state->sort_info, node); + + return node; +} diff --git a/widgets/table/e-table-state.h b/widgets/table/e-table-state.h new file mode 100644 index 0000000000..0ef8471166 --- /dev/null +++ b/widgets/table/e-table-state.h @@ -0,0 +1,43 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +#ifndef _E_TABLE_STATE_H_ +#define _E_TABLE_STATE_H_ + +#include <gtk/gtkobject.h> +#include <gnome-xml/tree.h> +#include <gal/e-table/e-table-sort-info.h> + +#define E_TABLE_STATE_TYPE (e_table_state_get_type ()) +#define E_TABLE_STATE(o) (GTK_CHECK_CAST ((o), E_TABLE_STATE_TYPE, ETableState)) +#define E_TABLE_STATE_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_STATE_TYPE, ETableStateClass)) +#define E_IS_TABLE_STATE(o) (GTK_CHECK_TYPE ((o), E_TABLE_STATE_TYPE)) +#define E_IS_TABLE_STATE_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_STATE_TYPE)) + +typedef struct { + GtkObject base; + + ETableSortInfo *sort_info; + int col_count; + int *columns; +} ETableState; + +typedef struct { + GtkObjectClass parent_class; +} ETableStateClass; + +GtkType e_table_state_get_type (void); +ETableState *e_table_state_new (void); + +gboolean e_table_state_load_from_file (ETableState *state, + const char *filename); +void e_table_state_load_from_string (ETableState *state, + const char *xml); +void e_table_state_load_from_node (ETableState *state, + const xmlNode *node); + +void e_table_state_save_to_file (ETableState *state, + const char *filename); +char *e_table_state_save_to_string (ETableState *state); +xmlNode *e_table_state_save_to_node (ETableState *state, + xmlNode *parent); + +#endif /* _E_TABLE_STATE_H_ */ diff --git a/widgets/table/e-table.c b/widgets/table/e-table.c index a9598c214f..2e14d0374c 100644 --- a/widgets/table/e-table.c +++ b/widgets/table/e-table.c @@ -18,11 +18,8 @@ #include <stdio.h> #include <libgnomeui/gnome-canvas.h> #include <gtk/gtksignal.h> -#include <gnome-xml/parser.h> -#include <gnome-xml/xmlmemory.h> #include "gal/util/e-util.h" -#include "gal/util/e-xml-utils.h" #include "gal/widgets/e-canvas.h" #include "gal/widgets/e-canvas-vbox.h" #include "e-table.h" @@ -32,6 +29,9 @@ #include "e-table-group.h" #include "e-table-group-leaf.h" #include "e-table-click-to-add.h" +#include "e-table-specification.h" +#include "e-table-state.h" +#include "e-table-column-specification.h" #define COLUMN_HEADER_HEIGHT 16 @@ -594,26 +594,74 @@ e_table_fill_table (ETable *e_table, ETableModel *model) e_table_group_add_all (e_table->group); } +static ETableCol * +et_col_spec_to_col (ETable *e_table, ETableColumnSpecification *col_spec, ETableExtras *ete) +{ + ETableCol *col = NULL; + ECell *cell; + GCompareFunc compare; + + cell = e_table_extras_get_cell(ete, col_spec->cell); + compare = e_table_extras_get_compare(ete, col_spec->compare); + + if (cell && compare) { + if (col_spec->title_ && *col_spec->title_) { + col = e_table_col_new (col_spec->model_col, col_spec->title_, + col_spec->expansion, col_spec->minimum_width, + cell, compare, col_spec->resizable); + } else if (col_spec->pixbuf && *col_spec->pixbuf) { + GdkPixbuf *pixbuf; + + pixbuf = e_table_extras_get_pixbuf(ete, col_spec->pixbuf); + if (pixbuf) { + col = e_table_col_new_with_pixbuf (col_spec->model_col, pixbuf, + col_spec->expansion, col_spec->minimum_width, + cell, compare, col_spec->resizable); + } + } + } + return col; +} + static ETableHeader * -et_xml_to_header (ETable *e_table, ETableHeader *full_header, xmlNode *xmlColumns) +et_spec_to_full_header (ETable *e_table, ETableSpecification *spec, ETableExtras *ete) +{ + ETableHeader *nh; + int column; + + g_return_val_if_fail (e_table, NULL); + g_return_val_if_fail (spec, NULL); + g_return_val_if_fail (ete, NULL); + + nh = e_table_header_new (); + + for (column = 0; spec->columns[column]; column++) { + ETableCol *col = et_col_spec_to_col(e_table, spec->columns[column], ete); + + if (col) + e_table_header_add_column (nh, col, -1); + } + + return nh; +} + +static ETableHeader * +et_state_to_header (ETable *e_table, ETableHeader *full_header, ETableState *state) { ETableHeader *nh; - xmlNode *column; const int max_cols = e_table_header_count (full_header); + int column; g_return_val_if_fail (e_table, NULL); g_return_val_if_fail (full_header, NULL); - g_return_val_if_fail (xmlColumns, NULL); + g_return_val_if_fail (state, NULL); nh = e_table_header_new (); - for (column = xmlColumns->childs; column; column = column->next) { - gchar *content; + for (column = 0; column < state->col_count; column++) { int col; - content = xmlNodeListGetString (column->doc, column->childs, 1); - col = atoi (content); - xmlFree (content); + col = state->columns[column]; if (col >= max_cols) continue; @@ -625,105 +673,93 @@ et_xml_to_header (ETable *e_table, ETableHeader *full_header, xmlNode *xmlColumn } static void -et_xml_config_header (ETable *e_table, xmlNode *xmlColumns) +et_set_state(ETable *e_table, ETableState *state) { - xmlNode *column; - const int max_cols = e_table_header_count(e_table->full_header); - int i; - - for (i=e_table_header_count(e_table->header)-1;i>=0;i--) { - e_table_header_remove(e_table->header, i); - } - - for (column = xmlColumns->childs; column; column = column->next) { - char *content; - int col; + if (e_table->header) + gtk_object_unref(GTK_OBJECT(e_table->header)); + e_table->header = et_state_to_header (e_table, e_table->full_header, state); + if (e_table->header) + gtk_object_ref(GTK_OBJECT(e_table->header)); - content = xmlNodeListGetString (column->doc, column->childs, 1); - col = atoi (content); - xmlFree (content); + if (e_table->sort_info) + gtk_object_unref(GTK_OBJECT(e_table->sort_info)); + e_table->sort_info = state->sort_info; + if (e_table->sort_info) + gtk_object_ref(GTK_OBJECT(e_table->sort_info)); - if (col >= max_cols) - continue; + if (e_table->header_item) + gtk_object_set(GTK_OBJECT(e_table->header_item), + "ETableHeader", e_table->header, + "sort_info", e_table->sort_info, + NULL); + if (e_table->click_to_add) + gtk_object_set(GTK_OBJECT(e_table->click_to_add), + "header", e_table->header, + NULL); - e_table_header_add_column (e_table->header, e_table_header_get_column (e_table->full_header, col), -1); - } + e_table->need_rebuild = TRUE; + if (!e_table->rebuild_idle_id) + e_table->rebuild_idle_id = g_idle_add_full (20, changed_idle, e_table, NULL); } -static void -et_grouping_xml_to_sort_info (ETable *table, xmlNode *grouping) +void e_table_set_state (ETable *e_table, + const gchar *state_str) { - int i; + ETableState *state; - g_return_if_fail (table!=NULL); - g_return_if_fail (grouping!=NULL); - - table->sort_info = e_table_sort_info_new (); - - gtk_object_ref (GTK_OBJECT (table->sort_info)); - gtk_object_sink (GTK_OBJECT (table->sort_info)); - - i = 0; - for (grouping = grouping->childs; grouping && !strcmp (grouping->name, "group"); 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(table->sort_info, i++, column); - } - i = 0; - for (; 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_sorting_set_nth(table->sort_info, i++, column); - } + g_return_if_fail(e_table != NULL); + g_return_if_fail(E_IS_TABLE(e_table)); + g_return_if_fail(state_str != NULL); - table->group_info_change_id = - gtk_signal_connect (GTK_OBJECT (table->sort_info), "group_info_changed", - GTK_SIGNAL_FUNC (sort_info_changed), table); + state = e_table_state_new(); + e_table_state_load_from_string(state, state_str); + + et_set_state(e_table, state); + + gtk_object_sink(GTK_OBJECT(state)); } -static int -et_real_set_specification (ETable *e_table, xmlDoc *xmlSpec) +void e_table_load_state (ETable *e_table, + const gchar *filename) { - xmlNode *xmlRoot; - xmlNode *xmlColumns; - xmlNode *xmlGrouping; + ETableState *state; + + g_return_if_fail(e_table != NULL); + g_return_if_fail(E_IS_TABLE(e_table)); + g_return_if_fail(filename != NULL); + + state = e_table_state_new(); + e_table_state_load_from_file(state, filename); - xmlRoot = xmlDocGetRootElement (xmlSpec); - xmlColumns = e_xml_get_child_by_name (xmlRoot, "columns-shown"); - xmlGrouping = e_xml_get_child_by_name (xmlRoot, "grouping"); + et_set_state(e_table, state); - if ((xmlColumns == NULL) || (xmlGrouping == NULL)) - return -1; + gtk_object_sink(GTK_OBJECT(state)); +} - et_xml_config_header(e_table, xmlColumns); +gchar *e_table_get_state (ETable *e_table) +{ + return NULL; +} - return 0; +void e_table_save_state (ETable *e_table, + const gchar *filename) +{ } + static ETable * -et_real_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm, - xmlDoc *xmlSpec) +et_real_construct (ETable *e_table, ETableModel *etm, ETableExtras *ete, + ETableSpecification *specification, ETableState *state) { - xmlNode *xmlRoot; - xmlNode *xmlColumns; - xmlNode *xmlGrouping; - gboolean no_header; int row = 0; - xmlRoot = xmlDocGetRootElement (xmlSpec); - xmlColumns = e_xml_get_child_by_name (xmlRoot, "columns-shown"); - xmlGrouping = e_xml_get_child_by_name (xmlRoot, "grouping"); - - if ((xmlColumns == NULL) || (xmlGrouping == NULL)) - return NULL; + if (ete) + gtk_object_ref(GTK_OBJECT(ete)); + else + ete = e_table_extras_new(); - no_header = e_xml_get_integer_prop_by_name(xmlRoot, "no-header"); - e_table->use_click_to_add = e_xml_get_integer_prop_by_name(xmlRoot, "click-to-add"); - - e_table->full_header = full_header; - gtk_object_ref (GTK_OBJECT (full_header)); + e_table->use_click_to_add = specification->click_to_add; + e_table->full_header = et_spec_to_full_header(e_table, specification, ete); e_table->model = etm; gtk_object_ref (GTK_OBJECT (etm)); @@ -731,8 +767,13 @@ et_real_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm, gtk_widget_push_visual (gdk_rgb_get_visual ()); gtk_widget_push_colormap (gdk_rgb_get_cmap ()); - e_table->header = et_xml_to_header (e_table, full_header, xmlColumns); - et_grouping_xml_to_sort_info (e_table, xmlGrouping); + e_table->header = et_state_to_header (e_table, e_table->full_header, state); + e_table->sort_info = state->sort_info; + + 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); + gtk_object_set(GTK_OBJECT(e_table->header), "sort_info", e_table->sort_info, @@ -745,16 +786,16 @@ et_real_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm, "sorter", e_table->sorter, NULL); - if (!no_header) { + if (!specification->no_headers) { e_table_setup_header (e_table); } - e_table_setup_table (e_table, full_header, e_table->header, etm); + e_table_setup_table (e_table, e_table->full_header, e_table->header, etm); e_table_fill_table (e_table, etm); gtk_layout_get_vadjustment (GTK_LAYOUT (e_table->table_canvas))->step_increment = 20; gtk_adjustment_changed(gtk_layout_get_vadjustment (GTK_LAYOUT (e_table->table_canvas))); - if (!no_header) { + if (!specification->no_headers) { /* * The header */ @@ -773,91 +814,120 @@ et_real_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm, gtk_widget_pop_colormap (); gtk_widget_pop_visual (); + gtk_object_unref(GTK_OBJECT(ete)); + return e_table; } ETable * -e_table_construct (ETable *e_table, ETableHeader *full_header, - ETableModel *etm, const char *spec) +e_table_construct (ETable *e_table, ETableModel *etm, ETableExtras *ete, + const char *spec_str, const char *state_str) { - xmlDoc *xmlSpec; - char *copy; + ETableSpecification *specification; + ETableState *state; g_return_val_if_fail(e_table != NULL, NULL); g_return_val_if_fail(E_IS_TABLE(e_table), NULL); - g_return_val_if_fail(full_header != NULL, NULL); - g_return_val_if_fail(E_IS_TABLE_HEADER(full_header), NULL); g_return_val_if_fail(etm != NULL, NULL); g_return_val_if_fail(E_IS_TABLE_MODEL(etm), NULL); - g_return_val_if_fail(spec != NULL, NULL); + g_return_val_if_fail(ete == NULL || E_IS_TABLE_EXTRAS(ete), NULL); + g_return_val_if_fail(spec_str != NULL, NULL); + + specification = e_table_specification_new(); + e_table_specification_load_from_string(specification, spec_str); + if (state_str) { + state = e_table_state_new(); + e_table_state_load_from_string(state, state_str); + } else { + state = specification->state; + gtk_object_ref(GTK_OBJECT(state)); + } - copy = g_strdup (spec); + e_table = et_real_construct (e_table, etm, ete, specification, state); - xmlSpec = xmlParseMemory (copy, strlen(copy)); - e_table = et_real_construct (e_table, full_header, etm, xmlSpec); - xmlFreeDoc (xmlSpec); - g_free (copy); + gtk_object_unref(GTK_OBJECT(specification)); + gtk_object_unref(GTK_OBJECT(state)); return e_table; } ETable * -e_table_construct_from_spec_file (ETable *e_table, ETableHeader *full_header, ETableModel *etm, - const char *filename) +e_table_construct_from_spec_file (ETable *e_table, ETableModel *etm, ETableExtras *ete, + const char *spec_fn, const char *state_fn) { - xmlDoc *xmlSpec; + ETableSpecification *specification; + ETableState *state; g_return_val_if_fail(e_table != NULL, NULL); g_return_val_if_fail(E_IS_TABLE(e_table), NULL); - g_return_val_if_fail(full_header != NULL, NULL); - g_return_val_if_fail(E_IS_TABLE_HEADER(full_header), NULL); g_return_val_if_fail(etm != NULL, NULL); g_return_val_if_fail(E_IS_TABLE_MODEL(etm), NULL); - g_return_val_if_fail(filename != NULL, NULL); + g_return_val_if_fail(ete == NULL || E_IS_TABLE_EXTRAS(ete), NULL); + g_return_val_if_fail(spec_fn != NULL, NULL); - xmlSpec = xmlParseFile (filename); - e_table = et_real_construct (e_table, full_header, etm, xmlSpec); - xmlFreeDoc (xmlSpec); + specification = e_table_specification_new(); + if (!e_table_specification_load_from_file(specification, spec_fn)) { + gtk_object_unref(GTK_OBJECT(specification)); + return NULL; + } + + if (state_fn) { + state = e_table_state_new(); + if (!e_table_state_load_from_file(state, state_fn)) { + gtk_object_unref(GTK_OBJECT(state)); + state = specification->state; + gtk_object_ref(GTK_OBJECT(state)); + } + } else { + state = specification->state; + gtk_object_ref(GTK_OBJECT(state)); + } + + e_table = et_real_construct (e_table, etm, ete, specification, state); + + gtk_object_unref(GTK_OBJECT(specification)); + gtk_object_unref(GTK_OBJECT(state)); return e_table; } GtkWidget * -e_table_new (ETableHeader *full_header, ETableModel *etm, const char *spec) +e_table_new (ETableModel *etm, ETableExtras *ete, const char *spec, const char *state) { ETable *e_table; - g_return_val_if_fail(full_header != NULL, NULL); - g_return_val_if_fail(E_IS_TABLE_HEADER(full_header), NULL); g_return_val_if_fail(etm != NULL, NULL); g_return_val_if_fail(E_IS_TABLE_MODEL(etm), NULL); + g_return_val_if_fail(ete == NULL || E_IS_TABLE_EXTRAS(ete), NULL); g_return_val_if_fail(spec != NULL, NULL); e_table = gtk_type_new (e_table_get_type ()); - e_table = e_table_construct (e_table, full_header, etm, spec); + e_table = e_table_construct (e_table, etm, ete, spec, state); return GTK_WIDGET (e_table); } GtkWidget * -e_table_new_from_spec_file (ETableHeader *full_header, ETableModel *etm, const char *filename) +e_table_new_from_spec_file (ETableModel *etm, ETableExtras *ete, const char *spec_fn, const char *state_fn) { ETable *e_table; - g_return_val_if_fail(full_header != NULL, NULL); - g_return_val_if_fail(E_IS_TABLE_HEADER(full_header), NULL); g_return_val_if_fail(etm != NULL, NULL); g_return_val_if_fail(E_IS_TABLE_MODEL(etm), NULL); - g_return_val_if_fail(filename != NULL, NULL); + g_return_val_if_fail(ete == NULL || E_IS_TABLE_EXTRAS(ete), NULL); + g_return_val_if_fail(spec_fn != NULL, NULL); e_table = gtk_type_new (e_table_get_type ()); - e_table = e_table_construct_from_spec_file (e_table, full_header, etm, filename); + e_table = e_table_construct_from_spec_file (e_table, etm, ete, spec_fn, state_fn); - return (GtkWidget *) e_table; + return GTK_WIDGET (e_table); } + + +#if 0 static xmlNode * et_build_column_spec (ETable *e_table) { @@ -993,6 +1063,7 @@ e_table_load_specification (ETable *e_table, gchar *filename) return ret; } +#endif void e_table_set_cursor_row (ETable *e_table, int row) diff --git a/widgets/table/e-table.h b/widgets/table/e-table.h index d5462ce65c..933f0f5155 100644 --- a/widgets/table/e-table.h +++ b/widgets/table/e-table.h @@ -11,6 +11,7 @@ #include <gal/e-table/e-table-sort-info.h> #include <gal/e-table/e-table-item.h> #include <gal/e-table/e-table-selection-model.h> +#include <gal/e-table/e-table-extras.h> #include <gal/widgets/e-printable.h> BEGIN_GNOME_DECLS @@ -156,103 +157,110 @@ typedef struct { guint time); } ETableClass; -GtkType e_table_get_type (void); - -ETable *e_table_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm, - const char *spec); -GtkWidget *e_table_new (ETableHeader *full_header, ETableModel *etm, - const char *spec); - -ETable *e_table_construct_from_spec_file (ETable *e_table, - ETableHeader *full_header, - ETableModel *etm, - const char *filename); -GtkWidget *e_table_new_from_spec_file (ETableHeader *full_header, - ETableModel *etm, - const char *filename); - -gchar *e_table_get_specification (ETable *e_table); -void e_table_save_specification (ETable *e_table, gchar *filename); -/* note that it is more efficient to provide the spec at creation time */ -int e_table_set_specification (ETable *e_table, const char *spec); -int e_table_load_specification (ETable *e_table, gchar *filename); - -void e_table_set_cursor_row (ETable *e_table, - int row); +GtkType e_table_get_type (void); + +ETable *e_table_construct (ETable *e_table, + ETableModel *etm, + ETableExtras *ete, + const char *spec, + const char *state); +GtkWidget *e_table_new (ETableModel *etm, + ETableExtras *ete, + const char *spec, + const char *state); + +/* Create an ETable using files. */ +ETable *e_table_construct_from_spec_file (ETable *e_table, + ETableModel *etm, + ETableExtras *ete, + const char *spec_fn, + const char *state_fn); +GtkWidget *e_table_new_from_spec_file (ETableModel *etm, + ETableExtras *ete, + const char *spec_fn, + const char *state_fn); + +/* To save the state */ +gchar *e_table_get_state (ETable *e_table); +void e_table_save_state (ETable *e_table, + const gchar *filename); + +/* note that it is more efficient to provide the state at creation time */ +void e_table_set_state (ETable *e_table, + const gchar *state); +void e_table_load_state (ETable *e_table, + const gchar *filename); + +void e_table_set_cursor_row (ETable *e_table, + int row); + /* -1 means we don't have the cursor. */ -int e_table_get_cursor_row (ETable *e_table); -void e_table_selected_row_foreach (ETable *e_table, - ETableForeachFunc callback, - gpointer closure); -EPrintable *e_table_get_printable (ETable *e_table); +int e_table_get_cursor_row (ETable *e_table); +void e_table_selected_row_foreach (ETable *e_table, + ETableForeachFunc callback, + gpointer closure); +EPrintable *e_table_get_printable (ETable *e_table); -gint e_table_get_next_row (ETable *e_table, - gint model_row); -gint e_table_get_prev_row (ETable *e_table, - gint model_row); +gint e_table_get_next_row (ETable *e_table, + gint model_row); +gint e_table_get_prev_row (ETable *e_table, + gint model_row); -gint e_table_model_to_view_row (ETable *e_table, - gint model_row); -gint e_table_view_to_model_row (ETable *e_table, - gint view_row); +gint e_table_model_to_view_row (ETable *e_table, + gint model_row); +gint e_table_view_to_model_row (ETable *e_table, + gint view_row); /* Drag & drop stuff. */ /* Target */ -void e_table_drag_get_data (ETable *table, - int row, - int col, - GdkDragContext *context, - GdkAtom target, - guint32 time); - -void e_table_drag_highlight (ETable *table, - int row, - int col); /* col == -1 to highlight entire row. */ -void e_table_drag_unhighlight (ETable *table); - -void e_table_drag_dest_set (ETable *table, - GtkDestDefaults flags, - const GtkTargetEntry *targets, - gint n_targets, - GdkDragAction actions); - -void e_table_drag_dest_set_proxy (ETable *table, - GdkWindow *proxy_window, - GdkDragProtocol protocol, - gboolean use_coordinates); +void e_table_drag_get_data (ETable *table, + int row, + int col, + GdkDragContext *context, + GdkAtom target, + guint32 time); +void e_table_drag_highlight (ETable *table, + int row, + int col); /* col == -1 to highlight entire row. */ +void e_table_drag_unhighlight (ETable *table); +void e_table_drag_dest_set (ETable *table, + GtkDestDefaults flags, + const GtkTargetEntry *targets, + gint n_targets, + GdkDragAction actions); +void e_table_drag_dest_set_proxy (ETable *table, + GdkWindow *proxy_window, + GdkDragProtocol protocol, + gboolean use_coordinates); /* There probably should be functions for setting the targets * as a GtkTargetList */ - -void e_table_drag_dest_unset (GtkWidget *widget); +void e_table_drag_dest_unset (GtkWidget *widget); /* Source side */ - -void e_table_drag_source_set (ETable *table, - GdkModifierType start_button_mask, - const GtkTargetEntry *targets, - gint n_targets, - GdkDragAction actions); - -void e_table_drag_source_unset (ETable *table); +void e_table_drag_source_set (ETable *table, + GdkModifierType start_button_mask, + const GtkTargetEntry *targets, + gint n_targets, + GdkDragAction actions); +void e_table_drag_source_unset (ETable *table); /* There probably should be functions for setting the targets * as a GtkTargetList */ - -GdkDragContext *e_table_drag_begin (ETable *table, - int row, - int col, - GtkTargetList *targets, - GdkDragAction actions, - gint button, - GdkEvent *event); +GdkDragContext *e_table_drag_begin (ETable *table, + int row, + int col, + GtkTargetList *targets, + GdkDragAction actions, + gint button, + GdkEvent *event); /* selection stuff */ -void e_table_select_all (ETable *table); -void e_table_invert_selection (ETable *table); +void e_table_select_all (ETable *table); +void e_table_invert_selection (ETable *table); END_GNOME_DECLS diff --git a/widgets/table/e-tree-model.c b/widgets/table/e-tree-model.c index 7687b5b185..a9c10343e5 100644 --- a/widgets/table/e-tree-model.c +++ b/widgets/table/e-tree-model.c @@ -361,7 +361,6 @@ static const char * etable_row_sort_group(ETableModel *etm, int row) { ETreeModel *etree = E_TREE_MODEL(etm); - ETreeModelClass *et_class = ETM_CLASS(etm); ETreePath* node = e_tree_model_node_at_row (etree, row); g_return_val_if_fail (node, ""); |