diff options
25 files changed, 517 insertions, 54 deletions
diff --git a/widgets/e-table/ChangeLog b/widgets/e-table/ChangeLog index 5c8edfe072..3057b58656 100644 --- a/widgets/e-table/ChangeLog +++ b/widgets/e-table/ChangeLog @@ -1,3 +1,43 @@ +2000-09-11 Iain Holmes <iain@helixcode.com> + + * e-table-header-item.c (ethi_maybe_start_drag): Set maybe_drag + to FALSE. Seems to fix a crash for me. + (ethi_event): Handle the double click on the dividers. + + * e-table-header.c (e_table_header_class_init): Add a + "request_width" signal. + + * e-table-item.c (eti_add_header_model): Connect to the + "request_width" signal. + (eti_request_column_width): Call the e_cell_max_width on the + appropriate column. + + * e-cell.c (e_cell_max_width): Call the max_width method. + + * e-cell-text.c (ect_max_width): Calculate the max width. + + * e-cell-toggle.c (etog_max_width): Calculate the max width. + + * e-cell-tree.c (ect_max_width): Same. + +2000-09-11 Iain Holmes <iain@helixcode.com> + + * e-table-header-item.c (ethi_drag_motion): Check if the + type of the dragged item is a etable header item. + +2000-09-11 Iain Holmes <iain@helixcode.com> + + * e-table-header-item.c (set_cursor): Check if the column + is resizeable before setting the cursor to E_CURSOR_SIZE_X + +2000-09-11 Iain Holmes <iain@helixcode.com> + + * e-table-header-item.c: Use the font and button drawing + from the theme. + + * e-table.c: Use the height of the font to set the size for + the header_canvas, instead of hard coding it to 16 + 2000-09-11 Ettore Perazzoli <ettore@helixcode.com> * Makefile.am (tree_example_2_LDADD): Add `$(GNOME_VFS_LIBS)' and @@ -17,6 +57,7 @@ * e-tree-simple.c: Fixed the ETableModel callbacks. +>>>>>>> 1.273 2000-09-08 Christopher James Lahey <clahey@helixcode.com> * e-tree-example-1.c: Added base ETableModel functions. diff --git a/widgets/e-table/e-cell-text.c b/widgets/e-table/e-cell-text.c index e78de94660..13008af8ad 100644 --- a/widgets/e-table/e-cell-text.c +++ b/widgets/e-table/e-cell-text.c @@ -460,6 +460,8 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable, gboolean selected; EFontStyle style; + EFontStyle style = E_FONT_PLAIN; + selected = flags & E_CELL_SELECTED; if (edit){ @@ -1267,6 +1269,32 @@ ect_print_height (ECellView *ecell_view, GnomePrintContext *context, return 16; } +static int +ect_max_width (ECellView *ecell_view, + int model_col, + int view_col) +{ + /* New ECellText */ + ECellTextView *text_view = (ECellTextView *) ecell_view; + EFont *font; + int row; + int number_of_rows; + int max_width = 0; + + font = text_view->font; + number_of_rows = e_table_model_row_count (ecell_view->e_table_model); + + for (row = 0; row < number_of_rows; row++) { + CurrentCell cell; + build_current_cell (&cell, text_view, model_col, view_col, row); + split_into_lines (&cell); + calc_line_widths (&cell); + max_width = MAX (max_width, cell.breaks->max_width); + } + + return max_width; +} + /* * GtkObject::destroy method */ @@ -1357,6 +1385,7 @@ e_cell_text_class_init (GtkObjectClass *object_class) ecc->leave_edit = ect_leave_edit; ecc->print = ect_print; ecc->print_height = ect_print_height; + ecc->max_width = ect_max_width; object_class->get_arg = ect_get_arg; object_class->set_arg = ect_set_arg; diff --git a/widgets/e-table/e-cell-toggle.c b/widgets/e-table/e-cell-toggle.c index f0a05b488a..e18f4b33e7 100644 --- a/widgets/e-table/e-cell-toggle.c +++ b/widgets/e-table/e-cell-toggle.c @@ -223,6 +223,28 @@ etog_height (ECellView *ecell_view, int model_col, int view_col, int row) return toggle->height; } +/* + * ECell::max_width method + */ +static int +etog_max_width (ECellView *ecell_view, int model_col, int view_col) +{ + ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell); + void *_value = e_table_model_value_at (ecell_view->e_table_model, model_col, 0); + int max_width = gdk_pixbuf_get_width (toggle->images[GPOINTER_TO_INT (_value)]); + int number_of_rows; + int row; + + number_of_rows = e_table_model_row_count (ecell_view->e_table_model); + for (row = 1; row < number_of_rows; row++) { + void *_value = e_table_model_value_at (ecell_view->e_table_model, + model_col, row); + max_width = MAX (max_width, gdk_pixbuf_get_width (toggle->images[GPOINTER_TO_INT (_value)])); + } + + return max_width; +} + static void etog_destroy (GtkObject *object) { @@ -251,6 +273,7 @@ e_cell_toggle_class_init (GtkObjectClass *object_class) ecc->draw = etog_draw; ecc->event = etog_event; ecc->height = etog_height; + ecc->max_width = etog_max_width; parent_class = gtk_type_class (PARENT_TYPE); } diff --git a/widgets/e-table/e-cell-tree.c b/widgets/e-table/e-cell-tree.c index 3cc06a73ee..48ae9f4af1 100644 --- a/widgets/e-table/e-cell-tree.c +++ b/widgets/e-table/e-cell-tree.c @@ -353,6 +353,67 @@ ect_height (ECellView *ecell_view, int model_col, int view_col, int row) } /* + * ECell::max_width method + */ +static int +ect_max_width (ECellView *ecell_view, int model_col, int view_col) +{ + ECellTreeView *tree_view = (ECellTreeView *) ecell_view; + int row; + int number_of_rows; + int max_width = 0; + int width = 0; + + number_of_rows = e_table_model_row_count (ecell_view->e_table_model); + + for (row = 0; row < number_of_rows; row++) { + ETreeModel *tree_model = e_cell_tree_get_tree_model(ecell_view->e_table_model, row); + ETreePath *node; + GdkPixbuf *node_image; + int node_image_width = 0, node_image_height = 0; + ETreePath *parent_node; + + int offset, subcell_offset; + gboolean expanded, expandable; + + node = e_cell_tree_get_node (tree_model, row); + + offset = offset_of_node (tree_model, node); + expandable = e_tree_model_node_is_expandable (tree_model, node); + expanded = e_tree_model_node_is_expanded (tree_model, node); + subcell_offset = offset; + + node_image = e_tree_model_icon_of_node (tree_model, node); + + if (node_image) { + node_image_width = gdk_pixbuf_get_width (node_image); + node_image_height = gdk_pixbuf_get_height (node_image); + } + + width = subcell_offset + node_image_width; + + if (expandable) { + GdkPixbuf *image; + + image = (expanded + ? E_CELL_TREE(tree_view->cell_view.ecell)->open_pixbuf + : E_CELL_TREE(tree_view->cell_view.ecell)->closed_pixbuf); + + width += gdk_pixbuf_get_width(image); + } + + width += e_cell_max_width (tree_view->subcell_view, model_col, + view_col); + + max_width = MAX (max_width, width); + } + + return max_width; +} + + + +/* * ECellView::enter_edit method */ static void * @@ -510,6 +571,7 @@ e_cell_tree_class_init (GtkObjectClass *object_class) ecc->leave_edit = ect_leave_edit; ecc->print = ect_print; ecc->print_height = ect_print_height; + ecc->max_width = ect_max_width; parent_class = gtk_type_class (PARENT_TYPE); } diff --git a/widgets/e-table/e-cell.c b/widgets/e-table/e-cell.c index 3212157675..ddab43dbd6 100644 --- a/widgets/e-table/e-cell.c +++ b/widgets/e-table/e-cell.c @@ -198,3 +198,11 @@ e_cell_leave_edit (ECellView *ecell_view, int model_col, int view_col, int row, E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->leave_edit ( ecell_view, model_col, view_col, row, edit_context); } + +int +e_cell_max_width (ECellView *ecell_view, int model_col, int view_col) +{ + return E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->max_width + (ecell_view, model_col, view_col); +} + diff --git a/widgets/e-table/e-cell.h b/widgets/e-table/e-cell.h index 3b12aab1e3..d097a7d6bd 100644 --- a/widgets/e-table/e-cell.h +++ b/widgets/e-table/e-cell.h @@ -69,6 +69,7 @@ typedef struct { gdouble width, gdouble height); gdouble (*print_height) (ECellView *ecell_view, GnomePrintContext *context, int model_col, int view_col, int row, gdouble width); + int (*max_width) (ECellView *ecell_view, int model_col, int view_col); } ECellClass; GtkType e_cell_get_type (void); @@ -88,6 +89,7 @@ void e_cell_print (ECellView *ecell_view, GnomePrintContext *context, double width, double height); gdouble e_cell_print_height (ECellView *ecell_view, GnomePrintContext *context, int model_col, int view_col, int row, gdouble width); +int e_cell_max_width (ECellView *ecell_view, int model_col, int view_col); void e_cell_focus (ECellView *ecell_view, int model_col, int view_col, int row, int x1, int y1, int x2, int y2); void e_cell_unfocus (ECellView *ecell_view); diff --git a/widgets/e-table/e-table-header-item.c b/widgets/e-table/e-table-header-item.c index 506ad546ca..93e787dffc 100644 --- a/widgets/e-table/e-table-header-item.c +++ b/widgets/e-table/e-table-header-item.c @@ -136,14 +136,12 @@ ethi_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags } static void -ethi_font_load (ETableHeaderItem *ethi, char *font) +ethi_font_set (ETableHeaderItem *ethi, GdkFont *font) { if (ethi->font) gdk_font_unref (ethi->font); - - ethi->font = gdk_fontset_load (font); - if (ethi->font == NULL) - ethi->font = gdk_font_load ("-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-iso8859-1"); + + ethi->font = font; ethi->height = ethi->font->ascent + ethi->font->descent + HEADER_PADDING; if (ethi->height < MIN_ARROW_SIZE + 4 + HEADER_PADDING) @@ -151,6 +149,18 @@ ethi_font_load (ETableHeaderItem *ethi, char *font) } static void +ethi_font_load (ETableHeaderItem *ethi, char *fontname) +{ + GdkFont *font; + + font = gdk_fontset_load (fontname); + if (font == NULL) + font = gdk_font_load ("-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-iso8859-1"); + + ethi_font_set (ethi, font); +} + +static void ethi_drop_table_header (ETableHeaderItem *ethi) { GtkObject *header; @@ -468,7 +478,21 @@ ethi_drag_motion (GtkObject *canvas, GdkDragContext *context, gint x, gint y, guint time, ETableHeaderItem *ethi) { + char *droptype, *headertype; + gdk_drag_status (context, 0, time); + + droptype = gdk_atom_name (GPOINTER_TO_INT (context->targets->data)); + headertype = g_strdup_printf ("%s-%s", TARGET_ETABLE_COL_TYPE, + ethi->dnd_code); + + if (strcmp (droptype, headertype) != 0) { + g_free (headertype); + return FALSE; + } + + g_free (headertype); + if ((x >= 0) && (x <= (ethi->width)) && (y >= 0) && (y <= (ethi->height))){ int col; @@ -530,6 +554,7 @@ ethi_drag_data_received (GtkWidget *canvas, int drop_col = ethi->drop_col; int i; ethi->drop_col = -1; + if (column < 0) return; for (i = 0; i < count; i++) { @@ -634,7 +659,7 @@ ethi_realize (GnomeCanvasItem *item) gdk_gc_set_foreground (ethi->gc, &c); if (!ethi->font) - ethi_font_load (ethi, "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-iso8859-1"); + ethi_font_set (ethi, GTK_WIDGET (item->canvas)->style->font); /* * Now, configure DnD @@ -643,7 +668,7 @@ ethi_realize (GnomeCanvasItem *item) gtk_drag_dest_set (GTK_WIDGET (item->canvas), 0, ethi_drop_types, ELEMENTS (ethi_drop_types), GDK_ACTION_MOVE); - g_free(ethi_drop_types[0].target); + g_free(ethi_drop_types[0].target); /* Drop signals */ ethi->drag_motion_id = gtk_signal_connect (GTK_OBJECT (item->canvas), "drag_motion", @@ -695,20 +720,23 @@ draw_button (ETableHeaderItem *ethi, ETableCol *col, { GdkRectangle clip; int xtra; + + clip.x = x; + clip.y = y; + clip.width = width; + clip.height = height; + + gdk_window_set_back_pixmap (GTK_WIDGET (GNOME_CANVAS_ITEM (ethi)->canvas)->window, NULL, FALSE); - gdk_draw_rectangle ( - drawable, gc, TRUE, - x + 1, y + 1, width - 2, height -2); - - gtk_draw_shadow ( - style, drawable, - GTK_STATE_NORMAL, GTK_SHADOW_OUT, - x , y, width, height); + gtk_paint_box (style, drawable, + GTK_STATE_NORMAL, GTK_SHADOW_OUT, + &clip, NULL, "button", + x, y, width, height); clip.x = x + HEADER_PADDING / 2; clip.y = y + HEADER_PADDING / 2; clip.width = width - HEADER_PADDING; - clip.height = ethi->height; + clip.height = ethi->height - HEADER_PADDING; gdk_gc_set_clip_rectangle (ethi->gc, &clip); @@ -882,15 +910,21 @@ is_pointer_on_division (ETableHeaderItem *ethi, int pos, int *the_total, int *re static void set_cursor (ETableHeaderItem *ethi, int pos) { + int col; GtkWidget *canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (ethi)->canvas); /* We might be invoked before we are realized */ if (!canvas->window) return; - if (is_pointer_on_division (ethi, pos, NULL, NULL)) - e_cursor_set (canvas->window, E_CURSOR_SIZE_X); - else + if (is_pointer_on_division (ethi, pos, NULL, &col)) { + ETableCol *ecol = e_table_header_get_column (ethi->eth, col); + + if (ecol->resizeable) + e_cursor_set (canvas->window, E_CURSOR_SIZE_X); + else + e_cursor_set (canvas->window, E_CURSOR_ARROW); + } else e_cursor_set (canvas->window, E_CURSOR_ARROW); } @@ -909,9 +943,11 @@ ethi_maybe_start_drag (ETableHeaderItem *ethi, GdkEventMotion *event) if (!ethi->maybe_drag) return FALSE; - if (ethi->eth->col_count < 2) + if (ethi->eth->col_count < 2) { + ethi->maybe_drag = FALSE; return FALSE; - + } + if (MAX (abs (ethi->click_x - event->x), abs (ethi->click_y - event->y)) <= 3) return FALSE; @@ -1280,6 +1316,16 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e) if (e->button.button != 1) break; + else { + int width = 0; + gtk_signal_emit_by_name (GTK_OBJECT (ethi->eth), + "request_width", + (int)ethi->resize_col, &width); + /* Add 10 to stop it from "..."ing */ + e_table_header_set_size (ethi->eth, ethi->resize_col, width + 10); + + gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(ethi)); + } break; case GDK_BUTTON_RELEASE: { @@ -1400,6 +1446,7 @@ ethi_class_init (GtkObjectClass *object_class) gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_POINTER); + gtk_object_class_add_signals (object_class, ethi_signals, LAST_SIGNAL); } static void diff --git a/widgets/e-table/e-table-header.c b/widgets/e-table/e-table-header.c index 0f8f9ed1e9..bc3b7a7e09 100644 --- a/widgets/e-table/e-table-header.c +++ b/widgets/e-table/e-table-header.c @@ -24,6 +24,7 @@ enum { enum { STRUCTURE_CHANGE, DIMENSION_CHANGE, + REQUEST_WIDTH, LAST_SIGNAL }; @@ -158,6 +159,13 @@ e_table_header_class_init (GtkObjectClass *object_class) GTK_SIGNAL_OFFSET (ETableHeaderClass, dimension_change), gtk_marshal_NONE__INT, GTK_TYPE_NONE, 1, GTK_TYPE_INT); + eth_signals [REQUEST_WIDTH] = + gtk_signal_new ("request_width", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (ETableHeaderClass, request_width), + gtk_marshal_INT__INT, + GTK_TYPE_INT, 1, GTK_TYPE_INT); gtk_object_class_add_signals (object_class, eth_signals, LAST_SIGNAL); } diff --git a/widgets/e-table/e-table-header.h b/widgets/e-table/e-table-header.h index 0dcce14b1e..dcdcc440ed 100644 --- a/widgets/e-table/e-table-header.h +++ b/widgets/e-table/e-table-header.h @@ -40,6 +40,7 @@ typedef struct { void (*structure_change) (ETableHeader *eth); void (*dimension_change) (ETableHeader *eth, int col); + int (*request_width) (ETableHeader *eth, int col); } ETableHeaderClass; GtkType e_table_header_get_type (void); diff --git a/widgets/e-table/e-table-item.c b/widgets/e-table/e-table-item.c index 1cd37d1961..186587838c 100644 --- a/widgets/e-table/e-table-item.c +++ b/widgets/e-table/e-table-item.c @@ -367,7 +367,9 @@ eti_remove_header_model (ETableItem *eti) eti->header_structure_change_id); gtk_signal_disconnect (GTK_OBJECT (eti->header), eti->header_dim_change_id); - + gtk_signal_disconnect (GTK_OBJECT (eti->header), + eti->header_request_width_id); + if (eti->cell_views){ eti_unrealize_cell_views (eti); eti_detach_cell_views (eti); @@ -377,6 +379,7 @@ eti_remove_header_model (ETableItem *eti) eti->header_structure_change_id = 0; eti->header_dim_change_id = 0; + eti->header_request_width_id = 0; eti->header = NULL; } @@ -826,6 +829,18 @@ eti_header_structure_changed (ETableHeader *eth, ETableItem *eti) e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti)); } +static int +eti_request_column_width (ETableHeader *eth, int col, ETableItem *eti) +{ + int width = 0; + + if (eti->cell_views) { + width = e_cell_max_width (eti->cell_views[col], view_to_model_col(eti, col), col); + } + + return width; +} + static void eti_add_header_model (ETableItem *eti, ETableHeader *header) { @@ -843,6 +858,10 @@ eti_add_header_model (ETableItem *eti, ETableHeader *header) eti->header_structure_change_id = gtk_signal_connect ( GTK_OBJECT (header), "structure_change", GTK_SIGNAL_FUNC (eti_header_structure_changed), eti); + + eti->header_request_width_id = gtk_signal_connect + (GTK_OBJECT (header), "request_width", + GTK_SIGNAL_FUNC (eti_request_column_width), eti); } /* diff --git a/widgets/e-table/e-table-item.h b/widgets/e-table/e-table-item.h index 82171f851f..e89f2587e5 100644 --- a/widgets/e-table/e-table-item.h +++ b/widgets/e-table/e-table-item.h @@ -40,6 +40,7 @@ typedef struct { */ int header_dim_change_id; int header_structure_change_id; + int header_request_width_id; int table_model_pre_change_id; int table_model_change_id; int table_model_row_change_id; diff --git a/widgets/e-table/e-table.c b/widgets/e-table/e-table.c index b40d7e4df8..cbc7ec3e4d 100644 --- a/widgets/e-table/e-table.c +++ b/widgets/e-table/e-table.c @@ -203,7 +203,17 @@ header_canvas_size_allocate (GtkWidget *widget, GtkAllocation *alloc, ETable *e_ { gnome_canvas_set_scroll_region ( GNOME_CANVAS (e_table->header_canvas), - 0, 0, alloc->width - 1, COLUMN_HEADER_HEIGHT - 1); + 0, 0, alloc->width - 1, /* COLUMN_HEADER_HEIGHT - 1 */ + E_TABLE_HEADER_ITEM (e_table->header_item)->height - 1); + + /* When the header item is created ->height == 0, + as the font is only created when everything is realized. + So we set the usize here as well, so that the size of the + header is correct */ + if (GTK_WIDGET (e_table->header_canvas)->allocation.height != + E_TABLE_HEADER_ITEM (e_table->header_item)->height) + gtk_widget_set_usize (GTK_WIDGET (e_table->header_canvas), -1, + E_TABLE_HEADER_ITEM (e_table->header_item)->height); } static void @@ -234,7 +244,8 @@ e_table_setup_header (ETable *e_table) GTK_OBJECT (e_table->header_canvas), "size_allocate", GTK_SIGNAL_FUNC (header_canvas_size_allocate), e_table); - gtk_widget_set_usize (GTK_WIDGET (e_table->header_canvas), -1, COLUMN_HEADER_HEIGHT); + gtk_widget_set_usize (GTK_WIDGET (e_table->header_canvas), -1, + E_TABLE_HEADER_ITEM (e_table->header_item)->height); } static gboolean diff --git a/widgets/e-table/table-test.c b/widgets/e-table/table-test.c index 62160e7035..f83b6e2808 100644 --- a/widgets/e-table/table-test.c +++ b/widgets/e-table/table-test.c @@ -32,9 +32,9 @@ main (int argc, char *argv []) e_cursors_init (); - table_browser_test (); - multi_cols_test (); - check_test (); +/* table_browser_test (); */ +/* multi_cols_test (); */ +/* check_test (); */ e_table_test (); diff --git a/widgets/table/e-cell-text.c b/widgets/table/e-cell-text.c index e78de94660..13008af8ad 100644 --- a/widgets/table/e-cell-text.c +++ b/widgets/table/e-cell-text.c @@ -460,6 +460,8 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable, gboolean selected; EFontStyle style; + EFontStyle style = E_FONT_PLAIN; + selected = flags & E_CELL_SELECTED; if (edit){ @@ -1267,6 +1269,32 @@ ect_print_height (ECellView *ecell_view, GnomePrintContext *context, return 16; } +static int +ect_max_width (ECellView *ecell_view, + int model_col, + int view_col) +{ + /* New ECellText */ + ECellTextView *text_view = (ECellTextView *) ecell_view; + EFont *font; + int row; + int number_of_rows; + int max_width = 0; + + font = text_view->font; + number_of_rows = e_table_model_row_count (ecell_view->e_table_model); + + for (row = 0; row < number_of_rows; row++) { + CurrentCell cell; + build_current_cell (&cell, text_view, model_col, view_col, row); + split_into_lines (&cell); + calc_line_widths (&cell); + max_width = MAX (max_width, cell.breaks->max_width); + } + + return max_width; +} + /* * GtkObject::destroy method */ @@ -1357,6 +1385,7 @@ e_cell_text_class_init (GtkObjectClass *object_class) ecc->leave_edit = ect_leave_edit; ecc->print = ect_print; ecc->print_height = ect_print_height; + ecc->max_width = ect_max_width; object_class->get_arg = ect_get_arg; object_class->set_arg = ect_set_arg; diff --git a/widgets/table/e-cell-toggle.c b/widgets/table/e-cell-toggle.c index f0a05b488a..e18f4b33e7 100644 --- a/widgets/table/e-cell-toggle.c +++ b/widgets/table/e-cell-toggle.c @@ -223,6 +223,28 @@ etog_height (ECellView *ecell_view, int model_col, int view_col, int row) return toggle->height; } +/* + * ECell::max_width method + */ +static int +etog_max_width (ECellView *ecell_view, int model_col, int view_col) +{ + ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell); + void *_value = e_table_model_value_at (ecell_view->e_table_model, model_col, 0); + int max_width = gdk_pixbuf_get_width (toggle->images[GPOINTER_TO_INT (_value)]); + int number_of_rows; + int row; + + number_of_rows = e_table_model_row_count (ecell_view->e_table_model); + for (row = 1; row < number_of_rows; row++) { + void *_value = e_table_model_value_at (ecell_view->e_table_model, + model_col, row); + max_width = MAX (max_width, gdk_pixbuf_get_width (toggle->images[GPOINTER_TO_INT (_value)])); + } + + return max_width; +} + static void etog_destroy (GtkObject *object) { @@ -251,6 +273,7 @@ e_cell_toggle_class_init (GtkObjectClass *object_class) ecc->draw = etog_draw; ecc->event = etog_event; ecc->height = etog_height; + ecc->max_width = etog_max_width; parent_class = gtk_type_class (PARENT_TYPE); } diff --git a/widgets/table/e-cell-tree.c b/widgets/table/e-cell-tree.c index 3cc06a73ee..48ae9f4af1 100644 --- a/widgets/table/e-cell-tree.c +++ b/widgets/table/e-cell-tree.c @@ -353,6 +353,67 @@ ect_height (ECellView *ecell_view, int model_col, int view_col, int row) } /* + * ECell::max_width method + */ +static int +ect_max_width (ECellView *ecell_view, int model_col, int view_col) +{ + ECellTreeView *tree_view = (ECellTreeView *) ecell_view; + int row; + int number_of_rows; + int max_width = 0; + int width = 0; + + number_of_rows = e_table_model_row_count (ecell_view->e_table_model); + + for (row = 0; row < number_of_rows; row++) { + ETreeModel *tree_model = e_cell_tree_get_tree_model(ecell_view->e_table_model, row); + ETreePath *node; + GdkPixbuf *node_image; + int node_image_width = 0, node_image_height = 0; + ETreePath *parent_node; + + int offset, subcell_offset; + gboolean expanded, expandable; + + node = e_cell_tree_get_node (tree_model, row); + + offset = offset_of_node (tree_model, node); + expandable = e_tree_model_node_is_expandable (tree_model, node); + expanded = e_tree_model_node_is_expanded (tree_model, node); + subcell_offset = offset; + + node_image = e_tree_model_icon_of_node (tree_model, node); + + if (node_image) { + node_image_width = gdk_pixbuf_get_width (node_image); + node_image_height = gdk_pixbuf_get_height (node_image); + } + + width = subcell_offset + node_image_width; + + if (expandable) { + GdkPixbuf *image; + + image = (expanded + ? E_CELL_TREE(tree_view->cell_view.ecell)->open_pixbuf + : E_CELL_TREE(tree_view->cell_view.ecell)->closed_pixbuf); + + width += gdk_pixbuf_get_width(image); + } + + width += e_cell_max_width (tree_view->subcell_view, model_col, + view_col); + + max_width = MAX (max_width, width); + } + + return max_width; +} + + + +/* * ECellView::enter_edit method */ static void * @@ -510,6 +571,7 @@ e_cell_tree_class_init (GtkObjectClass *object_class) ecc->leave_edit = ect_leave_edit; ecc->print = ect_print; ecc->print_height = ect_print_height; + ecc->max_width = ect_max_width; parent_class = gtk_type_class (PARENT_TYPE); } diff --git a/widgets/table/e-cell.c b/widgets/table/e-cell.c index 3212157675..ddab43dbd6 100644 --- a/widgets/table/e-cell.c +++ b/widgets/table/e-cell.c @@ -198,3 +198,11 @@ e_cell_leave_edit (ECellView *ecell_view, int model_col, int view_col, int row, E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->leave_edit ( ecell_view, model_col, view_col, row, edit_context); } + +int +e_cell_max_width (ECellView *ecell_view, int model_col, int view_col) +{ + return E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->max_width + (ecell_view, model_col, view_col); +} + diff --git a/widgets/table/e-cell.h b/widgets/table/e-cell.h index 3b12aab1e3..d097a7d6bd 100644 --- a/widgets/table/e-cell.h +++ b/widgets/table/e-cell.h @@ -69,6 +69,7 @@ typedef struct { gdouble width, gdouble height); gdouble (*print_height) (ECellView *ecell_view, GnomePrintContext *context, int model_col, int view_col, int row, gdouble width); + int (*max_width) (ECellView *ecell_view, int model_col, int view_col); } ECellClass; GtkType e_cell_get_type (void); @@ -88,6 +89,7 @@ void e_cell_print (ECellView *ecell_view, GnomePrintContext *context, double width, double height); gdouble e_cell_print_height (ECellView *ecell_view, GnomePrintContext *context, int model_col, int view_col, int row, gdouble width); +int e_cell_max_width (ECellView *ecell_view, int model_col, int view_col); void e_cell_focus (ECellView *ecell_view, int model_col, int view_col, int row, int x1, int y1, int x2, int y2); void e_cell_unfocus (ECellView *ecell_view); diff --git a/widgets/table/e-table-header-item.c b/widgets/table/e-table-header-item.c index 506ad546ca..93e787dffc 100644 --- a/widgets/table/e-table-header-item.c +++ b/widgets/table/e-table-header-item.c @@ -136,14 +136,12 @@ ethi_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags } static void -ethi_font_load (ETableHeaderItem *ethi, char *font) +ethi_font_set (ETableHeaderItem *ethi, GdkFont *font) { if (ethi->font) gdk_font_unref (ethi->font); - - ethi->font = gdk_fontset_load (font); - if (ethi->font == NULL) - ethi->font = gdk_font_load ("-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-iso8859-1"); + + ethi->font = font; ethi->height = ethi->font->ascent + ethi->font->descent + HEADER_PADDING; if (ethi->height < MIN_ARROW_SIZE + 4 + HEADER_PADDING) @@ -151,6 +149,18 @@ ethi_font_load (ETableHeaderItem *ethi, char *font) } static void +ethi_font_load (ETableHeaderItem *ethi, char *fontname) +{ + GdkFont *font; + + font = gdk_fontset_load (fontname); + if (font == NULL) + font = gdk_font_load ("-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-iso8859-1"); + + ethi_font_set (ethi, font); +} + +static void ethi_drop_table_header (ETableHeaderItem *ethi) { GtkObject *header; @@ -468,7 +478,21 @@ ethi_drag_motion (GtkObject *canvas, GdkDragContext *context, gint x, gint y, guint time, ETableHeaderItem *ethi) { + char *droptype, *headertype; + gdk_drag_status (context, 0, time); + + droptype = gdk_atom_name (GPOINTER_TO_INT (context->targets->data)); + headertype = g_strdup_printf ("%s-%s", TARGET_ETABLE_COL_TYPE, + ethi->dnd_code); + + if (strcmp (droptype, headertype) != 0) { + g_free (headertype); + return FALSE; + } + + g_free (headertype); + if ((x >= 0) && (x <= (ethi->width)) && (y >= 0) && (y <= (ethi->height))){ int col; @@ -530,6 +554,7 @@ ethi_drag_data_received (GtkWidget *canvas, int drop_col = ethi->drop_col; int i; ethi->drop_col = -1; + if (column < 0) return; for (i = 0; i < count; i++) { @@ -634,7 +659,7 @@ ethi_realize (GnomeCanvasItem *item) gdk_gc_set_foreground (ethi->gc, &c); if (!ethi->font) - ethi_font_load (ethi, "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-iso8859-1"); + ethi_font_set (ethi, GTK_WIDGET (item->canvas)->style->font); /* * Now, configure DnD @@ -643,7 +668,7 @@ ethi_realize (GnomeCanvasItem *item) gtk_drag_dest_set (GTK_WIDGET (item->canvas), 0, ethi_drop_types, ELEMENTS (ethi_drop_types), GDK_ACTION_MOVE); - g_free(ethi_drop_types[0].target); + g_free(ethi_drop_types[0].target); /* Drop signals */ ethi->drag_motion_id = gtk_signal_connect (GTK_OBJECT (item->canvas), "drag_motion", @@ -695,20 +720,23 @@ draw_button (ETableHeaderItem *ethi, ETableCol *col, { GdkRectangle clip; int xtra; + + clip.x = x; + clip.y = y; + clip.width = width; + clip.height = height; + + gdk_window_set_back_pixmap (GTK_WIDGET (GNOME_CANVAS_ITEM (ethi)->canvas)->window, NULL, FALSE); - gdk_draw_rectangle ( - drawable, gc, TRUE, - x + 1, y + 1, width - 2, height -2); - - gtk_draw_shadow ( - style, drawable, - GTK_STATE_NORMAL, GTK_SHADOW_OUT, - x , y, width, height); + gtk_paint_box (style, drawable, + GTK_STATE_NORMAL, GTK_SHADOW_OUT, + &clip, NULL, "button", + x, y, width, height); clip.x = x + HEADER_PADDING / 2; clip.y = y + HEADER_PADDING / 2; clip.width = width - HEADER_PADDING; - clip.height = ethi->height; + clip.height = ethi->height - HEADER_PADDING; gdk_gc_set_clip_rectangle (ethi->gc, &clip); @@ -882,15 +910,21 @@ is_pointer_on_division (ETableHeaderItem *ethi, int pos, int *the_total, int *re static void set_cursor (ETableHeaderItem *ethi, int pos) { + int col; GtkWidget *canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (ethi)->canvas); /* We might be invoked before we are realized */ if (!canvas->window) return; - if (is_pointer_on_division (ethi, pos, NULL, NULL)) - e_cursor_set (canvas->window, E_CURSOR_SIZE_X); - else + if (is_pointer_on_division (ethi, pos, NULL, &col)) { + ETableCol *ecol = e_table_header_get_column (ethi->eth, col); + + if (ecol->resizeable) + e_cursor_set (canvas->window, E_CURSOR_SIZE_X); + else + e_cursor_set (canvas->window, E_CURSOR_ARROW); + } else e_cursor_set (canvas->window, E_CURSOR_ARROW); } @@ -909,9 +943,11 @@ ethi_maybe_start_drag (ETableHeaderItem *ethi, GdkEventMotion *event) if (!ethi->maybe_drag) return FALSE; - if (ethi->eth->col_count < 2) + if (ethi->eth->col_count < 2) { + ethi->maybe_drag = FALSE; return FALSE; - + } + if (MAX (abs (ethi->click_x - event->x), abs (ethi->click_y - event->y)) <= 3) return FALSE; @@ -1280,6 +1316,16 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e) if (e->button.button != 1) break; + else { + int width = 0; + gtk_signal_emit_by_name (GTK_OBJECT (ethi->eth), + "request_width", + (int)ethi->resize_col, &width); + /* Add 10 to stop it from "..."ing */ + e_table_header_set_size (ethi->eth, ethi->resize_col, width + 10); + + gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(ethi)); + } break; case GDK_BUTTON_RELEASE: { @@ -1400,6 +1446,7 @@ ethi_class_init (GtkObjectClass *object_class) gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_POINTER); + gtk_object_class_add_signals (object_class, ethi_signals, LAST_SIGNAL); } static void diff --git a/widgets/table/e-table-header.c b/widgets/table/e-table-header.c index 0f8f9ed1e9..bc3b7a7e09 100644 --- a/widgets/table/e-table-header.c +++ b/widgets/table/e-table-header.c @@ -24,6 +24,7 @@ enum { enum { STRUCTURE_CHANGE, DIMENSION_CHANGE, + REQUEST_WIDTH, LAST_SIGNAL }; @@ -158,6 +159,13 @@ e_table_header_class_init (GtkObjectClass *object_class) GTK_SIGNAL_OFFSET (ETableHeaderClass, dimension_change), gtk_marshal_NONE__INT, GTK_TYPE_NONE, 1, GTK_TYPE_INT); + eth_signals [REQUEST_WIDTH] = + gtk_signal_new ("request_width", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (ETableHeaderClass, request_width), + gtk_marshal_INT__INT, + GTK_TYPE_INT, 1, GTK_TYPE_INT); gtk_object_class_add_signals (object_class, eth_signals, LAST_SIGNAL); } diff --git a/widgets/table/e-table-header.h b/widgets/table/e-table-header.h index 0dcce14b1e..dcdcc440ed 100644 --- a/widgets/table/e-table-header.h +++ b/widgets/table/e-table-header.h @@ -40,6 +40,7 @@ typedef struct { void (*structure_change) (ETableHeader *eth); void (*dimension_change) (ETableHeader *eth, int col); + int (*request_width) (ETableHeader *eth, int col); } ETableHeaderClass; GtkType e_table_header_get_type (void); diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c index 1cd37d1961..186587838c 100644 --- a/widgets/table/e-table-item.c +++ b/widgets/table/e-table-item.c @@ -367,7 +367,9 @@ eti_remove_header_model (ETableItem *eti) eti->header_structure_change_id); gtk_signal_disconnect (GTK_OBJECT (eti->header), eti->header_dim_change_id); - + gtk_signal_disconnect (GTK_OBJECT (eti->header), + eti->header_request_width_id); + if (eti->cell_views){ eti_unrealize_cell_views (eti); eti_detach_cell_views (eti); @@ -377,6 +379,7 @@ eti_remove_header_model (ETableItem *eti) eti->header_structure_change_id = 0; eti->header_dim_change_id = 0; + eti->header_request_width_id = 0; eti->header = NULL; } @@ -826,6 +829,18 @@ eti_header_structure_changed (ETableHeader *eth, ETableItem *eti) e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti)); } +static int +eti_request_column_width (ETableHeader *eth, int col, ETableItem *eti) +{ + int width = 0; + + if (eti->cell_views) { + width = e_cell_max_width (eti->cell_views[col], view_to_model_col(eti, col), col); + } + + return width; +} + static void eti_add_header_model (ETableItem *eti, ETableHeader *header) { @@ -843,6 +858,10 @@ eti_add_header_model (ETableItem *eti, ETableHeader *header) eti->header_structure_change_id = gtk_signal_connect ( GTK_OBJECT (header), "structure_change", GTK_SIGNAL_FUNC (eti_header_structure_changed), eti); + + eti->header_request_width_id = gtk_signal_connect + (GTK_OBJECT (header), "request_width", + GTK_SIGNAL_FUNC (eti_request_column_width), eti); } /* diff --git a/widgets/table/e-table-item.h b/widgets/table/e-table-item.h index 82171f851f..e89f2587e5 100644 --- a/widgets/table/e-table-item.h +++ b/widgets/table/e-table-item.h @@ -40,6 +40,7 @@ typedef struct { */ int header_dim_change_id; int header_structure_change_id; + int header_request_width_id; int table_model_pre_change_id; int table_model_change_id; int table_model_row_change_id; diff --git a/widgets/table/e-table.c b/widgets/table/e-table.c index b40d7e4df8..cbc7ec3e4d 100644 --- a/widgets/table/e-table.c +++ b/widgets/table/e-table.c @@ -203,7 +203,17 @@ header_canvas_size_allocate (GtkWidget *widget, GtkAllocation *alloc, ETable *e_ { gnome_canvas_set_scroll_region ( GNOME_CANVAS (e_table->header_canvas), - 0, 0, alloc->width - 1, COLUMN_HEADER_HEIGHT - 1); + 0, 0, alloc->width - 1, /* COLUMN_HEADER_HEIGHT - 1 */ + E_TABLE_HEADER_ITEM (e_table->header_item)->height - 1); + + /* When the header item is created ->height == 0, + as the font is only created when everything is realized. + So we set the usize here as well, so that the size of the + header is correct */ + if (GTK_WIDGET (e_table->header_canvas)->allocation.height != + E_TABLE_HEADER_ITEM (e_table->header_item)->height) + gtk_widget_set_usize (GTK_WIDGET (e_table->header_canvas), -1, + E_TABLE_HEADER_ITEM (e_table->header_item)->height); } static void @@ -234,7 +244,8 @@ e_table_setup_header (ETable *e_table) GTK_OBJECT (e_table->header_canvas), "size_allocate", GTK_SIGNAL_FUNC (header_canvas_size_allocate), e_table); - gtk_widget_set_usize (GTK_WIDGET (e_table->header_canvas), -1, COLUMN_HEADER_HEIGHT); + gtk_widget_set_usize (GTK_WIDGET (e_table->header_canvas), -1, + E_TABLE_HEADER_ITEM (e_table->header_item)->height); } static gboolean diff --git a/widgets/table/table-test.c b/widgets/table/table-test.c index 62160e7035..f83b6e2808 100644 --- a/widgets/table/table-test.c +++ b/widgets/table/table-test.c @@ -32,9 +32,9 @@ main (int argc, char *argv []) e_cursors_init (); - table_browser_test (); - multi_cols_test (); - check_test (); +/* table_browser_test (); */ +/* multi_cols_test (); */ +/* check_test (); */ e_table_test (); |