aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/table
diff options
context:
space:
mode:
authorIain Holmes <iain@src.gnome.org>2000-09-15 08:08:06 +0800
committerIain Holmes <iain@src.gnome.org>2000-09-15 08:08:06 +0800
commit22f72cc08e20c7871d93f05375fe2bafb0c1023a (patch)
treed765e7100abbfd00a916939716910b06e80e244c /widgets/table
parent6d35f43ab255e79770f4be53c058a084fe9c6826 (diff)
downloadgsoc2013-evolution-22f72cc08e20c7871d93f05375fe2bafb0c1023a.tar.gz
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
Diffstat (limited to 'widgets/table')
-rw-r--r--widgets/table/e-cell-text.c29
-rw-r--r--widgets/table/e-cell-toggle.c23
-rw-r--r--widgets/table/e-cell-tree.c62
-rw-r--r--widgets/table/e-cell.c8
-rw-r--r--widgets/table/e-cell.h2
-rw-r--r--widgets/table/e-table-header-item.c89
-rw-r--r--widgets/table/e-table-header.c8
-rw-r--r--widgets/table/e-table-header.h1
-rw-r--r--widgets/table/e-table-item.c21
-rw-r--r--widgets/table/e-table-item.h1
-rw-r--r--widgets/table/e-table.c15
-rw-r--r--widgets/table/table-test.c6
12 files changed, 238 insertions, 27 deletions
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 ();