diff options
Diffstat (limited to 'widgets/table')
-rw-r--r-- | widgets/table/e-table-header.c | 122 | ||||
-rw-r--r-- | widgets/table/e-table-header.h | 5 | ||||
-rw-r--r-- | widgets/table/e-table-sorted-variable.c | 2 |
3 files changed, 102 insertions, 27 deletions
diff --git a/widgets/table/e-table-header.c b/widgets/table/e-table-header.c index 61e1f9a9da..b438226153 100644 --- a/widgets/table/e-table-header.c +++ b/widgets/table/e-table-header.c @@ -30,11 +30,75 @@ enum { 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 void eth_set_width(ETableHeader *eth, int width); +static void eth_set_size (ETableHeader *eth, int idx, int size); +static void eth_calc_widths (ETableHeader *eth); +static void dequeue(ETableHeader *eth, int *column, int *width); static guint eth_signals [LAST_SIGNAL] = { 0, }; static GtkObjectClass *e_table_header_parent_class; +struct two_ints { + int column; + int width; +}; + +static gboolean +dequeue_idle(ETableHeader *eth) +{ + int column, width; + dequeue(eth, &column, &width); + while(eth->change_queue && ((struct two_ints *)eth->change_queue->data)->column == column) + dequeue(eth, &column, &width); + if (column == -1) + eth_set_width(eth, width); + else if (column < eth->col_count) + eth_set_size(eth, column, width); + if (eth->change_queue) + return TRUE; + else { + eth_calc_widths(eth); + eth->idle = 0; + return FALSE; + } +} + +static void +enqueue(ETableHeader *eth, int column, int width) +{ + struct two_ints *store; + store = g_new(struct two_ints, 1); + store->column = column; + store->width = width; + + eth->change_tail = g_slist_last(g_slist_append(eth->change_tail, store)); + if (!eth->change_queue) + eth->change_queue = eth->change_tail; + + if (!eth->idle) { + eth->idle = g_idle_add_full(G_PRIORITY_LOW, (GSourceFunc) dequeue_idle, eth, NULL); + } +} + +static void +dequeue(ETableHeader *eth, int *column, int *width) +{ + GSList *head; + struct two_ints *store; + head = eth->change_queue; + eth->change_queue = eth->change_queue->next; + if (!eth->change_queue) + eth->change_tail = NULL; + store = head->data; + g_slist_free_1(head); + if (column) + *column = store->column; + if (width) + *width = store->width; + g_free(store); +} + static void eth_destroy (GtkObject *object) { @@ -48,6 +112,9 @@ eth_destroy (GtkObject *object) eth->sort_info_group_change_id); gtk_object_unref(GTK_OBJECT(eth->sort_info)); } + + g_slist_foreach(eth->change_queue, (GFunc) g_free, NULL); + g_slist_free(eth->change_queue); /* * Destroy columns @@ -104,6 +171,9 @@ e_table_header_init (ETableHeader *eth) eth->columns = NULL; eth->selectable = FALSE; + + eth->change_queue = NULL; + eth->change_tail = NULL; } GtkType @@ -142,7 +212,13 @@ e_table_header_new (void) static void eth_group_info_changed(ETableSortInfo *info, ETableHeader *eth) { - e_table_header_calc_widths(eth); + enqueue(eth, -1, eth->nominal_width); +} + +static void +eth_set_width(ETableHeader *eth, int width) +{ + eth->width = width; } static void @@ -152,8 +228,8 @@ eth_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) switch (arg_id) { case ARG_WIDTH: - eth->width = GTK_VALUE_DOUBLE (*arg); - e_table_header_calc_widths(eth); + eth->nominal_width = GTK_VALUE_DOUBLE (*arg); + enqueue(eth, -1, GTK_VALUE_DOUBLE (*arg)); break; case ARG_SORT_INFO: if (eth->sort_info) { @@ -168,7 +244,7 @@ eth_set_arg (GtkObject *object, GtkArg *arg, guint arg_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); + enqueue(eth, -1, eth->nominal_width); break; default: break; @@ -185,7 +261,7 @@ eth_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(eth->sort_info); break; case ARG_WIDTH: - GTK_VALUE_DOUBLE (*arg) = eth->width; + GTK_VALUE_DOUBLE (*arg) = eth->nominal_width; break; default: arg->type = GTK_TYPE_INVALID; @@ -237,7 +313,7 @@ e_table_header_add_column (ETableHeader *eth, ETableCol *tc, int pos) eth_do_insert (eth, pos, tc); - e_table_header_calc_widths(eth); + enqueue(eth, -1, eth->nominal_width); gtk_signal_emit (GTK_OBJECT (eth), eth_signals [STRUCTURE_CHANGE]); } @@ -391,7 +467,7 @@ 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); + enqueue(eth, -1, eth->nominal_width); gtk_signal_emit (GTK_OBJECT (eth), eth_signals [STRUCTURE_CHANGE]); } @@ -401,7 +477,13 @@ e_table_header_set_selection (ETableHeader *eth, gboolean allow_selection) } void -e_table_header_set_size (ETableHeader *eth, int idx, int size) +e_table_header_set_size(ETableHeader *eth, int idx, int size) +{ + enqueue(eth, idx, size); +} + +static void +eth_set_size (ETableHeader *eth, int idx, int size) { double expansion; double old_expansion; @@ -440,7 +522,6 @@ e_table_header_set_size (ETableHeader *eth, int idx, int size) 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 ++; } @@ -457,7 +538,7 @@ e_table_header_set_size (ETableHeader *eth, int idx, int size) for (i = idx + 1; i < eth->col_count; i++) { eth->columns[i]->expansion = 0; } - goto end; + return; } total_extra = usable_width - min_width; @@ -466,7 +547,7 @@ e_table_header_set_size (ETableHeader *eth, int idx, int size) for (i = idx; i < eth->col_count; i++) { eth->columns[i]->expansion = 0; } - goto end; + return; } /* If you try to resize smaller than the minimum width, it @@ -474,8 +555,6 @@ e_table_header_set_size (ETableHeader *eth, int idx, int size) 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. */ @@ -484,7 +563,7 @@ e_table_header_set_size (ETableHeader *eth, int idx, int size) for (i = idx + 1; i < eth->col_count; i++) { eth->columns[i]->expansion = 0; } - goto end; + return; } /* The old_expansion used by columns to the right. */ @@ -495,10 +574,6 @@ e_table_header_set_size (ETableHeader *eth, int idx, int size) /* 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, @@ -512,7 +587,7 @@ e_table_header_set_size (ETableHeader *eth, int idx, int size) eth->columns[i]->expansion = expansion / expandable_count; } } - goto end; + return; } /* Remove from total_extra the amount used for this column. */ @@ -523,9 +598,6 @@ e_table_header_set_size (ETableHeader *eth, int idx, int size) eth->columns[i]->expansion *= expansion / old_expansion; } } - - end: - e_table_header_calc_widths(eth); } int @@ -552,8 +624,8 @@ e_table_header_col_diff (ETableHeader *eth, int start_col, int end_col) return total; } -void -e_table_header_calc_widths (ETableHeader *eth) +static void +eth_calc_widths (ETableHeader *eth) { int i; int extra, extra_left; @@ -563,7 +635,7 @@ e_table_header_calc_widths (ETableHeader *eth) expansion = 0; for (i = 0; i < eth->col_count; i++) { extra -= eth->columns[i]->min_width; - if (eth->columns[i]->resizeable) { + if (eth->columns[i]->resizeable && eth->columns[i]->expansion != 0.0) { expansion += eth->columns[i]->expansion; last_resizeable = i; } diff --git a/widgets/table/e-table-header.h b/widgets/table/e-table-header.h index 6ff4874f6f..0dcce14b1e 100644 --- a/widgets/table/e-table-header.h +++ b/widgets/table/e-table-header.h @@ -23,12 +23,16 @@ struct _ETableHeader { int col_count; int width; + int nominal_width; ETableSortInfo *sort_info; int sort_info_group_change_id; ETableCol **columns; gboolean selectable; + + GSList *change_queue, *change_tail; + gint idle; }; typedef struct { @@ -59,7 +63,6 @@ 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); diff --git a/widgets/table/e-table-sorted-variable.c b/widgets/table/e-table-sorted-variable.c index 5d11e03d6f..6ab832de94 100644 --- a/widgets/table/e-table-sorted-variable.c +++ b/widgets/table/e-table-sorted-variable.c @@ -215,7 +215,7 @@ int cols_closure; int *ascending_closure; GCompareFunc *compare_closure; -/* FIXME: Make it not cache the second and later rows (as if anyone cares.) */ +/* FIXME: Make it not cache the second and later columns (as if anyone cares.) */ static int qsort_callback(const void *data1, const void *data2) |