From 32471accadcf2099f9d3567f51add9fab197ec24 Mon Sep 17 00:00:00 2001 From: Christopher James Lahey Date: Sun, 14 May 2000 14:31:22 +0000 Subject: From widgets/e-table/ChangeLog 2000-05-14 Christopher James Lahey * Implemented the feature where the ETable columns automatically fill the given space. * e-cell-text.c, e-cell-text.h: Moved #include e-text-event-processor.h from the .h to the .c. * e-table-col.c, e-table-col.h: Added an expansion variable, and made it so that width isn't set by the programmer but instead by the e-table-header. * e-table-example-1.c, e-table-example-2.c, e-table-size-test.c, test-check.c, test-cols.c, test-table.c: Fixed to handle new ETable column resizing. * e-table-group-container.c, e-table-group-container.h, e-table-group-leaf.c, e-table-group-leaf.h, e-table-group.c, e-table-group.h, e-table-item.c, e-table-item.h: Fixed these to do a proper canvas reflow/update loop. Changed them to take a minimum width and return a width and a height. * e-table-header-item.c, e-table-header-item.h: Made this so that it depends on e-table-header.c for deciding the actual size of columns during resize (it was making incorrect decisions on its own.) * e-table-header.c, e-table-header.h: Changed this to make sure that the sum of the widths of the columns was always as close as possible to the width of the window. This is done by taking a full width and having each of the columns have an "expansion" field. This field is what makes each column have approximately the same portion of its part of the screen that it used to. * e-table.c: Changed this to set the width on the ETableHeader as well as set the proper minimum width on the ETableGroup and get the width and height it reports. From addressbook/ChangeLog 2000-05-14 Christopher James Lahey * backend/ebook/Makefile.am: Added libeutil for e-card's support for categories. * backend/ebook/e-card-list.c, backend/ebook/e-card-list.h: Added a function to get the length. * backend/ebook/e-card.c, backend/ebook/e-card.h: Added categories support (accessible either as "categories" or "category_list".) * contact-editor/Makefile.am: Added e-table and all of the categories files. * contact-editor/categories.glade, contact-editor/categories-strings.h, contact-editor/e-contact-editor-categories.c, contact-editor/e-contact-editor-categories.h: * contact-editor/contact-editor.glade, contact-editor/e-contact-editor-strings.h: Rearranged this dialog. * contact-editor/e-contact-editor.c: Rearranged dialog a bit. Added opening of categories dialog. * gui/component/Makefile.am: Rearranged libraries so that libetable would be available for the contact editor categories dialog. * gui/component/addressbook.c: Fix for new ETable resizing. Make contact editor dialog resizable. * gui/minicard/Makefile.am: Added libetable contact editor categories dialog. * gui/minicard/e-minicard.c: Make contact editor dialog resizable. From mail/ChangeLog 2000-05-14 Christopher James Lahey * message-list.c: Updated to work with new ETable resizing. svn path=/trunk/; revision=3027 --- widgets/e-table/ChangeLog | 38 +++ widgets/e-table/e-cell-text.c | 1 + widgets/e-table/e-cell-text.h | 1 - widgets/e-table/e-table-col.c | 22 +- widgets/e-table/e-table-col.h | 9 +- widgets/e-table/e-table-defines.h | 3 + widgets/e-table/e-table-example-1.c | 2 +- widgets/e-table/e-table-example-2.c | 4 +- widgets/e-table/e-table-group-container.c | 385 ++++------------------------- widgets/e-table/e-table-group-container.h | 4 +- widgets/e-table/e-table-group-leaf.c | 130 ++++------ widgets/e-table/e-table-group-leaf.h | 4 +- widgets/e-table/e-table-group.c | 79 +----- widgets/e-table/e-table-group.h | 4 - widgets/e-table/e-table-header-item.c | 58 ++--- widgets/e-table/e-table-header-item.h | 1 - widgets/e-table/e-table-header.c | 393 +++++++++++++++++++----------- widgets/e-table/e-table-header.h | 34 +-- widgets/e-table/e-table-item.c | 104 ++++---- widgets/e-table/e-table-item.h | 3 +- widgets/e-table/e-table-size-test.c | 2 +- widgets/e-table/e-table.c | 74 +++--- widgets/e-table/test-check.c | 4 +- widgets/e-table/test-cols.c | 4 +- widgets/e-table/test-table.c | 4 +- 25 files changed, 548 insertions(+), 819 deletions(-) create mode 100644 widgets/e-table/e-table-defines.h (limited to 'widgets/e-table') diff --git a/widgets/e-table/ChangeLog b/widgets/e-table/ChangeLog index 4237a13bd4..71799c21b1 100644 --- a/widgets/e-table/ChangeLog +++ b/widgets/e-table/ChangeLog @@ -1,3 +1,41 @@ +2000-05-14 Christopher James Lahey + + * Implemented the feature where the ETable columns automatically + fill the given space. + + * e-cell-text.c, e-cell-text.h: Moved #include + e-text-event-processor.h from the .h to the .c. + + * e-table-col.c, e-table-col.h: Added an expansion variable, and + made it so that width isn't set by the programmer but instead by + the e-table-header. + + * e-table-example-1.c, e-table-example-2.c, e-table-size-test.c, + test-check.c, test-cols.c, test-table.c: Fixed to handle new + ETable column resizing. + + * e-table-group-container.c, e-table-group-container.h, + e-table-group-leaf.c, e-table-group-leaf.h, e-table-group.c, + e-table-group.h, e-table-item.c, e-table-item.h: Fixed these to do + a proper canvas reflow/update loop. Changed them to take a + minimum width and return a width and a height. + + * e-table-header-item.c, e-table-header-item.h: Made this so that + it depends on e-table-header.c for deciding the actual size of + columns during resize (it was making incorrect decisions on its + own.) + + * e-table-header.c, e-table-header.h: Changed this to make sure + that the sum of the widths of the columns was always as close as + possible to the width of the window. This is done by taking a + full width and having each of the columns have an "expansion" + field. This field is what makes each column have approximately + the same portion of its part of the screen that it used to. + + * e-table.c: Changed this to set the width on the ETableHeader as + well as set the proper minimum width on the ETableGroup and get + the width and height it reports. + 2000-05-11 Miguel de Icaza * e-table.c: Removed dead code. diff --git a/widgets/e-table/e-cell-text.c b/widgets/e-table/e-cell-text.c index bf8b3d115a..68d70b2fed 100644 --- a/widgets/e-table/e-cell-text.c +++ b/widgets/e-table/e-cell-text.c @@ -30,6 +30,7 @@ #include "e-cell-text.h" #include "e-util/e-util.h" #include "e-table-item.h" +#include "e-text-event-processor.h" #include "e-text-event-processor-emacs-like.h" #include /* for BlackPixel */ diff --git a/widgets/e-table/e-cell-text.h b/widgets/e-table/e-cell-text.h index 997723b0d6..ae80235cb6 100644 --- a/widgets/e-table/e-cell-text.h +++ b/widgets/e-table/e-cell-text.h @@ -26,7 +26,6 @@ #include #include "e-cell.h" -#include "e-text-event-processor.h" #define E_CELL_TEXT_TYPE (e_cell_text_get_type ()) #define E_CELL_TEXT(o) (GTK_CHECK_CAST ((o), E_CELL_TEXT_TYPE, ECellText)) diff --git a/widgets/e-table/e-table-col.c b/widgets/e-table/e-table-col.c index 7bac1c4899..5a167a8940 100644 --- a/widgets/e-table/e-table-col.c +++ b/widgets/e-table/e-table-col.c @@ -39,17 +39,22 @@ e_table_col_class_init (GtkObjectClass *object_class) object_class->destroy = etc_destroy; } -E_MAKE_TYPE(e_table_col, "ETableCol", ETableCol, e_table_col_class_init, NULL, PARENT_TYPE); +static void +e_table_col_init (ETableCol *etc) +{ + etc->width = 0; +} + +E_MAKE_TYPE(e_table_col, "ETableCol", ETableCol, e_table_col_class_init, e_table_col_init, PARENT_TYPE); ETableCol * -e_table_col_new (int col_idx, const char *text, int width, int min_width, +e_table_col_new (int col_idx, const char *text, double expansion, int min_width, ECell *ecell, GCompareFunc compare, gboolean resizable) { ETableCol *etc; - g_return_val_if_fail (width >= 0, NULL); + g_return_val_if_fail (expansion >= 0, NULL); g_return_val_if_fail (min_width >= 0, NULL); - g_return_val_if_fail (width >= min_width, NULL); g_return_val_if_fail (compare != NULL, NULL); etc = gtk_type_new (E_TABLE_COL_TYPE); @@ -59,7 +64,7 @@ e_table_col_new (int col_idx, const char *text, int width, int min_width, etc->col_idx = col_idx; etc->text = g_strdup (text); etc->pixbuf = NULL; - etc->width = width; + etc->expansion = expansion; etc->min_width = min_width; etc->ecell = ecell; etc->compare = compare; @@ -75,14 +80,13 @@ e_table_col_new (int col_idx, const char *text, int width, int min_width, } ETableCol * -e_table_col_new_with_pixbuf (int col_idx, GdkPixbuf *pixbuf, int width, int min_width, +e_table_col_new_with_pixbuf (int col_idx, GdkPixbuf *pixbuf, double expansion, int min_width, ECell *ecell, GCompareFunc compare, gboolean resizable) { ETableCol *etc; - g_return_val_if_fail (width >= 0, NULL); + g_return_val_if_fail (expansion >= 0, NULL); g_return_val_if_fail (min_width >= 0, NULL); - g_return_val_if_fail (width >= min_width, NULL); g_return_val_if_fail (compare != NULL, NULL); etc = gtk_type_new (E_TABLE_COL_TYPE); @@ -92,7 +96,7 @@ e_table_col_new_with_pixbuf (int col_idx, GdkPixbuf *pixbuf, int width, int min_ etc->col_idx = col_idx; etc->text = NULL; etc->pixbuf = pixbuf; - etc->width = width; + etc->expansion = expansion; etc->min_width = min_width; etc->ecell = ecell; etc->compare = compare; diff --git a/widgets/e-table/e-table-col.h b/widgets/e-table/e-table-col.h index 816879792e..a7878fe4d7 100644 --- a/widgets/e-table/e-table-col.h +++ b/widgets/e-table/e-table-col.h @@ -28,8 +28,9 @@ struct _ETableCol { GtkObject base; char *text; GdkPixbuf *pixbuf; - short width; - short min_width; + int min_width; + int width; + double expansion; short x; GCompareFunc compare; unsigned int is_pixbuf:1; @@ -48,11 +49,11 @@ struct _ETableColClass { GtkType e_table_col_get_type (void); ETableCol *e_table_col_new (int col_idx, const char *text, - int width, int min_width, + double expansion, int min_width, ECell *ecell, GCompareFunc compare, gboolean resizable); ETableCol *e_table_col_new_with_pixbuf (int col_idx, GdkPixbuf *pixbuf, - int width, int min_width, + double expansion, int min_width, ECell *ecell, GCompareFunc compare, gboolean resizable); void e_table_col_destroy (ETableCol *etc); diff --git a/widgets/e-table/e-table-defines.h b/widgets/e-table/e-table-defines.h new file mode 100644 index 0000000000..02f1d19b77 --- /dev/null +++ b/widgets/e-table/e-table-defines.h @@ -0,0 +1,3 @@ +#define BUTTON_HEIGHT 10 +#define BUTTON_PADDING 2 +#define GROUP_INDENT (BUTTON_HEIGHT + (BUTTON_PADDING * 2)) diff --git a/widgets/e-table/e-table-example-1.c b/widgets/e-table/e-table-example-1.c index 0b3e40e5b7..70689c2953 100644 --- a/widgets/e-table/e-table-example-1.c +++ b/widgets/e-table/e-table-example-1.c @@ -215,7 +215,7 @@ create_table (void) /* Create the column. */ ETableCol *ecol = e_table_col_new ( i, headers [i], - 80, 20, cell_left_just, + 1.0, 20, cell_left_just, g_str_compare, TRUE); /* Add it to the header. */ e_table_header_add_column (e_table_header, ecol, i); diff --git a/widgets/e-table/e-table-example-2.c b/widgets/e-table/e-table-example-2.c index 6db06625a3..5bc6910437 100644 --- a/widgets/e-table/e-table-example-2.c +++ b/widgets/e-table/e-table-example-2.c @@ -239,7 +239,7 @@ create_table () /* Create the column. */ ETableCol *ecol = e_table_col_new ( i, headers [i], - 80, 20, cell_left_just, + 1.0, 20, cell_left_just, g_str_compare, TRUE); /* Add it to the header. */ e_table_header_add_column (e_table_header, ecol, i); @@ -249,7 +249,7 @@ create_table () cell_checkbox = e_cell_checkbox_new (); pixbuf = gdk_pixbuf_new_from_file ("clip.png"); - ecol = e_table_col_new_with_pixbuf (i, pixbuf, 18, 18, cell_checkbox, g_int_compare, TRUE); + ecol = e_table_col_new_with_pixbuf (i, pixbuf, 0.0, 18, cell_checkbox, g_int_compare, TRUE); e_table_header_add_column (e_table_header, ecol, i); /* diff --git a/widgets/e-table/e-table-group-container.c b/widgets/e-table/e-table-group-container.c index dd463b7ec0..4c5dfa38a6 100644 --- a/widgets/e-table/e-table-group-container.c +++ b/widgets/e-table/e-table-group-container.c @@ -19,12 +19,9 @@ #include "e-util/e-canvas.h" #include "e-util/e-canvas-utils.h" #include "widgets/e-text/e-text.h" +#include "e-table-defines.h" #define TITLE_HEIGHT 16 -#define GROUP_INDENT 10 - -#define BUTTON_HEIGHT 10 -#define BUTTON_PADDING 2 #define PARENT_TYPE e_table_group_get_type () @@ -35,7 +32,8 @@ enum { ARG_0, ARG_HEIGHT, ARG_WIDTH, - ARG_FROZEN + ARG_MINIMUM_WIDTH, + ARG_FROZEN, }; typedef struct { @@ -66,9 +64,6 @@ e_table_group_container_list_free (ETableGroupContainer *etgc) ETableGroupContainerChildNode *child_node; GList *list; - if (etgc->idle) - g_source_remove (etgc->idle); - for (list = etgc->children; list; list = g_list_next (list)) { child_node = (ETableGroupContainerChildNode *) list->data; e_table_group_container_child_node_free (etgc, child_node); @@ -100,102 +95,6 @@ etgc_destroy (GtkObject *object) GTK_OBJECT_CLASS (etgc_parent_class)->destroy (object); } -#if 0 -void -e_table_group_add (ETableGroup *etg, GnomeCanvasItem *item) -{ - double x1, y1, x2, y2; - - g_return_if_fail (etg != NULL); - g_return_if_fail (item != NULL); - g_return_if_fail (E_IS_TABLE_GROUP (etg)); - g_return_if_fail (GNOME_IS_CANVAS_ITEM (item)); - - etg->children = g_list_append (etg->children, item); - - GNOME_CANVAS_ITEM_CLASS (GTK_OBJECT (etg)->klass)->bounds (etg, &x1, &y1, &x2, &y2); - - if (GTK_OBJECT (etg)->flags & GNOME_CANVAS_ITEM_REALIZED){ - GList *l; - int height = etg->transparent ? 0 : TITLE_HEIGHT; - int x = etg->transparent ? 0 : GROUP_INDENT; - - for (l = etg->children; l->next; l = l->next){ - GnomeCanvasItem *child = l->data; - - height += child->y2 - child->y1; - - printf ("Height\n"); - if (E_IS_TABLE_ITEM (item)){ - printf (" Item: "); - } else { - printf (" Group: "); - } - printf ("%d\n", child->y2-child->y1); - } - - e_canvas_item_move_absolute (item, x, height); - - - if (E_IS_TABLE_ITEM (item)){ - - printf ("Table item! ---------\n"); - gtk_signal_connect (GTK_OBJECT (item), "resize", - GTK_SIGNAL_FUNC (etg_relayout), etg); - } - } -} - -static void -etg_realize (GnomeCanvasItem *item) -{ - ETableGroup *etg = E_TABLE_GROUP (item); - GList *l; - int height = 0; - - GNOME_CANVAS_ITEM_CLASS (etg_parent_class)->realize (item); - - for (l = etg->children; l; l = l->next){ - GnomeCanvasItem *child = l->data; - - printf ("During realization for child %p -> %d\n", child, height); - gnome_canvas_item_set ( - child, - "y", (double) height, - NULL); - - height += child->y2 - child->y1; - } -} - -static void -etg_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags) -{ - ETableGroup *etg = E_TABLE_GROUP (item); - - GNOME_CANVAS_ITEM_CLASS (etg_parent_class)->update (item, affine, clip_path, flags); - - if (!etg->transparent){ - int current_width, current_height; - - etg_dim (etg, ¤t_width, ¤t_height); - - if ((current_height != etg->height) || (current_width != etg->width)){ - etg->width = current_width; - etg->height = current_height; - - gnome_canvas_item_set ( - etg->rect, - "x1", 0.0, - "y1", 0.0, - "x2", (double) etg->width, - "y2", (double) etg->height, - NULL); - } - } -} -#endif - void e_table_group_container_construct (GnomeCanvasGroup *parent, ETableGroupContainer *etgc, ETableHeader *full_header, @@ -226,42 +125,6 @@ e_table_group_container_construct (GnomeCanvasGroup *parent, ETableGroupContaine gdk_font_ref (etgc->font); } etgc->open = TRUE; -#if 0 - etgc->transparent = transparent; - - etgc_dim (etgc, &etgc->width, &etgc->height); - - if (!etgc->transparent) - etgc->rect = gnome_canvas_item_new ( - GNOME_CANVAS_GROUP (etgc), - gnome_canvas_rect_get_type (), - "fill_color", "gray", - "outline_color", "gray20", - "x1", 0.0, - "y1", 0.0, - "x2", (double) etgc->width, - "y2", (double) etgc->height, - NULL); -#endif - -#if 0 - /* - * Reparent the child into our space. - */ - gnome_canvas_item_reparent (child, GNOME_CANVAS_GROUP (etgc)); - - gnome_canvas_item_set ( - child, - "x", (double) GROUP_INDENT, - "y", (double) TITLE_HEIGHT, - NULL); - - /* - * Force dimension computation - */ - GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->update ( - GNOME_CANVAS_ITEM (etgc), NULL, NULL, GNOME_CANVAS_UPDATE_REQUESTED); -#endif } ETableGroup * @@ -280,135 +143,6 @@ e_table_group_container_new (GnomeCanvasGroup *parent, ETableHeader *full_header return E_TABLE_GROUP (etgc); } -#if 0 -static void -etgc_relayout (GnomeCanvasItem *eti, ETableGroupContainer *etgc) -{ - GList *l; - int height = etgc->transparent ? 0 : GROUP_INDENT; - gboolean move = FALSE; - - printf ("Relaying out\n"); - - for (l = etgc->children; l->next; l = l->next){ - GnomeCanvasItem *child = l->data; - - height += child->y2 - child->y1; - - if (child == eti) - move = TRUE; - - if (move){ - printf ("Moving item %p\n", child); - gnome_canvas_item_set (child, - "y", (double) height, - NULL); - } - } - if (height != etgc->height){ - etgc->height = height; - gtk_signal_emit (GTK_OBJECT (etgc), etgc_signals [RESIZE]); - } -} - -void -e_table_group_container_add (ETableGroupContainer *etgc, GnomeCanvasItem *item) -{ - double x1, y1, x2, y2; - - g_return_if_fail (etgc != NULL); - g_return_if_fail (item != NULL); - g_return_if_fail (E_IS_TABLE_GROUP (etgc)); - g_return_if_fail (GNOME_IS_CANVAS_ITEM (item)); - - etgc->children = g_list_append (etgc->children, item); - - GNOME_CANVAS_ITEM_CLASS (GTK_OBJECT (etgc)->klass)->bounds (etgc, &x1, &y1, &x2, &y2); - - if (GTK_OBJECT (etgc)->flags & GNOME_CANVAS_ITEM_REALIZED){ - GList *l; - int height = etgc->transparent ? 0 : TITLE_HEIGHT; - int x = etgc->transparent ? 0 : GROUP_INDENT; - - for (l = etgc->children; l->next; l = l->next){ - GnomeCanvasItem *child = l->data; - - height += child->y2 - child->y1; - - printf ("Height\n"); - if (E_IS_TABLE_ITEM (item)){ - printf (" Item: "); - } else { - printf (" Group: "); - } - printf ("%d\n", child->y2-child->y1); - } - - e_canvas_item_move_absolute (item, x, height); - - - if (E_IS_TABLE_ITEM (item)){ - - printf ("Table item! ---------\n"); - gtk_signal_connect (GTK_OBJECT (item), "resize", - GTK_SIGNAL_FUNC (etgc_relayout), etgc); - } - } -} - -static void -etgc_realize (GnomeCanvasItem *item) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (item); - GList *l; - int height = 0; - - GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->realize (item); - - for (l = etgc->children; l; l = l->next){ - GnomeCanvasItem *child = l->data; - - printf ("During realization for child %p -> %d\n", child, height); - gnome_canvas_item_set ( - child, - "y", (double) height, - NULL); - - height += child->y2 - child->y1; - } -} - -static void -etgc_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (item); - - GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->update (item, affine, clip_path, flags); - - if (etgc->need_resize) { - - if (!etgc->transparent) { - int current_width, current_height; - - etgc_dim (etgc, ¤t_width, ¤t_height); - - if ((current_height != etgc->height) || (current_width != etgc->width)){ - etgc->width = current_width; - etgc->height = current_height; - - gnome_canvas_item_set ( - etgc->rect, - "x1", 0.0, - "y1", 0.0, - "x2", (double) etgc->width, - "y2", (double) etgc->height, - NULL); - } - } - etgc->need_resize = FALSE; - } -} -#endif static int etgc_event (GnomeCanvasItem *item, GdkEvent *event) @@ -699,6 +433,8 @@ static void etgc_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) { ETableGroup *etg = E_TABLE_GROUP (object); + ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (object); + GList *list; switch (arg_id) { case ARG_FROZEN: @@ -709,9 +445,15 @@ etgc_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) etgc_thaw (etg); } break; - case ARG_WIDTH: - if (E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->set_width) - E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->set_width (etg, GTK_VALUE_DOUBLE (*arg)); + case ARG_MINIMUM_WIDTH: + etgc->minimum_width = GTK_VALUE_DOUBLE(*arg); + + for (list = etgc->children; list; list = g_list_next (list)) { + ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *)list->data; + gtk_object_set (GTK_OBJECT(child_node->child), + "minimum_width", etgc->minimum_width - GROUP_INDENT, + NULL); + } break; default: break; @@ -722,22 +464,20 @@ static void etgc_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) { ETableGroup *etg = E_TABLE_GROUP (object); + ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (object); switch (arg_id) { case ARG_FROZEN: GTK_VALUE_BOOL (*arg) = etg->frozen; break; case ARG_HEIGHT: - if (E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_height) - GTK_VALUE_DOUBLE (*arg) = E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_height (etg); - else - arg->type = GTK_TYPE_INVALID; + GTK_VALUE_DOUBLE (*arg) = etgc->height; break; case ARG_WIDTH: - if (E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_width) - GTK_VALUE_DOUBLE (*arg) = E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_width (etg); - else - arg->type = GTK_TYPE_INVALID; + GTK_VALUE_DOUBLE (*arg) = etgc->width; + break; + case ARG_MINIMUM_WIDTH: + etgc->minimum_width = GTK_VALUE_DOUBLE(*arg); break; default: arg->type = GTK_TYPE_INVALID; @@ -745,38 +485,6 @@ etgc_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) } } -static void etgc_set_width (ETableGroup *etg, gdouble width) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg); - GList *list = etgc->children; - etgc->width = width; - - for (; list; list = g_list_next (list)){ - gdouble child_width = width - GROUP_INDENT; - ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *)list->data; - gtk_object_set (GTK_OBJECT(child_node->child), - "width", child_width, - NULL); - - gnome_canvas_item_set (GNOME_CANVAS_ITEM(child_node->rect), - "x1", (double) 0, - "x2", (double) etgc->width, - NULL); - } -} - -static gdouble etgc_get_width (ETableGroup *etg) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg); - return etgc->width; -} - -static gdouble etgc_get_height (ETableGroup *etg) -{ - ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg); - return etgc->height; -} - static void etgc_class_init (GtkObjectClass *object_class) { @@ -799,18 +507,15 @@ etgc_class_init (GtkObjectClass *object_class) e_group_class->increment = etgc_increment; e_group_class->set_focus = etgc_set_focus; e_group_class->get_focus_column = etgc_get_focus_column; - e_group_class->thaw = etgc_thaw; - - e_group_class->get_width = etgc_get_width; - e_group_class->set_width = etgc_set_width; - e_group_class->get_height = etgc_get_height; + gtk_object_add_arg_type ("ETableGroupContainer::frozen", GTK_TYPE_BOOL, + GTK_ARG_READWRITE, ARG_FROZEN); gtk_object_add_arg_type ("ETableGroupContainer::height", GTK_TYPE_DOUBLE, GTK_ARG_READABLE, ARG_HEIGHT); gtk_object_add_arg_type ("ETableGroupContainer::width", GTK_TYPE_DOUBLE, - GTK_ARG_READWRITE, ARG_WIDTH); - gtk_object_add_arg_type ("ETableGroupContainer::frozen", GTK_TYPE_BOOL, - GTK_ARG_READWRITE, ARG_FROZEN); + GTK_ARG_READABLE, ARG_WIDTH); + gtk_object_add_arg_type ("ETableGroupContainer::minimum_width", GTK_TYPE_DOUBLE, + GTK_ARG_READWRITE, ARG_MINIMUM_WIDTH); } static void @@ -823,23 +528,25 @@ etgc_reflow (GnomeCanvasItem *item, gint flags) "frozen", &frozen, NULL); - if (frozen){ - etgc->idle = 0; + if (frozen) return; - } + if (GTK_OBJECT_FLAGS(etgc)& GNOME_CANVAS_ITEM_REALIZED){ + gdouble running_height = 0; + gdouble running_width = 0; gdouble old_height; + gdouble old_width; old_height = etgc->height; + old_width = etgc->width; if (etgc->children == NULL){ } else { GList *list; - gdouble extra_height; - gdouble running_height; + gdouble extra_height = 0; gdouble item_height = 0; + gdouble item_width = 0; - extra_height = 0; if (etgc->font) extra_height += etgc->font->ascent + etgc->font->descent + BUTTON_PADDING * 2; @@ -847,8 +554,18 @@ etgc_reflow (GnomeCanvasItem *item, gint flags) running_height = extra_height; - list = etgc->children; - for (; list; list = g_list_next (list)){ + for ( list = etgc->children; list; list = g_list_next (list)){ + ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data; + ETableGroup *child = child_node->child; + + gtk_object_get (GTK_OBJECT(child), + "width", &item_width, + NULL); + + if (item_width > running_width) + running_width = item_width; + } + for ( list = etgc->children; list; list = g_list_next (list)){ ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data; ETableGroup *child = child_node->child; gtk_object_get (GTK_OBJECT(child), @@ -865,7 +582,7 @@ etgc_reflow (GnomeCanvasItem *item, gint flags) gnome_canvas_item_set (GNOME_CANVAS_ITEM(child_node->rect), "x1", (double) 0, - "x2", (double) etgc->width, + "x2", (double) running_width, "y1", (double) running_height - extra_height, "y2", (double) running_height + item_height, NULL); @@ -873,13 +590,13 @@ etgc_reflow (GnomeCanvasItem *item, gint flags) running_height += item_height + extra_height; } running_height -= extra_height; - if (running_height != old_height) { - etgc->height = running_height; - e_canvas_item_request_parent_reflow (item); - } + } + if (running_height != old_height || running_width != old_width) { + etgc->height = running_height; + etgc->width = running_width; + e_canvas_item_request_parent_reflow (item); } } - etgc->idle = 0; } static void diff --git a/widgets/e-table/e-table-group-container.h b/widgets/e-table/e-table-group-container.h index 50424009f2..7577a3d70a 100644 --- a/widgets/e-table/e-table-group-container.h +++ b/widgets/e-table/e-table-group-container.h @@ -34,13 +34,11 @@ typedef struct { GdkFont *font; - gdouble width, height; + gdouble width, height, minimum_width; ETableSortInfo *sort_info; int n; - gint idle; - /* * State: the ETableGroup is open or closed */ diff --git a/widgets/e-table/e-table-group-leaf.c b/widgets/e-table/e-table-group-leaf.c index e39afa7f88..caa0125a78 100644 --- a/widgets/e-table/e-table-group-leaf.c +++ b/widgets/e-table/e-table-group-leaf.c @@ -10,7 +10,6 @@ #include #include -#include "e-table-group-container.h" #include "e-table-group-leaf.h" #include "e-table-item.h" #include @@ -29,7 +28,8 @@ enum { ARG_0, ARG_HEIGHT, ARG_WIDTH, - ARG_FROZEN + ARG_MINIMUM_WIDTH, + ARG_FROZEN, }; static void etgl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id); @@ -48,21 +48,23 @@ etgl_destroy (GtkObject *object) } static void -e_table_group_leaf_construct (GnomeCanvasGroup *parent, ETableGroupLeaf *etgl, - ETableHeader *full_header, +e_table_group_leaf_construct (GnomeCanvasGroup *parent, + ETableGroupLeaf *etgl, + ETableHeader *full_header, ETableHeader *header, - ETableModel *model, - ETableSortInfo *sort_info) + ETableModel *model, + ETableSortInfo *sort_info) { etgl->subset = E_TABLE_SUBSET_VARIABLE(e_table_sorted_variable_new (model, full_header, sort_info)); e_table_group_construct (parent, E_TABLE_GROUP (etgl), full_header, header, model); } ETableGroup * -e_table_group_leaf_new (GnomeCanvasGroup *parent, ETableHeader *full_header, +e_table_group_leaf_new (GnomeCanvasGroup *parent, + ETableHeader *full_header, ETableHeader *header, - ETableModel *model, - ETableSortInfo *sort_info) + ETableModel *model, + ETableSortInfo *sort_info) { ETableGroupLeaf *etgl; @@ -85,6 +87,13 @@ etgl_row_selection (GtkObject *object, gint row, gboolean selected, ETableGroupL static void etgl_reflow (GnomeCanvasItem *item, gint flags) { + ETableGroupLeaf *leaf = E_TABLE_GROUP_LEAF(item); + gtk_object_get(GTK_OBJECT(leaf->item), + "height", &leaf->height, + NULL); + gtk_object_get(GTK_OBJECT(leaf->item), + "width", &leaf->width, + NULL); e_canvas_item_request_parent_reflow (item); } @@ -103,31 +112,13 @@ etgl_realize (GnomeCanvasItem *item) "drawgrid", TRUE, "drawfocus", TRUE, "spreadsheet", TRUE, - "width", etgl->width, + "minimum_width", etgl->minimum_width, "length_threshold", 200, NULL)); - + gtk_signal_connect (GTK_OBJECT(etgl->item), "row_selection", - GTK_SIGNAL_FUNC(etgl_row_selection), etgl); - e_canvas_item_request_parent_reflow (item); -} - -static int -etgl_event (GnomeCanvasItem *item, GdkEvent *event) -{ - gboolean return_val = TRUE; - - switch (event->type) { - - default: - return_val = FALSE; - } - if (return_val == FALSE){ - if (GNOME_CANVAS_ITEM_CLASS(etgl_parent_class)->event) - return GNOME_CANVAS_ITEM_CLASS(etgl_parent_class)->event (item, event); - } - return return_val; - + GTK_SIGNAL_FUNC(etgl_row_selection), etgl); + e_canvas_item_request_reflow(item); } static void @@ -176,48 +167,11 @@ etgl_get_focus_column (ETableGroup *etg) return e_table_item_get_focused_column (etgl->item); } -static void -etgl_set_width (ETableGroup *etg, gdouble width) -{ - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg); - etgl->width = width; -#if 0 - if (etgl->item){ - gnome_canvas_item_set (GNOME_CANVAS_ITEM(etgl->item), - "width", width, - NULL); - } -#endif -} - -static gdouble -etgl_get_width (ETableGroup *etg) -{ - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg); - gtk_object_get (GTK_OBJECT(etgl->item), - "width", &etgl->width, - NULL); - return etgl->width; -} - -static gdouble -etgl_get_height (ETableGroup *etg) -{ - ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg); - gdouble height; - if (etgl->item) - gtk_object_get (GTK_OBJECT(etgl->item), - "height", &height, - NULL); - else - height = 1; - return height; -} - static void etgl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) { ETableGroup *etg = E_TABLE_GROUP (object); + ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (object); switch (arg_id) { case ARG_FROZEN: @@ -227,9 +181,13 @@ etgl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) etg->frozen = FALSE; } break; - case ARG_WIDTH: - if (E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->set_width) - E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->set_width (etg, GTK_VALUE_DOUBLE (*arg)); + case ARG_MINIMUM_WIDTH: + etgl->minimum_width = GTK_VALUE_DOUBLE(*arg); + if (etgl->item) { + gnome_canvas_item_set (GNOME_CANVAS_ITEM(etgl->item), + "minimum_width", etgl->minimum_width, + NULL); + } break; default: break; @@ -240,22 +198,20 @@ static void etgl_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) { ETableGroup *etg = E_TABLE_GROUP (object); + ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (object); switch (arg_id) { case ARG_FROZEN: GTK_VALUE_BOOL (*arg) = etg->frozen; break; case ARG_HEIGHT: - if (E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_height) - GTK_VALUE_DOUBLE (*arg) = E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_height (etg); - else - arg->type = GTK_TYPE_INVALID; + GTK_VALUE_DOUBLE (*arg) = etgl->height; break; - case ARG_WIDTH: - if (E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_width) - GTK_VALUE_DOUBLE (*arg) = E_TABLE_GROUP_CLASS(GTK_OBJECT(etg)->klass)->get_width (etg); - else - arg->type = GTK_TYPE_INVALID; + case ARG_WIDTH: + GTK_VALUE_DOUBLE (*arg) = etgl->width; + break; + case ARG_MINIMUM_WIDTH: + GTK_VALUE_DOUBLE (*arg) = etgl->minimum_width; break; default: arg->type = GTK_TYPE_INVALID; @@ -274,7 +230,6 @@ etgl_class_init (GtkObjectClass *object_class) object_class->get_arg = etgl_get_arg; item_class->realize = etgl_realize; - item_class->event = etgl_event; etgl_parent_class = gtk_type_class (PARENT_TYPE); @@ -285,14 +240,12 @@ etgl_class_init (GtkObjectClass *object_class) e_group_class->set_focus = etgl_set_focus; e_group_class->get_focus_column = etgl_get_focus_column; - e_group_class->get_width = etgl_get_width; - e_group_class->set_width = etgl_set_width; - e_group_class->get_height = etgl_get_height; - gtk_object_add_arg_type ("ETableGroupLeaf::height", GTK_TYPE_DOUBLE, GTK_ARG_READABLE, ARG_HEIGHT); gtk_object_add_arg_type ("ETableGroupLeaf::width", GTK_TYPE_DOUBLE, - GTK_ARG_READWRITE, ARG_WIDTH); + GTK_ARG_READABLE, ARG_WIDTH); + gtk_object_add_arg_type ("ETableGroupLeaf::minimum_width", GTK_TYPE_DOUBLE, + GTK_ARG_READWRITE, ARG_MINIMUM_WIDTH); gtk_object_add_arg_type ("ETableGroupLeaf::frozen", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_FROZEN); } @@ -303,6 +256,9 @@ etgl_init (GtkObject *object) ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (object); etgl->width = 1; + etgl->height = 1; + etgl->minimum_width = 0; + etgl->subset = NULL; etgl->item = NULL; diff --git a/widgets/e-table/e-table-group-leaf.h b/widgets/e-table/e-table-group-leaf.h index 3f39fe95dd..bffeb798e0 100644 --- a/widgets/e-table/e-table-group-leaf.h +++ b/widgets/e-table/e-table-group-leaf.h @@ -21,8 +21,10 @@ typedef struct { */ ETableItem *item; + gdouble height; gdouble width; - + gdouble minimum_width; + ETableSubsetVariable *subset; } ETableGroupLeaf; diff --git a/widgets/e-table/e-table-group.c b/widgets/e-table/e-table-group.c index e47986472b..9544059a0c 100644 --- a/widgets/e-table/e-table-group.c +++ b/widgets/e-table/e-table-group.c @@ -34,16 +34,6 @@ enum { static gint etg_signals [LAST_SIGNAL] = { 0, }; -/* The arguments we take */ -enum { - ARG_0, - ARG_HEIGHT, - ARG_WIDTH, - ARG_FROZEN -}; - -static void etg_set_arg (GtkObject *object, GtkArg *arg, guint arg_id); -static void etg_get_arg (GtkObject *object, GtkArg *arg, guint arg_id); static gboolean etg_get_focus (ETableGroup *etg); static void etg_destroy (GtkObject *object); #if 0 @@ -261,66 +251,6 @@ etg_event (GnomeCanvasItem *item, GdkEvent *event) } -static void -etg_thaw (ETableGroup *etg) -{ - g_return_if_fail (etg != NULL); - g_return_if_fail (E_IS_TABLE_GROUP (etg)); - - if (ETG_CLASS (etg)->thaw) - ETG_CLASS (etg)->thaw (etg); -} - -static void -etg_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - ETableGroup *etg = E_TABLE_GROUP (object); - - switch (arg_id) { - case ARG_FROZEN: - if (GTK_VALUE_BOOL (*arg)) - etg->frozen = TRUE; - else { - etg->frozen = FALSE; - etg_thaw (etg); - } - break; - case ARG_WIDTH: - if (ETG_CLASS(etg)->set_width) - ETG_CLASS(etg)->set_width (etg, GTK_VALUE_DOUBLE (*arg)); - break; - default: - break; - } -} - -static void -etg_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - ETableGroup *etg = E_TABLE_GROUP (object); - - switch (arg_id) { - case ARG_FROZEN: - GTK_VALUE_BOOL (*arg) = etg->frozen; - break; - case ARG_HEIGHT: - if (ETG_CLASS(etg)->get_height) - GTK_VALUE_DOUBLE (*arg) = ETG_CLASS(etg)->get_height (etg); - else - arg->type = GTK_TYPE_INVALID; - break; - case ARG_WIDTH: - if (ETG_CLASS(etg)->get_width) - GTK_VALUE_DOUBLE (*arg) = ETG_CLASS(etg)->get_width (etg); - else - arg->type = GTK_TYPE_INVALID; - break; - default: - arg->type = GTK_TYPE_INVALID; - break; - } -} - static gboolean etg_get_focus (ETableGroup *etg) { @@ -332,9 +262,7 @@ etg_class_init (GtkObjectClass *object_class) { GnomeCanvasItemClass *item_class = (GnomeCanvasItemClass *) object_class; ETableGroupClass *klass = (ETableGroupClass *) object_class; - - object_class->set_arg = etg_set_arg; - object_class->get_arg = etg_get_arg; + object_class->destroy = etg_destroy; item_class->event = etg_event; @@ -350,11 +278,6 @@ etg_class_init (GtkObjectClass *object_class) klass->get_focus = etg_get_focus; klass->get_ecol = NULL; - klass->thaw = NULL; - klass->get_height = NULL; - klass->get_width = NULL; - klass->set_width = NULL; - etg_parent_class = gtk_type_class (PARENT_TYPE); etg_signals [ROW_SELECTION] = diff --git a/widgets/e-table/e-table-group.h b/widgets/e-table/e-table-group.h index 573a4f9547..dd0771745b 100644 --- a/widgets/e-table/e-table-group.h +++ b/widgets/e-table/e-table-group.h @@ -53,10 +53,6 @@ typedef struct { gint (*get_focus_column) (ETableGroup *etg); ETableCol *(*get_ecol) (ETableGroup *etg); - void (*thaw) (ETableGroup *etg); - gdouble (*get_height) (ETableGroup *etg); - gdouble (*get_width) (ETableGroup *etg); - void (*set_width) (ETableGroup *etg, gdouble width); } ETableGroupClass; void e_table_group_add (ETableGroup *etg, diff --git a/widgets/e-table/e-table-header-item.c b/widgets/e-table/e-table-header-item.c index 6923fffd0a..89d901b4be 100644 --- a/widgets/e-table/e-table-header-item.c +++ b/widgets/e-table/e-table-header-item.c @@ -21,6 +21,7 @@ #include "e-table-header.h" #include "e-table-header-item.h" #include "e-table-col-dnd.h" +#include "e-table-defines.h" #include "add-col.xpm" #include "remove-col.xpm" @@ -42,10 +43,8 @@ static guint ethi_signals [LAST_SIGNAL] = { 0, }; #define MIN_ARROW_SIZE 10 -#define GROUP_INDENT 10 - /* Defines the tolerance for proximity of the column division to the cursor position */ -#define TOLERANCE 3 +#define TOLERANCE 4 #define ETHI_RESIZING(x) ((x)->resize_col != -1) @@ -114,6 +113,13 @@ ethi_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->update) (*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->update)(item, affine, clip_path, flags); + if (ethi->sort_info) + ethi->group_indent_width = e_table_sort_info_grouping_get_count(ethi->sort_info) * GROUP_INDENT; + else + ethi->group_indent_width = 0; + + ethi->width = e_table_header_total_width (ethi->eth) + ethi->group_indent_width; + if (item->x1 != ethi->x1 || item->y1 != ethi->y1 || item->x2 != ethi->x1 + ethi->width || @@ -165,17 +171,13 @@ ethi_drop_table_header (ETableHeaderItem *ethi) static void structure_changed (ETableHeader *header, ETableHeaderItem *ethi) { - ethi->width = e_table_header_total_width (header) + ethi->group_indent_width; - - ethi_update (GNOME_CANVAS_ITEM (ethi), NULL, NULL, 0); + gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(ethi)); } static void dimension_changed (ETableHeader *header, int col, ETableHeaderItem *ethi) { - ethi->width = e_table_header_total_width (header) + ethi->group_indent_width; - - ethi_update (GNOME_CANVAS_ITEM (ethi), NULL, NULL, 0); + gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(ethi)); } static void @@ -183,7 +185,6 @@ ethi_add_table_header (ETableHeaderItem *ethi, ETableHeader *header) { ethi->eth = header; gtk_object_ref (GTK_OBJECT (ethi->eth)); - ethi->width = e_table_header_total_width (header) + ethi->group_indent_width; ethi->structure_change_id = gtk_signal_connect ( GTK_OBJECT (header), "structure_change", @@ -191,6 +192,7 @@ ethi_add_table_header (ETableHeaderItem *ethi, ETableHeader *header) ethi->dimension_change_id = gtk_signal_connect ( GTK_OBJECT (header), "dimension_change", GTK_SIGNAL_FUNC(dimension_changed), ethi); + gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(ethi)); } static void @@ -706,7 +708,6 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width int x1, x2; int col; GHashTable *arrows = g_hash_table_new (NULL, NULL); - gint group_indent = 0; if (ethi->sort_info) { @@ -714,7 +715,6 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width int i; for (i = 0; i < length; i++) { ETableSortColumn column = e_table_sort_info_grouping_get_nth(ethi->sort_info, i); - group_indent ++; g_hash_table_insert (arrows, (gpointer) column.column, (gpointer) (column.ascending ? @@ -732,7 +732,6 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width } } - ethi->group_indent_width = group_indent * GROUP_INDENT; ethi->width = e_table_header_total_width (ethi->eth) + ethi->group_indent_width; x1 = x2 = ethi->x1; x2 += ethi->group_indent_width; @@ -740,10 +739,7 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width ETableCol *ecol = e_table_header_get_column (ethi->eth, col); int col_width; - if (col == ethi->resize_col) - col_width = ethi->resize_width; - else - col_width = ecol->width; + col_width = ecol->width; x2 += col_width; @@ -839,14 +835,12 @@ ethi_request_redraw (ETableHeaderItem *ethi) } static void -ethi_end_resize (ETableHeaderItem *ethi, int new_size) +ethi_end_resize (ETableHeaderItem *ethi) { - e_table_header_set_size (ethi->eth, ethi->resize_col, new_size); - ethi->resize_col = -1; ethi->resize_guide = GINT_TO_POINTER (0); - - ethi_request_redraw (ethi); + + gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(ethi)); } static gboolean @@ -910,10 +904,7 @@ ethi_start_drag (ETableHeaderItem *ethi, GdkEvent *event) context = gtk_drag_begin (widget, list, GDK_ACTION_MOVE, 1, event); ecol = e_table_header_get_column (ethi->eth, ethi->drag_col); - if (ethi->drag_col == ethi->resize_col) - col_width = ethi->resize_width; - else - col_width = ecol->width; + col_width = ecol->width; pixmap = gdk_pixmap_new (widget->window, col_width, ethi->height, -1); gc = widget->style->bg_gc [GTK_STATE_ACTIVE]; draw_button (ethi, ecol, pixmap, gc, @@ -998,17 +989,9 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e) new_width = x - ethi->resize_start_pos; - if (new_width <= 0) - new_width = 1; + e_table_header_set_size (ethi->eth, ethi->resize_col, new_width); - if (new_width < ethi->resize_min_width) - new_width = ethi->resize_min_width; - ethi_request_redraw (ethi); - - ethi->resize_width = new_width; - e_table_header_set_size (ethi->eth, ethi->resize_col, ethi->resize_width); - - ethi_request_redraw (ethi); + gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(ethi)); } else if (ethi_maybe_start_drag (ethi, &e->motion)){ ethi_start_drag (ethi, e); } else @@ -1033,7 +1016,6 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e) if (!ecol->resizeable) break; ethi->resize_col = col; - ethi->resize_width = ecol->width; ethi->resize_start_pos = start - ecol->width; ethi->resize_min_width = ecol->min_width; } else { @@ -1065,7 +1047,7 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e) if (ethi->resize_col != -1){ needs_ungrab = (ethi->resize_guide != NULL); - ethi_end_resize (ethi, ethi->resize_width); + ethi_end_resize (ethi); } else if (was_maybe_drag && ethi->sort_info) { ETableCol *col; int model_col; diff --git a/widgets/e-table/e-table-header-item.h b/widgets/e-table/e-table-header-item.h index 2b3f2e8f74..300a7c81fb 100644 --- a/widgets/e-table/e-table-header-item.h +++ b/widgets/e-table/e-table-header-item.h @@ -27,7 +27,6 @@ typedef struct { * Used during resizing; Could be shorts */ int resize_col; - int resize_width; int resize_start_pos; int resize_min_width; diff --git a/widgets/e-table/e-table-header.c b/widgets/e-table/e-table-header.c index 4e9bf278ee..61e1f9a9da 100644 --- a/widgets/e-table/e-table-header.c +++ b/widgets/e-table/e-table-header.c @@ -12,6 +12,14 @@ #include #include #include "e-table-header.h" +#include "e-table-defines.h" + +/* The arguments we take */ +enum { + ARG_0, + ARG_SORT_INFO, + ARG_WIDTH, +}; enum { STRUCTURE_CHANGE, @@ -19,22 +27,33 @@ enum { LAST_SIGNAL }; +static void eth_set_arg (GtkObject *object, GtkArg *arg, guint arg_id); +static void eth_get_arg (GtkObject *object, GtkArg *arg, guint arg_id); +static void eth_do_remove (ETableHeader *eth, int idx, gboolean do_unref); + static guint eth_signals [LAST_SIGNAL] = { 0, }; static GtkObjectClass *e_table_header_parent_class; static void -e_table_header_destroy (GtkObject *object) +eth_destroy (GtkObject *object) { ETableHeader *eth = E_TABLE_HEADER (object); const int cols = eth->col_count; int i; + if (eth->sort_info) { + if (eth->sort_info_group_change_id) + gtk_signal_disconnect(GTK_OBJECT(eth->sort_info), + eth->sort_info_group_change_id); + gtk_object_unref(GTK_OBJECT(eth->sort_info)); + } + /* * Destroy columns */ for (i = cols - 1; i >= 0; i--){ - e_table_header_remove (eth, i); + eth_do_remove (eth, i, TRUE); } if (e_table_header_parent_class->destroy) @@ -44,10 +63,18 @@ e_table_header_destroy (GtkObject *object) static void e_table_header_class_init (GtkObjectClass *object_class) { - object_class->destroy = e_table_header_destroy; + object_class->destroy = eth_destroy; + object_class->set_arg = eth_set_arg; + object_class->get_arg = eth_get_arg; + e_table_header_parent_class = (gtk_type_class (gtk_object_get_type ())); + gtk_object_add_arg_type ("ETableHeader::width", GTK_TYPE_DOUBLE, + GTK_ARG_READWRITE, ARG_WIDTH); + gtk_object_add_arg_type ("ETableHeader::sort_info", GTK_TYPE_OBJECT, + GTK_ARG_READWRITE, ARG_SORT_INFO); + eth_signals [STRUCTURE_CHANGE] = gtk_signal_new ("structure_change", GTK_RUN_LAST, @@ -66,6 +93,19 @@ e_table_header_class_init (GtkObjectClass *object_class) gtk_object_class_add_signals (object_class, eth_signals, LAST_SIGNAL); } +static void +e_table_header_init (ETableHeader *eth) +{ + eth->col_count = 0; + eth->width = 0; + + eth->sort_info = NULL; + eth->sort_info_group_change_id = 0; + + eth->columns = NULL; + eth->selectable = FALSE; +} + GtkType e_table_header_get_type (void) { @@ -77,7 +117,7 @@ e_table_header_get_type (void) sizeof (ETableHeader), sizeof (ETableHeaderClass), (GtkClassInitFunc) e_table_header_class_init, - (GtkObjectInitFunc) NULL, + (GtkObjectInitFunc) e_table_header_init, NULL, /* reserved 1 */ NULL, /* reserved 2 */ (GtkClassInitFunc) NULL @@ -100,12 +140,57 @@ e_table_header_new (void) } static void -eth_do_insert (ETableHeader *eth, int pos, ETableCol *val) +eth_group_info_changed(ETableSortInfo *info, ETableHeader *eth) { - memmove (ð->columns [pos+1], ð->columns [pos], - sizeof (ETableCol *) * (eth->col_count - pos)); - eth->columns [pos] = val; - eth->col_count ++; + e_table_header_calc_widths(eth); +} + +static void +eth_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) +{ + ETableHeader *eth = E_TABLE_HEADER (object); + + switch (arg_id) { + case ARG_WIDTH: + eth->width = GTK_VALUE_DOUBLE (*arg); + e_table_header_calc_widths(eth); + break; + case ARG_SORT_INFO: + if (eth->sort_info) { + if (eth->sort_info_group_change_id) + gtk_signal_disconnect(GTK_OBJECT(eth->sort_info), eth->sort_info_group_change_id); + gtk_object_unref(GTK_OBJECT(eth->sort_info)); + } + eth->sort_info = E_TABLE_SORT_INFO(GTK_VALUE_OBJECT (*arg)); + if (eth->sort_info) { + gtk_object_ref(GTK_OBJECT(eth->sort_info)); + eth->sort_info_group_change_id + = gtk_signal_connect(GTK_OBJECT(eth->sort_info), "group_info_changed", + GTK_SIGNAL_FUNC(eth_group_info_changed), eth); + } + e_table_header_calc_widths(eth); + break; + default: + break; + } +} + +static void +eth_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) +{ + ETableHeader *eth = E_TABLE_HEADER (object); + + switch (arg_id) { + case ARG_SORT_INFO: + GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(eth->sort_info); + break; + case ARG_WIDTH: + GTK_VALUE_DOUBLE (*arg) = eth->width; + break; + default: + arg->type = GTK_TYPE_INVALID; + break; + } } static void @@ -122,6 +207,15 @@ eth_update_offsets (ETableHeader *eth) } } +static void +eth_do_insert (ETableHeader *eth, int pos, ETableCol *val) +{ + memmove (ð->columns [pos+1], ð->columns [pos], + sizeof (ETableCol *) * (eth->col_count - pos)); + eth->columns [pos] = val; + eth->col_count ++; +} + void e_table_header_add_column (ETableHeader *eth, ETableCol *tc, int pos) { @@ -142,10 +236,9 @@ e_table_header_add_column (ETableHeader *eth, ETableCol *tc, int pos) gtk_object_sink (GTK_OBJECT (tc)); eth_do_insert (eth, pos, tc); - eth_update_offsets (eth); + e_table_header_calc_widths(eth); gtk_signal_emit (GTK_OBJECT (eth), eth_signals [STRUCTURE_CHANGE]); - gtk_signal_emit (GTK_OBJECT (eth), eth_signals [DIMENSION_CHANGE]); } ETableCol * @@ -285,8 +378,8 @@ e_table_header_move (ETableHeader *eth, int source_index, int target_index) eth_do_insert (eth, target_index, old); eth_update_offsets (eth); - gtk_signal_emit (GTK_OBJECT (eth), eth_signals [STRUCTURE_CHANGE]); gtk_signal_emit (GTK_OBJECT (eth), eth_signals [DIMENSION_CHANGE]); + gtk_signal_emit (GTK_OBJECT (eth), eth_signals [STRUCTURE_CHANGE]); } void @@ -298,8 +391,8 @@ e_table_header_remove (ETableHeader *eth, int idx) g_return_if_fail (idx < eth->col_count); eth_do_remove (eth, idx, TRUE); + e_table_header_calc_widths(eth); gtk_signal_emit (GTK_OBJECT (eth), eth_signals [STRUCTURE_CHANGE]); - gtk_signal_emit (GTK_OBJECT (eth), eth_signals [DIMENSION_CHANGE]); } void @@ -310,14 +403,129 @@ e_table_header_set_selection (ETableHeader *eth, gboolean allow_selection) void e_table_header_set_size (ETableHeader *eth, int idx, int size) { + double expansion; + double old_expansion; + int min_width; + int left_width; + int total_extra; + int expandable_count; + int usable_width; + int i; g_return_if_fail (eth != NULL); g_return_if_fail (E_IS_TABLE_HEADER (eth)); g_return_if_fail (idx >= 0); g_return_if_fail (idx < eth->col_count); - g_return_if_fail (size > 0); + + /* If this column is not resizable, don't do anything. */ + if (!eth->columns[idx]->resizeable) + return; + + expansion = 0; + min_width = 0; + left_width = 0; + expandable_count = -1; + + /* Calculate usable area. */ + for (i = 0; i < idx; i++) { + left_width += eth->columns[i]->width; + } + usable_width = eth->width - left_width; + + if (eth->sort_info) + usable_width -= e_table_sort_info_grouping_get_count(eth->sort_info) * GROUP_INDENT; + + /* Calculate minimum_width of stuff on the right as well as + * total usable expansion on the right. + */ + for (; i < eth->col_count; i++) { + min_width += eth->columns[i]->min_width; + if (eth->columns[i]->resizeable) { + printf ("Expansion[%d] = %f\n", i, eth->columns[i]->expansion); + expansion += eth->columns[i]->expansion; + expandable_count ++; + } + } + /* If there's no room for anything, don't change. */ + if (expansion == 0) + return; + + /* (1) If none of the columns to the right are expandable, use + * all the expansion space in this column. + */ + if(expandable_count == 0) { + eth->columns[idx]->expansion = expansion; + for (i = idx + 1; i < eth->col_count; i++) { + eth->columns[i]->expansion = 0; + } + goto end; + } + + total_extra = usable_width - min_width; + /* If there's no extra space, set all expansions to 0. */ + if (total_extra <= 0) { + for (i = idx; i < eth->col_count; i++) { + eth->columns[i]->expansion = 0; + } + goto end; + } + + /* If you try to resize smaller than the minimum width, it + * uses the minimum. */ + if (size < eth->columns[idx]->min_width) + size = eth->columns[idx]->min_width; + + printf ("size = %d, eth->columns[idx]->min_width = %d, total_extra = %d, expansion = %f\n", size, eth->columns[idx]->min_width, total_extra, expansion); + + /* If all the extra space will be used up in this column, use + * all the expansion and set all others to 0. + */ + if (size >= total_extra + eth->columns[idx]->min_width) { + eth->columns[idx]->expansion = expansion; + for (i = idx + 1; i < eth->col_count; i++) { + eth->columns[i]->expansion = 0; + } + goto end; + } + + /* The old_expansion used by columns to the right. */ + old_expansion = expansion; + old_expansion -= eth->columns[idx]->expansion; + /* Set the new expansion so that it will generate the desired size. */ + eth->columns[idx]->expansion = expansion * (((double)(size - eth->columns[idx]->min_width))/((double)total_extra)); + /* The expansion left for the columns on the right. */ + expansion -= eth->columns[idx]->expansion; + + printf ("eth->columns[idx]->expansion = %f\n", eth->columns[idx]->expansion); + + printf ("At (2) old_expansion = %f, expansion = %f\n", old_expansion, expansion); + + /* (2) If the old columns to the right didn't have any + * expansion before, expand them evenly. old_expansion > 0 by + * expansion = SUM(i=idx to col_count -1, + * columns[i]->min_width) - columns[idx]->min_width) = + * SUM(non-negatives). + */ + if (old_expansion == 0) { + for (i = idx + 1; i < eth->col_count; i++) { + if (eth->columns[idx]->resizeable) { + /* expandable_count != 0 by (1) */ + eth->columns[i]->expansion = expansion / expandable_count; + } + } + goto end; + } - eth->columns [idx]->width = size; - gtk_signal_emit (GTK_OBJECT (eth), eth_signals [DIMENSION_CHANGE], idx); + /* Remove from total_extra the amount used for this column. */ + total_extra -= size - eth->columns[idx]->min_width; + for (i = idx + 1; i < eth->col_count; i++) { + if (eth->columns[idx]->resizeable) { + /* old_expansion != 0 by (2) */ + eth->columns[i]->expansion *= expansion / old_expansion; + } + } + + end: + e_table_header_calc_widths(eth); } int @@ -344,133 +552,38 @@ e_table_header_col_diff (ETableHeader *eth, int start_col, int end_col) return total; } -/* Forget model-view here. Really, this information belongs in the view anyway. */ -#if 0 -static void -set_arrows (ETableHeader *eth, ETableHeaderSortInfo info) -{ - ETableCol *col; - for (col = eth->columns, i = 0; i < eth->col_count; i++, col++) { - if (col->col_idx == info.model_col) - e_table_column_set_arrow (col, info.ascending ? E_TABLE_COL_ARROW_DOWN : E_TABLE_COL_ARROW_UP); - } -} - -static void -unset_arrows (ETableHeader *eth, ETableHeaderSortInfo info) -{ - ETableCol *col; - for (col = eth->columns, i = 0; i < eth->col_count; i++, col++) { - if (col->col_idx == info.model_col) - e_table_column_set_arrow (col, E_TABLE_COL_ARROW_NONE); - } -} - -ETableHeaderSortInfo -e_table_header_get_sort_info (ETableHeader *eth) -{ - ETableHeaderSortInfo dummy_info = {0, 1}; - g_return_val_if_fail (eth != NULL, dummy_info); - g_return_val_if_fail (E_IS_TABLE_HEADER (eth), dummy_info); - - return eth->sort_info; -} - void -e_table_header_set_sort_info (ETableHeader *eth, ETableHeaderSortInfo info) +e_table_header_calc_widths (ETableHeader *eth) { - g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_HEADER (eth)); - - unset_arrows (eth, eth->sort_info); - eth->sort_info = info; - set_arrows (eth, eth->sort_info); - - gtk_signal_emit (GTK_OBJECT (eth), eth_signals [STRUCTURE_CHANGE]); -} - - -int -e_table_header_get_group_count (ETableHeader *eth) -{ - g_return_val_if_fail (eth != NULL, 0); - g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0); - - return eth->grouping_count; -} - -ETableHeaderSortInfo * -e_table_header_get_groups (ETableHeader *eth) -{ - ETableHeaderSortInfo *ret; - g_return_val_if_fail (eth != NULL, NULL); - g_return_val_if_fail (E_IS_TABLE_HEADER (eth), NULL); - - ret = g_new (ETableHeaderSortInfo, eth->grouping_count); - memcpy (ret, eth->grouping, sizeof (ETableHeaderSortInfo) * eth->grouping_count); - return eth->grouping; -} - -ETableHeaderSortInfo -e_table_header_get_group (ETableHeader *eth, gint index) -{ - ETableHeaderSortInfo dummy_info = {0, 1}; - g_return_val_if_fail (eth != NULL, dummy_info); - g_return_val_if_fail (E_IS_TABLE_HEADER (eth), dummy_info); - g_return_val_if_fail (index >= 0, dummy_info); - g_return_val_if_fail (index < eth->grouping_count, dummy_info); - - return eth->grouping[index]; -} - -void -e_table_header_grouping_insert (ETableHeader *eth, gint index, ETableHeaderSortInfo info) -{ - g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_HEADER (eth)); - - eth->grouping = g_realloc (eth->grouping, sizeof(ETableHeaderSortInfo) * (eth->grouping_count + 1)); - memmove (eth->grouping + index + 1, eth->grouping + index, sizeof(ETableHeaderSortInfo) * (eth->grouping_count - index)); - eth->grouping[index] = info; - - eth->grouping_count ++; - - gtk_signal_emit (GTK_OBJECT (eth), eth_signals [STRUCTURE_CHANGE]); -} - -void -e_table_header_grouping_delete (ETableHeader *eth, gint index) -{ - g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_HEADER (eth)); - - memmove (eth->grouping + index, eth->grouping + index + 1, sizeof(ETableHeaderSortInfo) * (eth->grouping_count - index)); - eth->grouping = g_realloc (eth->grouping, sizeof(ETableHeaderSortInfo) * (eth->grouping_count - 1)); - - eth->grouping_count --; - - gtk_signal_emit (GTK_OBJECT (eth), eth_signals [STRUCTURE_CHANGE]); -} - -void -e_table_header_grouping_move (ETableHeader *eth, gint old_idx, gint new_idx) -{ - ETableHeaderSortInfo info; - - g_return_if_fail (eth != NULL); - g_return_if_fail (E_IS_TABLE_HEADER (eth)); - - if (old_idx == new_idx) + int i; + int extra, extra_left; + double expansion; + int last_resizeable = -1; + extra = eth->width; + expansion = 0; + for (i = 0; i < eth->col_count; i++) { + extra -= eth->columns[i]->min_width; + if (eth->columns[i]->resizeable) { + expansion += eth->columns[i]->expansion; + last_resizeable = i; + } + eth->columns[i]->width = eth->columns[i]->min_width; + } + if (eth->sort_info) + extra -= e_table_sort_info_grouping_get_count(eth->sort_info) * GROUP_INDENT; + if (expansion == 0 || extra < 0) return; - - info = eth->grouping[old_idx]; - if (old_idx < new_idx){ - memmove (eth->grouping + old_idx, eth->grouping + old_idx + 1, sizeof(ETableHeaderSortInfo) * (new_idx - old_idx)); - } else { - memmove (eth->grouping + new_idx + 1, eth->grouping + new_idx, sizeof(ETableHeaderSortInfo) * (old_idx - new_idx)); + extra_left = extra; + for (i = 0; i < last_resizeable; i++) { + if (eth->columns[i]->resizeable) { + int this_extra = MIN(extra_left, extra * (eth->columns[i]->expansion / expansion)); + eth->columns[i]->width += this_extra; + extra_left -= this_extra; + } } - eth->grouping[new_idx] = info; + if (i >= 0 && i < eth->col_count && eth->columns[i]->resizeable) + eth->columns[i]->width += extra_left; - gtk_signal_emit (GTK_OBJECT (eth), eth_signals [STRUCTURE_CHANGE]); + eth_update_offsets (eth); + gtk_signal_emit (GTK_OBJECT (eth), eth_signals [DIMENSION_CHANGE]); } -#endif diff --git a/widgets/e-table/e-table-header.h b/widgets/e-table/e-table-header.h index 244de59982..6ff4874f6f 100644 --- a/widgets/e-table/e-table-header.h +++ b/widgets/e-table/e-table-header.h @@ -4,6 +4,7 @@ #include #include +#include "e-table-sort-info.h" #include "e-table-col.h" typedef struct _ETableHeader ETableHeader; @@ -14,13 +15,6 @@ typedef struct _ETableHeader ETableHeader; #define E_IS_TABLE_HEADER(o) (GTK_CHECK_TYPE ((o), E_TABLE_HEADER_TYPE)) #define E_IS_TABLE_HEADER_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_HEADER_TYPE)) -#if 0 -typedef struct { - int model_col; - int ascending; -} ETableHeaderSortInfo; -#endif - /* * A Columnar header. */ @@ -28,14 +22,13 @@ struct _ETableHeader { GtkObject base; int col_count; + int width; + + ETableSortInfo *sort_info; + int sort_info_group_change_id; + ETableCol **columns; gboolean selectable; - -#if 0 - ETableHeaderSortInfo sort_info; - ETableHeaderSortInfo *grouping; - gint grouping_count; -#endif }; typedef struct { @@ -59,18 +52,6 @@ int e_table_header_get_index_at (ETableHeader *eth, int x_offset); ETableCol **e_table_header_get_columns (ETableHeader *eth); -#if 0 -ETableHeaderSortInfo e_table_header_get_sort_info (ETableHeader *eth); -void e_table_header_set_sort_info (ETableHeader *eth, ETableHeaderSortInfo info); - -int e_table_header_get_group_count (ETableHeader *eth); -ETableHeaderSortInfo *e_table_header_get_groups (ETableHeader *eth); -ETableHeaderSortInfo e_table_header_get_group (ETableHeader *eth, gint index); -void e_table_header_grouping_insert (ETableHeader *eth, gint index, ETableHeaderSortInfo info); -void e_table_header_grouping_delete (ETableHeader *eth, gint index); -void e_table_header_grouping_move (ETableHeader *eth, gint old_idx, gint new_idx); -#endif - gboolean e_table_header_selection_ok (ETableHeader *eth); int e_table_header_get_selected (ETableHeader *eth); int e_table_header_total_width (ETableHeader *eth); @@ -78,6 +59,7 @@ void e_table_header_move (ETableHeader *eth, int source_index, int target_index); void e_table_header_remove (ETableHeader *eth, int idx); +void e_table_header_set_width (ETableHeader *eth, int width); void e_table_header_set_size (ETableHeader *eth, int idx, int size); void e_table_header_set_selection (ETableHeader *eth, gboolean allow_selection); @@ -85,6 +67,8 @@ void e_table_header_set_selection (ETableHeader *eth, int e_table_header_col_diff (ETableHeader *eth, int start_col, int end_col); +void e_table_header_calc_widths (ETableHeader *eth); + GList *e_table_header_get_selected_indexes (ETableHeader *eth); diff --git a/widgets/e-table/e-table-item.c b/widgets/e-table/e-table-item.c index 13699e1d91..560cb4affe 100644 --- a/widgets/e-table/e-table-item.c +++ b/widgets/e-table/e-table-item.c @@ -42,12 +42,14 @@ enum { ARG_MODE_SPREADSHEET, ARG_LENGTH_THRESHOLD, + ARG_MINIMUM_WIDTH, ARG_WIDTH, ARG_HEIGHT, ARG_HAS_FOCUS, }; static int eti_get_height (ETableItem *eti); +static int eti_get_minimum_width (ETableItem *eti); static int eti_row_height (ETableItem *eti, int row); #define ETI_ROW_HEIGHT(eti,row) ((eti)->height_cache && (eti)->height_cache[(row)] != -1 ? (eti)->height_cache[(row)] : eti_row_height((eti),(row))) @@ -141,18 +143,10 @@ eti_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y { double i2c [6]; ArtPoint c1, c2, i1, i2; - int col, width = 0; ETableItem *eti = E_TABLE_ITEM (item); /* Wrong BBox's are the source of redraw nightmares */ - for (col = 0; col < eti->cols; col++, x1 = x2){ - ETableCol *ecol = e_table_header_get_column (eti->header, col); - - width += ecol->width; - } - eti->width = width; - gnome_canvas_item_i2c_affine (GNOME_CANVAS_ITEM (eti), i2c); i1.x = eti->x1; @@ -184,6 +178,17 @@ eti_reflow (GnomeCanvasItem *item, gint flags) } eti->needs_compute_height = 0; } + if (eti->needs_compute_width) { + int new_width = eti_get_minimum_width (eti); + new_width = MAX(new_width, eti->minimum_width); + if (new_width != eti->width) { + eti->width = new_width; + e_canvas_item_request_parent_reflow (GNOME_CANVAS_ITEM (eti)); + eti->needs_redraw = 1; + gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti)); + } + eti->needs_compute_width = 0; + } } /* @@ -363,7 +368,6 @@ calculate_height_cache (ETableItem *eti) static int eti_row_height (ETableItem *eti, int row) { -#if 1 if (!eti->height_cache) { calculate_height_cache (eti); } @@ -378,9 +382,6 @@ eti_row_height (ETableItem *eti, int row) } } return eti->height_cache[row]; -#else - return eti_row_height_real(eti, row); -#endif } /* @@ -435,6 +436,19 @@ eti_get_height (ETableItem *eti) return height; } +static int +eti_get_minimum_width (ETableItem *eti) +{ + int width = 0; + int col; + for (col = 0; col < eti->cols; col++){ + ETableCol *ecol = e_table_header_get_column (eti->header, col); + + width += ecol->min_width; + } + return width; +} + static void eti_item_region_redraw (ETableItem *eti, int x0, int y0, int x1, int y1) { @@ -472,20 +486,6 @@ eti_table_model_changed (ETableModel *table_model, ETableItem *eti) gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti)); } -/* Unused. */ -#if 0 -/* - * eti_request_redraw: - * - * Queues a canvas redraw for the entire ETableItem. - */ -static void -eti_request_redraw (ETableItem *eti) -{ - eti_item_region_redraw (eti, eti->x1, eti->y1, eti->x1 + eti->width + 1, eti->y1 + eti->height + 1); -} -#endif - /* * Computes the distance between @start_row and @end_row in pixels */ @@ -624,8 +624,8 @@ eti_add_table_model (ETableItem *eti, ETableModel *table_model) static void eti_header_dim_changed (ETableHeader *eth, int col, ETableItem *eti) { - eti->needs_redraw = 1; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti)); + eti->needs_compute_width = 1; + e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti)); } static void @@ -650,8 +650,8 @@ eti_header_structure_changed (ETableHeader *eth, ETableItem *eti) eti_attach_cell_views (eti); } } - eti->needs_redraw = 1; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti)); + eti->needs_compute_width = 1; + e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti)); } static void @@ -728,7 +728,13 @@ eti_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) case ARG_MODE_SPREADSHEET: eti->mode_spreadsheet = GTK_VALUE_BOOL (*arg); break; - + case ARG_MINIMUM_WIDTH: + if (eti->minimum_width == eti->width && GTK_VALUE_DOUBLE (*arg) > eti->width) + e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti)); + eti->minimum_width = GTK_VALUE_DOUBLE (*arg); + if (eti->minimum_width < eti->width) + e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti)); + break; } eti->needs_redraw = 1; gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(eti)); @@ -750,6 +756,9 @@ eti_get_arg (GtkObject *o, GtkArg *arg, guint arg_id) case ARG_HEIGHT: GTK_VALUE_DOUBLE (*arg) = eti->height; break; + case ARG_MINIMUM_WIDTH: + GTK_VALUE_DOUBLE (*arg) = eti->minimum_width; + break; default: arg->type = GTK_TYPE_INVALID; } @@ -765,6 +774,8 @@ eti_init (GnomeCanvasItem *item) eti->editing_col = -1; eti->editing_row = -1; eti->height = 0; + eti->width = 0; + eti->minimum_width = 0; eti->height_cache = NULL; eti->height_cache_idle_id = 0; @@ -1042,7 +1053,7 @@ find_cell (ETableItem *eti, double x, double y, int *col_res, int *row_res, doub y -= eti->y1; x1 = 0; - for (col = 0; col < cols; col++, x1 = x2){ + for (col = 0; col < cols - 1; col++, x1 = x2){ ETableCol *ecol = e_table_header_get_column (eti->header, col); if (x < x1) @@ -1050,31 +1061,26 @@ find_cell (ETableItem *eti, double x, double y, int *col_res, int *row_res, doub x2 = x1 + ecol->width; - if (x > x2) - continue; - - *col_res = col; - if (x1_res) - *x1_res = x - x1; - break; + if (x <= x2) + break; } y1 = y2 = 0; - for (row = 0; row < rows; row++, y1 = y2){ + for (row = 0; row < rows - 1; row++, y1 = y2){ if (y < y1) return FALSE; y2 += ETI_ROW_HEIGHT (eti, row) + 1; - if (y > y2) - continue; - - *row_res = row; - if (y1_res) - *y1_res = y - y1; - break; + if (y <= y2) + break; } - + *col_res = col; + if (x1_res) + *x1_res = x - x1; + *row_res = row; + if (y1_res) + *y1_res = y - y1; return TRUE; } @@ -1324,6 +1330,8 @@ eti_class_init (GtkObjectClass *object_class) gtk_object_add_arg_type ("ETableItem::length_threshold", GTK_TYPE_INT, GTK_ARG_WRITABLE, ARG_LENGTH_THRESHOLD); + gtk_object_add_arg_type ("ETableItem::minimum_width", GTK_TYPE_DOUBLE, + GTK_ARG_READWRITE, ARG_MINIMUM_WIDTH); gtk_object_add_arg_type ("ETableItem::width", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_WIDTH); gtk_object_add_arg_type ("ETableItem::height", GTK_TYPE_DOUBLE, diff --git a/widgets/e-table/e-table-item.h b/widgets/e-table/e-table-item.h index daa436db88..9cdb04c2ff 100644 --- a/widgets/e-table/e-table-item.h +++ b/widgets/e-table/e-table-item.h @@ -18,7 +18,7 @@ typedef struct { ETableHeader *header; int x1, y1; - int width, height; + int minimum_width, width, height; int cols, rows; @@ -73,6 +73,7 @@ typedef struct { guint needs_redraw : 1; guint needs_compute_height : 1; + guint needs_compute_width : 1; } ETableItem; typedef struct { diff --git a/widgets/e-table/e-table-size-test.c b/widgets/e-table/e-table-size-test.c index 0271b03697..d12a57fbbb 100644 --- a/widgets/e-table/e-table-size-test.c +++ b/widgets/e-table/e-table-size-test.c @@ -210,7 +210,7 @@ create_table (void) /* Create the column. */ ETableCol *ecol = e_table_col_new ( i, headers [i], - 80, 20, cell_left_just, + 1.0, 20, cell_left_just, g_str_compare, TRUE); /* Add it to the header. */ e_table_header_add_column (e_table_header, ecol, i); diff --git a/widgets/e-table/e-table.c b/widgets/e-table/e-table.c index 51b03f4f65..e306abf35f 100644 --- a/widgets/e-table/e-table.c +++ b/widgets/e-table/e-table.c @@ -134,8 +134,6 @@ e_table_setup_header (ETable *e_table) gnome_canvas_root (e_table->header_canvas), e_table_header_item_get_type (), "ETableHeader", e_table->header, - "x", 0, - "y", 0, "sort_info", e_table->sort_info, NULL); @@ -150,27 +148,31 @@ static void table_canvas_size_allocate (GtkWidget *widget, GtkAllocation *alloc, ETable *e_table) { - gdouble height; gdouble width; - - gtk_object_get (GTK_OBJECT (e_table->group), - "height", &height, - NULL); - gnome_canvas_set_scroll_region ( - GNOME_CANVAS (e_table->table_canvas), - 0, 0, alloc->width, MAX (height, alloc->height)); width = alloc->width; + gtk_object_set (GTK_OBJECT (e_table->group), + "minimum_width", width, + NULL); + gtk_object_set (GTK_OBJECT (e_table->header), "width", width, NULL); + } static void table_canvas_reflow (GnomeCanvas *canvas, ETable *e_table) { - table_canvas_size_allocate (GTK_WIDGET (canvas), - &(GTK_WIDGET (canvas)->allocation), - e_table); + gdouble height, width; + GtkAllocation *alloc = &(GTK_WIDGET (canvas)->allocation); + + gtk_object_get (GTK_OBJECT (e_table->group), + "height", &height, + "width", &width, + NULL); + gnome_canvas_set_scroll_region ( + GNOME_CANVAS (e_table->table_canvas), + 0, 0, MAX(width, alloc->width), MAX (height, alloc->height)); } static void @@ -199,7 +201,7 @@ changed_idle (gpointer data) e_table_fill_table (et, et->model); gtk_object_set (GTK_OBJECT (et->group), - "width", (double) GTK_WIDGET (et->table_canvas)->allocation.width, + "minimum_width", (double) GTK_WIDGET (et->table_canvas)->allocation.width, NULL); } @@ -295,16 +297,6 @@ static void e_table_fill_table (ETable *e_table, ETableModel *model) { e_table_group_add_all (e_table->group); -#if 0 - count = e_table_model_row_count (model); - gtk_object_set (GTK_OBJECT (e_table->group), - "frozen", TRUE, NULL); - for (i = 0; i < count; i++) - e_table_group_add (e_table->group, i); - - gtk_object_set (GTK_OBJECT (e_table->group), - "frozen", FALSE, NULL); -#endif } static ETableHeader * @@ -372,6 +364,8 @@ et_real_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm, xmlNode *xmlRoot; xmlNode *xmlColumns; xmlNode *xmlGrouping; + int no_header; + int row = 0; GtkWidget *scrolledwindow; @@ -381,6 +375,8 @@ et_real_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm, if ((xmlColumns == NULL) || (xmlGrouping == NULL)) return NULL; + + no_header = e_xml_get_integer_prop_by_name(xmlRoot, "no-header"); e_table->full_header = full_header; gtk_object_ref (GTK_OBJECT (full_header)); @@ -393,8 +389,14 @@ et_real_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm, e_table->header = et_xml_to_header (e_table, full_header, xmlColumns); et_grouping_xml_to_sort_info (e_table, xmlGrouping); + + gtk_object_set(GTK_OBJECT(e_table->header), + "sort_info", e_table->sort_info, + NULL); - e_table_setup_header (e_table); + if (!no_header) { + e_table_setup_header (e_table); + } e_table_setup_table (e_table, full_header, e_table->header, etm); e_table_fill_table (e_table, etm); @@ -412,21 +414,23 @@ et_real_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm, GTK_WIDGET (e_table->table_canvas)); gtk_widget_show (scrolledwindow); - /* - * The header - */ - gtk_table_attach ( - GTK_TABLE (e_table), GTK_WIDGET (e_table->header_canvas), - 1, 2, 1, 2, - GTK_FILL | GTK_EXPAND, - GTK_FILL, 0, 0); - + if (!no_header) { + /* + * The header + */ + gtk_table_attach ( + GTK_TABLE (e_table), GTK_WIDGET (e_table->header_canvas), + 0, 1, 0, 1, + GTK_FILL | GTK_EXPAND, + GTK_FILL, 0, 0); + row ++; + } /* * The body */ gtk_table_attach ( GTK_TABLE (e_table), GTK_WIDGET (scrolledwindow), - 1, 2, 2, 3, + 0, 1, 0 + row, 1 + row, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0); diff --git a/widgets/e-table/test-check.c b/widgets/e-table/test-check.c index c05111d1b4..3a32098245 100644 --- a/widgets/e-table/test-check.c +++ b/widgets/e-table/test-check.c @@ -139,11 +139,11 @@ check_test (void) cell_image_check = e_cell_checkbox_new (); pixbuf = gdk_pixbuf_new_from_file ("clip.png"); - col_0 = e_table_col_new_with_pixbuf (0, pixbuf, 18, 18, cell_image_check, g_int_compare, TRUE); + col_0 = e_table_col_new_with_pixbuf (0, pixbuf, 0.0, 18, cell_image_check, g_int_compare, TRUE); gdk_pixbuf_unref (pixbuf); e_table_header_add_column (e_table_header, col_0, 0); - col_1 = e_table_col_new (1, "Item Name", 180, 20, cell_left_just, g_str_compare, TRUE); + col_1 = e_table_col_new (1, "Item Name", 1.0, 20, cell_left_just, g_str_compare, TRUE); e_table_header_add_column (e_table_header, col_1, 1); e_table_col_set_arrow (col_1, E_TABLE_COL_ARROW_DOWN); diff --git a/widgets/e-table/test-cols.c b/widgets/e-table/test-cols.c index f60d22d915..6756511fb4 100644 --- a/widgets/e-table/test-cols.c +++ b/widgets/e-table/test-cols.c @@ -153,10 +153,10 @@ multi_cols_test (void) g_free (images); } - col_1 = e_table_col_new (1, "Item Name", 180, 20, cell_left_just, g_str_compare, TRUE); + col_1 = e_table_col_new (1, "Item Name", 1.0, 20, cell_left_just, g_str_compare, TRUE); e_table_header_add_column (e_table_header, col_1, 0); - col_0 = e_table_col_new (0, "A", 48, 48, cell_image_toggle, g_int_compare, TRUE); + col_0 = e_table_col_new (0, "A", 0.0, 48, cell_image_toggle, g_int_compare, TRUE); e_table_header_add_column (e_table_header, col_0, 1); /* diff --git a/widgets/e-table/test-table.c b/widgets/e-table/test-table.c index 38f690ec43..a882b8dbdf 100644 --- a/widgets/e-table/test-table.c +++ b/widgets/e-table/test-table.c @@ -231,7 +231,7 @@ table_browser_test (void) for (i = 0; i < cols; i++){ ETableCol *ecol = e_table_col_new ( i, column_labels [i], - 80, 20, cell_left_just, + 1.0, 20, cell_left_just, g_str_compare, TRUE); e_table_header_add_column (e_table_header, ecol, i); @@ -324,7 +324,7 @@ do_e_table_demo (const char *spec) for (i = 0; i < cols; i++){ ETableCol *ecol = e_table_col_new ( i, column_labels [i], - 80, 20, cell_left_just, + 1.0, 20, cell_left_just, g_str_compare, TRUE); e_table_header_add_column (full_header, ecol, i); -- cgit