diff options
author | Iain Holmes <iain@src.gnome.org> | 2000-09-15 08:08:06 +0800 |
---|---|---|
committer | Iain Holmes <iain@src.gnome.org> | 2000-09-15 08:08:06 +0800 |
commit | 22f72cc08e20c7871d93f05375fe2bafb0c1023a (patch) | |
tree | d765e7100abbfd00a916939716910b06e80e244c | |
parent | 6d35f43ab255e79770f4be53c058a084fe9c6826 (diff) | |
download | gsoc2013-evolution-22f72cc08e20c7871d93f05375fe2bafb0c1023a.tar gsoc2013-evolution-22f72cc08e20c7871d93f05375fe2bafb0c1023a.tar.gz gsoc2013-evolution-22f72cc08e20c7871d93f05375fe2bafb0c1023a.tar.bz2 gsoc2013-evolution-22f72cc08e20c7871d93f05375fe2bafb0c1023a.tar.lz gsoc2013-evolution-22f72cc08e20c7871d93f05375fe2bafb0c1023a.tar.xz gsoc2013-evolution-22f72cc08e20c7871d93f05375fe2bafb0c1023a.tar.zst gsoc2013-evolution-22f72cc08e20c7871d93f05375fe2bafb0c1023a.zip |
Fix some crashes Make double clicking on the header dividers automatically
Fix some crashes
Make double clicking on the header dividers automatically size the header
to it's best fit.
When dragging onto the header check the dragged item is a header object.
Check the column is resizeable before setting the cursor to <->
Use the font and themes to draw the table and items.
svn path=/trunk/; revision=5438
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 (); |