aboutsummaryrefslogtreecommitdiffstats
path: root/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'widgets')
-rw-r--r--widgets/ChangeLog19
-rw-r--r--widgets/Makefile.am2
-rw-r--r--widgets/ROADMAP.e-table19
-rw-r--r--widgets/e-cell-text.c139
-rw-r--r--widgets/e-cell-text.h9
-rw-r--r--widgets/e-cell.c71
-rw-r--r--widgets/e-cell.h38
-rw-r--r--widgets/e-table-col.c7
-rw-r--r--widgets/e-table-col.h17
-rw-r--r--widgets/e-table-header-item.c39
-rw-r--r--widgets/e-table-header-item.h5
-rw-r--r--widgets/e-table-item.c80
-rw-r--r--widgets/e-table-item.h7
-rw-r--r--widgets/e-table-model.c35
-rw-r--r--widgets/e-table-model.h9
-rw-r--r--widgets/e-table-simple.c4
-rw-r--r--widgets/e-table-sorted.c137
-rw-r--r--widgets/e-table-sorted.h19
-rw-r--r--widgets/e-table-subset.c114
-rw-r--r--widgets/e-table-subset.h12
-rw-r--r--widgets/e-table.c26
-rw-r--r--widgets/e-table/ChangeLog19
-rw-r--r--widgets/e-table/Makefile.am2
-rw-r--r--widgets/e-table/ROADMAP.e-table19
-rw-r--r--widgets/e-table/e-cell-text.c139
-rw-r--r--widgets/e-table/e-cell-text.h9
-rw-r--r--widgets/e-table/e-cell.c71
-rw-r--r--widgets/e-table/e-cell.h38
-rw-r--r--widgets/e-table/e-table-col.c7
-rw-r--r--widgets/e-table/e-table-col.h17
-rw-r--r--widgets/e-table/e-table-header-item.c39
-rw-r--r--widgets/e-table/e-table-header-item.h5
-rw-r--r--widgets/e-table/e-table-item.c80
-rw-r--r--widgets/e-table/e-table-item.h7
-rw-r--r--widgets/e-table/e-table-model.c35
-rw-r--r--widgets/e-table/e-table-model.h9
-rw-r--r--widgets/e-table/e-table-simple.c4
-rw-r--r--widgets/e-table/e-table-sorted.c137
-rw-r--r--widgets/e-table/e-table-sorted.h19
-rw-r--r--widgets/e-table/e-table-subset.c114
-rw-r--r--widgets/e-table/e-table-subset.h12
-rw-r--r--widgets/e-table/e-table.c26
-rw-r--r--widgets/e-table/table-test.c8
-rw-r--r--widgets/table-test.c8
-rw-r--r--widgets/table/e-cell-text.c139
-rw-r--r--widgets/table/e-cell-text.h9
-rw-r--r--widgets/table/e-cell.c71
-rw-r--r--widgets/table/e-cell.h38
-rw-r--r--widgets/table/e-table-col.c7
-rw-r--r--widgets/table/e-table-col.h17
-rw-r--r--widgets/table/e-table-header-item.c39
-rw-r--r--widgets/table/e-table-header-item.h5
-rw-r--r--widgets/table/e-table-item.c80
-rw-r--r--widgets/table/e-table-item.h7
-rw-r--r--widgets/table/e-table-model.c35
-rw-r--r--widgets/table/e-table-model.h9
-rw-r--r--widgets/table/e-table-simple.c4
-rw-r--r--widgets/table/e-table-sorted.c137
-rw-r--r--widgets/table/e-table-sorted.h19
-rw-r--r--widgets/table/e-table-subset.c114
-rw-r--r--widgets/table/e-table-subset.h12
-rw-r--r--widgets/table/e-table.c26
-rw-r--r--widgets/table/table-test.c8
63 files changed, 1713 insertions, 695 deletions
diff --git a/widgets/ChangeLog b/widgets/ChangeLog
index 188b1ff00c..973eb5d189 100644
--- a/widgets/ChangeLog
+++ b/widgets/ChangeLog
@@ -1,3 +1,22 @@
+1999-11-25 Miguel de Icaza <miguel@gnu.org>
+
+ * e-table-header-item.c (ethi_realize): Realize cells.
+
+ * e-table-item.c (eti_header_dim_changed): redraw before and after.
+
+ * e-table-header-item.c (ethi_event): Add continuous resizing.
+
+1999-11-24 Miguel de Icaza <miguel@gnu.org>
+
+ * e-table-subset.h, e-table-subset.c: New files, used to implement
+ subset tables.
+
+ * e-table-sorted.h, e-table-sorted.c: Now they derive from
+ e-table-subset.
+
+ * e-cell.c, e-cell.h: realize method now return per view instance
+ data.
+
1999-11-20 Miguel de Icaza <miguel@gnu.org>
* e-table-item.c (eti_draw): WOOOOHOOOOOoO! It took me quite a
diff --git a/widgets/Makefile.am b/widgets/Makefile.am
index ac2858025c..d9748531d5 100644
--- a/widgets/Makefile.am
+++ b/widgets/Makefile.am
@@ -25,8 +25,6 @@ libevolutionwidgets_a_SOURCES = \
e-table-item.h \
e-table-model.c \
e-table-model.h \
- e-table-render.c \
- e-table-render.h \
e-table-simple.c \
e-table-simple.h \
e-table-sorted.c \
diff --git a/widgets/ROADMAP.e-table b/widgets/ROADMAP.e-table
index 88afe506c3..65f19dabe1 100644
--- a/widgets/ROADMAP.e-table
+++ b/widgets/ROADMAP.e-table
@@ -29,14 +29,6 @@ e-table-simple.h, e-table-simple.c:
routines (you provide the callbacks). For lazy people, like
me.
-e-table-header.h, e-table-header.c:
-
- These implement the ETableHeader model. They describe what
- columns are shown in the screen and in which order.
-
- These emit signals: column-size-changed and structure-changed
- (if a column is added/removed)
-
e-cell.c, e-cell.h:
These are actually miss-named. Objects of type e-cell know
@@ -60,6 +52,17 @@ e-table-col.h, e-table-col.c:
* The Views
+e-table-header.h, e-table-header.c:
+
+ These implement the ETableHeaderItem canvas item. This item is
+ used both to control the columns displayed as well as displaying them.
+
+ They describe what columns are shown in the screen and in
+ which order.
+
+ These emit signals: column-size-changed and structure-changed
+ (if a column is added/removed)
+
e-table-item.c, e-table-item.h
This is a canvas item that renders the contents of a
diff --git a/widgets/e-cell-text.c b/widgets/e-cell-text.c
index c30e42cfd3..1b3f524a2e 100644
--- a/widgets/e-cell-text.c
+++ b/widgets/e-cell-text.c
@@ -7,42 +7,157 @@
* (C) 1999 Helix Code, Inc
*/
#include <config.h>
+#include <gtk/gtkenums.h>
#include "e-cell-text.h"
#include "e-util.h"
-#define PARENT_TYPE gtk_object_get_type()
+#define PARENT_TYPE e_cell_get_type()
+
+typedef struct {
+ ECellView cell_view;
+ GdkGC *gc;
+ GdkFont *font;
+ GnomeCanvas *canvas;
+} ECellTextView;
+
+static ECellClass *parent_class;
+
+static ECellView *
+ect_realize (ECell *ecell, GnomeCanvas *canvas)
+{
+ ECellText *ect = E_CELL_TEXT (ecell);
+ ECellTextView *ectv = g_new (ECellTextView, 1);
+
+ ectv->cell_view.ecell = ecell;
+ ectv->gc = gdk_gc_new (GTK_WIDGET (canvas)->window);
+ ectv->font = gdk_fontset_load (ect->font_name ? ect->font_name : "fixed");
+ ectv->canvas = canvas;
+
+ return (ECellView *)ectv;
+}
static void
-ec_realize (ECell *e_cell, GnomeCanvas *canvas)
+ect_unrealize (ECellView *ecv)
{
+ ECellTextView *ectv = (ECellTextView *) ecv;
+
+ gdk_gc_unref (ectv->gc);
+ ectv->gc = NULL;
+
+ gdk_font_unref (ectv->font);
+ ectv->font = NULL;
+
+ g_free (ectv);
}
static void
-ec_unrealize (ECell *e_cell)
+ect_draw (ECellView *ecell_view, GdkDrawable *drawable, int col, int row, int x1, int y1, int x2, int y2)
{
+ ECellText *ect = E_CELL_TEXT (ecell_view->ecell);
+ GdkRectangle rect;
+ const char *str = e_table_model_value_at (ecell_view->ecell->table_model, col, row);
+ int selected = e_table_model_get_selected_row (ecell_view->ecell->table_model) == row;
+ int xoff, w;
+
+ rect.x = x1;
+ rect.y = y1;
+ rect.width = x2 - x1;
+ rect.height = y2 - y1;
+
+ gdk_gc_set_clip_rectangle (ect->gc, &rect);
+
+ switch (ect->justify){
+ case GTK_JUSTIFY_LEFT:
+ xoff = 1;
+ break;
+
+ case GTK_JUSTIFY_RIGHT:
+ w = 1 + gdk_text_width (ect->font, str, strlen (str));
+ xoff = (x2 - x1) - w;
+ break;
+
+ case GTK_JUSTIFY_CENTER:
+ xoff = ((x2 - x1) - gdk_text_width (ect->font, str, strlen (str))) / 2;
+ break;
+ default:
+ g_warning ("Can not handle GTK_JUSTIFY_FILL");
+ break;
+ }
+
+ /* Draw now */
+ {
+ GtkWidget *w = GTK_WIDGET (ect->canvas);
+ GdkColor *background;
+ int idx;
+
+ if (selected)
+ idx = GTK_STATE_SELECTED;
+ else
+ idx = GTK_STATE_NORMAL;
+
+ gdk_gc_set_foreground (ect->gc, &w->style->bg [idx]);
+ gdk_draw_rectangle (drawable, ect->gc, TRUE, rect.x, rect.y, rect.width, rect.height);
+ gdk_gc_set_foreground (ect->gc, &w->style->fg [idx]);
+ gdk_draw_string (drawable, ect->font, ect->gc, x1 + xoff, y2 + ect->font->descent, str);
+ }
}
static void
-ec_draw (ECell *ecell, int x1, int y1, int x2, int y2)
+e_cell_text_start_editing (ECellText *ect, int col, int row)
{
+ printf ("Starting to edit %d %d\n", col, row);
}
static gint
-ec_event (ECell *ecell, GdkEvent *event)
+ect_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
{
+ ECell *ecell = ecell_view->ecell;
+ ECellText *ect = E_CELL_TEXT (ecell);
+
+ switch (event->type){
+ case GDK_BUTTON_PRESS:
+ if (e_table_model_get_selected_row (ecell->table_model) == row)
+ e_cell_text_start_editing (ect, col, row);
+ else
+ e_table_model_select_row (ecell->table_model, row);
+ return TRUE;
+ }
}
static void
-e_cell_class_init (GtkObjectClass *object_class)
+ect_destroy (GtkObject *object)
{
- ECellClass *ecc = (ECellClass *) object_class;
+ ECellText *ect = E_CELL_TEXT (object);
+
+ g_free (ect->font_name);
- ecc->realize = ec_realize;
- ecc->unrealize = ec_unrealize;
- ecc->draw = ec_draw;
- ecc->event = ec_event;
+ GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
-E_MAKE_TYPE(e_cell, "ECell", ECell, e_cell_class_init, NULL, PARENT_TYPE);
+static void
+e_cell_text_class_init (GtkObjectClass *object_class)
+{
+ ECellClass *ecc = (ECellClass *) object_class;
+ object_class->destroy = ect_destroy;
+ ecc->realize = ect_realize;
+ ecc->unrealize = ect_unrealize;
+ ecc->draw = ect_draw;
+ ecc->event = ect_event;
+
+ parent_class = gtk_type_class (PARENT_TYPE);
+}
+
+E_MAKE_TYPE(e_cell_text, "ECellText", ECellText, e_cell_text_class_init, NULL, PARENT_TYPE);
+
+ECell *
+e_cell_text_new (const char *fontname, GtkJustification justify)
+{
+ ECellText *ect = gtk_type_new (e_cell_text_get_type ());
+
+ ect->font_name = g_strdup (fontname);
+ ect->justify = justify;
+
+ return (ECell *) ect;
+}
diff --git a/widgets/e-cell-text.h b/widgets/e-cell-text.h
index 19d913a678..24def9f0f8 100644
--- a/widgets/e-cell-text.h
+++ b/widgets/e-cell-text.h
@@ -12,6 +12,13 @@
typedef struct {
ECell parent;
+
+ GdkGC *gc;
+ GdkFont *font;
+ GtkJustification justify;
+
+ char *font_name;
+ GnomeCanvas *canvas;
} ECellText;
typedef struct {
@@ -19,6 +26,6 @@ typedef struct {
} ECellTextClass;
GtkType e_cell_text_get_type (void);
-ECell *e_cell_text_new (void);
+ECell *e_cell_text_new (const char *fontname, GtkJustification justify);
#endif /* _E_CELL_TEXT_H_ */
diff --git a/widgets/e-cell.c b/widgets/e-cell.c
index e5ceb0fe8a..bff0fb88f2 100644
--- a/widgets/e-cell.c
+++ b/widgets/e-cell.c
@@ -12,24 +12,49 @@
#define PARENT_TYPE gtk_object_get_type()
-static void
+static ECellView *
ec_realize (ECell *e_cell, GnomeCanvas *canvas)
{
+ return NULL;
}
static void
-ec_unrealize (ECell *e_cell)
+ec_unrealize (ECellView *e_cell)
{
}
static void
-ec_draw (ECell *ecell, int x1, int y1, int x2, int y2)
+ec_draw (ECellView *ecell_view, GdkDrawable *drawable, int col, int row, int x1, int y1, int x2, int y2)
{
+ g_warning ("e-cell-draw invoked\n");
}
static gint
-ec_event (ECell *ecell, GdkEvent *event)
+ec_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
{
+ g_warning ("e-cell-event invoked\n");
+}
+
+static void
+ec_focus (ECellView *ecell_view, int col, int row, int x1, int y1, int x2, int y2)
+{
+ ecell_view->focus_col = col;
+ ecell_view->focus_row = row;
+ ecell_view->focus_x1 = x1;
+ ecell_view->focus_y1 = y1;
+ ecell_view->focus_x2 = x2;
+ ecell_view->focus_y2 = y2;
+}
+
+static void
+ec_unfocus (ECellView *ecell_view)
+{
+ ecell_view->focus_col = -1;
+ ecell_view->focus_row = -1;
+ ecell_view->focus_x1 = -1;
+ ecell_view->focus_y1 = -1;
+ ecell_view->focus_x2 = -1;
+ ecell_view->focus_y2 = -1;
}
static void
@@ -41,8 +66,44 @@ e_cell_class_init (GtkObjectClass *object_class)
ecc->unrealize = ec_unrealize;
ecc->draw = ec_draw;
ecc->event = ec_event;
+ ecc->focus = ec_focus;
+ ecc->unfocus = ec_unfocus;
+}
+
+static void
+e_cell_init (GtkObject *object)
+{
+ ECell *e_cell = E_CELL (object);
}
-E_MAKE_TYPE(e_cell, "ECell", ECell, e_cell_class_init, NULL, PARENT_TYPE);
+E_MAKE_TYPE(e_cell, "ECell", ECell, e_cell_class_init, e_cell_init, PARENT_TYPE);
+void
+e_cell_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
+{
+ E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->event (
+ ecell_view, event, col, row);
+}
+
+ECellView *
+e_cell_realize (ECell *ecell, GnomeCanvas *canvas)
+{
+ return E_CELL_CLASS (GTK_OBJECT (ecell)->klass)->realize (
+ ecell, canvas);
+}
+
+void
+e_cell_unrealize (ECellView *ecell_view)
+{
+ E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->unrealize (ecell_view);
+}
+
+void
+e_cell_draw (ECellView *ecell_view, GdkDrawable *drawable,
+ int col, int row, int x1, int y1, int x2, int y2)
+{
+ E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->draw (
+ ecell_view, drawable, col, row, x1, y1, x2, y2);
+}
+
diff --git a/widgets/e-cell.h b/widgets/e-cell.h
index 8395d3e290..0cafe0fff4 100644
--- a/widgets/e-cell.h
+++ b/widgets/e-cell.h
@@ -2,6 +2,7 @@
#define _E_CELL_H_
#include <libgnomeui/gnome-canvas.h>
+#include "e-table-model.h"
#define E_CELL_TYPE (e_cell_get_type ())
#define E_CELL(o) (GTK_CHECK_CAST ((o), E_CELL_TYPE, ECell))
@@ -9,19 +10,42 @@
#define E_IS_CELL(o) (GTK_CHECK_TYPE ((o), E_CELL_TYPE))
#define E_IS_CELL_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_CELL_TYPE))
-typedef struct {
+typedef struct _ECell ECell;
+typedef struct _ECellView ECellView;
+
+struct _ECell {
GtkObject object;
-} ECell;
+
+ ETableModel *table_model;
+};
+
+struct _ECellView {
+ ECell *ecell;
+ gint focus_x1, focus_y1, focus_x2, focus_y2;
+ gint focus_col, focus_row;
+};
+
+#define E_CELL_IS_FOCUSED(ecell_view) (ecell_view->focus_x1 != -1)
typedef struct {
GtkObjectClass parent_class;
- void (*realize) (ECell *, GnomeCanvas *canvas);
- void (*unrealize) (ECell *);
- void (*draw) (ECell *ecell, int x1, int y1, int x2, int y2);
- gint (*event) (ECell *ecell, GdkEvent *event);
+ ECellView *(*realize) (ECell *, GnomeCanvas *canvas);
+ void (*unrealize) (ECellView *);
+ void (*draw) (ECellView *ecell_view, GdkDrawable *drawable,
+ int col, int row, int x1, int y1, int x2, int y2);
+ gint (*event) (ECellView *ecell_view, GdkEvent *event, int col, int row);
+ void (*focus) (ECellView *ecell, int col, int row, int x1, int y1, int x2, int y2);
+ void (*unfocus) (ECellView *ecell);
} ECellClass;
-GtkType e_cell_get_type (void);
+GtkType e_cell_get_type (void);
+void e_cell_event (ECellView *ecell_view, GdkEvent *event, int col, int row);
+ECellView *e_cell_realize (ECell *ecell, GnomeCanvas *canvas);
+void e_cell_unrealize (ECellView *ecell);
+void e_cell_draw (ECellView *ecell, GdkDrawable *dr,
+ int col, int row, int x1, int y1, int x2, int y2);
+void e_cell_focus (ECellView *ecell, int col, int row, int x1, int y1, int x2, int y2);
+void e_cell_unfocus (ECellView *ecell);
#endif /* _E_CELL_H_ */
diff --git a/widgets/e-table-col.c b/widgets/e-table-col.c
index c75bc6b195..4c61cddd0f 100644
--- a/widgets/e-table-col.c
+++ b/widgets/e-table-col.c
@@ -13,8 +13,7 @@
ETableCol *
e_table_col_new (const char *id, int width, int min_width,
- ETableColRenderFn render, void *render_data,
- GCompareFunc compare, gboolean resizable)
+ ECell *ecell, GCompareFunc compare, gboolean resizable)
{
ETableCol *etc;
@@ -22,7 +21,6 @@ e_table_col_new (const char *id, int width, int min_width,
g_return_if_fail (width >= 0);
g_return_if_fail (min_width >= 0);
g_return_if_fail (width >= min_width);
- g_return_if_fail (render != NULL);
g_return_if_fail (compare != NULL);
etc = g_new (ETableCol, 1);
@@ -30,8 +28,7 @@ e_table_col_new (const char *id, int width, int min_width,
etc->id = g_strdup (id);
etc->width = width;
etc->min_width = min_width;
- etc->render = render;
- etc->render_data = render_data;
+ etc->ecell = ecell;
etc->compare = compare;
etc->selected = 0;
diff --git a/widgets/e-table-col.h b/widgets/e-table-col.h
index 215df07797..950bf23352 100644
--- a/widgets/e-table-col.h
+++ b/widgets/e-table-col.h
@@ -2,13 +2,7 @@
#define _E_TABLE_COL_H_
typedef struct _ETableCol ETableCol;
-
-/*
- * Rendering function for the column header
- */
-typedef struct ERenderContext ERenderContext;
-
-typedef void (*ETableColRenderFn)(ERenderContext *ctxt);
+typedef struct _ECell ECell;
/*
* Information about a single column
@@ -18,16 +12,17 @@ struct _ETableCol {
short width;
short min_width;
short x;
- ETableColRenderFn render;
GCompareFunc compare;
- void *render_data;
unsigned int selected:1;
unsigned int resizeable:1;
+
+ ECell *ecell;
};
ETableCol *e_table_col_new (const char *id, int width, int min_width,
- ETableColRenderFn render, void *render_data,
- GCompareFunc compare, gboolean resizable);
+ ECell *ecell, GCompareFunc compare,
+ gboolean resizable);
#endif /* _E_TABLE_COL_H_ */
+
diff --git a/widgets/e-table-header-item.c b/widgets/e-table-header-item.c
index dab5d3d71d..ab59d9a01c 100644
--- a/widgets/e-table-header-item.c
+++ b/widgets/e-table-header-item.c
@@ -157,6 +157,7 @@ ethi_realize (GnomeCanvasItem *item)
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
GdkWindow *window;
GdkColor c;
+ int i;
if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)-> realize)
(*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->realize)(item);
@@ -171,13 +172,27 @@ ethi_realize (GnomeCanvasItem *item)
if (!ethi->font)
ethi_font_load (ethi, "fixed");
+
+ /*
+ * Now realize the various ECells
+ */
+ ethi->n_cells = e_table_header_count (ethi->eth);
+ ethi->cell_views = g_new (ECellView *, ethi->n_cells);
+
+ for (i = 0; i < ethi->n_cells; i++){
+ ETableCol *col = e_table_header_get_column (ethi->eth, i);
+
+ ethi->cell_views [i] = e_cell_realize (col->ecell, item->canvas);
+ }
+
}
static void
ethi_unrealize (GnomeCanvasItem *item)
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
-
+ int i;
+
gdk_gc_unref (ethi->gc);
ethi->gc = NULL;
@@ -187,6 +202,14 @@ ethi_unrealize (GnomeCanvasItem *item)
gdk_cursor_destroy (ethi->normal_cursor);
ethi->normal_cursor = NULL;
+ for (i = 0; i < ethi->n_cells; i++){
+ ETableCol *col = e_table_header_get_column (ethi->eth, i);
+
+ e_cell_unrealize (col->ecell, ethi->cell_views [i]);
+ ethi->cell_views = NULL;
+ }
+ g_free (ethi->cell_views);
+
if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize)
(*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize)(item);
}
@@ -244,8 +267,10 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x1, int y1, int wid
total = 0;
x = -x1;
+#if 0
printf ("My coords are: %g %g %g %g\n",
item->x1, item->y1, item->x2, item->y2);
+#endif
for (col = 0; col < cols; col++){
ETableCol *ecol = e_table_header_get_column (ethi->eth, col);
@@ -353,11 +378,6 @@ ethi_end_resize (ETableHeaderItem *ethi, int new_size)
{
e_table_header_set_size (ethi->eth, ethi->resize_col, new_size);
- if (ethi->resize_guide){
-#warning Fix this
- /* gtk_object_destroy (ethi->resize_guide);*/
- ethi->resize_guide = NULL;
- }
ethi->resize_col = -1;
ethi_request_redraw (ethi);
}
@@ -394,9 +414,12 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
if (x - ethi->resize_start_pos <= 0)
break;
-
+
+ ethi_request_redraw (ethi);
+
ethi->resize_width = x - ethi->resize_start_pos;
-
+ e_table_header_set_size (ethi->eth, ethi->resize_col, ethi->resize_width);
+
ethi_request_redraw (ethi);
} else
set_cursor (ethi, x);
diff --git a/widgets/e-table-header-item.h b/widgets/e-table-header-item.h
index d6b7d64a9f..10b84e1897 100644
--- a/widgets/e-table-header-item.h
+++ b/widgets/e-table-header-item.h
@@ -10,6 +10,8 @@
#define E_IS_TABLE_HEADER_ITEM(o) (GTK_CHECK_TYPE ((o), E_TABLE_HEADER_ITEM_TYPE))
#define E_IS_TABLE_HEADER_ITEM_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_HEADER_ITEM_TYPE))
+typedef struct _ECellView ECellView;
+
typedef struct {
GnomeCanvasItem parent;
ETableHeader *eth;
@@ -28,6 +30,9 @@ typedef struct {
int resize_start_pos;
GtkObject *resize_guide;
+ ECellView **cell_views;
+ int n_cells;
+
/*
* Ids
*/
diff --git a/widgets/e-table-item.c b/widgets/e-table-item.c
index 1e53180804..5bf1e24fd0 100644
--- a/widgets/e-table-item.c
+++ b/widgets/e-table-item.c
@@ -44,9 +44,11 @@ eti_remove_table_model (ETableItem *eti)
return;
gtk_signal_disconnect (eti->table_model_change_id);
+ gtk_signal_disconnect (eti->table_model_selection_id);
gtk_object_unref (GTK_OBJECT (eti->table_model));
eti->table_model_change_id = 0;
+ eti->table_model_selection_id = 0;
eti->table_model = NULL;
}
@@ -74,6 +76,23 @@ eti_table_model_changed (ETableModel *table_model, ETableItem *eti)
}
static void
+eti_request_redraw (ETableItem *eti)
+{
+ GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
+
+ gnome_canvas_request_redraw (canvas, eti->x1, eti->y1,
+ eti->x1 + eti->width + 1,
+ eti->y1 + eti->height + 1);
+}
+
+static void
+eti_table_model_row_selection (ETableModel *table_model, ETableItem *eti)
+{
+ /* FIXME: we should optimize this to only redraw the selection change */
+ eti_request_redraw (eti);
+}
+
+static void
eti_add_table_model (ETableItem *eti, ETableModel *table_model)
{
g_assert (eti->table_model == NULL);
@@ -83,31 +102,30 @@ eti_add_table_model (ETableItem *eti, ETableModel *table_model)
eti->table_model_change_id = gtk_signal_connect (
GTK_OBJECT (table_model), "model_changed",
GTK_SIGNAL_FUNC (eti_table_model_changed), eti);
-}
-
-static void
-eti_request_redraw (ETableItem *eti)
-{
- GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
-
- gnome_canvas_request_redraw (canvas, eti->x1, eti->y1, eti->x1 + eti->width, eti->y1 + eti->height);
+ eti->table_model_selection_id = gtk_signal_connect (
+ GTK_OBJECT (table_model), "row_selection",
+ GTK_SIGNAL_FUNC (eti_table_model_row_selection), eti);
}
static void
eti_header_dim_changed (ETableHeader *eth, int col, ETableItem *eti)
{
- eti->width = e_table_header_total_width (eti->header);
+ eti_request_redraw (eti);
+ eti->width = e_table_header_total_width (eti->header);
eti_update (GNOME_CANVAS_ITEM (eti), NULL, NULL, 0);
+
eti_request_redraw (eti);
}
static void
eti_header_structure_changed (ETableHeader *eth, ETableItem *eti)
{
- eti->width = e_table_header_total_width (eti->header);
+ eti_request_redraw (eti);
+ eti->width = e_table_header_total_width (eti->header);
eti_update (GNOME_CANVAS_ITEM (eti), NULL, NULL, 0);
+
eti_request_redraw (eti);
}
@@ -181,6 +199,9 @@ static void
eti_init (GnomeCanvasItem *item)
{
ETableItem *eti = E_TABLE_ITEM (item);
+
+ eti->focused_col = -1;
+ eti->focused_row = -1;
}
static void
@@ -199,6 +220,7 @@ eti_realize (GnomeCanvasItem *item)
gdk_gc_ref (canvas_widget->style->white_gc);
eti->grid_gc = gdk_gc_new (window);
gdk_gc_set_foreground (eti->grid_gc, &canvas_widget->style->fg [GTK_STATE_NORMAL]);
+
}
static void
@@ -277,7 +299,10 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
if (first_col == -1)
return;
+#if 0
printf ("Cols %d %d\n", first_col, last_col);
+#endif
+
/*
* Draw individual lines
*/
@@ -318,6 +343,25 @@ eti_point (GnomeCanvasItem *item, double x, double y, int cx, int cy,
static int
eti_event (GnomeCanvasItem *item, GdkEvent *e)
{
+ ETableItem *eti = E_TABLE_ITEM (item);
+ ETableCol *etc;
+
+ switch (e->type){
+ case GDK_BUTTON_PRESS:
+ case GDK_BUTTON_RELEASE:
+ case GDK_2BUTTON_PRESS:
+
+ case GDK_KEY_PRESS:
+ case GDK_KEY_RELEASE:
+ if (eti->focused_col == -1)
+ return FALSE;
+
+ etc = e_table_header_get_column (eti->header, eti->focused_col);
+
+ e_cell_event (etc->ecell, e, eti->focused_col, eti->focused_row);
+ break;
+
+ }
return FALSE;
}
@@ -371,3 +415,19 @@ e_table_item_get_type (void)
return type;
}
+void
+e_table_item_focus (ETableItem *eti, int col, int row)
+{
+ if (eti->focused_col != -1)
+ e_table_item_unfocus (eti);
+
+ eti->focused_col = col;
+ eti->focused_row = row;
+}
+
+void
+e_table_item_unfocus (ETableItem *eti)
+{
+ eti->focused_col = -1;
+ eti->focused_row = -1;
+}
diff --git a/widgets/e-table-item.h b/widgets/e-table-item.h
index 7e548cf49d..fefa221227 100644
--- a/widgets/e-table-item.h
+++ b/widgets/e-table-item.h
@@ -27,11 +27,14 @@ typedef struct {
int header_dim_change_id;
int header_structure_change_id;
int table_model_change_id;
-
+ int table_model_selection_id;
+
GdkGC *fill_gc;
GdkGC *grid_gc;
unsigned int draw_grid:1;
+
+ int focused_col, focused_row;
} ETableItem;
typedef struct {
@@ -39,5 +42,7 @@ typedef struct {
} ETableItemClass;
GtkType e_table_item_get_type (void);
+void e_table_item_focus (ETableItem *eti, int col, int row);
+void e_table_item_unfocus (ETableItem *eti);
#endif /* _E_TABLE_ITEM_H_ */
diff --git a/widgets/e-table-model.c b/widgets/e-table-model.c
index de7bc67c51..1176b33ec7 100644
--- a/widgets/e-table-model.c
+++ b/widgets/e-table-model.c
@@ -16,6 +16,7 @@ static GtkObjectClass *e_table_model_parent_class;
enum {
MODEL_CHANGED,
+ ROW_SELECTION,
LAST_SIGNAL
};
@@ -88,6 +89,14 @@ e_table_model_class_init (GtkObjectClass *object_class)
GTK_SIGNAL_OFFSET (ETableModelClass, model_changed),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
+
+ etm_signals [ROW_SELECTION] =
+ gtk_signal_new ("row_selection",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETableModelClass, row_selection),
+ gtk_marshal_NONE__INT_INT,
+ GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
gtk_object_class_add_signals (object_class, etm_signals, LAST_SIGNAL);
}
@@ -158,3 +167,29 @@ e_table_model_max_col_width (ETableModel *etm, int col)
return max;
}
#endif
+
+void
+e_table_model_select_row (ETableModel *etm, int row)
+{
+ gtk_signal_emit (GTK_OBJECT (etm), etm_signals [ROW_SELECTION], row, 1);
+ etm->row_selected = row;
+}
+
+void
+e_table_model_unselect_row (ETableModel *etm, int row)
+{
+ if (etm->row_selected != -1){
+ gtk_signal_emit (
+ GTK_OBJECT (etm), etm_signals [ROW_SELECTION],
+ etm->row_selected, 0);
+ }
+
+ etm->row_selected = -1;
+}
+
+gint
+e_table_model_get_selected_row (ETableModel *etm)
+{
+ return etm->row_selected;
+}
+
diff --git a/widgets/e-table-model.h b/widgets/e-table-model.h
index d12a465c0b..2d439a0065 100644
--- a/widgets/e-table-model.h
+++ b/widgets/e-table-model.h
@@ -11,6 +11,9 @@
typedef struct {
GtkObject base;
+
+ /* Temporary. I swear */
+ int row_selected;
} ETableModel;
typedef struct {
@@ -30,7 +33,8 @@ typedef struct {
/*
* Signals
*/
- void (*model_changed) (ETableModel *etm, int row);
+ void (*model_changed) (ETableModel *etm);
+ void (*row_selection) (ETableModel *etc, int row);
} ETableModelClass;
GtkType e_table_model_get_type (void);
@@ -44,6 +48,9 @@ void *e_table_model_value_at (ETableModel *e_table_model, int col,
void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, void *data);
gboolean e_table_model_is_cell_editable (ETableModel *e_table_model, int col, int row);
+void e_table_model_select_row (ETableModel *e_table_model, int row);
+gint e_table_model_get_selected_row (ETableModel *e_table_model);
+
/*
* Routines for emitting signals on the e_table
*/
diff --git a/widgets/e-table-simple.c b/widgets/e-table-simple.c
index 32f7145bc6..b23cda1220 100644
--- a/widgets/e-table-simple.c
+++ b/widgets/e-table-simple.c
@@ -12,6 +12,8 @@
#include <config.h>
#include "e-table-simple.h"
+#define PARENT_TYPE e_table_model_get_type()
+
static int
simple_column_count (ETableModel *etm)
{
@@ -99,7 +101,7 @@ e_table_simple_get_type (void)
(GtkClassInitFunc) NULL
};
- type = gtk_type_unique (e_table_model_get_type (), &info);
+ type = gtk_type_unique (PARENT_TYPE, &info);
}
return type;
diff --git a/widgets/e-table-sorted.c b/widgets/e-table-sorted.c
index 2d53c79e5d..be19de2efb 100644
--- a/widgets/e-table-sorted.c
+++ b/widgets/e-table-sorted.c
@@ -11,93 +11,16 @@
#include "e-util.h"
#include "e-table-sorted.h"
-#define PARENT_TYPE E_TABLE_MODEL_TYPE
+#define PARENT_TYPE E_TABLE_SUBSET_TYPE
static ETableModelClass *ets_parent_class;
static void
-ets_destroy (GtkObject *object)
-{
- ETableSorted *ets = E_TABLE_SORTED (object);
-
- gtk_object_unref (GTK_OBJECT (ets->source));
- gtk_object_unref (GTK_OBJECT (ets->header));
- free (ets->map_table);
-
- GTK_OBJECT_CLASS (ets_parent_class)->destroy (object);
-}
-
-static int
-ets_column_count (ETableModel *etm)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_column_count (ets->source);
-}
-
-static const char *
-ets_column_name (ETableModel *etm, int col)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_column_name (ets->source, col);
-}
-
-static int
-ets_row_count (ETableModel *etm)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_row_count (ets->source);
-}
-
-static void *
-ets_value_at (ETableModel *etm, int col, int row)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_value_at (ets->source, col, ets->map_table [row]);
-}
-
-static void
-ets_set_value_at (ETableModel *etm, int col, int row, void *val)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_set_value_at (ets->source, col, ets->map_table [row], val);
-}
-
-static gboolean
-ets_is_cell_editable (ETableModel *etm, int col, int row)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_is_cell_editable (ets->source, col, ets->map_table [row]);
-}
-
-static int
-ets_row_height (ETableModel *etm, int row)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_row_height (ets->source, ets->map_table [row]);
-}
-
-static void
ets_class_init (GtkObjectClass *klass)
{
ETableModelClass *table_class = (ETableModelClass *) klass;
ets_parent_class = gtk_type_class (PARENT_TYPE);
- klass->destroy = ets_destroy;
-
- table_class->column_count = ets_column_count;
- table_class->column_name = ets_column_name;
- table_class->row_count = ets_row_count;
- table_class->value_at = ets_value_at;
- table_class->set_value_at = ets_set_value_at;
- table_class->is_cell_editable = ets_is_cell_editable;
- table_class->row_height = ets_row_height;
}
E_MAKE_TYPE(e_table_sorted, "ETableSorted", ETableSorted, ets_class_init, NULL, PARENT_TYPE);
@@ -108,49 +31,63 @@ static int
my_sort (const void *a, const void *b)
{
GCompareFunc comp;
+ ETableModel *source = E_TABLE_SUBSET (sort_ets)->source;
const int *ia = (const int *) a;
const int *ib = (const int *) b;
void *va, *vb;
- va = e_table_model_value_at (sort_ets->source, sort_ets->sort_idx, *ia);
- vb = e_table_model_value_at (sort_ets->source, sort_ets->sort_idx, *ib);
+ va = e_table_model_value_at (source, sort_ets->sort_col, *ia);
+ vb = e_table_model_value_at (source, sort_ets->sort_col, *ib);
- comp = sort_ets->sort_col->compare;
+ return (*sort_ets->compare) (va, vb);
+}
- return (*comp) (va, vb);
+static void
+do_sort (ETableSorted *ets)
+{
+ ETableSubset *etss = E_TABLE_SUBSET (ets);
+ g_assert (sort_ets == NULL);
+
+ sort_ets = ets;
+ qsort (etss->map_table, etss->n_map, sizeof (unsigned int), my_sort);
+ sort_ets = NULL;
}
ETableModel *
-e_table_sorted_new (ETableModel *source, ETableHeader *header, short sort_field)
+e_table_sorted_new (ETableModel *source, int col, GCompareFunc compare)
{
ETableSorted *ets = gtk_type_new (E_TABLE_SORTED_TYPE);
+ ETableSubset *etss = E_TABLE_SUBSET (ets);
const int nvals = e_table_model_row_count (source);
unsigned int *buffer;
int i;
- buffer = malloc (sizeof (unsigned int *) * nvals);
- if (buffer = NULL)
+ if (e_table_subset_construct (etss, source, nvals) == NULL){
+ gtk_object_destroy (GTK_OBJECT (ets));
return NULL;
- ets->map_table = buffer;
- ets->n_map = nvals;
- ets->source = source;
- ets->header = header;
- ets->sort_col = e_table_header_get_column (header, sort_field);
- ets->sort_idx = sort_field;
- gtk_object_ref (GTK_OBJECT (source));
- gtk_object_ref (GTK_OBJECT (header));
+ }
+
+ ets->compare = compare;
+ ets->sort_col = col;
/* Init */
for (i = 0; i < nvals; i++)
- ets->map_table [i] = i;
+ etss->map_table [i] = i;
- /* Sort */
- g_assert (sort_ets == NULL);
- sort_ets = ets;
- qsort (ets->map_table, nvals, sizeof (unsigned int), my_sort);
- sort_ets = NULL;
+ do_sort (ets);
return (ETableModel *) ets;
}
-
+void
+e_table_sorted_resort (ETableSorted *ets, int col, GCompareFunc compare)
+{
+ if (col == -1 || compare == NULL)
+ do_sort (ets);
+ else {
+ ets->sort_col = col;
+ ets->compare = compare;
+ do_sort (ets);
+ }
+}
+
diff --git a/widgets/e-table-sorted.h b/widgets/e-table-sorted.h
index 65578b7b83..2ec52df2e7 100644
--- a/widgets/e-table-sorted.h
+++ b/widgets/e-table-sorted.h
@@ -3,7 +3,7 @@
#include <gtk/gtkobject.h>
#include "e-table-model.h"
-#include "e-table-header.h"
+#include "e-table-subset.h"
#define E_TABLE_SORTED_TYPE (e_table_sorted_get_type ())
#define E_TABLE_SORTED(o) (GTK_CHECK_CAST ((o), E_TABLE_SORTED_TYPE, ETableSorted))
@@ -12,23 +12,18 @@
#define E_IS_TABLE_SORTED_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_SORTED_TYPE))
typedef struct {
- ETableModel base;
+ ETableSubset base;
- ETableModel *source;
- ETableHeader *header;
- ETableCol *sort_col;
- short sort_idx;
-
- int n_map;
- unsigned int *map_table;
+ short sort_col;
+ GCompareFunc compare;
} ETableSorted;
typedef struct {
- ETableModelClass parent_class;
+ ETableSubset parent_class;
} ETableSortedClass;
GtkType e_table_sorted_get_type (void);
-ETableModel *e_table_sorted_new (ETableModel *etm, ETableHeader *header,
- short sort_field);
+ETableModel *e_table_sorted_new (ETableModel *etm, int col, GCompareFunc compare);
+void e_table_sorted_resort (ETableSorted *ets, int col, GCompareFunc compare);
#endif /* _E_TABLE_SORTED_H_ */
diff --git a/widgets/e-table-subset.c b/widgets/e-table-subset.c
index 0b9621ac84..afa1b862b4 100644
--- a/widgets/e-table-subset.c
+++ b/widgets/e-table-subset.c
@@ -19,52 +19,122 @@ etss_destroy (GtkObject *object)
{
ETableSubset *etss = E_TABLE_SUBSET (object);
- gtk_object_unref (GTK_OBJECT (etss->source));
- free (ets->subset_table);
+ if (etss->source)
+ gtk_object_unref (GTK_OBJECT (etss->source));
- GTK_OBJECT_CLASS (ets_parent_class)->destroy (object);
+ if (etss->map_table)
+ free (etss->map_table);
+
+ GTK_OBJECT_CLASS (etss_parent_class)->destroy (object);
+}
+
+static int
+etss_column_count (ETableModel *etm)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_column_count (etss->source);
+}
+
+static const char *
+etss_column_name (ETableModel *etm, int col)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_column_name (etss->source, col);
+}
+
+static int
+etss_row_count (ETableModel *etm)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_row_count (etss->source);
+}
+
+static void *
+etss_value_at (ETableModel *etm, int col, int row)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_value_at (etss->source, col, etss->map_table [row]);
+}
+
+static void
+etss_set_value_at (ETableModel *etm, int col, int row, void *val)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_set_value_at (etss->source, col, etss->map_table [row], val);
+}
+
+static gboolean
+etss_is_cell_editable (ETableModel *etm, int col, int row)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_is_cell_editable (etss->source, col, etss->map_table [row]);
+}
+
+static int
+etss_row_height (ETableModel *etm, int row)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_row_height (etss->source, etss->map_table [row]);
}
static void
etss_class_init (GtkObjectClass *klass)
{
+ ETableModelClass *table_class = (ETableModelClass *) klass;
+
etss_parent_class = gtk_type_class (PARENT_TYPE);
klass->destroy = etss_destroy;
+
+ table_class->column_count = etss_column_count;
+ table_class->column_name = etss_column_name;
+ table_class->row_count = etss_row_count;
+ table_class->value_at = etss_value_at;
+ table_class->set_value_at = etss_set_value_at;
+ table_class->is_cell_editable = etss_is_cell_editable;
+ table_class->row_height = etss_row_height;
+
}
E_MAKE_TYPE(e_table_subset, "ETableSubset", ETableSubset, etss_class_init, NULL, PARENT_TYPE);
ETableModel *
-e_table_subset_new (ETableModel *source, ETableHeader *header, short sort_field)
+e_table_subset_construct (ETableSubset *etss, ETableModel *source, int nvals)
{
- ETableSorted *ets = gtk_type_new (E_TABLE_SORTED_TYPE);
- const int nvals = e_table_model_row_count (source);
unsigned int *buffer;
int i;
- buffer = malloc (sizeof (unsigned int *) * nvals);
+ buffer = (unsigned int *) malloc (sizeof (unsigned int *) * nvals);
if (buffer = NULL)
return NULL;
- ets->map_table = buffer;
- ets->n_map = nvals;
- ets->source = source;
- ets->header = header;
- ets->sort_col = e_table_header_get_column (header, sort_field);
- ets->sort_idx = sort_field;
+ etss->map_table = buffer;
+ etss->n_map = nvals;
+ etss->source = source;
gtk_object_ref (GTK_OBJECT (source));
- gtk_object_ref (GTK_OBJECT (header));
/* Init */
for (i = 0; i < nvals; i++)
- ets->map_table [i] = i;
+ etss->map_table [i] = i;
- /* Sort */
- g_assert (sort_ets == NULL);
- sort_ets = ets;
- qsort (ets->map_table, nvals, sizeof (unsigned int), my_sort);
- sort_ets = NULL;
-
- return (ETableModel *) ets;
+}
+
+ETableModel *
+e_table_subset_new (ETableModel *source, const int nvals)
+{
+ ETableSubset *etss = gtk_type_new (E_TABLE_SUBSET_TYPE);
+
+ if (e_table_subset_construct (etss, source, nvals) == NULL){
+ gtk_object_destroy (GTK_OBJECT (etss));
+ return NULL;
+ }
+
+ return (ETableModel *) etss;
}
diff --git a/widgets/e-table-subset.h b/widgets/e-table-subset.h
index a87d6d0df8..5576c55f1d 100644
--- a/widgets/e-table-subset.h
+++ b/widgets/e-table-subset.h
@@ -3,7 +3,6 @@
#include <gtk/gtkobject.h>
#include "e-table-model.h"
-#include "e-table-header.h"
#define E_TABLE_SUBSET_TYPE (e_table_subset_get_type ())
#define E_TABLE_SUBSET(o) (GTK_CHECK_CAST ((o), E_TABLE_SUBSET_TYPE, ETableSubset))
@@ -15,15 +14,16 @@ typedef struct {
ETableModel base;
ETableModel *source;
- int subset_count;
- int *subset_table;
+ int n_map;
+ int *map_table;
} ETableSubset;
typedef struct {
ETableModelClass parent_class;
} ETableSubsetClass;
-GtkType e_table_subset_get_type (void);
-ETableModel *e_table_subset_new (ETableModel *etm,
- int n_vals, int *ptrs);
+GtkType e_table_subset_get_type (void);
+ETableModel *e_table_subset_new (ETableModel *etm, int n_vals);
+ETableModel *e_table_subset_construct (ETableSubset *ets, ETableModel *source, int nvals);
+
#endif /* _E_TABLE_SUBSET_H_ */
diff --git a/widgets/e-table.c b/widgets/e-table.c
index 795c737b36..3b13e87d6b 100644
--- a/widgets/e-table.c
+++ b/widgets/e-table.c
@@ -9,28 +9,14 @@
#include <config.h>
#include <libgnomeui/gnome-canvas.h>
#include "e-table.h"
+#include "e-util.h"
#define PARENT_OBJECT_TYPE gnome_canvas_get_type ()
-GtkType
-e_table_get_type (void)
-{
- static GtkType type = 0;
-
- if (!type){
- GtkTypeInfo info = {
- "ETable",
- sizeof (ETable),
- sizeof (ETableClass),
- (GtkClassInitFunc) e_table_class_init,
- (GtkObjectInitFunc) NULL,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (PARENT_OBJECT_TYPE, &info);
- }
+E_MAKE_TYPE(e_table, "ETable", ETable, e_table_class_init, NULL, PARENT_TYPE);
- return type;
+ETable *
+e_table_new (ETableHeader *eth, ETableModel *etm)
+{
}
+
diff --git a/widgets/e-table/ChangeLog b/widgets/e-table/ChangeLog
index 188b1ff00c..973eb5d189 100644
--- a/widgets/e-table/ChangeLog
+++ b/widgets/e-table/ChangeLog
@@ -1,3 +1,22 @@
+1999-11-25 Miguel de Icaza <miguel@gnu.org>
+
+ * e-table-header-item.c (ethi_realize): Realize cells.
+
+ * e-table-item.c (eti_header_dim_changed): redraw before and after.
+
+ * e-table-header-item.c (ethi_event): Add continuous resizing.
+
+1999-11-24 Miguel de Icaza <miguel@gnu.org>
+
+ * e-table-subset.h, e-table-subset.c: New files, used to implement
+ subset tables.
+
+ * e-table-sorted.h, e-table-sorted.c: Now they derive from
+ e-table-subset.
+
+ * e-cell.c, e-cell.h: realize method now return per view instance
+ data.
+
1999-11-20 Miguel de Icaza <miguel@gnu.org>
* e-table-item.c (eti_draw): WOOOOHOOOOOoO! It took me quite a
diff --git a/widgets/e-table/Makefile.am b/widgets/e-table/Makefile.am
index ac2858025c..d9748531d5 100644
--- a/widgets/e-table/Makefile.am
+++ b/widgets/e-table/Makefile.am
@@ -25,8 +25,6 @@ libevolutionwidgets_a_SOURCES = \
e-table-item.h \
e-table-model.c \
e-table-model.h \
- e-table-render.c \
- e-table-render.h \
e-table-simple.c \
e-table-simple.h \
e-table-sorted.c \
diff --git a/widgets/e-table/ROADMAP.e-table b/widgets/e-table/ROADMAP.e-table
index 88afe506c3..65f19dabe1 100644
--- a/widgets/e-table/ROADMAP.e-table
+++ b/widgets/e-table/ROADMAP.e-table
@@ -29,14 +29,6 @@ e-table-simple.h, e-table-simple.c:
routines (you provide the callbacks). For lazy people, like
me.
-e-table-header.h, e-table-header.c:
-
- These implement the ETableHeader model. They describe what
- columns are shown in the screen and in which order.
-
- These emit signals: column-size-changed and structure-changed
- (if a column is added/removed)
-
e-cell.c, e-cell.h:
These are actually miss-named. Objects of type e-cell know
@@ -60,6 +52,17 @@ e-table-col.h, e-table-col.c:
* The Views
+e-table-header.h, e-table-header.c:
+
+ These implement the ETableHeaderItem canvas item. This item is
+ used both to control the columns displayed as well as displaying them.
+
+ They describe what columns are shown in the screen and in
+ which order.
+
+ These emit signals: column-size-changed and structure-changed
+ (if a column is added/removed)
+
e-table-item.c, e-table-item.h
This is a canvas item that renders the contents of a
diff --git a/widgets/e-table/e-cell-text.c b/widgets/e-table/e-cell-text.c
index c30e42cfd3..1b3f524a2e 100644
--- a/widgets/e-table/e-cell-text.c
+++ b/widgets/e-table/e-cell-text.c
@@ -7,42 +7,157 @@
* (C) 1999 Helix Code, Inc
*/
#include <config.h>
+#include <gtk/gtkenums.h>
#include "e-cell-text.h"
#include "e-util.h"
-#define PARENT_TYPE gtk_object_get_type()
+#define PARENT_TYPE e_cell_get_type()
+
+typedef struct {
+ ECellView cell_view;
+ GdkGC *gc;
+ GdkFont *font;
+ GnomeCanvas *canvas;
+} ECellTextView;
+
+static ECellClass *parent_class;
+
+static ECellView *
+ect_realize (ECell *ecell, GnomeCanvas *canvas)
+{
+ ECellText *ect = E_CELL_TEXT (ecell);
+ ECellTextView *ectv = g_new (ECellTextView, 1);
+
+ ectv->cell_view.ecell = ecell;
+ ectv->gc = gdk_gc_new (GTK_WIDGET (canvas)->window);
+ ectv->font = gdk_fontset_load (ect->font_name ? ect->font_name : "fixed");
+ ectv->canvas = canvas;
+
+ return (ECellView *)ectv;
+}
static void
-ec_realize (ECell *e_cell, GnomeCanvas *canvas)
+ect_unrealize (ECellView *ecv)
{
+ ECellTextView *ectv = (ECellTextView *) ecv;
+
+ gdk_gc_unref (ectv->gc);
+ ectv->gc = NULL;
+
+ gdk_font_unref (ectv->font);
+ ectv->font = NULL;
+
+ g_free (ectv);
}
static void
-ec_unrealize (ECell *e_cell)
+ect_draw (ECellView *ecell_view, GdkDrawable *drawable, int col, int row, int x1, int y1, int x2, int y2)
{
+ ECellText *ect = E_CELL_TEXT (ecell_view->ecell);
+ GdkRectangle rect;
+ const char *str = e_table_model_value_at (ecell_view->ecell->table_model, col, row);
+ int selected = e_table_model_get_selected_row (ecell_view->ecell->table_model) == row;
+ int xoff, w;
+
+ rect.x = x1;
+ rect.y = y1;
+ rect.width = x2 - x1;
+ rect.height = y2 - y1;
+
+ gdk_gc_set_clip_rectangle (ect->gc, &rect);
+
+ switch (ect->justify){
+ case GTK_JUSTIFY_LEFT:
+ xoff = 1;
+ break;
+
+ case GTK_JUSTIFY_RIGHT:
+ w = 1 + gdk_text_width (ect->font, str, strlen (str));
+ xoff = (x2 - x1) - w;
+ break;
+
+ case GTK_JUSTIFY_CENTER:
+ xoff = ((x2 - x1) - gdk_text_width (ect->font, str, strlen (str))) / 2;
+ break;
+ default:
+ g_warning ("Can not handle GTK_JUSTIFY_FILL");
+ break;
+ }
+
+ /* Draw now */
+ {
+ GtkWidget *w = GTK_WIDGET (ect->canvas);
+ GdkColor *background;
+ int idx;
+
+ if (selected)
+ idx = GTK_STATE_SELECTED;
+ else
+ idx = GTK_STATE_NORMAL;
+
+ gdk_gc_set_foreground (ect->gc, &w->style->bg [idx]);
+ gdk_draw_rectangle (drawable, ect->gc, TRUE, rect.x, rect.y, rect.width, rect.height);
+ gdk_gc_set_foreground (ect->gc, &w->style->fg [idx]);
+ gdk_draw_string (drawable, ect->font, ect->gc, x1 + xoff, y2 + ect->font->descent, str);
+ }
}
static void
-ec_draw (ECell *ecell, int x1, int y1, int x2, int y2)
+e_cell_text_start_editing (ECellText *ect, int col, int row)
{
+ printf ("Starting to edit %d %d\n", col, row);
}
static gint
-ec_event (ECell *ecell, GdkEvent *event)
+ect_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
{
+ ECell *ecell = ecell_view->ecell;
+ ECellText *ect = E_CELL_TEXT (ecell);
+
+ switch (event->type){
+ case GDK_BUTTON_PRESS:
+ if (e_table_model_get_selected_row (ecell->table_model) == row)
+ e_cell_text_start_editing (ect, col, row);
+ else
+ e_table_model_select_row (ecell->table_model, row);
+ return TRUE;
+ }
}
static void
-e_cell_class_init (GtkObjectClass *object_class)
+ect_destroy (GtkObject *object)
{
- ECellClass *ecc = (ECellClass *) object_class;
+ ECellText *ect = E_CELL_TEXT (object);
+
+ g_free (ect->font_name);
- ecc->realize = ec_realize;
- ecc->unrealize = ec_unrealize;
- ecc->draw = ec_draw;
- ecc->event = ec_event;
+ GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
-E_MAKE_TYPE(e_cell, "ECell", ECell, e_cell_class_init, NULL, PARENT_TYPE);
+static void
+e_cell_text_class_init (GtkObjectClass *object_class)
+{
+ ECellClass *ecc = (ECellClass *) object_class;
+ object_class->destroy = ect_destroy;
+ ecc->realize = ect_realize;
+ ecc->unrealize = ect_unrealize;
+ ecc->draw = ect_draw;
+ ecc->event = ect_event;
+
+ parent_class = gtk_type_class (PARENT_TYPE);
+}
+
+E_MAKE_TYPE(e_cell_text, "ECellText", ECellText, e_cell_text_class_init, NULL, PARENT_TYPE);
+
+ECell *
+e_cell_text_new (const char *fontname, GtkJustification justify)
+{
+ ECellText *ect = gtk_type_new (e_cell_text_get_type ());
+
+ ect->font_name = g_strdup (fontname);
+ ect->justify = justify;
+
+ return (ECell *) ect;
+}
diff --git a/widgets/e-table/e-cell-text.h b/widgets/e-table/e-cell-text.h
index 19d913a678..24def9f0f8 100644
--- a/widgets/e-table/e-cell-text.h
+++ b/widgets/e-table/e-cell-text.h
@@ -12,6 +12,13 @@
typedef struct {
ECell parent;
+
+ GdkGC *gc;
+ GdkFont *font;
+ GtkJustification justify;
+
+ char *font_name;
+ GnomeCanvas *canvas;
} ECellText;
typedef struct {
@@ -19,6 +26,6 @@ typedef struct {
} ECellTextClass;
GtkType e_cell_text_get_type (void);
-ECell *e_cell_text_new (void);
+ECell *e_cell_text_new (const char *fontname, GtkJustification justify);
#endif /* _E_CELL_TEXT_H_ */
diff --git a/widgets/e-table/e-cell.c b/widgets/e-table/e-cell.c
index e5ceb0fe8a..bff0fb88f2 100644
--- a/widgets/e-table/e-cell.c
+++ b/widgets/e-table/e-cell.c
@@ -12,24 +12,49 @@
#define PARENT_TYPE gtk_object_get_type()
-static void
+static ECellView *
ec_realize (ECell *e_cell, GnomeCanvas *canvas)
{
+ return NULL;
}
static void
-ec_unrealize (ECell *e_cell)
+ec_unrealize (ECellView *e_cell)
{
}
static void
-ec_draw (ECell *ecell, int x1, int y1, int x2, int y2)
+ec_draw (ECellView *ecell_view, GdkDrawable *drawable, int col, int row, int x1, int y1, int x2, int y2)
{
+ g_warning ("e-cell-draw invoked\n");
}
static gint
-ec_event (ECell *ecell, GdkEvent *event)
+ec_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
{
+ g_warning ("e-cell-event invoked\n");
+}
+
+static void
+ec_focus (ECellView *ecell_view, int col, int row, int x1, int y1, int x2, int y2)
+{
+ ecell_view->focus_col = col;
+ ecell_view->focus_row = row;
+ ecell_view->focus_x1 = x1;
+ ecell_view->focus_y1 = y1;
+ ecell_view->focus_x2 = x2;
+ ecell_view->focus_y2 = y2;
+}
+
+static void
+ec_unfocus (ECellView *ecell_view)
+{
+ ecell_view->focus_col = -1;
+ ecell_view->focus_row = -1;
+ ecell_view->focus_x1 = -1;
+ ecell_view->focus_y1 = -1;
+ ecell_view->focus_x2 = -1;
+ ecell_view->focus_y2 = -1;
}
static void
@@ -41,8 +66,44 @@ e_cell_class_init (GtkObjectClass *object_class)
ecc->unrealize = ec_unrealize;
ecc->draw = ec_draw;
ecc->event = ec_event;
+ ecc->focus = ec_focus;
+ ecc->unfocus = ec_unfocus;
+}
+
+static void
+e_cell_init (GtkObject *object)
+{
+ ECell *e_cell = E_CELL (object);
}
-E_MAKE_TYPE(e_cell, "ECell", ECell, e_cell_class_init, NULL, PARENT_TYPE);
+E_MAKE_TYPE(e_cell, "ECell", ECell, e_cell_class_init, e_cell_init, PARENT_TYPE);
+void
+e_cell_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
+{
+ E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->event (
+ ecell_view, event, col, row);
+}
+
+ECellView *
+e_cell_realize (ECell *ecell, GnomeCanvas *canvas)
+{
+ return E_CELL_CLASS (GTK_OBJECT (ecell)->klass)->realize (
+ ecell, canvas);
+}
+
+void
+e_cell_unrealize (ECellView *ecell_view)
+{
+ E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->unrealize (ecell_view);
+}
+
+void
+e_cell_draw (ECellView *ecell_view, GdkDrawable *drawable,
+ int col, int row, int x1, int y1, int x2, int y2)
+{
+ E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->draw (
+ ecell_view, drawable, col, row, x1, y1, x2, y2);
+}
+
diff --git a/widgets/e-table/e-cell.h b/widgets/e-table/e-cell.h
index 8395d3e290..0cafe0fff4 100644
--- a/widgets/e-table/e-cell.h
+++ b/widgets/e-table/e-cell.h
@@ -2,6 +2,7 @@
#define _E_CELL_H_
#include <libgnomeui/gnome-canvas.h>
+#include "e-table-model.h"
#define E_CELL_TYPE (e_cell_get_type ())
#define E_CELL(o) (GTK_CHECK_CAST ((o), E_CELL_TYPE, ECell))
@@ -9,19 +10,42 @@
#define E_IS_CELL(o) (GTK_CHECK_TYPE ((o), E_CELL_TYPE))
#define E_IS_CELL_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_CELL_TYPE))
-typedef struct {
+typedef struct _ECell ECell;
+typedef struct _ECellView ECellView;
+
+struct _ECell {
GtkObject object;
-} ECell;
+
+ ETableModel *table_model;
+};
+
+struct _ECellView {
+ ECell *ecell;
+ gint focus_x1, focus_y1, focus_x2, focus_y2;
+ gint focus_col, focus_row;
+};
+
+#define E_CELL_IS_FOCUSED(ecell_view) (ecell_view->focus_x1 != -1)
typedef struct {
GtkObjectClass parent_class;
- void (*realize) (ECell *, GnomeCanvas *canvas);
- void (*unrealize) (ECell *);
- void (*draw) (ECell *ecell, int x1, int y1, int x2, int y2);
- gint (*event) (ECell *ecell, GdkEvent *event);
+ ECellView *(*realize) (ECell *, GnomeCanvas *canvas);
+ void (*unrealize) (ECellView *);
+ void (*draw) (ECellView *ecell_view, GdkDrawable *drawable,
+ int col, int row, int x1, int y1, int x2, int y2);
+ gint (*event) (ECellView *ecell_view, GdkEvent *event, int col, int row);
+ void (*focus) (ECellView *ecell, int col, int row, int x1, int y1, int x2, int y2);
+ void (*unfocus) (ECellView *ecell);
} ECellClass;
-GtkType e_cell_get_type (void);
+GtkType e_cell_get_type (void);
+void e_cell_event (ECellView *ecell_view, GdkEvent *event, int col, int row);
+ECellView *e_cell_realize (ECell *ecell, GnomeCanvas *canvas);
+void e_cell_unrealize (ECellView *ecell);
+void e_cell_draw (ECellView *ecell, GdkDrawable *dr,
+ int col, int row, int x1, int y1, int x2, int y2);
+void e_cell_focus (ECellView *ecell, int col, int row, int x1, int y1, int x2, int y2);
+void e_cell_unfocus (ECellView *ecell);
#endif /* _E_CELL_H_ */
diff --git a/widgets/e-table/e-table-col.c b/widgets/e-table/e-table-col.c
index c75bc6b195..4c61cddd0f 100644
--- a/widgets/e-table/e-table-col.c
+++ b/widgets/e-table/e-table-col.c
@@ -13,8 +13,7 @@
ETableCol *
e_table_col_new (const char *id, int width, int min_width,
- ETableColRenderFn render, void *render_data,
- GCompareFunc compare, gboolean resizable)
+ ECell *ecell, GCompareFunc compare, gboolean resizable)
{
ETableCol *etc;
@@ -22,7 +21,6 @@ e_table_col_new (const char *id, int width, int min_width,
g_return_if_fail (width >= 0);
g_return_if_fail (min_width >= 0);
g_return_if_fail (width >= min_width);
- g_return_if_fail (render != NULL);
g_return_if_fail (compare != NULL);
etc = g_new (ETableCol, 1);
@@ -30,8 +28,7 @@ e_table_col_new (const char *id, int width, int min_width,
etc->id = g_strdup (id);
etc->width = width;
etc->min_width = min_width;
- etc->render = render;
- etc->render_data = render_data;
+ etc->ecell = ecell;
etc->compare = compare;
etc->selected = 0;
diff --git a/widgets/e-table/e-table-col.h b/widgets/e-table/e-table-col.h
index 215df07797..950bf23352 100644
--- a/widgets/e-table/e-table-col.h
+++ b/widgets/e-table/e-table-col.h
@@ -2,13 +2,7 @@
#define _E_TABLE_COL_H_
typedef struct _ETableCol ETableCol;
-
-/*
- * Rendering function for the column header
- */
-typedef struct ERenderContext ERenderContext;
-
-typedef void (*ETableColRenderFn)(ERenderContext *ctxt);
+typedef struct _ECell ECell;
/*
* Information about a single column
@@ -18,16 +12,17 @@ struct _ETableCol {
short width;
short min_width;
short x;
- ETableColRenderFn render;
GCompareFunc compare;
- void *render_data;
unsigned int selected:1;
unsigned int resizeable:1;
+
+ ECell *ecell;
};
ETableCol *e_table_col_new (const char *id, int width, int min_width,
- ETableColRenderFn render, void *render_data,
- GCompareFunc compare, gboolean resizable);
+ ECell *ecell, GCompareFunc compare,
+ gboolean resizable);
#endif /* _E_TABLE_COL_H_ */
+
diff --git a/widgets/e-table/e-table-header-item.c b/widgets/e-table/e-table-header-item.c
index dab5d3d71d..ab59d9a01c 100644
--- a/widgets/e-table/e-table-header-item.c
+++ b/widgets/e-table/e-table-header-item.c
@@ -157,6 +157,7 @@ ethi_realize (GnomeCanvasItem *item)
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
GdkWindow *window;
GdkColor c;
+ int i;
if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)-> realize)
(*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->realize)(item);
@@ -171,13 +172,27 @@ ethi_realize (GnomeCanvasItem *item)
if (!ethi->font)
ethi_font_load (ethi, "fixed");
+
+ /*
+ * Now realize the various ECells
+ */
+ ethi->n_cells = e_table_header_count (ethi->eth);
+ ethi->cell_views = g_new (ECellView *, ethi->n_cells);
+
+ for (i = 0; i < ethi->n_cells; i++){
+ ETableCol *col = e_table_header_get_column (ethi->eth, i);
+
+ ethi->cell_views [i] = e_cell_realize (col->ecell, item->canvas);
+ }
+
}
static void
ethi_unrealize (GnomeCanvasItem *item)
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
-
+ int i;
+
gdk_gc_unref (ethi->gc);
ethi->gc = NULL;
@@ -187,6 +202,14 @@ ethi_unrealize (GnomeCanvasItem *item)
gdk_cursor_destroy (ethi->normal_cursor);
ethi->normal_cursor = NULL;
+ for (i = 0; i < ethi->n_cells; i++){
+ ETableCol *col = e_table_header_get_column (ethi->eth, i);
+
+ e_cell_unrealize (col->ecell, ethi->cell_views [i]);
+ ethi->cell_views = NULL;
+ }
+ g_free (ethi->cell_views);
+
if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize)
(*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize)(item);
}
@@ -244,8 +267,10 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x1, int y1, int wid
total = 0;
x = -x1;
+#if 0
printf ("My coords are: %g %g %g %g\n",
item->x1, item->y1, item->x2, item->y2);
+#endif
for (col = 0; col < cols; col++){
ETableCol *ecol = e_table_header_get_column (ethi->eth, col);
@@ -353,11 +378,6 @@ ethi_end_resize (ETableHeaderItem *ethi, int new_size)
{
e_table_header_set_size (ethi->eth, ethi->resize_col, new_size);
- if (ethi->resize_guide){
-#warning Fix this
- /* gtk_object_destroy (ethi->resize_guide);*/
- ethi->resize_guide = NULL;
- }
ethi->resize_col = -1;
ethi_request_redraw (ethi);
}
@@ -394,9 +414,12 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
if (x - ethi->resize_start_pos <= 0)
break;
-
+
+ ethi_request_redraw (ethi);
+
ethi->resize_width = x - ethi->resize_start_pos;
-
+ e_table_header_set_size (ethi->eth, ethi->resize_col, ethi->resize_width);
+
ethi_request_redraw (ethi);
} else
set_cursor (ethi, x);
diff --git a/widgets/e-table/e-table-header-item.h b/widgets/e-table/e-table-header-item.h
index d6b7d64a9f..10b84e1897 100644
--- a/widgets/e-table/e-table-header-item.h
+++ b/widgets/e-table/e-table-header-item.h
@@ -10,6 +10,8 @@
#define E_IS_TABLE_HEADER_ITEM(o) (GTK_CHECK_TYPE ((o), E_TABLE_HEADER_ITEM_TYPE))
#define E_IS_TABLE_HEADER_ITEM_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_HEADER_ITEM_TYPE))
+typedef struct _ECellView ECellView;
+
typedef struct {
GnomeCanvasItem parent;
ETableHeader *eth;
@@ -28,6 +30,9 @@ typedef struct {
int resize_start_pos;
GtkObject *resize_guide;
+ ECellView **cell_views;
+ int n_cells;
+
/*
* Ids
*/
diff --git a/widgets/e-table/e-table-item.c b/widgets/e-table/e-table-item.c
index 1e53180804..5bf1e24fd0 100644
--- a/widgets/e-table/e-table-item.c
+++ b/widgets/e-table/e-table-item.c
@@ -44,9 +44,11 @@ eti_remove_table_model (ETableItem *eti)
return;
gtk_signal_disconnect (eti->table_model_change_id);
+ gtk_signal_disconnect (eti->table_model_selection_id);
gtk_object_unref (GTK_OBJECT (eti->table_model));
eti->table_model_change_id = 0;
+ eti->table_model_selection_id = 0;
eti->table_model = NULL;
}
@@ -74,6 +76,23 @@ eti_table_model_changed (ETableModel *table_model, ETableItem *eti)
}
static void
+eti_request_redraw (ETableItem *eti)
+{
+ GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
+
+ gnome_canvas_request_redraw (canvas, eti->x1, eti->y1,
+ eti->x1 + eti->width + 1,
+ eti->y1 + eti->height + 1);
+}
+
+static void
+eti_table_model_row_selection (ETableModel *table_model, ETableItem *eti)
+{
+ /* FIXME: we should optimize this to only redraw the selection change */
+ eti_request_redraw (eti);
+}
+
+static void
eti_add_table_model (ETableItem *eti, ETableModel *table_model)
{
g_assert (eti->table_model == NULL);
@@ -83,31 +102,30 @@ eti_add_table_model (ETableItem *eti, ETableModel *table_model)
eti->table_model_change_id = gtk_signal_connect (
GTK_OBJECT (table_model), "model_changed",
GTK_SIGNAL_FUNC (eti_table_model_changed), eti);
-}
-
-static void
-eti_request_redraw (ETableItem *eti)
-{
- GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
-
- gnome_canvas_request_redraw (canvas, eti->x1, eti->y1, eti->x1 + eti->width, eti->y1 + eti->height);
+ eti->table_model_selection_id = gtk_signal_connect (
+ GTK_OBJECT (table_model), "row_selection",
+ GTK_SIGNAL_FUNC (eti_table_model_row_selection), eti);
}
static void
eti_header_dim_changed (ETableHeader *eth, int col, ETableItem *eti)
{
- eti->width = e_table_header_total_width (eti->header);
+ eti_request_redraw (eti);
+ eti->width = e_table_header_total_width (eti->header);
eti_update (GNOME_CANVAS_ITEM (eti), NULL, NULL, 0);
+
eti_request_redraw (eti);
}
static void
eti_header_structure_changed (ETableHeader *eth, ETableItem *eti)
{
- eti->width = e_table_header_total_width (eti->header);
+ eti_request_redraw (eti);
+ eti->width = e_table_header_total_width (eti->header);
eti_update (GNOME_CANVAS_ITEM (eti), NULL, NULL, 0);
+
eti_request_redraw (eti);
}
@@ -181,6 +199,9 @@ static void
eti_init (GnomeCanvasItem *item)
{
ETableItem *eti = E_TABLE_ITEM (item);
+
+ eti->focused_col = -1;
+ eti->focused_row = -1;
}
static void
@@ -199,6 +220,7 @@ eti_realize (GnomeCanvasItem *item)
gdk_gc_ref (canvas_widget->style->white_gc);
eti->grid_gc = gdk_gc_new (window);
gdk_gc_set_foreground (eti->grid_gc, &canvas_widget->style->fg [GTK_STATE_NORMAL]);
+
}
static void
@@ -277,7 +299,10 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
if (first_col == -1)
return;
+#if 0
printf ("Cols %d %d\n", first_col, last_col);
+#endif
+
/*
* Draw individual lines
*/
@@ -318,6 +343,25 @@ eti_point (GnomeCanvasItem *item, double x, double y, int cx, int cy,
static int
eti_event (GnomeCanvasItem *item, GdkEvent *e)
{
+ ETableItem *eti = E_TABLE_ITEM (item);
+ ETableCol *etc;
+
+ switch (e->type){
+ case GDK_BUTTON_PRESS:
+ case GDK_BUTTON_RELEASE:
+ case GDK_2BUTTON_PRESS:
+
+ case GDK_KEY_PRESS:
+ case GDK_KEY_RELEASE:
+ if (eti->focused_col == -1)
+ return FALSE;
+
+ etc = e_table_header_get_column (eti->header, eti->focused_col);
+
+ e_cell_event (etc->ecell, e, eti->focused_col, eti->focused_row);
+ break;
+
+ }
return FALSE;
}
@@ -371,3 +415,19 @@ e_table_item_get_type (void)
return type;
}
+void
+e_table_item_focus (ETableItem *eti, int col, int row)
+{
+ if (eti->focused_col != -1)
+ e_table_item_unfocus (eti);
+
+ eti->focused_col = col;
+ eti->focused_row = row;
+}
+
+void
+e_table_item_unfocus (ETableItem *eti)
+{
+ eti->focused_col = -1;
+ eti->focused_row = -1;
+}
diff --git a/widgets/e-table/e-table-item.h b/widgets/e-table/e-table-item.h
index 7e548cf49d..fefa221227 100644
--- a/widgets/e-table/e-table-item.h
+++ b/widgets/e-table/e-table-item.h
@@ -27,11 +27,14 @@ typedef struct {
int header_dim_change_id;
int header_structure_change_id;
int table_model_change_id;
-
+ int table_model_selection_id;
+
GdkGC *fill_gc;
GdkGC *grid_gc;
unsigned int draw_grid:1;
+
+ int focused_col, focused_row;
} ETableItem;
typedef struct {
@@ -39,5 +42,7 @@ typedef struct {
} ETableItemClass;
GtkType e_table_item_get_type (void);
+void e_table_item_focus (ETableItem *eti, int col, int row);
+void e_table_item_unfocus (ETableItem *eti);
#endif /* _E_TABLE_ITEM_H_ */
diff --git a/widgets/e-table/e-table-model.c b/widgets/e-table/e-table-model.c
index de7bc67c51..1176b33ec7 100644
--- a/widgets/e-table/e-table-model.c
+++ b/widgets/e-table/e-table-model.c
@@ -16,6 +16,7 @@ static GtkObjectClass *e_table_model_parent_class;
enum {
MODEL_CHANGED,
+ ROW_SELECTION,
LAST_SIGNAL
};
@@ -88,6 +89,14 @@ e_table_model_class_init (GtkObjectClass *object_class)
GTK_SIGNAL_OFFSET (ETableModelClass, model_changed),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
+
+ etm_signals [ROW_SELECTION] =
+ gtk_signal_new ("row_selection",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETableModelClass, row_selection),
+ gtk_marshal_NONE__INT_INT,
+ GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
gtk_object_class_add_signals (object_class, etm_signals, LAST_SIGNAL);
}
@@ -158,3 +167,29 @@ e_table_model_max_col_width (ETableModel *etm, int col)
return max;
}
#endif
+
+void
+e_table_model_select_row (ETableModel *etm, int row)
+{
+ gtk_signal_emit (GTK_OBJECT (etm), etm_signals [ROW_SELECTION], row, 1);
+ etm->row_selected = row;
+}
+
+void
+e_table_model_unselect_row (ETableModel *etm, int row)
+{
+ if (etm->row_selected != -1){
+ gtk_signal_emit (
+ GTK_OBJECT (etm), etm_signals [ROW_SELECTION],
+ etm->row_selected, 0);
+ }
+
+ etm->row_selected = -1;
+}
+
+gint
+e_table_model_get_selected_row (ETableModel *etm)
+{
+ return etm->row_selected;
+}
+
diff --git a/widgets/e-table/e-table-model.h b/widgets/e-table/e-table-model.h
index d12a465c0b..2d439a0065 100644
--- a/widgets/e-table/e-table-model.h
+++ b/widgets/e-table/e-table-model.h
@@ -11,6 +11,9 @@
typedef struct {
GtkObject base;
+
+ /* Temporary. I swear */
+ int row_selected;
} ETableModel;
typedef struct {
@@ -30,7 +33,8 @@ typedef struct {
/*
* Signals
*/
- void (*model_changed) (ETableModel *etm, int row);
+ void (*model_changed) (ETableModel *etm);
+ void (*row_selection) (ETableModel *etc, int row);
} ETableModelClass;
GtkType e_table_model_get_type (void);
@@ -44,6 +48,9 @@ void *e_table_model_value_at (ETableModel *e_table_model, int col,
void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, void *data);
gboolean e_table_model_is_cell_editable (ETableModel *e_table_model, int col, int row);
+void e_table_model_select_row (ETableModel *e_table_model, int row);
+gint e_table_model_get_selected_row (ETableModel *e_table_model);
+
/*
* Routines for emitting signals on the e_table
*/
diff --git a/widgets/e-table/e-table-simple.c b/widgets/e-table/e-table-simple.c
index 32f7145bc6..b23cda1220 100644
--- a/widgets/e-table/e-table-simple.c
+++ b/widgets/e-table/e-table-simple.c
@@ -12,6 +12,8 @@
#include <config.h>
#include "e-table-simple.h"
+#define PARENT_TYPE e_table_model_get_type()
+
static int
simple_column_count (ETableModel *etm)
{
@@ -99,7 +101,7 @@ e_table_simple_get_type (void)
(GtkClassInitFunc) NULL
};
- type = gtk_type_unique (e_table_model_get_type (), &info);
+ type = gtk_type_unique (PARENT_TYPE, &info);
}
return type;
diff --git a/widgets/e-table/e-table-sorted.c b/widgets/e-table/e-table-sorted.c
index 2d53c79e5d..be19de2efb 100644
--- a/widgets/e-table/e-table-sorted.c
+++ b/widgets/e-table/e-table-sorted.c
@@ -11,93 +11,16 @@
#include "e-util.h"
#include "e-table-sorted.h"
-#define PARENT_TYPE E_TABLE_MODEL_TYPE
+#define PARENT_TYPE E_TABLE_SUBSET_TYPE
static ETableModelClass *ets_parent_class;
static void
-ets_destroy (GtkObject *object)
-{
- ETableSorted *ets = E_TABLE_SORTED (object);
-
- gtk_object_unref (GTK_OBJECT (ets->source));
- gtk_object_unref (GTK_OBJECT (ets->header));
- free (ets->map_table);
-
- GTK_OBJECT_CLASS (ets_parent_class)->destroy (object);
-}
-
-static int
-ets_column_count (ETableModel *etm)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_column_count (ets->source);
-}
-
-static const char *
-ets_column_name (ETableModel *etm, int col)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_column_name (ets->source, col);
-}
-
-static int
-ets_row_count (ETableModel *etm)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_row_count (ets->source);
-}
-
-static void *
-ets_value_at (ETableModel *etm, int col, int row)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_value_at (ets->source, col, ets->map_table [row]);
-}
-
-static void
-ets_set_value_at (ETableModel *etm, int col, int row, void *val)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_set_value_at (ets->source, col, ets->map_table [row], val);
-}
-
-static gboolean
-ets_is_cell_editable (ETableModel *etm, int col, int row)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_is_cell_editable (ets->source, col, ets->map_table [row]);
-}
-
-static int
-ets_row_height (ETableModel *etm, int row)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_row_height (ets->source, ets->map_table [row]);
-}
-
-static void
ets_class_init (GtkObjectClass *klass)
{
ETableModelClass *table_class = (ETableModelClass *) klass;
ets_parent_class = gtk_type_class (PARENT_TYPE);
- klass->destroy = ets_destroy;
-
- table_class->column_count = ets_column_count;
- table_class->column_name = ets_column_name;
- table_class->row_count = ets_row_count;
- table_class->value_at = ets_value_at;
- table_class->set_value_at = ets_set_value_at;
- table_class->is_cell_editable = ets_is_cell_editable;
- table_class->row_height = ets_row_height;
}
E_MAKE_TYPE(e_table_sorted, "ETableSorted", ETableSorted, ets_class_init, NULL, PARENT_TYPE);
@@ -108,49 +31,63 @@ static int
my_sort (const void *a, const void *b)
{
GCompareFunc comp;
+ ETableModel *source = E_TABLE_SUBSET (sort_ets)->source;
const int *ia = (const int *) a;
const int *ib = (const int *) b;
void *va, *vb;
- va = e_table_model_value_at (sort_ets->source, sort_ets->sort_idx, *ia);
- vb = e_table_model_value_at (sort_ets->source, sort_ets->sort_idx, *ib);
+ va = e_table_model_value_at (source, sort_ets->sort_col, *ia);
+ vb = e_table_model_value_at (source, sort_ets->sort_col, *ib);
- comp = sort_ets->sort_col->compare;
+ return (*sort_ets->compare) (va, vb);
+}
- return (*comp) (va, vb);
+static void
+do_sort (ETableSorted *ets)
+{
+ ETableSubset *etss = E_TABLE_SUBSET (ets);
+ g_assert (sort_ets == NULL);
+
+ sort_ets = ets;
+ qsort (etss->map_table, etss->n_map, sizeof (unsigned int), my_sort);
+ sort_ets = NULL;
}
ETableModel *
-e_table_sorted_new (ETableModel *source, ETableHeader *header, short sort_field)
+e_table_sorted_new (ETableModel *source, int col, GCompareFunc compare)
{
ETableSorted *ets = gtk_type_new (E_TABLE_SORTED_TYPE);
+ ETableSubset *etss = E_TABLE_SUBSET (ets);
const int nvals = e_table_model_row_count (source);
unsigned int *buffer;
int i;
- buffer = malloc (sizeof (unsigned int *) * nvals);
- if (buffer = NULL)
+ if (e_table_subset_construct (etss, source, nvals) == NULL){
+ gtk_object_destroy (GTK_OBJECT (ets));
return NULL;
- ets->map_table = buffer;
- ets->n_map = nvals;
- ets->source = source;
- ets->header = header;
- ets->sort_col = e_table_header_get_column (header, sort_field);
- ets->sort_idx = sort_field;
- gtk_object_ref (GTK_OBJECT (source));
- gtk_object_ref (GTK_OBJECT (header));
+ }
+
+ ets->compare = compare;
+ ets->sort_col = col;
/* Init */
for (i = 0; i < nvals; i++)
- ets->map_table [i] = i;
+ etss->map_table [i] = i;
- /* Sort */
- g_assert (sort_ets == NULL);
- sort_ets = ets;
- qsort (ets->map_table, nvals, sizeof (unsigned int), my_sort);
- sort_ets = NULL;
+ do_sort (ets);
return (ETableModel *) ets;
}
-
+void
+e_table_sorted_resort (ETableSorted *ets, int col, GCompareFunc compare)
+{
+ if (col == -1 || compare == NULL)
+ do_sort (ets);
+ else {
+ ets->sort_col = col;
+ ets->compare = compare;
+ do_sort (ets);
+ }
+}
+
diff --git a/widgets/e-table/e-table-sorted.h b/widgets/e-table/e-table-sorted.h
index 65578b7b83..2ec52df2e7 100644
--- a/widgets/e-table/e-table-sorted.h
+++ b/widgets/e-table/e-table-sorted.h
@@ -3,7 +3,7 @@
#include <gtk/gtkobject.h>
#include "e-table-model.h"
-#include "e-table-header.h"
+#include "e-table-subset.h"
#define E_TABLE_SORTED_TYPE (e_table_sorted_get_type ())
#define E_TABLE_SORTED(o) (GTK_CHECK_CAST ((o), E_TABLE_SORTED_TYPE, ETableSorted))
@@ -12,23 +12,18 @@
#define E_IS_TABLE_SORTED_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_SORTED_TYPE))
typedef struct {
- ETableModel base;
+ ETableSubset base;
- ETableModel *source;
- ETableHeader *header;
- ETableCol *sort_col;
- short sort_idx;
-
- int n_map;
- unsigned int *map_table;
+ short sort_col;
+ GCompareFunc compare;
} ETableSorted;
typedef struct {
- ETableModelClass parent_class;
+ ETableSubset parent_class;
} ETableSortedClass;
GtkType e_table_sorted_get_type (void);
-ETableModel *e_table_sorted_new (ETableModel *etm, ETableHeader *header,
- short sort_field);
+ETableModel *e_table_sorted_new (ETableModel *etm, int col, GCompareFunc compare);
+void e_table_sorted_resort (ETableSorted *ets, int col, GCompareFunc compare);
#endif /* _E_TABLE_SORTED_H_ */
diff --git a/widgets/e-table/e-table-subset.c b/widgets/e-table/e-table-subset.c
index 0b9621ac84..afa1b862b4 100644
--- a/widgets/e-table/e-table-subset.c
+++ b/widgets/e-table/e-table-subset.c
@@ -19,52 +19,122 @@ etss_destroy (GtkObject *object)
{
ETableSubset *etss = E_TABLE_SUBSET (object);
- gtk_object_unref (GTK_OBJECT (etss->source));
- free (ets->subset_table);
+ if (etss->source)
+ gtk_object_unref (GTK_OBJECT (etss->source));
- GTK_OBJECT_CLASS (ets_parent_class)->destroy (object);
+ if (etss->map_table)
+ free (etss->map_table);
+
+ GTK_OBJECT_CLASS (etss_parent_class)->destroy (object);
+}
+
+static int
+etss_column_count (ETableModel *etm)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_column_count (etss->source);
+}
+
+static const char *
+etss_column_name (ETableModel *etm, int col)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_column_name (etss->source, col);
+}
+
+static int
+etss_row_count (ETableModel *etm)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_row_count (etss->source);
+}
+
+static void *
+etss_value_at (ETableModel *etm, int col, int row)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_value_at (etss->source, col, etss->map_table [row]);
+}
+
+static void
+etss_set_value_at (ETableModel *etm, int col, int row, void *val)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_set_value_at (etss->source, col, etss->map_table [row], val);
+}
+
+static gboolean
+etss_is_cell_editable (ETableModel *etm, int col, int row)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_is_cell_editable (etss->source, col, etss->map_table [row]);
+}
+
+static int
+etss_row_height (ETableModel *etm, int row)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_row_height (etss->source, etss->map_table [row]);
}
static void
etss_class_init (GtkObjectClass *klass)
{
+ ETableModelClass *table_class = (ETableModelClass *) klass;
+
etss_parent_class = gtk_type_class (PARENT_TYPE);
klass->destroy = etss_destroy;
+
+ table_class->column_count = etss_column_count;
+ table_class->column_name = etss_column_name;
+ table_class->row_count = etss_row_count;
+ table_class->value_at = etss_value_at;
+ table_class->set_value_at = etss_set_value_at;
+ table_class->is_cell_editable = etss_is_cell_editable;
+ table_class->row_height = etss_row_height;
+
}
E_MAKE_TYPE(e_table_subset, "ETableSubset", ETableSubset, etss_class_init, NULL, PARENT_TYPE);
ETableModel *
-e_table_subset_new (ETableModel *source, ETableHeader *header, short sort_field)
+e_table_subset_construct (ETableSubset *etss, ETableModel *source, int nvals)
{
- ETableSorted *ets = gtk_type_new (E_TABLE_SORTED_TYPE);
- const int nvals = e_table_model_row_count (source);
unsigned int *buffer;
int i;
- buffer = malloc (sizeof (unsigned int *) * nvals);
+ buffer = (unsigned int *) malloc (sizeof (unsigned int *) * nvals);
if (buffer = NULL)
return NULL;
- ets->map_table = buffer;
- ets->n_map = nvals;
- ets->source = source;
- ets->header = header;
- ets->sort_col = e_table_header_get_column (header, sort_field);
- ets->sort_idx = sort_field;
+ etss->map_table = buffer;
+ etss->n_map = nvals;
+ etss->source = source;
gtk_object_ref (GTK_OBJECT (source));
- gtk_object_ref (GTK_OBJECT (header));
/* Init */
for (i = 0; i < nvals; i++)
- ets->map_table [i] = i;
+ etss->map_table [i] = i;
- /* Sort */
- g_assert (sort_ets == NULL);
- sort_ets = ets;
- qsort (ets->map_table, nvals, sizeof (unsigned int), my_sort);
- sort_ets = NULL;
-
- return (ETableModel *) ets;
+}
+
+ETableModel *
+e_table_subset_new (ETableModel *source, const int nvals)
+{
+ ETableSubset *etss = gtk_type_new (E_TABLE_SUBSET_TYPE);
+
+ if (e_table_subset_construct (etss, source, nvals) == NULL){
+ gtk_object_destroy (GTK_OBJECT (etss));
+ return NULL;
+ }
+
+ return (ETableModel *) etss;
}
diff --git a/widgets/e-table/e-table-subset.h b/widgets/e-table/e-table-subset.h
index a87d6d0df8..5576c55f1d 100644
--- a/widgets/e-table/e-table-subset.h
+++ b/widgets/e-table/e-table-subset.h
@@ -3,7 +3,6 @@
#include <gtk/gtkobject.h>
#include "e-table-model.h"
-#include "e-table-header.h"
#define E_TABLE_SUBSET_TYPE (e_table_subset_get_type ())
#define E_TABLE_SUBSET(o) (GTK_CHECK_CAST ((o), E_TABLE_SUBSET_TYPE, ETableSubset))
@@ -15,15 +14,16 @@ typedef struct {
ETableModel base;
ETableModel *source;
- int subset_count;
- int *subset_table;
+ int n_map;
+ int *map_table;
} ETableSubset;
typedef struct {
ETableModelClass parent_class;
} ETableSubsetClass;
-GtkType e_table_subset_get_type (void);
-ETableModel *e_table_subset_new (ETableModel *etm,
- int n_vals, int *ptrs);
+GtkType e_table_subset_get_type (void);
+ETableModel *e_table_subset_new (ETableModel *etm, int n_vals);
+ETableModel *e_table_subset_construct (ETableSubset *ets, ETableModel *source, int nvals);
+
#endif /* _E_TABLE_SUBSET_H_ */
diff --git a/widgets/e-table/e-table.c b/widgets/e-table/e-table.c
index 795c737b36..3b13e87d6b 100644
--- a/widgets/e-table/e-table.c
+++ b/widgets/e-table/e-table.c
@@ -9,28 +9,14 @@
#include <config.h>
#include <libgnomeui/gnome-canvas.h>
#include "e-table.h"
+#include "e-util.h"
#define PARENT_OBJECT_TYPE gnome_canvas_get_type ()
-GtkType
-e_table_get_type (void)
-{
- static GtkType type = 0;
-
- if (!type){
- GtkTypeInfo info = {
- "ETable",
- sizeof (ETable),
- sizeof (ETableClass),
- (GtkClassInitFunc) e_table_class_init,
- (GtkObjectInitFunc) NULL,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (PARENT_OBJECT_TYPE, &info);
- }
+E_MAKE_TYPE(e_table, "ETable", ETable, e_table_class_init, NULL, PARENT_TYPE);
- return type;
+ETable *
+e_table_new (ETableHeader *eth, ETableModel *etm)
+{
}
+
diff --git a/widgets/e-table/table-test.c b/widgets/e-table/table-test.c
index 54392a73bc..e646b44655 100644
--- a/widgets/e-table/table-test.c
+++ b/widgets/e-table/table-test.c
@@ -11,7 +11,6 @@
#include "e-table-simple.h"
#include "e-table-header.h"
#include "e-table-header-item.h"
-#include "e-table-render.h"
#include "e-table-item.h"
char buffer [1024];
@@ -185,6 +184,7 @@ main (int argc, char *argv [])
GtkWidget *canvas, *window;
ETableModel *e_table_model;
ETableHeader *e_table_header;
+ ECell *cell_left_just;
int i;
gnome_init ("TableTest", "TableTest", argc, argv);
@@ -203,10 +203,12 @@ main (int argc, char *argv [])
* Header
*/
e_table_header = e_table_header_new ();
+ cell_left_just = e_cell_text_new ("fixed", GTK_JUSTIFY_LEFT);
+
for (i = 0; i < cols; i++){
ETableCol *ecol = e_table_col_new (
- column_labels [i], 80, 20, e_table_render_string,
- NULL, g_str_equal, TRUE);
+ column_labels [i], 80, 20, cell_left_just,
+ g_str_equal, TRUE);
e_table_header_add_column (e_table_header, ecol, i);
}
diff --git a/widgets/table-test.c b/widgets/table-test.c
index 54392a73bc..e646b44655 100644
--- a/widgets/table-test.c
+++ b/widgets/table-test.c
@@ -11,7 +11,6 @@
#include "e-table-simple.h"
#include "e-table-header.h"
#include "e-table-header-item.h"
-#include "e-table-render.h"
#include "e-table-item.h"
char buffer [1024];
@@ -185,6 +184,7 @@ main (int argc, char *argv [])
GtkWidget *canvas, *window;
ETableModel *e_table_model;
ETableHeader *e_table_header;
+ ECell *cell_left_just;
int i;
gnome_init ("TableTest", "TableTest", argc, argv);
@@ -203,10 +203,12 @@ main (int argc, char *argv [])
* Header
*/
e_table_header = e_table_header_new ();
+ cell_left_just = e_cell_text_new ("fixed", GTK_JUSTIFY_LEFT);
+
for (i = 0; i < cols; i++){
ETableCol *ecol = e_table_col_new (
- column_labels [i], 80, 20, e_table_render_string,
- NULL, g_str_equal, TRUE);
+ column_labels [i], 80, 20, cell_left_just,
+ g_str_equal, TRUE);
e_table_header_add_column (e_table_header, ecol, i);
}
diff --git a/widgets/table/e-cell-text.c b/widgets/table/e-cell-text.c
index c30e42cfd3..1b3f524a2e 100644
--- a/widgets/table/e-cell-text.c
+++ b/widgets/table/e-cell-text.c
@@ -7,42 +7,157 @@
* (C) 1999 Helix Code, Inc
*/
#include <config.h>
+#include <gtk/gtkenums.h>
#include "e-cell-text.h"
#include "e-util.h"
-#define PARENT_TYPE gtk_object_get_type()
+#define PARENT_TYPE e_cell_get_type()
+
+typedef struct {
+ ECellView cell_view;
+ GdkGC *gc;
+ GdkFont *font;
+ GnomeCanvas *canvas;
+} ECellTextView;
+
+static ECellClass *parent_class;
+
+static ECellView *
+ect_realize (ECell *ecell, GnomeCanvas *canvas)
+{
+ ECellText *ect = E_CELL_TEXT (ecell);
+ ECellTextView *ectv = g_new (ECellTextView, 1);
+
+ ectv->cell_view.ecell = ecell;
+ ectv->gc = gdk_gc_new (GTK_WIDGET (canvas)->window);
+ ectv->font = gdk_fontset_load (ect->font_name ? ect->font_name : "fixed");
+ ectv->canvas = canvas;
+
+ return (ECellView *)ectv;
+}
static void
-ec_realize (ECell *e_cell, GnomeCanvas *canvas)
+ect_unrealize (ECellView *ecv)
{
+ ECellTextView *ectv = (ECellTextView *) ecv;
+
+ gdk_gc_unref (ectv->gc);
+ ectv->gc = NULL;
+
+ gdk_font_unref (ectv->font);
+ ectv->font = NULL;
+
+ g_free (ectv);
}
static void
-ec_unrealize (ECell *e_cell)
+ect_draw (ECellView *ecell_view, GdkDrawable *drawable, int col, int row, int x1, int y1, int x2, int y2)
{
+ ECellText *ect = E_CELL_TEXT (ecell_view->ecell);
+ GdkRectangle rect;
+ const char *str = e_table_model_value_at (ecell_view->ecell->table_model, col, row);
+ int selected = e_table_model_get_selected_row (ecell_view->ecell->table_model) == row;
+ int xoff, w;
+
+ rect.x = x1;
+ rect.y = y1;
+ rect.width = x2 - x1;
+ rect.height = y2 - y1;
+
+ gdk_gc_set_clip_rectangle (ect->gc, &rect);
+
+ switch (ect->justify){
+ case GTK_JUSTIFY_LEFT:
+ xoff = 1;
+ break;
+
+ case GTK_JUSTIFY_RIGHT:
+ w = 1 + gdk_text_width (ect->font, str, strlen (str));
+ xoff = (x2 - x1) - w;
+ break;
+
+ case GTK_JUSTIFY_CENTER:
+ xoff = ((x2 - x1) - gdk_text_width (ect->font, str, strlen (str))) / 2;
+ break;
+ default:
+ g_warning ("Can not handle GTK_JUSTIFY_FILL");
+ break;
+ }
+
+ /* Draw now */
+ {
+ GtkWidget *w = GTK_WIDGET (ect->canvas);
+ GdkColor *background;
+ int idx;
+
+ if (selected)
+ idx = GTK_STATE_SELECTED;
+ else
+ idx = GTK_STATE_NORMAL;
+
+ gdk_gc_set_foreground (ect->gc, &w->style->bg [idx]);
+ gdk_draw_rectangle (drawable, ect->gc, TRUE, rect.x, rect.y, rect.width, rect.height);
+ gdk_gc_set_foreground (ect->gc, &w->style->fg [idx]);
+ gdk_draw_string (drawable, ect->font, ect->gc, x1 + xoff, y2 + ect->font->descent, str);
+ }
}
static void
-ec_draw (ECell *ecell, int x1, int y1, int x2, int y2)
+e_cell_text_start_editing (ECellText *ect, int col, int row)
{
+ printf ("Starting to edit %d %d\n", col, row);
}
static gint
-ec_event (ECell *ecell, GdkEvent *event)
+ect_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
{
+ ECell *ecell = ecell_view->ecell;
+ ECellText *ect = E_CELL_TEXT (ecell);
+
+ switch (event->type){
+ case GDK_BUTTON_PRESS:
+ if (e_table_model_get_selected_row (ecell->table_model) == row)
+ e_cell_text_start_editing (ect, col, row);
+ else
+ e_table_model_select_row (ecell->table_model, row);
+ return TRUE;
+ }
}
static void
-e_cell_class_init (GtkObjectClass *object_class)
+ect_destroy (GtkObject *object)
{
- ECellClass *ecc = (ECellClass *) object_class;
+ ECellText *ect = E_CELL_TEXT (object);
+
+ g_free (ect->font_name);
- ecc->realize = ec_realize;
- ecc->unrealize = ec_unrealize;
- ecc->draw = ec_draw;
- ecc->event = ec_event;
+ GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
-E_MAKE_TYPE(e_cell, "ECell", ECell, e_cell_class_init, NULL, PARENT_TYPE);
+static void
+e_cell_text_class_init (GtkObjectClass *object_class)
+{
+ ECellClass *ecc = (ECellClass *) object_class;
+ object_class->destroy = ect_destroy;
+ ecc->realize = ect_realize;
+ ecc->unrealize = ect_unrealize;
+ ecc->draw = ect_draw;
+ ecc->event = ect_event;
+
+ parent_class = gtk_type_class (PARENT_TYPE);
+}
+
+E_MAKE_TYPE(e_cell_text, "ECellText", ECellText, e_cell_text_class_init, NULL, PARENT_TYPE);
+
+ECell *
+e_cell_text_new (const char *fontname, GtkJustification justify)
+{
+ ECellText *ect = gtk_type_new (e_cell_text_get_type ());
+
+ ect->font_name = g_strdup (fontname);
+ ect->justify = justify;
+
+ return (ECell *) ect;
+}
diff --git a/widgets/table/e-cell-text.h b/widgets/table/e-cell-text.h
index 19d913a678..24def9f0f8 100644
--- a/widgets/table/e-cell-text.h
+++ b/widgets/table/e-cell-text.h
@@ -12,6 +12,13 @@
typedef struct {
ECell parent;
+
+ GdkGC *gc;
+ GdkFont *font;
+ GtkJustification justify;
+
+ char *font_name;
+ GnomeCanvas *canvas;
} ECellText;
typedef struct {
@@ -19,6 +26,6 @@ typedef struct {
} ECellTextClass;
GtkType e_cell_text_get_type (void);
-ECell *e_cell_text_new (void);
+ECell *e_cell_text_new (const char *fontname, GtkJustification justify);
#endif /* _E_CELL_TEXT_H_ */
diff --git a/widgets/table/e-cell.c b/widgets/table/e-cell.c
index e5ceb0fe8a..bff0fb88f2 100644
--- a/widgets/table/e-cell.c
+++ b/widgets/table/e-cell.c
@@ -12,24 +12,49 @@
#define PARENT_TYPE gtk_object_get_type()
-static void
+static ECellView *
ec_realize (ECell *e_cell, GnomeCanvas *canvas)
{
+ return NULL;
}
static void
-ec_unrealize (ECell *e_cell)
+ec_unrealize (ECellView *e_cell)
{
}
static void
-ec_draw (ECell *ecell, int x1, int y1, int x2, int y2)
+ec_draw (ECellView *ecell_view, GdkDrawable *drawable, int col, int row, int x1, int y1, int x2, int y2)
{
+ g_warning ("e-cell-draw invoked\n");
}
static gint
-ec_event (ECell *ecell, GdkEvent *event)
+ec_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
{
+ g_warning ("e-cell-event invoked\n");
+}
+
+static void
+ec_focus (ECellView *ecell_view, int col, int row, int x1, int y1, int x2, int y2)
+{
+ ecell_view->focus_col = col;
+ ecell_view->focus_row = row;
+ ecell_view->focus_x1 = x1;
+ ecell_view->focus_y1 = y1;
+ ecell_view->focus_x2 = x2;
+ ecell_view->focus_y2 = y2;
+}
+
+static void
+ec_unfocus (ECellView *ecell_view)
+{
+ ecell_view->focus_col = -1;
+ ecell_view->focus_row = -1;
+ ecell_view->focus_x1 = -1;
+ ecell_view->focus_y1 = -1;
+ ecell_view->focus_x2 = -1;
+ ecell_view->focus_y2 = -1;
}
static void
@@ -41,8 +66,44 @@ e_cell_class_init (GtkObjectClass *object_class)
ecc->unrealize = ec_unrealize;
ecc->draw = ec_draw;
ecc->event = ec_event;
+ ecc->focus = ec_focus;
+ ecc->unfocus = ec_unfocus;
+}
+
+static void
+e_cell_init (GtkObject *object)
+{
+ ECell *e_cell = E_CELL (object);
}
-E_MAKE_TYPE(e_cell, "ECell", ECell, e_cell_class_init, NULL, PARENT_TYPE);
+E_MAKE_TYPE(e_cell, "ECell", ECell, e_cell_class_init, e_cell_init, PARENT_TYPE);
+void
+e_cell_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
+{
+ E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->event (
+ ecell_view, event, col, row);
+}
+
+ECellView *
+e_cell_realize (ECell *ecell, GnomeCanvas *canvas)
+{
+ return E_CELL_CLASS (GTK_OBJECT (ecell)->klass)->realize (
+ ecell, canvas);
+}
+
+void
+e_cell_unrealize (ECellView *ecell_view)
+{
+ E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->unrealize (ecell_view);
+}
+
+void
+e_cell_draw (ECellView *ecell_view, GdkDrawable *drawable,
+ int col, int row, int x1, int y1, int x2, int y2)
+{
+ E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->draw (
+ ecell_view, drawable, col, row, x1, y1, x2, y2);
+}
+
diff --git a/widgets/table/e-cell.h b/widgets/table/e-cell.h
index 8395d3e290..0cafe0fff4 100644
--- a/widgets/table/e-cell.h
+++ b/widgets/table/e-cell.h
@@ -2,6 +2,7 @@
#define _E_CELL_H_
#include <libgnomeui/gnome-canvas.h>
+#include "e-table-model.h"
#define E_CELL_TYPE (e_cell_get_type ())
#define E_CELL(o) (GTK_CHECK_CAST ((o), E_CELL_TYPE, ECell))
@@ -9,19 +10,42 @@
#define E_IS_CELL(o) (GTK_CHECK_TYPE ((o), E_CELL_TYPE))
#define E_IS_CELL_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_CELL_TYPE))
-typedef struct {
+typedef struct _ECell ECell;
+typedef struct _ECellView ECellView;
+
+struct _ECell {
GtkObject object;
-} ECell;
+
+ ETableModel *table_model;
+};
+
+struct _ECellView {
+ ECell *ecell;
+ gint focus_x1, focus_y1, focus_x2, focus_y2;
+ gint focus_col, focus_row;
+};
+
+#define E_CELL_IS_FOCUSED(ecell_view) (ecell_view->focus_x1 != -1)
typedef struct {
GtkObjectClass parent_class;
- void (*realize) (ECell *, GnomeCanvas *canvas);
- void (*unrealize) (ECell *);
- void (*draw) (ECell *ecell, int x1, int y1, int x2, int y2);
- gint (*event) (ECell *ecell, GdkEvent *event);
+ ECellView *(*realize) (ECell *, GnomeCanvas *canvas);
+ void (*unrealize) (ECellView *);
+ void (*draw) (ECellView *ecell_view, GdkDrawable *drawable,
+ int col, int row, int x1, int y1, int x2, int y2);
+ gint (*event) (ECellView *ecell_view, GdkEvent *event, int col, int row);
+ void (*focus) (ECellView *ecell, int col, int row, int x1, int y1, int x2, int y2);
+ void (*unfocus) (ECellView *ecell);
} ECellClass;
-GtkType e_cell_get_type (void);
+GtkType e_cell_get_type (void);
+void e_cell_event (ECellView *ecell_view, GdkEvent *event, int col, int row);
+ECellView *e_cell_realize (ECell *ecell, GnomeCanvas *canvas);
+void e_cell_unrealize (ECellView *ecell);
+void e_cell_draw (ECellView *ecell, GdkDrawable *dr,
+ int col, int row, int x1, int y1, int x2, int y2);
+void e_cell_focus (ECellView *ecell, int col, int row, int x1, int y1, int x2, int y2);
+void e_cell_unfocus (ECellView *ecell);
#endif /* _E_CELL_H_ */
diff --git a/widgets/table/e-table-col.c b/widgets/table/e-table-col.c
index c75bc6b195..4c61cddd0f 100644
--- a/widgets/table/e-table-col.c
+++ b/widgets/table/e-table-col.c
@@ -13,8 +13,7 @@
ETableCol *
e_table_col_new (const char *id, int width, int min_width,
- ETableColRenderFn render, void *render_data,
- GCompareFunc compare, gboolean resizable)
+ ECell *ecell, GCompareFunc compare, gboolean resizable)
{
ETableCol *etc;
@@ -22,7 +21,6 @@ e_table_col_new (const char *id, int width, int min_width,
g_return_if_fail (width >= 0);
g_return_if_fail (min_width >= 0);
g_return_if_fail (width >= min_width);
- g_return_if_fail (render != NULL);
g_return_if_fail (compare != NULL);
etc = g_new (ETableCol, 1);
@@ -30,8 +28,7 @@ e_table_col_new (const char *id, int width, int min_width,
etc->id = g_strdup (id);
etc->width = width;
etc->min_width = min_width;
- etc->render = render;
- etc->render_data = render_data;
+ etc->ecell = ecell;
etc->compare = compare;
etc->selected = 0;
diff --git a/widgets/table/e-table-col.h b/widgets/table/e-table-col.h
index 215df07797..950bf23352 100644
--- a/widgets/table/e-table-col.h
+++ b/widgets/table/e-table-col.h
@@ -2,13 +2,7 @@
#define _E_TABLE_COL_H_
typedef struct _ETableCol ETableCol;
-
-/*
- * Rendering function for the column header
- */
-typedef struct ERenderContext ERenderContext;
-
-typedef void (*ETableColRenderFn)(ERenderContext *ctxt);
+typedef struct _ECell ECell;
/*
* Information about a single column
@@ -18,16 +12,17 @@ struct _ETableCol {
short width;
short min_width;
short x;
- ETableColRenderFn render;
GCompareFunc compare;
- void *render_data;
unsigned int selected:1;
unsigned int resizeable:1;
+
+ ECell *ecell;
};
ETableCol *e_table_col_new (const char *id, int width, int min_width,
- ETableColRenderFn render, void *render_data,
- GCompareFunc compare, gboolean resizable);
+ ECell *ecell, GCompareFunc compare,
+ gboolean resizable);
#endif /* _E_TABLE_COL_H_ */
+
diff --git a/widgets/table/e-table-header-item.c b/widgets/table/e-table-header-item.c
index dab5d3d71d..ab59d9a01c 100644
--- a/widgets/table/e-table-header-item.c
+++ b/widgets/table/e-table-header-item.c
@@ -157,6 +157,7 @@ ethi_realize (GnomeCanvasItem *item)
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
GdkWindow *window;
GdkColor c;
+ int i;
if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)-> realize)
(*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->realize)(item);
@@ -171,13 +172,27 @@ ethi_realize (GnomeCanvasItem *item)
if (!ethi->font)
ethi_font_load (ethi, "fixed");
+
+ /*
+ * Now realize the various ECells
+ */
+ ethi->n_cells = e_table_header_count (ethi->eth);
+ ethi->cell_views = g_new (ECellView *, ethi->n_cells);
+
+ for (i = 0; i < ethi->n_cells; i++){
+ ETableCol *col = e_table_header_get_column (ethi->eth, i);
+
+ ethi->cell_views [i] = e_cell_realize (col->ecell, item->canvas);
+ }
+
}
static void
ethi_unrealize (GnomeCanvasItem *item)
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
-
+ int i;
+
gdk_gc_unref (ethi->gc);
ethi->gc = NULL;
@@ -187,6 +202,14 @@ ethi_unrealize (GnomeCanvasItem *item)
gdk_cursor_destroy (ethi->normal_cursor);
ethi->normal_cursor = NULL;
+ for (i = 0; i < ethi->n_cells; i++){
+ ETableCol *col = e_table_header_get_column (ethi->eth, i);
+
+ e_cell_unrealize (col->ecell, ethi->cell_views [i]);
+ ethi->cell_views = NULL;
+ }
+ g_free (ethi->cell_views);
+
if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize)
(*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize)(item);
}
@@ -244,8 +267,10 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x1, int y1, int wid
total = 0;
x = -x1;
+#if 0
printf ("My coords are: %g %g %g %g\n",
item->x1, item->y1, item->x2, item->y2);
+#endif
for (col = 0; col < cols; col++){
ETableCol *ecol = e_table_header_get_column (ethi->eth, col);
@@ -353,11 +378,6 @@ ethi_end_resize (ETableHeaderItem *ethi, int new_size)
{
e_table_header_set_size (ethi->eth, ethi->resize_col, new_size);
- if (ethi->resize_guide){
-#warning Fix this
- /* gtk_object_destroy (ethi->resize_guide);*/
- ethi->resize_guide = NULL;
- }
ethi->resize_col = -1;
ethi_request_redraw (ethi);
}
@@ -394,9 +414,12 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
if (x - ethi->resize_start_pos <= 0)
break;
-
+
+ ethi_request_redraw (ethi);
+
ethi->resize_width = x - ethi->resize_start_pos;
-
+ e_table_header_set_size (ethi->eth, ethi->resize_col, ethi->resize_width);
+
ethi_request_redraw (ethi);
} else
set_cursor (ethi, x);
diff --git a/widgets/table/e-table-header-item.h b/widgets/table/e-table-header-item.h
index d6b7d64a9f..10b84e1897 100644
--- a/widgets/table/e-table-header-item.h
+++ b/widgets/table/e-table-header-item.h
@@ -10,6 +10,8 @@
#define E_IS_TABLE_HEADER_ITEM(o) (GTK_CHECK_TYPE ((o), E_TABLE_HEADER_ITEM_TYPE))
#define E_IS_TABLE_HEADER_ITEM_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_HEADER_ITEM_TYPE))
+typedef struct _ECellView ECellView;
+
typedef struct {
GnomeCanvasItem parent;
ETableHeader *eth;
@@ -28,6 +30,9 @@ typedef struct {
int resize_start_pos;
GtkObject *resize_guide;
+ ECellView **cell_views;
+ int n_cells;
+
/*
* Ids
*/
diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c
index 1e53180804..5bf1e24fd0 100644
--- a/widgets/table/e-table-item.c
+++ b/widgets/table/e-table-item.c
@@ -44,9 +44,11 @@ eti_remove_table_model (ETableItem *eti)
return;
gtk_signal_disconnect (eti->table_model_change_id);
+ gtk_signal_disconnect (eti->table_model_selection_id);
gtk_object_unref (GTK_OBJECT (eti->table_model));
eti->table_model_change_id = 0;
+ eti->table_model_selection_id = 0;
eti->table_model = NULL;
}
@@ -74,6 +76,23 @@ eti_table_model_changed (ETableModel *table_model, ETableItem *eti)
}
static void
+eti_request_redraw (ETableItem *eti)
+{
+ GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
+
+ gnome_canvas_request_redraw (canvas, eti->x1, eti->y1,
+ eti->x1 + eti->width + 1,
+ eti->y1 + eti->height + 1);
+}
+
+static void
+eti_table_model_row_selection (ETableModel *table_model, ETableItem *eti)
+{
+ /* FIXME: we should optimize this to only redraw the selection change */
+ eti_request_redraw (eti);
+}
+
+static void
eti_add_table_model (ETableItem *eti, ETableModel *table_model)
{
g_assert (eti->table_model == NULL);
@@ -83,31 +102,30 @@ eti_add_table_model (ETableItem *eti, ETableModel *table_model)
eti->table_model_change_id = gtk_signal_connect (
GTK_OBJECT (table_model), "model_changed",
GTK_SIGNAL_FUNC (eti_table_model_changed), eti);
-}
-
-static void
-eti_request_redraw (ETableItem *eti)
-{
- GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
-
- gnome_canvas_request_redraw (canvas, eti->x1, eti->y1, eti->x1 + eti->width, eti->y1 + eti->height);
+ eti->table_model_selection_id = gtk_signal_connect (
+ GTK_OBJECT (table_model), "row_selection",
+ GTK_SIGNAL_FUNC (eti_table_model_row_selection), eti);
}
static void
eti_header_dim_changed (ETableHeader *eth, int col, ETableItem *eti)
{
- eti->width = e_table_header_total_width (eti->header);
+ eti_request_redraw (eti);
+ eti->width = e_table_header_total_width (eti->header);
eti_update (GNOME_CANVAS_ITEM (eti), NULL, NULL, 0);
+
eti_request_redraw (eti);
}
static void
eti_header_structure_changed (ETableHeader *eth, ETableItem *eti)
{
- eti->width = e_table_header_total_width (eti->header);
+ eti_request_redraw (eti);
+ eti->width = e_table_header_total_width (eti->header);
eti_update (GNOME_CANVAS_ITEM (eti), NULL, NULL, 0);
+
eti_request_redraw (eti);
}
@@ -181,6 +199,9 @@ static void
eti_init (GnomeCanvasItem *item)
{
ETableItem *eti = E_TABLE_ITEM (item);
+
+ eti->focused_col = -1;
+ eti->focused_row = -1;
}
static void
@@ -199,6 +220,7 @@ eti_realize (GnomeCanvasItem *item)
gdk_gc_ref (canvas_widget->style->white_gc);
eti->grid_gc = gdk_gc_new (window);
gdk_gc_set_foreground (eti->grid_gc, &canvas_widget->style->fg [GTK_STATE_NORMAL]);
+
}
static void
@@ -277,7 +299,10 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
if (first_col == -1)
return;
+#if 0
printf ("Cols %d %d\n", first_col, last_col);
+#endif
+
/*
* Draw individual lines
*/
@@ -318,6 +343,25 @@ eti_point (GnomeCanvasItem *item, double x, double y, int cx, int cy,
static int
eti_event (GnomeCanvasItem *item, GdkEvent *e)
{
+ ETableItem *eti = E_TABLE_ITEM (item);
+ ETableCol *etc;
+
+ switch (e->type){
+ case GDK_BUTTON_PRESS:
+ case GDK_BUTTON_RELEASE:
+ case GDK_2BUTTON_PRESS:
+
+ case GDK_KEY_PRESS:
+ case GDK_KEY_RELEASE:
+ if (eti->focused_col == -1)
+ return FALSE;
+
+ etc = e_table_header_get_column (eti->header, eti->focused_col);
+
+ e_cell_event (etc->ecell, e, eti->focused_col, eti->focused_row);
+ break;
+
+ }
return FALSE;
}
@@ -371,3 +415,19 @@ e_table_item_get_type (void)
return type;
}
+void
+e_table_item_focus (ETableItem *eti, int col, int row)
+{
+ if (eti->focused_col != -1)
+ e_table_item_unfocus (eti);
+
+ eti->focused_col = col;
+ eti->focused_row = row;
+}
+
+void
+e_table_item_unfocus (ETableItem *eti)
+{
+ eti->focused_col = -1;
+ eti->focused_row = -1;
+}
diff --git a/widgets/table/e-table-item.h b/widgets/table/e-table-item.h
index 7e548cf49d..fefa221227 100644
--- a/widgets/table/e-table-item.h
+++ b/widgets/table/e-table-item.h
@@ -27,11 +27,14 @@ typedef struct {
int header_dim_change_id;
int header_structure_change_id;
int table_model_change_id;
-
+ int table_model_selection_id;
+
GdkGC *fill_gc;
GdkGC *grid_gc;
unsigned int draw_grid:1;
+
+ int focused_col, focused_row;
} ETableItem;
typedef struct {
@@ -39,5 +42,7 @@ typedef struct {
} ETableItemClass;
GtkType e_table_item_get_type (void);
+void e_table_item_focus (ETableItem *eti, int col, int row);
+void e_table_item_unfocus (ETableItem *eti);
#endif /* _E_TABLE_ITEM_H_ */
diff --git a/widgets/table/e-table-model.c b/widgets/table/e-table-model.c
index de7bc67c51..1176b33ec7 100644
--- a/widgets/table/e-table-model.c
+++ b/widgets/table/e-table-model.c
@@ -16,6 +16,7 @@ static GtkObjectClass *e_table_model_parent_class;
enum {
MODEL_CHANGED,
+ ROW_SELECTION,
LAST_SIGNAL
};
@@ -88,6 +89,14 @@ e_table_model_class_init (GtkObjectClass *object_class)
GTK_SIGNAL_OFFSET (ETableModelClass, model_changed),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
+
+ etm_signals [ROW_SELECTION] =
+ gtk_signal_new ("row_selection",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETableModelClass, row_selection),
+ gtk_marshal_NONE__INT_INT,
+ GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
gtk_object_class_add_signals (object_class, etm_signals, LAST_SIGNAL);
}
@@ -158,3 +167,29 @@ e_table_model_max_col_width (ETableModel *etm, int col)
return max;
}
#endif
+
+void
+e_table_model_select_row (ETableModel *etm, int row)
+{
+ gtk_signal_emit (GTK_OBJECT (etm), etm_signals [ROW_SELECTION], row, 1);
+ etm->row_selected = row;
+}
+
+void
+e_table_model_unselect_row (ETableModel *etm, int row)
+{
+ if (etm->row_selected != -1){
+ gtk_signal_emit (
+ GTK_OBJECT (etm), etm_signals [ROW_SELECTION],
+ etm->row_selected, 0);
+ }
+
+ etm->row_selected = -1;
+}
+
+gint
+e_table_model_get_selected_row (ETableModel *etm)
+{
+ return etm->row_selected;
+}
+
diff --git a/widgets/table/e-table-model.h b/widgets/table/e-table-model.h
index d12a465c0b..2d439a0065 100644
--- a/widgets/table/e-table-model.h
+++ b/widgets/table/e-table-model.h
@@ -11,6 +11,9 @@
typedef struct {
GtkObject base;
+
+ /* Temporary. I swear */
+ int row_selected;
} ETableModel;
typedef struct {
@@ -30,7 +33,8 @@ typedef struct {
/*
* Signals
*/
- void (*model_changed) (ETableModel *etm, int row);
+ void (*model_changed) (ETableModel *etm);
+ void (*row_selection) (ETableModel *etc, int row);
} ETableModelClass;
GtkType e_table_model_get_type (void);
@@ -44,6 +48,9 @@ void *e_table_model_value_at (ETableModel *e_table_model, int col,
void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, void *data);
gboolean e_table_model_is_cell_editable (ETableModel *e_table_model, int col, int row);
+void e_table_model_select_row (ETableModel *e_table_model, int row);
+gint e_table_model_get_selected_row (ETableModel *e_table_model);
+
/*
* Routines for emitting signals on the e_table
*/
diff --git a/widgets/table/e-table-simple.c b/widgets/table/e-table-simple.c
index 32f7145bc6..b23cda1220 100644
--- a/widgets/table/e-table-simple.c
+++ b/widgets/table/e-table-simple.c
@@ -12,6 +12,8 @@
#include <config.h>
#include "e-table-simple.h"
+#define PARENT_TYPE e_table_model_get_type()
+
static int
simple_column_count (ETableModel *etm)
{
@@ -99,7 +101,7 @@ e_table_simple_get_type (void)
(GtkClassInitFunc) NULL
};
- type = gtk_type_unique (e_table_model_get_type (), &info);
+ type = gtk_type_unique (PARENT_TYPE, &info);
}
return type;
diff --git a/widgets/table/e-table-sorted.c b/widgets/table/e-table-sorted.c
index 2d53c79e5d..be19de2efb 100644
--- a/widgets/table/e-table-sorted.c
+++ b/widgets/table/e-table-sorted.c
@@ -11,93 +11,16 @@
#include "e-util.h"
#include "e-table-sorted.h"
-#define PARENT_TYPE E_TABLE_MODEL_TYPE
+#define PARENT_TYPE E_TABLE_SUBSET_TYPE
static ETableModelClass *ets_parent_class;
static void
-ets_destroy (GtkObject *object)
-{
- ETableSorted *ets = E_TABLE_SORTED (object);
-
- gtk_object_unref (GTK_OBJECT (ets->source));
- gtk_object_unref (GTK_OBJECT (ets->header));
- free (ets->map_table);
-
- GTK_OBJECT_CLASS (ets_parent_class)->destroy (object);
-}
-
-static int
-ets_column_count (ETableModel *etm)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_column_count (ets->source);
-}
-
-static const char *
-ets_column_name (ETableModel *etm, int col)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_column_name (ets->source, col);
-}
-
-static int
-ets_row_count (ETableModel *etm)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_row_count (ets->source);
-}
-
-static void *
-ets_value_at (ETableModel *etm, int col, int row)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_value_at (ets->source, col, ets->map_table [row]);
-}
-
-static void
-ets_set_value_at (ETableModel *etm, int col, int row, void *val)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_set_value_at (ets->source, col, ets->map_table [row], val);
-}
-
-static gboolean
-ets_is_cell_editable (ETableModel *etm, int col, int row)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_is_cell_editable (ets->source, col, ets->map_table [row]);
-}
-
-static int
-ets_row_height (ETableModel *etm, int row)
-{
- ETableSorted *ets = (ETableSorted *)etm;
-
- return e_table_model_row_height (ets->source, ets->map_table [row]);
-}
-
-static void
ets_class_init (GtkObjectClass *klass)
{
ETableModelClass *table_class = (ETableModelClass *) klass;
ets_parent_class = gtk_type_class (PARENT_TYPE);
- klass->destroy = ets_destroy;
-
- table_class->column_count = ets_column_count;
- table_class->column_name = ets_column_name;
- table_class->row_count = ets_row_count;
- table_class->value_at = ets_value_at;
- table_class->set_value_at = ets_set_value_at;
- table_class->is_cell_editable = ets_is_cell_editable;
- table_class->row_height = ets_row_height;
}
E_MAKE_TYPE(e_table_sorted, "ETableSorted", ETableSorted, ets_class_init, NULL, PARENT_TYPE);
@@ -108,49 +31,63 @@ static int
my_sort (const void *a, const void *b)
{
GCompareFunc comp;
+ ETableModel *source = E_TABLE_SUBSET (sort_ets)->source;
const int *ia = (const int *) a;
const int *ib = (const int *) b;
void *va, *vb;
- va = e_table_model_value_at (sort_ets->source, sort_ets->sort_idx, *ia);
- vb = e_table_model_value_at (sort_ets->source, sort_ets->sort_idx, *ib);
+ va = e_table_model_value_at (source, sort_ets->sort_col, *ia);
+ vb = e_table_model_value_at (source, sort_ets->sort_col, *ib);
- comp = sort_ets->sort_col->compare;
+ return (*sort_ets->compare) (va, vb);
+}
- return (*comp) (va, vb);
+static void
+do_sort (ETableSorted *ets)
+{
+ ETableSubset *etss = E_TABLE_SUBSET (ets);
+ g_assert (sort_ets == NULL);
+
+ sort_ets = ets;
+ qsort (etss->map_table, etss->n_map, sizeof (unsigned int), my_sort);
+ sort_ets = NULL;
}
ETableModel *
-e_table_sorted_new (ETableModel *source, ETableHeader *header, short sort_field)
+e_table_sorted_new (ETableModel *source, int col, GCompareFunc compare)
{
ETableSorted *ets = gtk_type_new (E_TABLE_SORTED_TYPE);
+ ETableSubset *etss = E_TABLE_SUBSET (ets);
const int nvals = e_table_model_row_count (source);
unsigned int *buffer;
int i;
- buffer = malloc (sizeof (unsigned int *) * nvals);
- if (buffer = NULL)
+ if (e_table_subset_construct (etss, source, nvals) == NULL){
+ gtk_object_destroy (GTK_OBJECT (ets));
return NULL;
- ets->map_table = buffer;
- ets->n_map = nvals;
- ets->source = source;
- ets->header = header;
- ets->sort_col = e_table_header_get_column (header, sort_field);
- ets->sort_idx = sort_field;
- gtk_object_ref (GTK_OBJECT (source));
- gtk_object_ref (GTK_OBJECT (header));
+ }
+
+ ets->compare = compare;
+ ets->sort_col = col;
/* Init */
for (i = 0; i < nvals; i++)
- ets->map_table [i] = i;
+ etss->map_table [i] = i;
- /* Sort */
- g_assert (sort_ets == NULL);
- sort_ets = ets;
- qsort (ets->map_table, nvals, sizeof (unsigned int), my_sort);
- sort_ets = NULL;
+ do_sort (ets);
return (ETableModel *) ets;
}
-
+void
+e_table_sorted_resort (ETableSorted *ets, int col, GCompareFunc compare)
+{
+ if (col == -1 || compare == NULL)
+ do_sort (ets);
+ else {
+ ets->sort_col = col;
+ ets->compare = compare;
+ do_sort (ets);
+ }
+}
+
diff --git a/widgets/table/e-table-sorted.h b/widgets/table/e-table-sorted.h
index 65578b7b83..2ec52df2e7 100644
--- a/widgets/table/e-table-sorted.h
+++ b/widgets/table/e-table-sorted.h
@@ -3,7 +3,7 @@
#include <gtk/gtkobject.h>
#include "e-table-model.h"
-#include "e-table-header.h"
+#include "e-table-subset.h"
#define E_TABLE_SORTED_TYPE (e_table_sorted_get_type ())
#define E_TABLE_SORTED(o) (GTK_CHECK_CAST ((o), E_TABLE_SORTED_TYPE, ETableSorted))
@@ -12,23 +12,18 @@
#define E_IS_TABLE_SORTED_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_SORTED_TYPE))
typedef struct {
- ETableModel base;
+ ETableSubset base;
- ETableModel *source;
- ETableHeader *header;
- ETableCol *sort_col;
- short sort_idx;
-
- int n_map;
- unsigned int *map_table;
+ short sort_col;
+ GCompareFunc compare;
} ETableSorted;
typedef struct {
- ETableModelClass parent_class;
+ ETableSubset parent_class;
} ETableSortedClass;
GtkType e_table_sorted_get_type (void);
-ETableModel *e_table_sorted_new (ETableModel *etm, ETableHeader *header,
- short sort_field);
+ETableModel *e_table_sorted_new (ETableModel *etm, int col, GCompareFunc compare);
+void e_table_sorted_resort (ETableSorted *ets, int col, GCompareFunc compare);
#endif /* _E_TABLE_SORTED_H_ */
diff --git a/widgets/table/e-table-subset.c b/widgets/table/e-table-subset.c
index 0b9621ac84..afa1b862b4 100644
--- a/widgets/table/e-table-subset.c
+++ b/widgets/table/e-table-subset.c
@@ -19,52 +19,122 @@ etss_destroy (GtkObject *object)
{
ETableSubset *etss = E_TABLE_SUBSET (object);
- gtk_object_unref (GTK_OBJECT (etss->source));
- free (ets->subset_table);
+ if (etss->source)
+ gtk_object_unref (GTK_OBJECT (etss->source));
- GTK_OBJECT_CLASS (ets_parent_class)->destroy (object);
+ if (etss->map_table)
+ free (etss->map_table);
+
+ GTK_OBJECT_CLASS (etss_parent_class)->destroy (object);
+}
+
+static int
+etss_column_count (ETableModel *etm)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_column_count (etss->source);
+}
+
+static const char *
+etss_column_name (ETableModel *etm, int col)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_column_name (etss->source, col);
+}
+
+static int
+etss_row_count (ETableModel *etm)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_row_count (etss->source);
+}
+
+static void *
+etss_value_at (ETableModel *etm, int col, int row)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_value_at (etss->source, col, etss->map_table [row]);
+}
+
+static void
+etss_set_value_at (ETableModel *etm, int col, int row, void *val)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_set_value_at (etss->source, col, etss->map_table [row], val);
+}
+
+static gboolean
+etss_is_cell_editable (ETableModel *etm, int col, int row)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_is_cell_editable (etss->source, col, etss->map_table [row]);
+}
+
+static int
+etss_row_height (ETableModel *etm, int row)
+{
+ ETableSubset *etss = (ETableSubset *)etm;
+
+ return e_table_model_row_height (etss->source, etss->map_table [row]);
}
static void
etss_class_init (GtkObjectClass *klass)
{
+ ETableModelClass *table_class = (ETableModelClass *) klass;
+
etss_parent_class = gtk_type_class (PARENT_TYPE);
klass->destroy = etss_destroy;
+
+ table_class->column_count = etss_column_count;
+ table_class->column_name = etss_column_name;
+ table_class->row_count = etss_row_count;
+ table_class->value_at = etss_value_at;
+ table_class->set_value_at = etss_set_value_at;
+ table_class->is_cell_editable = etss_is_cell_editable;
+ table_class->row_height = etss_row_height;
+
}
E_MAKE_TYPE(e_table_subset, "ETableSubset", ETableSubset, etss_class_init, NULL, PARENT_TYPE);
ETableModel *
-e_table_subset_new (ETableModel *source, ETableHeader *header, short sort_field)
+e_table_subset_construct (ETableSubset *etss, ETableModel *source, int nvals)
{
- ETableSorted *ets = gtk_type_new (E_TABLE_SORTED_TYPE);
- const int nvals = e_table_model_row_count (source);
unsigned int *buffer;
int i;
- buffer = malloc (sizeof (unsigned int *) * nvals);
+ buffer = (unsigned int *) malloc (sizeof (unsigned int *) * nvals);
if (buffer = NULL)
return NULL;
- ets->map_table = buffer;
- ets->n_map = nvals;
- ets->source = source;
- ets->header = header;
- ets->sort_col = e_table_header_get_column (header, sort_field);
- ets->sort_idx = sort_field;
+ etss->map_table = buffer;
+ etss->n_map = nvals;
+ etss->source = source;
gtk_object_ref (GTK_OBJECT (source));
- gtk_object_ref (GTK_OBJECT (header));
/* Init */
for (i = 0; i < nvals; i++)
- ets->map_table [i] = i;
+ etss->map_table [i] = i;
- /* Sort */
- g_assert (sort_ets == NULL);
- sort_ets = ets;
- qsort (ets->map_table, nvals, sizeof (unsigned int), my_sort);
- sort_ets = NULL;
-
- return (ETableModel *) ets;
+}
+
+ETableModel *
+e_table_subset_new (ETableModel *source, const int nvals)
+{
+ ETableSubset *etss = gtk_type_new (E_TABLE_SUBSET_TYPE);
+
+ if (e_table_subset_construct (etss, source, nvals) == NULL){
+ gtk_object_destroy (GTK_OBJECT (etss));
+ return NULL;
+ }
+
+ return (ETableModel *) etss;
}
diff --git a/widgets/table/e-table-subset.h b/widgets/table/e-table-subset.h
index a87d6d0df8..5576c55f1d 100644
--- a/widgets/table/e-table-subset.h
+++ b/widgets/table/e-table-subset.h
@@ -3,7 +3,6 @@
#include <gtk/gtkobject.h>
#include "e-table-model.h"
-#include "e-table-header.h"
#define E_TABLE_SUBSET_TYPE (e_table_subset_get_type ())
#define E_TABLE_SUBSET(o) (GTK_CHECK_CAST ((o), E_TABLE_SUBSET_TYPE, ETableSubset))
@@ -15,15 +14,16 @@ typedef struct {
ETableModel base;
ETableModel *source;
- int subset_count;
- int *subset_table;
+ int n_map;
+ int *map_table;
} ETableSubset;
typedef struct {
ETableModelClass parent_class;
} ETableSubsetClass;
-GtkType e_table_subset_get_type (void);
-ETableModel *e_table_subset_new (ETableModel *etm,
- int n_vals, int *ptrs);
+GtkType e_table_subset_get_type (void);
+ETableModel *e_table_subset_new (ETableModel *etm, int n_vals);
+ETableModel *e_table_subset_construct (ETableSubset *ets, ETableModel *source, int nvals);
+
#endif /* _E_TABLE_SUBSET_H_ */
diff --git a/widgets/table/e-table.c b/widgets/table/e-table.c
index 795c737b36..3b13e87d6b 100644
--- a/widgets/table/e-table.c
+++ b/widgets/table/e-table.c
@@ -9,28 +9,14 @@
#include <config.h>
#include <libgnomeui/gnome-canvas.h>
#include "e-table.h"
+#include "e-util.h"
#define PARENT_OBJECT_TYPE gnome_canvas_get_type ()
-GtkType
-e_table_get_type (void)
-{
- static GtkType type = 0;
-
- if (!type){
- GtkTypeInfo info = {
- "ETable",
- sizeof (ETable),
- sizeof (ETableClass),
- (GtkClassInitFunc) e_table_class_init,
- (GtkObjectInitFunc) NULL,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (PARENT_OBJECT_TYPE, &info);
- }
+E_MAKE_TYPE(e_table, "ETable", ETable, e_table_class_init, NULL, PARENT_TYPE);
- return type;
+ETable *
+e_table_new (ETableHeader *eth, ETableModel *etm)
+{
}
+
diff --git a/widgets/table/table-test.c b/widgets/table/table-test.c
index 54392a73bc..e646b44655 100644
--- a/widgets/table/table-test.c
+++ b/widgets/table/table-test.c
@@ -11,7 +11,6 @@
#include "e-table-simple.h"
#include "e-table-header.h"
#include "e-table-header-item.h"
-#include "e-table-render.h"
#include "e-table-item.h"
char buffer [1024];
@@ -185,6 +184,7 @@ main (int argc, char *argv [])
GtkWidget *canvas, *window;
ETableModel *e_table_model;
ETableHeader *e_table_header;
+ ECell *cell_left_just;
int i;
gnome_init ("TableTest", "TableTest", argc, argv);
@@ -203,10 +203,12 @@ main (int argc, char *argv [])
* Header
*/
e_table_header = e_table_header_new ();
+ cell_left_just = e_cell_text_new ("fixed", GTK_JUSTIFY_LEFT);
+
for (i = 0; i < cols; i++){
ETableCol *ecol = e_table_col_new (
- column_labels [i], 80, 20, e_table_render_string,
- NULL, g_str_equal, TRUE);
+ column_labels [i], 80, 20, cell_left_just,
+ g_str_equal, TRUE);
e_table_header_add_column (e_table_header, ecol, i);
}