diff options
author | Miguel de Icaza <miguel@gnu.org> | 1999-12-31 10:23:37 +0800 |
---|---|---|
committer | Arturo Espinosa <unammx@src.gnome.org> | 1999-12-31 10:23:37 +0800 |
commit | f55c64565cd6b2820652b09cd647581067e4c188 (patch) | |
tree | d7c39cd75444e9454480d84662ffb76ed9949d9a | |
parent | d0606659a4bb08bdb635fea2b702856b2fabb480 (diff) | |
download | gsoc2013-evolution-f55c64565cd6b2820652b09cd647581067e4c188.tar gsoc2013-evolution-f55c64565cd6b2820652b09cd647581067e4c188.tar.gz gsoc2013-evolution-f55c64565cd6b2820652b09cd647581067e4c188.tar.bz2 gsoc2013-evolution-f55c64565cd6b2820652b09cd647581067e4c188.tar.lz gsoc2013-evolution-f55c64565cd6b2820652b09cd647581067e4c188.tar.xz gsoc2013-evolution-f55c64565cd6b2820652b09cd647581067e4c188.tar.zst gsoc2013-evolution-f55c64565cd6b2820652b09cd647581067e4c188.zip |
Ok, the restructuring of ETableItem to compute its size without hacks is
Ok, the restructuring of ETableItem to compute its size without hacks is
in now. I am feeling better now.
1999-12-30 Miguel de Icaza <miguel@gnu.org>
* e-table-item.c (eti_attach_cell_views): New routine, creates the
cell views.
(eti_detach_cell_views): Detaches the cell_views from the
ETableItem.
(eti_realize_cell_views, eti_unrealize_cell_views): Simplified to
just do realize/unrealize notification.
(eti_add_table_model): Only attach the cells when we have both the
table model and the header model.
* e-cell.h (ECellClass): Added two new methods: new_view and
kill_view which drive the view process (instead of putting that on
realize/unrealize).
* e-cell.c: Adapt the code to use the new scheme for view
instantiation.
* e-cell-text.c, e-cell-toggle.c: Adapted to the new class
changes.
svn path=/trunk/; revision=1523
-rw-r--r-- | widgets/ChangeLog | 21 | ||||
-rw-r--r-- | widgets/e-cell-text.c | 65 | ||||
-rw-r--r-- | widgets/e-cell-toggle.c | 40 | ||||
-rw-r--r-- | widgets/e-cell.c | 32 | ||||
-rw-r--r-- | widgets/e-cell.h | 18 | ||||
-rw-r--r-- | widgets/e-table-item.c | 74 | ||||
-rw-r--r-- | widgets/e-table-item.h | 1 | ||||
-rw-r--r-- | widgets/e-table.c | 11 | ||||
-rw-r--r-- | widgets/e-table.h | 5 | ||||
-rw-r--r-- | widgets/e-table/ChangeLog | 21 | ||||
-rw-r--r-- | widgets/e-table/e-cell-text.c | 65 | ||||
-rw-r--r-- | widgets/e-table/e-cell-toggle.c | 40 | ||||
-rw-r--r-- | widgets/e-table/e-cell.c | 32 | ||||
-rw-r--r-- | widgets/e-table/e-cell.h | 18 | ||||
-rw-r--r-- | widgets/e-table/e-table-item.c | 74 | ||||
-rw-r--r-- | widgets/e-table/e-table-item.h | 1 | ||||
-rw-r--r-- | widgets/e-table/e-table.c | 11 | ||||
-rw-r--r-- | widgets/e-table/e-table.h | 5 | ||||
-rw-r--r-- | widgets/table/e-cell-text.c | 65 | ||||
-rw-r--r-- | widgets/table/e-cell-toggle.c | 40 | ||||
-rw-r--r-- | widgets/table/e-cell.c | 32 | ||||
-rw-r--r-- | widgets/table/e-cell.h | 18 | ||||
-rw-r--r-- | widgets/table/e-table-item.c | 74 | ||||
-rw-r--r-- | widgets/table/e-table-item.h | 1 | ||||
-rw-r--r-- | widgets/table/e-table.c | 11 | ||||
-rw-r--r-- | widgets/table/e-table.h | 5 |
26 files changed, 564 insertions, 216 deletions
diff --git a/widgets/ChangeLog b/widgets/ChangeLog index f3eeb358b3..47e410e613 100644 --- a/widgets/ChangeLog +++ b/widgets/ChangeLog @@ -1,3 +1,24 @@ +1999-12-30 Miguel de Icaza <miguel@gnu.org> + + * e-table-item.c (eti_attach_cell_views): New routine, creates the + cell views. + (eti_detach_cell_views): Detaches the cell_views from the + ETableItem. + (eti_realize_cell_views, eti_unrealize_cell_views): Simplified to + just do realize/unrealize notification. + (eti_add_table_model): Only attach the cells when we have both the + table model and the header model. + + * e-cell.h (ECellClass): Added two new methods: new_view and + kill_view which drive the view process (instead of putting that on + realize/unrealize). + + * e-cell.c: Adapt the code to use the new scheme for view + instantiation. + + * e-cell-text.c, e-cell-toggle.c: Adapted to the new class + changes. + 1999-12-22 Miguel de Icaza <miguel@helixcode.com> * e-table-item.c (e_table_item_focus): grab focus here with the diff --git a/widgets/e-cell-text.c b/widgets/e-cell-text.c index 9d599f3d4c..1b2205ba51 100644 --- a/widgets/e-cell-text.c +++ b/widgets/e-cell-text.c @@ -38,7 +38,6 @@ typedef struct { GdkGC *gc; GdkFont *font; GnomeCanvas *canvas; - ETableItem *eti; /* * During edition. @@ -51,7 +50,9 @@ static ECellClass *parent_class; static void ect_queue_redraw (ECellTextView *text_view, int view_col, int view_row) { - e_table_item_redraw_range (text_view->eti, view_col, view_row, view_col, view_row); + e_table_item_redraw_range ( + text_view->cell_view.e_table_item_view, + view_col, view_row, view_col, view_row); } /* @@ -63,7 +64,7 @@ ect_accept_edits (ECellTextView *text_view) const char *text = gtk_entry_get_text (text_view->edit->entry); CellEdit *edit = text_view->edit; - e_table_model_set_value_at (text_view->cell_view.table_model, edit->model_col, edit->row, text); + e_table_model_set_value_at (text_view->cell_view.e_table_model, edit->model_col, edit->row, text); } /* @@ -84,7 +85,7 @@ ect_stop_editing (ECellTextView *text_view) text_view->edit = NULL; - e_table_item_leave_edit (text_view->eti); + e_table_item_leave_edit (text_view->cell_view.e_table_item_view); } /* @@ -98,20 +99,19 @@ ect_cancel_edit (ECellTextView *text_view) } /* - * ECell::realize method + * ECell::new_view method */ static ECellView * -ect_realize (ECell *ecell, ETableModel *table_model, void *view) +ect_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view) { ECellText *ect = E_CELL_TEXT (ecell); ECellTextView *text_view = g_new0 (ECellTextView, 1); - ETableItem *eti = E_TABLE_ITEM (view); - GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas; + GnomeCanvas *canvas = GNOME_CANVAS_ITEM (e_table_item_view)->canvas; text_view->cell_view.ecell = ecell; - text_view->cell_view.table_model = table_model; + text_view->cell_view.e_table_model = table_model; + text_view->cell_view.e_table_item_view = e_table_item_view; - text_view->gc = gdk_gc_new (GTK_WIDGET (canvas)->window); if (ect->font_name){ GdkFont *f; @@ -124,23 +124,19 @@ ect_realize (ECell *ecell, ETableModel *table_model, void *view) gdk_font_ref (text_view->font); } - text_view->eti = eti; text_view->canvas = canvas; return (ECellView *)text_view; } /* - * ECell::unrealize method + * ECell::kill_view method */ static void -ect_unrealize (ECellView *ecv) +ect_kill_view (ECellView *ecv) { ECellTextView *text_view = (ECellTextView *) ecv; - gdk_gc_unref (text_view->gc); - text_view->gc = NULL; - gdk_font_unref (text_view->font); text_view->font = NULL; @@ -148,6 +144,29 @@ ect_unrealize (ECellView *ecv) } /* + * ECell::realize method + */ +static void +ect_realize (ECellView *ecell_view) +{ + ECellTextView *text_view = (ECellTextView *) ecell_view; + + text_view->gc = gdk_gc_new (GTK_WIDGET (text_view->canvas)->window); +} + +/* + * ECell::unrealize method + */ +static void +ect_unrealize (ECellView *ecv) +{ + ECellTextView *text_view = (ECellTextView *) ecv; + + gdk_gc_unref (text_view->gc); + text_view->gc = NULL; +} + +/* * ECell::draw method */ static void @@ -159,7 +178,7 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable, ECellTextView *text_view = (ECellTextView *) ecell_view; GtkWidget *w = GTK_WIDGET (text_view->canvas); GdkRectangle rect; - const char *str = e_table_model_value_at (ecell_view->table_model, model_col, row); + const char *str = e_table_model_value_at (ecell_view->e_table_model, model_col, row); GdkFont *font = text_view->font; const int height = font->ascent + font->descent; int xoff; @@ -333,7 +352,7 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, if (text_view->edit){ printf ("FIXME: Should handle click here\n"); } else - e_table_item_enter_edit (text_view->eti, view_col, row); + e_table_item_enter_edit (text_view->cell_view.e_table_item_view, view_col, row); break; case GDK_BUTTON_RELEASE: @@ -351,7 +370,7 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, } if (!text_view->edit){ - e_table_item_enter_edit (text_view->eti, view_col, row); + e_table_item_enter_edit (text_view->cell_view.e_table_item_view, view_col, row); ect_edit_select_all (text_view); } @@ -385,7 +404,7 @@ ect_height (ECellView *ecell_view, int model_col, int view_col, int row) static void ect_entry_activate (GtkEntry *entry, ECellTextView *text_view) { - e_table_item_leave_edit (text_view->eti); + e_table_item_leave_edit (text_view->cell_view.e_table_item_view); } /* @@ -395,7 +414,7 @@ static void * ect_enter_edit (ECellView *ecell_view, int model_col, int view_col, int row) { ECellTextView *text_view = (ECellTextView *) ecell_view; - const char *str = e_table_model_value_at (ecell_view->table_model, model_col, row); + const char *str = e_table_model_value_at (ecell_view->e_table_model, model_col, row); CellEdit *edit; edit = g_new (CellEdit, 1); @@ -461,7 +480,9 @@ e_cell_text_class_init (GtkObjectClass *object_class) ECellClass *ecc = (ECellClass *) object_class; object_class->destroy = ect_destroy; - + + ecc->new_view = ect_new_view; + ecc->kill_view = ect_kill_view; ecc->realize = ect_realize; ecc->unrealize = ect_unrealize; ecc->draw = ect_draw; diff --git a/widgets/e-cell-toggle.c b/widgets/e-cell-toggle.c index dbe5fe5cbd..6ea181ea40 100644 --- a/widgets/e-cell-toggle.c +++ b/widgets/e-cell-toggle.c @@ -23,7 +23,6 @@ typedef struct { ECellView cell_view; GdkGC *gc; GnomeCanvas *canvas; - ETableItem *eti; } ECellToggleView; static ECellClass *parent_class; @@ -31,28 +30,43 @@ static ECellClass *parent_class; static void etog_queue_redraw (ECellToggleView *text_view, int view_col, int view_row) { - e_table_item_redraw_range (text_view->eti, view_col, view_row, view_col, view_row); + e_table_item_redraw_range ( + text_view->cell_view.e_table_item_view, + view_col, view_row, view_col, view_row); } /* * ECell::realize method */ static ECellView * -etog_realize (ECell *ecell, ETableModel *table_model, void *view) +etog_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view) { ECellToggleView *toggle_view = g_new0 (ECellToggleView, 1); - ETableItem *eti = E_TABLE_ITEM (view); + ETableItem *eti = E_TABLE_ITEM (e_table_item_view); GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas; toggle_view->cell_view.ecell = ecell; - toggle_view->cell_view.table_model = table_model; - toggle_view->eti = eti; + toggle_view->cell_view.e_table_model = table_model; + toggle_view->cell_view.e_table_item_view = e_table_item_view; toggle_view->canvas = canvas; - toggle_view->gc = gdk_gc_new (GTK_WIDGET (canvas)->window); return (ECellView *) toggle_view; } +static void +etog_kill_view (ECellView *ecell_view) +{ + g_free (ecell_view); +} + +static void +etog_realize (ECellView *ecell_view) +{ + ECellToggleView *toggle_view = (ECellToggleView *) ecell_view; + + toggle_view->gc = gdk_gc_new (GTK_WIDGET (toggle_view->canvas)->window); +} + /* * ECell::unrealize method */ @@ -63,8 +77,6 @@ etog_unrealize (ECellView *ecv) gdk_gc_unref (toggle_view->gc); toggle_view->gc = NULL; - - g_free (toggle_view); } /* @@ -81,7 +93,7 @@ etog_draw (ECellView *ecell_view, GdkDrawable *drawable, ArtPixBuf *art; int x, y, width, height; const int value = GPOINTER_TO_INT ( - e_table_model_value_at (ecell_view->table_model, model_col, row)); + e_table_model_value_at (ecell_view->e_table_model, model_col, row)); if (value >= toggle->n_states){ g_warning ("Value from the table model is %d, the states we support are [0..%d)\n", @@ -173,7 +185,7 @@ etog_set_value (ECellToggleView *toggle_view, int model_col, int view_col, int r if (value >= toggle->n_states) value = 0; - e_table_model_set_value_at (toggle_view->cell_view.table_model, + e_table_model_set_value_at (toggle_view->cell_view.e_table_model, model_col, row, GINT_TO_POINTER (value)); etog_queue_redraw (toggle_view, view_col, row); } @@ -185,7 +197,7 @@ static gint etog_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row) { ECellToggleView *toggle_view = (ECellToggleView *) ecell_view; - void *_value = e_table_model_value_at (ecell_view->table_model, model_col, row); + void *_value = e_table_model_value_at (ecell_view->e_table_model, model_col, row); const int value = GPOINTER_TO_INT (_value); switch (event->type){ @@ -237,7 +249,9 @@ e_cell_toggle_class_init (GtkObjectClass *object_class) ECellClass *ecc = (ECellClass *) object_class; object_class->destroy = etog_destroy; - + + ecc->new_view = etog_new_view; + ecc->kill_view = etog_kill_view; ecc->realize = etog_realize; ecc->unrealize = etog_unrealize; ecc->draw = etog_draw; diff --git a/widgets/e-cell.c b/widgets/e-cell.c index 4495bbb1a7..0f9297ecba 100644 --- a/widgets/e-cell.c +++ b/widgets/e-cell.c @@ -13,12 +13,22 @@ #define PARENT_TYPE gtk_object_get_type() static ECellView * -ec_realize (ECell *e_cell, ETableModel *table_model, void *view) +ec_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view) { return NULL; } static void +ec_realize (ECellView *e_cell) +{ +} + +static void +ec_kill_view (ECellView *ecell_view) +{ +} + +static void ec_unrealize (ECellView *e_cell) { } @@ -85,6 +95,8 @@ e_cell_class_init (GtkObjectClass *object_class) ecc->realize = ec_realize; ecc->unrealize = ec_unrealize; + ecc->new_view = ec_new_view; + ecc->kill_view = ec_kill_view; ecc->draw = ec_draw; ecc->event = ec_event; ecc->focus = ec_focus; @@ -110,10 +122,22 @@ e_cell_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_co } ECellView * -e_cell_realize (ECell *ecell, ETableModel *table_model, void *view) +e_cell_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view) +{ + return E_CELL_CLASS (GTK_OBJECT (ecell)->klass)->new_view ( + ecell, table_model, e_table_item_view); +} + +void +e_cell_view_realize (ECellView *ecell_view) +{ + return E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->realize (ecell_view); +} + +void +e_cell_kill_view (ECellView *ecell_view) { - return E_CELL_CLASS (GTK_OBJECT (ecell)->klass)->realize ( - ecell, table_model, view); + E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->kill_view (ecell_view); } void diff --git a/widgets/e-cell.h b/widgets/e-cell.h index 23173a586c..3c258689e4 100644 --- a/widgets/e-cell.h +++ b/widgets/e-cell.h @@ -19,7 +19,8 @@ struct _ECell { struct _ECellView { ECell *ecell; - ETableModel *table_model; + ETableModel *e_table_model; + void *e_table_item_view; gint focus_x1, focus_y1, focus_x2, focus_y2; gint focus_col, focus_row; @@ -29,9 +30,13 @@ struct _ECellView { typedef struct { GtkObjectClass parent_class; + + ECellView *(*new_view) (ECell *ecell, ETableModel *table_model, void *e_table_item_view); + void (*kill_view) (ECellView *ecell_view); + + void (*realize) (ECellView *ecell_view); + void (*unrealize) (ECellView *ecell_view); - ECellView *(*realize) (ECell *ecell, ETableModel *table_model, void *view); - void (*unrealize) (ECellView *e_cell_view); void (*draw) (ECellView *ecell_view, GdkDrawable *drawable, int model_col, int view_col, int row, gboolean selected, int x1, int y1, int x2, int y2); @@ -46,9 +51,14 @@ typedef struct { } ECellClass; GtkType e_cell_get_type (void); +ECellView *e_cell_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view); +void e_cell_kill_view (ECellView *ecell_view); + void e_cell_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row); -ECellView *e_cell_realize (ECell *ecell, ETableModel *table_model, void *view); + +void e_cell_realize (ECellView *ecell_view); void e_cell_unrealize (ECellView *ecell_view); + void e_cell_draw (ECellView *ecell_view, GdkDrawable *dr, int model_col, int view_col, int row, gboolean selected, int x1, int y1, int x2, int y2); diff --git a/widgets/e-table-item.c b/widgets/e-table-item.c index f9c5bc197d..33f0c18616 100644 --- a/widgets/e-table-item.c +++ b/widgets/e-table-item.c @@ -66,6 +66,21 @@ eti_realize_cell_views (ETableItem *eti) { int i; + for (i = 0; i < eti->n_cells; i++) + e_cell_view_realize (eti->cell_views [i], eti); + eti->cell_views_realized = 1; +} + +static void eti_compute_height (ETableItem *eti); + +static void +eti_attach_cell_views (ETableItem *eti) +{ + int i; + + g_assert (eti->header); + g_assert (eti->table_model); + /* * Now realize the various ECells */ @@ -75,35 +90,50 @@ eti_realize_cell_views (ETableItem *eti) for (i = 0; i < eti->n_cells; i++){ ETableCol *col = e_table_header_get_column (eti->header, i); - eti->cell_views [i] = e_cell_realize (col->ecell, eti->table_model, eti); + eti->cell_views [i] = e_cell_new_view (col->ecell, eti->table_model, eti); } + + eti_compute_height (eti); } /* * During unrealization: we invoke every e-cell (one per column in the current - * setup) to dispose all resources allocated + * setup) to dispose all X resources allocated */ static void eti_unrealize_cell_views (ETableItem *eti) { int i; - for (i = 0; i < eti->n_cells; i++){ + if (eti->cell_views_realized == 0) + return; + + for (i = 0; i < eti->n_cells; i++) e_cell_unrealize (eti->cell_views [i]); + eti->cell_views_realized = 0; +} + +static void +eti_detach_cell_views (ETableItem *eti) +{ + int i; + + for (i = 0; i < eti->n_cells; i++){ + e_cell_kill_view (eti->cell_views [i]); eti->cell_views [i] = NULL; } + g_free (eti->cell_views); eti->cell_views = NULL; eti->n_cells = 0; - } static void -eti_bounds (ETableItem *eti, double *x1, double *y1, double *x2, double *y2) +eti_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2) { double i2c [6]; ArtPoint c1, c2, i1, i2; - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti); + ETableItem *eti = E_TABLE_ITEM (item); gnome_canvas_item_i2c_affine (item, i2c); i1.x = eti->x1; @@ -126,12 +156,10 @@ eti_bounds (ETableItem *eti, double *x1, double *y1, double *x2, double *y2) static void eti_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags) { - ETableItem *eti = E_TABLE_ITEM (item); - if (GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->update) (*GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->update)(item, affine, clip_path, flags); - eti_bounds (eti, &item->x1, &item->y1, &item->x2, &item->y2); + eti_bounds (item, &item->x1, &item->y1, &item->x2, &item->y2); gnome_canvas_group_child_bounds (GNOME_CANVAS_GROUP (item->parent), item); } @@ -172,8 +200,14 @@ eti_remove_header_model (ETableItem *eti) eti->header_structure_change_id); gtk_signal_disconnect (GTK_OBJECT (eti->header), eti->header_dim_change_id); + + if (eti->cell_views){ + eti_unrealize_cell_views (eti); + eti_detach_cell_views (eti); + } gtk_object_unref (GTK_OBJECT (eti->header)); + eti->header_structure_change_id = 0; eti->header_dim_change_id = 0; eti->header = NULL; @@ -192,6 +226,8 @@ eti_row_height (ETableItem *eti, int row) int col; int h, max_h; + g_assert (eti->cell_views); + max_h = 0; for (col = 0; col < cols; col++){ @@ -395,7 +431,12 @@ eti_add_table_model (ETableItem *eti, ETableModel *table_model) eti->table_model_row_change_id = gtk_signal_connect ( GTK_OBJECT (table_model), "model_row_changed", GTK_SIGNAL_FUNC (eti_table_model_row_changed), eti); - + + if (eti->header){ + eti_detach_cell_views (eti); + eti_attach_cell_views (eti); + } + eti_table_model_changed (table_model, eti); } @@ -420,7 +461,14 @@ eti_header_structure_changed (ETableHeader *eth, ETableItem *eti) if (eti->cell_views){ eti_unrealize_cell_views (eti); + eti_detach_cell_views (eti); + eti_attach_cell_views (eti); eti_realize_cell_views (eti); + } else { + if (eti->table_model){ + eti_detach_cell_views (eti); + eti_attach_cell_views (eti); + } } eti_update (GNOME_CANVAS_ITEM (eti), NULL, NULL, 0); @@ -565,10 +613,10 @@ eti_realize (GnomeCanvasItem *item) gdk_gc_set_ts_origin (eti->focus_gc, 0, 0); gdk_gc_set_stipple (eti->focus_gc, eti->stipple); gdk_gc_set_fill (eti->focus_gc, GDK_OPAQUE_STIPPLED); + + if (eti->cell_views == NULL) + eti_attach_cell_views (eti); - /* - * - */ eti_realize_cell_views (eti); eti_compute_height (eti); diff --git a/widgets/e-table-item.h b/widgets/e-table-item.h index 0867a09d6b..f19819f2fc 100644 --- a/widgets/e-table-item.h +++ b/widgets/e-table-item.h @@ -38,6 +38,7 @@ typedef struct { unsigned int draw_focus:1; unsigned int mode_spreadsheet:1; unsigned int renderers_can_change_size:1; + unsigned int cell_views_realized:1; int focused_col, focused_row; diff --git a/widgets/e-table.c b/widgets/e-table.c index ff81866361..01389135bf 100644 --- a/widgets/e-table.c +++ b/widgets/e-table.c @@ -441,21 +441,10 @@ e_table_canvas_realize (GtkWidget *widget) "y", 0.0, NULL); - e_table->gen_header_width = e_table_header_total_width (e_table->header); - leaf = e_table_create_nodes ( e_table, e_table->model, e_table->header, GNOME_CANVAS_GROUP (e_table->root), 0, groups); - { - static int warn_shown; - - if (!warn_shown){ - g_warning ("Precompute the width, and update on model changes"); - warn_shown = 1; - } - } - gnome_canvas_set_scroll_region ( GNOME_CANVAS (e_table_canvas), 0, 0, diff --git a/widgets/e-table.h b/widgets/e-table.h index e2a5a3e9d5..63c131324f 100644 --- a/widgets/e-table.h +++ b/widgets/e-table.h @@ -30,11 +30,6 @@ typedef struct { guint spreadsheet:1; char *group_spec; - - /* - * Used during table generation - */ - int gen_header_width; } ETable; typedef struct { diff --git a/widgets/e-table/ChangeLog b/widgets/e-table/ChangeLog index f3eeb358b3..47e410e613 100644 --- a/widgets/e-table/ChangeLog +++ b/widgets/e-table/ChangeLog @@ -1,3 +1,24 @@ +1999-12-30 Miguel de Icaza <miguel@gnu.org> + + * e-table-item.c (eti_attach_cell_views): New routine, creates the + cell views. + (eti_detach_cell_views): Detaches the cell_views from the + ETableItem. + (eti_realize_cell_views, eti_unrealize_cell_views): Simplified to + just do realize/unrealize notification. + (eti_add_table_model): Only attach the cells when we have both the + table model and the header model. + + * e-cell.h (ECellClass): Added two new methods: new_view and + kill_view which drive the view process (instead of putting that on + realize/unrealize). + + * e-cell.c: Adapt the code to use the new scheme for view + instantiation. + + * e-cell-text.c, e-cell-toggle.c: Adapted to the new class + changes. + 1999-12-22 Miguel de Icaza <miguel@helixcode.com> * e-table-item.c (e_table_item_focus): grab focus here with the diff --git a/widgets/e-table/e-cell-text.c b/widgets/e-table/e-cell-text.c index 9d599f3d4c..1b2205ba51 100644 --- a/widgets/e-table/e-cell-text.c +++ b/widgets/e-table/e-cell-text.c @@ -38,7 +38,6 @@ typedef struct { GdkGC *gc; GdkFont *font; GnomeCanvas *canvas; - ETableItem *eti; /* * During edition. @@ -51,7 +50,9 @@ static ECellClass *parent_class; static void ect_queue_redraw (ECellTextView *text_view, int view_col, int view_row) { - e_table_item_redraw_range (text_view->eti, view_col, view_row, view_col, view_row); + e_table_item_redraw_range ( + text_view->cell_view.e_table_item_view, + view_col, view_row, view_col, view_row); } /* @@ -63,7 +64,7 @@ ect_accept_edits (ECellTextView *text_view) const char *text = gtk_entry_get_text (text_view->edit->entry); CellEdit *edit = text_view->edit; - e_table_model_set_value_at (text_view->cell_view.table_model, edit->model_col, edit->row, text); + e_table_model_set_value_at (text_view->cell_view.e_table_model, edit->model_col, edit->row, text); } /* @@ -84,7 +85,7 @@ ect_stop_editing (ECellTextView *text_view) text_view->edit = NULL; - e_table_item_leave_edit (text_view->eti); + e_table_item_leave_edit (text_view->cell_view.e_table_item_view); } /* @@ -98,20 +99,19 @@ ect_cancel_edit (ECellTextView *text_view) } /* - * ECell::realize method + * ECell::new_view method */ static ECellView * -ect_realize (ECell *ecell, ETableModel *table_model, void *view) +ect_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view) { ECellText *ect = E_CELL_TEXT (ecell); ECellTextView *text_view = g_new0 (ECellTextView, 1); - ETableItem *eti = E_TABLE_ITEM (view); - GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas; + GnomeCanvas *canvas = GNOME_CANVAS_ITEM (e_table_item_view)->canvas; text_view->cell_view.ecell = ecell; - text_view->cell_view.table_model = table_model; + text_view->cell_view.e_table_model = table_model; + text_view->cell_view.e_table_item_view = e_table_item_view; - text_view->gc = gdk_gc_new (GTK_WIDGET (canvas)->window); if (ect->font_name){ GdkFont *f; @@ -124,23 +124,19 @@ ect_realize (ECell *ecell, ETableModel *table_model, void *view) gdk_font_ref (text_view->font); } - text_view->eti = eti; text_view->canvas = canvas; return (ECellView *)text_view; } /* - * ECell::unrealize method + * ECell::kill_view method */ static void -ect_unrealize (ECellView *ecv) +ect_kill_view (ECellView *ecv) { ECellTextView *text_view = (ECellTextView *) ecv; - gdk_gc_unref (text_view->gc); - text_view->gc = NULL; - gdk_font_unref (text_view->font); text_view->font = NULL; @@ -148,6 +144,29 @@ ect_unrealize (ECellView *ecv) } /* + * ECell::realize method + */ +static void +ect_realize (ECellView *ecell_view) +{ + ECellTextView *text_view = (ECellTextView *) ecell_view; + + text_view->gc = gdk_gc_new (GTK_WIDGET (text_view->canvas)->window); +} + +/* + * ECell::unrealize method + */ +static void +ect_unrealize (ECellView *ecv) +{ + ECellTextView *text_view = (ECellTextView *) ecv; + + gdk_gc_unref (text_view->gc); + text_view->gc = NULL; +} + +/* * ECell::draw method */ static void @@ -159,7 +178,7 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable, ECellTextView *text_view = (ECellTextView *) ecell_view; GtkWidget *w = GTK_WIDGET (text_view->canvas); GdkRectangle rect; - const char *str = e_table_model_value_at (ecell_view->table_model, model_col, row); + const char *str = e_table_model_value_at (ecell_view->e_table_model, model_col, row); GdkFont *font = text_view->font; const int height = font->ascent + font->descent; int xoff; @@ -333,7 +352,7 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, if (text_view->edit){ printf ("FIXME: Should handle click here\n"); } else - e_table_item_enter_edit (text_view->eti, view_col, row); + e_table_item_enter_edit (text_view->cell_view.e_table_item_view, view_col, row); break; case GDK_BUTTON_RELEASE: @@ -351,7 +370,7 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, } if (!text_view->edit){ - e_table_item_enter_edit (text_view->eti, view_col, row); + e_table_item_enter_edit (text_view->cell_view.e_table_item_view, view_col, row); ect_edit_select_all (text_view); } @@ -385,7 +404,7 @@ ect_height (ECellView *ecell_view, int model_col, int view_col, int row) static void ect_entry_activate (GtkEntry *entry, ECellTextView *text_view) { - e_table_item_leave_edit (text_view->eti); + e_table_item_leave_edit (text_view->cell_view.e_table_item_view); } /* @@ -395,7 +414,7 @@ static void * ect_enter_edit (ECellView *ecell_view, int model_col, int view_col, int row) { ECellTextView *text_view = (ECellTextView *) ecell_view; - const char *str = e_table_model_value_at (ecell_view->table_model, model_col, row); + const char *str = e_table_model_value_at (ecell_view->e_table_model, model_col, row); CellEdit *edit; edit = g_new (CellEdit, 1); @@ -461,7 +480,9 @@ e_cell_text_class_init (GtkObjectClass *object_class) ECellClass *ecc = (ECellClass *) object_class; object_class->destroy = ect_destroy; - + + ecc->new_view = ect_new_view; + ecc->kill_view = ect_kill_view; ecc->realize = ect_realize; ecc->unrealize = ect_unrealize; ecc->draw = ect_draw; diff --git a/widgets/e-table/e-cell-toggle.c b/widgets/e-table/e-cell-toggle.c index dbe5fe5cbd..6ea181ea40 100644 --- a/widgets/e-table/e-cell-toggle.c +++ b/widgets/e-table/e-cell-toggle.c @@ -23,7 +23,6 @@ typedef struct { ECellView cell_view; GdkGC *gc; GnomeCanvas *canvas; - ETableItem *eti; } ECellToggleView; static ECellClass *parent_class; @@ -31,28 +30,43 @@ static ECellClass *parent_class; static void etog_queue_redraw (ECellToggleView *text_view, int view_col, int view_row) { - e_table_item_redraw_range (text_view->eti, view_col, view_row, view_col, view_row); + e_table_item_redraw_range ( + text_view->cell_view.e_table_item_view, + view_col, view_row, view_col, view_row); } /* * ECell::realize method */ static ECellView * -etog_realize (ECell *ecell, ETableModel *table_model, void *view) +etog_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view) { ECellToggleView *toggle_view = g_new0 (ECellToggleView, 1); - ETableItem *eti = E_TABLE_ITEM (view); + ETableItem *eti = E_TABLE_ITEM (e_table_item_view); GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas; toggle_view->cell_view.ecell = ecell; - toggle_view->cell_view.table_model = table_model; - toggle_view->eti = eti; + toggle_view->cell_view.e_table_model = table_model; + toggle_view->cell_view.e_table_item_view = e_table_item_view; toggle_view->canvas = canvas; - toggle_view->gc = gdk_gc_new (GTK_WIDGET (canvas)->window); return (ECellView *) toggle_view; } +static void +etog_kill_view (ECellView *ecell_view) +{ + g_free (ecell_view); +} + +static void +etog_realize (ECellView *ecell_view) +{ + ECellToggleView *toggle_view = (ECellToggleView *) ecell_view; + + toggle_view->gc = gdk_gc_new (GTK_WIDGET (toggle_view->canvas)->window); +} + /* * ECell::unrealize method */ @@ -63,8 +77,6 @@ etog_unrealize (ECellView *ecv) gdk_gc_unref (toggle_view->gc); toggle_view->gc = NULL; - - g_free (toggle_view); } /* @@ -81,7 +93,7 @@ etog_draw (ECellView *ecell_view, GdkDrawable *drawable, ArtPixBuf *art; int x, y, width, height; const int value = GPOINTER_TO_INT ( - e_table_model_value_at (ecell_view->table_model, model_col, row)); + e_table_model_value_at (ecell_view->e_table_model, model_col, row)); if (value >= toggle->n_states){ g_warning ("Value from the table model is %d, the states we support are [0..%d)\n", @@ -173,7 +185,7 @@ etog_set_value (ECellToggleView *toggle_view, int model_col, int view_col, int r if (value >= toggle->n_states) value = 0; - e_table_model_set_value_at (toggle_view->cell_view.table_model, + e_table_model_set_value_at (toggle_view->cell_view.e_table_model, model_col, row, GINT_TO_POINTER (value)); etog_queue_redraw (toggle_view, view_col, row); } @@ -185,7 +197,7 @@ static gint etog_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row) { ECellToggleView *toggle_view = (ECellToggleView *) ecell_view; - void *_value = e_table_model_value_at (ecell_view->table_model, model_col, row); + void *_value = e_table_model_value_at (ecell_view->e_table_model, model_col, row); const int value = GPOINTER_TO_INT (_value); switch (event->type){ @@ -237,7 +249,9 @@ e_cell_toggle_class_init (GtkObjectClass *object_class) ECellClass *ecc = (ECellClass *) object_class; object_class->destroy = etog_destroy; - + + ecc->new_view = etog_new_view; + ecc->kill_view = etog_kill_view; ecc->realize = etog_realize; ecc->unrealize = etog_unrealize; ecc->draw = etog_draw; diff --git a/widgets/e-table/e-cell.c b/widgets/e-table/e-cell.c index 4495bbb1a7..0f9297ecba 100644 --- a/widgets/e-table/e-cell.c +++ b/widgets/e-table/e-cell.c @@ -13,12 +13,22 @@ #define PARENT_TYPE gtk_object_get_type() static ECellView * -ec_realize (ECell *e_cell, ETableModel *table_model, void *view) +ec_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view) { return NULL; } static void +ec_realize (ECellView *e_cell) +{ +} + +static void +ec_kill_view (ECellView *ecell_view) +{ +} + +static void ec_unrealize (ECellView *e_cell) { } @@ -85,6 +95,8 @@ e_cell_class_init (GtkObjectClass *object_class) ecc->realize = ec_realize; ecc->unrealize = ec_unrealize; + ecc->new_view = ec_new_view; + ecc->kill_view = ec_kill_view; ecc->draw = ec_draw; ecc->event = ec_event; ecc->focus = ec_focus; @@ -110,10 +122,22 @@ e_cell_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_co } ECellView * -e_cell_realize (ECell *ecell, ETableModel *table_model, void *view) +e_cell_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view) +{ + return E_CELL_CLASS (GTK_OBJECT (ecell)->klass)->new_view ( + ecell, table_model, e_table_item_view); +} + +void +e_cell_view_realize (ECellView *ecell_view) +{ + return E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->realize (ecell_view); +} + +void +e_cell_kill_view (ECellView *ecell_view) { - return E_CELL_CLASS (GTK_OBJECT (ecell)->klass)->realize ( - ecell, table_model, view); + E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->kill_view (ecell_view); } void diff --git a/widgets/e-table/e-cell.h b/widgets/e-table/e-cell.h index 23173a586c..3c258689e4 100644 --- a/widgets/e-table/e-cell.h +++ b/widgets/e-table/e-cell.h @@ -19,7 +19,8 @@ struct _ECell { struct _ECellView { ECell *ecell; - ETableModel *table_model; + ETableModel *e_table_model; + void *e_table_item_view; gint focus_x1, focus_y1, focus_x2, focus_y2; gint focus_col, focus_row; @@ -29,9 +30,13 @@ struct _ECellView { typedef struct { GtkObjectClass parent_class; + + ECellView *(*new_view) (ECell *ecell, ETableModel *table_model, void *e_table_item_view); + void (*kill_view) (ECellView *ecell_view); + + void (*realize) (ECellView *ecell_view); + void (*unrealize) (ECellView *ecell_view); - ECellView *(*realize) (ECell *ecell, ETableModel *table_model, void *view); - void (*unrealize) (ECellView *e_cell_view); void (*draw) (ECellView *ecell_view, GdkDrawable *drawable, int model_col, int view_col, int row, gboolean selected, int x1, int y1, int x2, int y2); @@ -46,9 +51,14 @@ typedef struct { } ECellClass; GtkType e_cell_get_type (void); +ECellView *e_cell_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view); +void e_cell_kill_view (ECellView *ecell_view); + void e_cell_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row); -ECellView *e_cell_realize (ECell *ecell, ETableModel *table_model, void *view); + +void e_cell_realize (ECellView *ecell_view); void e_cell_unrealize (ECellView *ecell_view); + void e_cell_draw (ECellView *ecell_view, GdkDrawable *dr, int model_col, int view_col, int row, gboolean selected, int x1, int y1, int x2, int y2); diff --git a/widgets/e-table/e-table-item.c b/widgets/e-table/e-table-item.c index f9c5bc197d..33f0c18616 100644 --- a/widgets/e-table/e-table-item.c +++ b/widgets/e-table/e-table-item.c @@ -66,6 +66,21 @@ eti_realize_cell_views (ETableItem *eti) { int i; + for (i = 0; i < eti->n_cells; i++) + e_cell_view_realize (eti->cell_views [i], eti); + eti->cell_views_realized = 1; +} + +static void eti_compute_height (ETableItem *eti); + +static void +eti_attach_cell_views (ETableItem *eti) +{ + int i; + + g_assert (eti->header); + g_assert (eti->table_model); + /* * Now realize the various ECells */ @@ -75,35 +90,50 @@ eti_realize_cell_views (ETableItem *eti) for (i = 0; i < eti->n_cells; i++){ ETableCol *col = e_table_header_get_column (eti->header, i); - eti->cell_views [i] = e_cell_realize (col->ecell, eti->table_model, eti); + eti->cell_views [i] = e_cell_new_view (col->ecell, eti->table_model, eti); } + + eti_compute_height (eti); } /* * During unrealization: we invoke every e-cell (one per column in the current - * setup) to dispose all resources allocated + * setup) to dispose all X resources allocated */ static void eti_unrealize_cell_views (ETableItem *eti) { int i; - for (i = 0; i < eti->n_cells; i++){ + if (eti->cell_views_realized == 0) + return; + + for (i = 0; i < eti->n_cells; i++) e_cell_unrealize (eti->cell_views [i]); + eti->cell_views_realized = 0; +} + +static void +eti_detach_cell_views (ETableItem *eti) +{ + int i; + + for (i = 0; i < eti->n_cells; i++){ + e_cell_kill_view (eti->cell_views [i]); eti->cell_views [i] = NULL; } + g_free (eti->cell_views); eti->cell_views = NULL; eti->n_cells = 0; - } static void -eti_bounds (ETableItem *eti, double *x1, double *y1, double *x2, double *y2) +eti_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2) { double i2c [6]; ArtPoint c1, c2, i1, i2; - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti); + ETableItem *eti = E_TABLE_ITEM (item); gnome_canvas_item_i2c_affine (item, i2c); i1.x = eti->x1; @@ -126,12 +156,10 @@ eti_bounds (ETableItem *eti, double *x1, double *y1, double *x2, double *y2) static void eti_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags) { - ETableItem *eti = E_TABLE_ITEM (item); - if (GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->update) (*GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->update)(item, affine, clip_path, flags); - eti_bounds (eti, &item->x1, &item->y1, &item->x2, &item->y2); + eti_bounds (item, &item->x1, &item->y1, &item->x2, &item->y2); gnome_canvas_group_child_bounds (GNOME_CANVAS_GROUP (item->parent), item); } @@ -172,8 +200,14 @@ eti_remove_header_model (ETableItem *eti) eti->header_structure_change_id); gtk_signal_disconnect (GTK_OBJECT (eti->header), eti->header_dim_change_id); + + if (eti->cell_views){ + eti_unrealize_cell_views (eti); + eti_detach_cell_views (eti); + } gtk_object_unref (GTK_OBJECT (eti->header)); + eti->header_structure_change_id = 0; eti->header_dim_change_id = 0; eti->header = NULL; @@ -192,6 +226,8 @@ eti_row_height (ETableItem *eti, int row) int col; int h, max_h; + g_assert (eti->cell_views); + max_h = 0; for (col = 0; col < cols; col++){ @@ -395,7 +431,12 @@ eti_add_table_model (ETableItem *eti, ETableModel *table_model) eti->table_model_row_change_id = gtk_signal_connect ( GTK_OBJECT (table_model), "model_row_changed", GTK_SIGNAL_FUNC (eti_table_model_row_changed), eti); - + + if (eti->header){ + eti_detach_cell_views (eti); + eti_attach_cell_views (eti); + } + eti_table_model_changed (table_model, eti); } @@ -420,7 +461,14 @@ eti_header_structure_changed (ETableHeader *eth, ETableItem *eti) if (eti->cell_views){ eti_unrealize_cell_views (eti); + eti_detach_cell_views (eti); + eti_attach_cell_views (eti); eti_realize_cell_views (eti); + } else { + if (eti->table_model){ + eti_detach_cell_views (eti); + eti_attach_cell_views (eti); + } } eti_update (GNOME_CANVAS_ITEM (eti), NULL, NULL, 0); @@ -565,10 +613,10 @@ eti_realize (GnomeCanvasItem *item) gdk_gc_set_ts_origin (eti->focus_gc, 0, 0); gdk_gc_set_stipple (eti->focus_gc, eti->stipple); gdk_gc_set_fill (eti->focus_gc, GDK_OPAQUE_STIPPLED); + + if (eti->cell_views == NULL) + eti_attach_cell_views (eti); - /* - * - */ eti_realize_cell_views (eti); eti_compute_height (eti); diff --git a/widgets/e-table/e-table-item.h b/widgets/e-table/e-table-item.h index 0867a09d6b..f19819f2fc 100644 --- a/widgets/e-table/e-table-item.h +++ b/widgets/e-table/e-table-item.h @@ -38,6 +38,7 @@ typedef struct { unsigned int draw_focus:1; unsigned int mode_spreadsheet:1; unsigned int renderers_can_change_size:1; + unsigned int cell_views_realized:1; int focused_col, focused_row; diff --git a/widgets/e-table/e-table.c b/widgets/e-table/e-table.c index ff81866361..01389135bf 100644 --- a/widgets/e-table/e-table.c +++ b/widgets/e-table/e-table.c @@ -441,21 +441,10 @@ e_table_canvas_realize (GtkWidget *widget) "y", 0.0, NULL); - e_table->gen_header_width = e_table_header_total_width (e_table->header); - leaf = e_table_create_nodes ( e_table, e_table->model, e_table->header, GNOME_CANVAS_GROUP (e_table->root), 0, groups); - { - static int warn_shown; - - if (!warn_shown){ - g_warning ("Precompute the width, and update on model changes"); - warn_shown = 1; - } - } - gnome_canvas_set_scroll_region ( GNOME_CANVAS (e_table_canvas), 0, 0, diff --git a/widgets/e-table/e-table.h b/widgets/e-table/e-table.h index e2a5a3e9d5..63c131324f 100644 --- a/widgets/e-table/e-table.h +++ b/widgets/e-table/e-table.h @@ -30,11 +30,6 @@ typedef struct { guint spreadsheet:1; char *group_spec; - - /* - * Used during table generation - */ - int gen_header_width; } ETable; typedef struct { diff --git a/widgets/table/e-cell-text.c b/widgets/table/e-cell-text.c index 9d599f3d4c..1b2205ba51 100644 --- a/widgets/table/e-cell-text.c +++ b/widgets/table/e-cell-text.c @@ -38,7 +38,6 @@ typedef struct { GdkGC *gc; GdkFont *font; GnomeCanvas *canvas; - ETableItem *eti; /* * During edition. @@ -51,7 +50,9 @@ static ECellClass *parent_class; static void ect_queue_redraw (ECellTextView *text_view, int view_col, int view_row) { - e_table_item_redraw_range (text_view->eti, view_col, view_row, view_col, view_row); + e_table_item_redraw_range ( + text_view->cell_view.e_table_item_view, + view_col, view_row, view_col, view_row); } /* @@ -63,7 +64,7 @@ ect_accept_edits (ECellTextView *text_view) const char *text = gtk_entry_get_text (text_view->edit->entry); CellEdit *edit = text_view->edit; - e_table_model_set_value_at (text_view->cell_view.table_model, edit->model_col, edit->row, text); + e_table_model_set_value_at (text_view->cell_view.e_table_model, edit->model_col, edit->row, text); } /* @@ -84,7 +85,7 @@ ect_stop_editing (ECellTextView *text_view) text_view->edit = NULL; - e_table_item_leave_edit (text_view->eti); + e_table_item_leave_edit (text_view->cell_view.e_table_item_view); } /* @@ -98,20 +99,19 @@ ect_cancel_edit (ECellTextView *text_view) } /* - * ECell::realize method + * ECell::new_view method */ static ECellView * -ect_realize (ECell *ecell, ETableModel *table_model, void *view) +ect_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view) { ECellText *ect = E_CELL_TEXT (ecell); ECellTextView *text_view = g_new0 (ECellTextView, 1); - ETableItem *eti = E_TABLE_ITEM (view); - GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas; + GnomeCanvas *canvas = GNOME_CANVAS_ITEM (e_table_item_view)->canvas; text_view->cell_view.ecell = ecell; - text_view->cell_view.table_model = table_model; + text_view->cell_view.e_table_model = table_model; + text_view->cell_view.e_table_item_view = e_table_item_view; - text_view->gc = gdk_gc_new (GTK_WIDGET (canvas)->window); if (ect->font_name){ GdkFont *f; @@ -124,23 +124,19 @@ ect_realize (ECell *ecell, ETableModel *table_model, void *view) gdk_font_ref (text_view->font); } - text_view->eti = eti; text_view->canvas = canvas; return (ECellView *)text_view; } /* - * ECell::unrealize method + * ECell::kill_view method */ static void -ect_unrealize (ECellView *ecv) +ect_kill_view (ECellView *ecv) { ECellTextView *text_view = (ECellTextView *) ecv; - gdk_gc_unref (text_view->gc); - text_view->gc = NULL; - gdk_font_unref (text_view->font); text_view->font = NULL; @@ -148,6 +144,29 @@ ect_unrealize (ECellView *ecv) } /* + * ECell::realize method + */ +static void +ect_realize (ECellView *ecell_view) +{ + ECellTextView *text_view = (ECellTextView *) ecell_view; + + text_view->gc = gdk_gc_new (GTK_WIDGET (text_view->canvas)->window); +} + +/* + * ECell::unrealize method + */ +static void +ect_unrealize (ECellView *ecv) +{ + ECellTextView *text_view = (ECellTextView *) ecv; + + gdk_gc_unref (text_view->gc); + text_view->gc = NULL; +} + +/* * ECell::draw method */ static void @@ -159,7 +178,7 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable, ECellTextView *text_view = (ECellTextView *) ecell_view; GtkWidget *w = GTK_WIDGET (text_view->canvas); GdkRectangle rect; - const char *str = e_table_model_value_at (ecell_view->table_model, model_col, row); + const char *str = e_table_model_value_at (ecell_view->e_table_model, model_col, row); GdkFont *font = text_view->font; const int height = font->ascent + font->descent; int xoff; @@ -333,7 +352,7 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, if (text_view->edit){ printf ("FIXME: Should handle click here\n"); } else - e_table_item_enter_edit (text_view->eti, view_col, row); + e_table_item_enter_edit (text_view->cell_view.e_table_item_view, view_col, row); break; case GDK_BUTTON_RELEASE: @@ -351,7 +370,7 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, } if (!text_view->edit){ - e_table_item_enter_edit (text_view->eti, view_col, row); + e_table_item_enter_edit (text_view->cell_view.e_table_item_view, view_col, row); ect_edit_select_all (text_view); } @@ -385,7 +404,7 @@ ect_height (ECellView *ecell_view, int model_col, int view_col, int row) static void ect_entry_activate (GtkEntry *entry, ECellTextView *text_view) { - e_table_item_leave_edit (text_view->eti); + e_table_item_leave_edit (text_view->cell_view.e_table_item_view); } /* @@ -395,7 +414,7 @@ static void * ect_enter_edit (ECellView *ecell_view, int model_col, int view_col, int row) { ECellTextView *text_view = (ECellTextView *) ecell_view; - const char *str = e_table_model_value_at (ecell_view->table_model, model_col, row); + const char *str = e_table_model_value_at (ecell_view->e_table_model, model_col, row); CellEdit *edit; edit = g_new (CellEdit, 1); @@ -461,7 +480,9 @@ e_cell_text_class_init (GtkObjectClass *object_class) ECellClass *ecc = (ECellClass *) object_class; object_class->destroy = ect_destroy; - + + ecc->new_view = ect_new_view; + ecc->kill_view = ect_kill_view; ecc->realize = ect_realize; ecc->unrealize = ect_unrealize; ecc->draw = ect_draw; diff --git a/widgets/table/e-cell-toggle.c b/widgets/table/e-cell-toggle.c index dbe5fe5cbd..6ea181ea40 100644 --- a/widgets/table/e-cell-toggle.c +++ b/widgets/table/e-cell-toggle.c @@ -23,7 +23,6 @@ typedef struct { ECellView cell_view; GdkGC *gc; GnomeCanvas *canvas; - ETableItem *eti; } ECellToggleView; static ECellClass *parent_class; @@ -31,28 +30,43 @@ static ECellClass *parent_class; static void etog_queue_redraw (ECellToggleView *text_view, int view_col, int view_row) { - e_table_item_redraw_range (text_view->eti, view_col, view_row, view_col, view_row); + e_table_item_redraw_range ( + text_view->cell_view.e_table_item_view, + view_col, view_row, view_col, view_row); } /* * ECell::realize method */ static ECellView * -etog_realize (ECell *ecell, ETableModel *table_model, void *view) +etog_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view) { ECellToggleView *toggle_view = g_new0 (ECellToggleView, 1); - ETableItem *eti = E_TABLE_ITEM (view); + ETableItem *eti = E_TABLE_ITEM (e_table_item_view); GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas; toggle_view->cell_view.ecell = ecell; - toggle_view->cell_view.table_model = table_model; - toggle_view->eti = eti; + toggle_view->cell_view.e_table_model = table_model; + toggle_view->cell_view.e_table_item_view = e_table_item_view; toggle_view->canvas = canvas; - toggle_view->gc = gdk_gc_new (GTK_WIDGET (canvas)->window); return (ECellView *) toggle_view; } +static void +etog_kill_view (ECellView *ecell_view) +{ + g_free (ecell_view); +} + +static void +etog_realize (ECellView *ecell_view) +{ + ECellToggleView *toggle_view = (ECellToggleView *) ecell_view; + + toggle_view->gc = gdk_gc_new (GTK_WIDGET (toggle_view->canvas)->window); +} + /* * ECell::unrealize method */ @@ -63,8 +77,6 @@ etog_unrealize (ECellView *ecv) gdk_gc_unref (toggle_view->gc); toggle_view->gc = NULL; - - g_free (toggle_view); } /* @@ -81,7 +93,7 @@ etog_draw (ECellView *ecell_view, GdkDrawable *drawable, ArtPixBuf *art; int x, y, width, height; const int value = GPOINTER_TO_INT ( - e_table_model_value_at (ecell_view->table_model, model_col, row)); + e_table_model_value_at (ecell_view->e_table_model, model_col, row)); if (value >= toggle->n_states){ g_warning ("Value from the table model is %d, the states we support are [0..%d)\n", @@ -173,7 +185,7 @@ etog_set_value (ECellToggleView *toggle_view, int model_col, int view_col, int r if (value >= toggle->n_states) value = 0; - e_table_model_set_value_at (toggle_view->cell_view.table_model, + e_table_model_set_value_at (toggle_view->cell_view.e_table_model, model_col, row, GINT_TO_POINTER (value)); etog_queue_redraw (toggle_view, view_col, row); } @@ -185,7 +197,7 @@ static gint etog_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row) { ECellToggleView *toggle_view = (ECellToggleView *) ecell_view; - void *_value = e_table_model_value_at (ecell_view->table_model, model_col, row); + void *_value = e_table_model_value_at (ecell_view->e_table_model, model_col, row); const int value = GPOINTER_TO_INT (_value); switch (event->type){ @@ -237,7 +249,9 @@ e_cell_toggle_class_init (GtkObjectClass *object_class) ECellClass *ecc = (ECellClass *) object_class; object_class->destroy = etog_destroy; - + + ecc->new_view = etog_new_view; + ecc->kill_view = etog_kill_view; ecc->realize = etog_realize; ecc->unrealize = etog_unrealize; ecc->draw = etog_draw; diff --git a/widgets/table/e-cell.c b/widgets/table/e-cell.c index 4495bbb1a7..0f9297ecba 100644 --- a/widgets/table/e-cell.c +++ b/widgets/table/e-cell.c @@ -13,12 +13,22 @@ #define PARENT_TYPE gtk_object_get_type() static ECellView * -ec_realize (ECell *e_cell, ETableModel *table_model, void *view) +ec_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view) { return NULL; } static void +ec_realize (ECellView *e_cell) +{ +} + +static void +ec_kill_view (ECellView *ecell_view) +{ +} + +static void ec_unrealize (ECellView *e_cell) { } @@ -85,6 +95,8 @@ e_cell_class_init (GtkObjectClass *object_class) ecc->realize = ec_realize; ecc->unrealize = ec_unrealize; + ecc->new_view = ec_new_view; + ecc->kill_view = ec_kill_view; ecc->draw = ec_draw; ecc->event = ec_event; ecc->focus = ec_focus; @@ -110,10 +122,22 @@ e_cell_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_co } ECellView * -e_cell_realize (ECell *ecell, ETableModel *table_model, void *view) +e_cell_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view) +{ + return E_CELL_CLASS (GTK_OBJECT (ecell)->klass)->new_view ( + ecell, table_model, e_table_item_view); +} + +void +e_cell_view_realize (ECellView *ecell_view) +{ + return E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->realize (ecell_view); +} + +void +e_cell_kill_view (ECellView *ecell_view) { - return E_CELL_CLASS (GTK_OBJECT (ecell)->klass)->realize ( - ecell, table_model, view); + E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->kill_view (ecell_view); } void diff --git a/widgets/table/e-cell.h b/widgets/table/e-cell.h index 23173a586c..3c258689e4 100644 --- a/widgets/table/e-cell.h +++ b/widgets/table/e-cell.h @@ -19,7 +19,8 @@ struct _ECell { struct _ECellView { ECell *ecell; - ETableModel *table_model; + ETableModel *e_table_model; + void *e_table_item_view; gint focus_x1, focus_y1, focus_x2, focus_y2; gint focus_col, focus_row; @@ -29,9 +30,13 @@ struct _ECellView { typedef struct { GtkObjectClass parent_class; + + ECellView *(*new_view) (ECell *ecell, ETableModel *table_model, void *e_table_item_view); + void (*kill_view) (ECellView *ecell_view); + + void (*realize) (ECellView *ecell_view); + void (*unrealize) (ECellView *ecell_view); - ECellView *(*realize) (ECell *ecell, ETableModel *table_model, void *view); - void (*unrealize) (ECellView *e_cell_view); void (*draw) (ECellView *ecell_view, GdkDrawable *drawable, int model_col, int view_col, int row, gboolean selected, int x1, int y1, int x2, int y2); @@ -46,9 +51,14 @@ typedef struct { } ECellClass; GtkType e_cell_get_type (void); +ECellView *e_cell_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view); +void e_cell_kill_view (ECellView *ecell_view); + void e_cell_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row); -ECellView *e_cell_realize (ECell *ecell, ETableModel *table_model, void *view); + +void e_cell_realize (ECellView *ecell_view); void e_cell_unrealize (ECellView *ecell_view); + void e_cell_draw (ECellView *ecell_view, GdkDrawable *dr, int model_col, int view_col, int row, gboolean selected, int x1, int y1, int x2, int y2); diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c index f9c5bc197d..33f0c18616 100644 --- a/widgets/table/e-table-item.c +++ b/widgets/table/e-table-item.c @@ -66,6 +66,21 @@ eti_realize_cell_views (ETableItem *eti) { int i; + for (i = 0; i < eti->n_cells; i++) + e_cell_view_realize (eti->cell_views [i], eti); + eti->cell_views_realized = 1; +} + +static void eti_compute_height (ETableItem *eti); + +static void +eti_attach_cell_views (ETableItem *eti) +{ + int i; + + g_assert (eti->header); + g_assert (eti->table_model); + /* * Now realize the various ECells */ @@ -75,35 +90,50 @@ eti_realize_cell_views (ETableItem *eti) for (i = 0; i < eti->n_cells; i++){ ETableCol *col = e_table_header_get_column (eti->header, i); - eti->cell_views [i] = e_cell_realize (col->ecell, eti->table_model, eti); + eti->cell_views [i] = e_cell_new_view (col->ecell, eti->table_model, eti); } + + eti_compute_height (eti); } /* * During unrealization: we invoke every e-cell (one per column in the current - * setup) to dispose all resources allocated + * setup) to dispose all X resources allocated */ static void eti_unrealize_cell_views (ETableItem *eti) { int i; - for (i = 0; i < eti->n_cells; i++){ + if (eti->cell_views_realized == 0) + return; + + for (i = 0; i < eti->n_cells; i++) e_cell_unrealize (eti->cell_views [i]); + eti->cell_views_realized = 0; +} + +static void +eti_detach_cell_views (ETableItem *eti) +{ + int i; + + for (i = 0; i < eti->n_cells; i++){ + e_cell_kill_view (eti->cell_views [i]); eti->cell_views [i] = NULL; } + g_free (eti->cell_views); eti->cell_views = NULL; eti->n_cells = 0; - } static void -eti_bounds (ETableItem *eti, double *x1, double *y1, double *x2, double *y2) +eti_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2) { double i2c [6]; ArtPoint c1, c2, i1, i2; - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti); + ETableItem *eti = E_TABLE_ITEM (item); gnome_canvas_item_i2c_affine (item, i2c); i1.x = eti->x1; @@ -126,12 +156,10 @@ eti_bounds (ETableItem *eti, double *x1, double *y1, double *x2, double *y2) static void eti_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags) { - ETableItem *eti = E_TABLE_ITEM (item); - if (GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->update) (*GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->update)(item, affine, clip_path, flags); - eti_bounds (eti, &item->x1, &item->y1, &item->x2, &item->y2); + eti_bounds (item, &item->x1, &item->y1, &item->x2, &item->y2); gnome_canvas_group_child_bounds (GNOME_CANVAS_GROUP (item->parent), item); } @@ -172,8 +200,14 @@ eti_remove_header_model (ETableItem *eti) eti->header_structure_change_id); gtk_signal_disconnect (GTK_OBJECT (eti->header), eti->header_dim_change_id); + + if (eti->cell_views){ + eti_unrealize_cell_views (eti); + eti_detach_cell_views (eti); + } gtk_object_unref (GTK_OBJECT (eti->header)); + eti->header_structure_change_id = 0; eti->header_dim_change_id = 0; eti->header = NULL; @@ -192,6 +226,8 @@ eti_row_height (ETableItem *eti, int row) int col; int h, max_h; + g_assert (eti->cell_views); + max_h = 0; for (col = 0; col < cols; col++){ @@ -395,7 +431,12 @@ eti_add_table_model (ETableItem *eti, ETableModel *table_model) eti->table_model_row_change_id = gtk_signal_connect ( GTK_OBJECT (table_model), "model_row_changed", GTK_SIGNAL_FUNC (eti_table_model_row_changed), eti); - + + if (eti->header){ + eti_detach_cell_views (eti); + eti_attach_cell_views (eti); + } + eti_table_model_changed (table_model, eti); } @@ -420,7 +461,14 @@ eti_header_structure_changed (ETableHeader *eth, ETableItem *eti) if (eti->cell_views){ eti_unrealize_cell_views (eti); + eti_detach_cell_views (eti); + eti_attach_cell_views (eti); eti_realize_cell_views (eti); + } else { + if (eti->table_model){ + eti_detach_cell_views (eti); + eti_attach_cell_views (eti); + } } eti_update (GNOME_CANVAS_ITEM (eti), NULL, NULL, 0); @@ -565,10 +613,10 @@ eti_realize (GnomeCanvasItem *item) gdk_gc_set_ts_origin (eti->focus_gc, 0, 0); gdk_gc_set_stipple (eti->focus_gc, eti->stipple); gdk_gc_set_fill (eti->focus_gc, GDK_OPAQUE_STIPPLED); + + if (eti->cell_views == NULL) + eti_attach_cell_views (eti); - /* - * - */ eti_realize_cell_views (eti); eti_compute_height (eti); diff --git a/widgets/table/e-table-item.h b/widgets/table/e-table-item.h index 0867a09d6b..f19819f2fc 100644 --- a/widgets/table/e-table-item.h +++ b/widgets/table/e-table-item.h @@ -38,6 +38,7 @@ typedef struct { unsigned int draw_focus:1; unsigned int mode_spreadsheet:1; unsigned int renderers_can_change_size:1; + unsigned int cell_views_realized:1; int focused_col, focused_row; diff --git a/widgets/table/e-table.c b/widgets/table/e-table.c index ff81866361..01389135bf 100644 --- a/widgets/table/e-table.c +++ b/widgets/table/e-table.c @@ -441,21 +441,10 @@ e_table_canvas_realize (GtkWidget *widget) "y", 0.0, NULL); - e_table->gen_header_width = e_table_header_total_width (e_table->header); - leaf = e_table_create_nodes ( e_table, e_table->model, e_table->header, GNOME_CANVAS_GROUP (e_table->root), 0, groups); - { - static int warn_shown; - - if (!warn_shown){ - g_warning ("Precompute the width, and update on model changes"); - warn_shown = 1; - } - } - gnome_canvas_set_scroll_region ( GNOME_CANVAS (e_table_canvas), 0, 0, diff --git a/widgets/table/e-table.h b/widgets/table/e-table.h index e2a5a3e9d5..63c131324f 100644 --- a/widgets/table/e-table.h +++ b/widgets/table/e-table.h @@ -30,11 +30,6 @@ typedef struct { guint spreadsheet:1; char *group_spec; - - /* - * Used during table generation - */ - int gen_header_width; } ETable; typedef struct { |