diff options
-rw-r--r-- | widgets/table/e-table-column-specification.c | 37 | ||||
-rw-r--r-- | widgets/table/e-table-config-field.c | 279 | ||||
-rw-r--r-- | widgets/table/e-table-config-field.h | 43 | ||||
-rw-r--r-- | widgets/table/e-table-config.c | 440 | ||||
-rw-r--r-- | widgets/table/e-table-config.glade | 11 | ||||
-rw-r--r-- | widgets/table/e-table-config.glade.h | 2 | ||||
-rw-r--r-- | widgets/table/e-table-config.h | 43 | ||||
-rw-r--r-- | widgets/table/e-table-header-item.c | 37 | ||||
-rw-r--r-- | widgets/table/e-table-header-item.h | 3 | ||||
-rw-r--r-- | widgets/table/e-table.c | 33 | ||||
-rw-r--r-- | widgets/table/e-table.h | 4 |
11 files changed, 704 insertions, 228 deletions
diff --git a/widgets/table/e-table-column-specification.c b/widgets/table/e-table-column-specification.c index 1b16fdf170..88604e03ea 100644 --- a/widgets/table/e-table-column-specification.c +++ b/widgets/table/e-table-column-specification.c @@ -21,14 +21,20 @@ static GtkObjectClass *etcs_parent_class; static void -etcs_destroy (GtkObject *object) +free_strings (ETableColumnSpecification *etcs) { - ETableColumnSpecification *etcs = E_TABLE_COLUMN_SPECIFICATION (object); - g_free(etcs->title_); g_free(etcs->pixbuf); g_free(etcs->cell); g_free(etcs->compare); +} + +static void +etcs_destroy (GtkObject *object) +{ + ETableColumnSpecification *etcs = E_TABLE_COLUMN_SPECIFICATION (object); + + free_strings(etcs); GTK_OBJECT_CLASS (etcs_parent_class)->destroy (object); } @@ -45,7 +51,7 @@ static void etcs_init (ETableColumnSpecification *specification) { specification->model_col = 0; - specification->title_ = NULL; + specification->title_ = g_strdup(""); specification->pixbuf = NULL; specification->expansion = 0; @@ -67,19 +73,24 @@ e_table_column_specification_new (void) } void -e_table_column_specification_load_from_node (ETableColumnSpecification *specification, +e_table_column_specification_load_from_node (ETableColumnSpecification *etcs, 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"); + free_strings(etcs); + + etcs->model_col = e_xml_get_integer_prop_by_name(node, "model_col"); + etcs->title_ = e_xml_get_translated_string_prop_by_name(node, "_title"); + etcs->pixbuf = e_xml_get_translated_string_prop_by_name(node, "pixbuf"); + + etcs->expansion = e_xml_get_double_prop_by_name(node, "expansion"); + etcs->minimum_width = e_xml_get_integer_prop_by_name(node, "minimum_width"); + etcs->resizable = e_xml_get_bool_prop_by_name(node, "resizable"); - 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"); + etcs->cell = e_xml_get_string_prop_by_name(node, "cell"); + etcs->compare = e_xml_get_string_prop_by_name(node, "compare"); - specification->cell = e_xml_get_string_prop_by_name(node, "cell"); - specification->compare = e_xml_get_string_prop_by_name(node, "compare"); + if (etcs->title_ == NULL) + etcs->title_ = g_strdup(""); } xmlNode * diff --git a/widgets/table/e-table-config-field.c b/widgets/table/e-table-config-field.c new file mode 100644 index 0000000000..09ec4184e8 --- /dev/null +++ b/widgets/table/e-table-config-field.c @@ -0,0 +1,279 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * E-table-config-field.c: One field of either the sort or group dialog. + * + * Author: + * Chris Lahey <clahey@helixcode.com> + * + * (C) 2000 Helix Code, Inc. + */ +#include <config.h> +#include <stdlib.h> +#include <gnome.h> +#include "gal/util/e-util.h" +#include "e-table-config-field.h" + +#define PARENT_TYPE (gtk_vbox_get_type()) + +static GtkVBoxClass *etcf_parent_class; + +static void +etcf_destroy (GtkObject *object) +{ + ETableConfigField *etcf = E_TABLE_CONFIG_FIELD (object); + + gtk_object_unref(GTK_OBJECT(etcf->spec)); + gtk_object_unref(GTK_OBJECT(etcf->sort_info)); + + GTK_OBJECT_CLASS (etcf_parent_class)->destroy (object); +} + +static void +etcf_class_init (GtkObjectClass *klass) +{ + etcf_parent_class = gtk_type_class (PARENT_TYPE); + + klass->destroy = etcf_destroy; +} + +static void +etcf_init (ETableConfigField *etcf) +{ + etcf->spec = NULL; + etcf->sort_info = NULL; + + etcf->combo = NULL; + etcf->radio_ascending = NULL; + etcf->radio_descending = NULL; + etcf->child_fields = NULL; +} + +E_MAKE_TYPE(e_table_config_field, "ETableConfigField", ETableConfigField, etcf_class_init, etcf_init, PARENT_TYPE); + +ETableConfigField * +e_table_config_field_new (ETableSpecification *spec, + ETableSortInfo *sort_info, + gboolean grouping) +{ + ETableConfigField *etcf = gtk_type_new (E_TABLE_CONFIG_FIELD_TYPE); + + e_table_config_field_construct (etcf, spec, sort_info, grouping); + + return (ETableConfigField *) etcf; +} + +inline static int +etcf_get_count (ETableConfigField *etcf) +{ + if (etcf->grouping) + return e_table_sort_info_grouping_get_count(etcf->sort_info); + else + return e_table_sort_info_sorting_get_count(etcf->sort_info); +} + +inline static ETableSortColumn +etcf_get_nth (ETableConfigField *etcf) +{ + if (etcf->grouping) + return e_table_sort_info_grouping_get_nth(etcf->sort_info, etcf->n); + else + return e_table_sort_info_sorting_get_nth(etcf->sort_info, etcf->n); +} + +inline static void +etcf_set_nth (ETableConfigField *etcf, ETableSortColumn column) +{ + if (etcf->grouping) + e_table_sort_info_grouping_set_nth(etcf->sort_info, etcf->n, column); + else + e_table_sort_info_sorting_set_nth(etcf->sort_info, etcf->n, column); +} + +inline static void +etcf_truncate (ETableConfigField *etcf) +{ + if (etcf->grouping) + e_table_sort_info_grouping_truncate(etcf->sort_info, etcf->n); + else + e_table_sort_info_sorting_truncate(etcf->sort_info, etcf->n); +} + +static void +etcf_set_sensitivity(ETableConfigField *etcf) +{ + int count = etcf_get_count(etcf); + + if (etcf->n >= count) { + gtk_widget_set_sensitive(etcf->radio_ascending, FALSE); + gtk_widget_set_sensitive(etcf->radio_descending, FALSE); + if (etcf->child_fields) + gtk_widget_set_sensitive(etcf->child_fields, FALSE); + } else { + gtk_widget_set_sensitive(etcf->radio_ascending, TRUE); + gtk_widget_set_sensitive(etcf->radio_descending, TRUE); + if (etcf->child_fields) + gtk_widget_set_sensitive(etcf->child_fields, TRUE); + } +} + +static void +toggled(GtkWidget *widget, ETableConfigField *etcf) +{ + int count; + + count = etcf_get_count(etcf); + if (count > etcf->n) { + ETableSortColumn sort_column; + + sort_column = etcf_get_nth(etcf); + sort_column.ascending = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(etcf->radio_ascending)); + etcf_set_nth(etcf, sort_column); + } +} + +static void +changed(GtkWidget *widget, ETableConfigField *etcf) +{ + ETableColumnSpecification **column; + gchar *text; + + text = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(etcf->combo)->entry)); + for (column = etcf->spec->columns; *column; column++) { + if (!strcmp((*column)->title_, text)) { + ETableSortColumn sort_column; + + sort_column.ascending = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(etcf->radio_ascending)); + sort_column.column = (*column)->model_col; + + etcf_set_nth(etcf, sort_column); + etcf_set_sensitivity(etcf); + return; + } + } + etcf_truncate(etcf); + etcf_set_sensitivity(etcf); +} + +static void +etcf_setup(ETableConfigField *etcf) +{ + int count; + GList *list = NULL; + ETableColumnSpecification **column; + ETableColumnSpecification *chosen_column = NULL; + int model_col = -1; + + etcf_set_sensitivity(etcf); + + count = etcf_get_count(etcf); + + if (count > etcf->n) { + ETableSortColumn sort_column; + + sort_column = etcf_get_nth(etcf); + model_col = sort_column.column; + if (sort_column.ascending) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(etcf->radio_ascending), TRUE); + else + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(etcf->radio_descending), TRUE); + } + + for (column = etcf->spec->columns; *column; column++) { + list = g_list_prepend(list, (*column)->title_); + if (count > etcf->n && chosen_column == NULL && (*column)->model_col == model_col) { + chosen_column = *column; + } + } + list = g_list_reverse(list); + list = g_list_prepend(list, "None"); + + gtk_combo_set_popdown_strings(GTK_COMBO(etcf->combo), list); + g_list_free(list); + + if (chosen_column) { + gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(etcf->combo)->entry), chosen_column->title_); + } else { + gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(etcf->combo)->entry), "None"); + } + + gtk_signal_connect(GTK_OBJECT(GTK_COMBO(etcf->combo)->entry), "changed", + GTK_SIGNAL_FUNC(changed), etcf); + gtk_signal_connect(GTK_OBJECT(etcf->radio_ascending), "toggled", + GTK_SIGNAL_FUNC(toggled), etcf); + gtk_signal_connect(GTK_OBJECT(etcf->radio_descending), "toggled", + GTK_SIGNAL_FUNC(toggled), etcf); +} + +static ETableConfigField * +e_table_config_field_construct_nth (ETableConfigField *etcf, + ETableSpecification *spec, + ETableSortInfo *sort_info, + gboolean grouping, + int n) +{ + GtkWidget *frame; + GtkWidget *internal_hbox; + GtkWidget *internal_vbox1; + GtkWidget *internal_vbox2; + + etcf->spec = spec; + gtk_object_ref(GTK_OBJECT(spec)); + + etcf->sort_info = sort_info; + gtk_object_ref(GTK_OBJECT(sort_info)); + + etcf->grouping = grouping; + etcf->n = n; + + gtk_box_set_spacing(GTK_BOX(etcf), 6); + + frame = gtk_frame_new(n > 0 ? _("Then By") : (grouping ? _("Group By") : _("Sort By"))); + gtk_box_pack_start(GTK_BOX(etcf), frame, FALSE, FALSE, 0); + + internal_hbox = gtk_hbox_new(FALSE, 6); + gtk_container_add(GTK_CONTAINER(frame), internal_hbox); + gtk_container_set_border_width(GTK_CONTAINER(internal_hbox), 6); + + internal_vbox1 = gtk_vbox_new(FALSE, 6); + gtk_box_pack_start(GTK_BOX(internal_hbox), internal_vbox1, FALSE, FALSE, 0); + + etcf->combo = gtk_combo_new(); + gtk_box_pack_start(GTK_BOX(internal_vbox1), etcf->combo, FALSE, FALSE, 0); + + internal_vbox2 = gtk_vbox_new(FALSE, 6); + gtk_box_pack_start(GTK_BOX(internal_hbox), internal_vbox2, FALSE, FALSE, 0); + + etcf->radio_ascending = gtk_radio_button_new_with_label (NULL, _("Ascending")); + gtk_box_pack_start(GTK_BOX(internal_vbox2), etcf->radio_ascending, FALSE, FALSE, 0); + + etcf->radio_descending = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON(etcf->radio_ascending), _("Descending")); + gtk_box_pack_start(GTK_BOX(internal_vbox2), etcf->radio_descending, FALSE, FALSE, 0); + + if (n < 3) { + etcf->child_fields = GTK_WIDGET(gtk_type_new (E_TABLE_CONFIG_FIELD_TYPE)); + e_table_config_field_construct_nth(E_TABLE_CONFIG_FIELD(etcf->child_fields), spec, sort_info, grouping, n + 1); + gtk_box_pack_start(GTK_BOX(etcf), etcf->child_fields, FALSE, FALSE, 0); + gtk_widget_show(etcf->child_fields); + } else + etcf->child_fields = NULL; + + etcf_setup(etcf); + + gtk_widget_show(etcf->radio_descending); + gtk_widget_show(etcf->radio_ascending); + gtk_widget_show(internal_vbox2); + gtk_widget_show(etcf->combo); + gtk_widget_show(internal_vbox1); + gtk_widget_show(internal_hbox); + gtk_widget_show(frame); + return etcf; +} + +ETableConfigField * +e_table_config_field_construct (ETableConfigField *etcf, + ETableSpecification *spec, + ETableSortInfo *sort_info, + gboolean grouping) +{ + return e_table_config_field_construct_nth(etcf, spec, sort_info, grouping, 0); +} diff --git a/widgets/table/e-table-config-field.h b/widgets/table/e-table-config-field.h new file mode 100644 index 0000000000..a6c215b895 --- /dev/null +++ b/widgets/table/e-table-config-field.h @@ -0,0 +1,43 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +#ifndef _E_TABLE_CONFIG_FIELD_H_ +#define _E_TABLE_CONFIG_FIELD_H_ + +#include <gtk/gtkvbox.h> +#include <gal/e-table/e-table-sort-info.h> +#include <gal/e-table/e-table-specification.h> + +#define E_TABLE_CONFIG_FIELD_TYPE (e_table_config_field_get_type ()) +#define E_TABLE_CONFIG_FIELD(o) (GTK_CHECK_CAST ((o), E_TABLE_CONFIG_FIELD_TYPE, ETableConfigField)) +#define E_TABLE_CONFIG_FIELD_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_CONFIG_FIELD_TYPE, ETableConfigFieldClass)) +#define E_IS_TABLE_CONFIG_FIELD(o) (GTK_CHECK_TYPE ((o), E_TABLE_CONFIG_FIELD_TYPE)) +#define E_IS_TABLE_CONFIG_FIELD_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_CONFIG_FIELD_TYPE)) + +typedef struct { + GtkVBox base; + + ETableSpecification *spec; + ETableSortInfo *sort_info; + guint grouping : 1; + int n; + + GtkWidget *combo; + GtkWidget *radio_ascending; + GtkWidget *radio_descending; + + GtkWidget *child_fields; +} ETableConfigField; + +typedef struct { + GtkVBoxClass parent_class; +} ETableConfigFieldClass; + +GtkType e_table_config_field_get_type (void); +ETableConfigField *e_table_config_field_new (ETableSpecification *spec, + ETableSortInfo *sort_info, + gboolean grouping); +ETableConfigField *e_table_config_field_construct (ETableConfigField *field, + ETableSpecification *spec, + ETableSortInfo *sort_info, + gboolean grouping); + +#endif /* _E_TABLE_CONFIG_FIELD_H_ */ diff --git a/widgets/table/e-table-config.c b/widgets/table/e-table-config.c index a2831da73a..679c2d5b63 100644 --- a/widgets/table/e-table-config.c +++ b/widgets/table/e-table-config.c @@ -1,250 +1,312 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * E-table.c: A graphical view of a Table. + * E-table-config.c: The ETable config dialog. * * Author: - * Miguel de Icaza (miguel@gnu.org) + * Chris Lahey <clahey@helixcode.com> * - * Copyright 1999, Helix Code, Inc + * (C) 2000 Helix Code, Inc. */ + #include <config.h> +#include <stdlib.h> #include <gnome.h> -#include <glade/glade.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 "e-table.h" -#include "e-table-header-item.h" -#include "e-table-subset.h" -#include "e-table-item.h" -#include "e-table-group.h" #include "e-table-config.h" +#include "e-table-config-field.h" +#include "gal/util/e-util.h" -typedef struct { - GladeXML *gui; - char *old_spec; -} ConfigData; - -static void -load_data (GladeXML *xml, char *label_widget, const char *content) -{ - GtkLabel *label = GTK_LABEL (glade_xml_get_widget (xml, label_widget)); +#define PARENT_TYPE (gnome_dialog_get_type()) - gtk_label_set_text (label, content); -} +static GnomeDialogClass *etco_parent_class; -static char * -get_fields (ETable *etable, xmlNode *xmlRoot) +static void +etco_destroy (GtkObject *object) { - xmlNode *xmlColumns; - xmlNode *column; - GString *res; - char *s; - - res = g_string_new (""); - xmlColumns = e_xml_get_child_by_name (xmlRoot, "columns-shown"); - - for (column = xmlColumns->childs; column; column = column->next){ - ETableCol *ecol; - char *content; - int col; - - content = xmlNodeListGetString (column->doc, column->childs, 1); - col = atoi (content); - xmlFree (content); - - ecol = e_table_header_get_column (etable->header, col); - - g_string_append (res, ecol->text); - if (column->next) - g_string_append (res, ", "); + ETableConfig *etco = E_TABLE_CONFIG (object); + + if (etco->state) { + if (etco->sorting_changed_id) + gtk_signal_disconnect(GTK_OBJECT(etco->state->sort_info), etco->sorting_changed_id); + if (etco->grouping_changed_id) + gtk_signal_disconnect(GTK_OBJECT(etco->state->sort_info), etco->grouping_changed_id); + gtk_object_unref(GTK_OBJECT(etco->state)); } - s = res->str; - g_string_free (res, FALSE); - - return s; -} - -static char * -get_grouping (ETable *etable, xmlNode *xmlRoot) -{ - xmlNode *xmlGrouping; - GString *res; - char *s; - - res = g_string_new (""); - xmlGrouping = e_xml_get_child_by_name (xmlRoot, "grouping"); - s = res->str; - g_string_free (res, FALSE); + gtk_object_unref(GTK_OBJECT(etco->spec)); - return s; -} - -static char * -get_sort (ETable *etable) -{ - return g_strdup ("None"); -} - -static char * -get_filter (ETable *etable) -{ - return g_strdup ("None"); + GTK_OBJECT_CLASS (etco_parent_class)->destroy (object); } -/* - * Loads a user-readable definition of the various e-table parameters - * into the dialog for configuring it - */ static void -load_label_data (GladeXML *gui, ETable *etable) +etco_class_init (GtkObjectClass *klass) { - /* FIXME: Set this to the right value. */ - xmlNode *xmlRoot = NULL; - char *s; + etco_parent_class = gtk_type_class (PARENT_TYPE); -/* xmlRoot = xmlDocGetRootElement (etable->specification); */ - - s = get_fields (etable, xmlRoot); - load_data (gui, "label1", s); - g_free (s); - - s = get_grouping (etable, xmlRoot); - load_data (gui, "label2", s); - g_free (s); - - s = get_sort (etable); - load_data (gui, "label3", s); - g_free (s); - - s = get_filter (etable); - load_data (gui, "label4", s); - g_free (s); + klass->destroy = etco_destroy; } static void -cb_button_fields (GtkWidget *widget, ETable *etable) +etco_clear_sort(GtkWidget *widget, ETableConfig *etco) { + etco->sort_dialog = NULL; + gtk_object_unref(GTK_OBJECT(etco)); } static void -cb_button_grouping (GtkWidget *widget, ETable *etable) +etco_clear_group(GtkWidget *widget, ETableConfig *etco) { + etco->group_dialog = NULL; + gtk_object_unref(GTK_OBJECT(etco)); } static void -cb_button_sort (GtkWidget *widget, ETable *etable) +etco_sort_config_show(GtkWidget *widget, ETableConfig *etco) { + if (etco->sort_dialog) + gdk_window_raise(GTK_WIDGET(etco->sort_dialog)->window); + else { + GtkWidget *etcf; + etco->sort_dialog = gnome_dialog_new(_("Sort"), + GNOME_STOCK_BUTTON_OK, + NULL); + etcf = GTK_WIDGET(e_table_config_field_new(etco->spec, + etco->state->sort_info, + FALSE)); + gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(etco->sort_dialog)->vbox), etcf, FALSE, FALSE, 0); + gnome_dialog_set_parent(GNOME_DIALOG(etco->sort_dialog), + GTK_WINDOW(etco)); + + gtk_signal_connect(GTK_OBJECT(etco->sort_dialog), "destroy", + GTK_SIGNAL_FUNC(etco_clear_sort), etco); + gtk_object_ref(GTK_OBJECT(etco)); + + gtk_signal_connect(GTK_OBJECT(etco->sort_dialog), "clicked", + GTK_SIGNAL_FUNC(gnome_dialog_close), etco); + + gtk_widget_show(GTK_WIDGET(etcf)); + gtk_widget_show(GTK_WIDGET(etco->sort_dialog)); + } } static void -cb_button_filter (GtkWidget *widget, ETable *etable) +etco_group_config_show(GtkWidget *widget, ETableConfig *etco) { + if (etco->group_dialog) + gdk_window_raise(GTK_WIDGET(etco->group_dialog)->window); + else { + GtkWidget *etcf; + etco->group_dialog = gnome_dialog_new(_("Group"), + GNOME_STOCK_BUTTON_OK, + NULL); + etcf = GTK_WIDGET(e_table_config_field_new(etco->spec, + etco->state->sort_info, + TRUE)); + gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(etco->group_dialog)->vbox), etcf, FALSE, FALSE, 0); + gnome_dialog_set_parent(GNOME_DIALOG(etco->group_dialog), + GTK_WINDOW(etco)); + + gtk_signal_connect(GTK_OBJECT(etco->group_dialog), "destroy", + GTK_SIGNAL_FUNC(etco_clear_group), etco); + gtk_signal_connect(GTK_OBJECT(etco->group_dialog), "clicked", + GTK_SIGNAL_FUNC(gnome_dialog_close), etco); + gtk_object_ref(GTK_OBJECT(etco)); + + gtk_widget_show(GTK_WIDGET(etcf)); + gtk_widget_show(GTK_WIDGET(etco->group_dialog)); + } } -GnomeDialog * -e_table_gui_config (ETable *etable) +static void +etco_sort_info_update(ETableSortInfo *info, ETableConfig *etco) { - GladeXML *gui; - GnomeDialog *dialog; - ConfigData *config_data; - - g_return_val_if_fail(etable != NULL, NULL); - g_return_val_if_fail(E_IS_TABLE(etable), NULL); - - glade_gnome_init (); - gui = glade_xml_new (ETABLE_GLADEDIR "/e-table-config.glade", NULL); - if (!gui) - return NULL; - - dialog = GNOME_DIALOG (glade_xml_get_widget (gui, "e-table-config")); - - gtk_signal_connect ( - GTK_OBJECT (glade_xml_get_widget (gui, "button-fields")), - "clicked", GTK_SIGNAL_FUNC (cb_button_fields), etable); - gtk_signal_connect ( - GTK_OBJECT (glade_xml_get_widget (gui, "button-grouping")), - "clicked", GTK_SIGNAL_FUNC (cb_button_grouping), etable); - gtk_signal_connect ( - GTK_OBJECT (glade_xml_get_widget (gui, "button-sort")), - "clicked", GTK_SIGNAL_FUNC (cb_button_sort), etable); - gtk_signal_connect ( - GTK_OBJECT (glade_xml_get_widget (gui, "button-filter")), - "clicked", GTK_SIGNAL_FUNC (cb_button_filter), etable); - - load_label_data (gui, etable); - - config_data = g_new (ConfigData, 1); - config_data->gui = gui; - config_data->old_spec = e_table_get_state (etable); - - gtk_object_set_data ( - GTK_OBJECT (dialog), "config-data", - config_data); - - return dialog; + int count; + int i; + gchar **strings; + gchar *substrings[3]; + int stringcount = 0; + gchar *string; + + count = e_table_sort_info_sorting_get_count(info); + strings = g_new(gchar *, count + 1); + + for (i = 0; i < count; i++) { + ETableSortColumn col = e_table_sort_info_sorting_get_nth(info, i); + ETableColumnSpecification **column; + + substrings[0] = NULL; + + for (column = etco->spec->columns; *column; column++) { + if (col.column == (*column)->model_col) { + substrings[0] = (*column)->title_; + break; + } + } + + if (substrings[0]) { + substrings[1] = col.ascending ? _("(Ascending)") : _("(Descending)"); + substrings[2] = NULL; + strings[stringcount++] = g_strjoinv(" ", substrings); + } + } + strings[stringcount] = NULL; + string = g_strjoinv(", ", strings); + + for (i = 0; strings[i]; i++) { + g_free(strings[i]); + } + gtk_label_set_text(GTK_LABEL(etco->sort_label), string); + g_free(string); + } static void -e_table_gui_destroy_config_data (GtkWidget *widget) +etco_group_info_update(ETableSortInfo *info, ETableConfig *etco) { - ConfigData *cd = gtk_object_get_data (GTK_OBJECT (widget), "config-data"); + int count; + int i; + gchar **strings; + gchar *substrings[3]; + int stringcount = 0; + gchar *string; + + count = e_table_sort_info_grouping_get_count(info); + strings = g_new(gchar *, count + 1); + + for (i = 0; i < count; i++) { + ETableSortColumn col = e_table_sort_info_grouping_get_nth(info, i); + ETableColumnSpecification **column; + + substrings[0] = NULL; + + for (column = etco->spec->columns; *column; column++) { + if (col.column == (*column)->model_col) { + substrings[0] = (*column)->title_; + break; + } + } + + if (substrings[0]) { + substrings[1] = col.ascending ? _("(Ascending)") : _("(Descending)"); + substrings[2] = NULL; + strings[stringcount++] = g_strjoinv(" ", substrings); + } + } + strings[stringcount] = NULL; + string = g_strjoinv(", ", strings); + + for (i = 0; strings[i]; i++) { + g_free(strings[i]); + } + gtk_label_set_text(GTK_LABEL(etco->group_label), string); + g_free(string); - g_free (cd->old_spec); - gtk_object_destroy (GTK_OBJECT (cd->gui)); - g_free (cd); } -void -e_table_gui_config_accept (GtkWidget *widget, ETable *etable) +static void +etco_init (ETableConfig *etco) { - g_return_if_fail(etable != NULL); - g_return_if_fail(E_IS_TABLE(etable)); - g_return_if_fail(widget != NULL); - g_return_if_fail(GTK_IS_WIDGET(widget)); - - e_table_gui_destroy_config_data (widget); + GtkWidget *frame; + GtkWidget *table; + GtkWidget *sort_button; + GtkWidget *group_button; + + gtk_window_set_title(GTK_WINDOW(etco), _("View Summary")); + gnome_dialog_append_buttons(GNOME_DIALOG(etco), + GNOME_STOCK_BUTTON_OK, + NULL); + gnome_dialog_set_default(GNOME_DIALOG(etco), 0); + + frame = gtk_frame_new(_("Description")); + gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(etco)->vbox), frame, FALSE, FALSE, 0); + + table = gtk_table_new(2, 2, FALSE); + gtk_table_set_row_spacings(GTK_TABLE(table), 6); + gtk_table_set_col_spacings(GTK_TABLE(table), 6); + gtk_container_add(GTK_CONTAINER(frame), table); + gtk_container_set_border_width(GTK_CONTAINER(table), 6); + + sort_button = gtk_button_new_with_label(_("Sort...")); + gtk_table_attach(GTK_TABLE(table), + sort_button, + 0, 1, 0, 1, + GTK_FILL, + GTK_FILL, + 0, 0); + + group_button = gtk_button_new_with_label(_("Group By...")); + gtk_table_attach(GTK_TABLE(table), + group_button, + 0, 1, 1, 2, + GTK_FILL, + GTK_FILL, + 0, 0); + + etco->sort_label = gtk_label_new(""); + gtk_table_attach(GTK_TABLE(table), + etco->sort_label, + 1, 2, 0, 1, + GTK_FILL | GTK_EXPAND, + GTK_FILL, + 0, 0); + + etco->group_label = gtk_label_new(""); + gtk_table_attach(GTK_TABLE(table), + etco->group_label, + 1, 2, 1, 2, + GTK_FILL | GTK_EXPAND, + GTK_FILL, + 0, 0); + + gtk_signal_connect(GTK_OBJECT(sort_button), "clicked", + GTK_SIGNAL_FUNC(etco_sort_config_show), etco); + gtk_signal_connect(GTK_OBJECT(group_button), "clicked", + GTK_SIGNAL_FUNC(etco_group_config_show), etco); + + gtk_widget_show(etco->group_label); + gtk_widget_show(etco->sort_label); + gtk_widget_show(group_button); + gtk_widget_show(sort_button); + gtk_widget_show(table); + gtk_widget_show(frame); + + etco->sorting_changed_id = 0; + etco->grouping_changed_id = 0; } -void -e_table_gui_config_cancel (GtkWidget *widget, ETable *etable) +E_MAKE_TYPE(e_table_config, "ETableConfig", ETableConfig, etco_class_init, etco_init, PARENT_TYPE); + +GtkWidget * +e_table_config_new (ETableSpecification *spec, + ETableState *state) { - g_return_if_fail(etable != NULL); - g_return_if_fail(E_IS_TABLE(etable)); - g_return_if_fail(widget != NULL); - g_return_if_fail(GTK_IS_WIDGET(widget)); + ETableConfig *etco = gtk_type_new (E_TABLE_CONFIG_TYPE); - e_table_gui_destroy_config_data (widget); + e_table_config_construct(etco, spec, state); + + return GTK_WIDGET(etco); } -void -e_table_do_gui_config (GtkWidget *parent, ETable *etable) +GtkWidget * +e_table_config_construct (ETableConfig *etco, + ETableSpecification *spec, + ETableState *state) { - GnomeDialog *dialog; - int r; - - g_return_if_fail(etable != NULL); - g_return_if_fail(E_IS_TABLE(etable)); - g_return_if_fail(parent == NULL || GTK_IS_WINDOW(parent)); + etco->spec = spec; + etco->state = state; - dialog = GNOME_DIALOG (e_table_gui_config (etable)); - if (!dialog) - return; + if (etco->spec) + gtk_object_ref(GTK_OBJECT(etco->spec)); + if (etco->state) + gtk_object_ref(GTK_OBJECT(etco->state)); - if (parent) - gnome_dialog_set_parent (dialog, GTK_WINDOW (parent)); - - r = gnome_dialog_run (GNOME_DIALOG (dialog)); + etco->sorting_changed_id = gtk_signal_connect(GTK_OBJECT(etco->state->sort_info), "sort_info_changed", + GTK_SIGNAL_FUNC(etco_sort_info_update), etco); + etco->grouping_changed_id = gtk_signal_connect(GTK_OBJECT(etco->state->sort_info), "group_info_changed", + GTK_SIGNAL_FUNC(etco_group_info_update), etco); - if (r == -1 || r == 1) - e_table_gui_config_cancel (GTK_WIDGET (dialog), etable); - else - e_table_gui_config_accept (GTK_WIDGET (dialog), etable); + etco_sort_info_update(etco->state->sort_info, etco); + etco_group_info_update(etco->state->sort_info, etco); - if (r != -1) - gtk_object_destroy (GTK_OBJECT (dialog)); + return GTK_WIDGET(etco); } - diff --git a/widgets/table/e-table-config.glade b/widgets/table/e-table-config.glade index 811ca18e4e..823992af39 100644 --- a/widgets/table/e-table-config.glade +++ b/widgets/table/e-table-config.glade @@ -268,6 +268,7 @@ Full Name, Company, </label> <last_modification_time>Tue, 03 Oct 2000 22:11:12 GMT</last_modification_time> </signal> <label>_Fields...</label> + <relief>GTK_RELIEF_NORMAL</relief> <child> <left_attach>0</left_attach> <right_attach>1</right_attach> @@ -295,6 +296,7 @@ Full Name, Company, </label> <last_modification_time>Tue, 03 Oct 2000 22:10:58 GMT</last_modification_time> </signal> <label>_Sort...</label> + <relief>GTK_RELIEF_NORMAL</relief> <child> <left_attach>0</left_attach> <right_attach>1</right_attach> @@ -322,6 +324,7 @@ Full Name, Company, </label> <last_modification_time>Tue, 03 Oct 2000 22:10:50 GMT</last_modification_time> </signal> <label>_Group By...</label> + <relief>GTK_RELIEF_NORMAL</relief> <child> <left_attach>0</left_attach> <right_attach>1</right_attach> @@ -539,6 +542,7 @@ Full Name, Company, </label> <name>table-1</name> <can_focus>True</can_focus> <label>Table HERE</label> + <relief>GTK_RELIEF_NORMAL</relief> </widget> </widget> </widget> @@ -587,6 +591,7 @@ Full Name, Company, </label> <name>table-2</name> <can_focus>True</can_focus> <label>Table HERE</label> + <relief>GTK_RELIEF_NORMAL</relief> </widget> </widget> </widget> @@ -607,6 +612,7 @@ Full Name, Company, </label> <name>button-up</name> <can_focus>True</can_focus> <label>Move _Up</label> + <relief>GTK_RELIEF_NORMAL</relief> <child> <padding>0</padding> <expand>False</expand> @@ -619,6 +625,7 @@ Full Name, Company, </label> <name>button-down</name> <can_focus>True</can_focus> <label>Move _Down</label> + <relief>GTK_RELIEF_NORMAL</relief> <child> <padding>0</padding> <expand>False</expand> @@ -653,6 +660,7 @@ Full Name, Company, </label> <name>button-add</name> <can_focus>True</can_focus> <label>_Add -></label> + <relief>GTK_RELIEF_NORMAL</relief> <child> <padding>0</padding> <expand>False</expand> @@ -665,6 +673,7 @@ Full Name, Company, </label> <name>button-remove</name> <can_focus>True</can_focus> <label><- _Remove</label> + <relief>GTK_RELIEF_NORMAL</relief> <child> <padding>0</padding> <expand>False</expand> @@ -685,7 +694,7 @@ Full Name, Company, </label> <class>GnomeDialog</class> <name>dialog-group-by</name> <visible>False</visible> - <title>Group By</title> + <title>Group</title> <type>GTK_WINDOW_TOPLEVEL</type> <position>GTK_WIN_POS_NONE</position> <modal>False</modal> diff --git a/widgets/table/e-table-config.glade.h b/widgets/table/e-table-config.glade.h index bfa2bf433e..ce5520bb27 100644 --- a/widgets/table/e-table-config.glade.h +++ b/widgets/table/e-table-config.glade.h @@ -22,7 +22,7 @@ gchar *s = N_("Move _Up"); gchar *s = N_("Move _Down"); gchar *s = N_("_Add ->"); gchar *s = N_("<- _Remove"); -gchar *s = N_("Group By"); +gchar *s = N_("Group"); gchar *s = N_("_Clear All"); gchar *s = N_("Group Items By"); gchar *s = N_("Show field in View"); diff --git a/widgets/table/e-table-config.h b/widgets/table/e-table-config.h index 617ef6a331..ddae3f1497 100644 --- a/widgets/table/e-table-config.h +++ b/widgets/table/e-table-config.h @@ -1,11 +1,42 @@ -#ifndef _E_TABLE_CONFIG_H -#define _E_TABLE_CONFIG_H +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +#ifndef _E_TABLE_CONFIG_H_ +#define _E_TABLE_CONFIG_H_ -GnomeDialog *e_table_gui_config (ETable *etable); -void e_table_do_gui_config (GtkWidget *, ETable *etable); +#include <gnome.h> +#include <gal/e-table/e-table-sort-info.h> +#include <gal/e-table/e-table-specification.h> -void e_table_gui_config_accept (GtkWidget *widget, ETable *etable); -void e_table_gui_config_cancel (GtkWidget *widget, ETable *etable); +#define E_TABLE_CONFIG_TYPE (e_table_config_get_type ()) +#define E_TABLE_CONFIG(o) (GTK_CHECK_CAST ((o), E_TABLE_CONFIG_TYPE, ETableConfig)) +#define E_TABLE_CONFIG_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_CONFIG_TYPE, ETableConfigClass)) +#define E_IS_TABLE_CONFIG(o) (GTK_CHECK_TYPE ((o), E_TABLE_CONFIG_TYPE)) +#define E_IS_TABLE_CONFIG_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_CONFIG_TYPE)) +typedef struct { + GnomeDialog base; + + ETableSpecification *spec; + ETableState *state; + + GtkWidget *sort_label; + GtkWidget *group_label; + + GtkWidget *sort_dialog; + GtkWidget *group_dialog; + + int sorting_changed_id; + int grouping_changed_id; +} ETableConfig; + +typedef struct { + GnomeDialogClass parent_class; +} ETableConfigClass; + +GtkType e_table_config_get_type (void); +GtkWidget *e_table_config_new (ETableSpecification *spec, + ETableState *state); +GtkWidget *e_table_config_construct (ETableConfig *etco, + ETableSpecification *spec, + ETableState *state); #endif /* _E_TABLE_CONFIG_H */ diff --git a/widgets/table/e-table-header-item.c b/widgets/table/e-table-header-item.c index a64d0dd380..275cb67a88 100644 --- a/widgets/table/e-table-header-item.c +++ b/widgets/table/e-table-header-item.c @@ -23,6 +23,8 @@ #include "e-table-col-dnd.h" #include "e-table-defines.h" #include "e-table-field-chooser-dialog.h" +#include "e-table-config.h" +#include "e-table.h" #include "add-col.xpm" #include "remove-col.xpm" @@ -71,7 +73,8 @@ enum { ARG_FULL_HEADER, ARG_DND_CODE, ARG_TABLE_FONTSET, - ARG_SORT_INFO + ARG_SORT_INFO, + ARG_TABLE, }; static void @@ -266,7 +269,12 @@ ethi_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) GTK_OBJECT(ethi->sort_info), "group_info_changed", GTK_SIGNAL_FUNC(ethi_sort_info_changed), ethi); break; - + case ARG_TABLE: + if (GTK_VALUE_OBJECT(*arg)) + ethi->table = E_TABLE(GTK_VALUE_OBJECT(*arg)); + else + ethi->table = NULL; + break; } gnome_canvas_item_request_update(item); } @@ -1263,10 +1271,25 @@ ethi_popup_format_columns(GtkWidget *widget, EthiHeaderInfo *info) static void ethi_popup_customize_view(GtkWidget *widget, EthiHeaderInfo *info) { + ETableHeaderItem *ethi = info->ethi; + ETableState *state; + + if (ethi->config) + gdk_window_raise(GTK_WIDGET(ethi->config)->window); + else { + state = e_table_get_state_object(ethi->table); + + ethi->config = e_table_config_new(ethi->table->spec, + state); + gtk_signal_connect(GTK_OBJECT(ethi->config), "clicked", + GTK_SIGNAL_FUNC(gnome_dialog_close), ethi); + gtk_widget_show(ethi->config); + } } /* Bit 1 is always disabled. */ /* Bit 2 is disabled if not "sortable". */ +/* Bit 4 is disabled if we don't have a pointer to our table object. */ static EPopupMenu ethi_context_menu [] = { { N_("Sort Ascending"), NULL, GTK_SIGNAL_FUNC(ethi_popup_sort_ascending), 2}, { N_("Sort Descending"), NULL, GTK_SIGNAL_FUNC(ethi_popup_sort_descending), 2}, @@ -1282,7 +1305,7 @@ static EPopupMenu ethi_context_menu [] = { { N_("Best Fit"), NULL, GTK_SIGNAL_FUNC(ethi_popup_best_fit), 2}, { N_("Format Columns..."), NULL, GTK_SIGNAL_FUNC(ethi_popup_format_columns), 1}, { "", NULL, GTK_SIGNAL_FUNC(NULL), 1}, - { N_("Customize Current View..."), NULL, GTK_SIGNAL_FUNC(ethi_popup_customize_view), 1}, + { N_("Customize Current View..."), NULL, GTK_SIGNAL_FUNC(ethi_popup_customize_view), 4}, { NULL, NULL, NULL, 0 } }; @@ -1294,7 +1317,10 @@ ethi_header_context_menu (ETableHeaderItem *ethi, GdkEventButton *event) info->ethi = ethi; info->col = ethi_find_col_by_x (ethi, event->x); col = e_table_header_get_column (ethi->eth, info->col); - e_popup_menu_run (ethi_context_menu, event, 1 + (col->sortable ? 0 : 2), 0, info); + e_popup_menu_run (ethi_context_menu, event, + 1 + + (col->sortable ? 0 : 2) + + (ethi->table ? 0 : 4), 0, info); } static void @@ -1505,6 +1531,8 @@ ethi_class_init (GtkObjectClass *object_class) GTK_ARG_WRITABLE, ARG_TABLE_FONTSET); gtk_object_add_arg_type ("ETableHeaderItem::sort_info", GTK_TYPE_OBJECT, GTK_ARG_WRITABLE, ARG_SORT_INFO); + gtk_object_add_arg_type ("ETableHeaderItem::table", GTK_TYPE_OBJECT, + GTK_ARG_WRITABLE, ARG_TABLE); /* * Create our pixmaps for DnD @@ -1550,6 +1578,7 @@ ethi_init (GnomeCanvasItem *item) ethi->group_info_changed_id = 0; ethi->group_indent_width = 0; + ethi->table = NULL; } GtkType diff --git a/widgets/table/e-table-header-item.h b/widgets/table/e-table-header-item.h index 7511106c16..b029d58280 100644 --- a/widgets/table/e-table-header-item.h +++ b/widgets/table/e-table-header-item.h @@ -2,6 +2,7 @@ #ifndef _E_TABLE_HEADER_ITEM_H_ #define _E_TABLE_HEADER_ITEM_H_ +#include <gal/e-table/e-table.h> #include <libgnomeui/gnome-canvas.h> #include <gnome-xml/tree.h> #include <gal/e-table/e-table-header.h> @@ -60,6 +61,8 @@ typedef struct { /* For adding fields. */ ETableHeader *full_header; + ETable *table; + GtkWidget *config; } ETableHeaderItem; typedef struct { diff --git a/widgets/table/e-table.c b/widgets/table/e-table.c index e51bc39506..8794e2142e 100644 --- a/widgets/table/e-table.c +++ b/widgets/table/e-table.c @@ -144,6 +144,8 @@ et_destroy (GtkObject *object) gtk_object_unref (GTK_OBJECT (et->sort_info)); gtk_object_unref (GTK_OBJECT (et->sorter)); gtk_object_unref (GTK_OBJECT (et->selection)); + if (et->spec) + gtk_object_unref (GTK_OBJECT (et->spec)); if (et->header_canvas != NULL) gtk_widget_destroy (GTK_WIDGET (et->header_canvas)); @@ -193,6 +195,7 @@ e_table_init (GtkObject *object) e_table->sorter = NULL; e_table->selection = e_table_selection_model_new(); e_table->cursor_loc = E_TABLE_CURSOR_LOC_NONE; + e_table->spec = NULL; } static void @@ -235,6 +238,7 @@ e_table_setup_header (ETable *e_table) "full_header", e_table->full_header, "sort_info", e_table->sort_info, "dnd_code", "(unset)", + "table", e_table, NULL); gtk_signal_connect ( @@ -602,19 +606,20 @@ et_col_spec_to_col (ETable *e_table, ETableColumnSpecification *col_spec, ETable 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) { + 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); } + } + if (col == NULL && 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); } } return col; @@ -733,8 +738,8 @@ void e_table_load_state (ETable *e_table gtk_object_sink(GTK_OBJECT(state)); } -static ETableState * -et_get_state (ETable *e_table) +ETableState * +e_table_get_state_object (ETable *e_table) { ETableState *state; int full_col_count; @@ -767,9 +772,9 @@ gchar *e_table_get_state (ETable *e_table ETableState *state; gchar *string; - state = et_get_state(e_table); + state = e_table_get_state_object(e_table); string = e_table_state_save_to_string(state); - gtk_object_sink(state); + gtk_object_sink(GTK_OBJECT(state)); return string; } @@ -778,9 +783,9 @@ void e_table_save_state (ETable *e_table { ETableState *state; - state = et_get_state(e_table); + state = e_table_get_state_object(e_table); e_table_state_save_to_file(state, filename); - gtk_object_sink(state); + gtk_object_sink(GTK_OBJECT(state)); } @@ -885,7 +890,7 @@ e_table_construct (ETable *e_table, ETableModel *etm, ETableExtras *ete, e_table = et_real_construct (e_table, etm, ete, specification, state); - gtk_object_unref(GTK_OBJECT(specification)); + e_table->spec = specification; gtk_object_unref(GTK_OBJECT(state)); return e_table; @@ -925,7 +930,7 @@ e_table_construct_from_spec_file (ETable *e_table, ETableModel *etm, ETableExtra e_table = et_real_construct (e_table, etm, ete, specification, state); - gtk_object_unref(GTK_OBJECT(specification)); + e_table->spec = specification; gtk_object_unref(GTK_OBJECT(state)); return e_table; diff --git a/widgets/table/e-table.h b/widgets/table/e-table.h index 933f0f5155..717272309e 100644 --- a/widgets/table/e-table.h +++ b/widgets/table/e-table.h @@ -12,7 +12,9 @@ #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/e-table/e-table-specification.h> #include <gal/widgets/e-printable.h> +#include <gal/e-table/e-table-state.h> BEGIN_GNOME_DECLS @@ -45,6 +47,7 @@ typedef struct { ETableSelectionModel *selection; ETableCursorLoc cursor_loc; + ETableSpecification *spec; int table_model_change_id; int table_row_change_id; @@ -184,6 +187,7 @@ GtkWidget *e_table_new_from_spec_file (ETableModel *etm, gchar *e_table_get_state (ETable *e_table); void e_table_save_state (ETable *e_table, const gchar *filename); +ETableState *e_table_get_state_object (ETable *e_table); /* note that it is more efficient to provide the state at creation time */ void e_table_set_state (ETable *e_table, |