aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--widgets/ChangeLog13
-rw-r--r--widgets/e-cell-text.c361
-rw-r--r--widgets/e-cell.c25
-rw-r--r--widgets/e-cell.h20
-rw-r--r--widgets/e-table-item.c87
-rw-r--r--widgets/e-table-item.h17
-rw-r--r--widgets/e-table-model.c2
-rw-r--r--widgets/e-table-model.h4
-rw-r--r--widgets/e-table-simple.c2
-rw-r--r--widgets/e-table-simple.h2
-rw-r--r--widgets/e-table/ChangeLog13
-rw-r--r--widgets/e-table/e-cell-text.c361
-rw-r--r--widgets/e-table/e-cell.c25
-rw-r--r--widgets/e-table/e-cell.h20
-rw-r--r--widgets/e-table/e-table-item.c87
-rw-r--r--widgets/e-table/e-table-item.h17
-rw-r--r--widgets/e-table/e-table-model.c2
-rw-r--r--widgets/e-table/e-table-model.h4
-rw-r--r--widgets/e-table/e-table-simple.c2
-rw-r--r--widgets/e-table/e-table-simple.h2
-rw-r--r--widgets/e-table/table-test.c3
-rw-r--r--widgets/table-test.c3
-rw-r--r--widgets/table/e-cell-text.c361
-rw-r--r--widgets/table/e-cell.c25
-rw-r--r--widgets/table/e-cell.h20
-rw-r--r--widgets/table/e-table-item.c87
-rw-r--r--widgets/table/e-table-item.h17
-rw-r--r--widgets/table/e-table-model.c2
-rw-r--r--widgets/table/e-table-model.h4
-rw-r--r--widgets/table/e-table-simple.c2
-rw-r--r--widgets/table/e-table-simple.h2
-rw-r--r--widgets/table/table-test.c3
32 files changed, 1301 insertions, 294 deletions
diff --git a/widgets/ChangeLog b/widgets/ChangeLog
index 20d4c1e3d7..afc69d71a4 100644
--- a/widgets/ChangeLog
+++ b/widgets/ChangeLog
@@ -1,3 +1,16 @@
+1999-11-28 Miguel de Icaza <miguel@gnu.org>
+
+ * e-cell-text.c (ect_enter_edit, ect_leave_edit): New methods;
+ They implement editing.
+
+ * e-cell.h: new methods: enter_edit, leave_edit
+
+ * e-table-model.h (set_value_at): make val argument const.
+
+ * e-table-simple.c (simple_set_value_at): Make value argument const;
+
+ * e-table-item.c (eti_set_arg): Add new mode: draw_focus;
+
1999-11-27 Miguel de Icaza <miguel@gnu.org>
* e-table-item.c (eti_event): beginning of the keyboard navigation.
diff --git a/widgets/e-cell-text.c b/widgets/e-cell-text.c
index a997d745d3..f0501ab4cb 100644
--- a/widgets/e-cell-text.c
+++ b/widgets/e-cell-text.c
@@ -8,61 +8,143 @@
*/
#include <config.h>
#include <gtk/gtkenums.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtksignal.h>
+#include <gdk/gdkkeysyms.h>
+#include <libgnomeui/gnome-canvas.h>
#include "e-cell-text.h"
#include "e-util.h"
+#include "e-table-item.h"
#define PARENT_TYPE e_cell_get_type()
#define TEXT_PAD 2
typedef struct {
+ char *old_text;
+ GtkWidget *entry_top;
+ GtkEntry *entry;
+
+ /*
+ * Where the editing is taking place
+ */
+ int col, row;
+} CellEdit;
+
+typedef struct {
ECellView cell_view;
GdkGC *gc;
GdkFont *font;
GnomeCanvas *canvas;
+ ETableItem *eti;
+
+ /*
+ * During edition.
+ */
+ CellEdit *edit;
} ECellTextView;
static ECellClass *parent_class;
+static void
+ect_queue_redraw (ECellTextView *text_view, int col, int row)
+{
+ e_table_item_redraw_range (text_view->eti, col, row, col, row);
+}
+
+/*
+ * Accept the currently edited text
+ */
+static void
+ect_accept_edits (ECellTextView *text_view)
+{
+ const char *text = gtk_entry_get_text (text_view->edit->entry);
+ CellEdit *edit = text_view->edit;
+
+ e_table_model_set_value_at (text_view->eti->table_model, edit->col, edit->row, text);
+}
+
+/*
+ * Shuts down the editing process
+ */
+static void
+ect_stop_editing (ECellTextView *text_view)
+{
+ CellEdit *edit = text_view->edit;
+
+ g_free (edit->old_text);
+ edit->old_text = NULL;
+ gtk_widget_destroy (edit->entry_top);
+ edit->entry_top = NULL;
+ edit->entry = NULL;
+
+ g_free (edit);
+
+ text_view->edit = NULL;
+}
+
+/*
+ * Cancels the edits
+ */
+static void
+ect_cancel_edit (ECellTextView *text_view)
+{
+ ect_queue_redraw (text_view, text_view->edit->col, text_view->edit->row);
+ ect_stop_editing (text_view);
+}
+
+/*
+ * ECell::realize method
+ */
static ECellView *
-ect_realize (ECell *ecell, GnomeCanvas *canvas)
+ect_realize (ECell *ecell, void *view)
{
ECellText *ect = E_CELL_TEXT (ecell);
- ECellTextView *ectv = g_new0 (ECellTextView, 1);
-
- ectv->cell_view.ecell = ecell;
- ectv->gc = gdk_gc_new (GTK_WIDGET (canvas)->window);
+ ECellTextView *text_view = g_new0 (ECellTextView, 1);
+ ETableItem *eti = E_TABLE_ITEM (view);
+ GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
+
+ text_view->cell_view.ecell = ecell;
+ text_view->gc = gdk_gc_new (GTK_WIDGET (canvas)->window);
if (ect->font_name){
GdkFont *f;
f = gdk_fontset_load (ect->font_name);
- ectv->font = f;
+ text_view->font = f;
}
- if (!ectv->font){
- ectv->font = GTK_WIDGET (canvas)->style->font;
+ if (!text_view->font){
+ text_view->font = GTK_WIDGET (canvas)->style->font;
- gdk_font_ref (ectv->font);
+ gdk_font_ref (text_view->font);
}
-
- ectv->canvas = canvas;
- return (ECellView *)ectv;
+ text_view->eti = eti;
+ text_view->canvas = canvas;
+
+ return (ECellView *)text_view;
}
+/*
+ * ECell::unrealize method
+ */
static void
ect_unrealize (ECellView *ecv)
{
- ECellTextView *ectv = (ECellTextView *) ecv;
+ ECellTextView *text_view = (ECellTextView *) ecv;
- gdk_gc_unref (ectv->gc);
- ectv->gc = NULL;
+ gdk_gc_unref (text_view->gc);
+ text_view->gc = NULL;
- gdk_font_unref (ectv->font);
- ectv->font = NULL;
+ gdk_font_unref (text_view->font);
+ text_view->font = NULL;
- g_free (ectv);
+ g_free (text_view);
}
+/*
+ * ECell::draw method
+ */
static void
ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected,
@@ -70,41 +152,117 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
{
ECellText *ect = E_CELL_TEXT (ecell_view->ecell);
ECellTextView *text_view = (ECellTextView *) ecell_view;
+ GtkWidget *w = GTK_WIDGET (text_view->canvas);
GdkRectangle rect;
const char *str = e_table_model_value_at (ecell_view->ecell->table_model, col, row);
- int xoff, w;
+ GdkFont *font = text_view->font;
+ const int height = font->ascent + font->descent;
+ int xoff;
+ gboolean edit_display = FALSE;
+
+ /*
+ * Figure if this cell is being edited
+ */
+ if (text_view->edit){
+ CellEdit *edit = text_view->edit;
+
+ printf ("We are editing a cell [%d %d %d %d]\n", col, row, edit->col, edit->row);
+ if ((edit->col == col) && (edit->row == row))
+ edit_display = TRUE;
+ }
+
+ /*
+ * Be a nice citizen: clip to the region we are supposed to draw on
+ */
rect.x = x1;
rect.y = y1;
rect.width = x2 - x1;
rect.height = y2 - y1;
-
gdk_gc_set_clip_rectangle (text_view->gc, &rect);
- switch (ect->justify){
- case GTK_JUSTIFY_LEFT:
- xoff = 1;
- break;
-
- case GTK_JUSTIFY_RIGHT:
- w = 1 + gdk_text_width (text_view->font, str, strlen (str));
- xoff = (x2 - x1) - w;
- break;
+ if (edit_display){
+ CellEdit *edit = text_view->edit;
+ const char *text = gtk_entry_get_text (edit->entry);
+ GdkWChar *text_wc = g_new (GdkWChar, strlen (text) + 1);
+ int text_wc_len = gdk_mbstowcs (text_wc, text, strlen (text));
+ const int cursor_pos = GTK_EDITABLE (edit->entry)->current_pos;
+ const int left_len = gdk_text_width_wc (text_view->font, text_wc, cursor_pos);
+
+ text_wc [text_wc_len] = 0;
- case GTK_JUSTIFY_CENTER:
- xoff = ((x2 - x1) - gdk_text_width (text_view->font, str, strlen (str))) / 2;
- break;
- default:
+ /*
+ * Find a good spot for painting
+ */
xoff = 0;
- g_warning ("Can not handle GTK_JUSTIFY_FILL");
- break;
- }
+
+ /*
+ * Paint
+ */
+ gdk_gc_set_foreground (text_view->gc, &w->style->base [GTK_STATE_NORMAL]);
+ gdk_draw_rectangle (drawable, text_view->gc, TRUE,
+ rect.x, rect.y, rect.width, rect.height);
+ gdk_gc_set_foreground (text_view->gc, &w->style->text [GTK_STATE_NORMAL]);
+
+ {
+ GdkGC *gc = text_view->gc;
+ const int y = y2 - font->descent - ((y2-y1-height)/2);
+ int px, i;
+
+ px = x1;
+
+ printf ("Cursor at: %d\n", cursor_pos);
+
+ for (i = 0; *text_wc; text_wc++, i++){
+ gdk_draw_text_wc (
+ drawable, font, gc, px, y, text_wc, 1);
+
+ if (i == cursor_pos){
+ gdk_draw_line (
+ drawable, gc,
+ px, y - font->ascent,
+ px, y + font->descent - 1);
+ }
- /* Draw now */
- {
- GtkWidget *w = GTK_WIDGET (text_view->canvas);
+ px += gdk_text_width_wc (font, text_wc, 1);
+ }
+
+ if (i == cursor_pos){
+ gdk_draw_line (
+ drawable, gc,
+ px, y - font->ascent,
+ px, y + font->descent - 1);
+ }
+ }
+ } else {
+ /*
+ * Regular cell
+ */
GdkColor *background, *foreground;
- const int height = text_view->font->ascent + text_view->font->descent;
+ int width;
+
+ /*
+ * Compute draw mode
+ */
+ switch (ect->justify){
+ case GTK_JUSTIFY_LEFT:
+ xoff = 1;
+ break;
+
+ case GTK_JUSTIFY_RIGHT:
+ width = 1 + gdk_text_width (font, str, strlen (str));
+ xoff = (x2 - x1) - width;
+ break;
+
+ case GTK_JUSTIFY_CENTER:
+ xoff = ((x2 - x1) - gdk_text_width (font, str, strlen (str))) / 2;
+ break;
+ default:
+ xoff = 0;
+ g_warning ("Can not handle GTK_JUSTIFY_FILL");
+ break;
+ }
+
if (selected){
background = &w->style->bg [GTK_STATE_SELECTED];
@@ -118,33 +276,58 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
gdk_draw_rectangle (drawable, text_view->gc, TRUE,
rect.x, rect.y, rect.width, rect.height);
gdk_gc_set_foreground (text_view->gc, foreground);
- gdk_draw_string (drawable, text_view->font, text_view->gc,
- x1 + xoff, y2 - text_view->font->descent - ((y2-y1-height)/2), str);
- }
-}
-static void
-e_cell_text_start_editing (ECellText *ect, int col, int row)
-{
- printf ("Starting to edit %d %d\n", col, row);
+ gdk_draw_string (
+ drawable, font, text_view->gc,
+ x1 + xoff,
+ y2 - font->descent - ((y2-y1-height)/2), str);
+ }
}
+/*
+ * ECell::event method
+ */
static gint
ect_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
{
- ECell *ecell = ecell_view->ecell;
- ECellText *ect = E_CELL_TEXT (ecell);
+ ECellTextView *text_view = (ECellTextView *) ecell_view;
switch (event->type){
case GDK_BUTTON_PRESS:
+ if (text_view->edit){
+ printf ("FIXME: Should handle click here\n");
+ } else
+ e_table_item_enter_edit (text_view->eti, col, row);
+ break;
+
+ case GDK_BUTTON_RELEASE:
return TRUE;
- default:
+ case GDK_KEY_PRESS:
+ if (event->key.keyval == GDK_Escape){
+ ect_cancel_edit (text_view);
+ return TRUE;
+ }
+
+ if (!text_view->edit)
+ e_table_item_enter_edit (text_view->eti, col, row);
+
+ gtk_widget_event (GTK_WIDGET (text_view->edit->entry), event);
+ ect_queue_redraw (text_view, col, row);
+ break;
+
+ case GDK_KEY_RELEASE:
break;
+
+ default:
+ return FALSE;
}
- return FALSE;
+ return TRUE;
}
+/*
+ * ECell::height method
+ */
static int
ect_height (ECellView *ecell_view, int col, int row)
{
@@ -153,6 +336,66 @@ ect_height (ECellView *ecell_view, int col, int row)
return (text_view->font->ascent + text_view->font->descent) + TEXT_PAD;
}
+/*
+ * Callback: invoked when the user pressed "enter" on the GtkEntry
+ */
+static void
+ect_entry_activate (GtkEntry *entry, ECellTextView *text_view)
+{
+ e_table_item_leave_edit (text_view->eti);
+}
+
+/*
+ * ECellView::enter_edit method
+ */
+static void *
+ect_enter_edit (ECellView *ecell_view, int col, int row)
+{
+ ECellTextView *text_view = (ECellTextView *) ecell_view;
+ const char *str = e_table_model_value_at (ecell_view->ecell->table_model, col, row);
+ CellEdit *edit;
+
+ printf ("Entering edit mode! [%d %d]\n", col, row);
+
+ edit = g_new (CellEdit, 1);
+ text_view->edit = edit;
+
+ edit->entry = (GtkEntry *) gtk_entry_new ();
+ gtk_entry_set_text (edit->entry, str);
+ edit->old_text = g_strdup (str);
+ gtk_signal_connect (GTK_OBJECT (edit->entry), "activate",
+ GTK_SIGNAL_FUNC (ect_entry_activate), text_view);
+
+ /*
+ * The hack: create this window off-screen
+ */
+ edit->entry_top = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_container_add (GTK_CONTAINER (edit->entry_top), GTK_WIDGET (edit->entry));
+ gtk_widget_set_uposition (edit->entry_top, 20000, 20000);
+ gtk_widget_show_all (edit->entry_top);
+
+ ect_queue_redraw (text_view, col, row);
+
+ return NULL;
+}
+
+/*
+ * ECellView::leave_edit method
+ */
+static void
+ect_leave_edit (ECellView *ecell_view, int col, int row, void *edit_context)
+{
+ ECellTextView *text_view = (ECellTextView *) ecell_view;
+
+ printf ("Leaving edit mode!\n");
+
+ ect_accept_edits (text_view);
+ ect_stop_editing (text_view);
+}
+
+/*
+ * GtkObject::destroy method
+ */
static void
ect_destroy (GtkObject *object)
{
@@ -170,12 +413,14 @@ e_cell_text_class_init (GtkObjectClass *object_class)
object_class->destroy = ect_destroy;
- ecc->realize = ect_realize;
- ecc->unrealize = ect_unrealize;
- ecc->draw = ect_draw;
- ecc->event = ect_event;
- ecc->height = ect_height;
-
+ ecc->realize = ect_realize;
+ ecc->unrealize = ect_unrealize;
+ ecc->draw = ect_draw;
+ ecc->event = ect_event;
+ ecc->height = ect_height;
+ ecc->enter_edit = ect_enter_edit;
+ ecc->leave_edit = ect_leave_edit;
+
parent_class = gtk_type_class (PARENT_TYPE);
}
diff --git a/widgets/e-cell.c b/widgets/e-cell.c
index 9caa31f2ca..2bc49f7a45 100644
--- a/widgets/e-cell.c
+++ b/widgets/e-cell.c
@@ -13,7 +13,7 @@
#define PARENT_TYPE gtk_object_get_type()
static ECellView *
-ec_realize (ECell *e_cell, GnomeCanvas *canvas)
+ec_realize (ECell *e_cell, void *view)
{
return NULL;
}
@@ -28,20 +28,20 @@ ec_draw (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected,
int x1, int y1, int x2, int y2)
{
- g_warning ("e-cell-draw invoked\n");
+ g_error ("e-cell-draw invoked\n");
}
static gint
ec_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
{
- g_warning ("e-cell-event invoked\n");
+ g_error ("e-cell-event invoked\n");
return 0;
}
static gint
ec_height (ECellView *ecell_view, int col, int row)
{
- g_warning ("e-cell-event invoked\n");
+ g_error ("e-cell-event invoked\n");
return 0;
}
@@ -98,10 +98,10 @@ e_cell_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
}
ECellView *
-e_cell_realize (ECell *ecell, GnomeCanvas *canvas)
+e_cell_realize (ECell *ecell, void *view)
{
return E_CELL_CLASS (GTK_OBJECT (ecell)->klass)->realize (
- ecell, canvas);
+ ecell, view);
}
void
@@ -125,3 +125,16 @@ e_cell_height (ECellView *ecell_view, int col, int row)
ecell_view, col, row);
}
+void *
+e_cell_enter_edit (ECellView *ecell_view, int col, int row)
+{
+ return E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->enter_edit (
+ ecell_view, col, row);
+}
+
+void
+e_cell_leave_edit (ECellView *ecell_view, int col, int row, void *edit_context)
+{
+ E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->leave_edit (
+ ecell_view, col, row, edit_context);
+}
diff --git a/widgets/e-cell.h b/widgets/e-cell.h
index 9cd62f3909..b0f62d020c 100644
--- a/widgets/e-cell.h
+++ b/widgets/e-cell.h
@@ -1,7 +1,7 @@
#ifndef _E_CELL_H_
#define _E_CELL_H_
-#include <libgnomeui/gnome-canvas.h>
+#include <gdk/gdktypes.h>
#include "e-table-model.h"
#define E_CELL_TYPE (e_cell_get_type ())
@@ -29,19 +29,22 @@ struct _ECellView {
typedef struct {
GtkObjectClass parent_class;
- ECellView *(*realize) (ECell *, GnomeCanvas *canvas);
- void (*unrealize) (ECellView *);
+ ECellView *(*realize) (ECell *ecell, void *view);
+ void (*unrealize) (ECellView *e_cell_view);
void (*draw) (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected, 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);
- int (*height) (ECellView *ecell, int col, int row);
+ void (*focus) (ECellView *ecell_view, int col, int row, int x1, int y1, int x2, int y2);
+ void (*unfocus) (ECellView *ecell_view);
+ int (*height) (ECellView *ecell_view, int col, int row);
+
+ void *(*enter_edit)(ECellView *ecell_view, int col, int row);
+ void (*leave_edit)(ECellView *ecell_view, int col, int row, void *context);
} ECellClass;
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);
+ECellView *e_cell_realize (ECell *ecell, void *view);
void e_cell_unrealize (ECellView *ecell_view);
void e_cell_draw (ECellView *ecell_view, GdkDrawable *dr,
int col, int row, gboolean selected,
@@ -50,4 +53,7 @@ void e_cell_focus (ECellView *ecell_view, int col, int row, int x1, in
void e_cell_unfocus (ECellView *ecell_view);
int e_cell_height (ECellView *ecell_view, int col, int row);
+void *e_cell_enter_edit(ECellView *ecell_view, int col, int row);
+void e_cell_leave_edit(ECellView *ecell_view, int col, int row, void *edit_context);
+
#endif /* _E_CELL_H_ */
diff --git a/widgets/e-table-item.c b/widgets/e-table-item.c
index a561fbfd15..1b98bbfce4 100644
--- a/widgets/e-table-item.c
+++ b/widgets/e-table-item.c
@@ -37,6 +37,7 @@ enum {
ARG_TABLE_X,
ARG_TABLE_Y,
ARG_TABLE_DRAW_GRID,
+ ARG_TABLE_DRAW_FOCUS,
ARG_LENGHT_THRESHOLD
};
@@ -51,7 +52,6 @@ enum {
static void
eti_realize_cell_views (ETableItem *eti)
{
- GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti);
int i;
/*
@@ -63,7 +63,7 @@ eti_realize_cell_views (ETableItem *eti)
for (i = 0; i < eti->n_cells; i++){
ETableCol *col = e_table_header_get_column (eti->header, i);
- eti->cell_views [i] = e_cell_realize (col->ecell, item->canvas);
+ eti->cell_views [i] = e_cell_realize (col->ecell, eti);
}
}
@@ -117,12 +117,9 @@ eti_remove_table_model (ETableItem *eti)
gtk_signal_disconnect (GTK_OBJECT (eti->table_model),
eti->table_model_change_id);
- gtk_signal_disconnect (GTK_OBJECT (eti->table_model),
- 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;
}
@@ -284,7 +281,9 @@ eti_row_diff (ETableItem *eti, int start_row, int end_row)
* border as well.
*/
static void
-eti_request_region_redraw (ETableItem *eti, int start_col, int start_row, int end_col, int end_row, int border)
+eti_request_region_redraw (ETableItem *eti,
+ int start_col, int start_row,
+ int end_col, int end_row, int border)
{
GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
int x1, y1, width, height;
@@ -301,10 +300,25 @@ eti_request_region_redraw (ETableItem *eti, int start_col, int start_row, int en
eti->y1 + y1 + height + 1 + border);
}
-static void
-eti_table_model_row_selection (ETableModel *table_model, int row, gboolean selected, ETableItem *eti)
+void
+e_table_item_redraw_range (ETableItem *eti,
+ int start_col, int start_row,
+ int end_col, int end_row)
{
- eti_request_region_redraw (eti, 0, row, eti->cols - 1, row, 0);
+ int border;
+
+ g_return_if_fail (eti != NULL);
+ g_return_if_fail (E_IS_TABLE_ITEM (eti));
+
+ if ((start_col == eti->focused_col) ||
+ (end_col == eti->focused_col) ||
+ (start_row == eti->focused_row) ||
+ (end_row == eti->focused_row))
+ border = 2;
+ else
+ border = 0;
+
+ eti_request_region_redraw (eti, start_col, start_row, end_col, end_row, border);
}
static void
@@ -313,14 +327,11 @@ eti_add_table_model (ETableItem *eti, ETableModel *table_model)
g_assert (eti->table_model == NULL);
eti->table_model = table_model;
- gtk_object_ref (GTK_OBJECT (table_model));
+ gtk_object_ref (GTK_OBJECT (eti->table_model));
eti->table_model_change_id = gtk_signal_connect (
GTK_OBJECT (table_model), "model_changed",
GTK_SIGNAL_FUNC (eti_table_model_changed), eti);
- eti->table_model_selection_id = gtk_signal_connect (
- GTK_OBJECT (table_model), "row_selection",
- GTK_SIGNAL_FUNC (eti_table_model_row_selection), eti);
eti_table_model_changed (table_model, eti);
}
@@ -418,6 +429,11 @@ eti_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
case ARG_TABLE_DRAW_GRID:
eti->draw_grid = GTK_VALUE_BOOL (*arg);
+ break;
+
+ case ARG_TABLE_DRAW_FOCUS:
+ eti->draw_focus = GTK_VALUE_BOOL (*arg);
+ break;
}
eti_update (item, NULL, NULL, 0);
}
@@ -529,7 +545,7 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
int f_x1, f_x2, f_y1, f_y2;
gboolean f_found;
- printf ("Rect: %d %d %d %d\n", x, y, width, height);
+/* printf ("Rect: %d %d %d %d\n", x, y, width, height); */
/*
* Clear the background
*/
@@ -604,7 +620,7 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
height = eti_row_height (eti, row);
xd = x_offset;
- printf ("paint: %d %d\n", yd, yd + height);
+/* printf ("paint: %d %d\n", yd, yd + height); */
selected = g_slist_find (eti->selection, GINT_TO_POINTER (row)) != NULL;
@@ -631,9 +647,7 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
/*
* Draw focus
*/
- if (f_found){
- printf ("FOUD: %d %d %d %d!\n",
- f_x1 - 1, f_y1 - 1, f_x2 - f_x1 + 2 , f_y2 - f_y1 + 2);
+ if (f_found && eti->draw_focus){
gdk_draw_rectangle (
drawable, eti->focus_gc, FALSE,
f_x1 - 1, f_y1 - 1, f_x2 - f_x1 + 2 , f_y2 - f_y1 + 2);
@@ -725,6 +739,8 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
}
case GDK_KEY_PRESS:
+ printf ("KEYPRESS!\n");
+
if (eti->focused_col == -1)
return FALSE;
@@ -781,6 +797,7 @@ eti_row_selection (ETableItem *eti, int row, gboolean selected)
eti->selection = g_slist_prepend (eti->selection, GINT_TO_POINTER (row));
else
eti->selection = g_slist_remove (eti->selection, GINT_TO_POINTER (row));
+
}
static void
@@ -813,6 +830,8 @@ eti_class_init (GtkObjectClass *object_class)
GTK_ARG_WRITABLE, ARG_TABLE_Y);
gtk_object_add_arg_type ("ETableItem::drawgrid", GTK_TYPE_BOOL,
GTK_ARG_WRITABLE, ARG_TABLE_DRAW_GRID);
+ gtk_object_add_arg_type ("ETableItem::drawfocus", GTK_TYPE_BOOL,
+ GTK_ARG_WRITABLE, ARG_TABLE_DRAW_FOCUS);
eti_signals [ROW_SELECTION] =
gtk_signal_new ("row_selection",
@@ -862,6 +881,11 @@ e_table_item_focus (ETableItem *eti, int col, int row)
eti->focused_row = row;
eti_request_region_redraw (eti, col, row, col, row, FOCUSED_BORDER);
+
+ /*
+ * make sure we have the Gtk Focus
+ */
+ gtk_widget_grab_focus (GTK_WIDGET (GNOME_CANVAS_ITEM (eti)->canvas));
}
void
@@ -944,7 +968,7 @@ void
e_table_item_select_row (ETableItem *eti, int row)
{
g_return_if_fail (eti != NULL);
- g_return_if_fail (E_IS_TABLE_ITEM (eti));
+ g_return_if_fail (E_IS_TABLE_ITEM (eti));
switch (eti->selection_mode){
case GTK_SELECTION_SINGLE:
@@ -973,3 +997,28 @@ e_table_item_select_row (ETableItem *eti, int row)
}
}
+
+void
+e_table_item_enter_edit (ETableItem *eti, int col, int row)
+{
+ g_return_if_fail (eti != NULL);
+ g_return_if_fail (E_IS_TABLE_ITEM (eti));
+
+ eti->editing_col = col;
+ eti->editing_row = row;
+
+ eti->edit_ctx = e_cell_enter_edit (eti->cell_views [col], col, row);
+}
+
+void
+e_table_item_leave_edit (ETableItem *eti)
+{
+ g_return_if_fail (eti != NULL);
+ g_return_if_fail (E_IS_TABLE_ITEM (eti));
+
+ e_cell_leave_edit (eti->cell_views [eti->editing_col], eti->editing_col, eti->editing_row, eti->edit_ctx);
+ eti->editing_col = -1;
+ eti->editing_row = -1;
+ eti->edit_ctx = NULL;
+}
+
diff --git a/widgets/e-table-item.h b/widgets/e-table-item.h
index 17d422ddf5..02f7beb1ac 100644
--- a/widgets/e-table-item.h
+++ b/widgets/e-table-item.h
@@ -28,14 +28,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;
GdkGC *focus_gc;
unsigned int draw_grid:1;
-
+ unsigned int draw_focus:1;
+
int focused_col, focused_row;
/*
@@ -52,6 +52,12 @@ typedef struct {
GSList *selection;
GtkSelectionMode selection_mode;
+
+ /*
+ * During edition
+ */
+ int editing_col, editing_row;
+ void *edit_ctx;
} ETableItem;
typedef struct {
@@ -85,4 +91,11 @@ void e_table_item_set_selection_mode (ETableItem *e_table_Item,
gboolean e_table_item_is_row_selected (ETableItem *e_table_Item,
int row);
+void e_table_item_leave_edit (ETableItem *eti);
+void e_table_item_enter_edit (ETableItem *eti, int col, int row);
+
+void e_table_item_redraw_range (ETableItem *eti,
+ int start_col, int start_row,
+ int end_col, int end_row);
+
#endif /* _E_TABLE_ITEM_H_ */
diff --git a/widgets/e-table-model.c b/widgets/e-table-model.c
index 288c20f20e..103bb31b57 100644
--- a/widgets/e-table-model.c
+++ b/widgets/e-table-model.c
@@ -61,7 +61,7 @@ e_table_model_value_at (ETableModel *e_table_model, int col, int row)
}
void
-e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, void *data)
+e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, const void *data)
{
g_return_if_fail (e_table_model != NULL);
g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
diff --git a/widgets/e-table-model.h b/widgets/e-table-model.h
index ea5d31493d..22339ae484 100644
--- a/widgets/e-table-model.h
+++ b/widgets/e-table-model.h
@@ -23,7 +23,7 @@ typedef struct {
const char *(*column_name) (ETableModel *etm, int col);
int (*row_count) (ETableModel *etm);
void *(*value_at) (ETableModel *etm, int col, int row);
- void (*set_value_at) (ETableModel *etm, int col, int row, void *value);
+ void (*set_value_at) (ETableModel *etm, int col, int row, const void *value);
gboolean (*is_cell_editable) (ETableModel *etm, int col, int row);
/*
@@ -40,7 +40,7 @@ int e_table_model_column_count (ETableModel *e_table_model);
const char *e_table_model_column_name (ETableModel *e_table_model, int col);
int e_table_model_row_count (ETableModel *e_table_model);
void *e_table_model_value_at (ETableModel *e_table_model, int col, int row);
-void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, void *data);
+void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, const void *data);
gboolean e_table_model_is_cell_editable (ETableModel *e_table_model, int col, int row);
/*
diff --git a/widgets/e-table-simple.c b/widgets/e-table-simple.c
index 16691e5442..2076e06cef 100644
--- a/widgets/e-table-simple.c
+++ b/widgets/e-table-simple.c
@@ -47,7 +47,7 @@ simple_value_at (ETableModel *etm, int col, int row)
}
static void
-simple_set_value_at (ETableModel *etm, int col, int row, void *val)
+simple_set_value_at (ETableModel *etm, int col, int row, const void *val)
{
ETableSimple *simple = (ETableSimple *)etm;
diff --git a/widgets/e-table-simple.h b/widgets/e-table-simple.h
index 544e681a6c..1f7a17aeff 100644
--- a/widgets/e-table-simple.h
+++ b/widgets/e-table-simple.h
@@ -7,7 +7,7 @@ typedef int (*ETableSimpleColumnCountFn) (ETableModel *etm, void *dat
typedef const char *(*ETableSimpleColumnNameFn) (ETableModel *etm, int col, void *data);
typedef int (*ETableSimpleRowCountFn) (ETableModel *etm, void *data);
typedef void *(*ETableSimpleValueAtFn) (ETableModel *etm, int col, int row, void *data);
-typedef void (*ETableSimpleSetValueAtFn) (ETableModel *etm, int col, int row, void *val, void *data);
+typedef void (*ETableSimpleSetValueAtFn) (ETableModel *etm, int col, int row, const void *val, void *data);
typedef gboolean (*ETableSimpleIsCellEditableFn) (ETableModel *etm, int col, int row, void *data);
typedef struct {
diff --git a/widgets/e-table/ChangeLog b/widgets/e-table/ChangeLog
index 20d4c1e3d7..afc69d71a4 100644
--- a/widgets/e-table/ChangeLog
+++ b/widgets/e-table/ChangeLog
@@ -1,3 +1,16 @@
+1999-11-28 Miguel de Icaza <miguel@gnu.org>
+
+ * e-cell-text.c (ect_enter_edit, ect_leave_edit): New methods;
+ They implement editing.
+
+ * e-cell.h: new methods: enter_edit, leave_edit
+
+ * e-table-model.h (set_value_at): make val argument const.
+
+ * e-table-simple.c (simple_set_value_at): Make value argument const;
+
+ * e-table-item.c (eti_set_arg): Add new mode: draw_focus;
+
1999-11-27 Miguel de Icaza <miguel@gnu.org>
* e-table-item.c (eti_event): beginning of the keyboard navigation.
diff --git a/widgets/e-table/e-cell-text.c b/widgets/e-table/e-cell-text.c
index a997d745d3..f0501ab4cb 100644
--- a/widgets/e-table/e-cell-text.c
+++ b/widgets/e-table/e-cell-text.c
@@ -8,61 +8,143 @@
*/
#include <config.h>
#include <gtk/gtkenums.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtksignal.h>
+#include <gdk/gdkkeysyms.h>
+#include <libgnomeui/gnome-canvas.h>
#include "e-cell-text.h"
#include "e-util.h"
+#include "e-table-item.h"
#define PARENT_TYPE e_cell_get_type()
#define TEXT_PAD 2
typedef struct {
+ char *old_text;
+ GtkWidget *entry_top;
+ GtkEntry *entry;
+
+ /*
+ * Where the editing is taking place
+ */
+ int col, row;
+} CellEdit;
+
+typedef struct {
ECellView cell_view;
GdkGC *gc;
GdkFont *font;
GnomeCanvas *canvas;
+ ETableItem *eti;
+
+ /*
+ * During edition.
+ */
+ CellEdit *edit;
} ECellTextView;
static ECellClass *parent_class;
+static void
+ect_queue_redraw (ECellTextView *text_view, int col, int row)
+{
+ e_table_item_redraw_range (text_view->eti, col, row, col, row);
+}
+
+/*
+ * Accept the currently edited text
+ */
+static void
+ect_accept_edits (ECellTextView *text_view)
+{
+ const char *text = gtk_entry_get_text (text_view->edit->entry);
+ CellEdit *edit = text_view->edit;
+
+ e_table_model_set_value_at (text_view->eti->table_model, edit->col, edit->row, text);
+}
+
+/*
+ * Shuts down the editing process
+ */
+static void
+ect_stop_editing (ECellTextView *text_view)
+{
+ CellEdit *edit = text_view->edit;
+
+ g_free (edit->old_text);
+ edit->old_text = NULL;
+ gtk_widget_destroy (edit->entry_top);
+ edit->entry_top = NULL;
+ edit->entry = NULL;
+
+ g_free (edit);
+
+ text_view->edit = NULL;
+}
+
+/*
+ * Cancels the edits
+ */
+static void
+ect_cancel_edit (ECellTextView *text_view)
+{
+ ect_queue_redraw (text_view, text_view->edit->col, text_view->edit->row);
+ ect_stop_editing (text_view);
+}
+
+/*
+ * ECell::realize method
+ */
static ECellView *
-ect_realize (ECell *ecell, GnomeCanvas *canvas)
+ect_realize (ECell *ecell, void *view)
{
ECellText *ect = E_CELL_TEXT (ecell);
- ECellTextView *ectv = g_new0 (ECellTextView, 1);
-
- ectv->cell_view.ecell = ecell;
- ectv->gc = gdk_gc_new (GTK_WIDGET (canvas)->window);
+ ECellTextView *text_view = g_new0 (ECellTextView, 1);
+ ETableItem *eti = E_TABLE_ITEM (view);
+ GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
+
+ text_view->cell_view.ecell = ecell;
+ text_view->gc = gdk_gc_new (GTK_WIDGET (canvas)->window);
if (ect->font_name){
GdkFont *f;
f = gdk_fontset_load (ect->font_name);
- ectv->font = f;
+ text_view->font = f;
}
- if (!ectv->font){
- ectv->font = GTK_WIDGET (canvas)->style->font;
+ if (!text_view->font){
+ text_view->font = GTK_WIDGET (canvas)->style->font;
- gdk_font_ref (ectv->font);
+ gdk_font_ref (text_view->font);
}
-
- ectv->canvas = canvas;
- return (ECellView *)ectv;
+ text_view->eti = eti;
+ text_view->canvas = canvas;
+
+ return (ECellView *)text_view;
}
+/*
+ * ECell::unrealize method
+ */
static void
ect_unrealize (ECellView *ecv)
{
- ECellTextView *ectv = (ECellTextView *) ecv;
+ ECellTextView *text_view = (ECellTextView *) ecv;
- gdk_gc_unref (ectv->gc);
- ectv->gc = NULL;
+ gdk_gc_unref (text_view->gc);
+ text_view->gc = NULL;
- gdk_font_unref (ectv->font);
- ectv->font = NULL;
+ gdk_font_unref (text_view->font);
+ text_view->font = NULL;
- g_free (ectv);
+ g_free (text_view);
}
+/*
+ * ECell::draw method
+ */
static void
ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected,
@@ -70,41 +152,117 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
{
ECellText *ect = E_CELL_TEXT (ecell_view->ecell);
ECellTextView *text_view = (ECellTextView *) ecell_view;
+ GtkWidget *w = GTK_WIDGET (text_view->canvas);
GdkRectangle rect;
const char *str = e_table_model_value_at (ecell_view->ecell->table_model, col, row);
- int xoff, w;
+ GdkFont *font = text_view->font;
+ const int height = font->ascent + font->descent;
+ int xoff;
+ gboolean edit_display = FALSE;
+
+ /*
+ * Figure if this cell is being edited
+ */
+ if (text_view->edit){
+ CellEdit *edit = text_view->edit;
+
+ printf ("We are editing a cell [%d %d %d %d]\n", col, row, edit->col, edit->row);
+ if ((edit->col == col) && (edit->row == row))
+ edit_display = TRUE;
+ }
+
+ /*
+ * Be a nice citizen: clip to the region we are supposed to draw on
+ */
rect.x = x1;
rect.y = y1;
rect.width = x2 - x1;
rect.height = y2 - y1;
-
gdk_gc_set_clip_rectangle (text_view->gc, &rect);
- switch (ect->justify){
- case GTK_JUSTIFY_LEFT:
- xoff = 1;
- break;
-
- case GTK_JUSTIFY_RIGHT:
- w = 1 + gdk_text_width (text_view->font, str, strlen (str));
- xoff = (x2 - x1) - w;
- break;
+ if (edit_display){
+ CellEdit *edit = text_view->edit;
+ const char *text = gtk_entry_get_text (edit->entry);
+ GdkWChar *text_wc = g_new (GdkWChar, strlen (text) + 1);
+ int text_wc_len = gdk_mbstowcs (text_wc, text, strlen (text));
+ const int cursor_pos = GTK_EDITABLE (edit->entry)->current_pos;
+ const int left_len = gdk_text_width_wc (text_view->font, text_wc, cursor_pos);
+
+ text_wc [text_wc_len] = 0;
- case GTK_JUSTIFY_CENTER:
- xoff = ((x2 - x1) - gdk_text_width (text_view->font, str, strlen (str))) / 2;
- break;
- default:
+ /*
+ * Find a good spot for painting
+ */
xoff = 0;
- g_warning ("Can not handle GTK_JUSTIFY_FILL");
- break;
- }
+
+ /*
+ * Paint
+ */
+ gdk_gc_set_foreground (text_view->gc, &w->style->base [GTK_STATE_NORMAL]);
+ gdk_draw_rectangle (drawable, text_view->gc, TRUE,
+ rect.x, rect.y, rect.width, rect.height);
+ gdk_gc_set_foreground (text_view->gc, &w->style->text [GTK_STATE_NORMAL]);
+
+ {
+ GdkGC *gc = text_view->gc;
+ const int y = y2 - font->descent - ((y2-y1-height)/2);
+ int px, i;
+
+ px = x1;
+
+ printf ("Cursor at: %d\n", cursor_pos);
+
+ for (i = 0; *text_wc; text_wc++, i++){
+ gdk_draw_text_wc (
+ drawable, font, gc, px, y, text_wc, 1);
+
+ if (i == cursor_pos){
+ gdk_draw_line (
+ drawable, gc,
+ px, y - font->ascent,
+ px, y + font->descent - 1);
+ }
- /* Draw now */
- {
- GtkWidget *w = GTK_WIDGET (text_view->canvas);
+ px += gdk_text_width_wc (font, text_wc, 1);
+ }
+
+ if (i == cursor_pos){
+ gdk_draw_line (
+ drawable, gc,
+ px, y - font->ascent,
+ px, y + font->descent - 1);
+ }
+ }
+ } else {
+ /*
+ * Regular cell
+ */
GdkColor *background, *foreground;
- const int height = text_view->font->ascent + text_view->font->descent;
+ int width;
+
+ /*
+ * Compute draw mode
+ */
+ switch (ect->justify){
+ case GTK_JUSTIFY_LEFT:
+ xoff = 1;
+ break;
+
+ case GTK_JUSTIFY_RIGHT:
+ width = 1 + gdk_text_width (font, str, strlen (str));
+ xoff = (x2 - x1) - width;
+ break;
+
+ case GTK_JUSTIFY_CENTER:
+ xoff = ((x2 - x1) - gdk_text_width (font, str, strlen (str))) / 2;
+ break;
+ default:
+ xoff = 0;
+ g_warning ("Can not handle GTK_JUSTIFY_FILL");
+ break;
+ }
+
if (selected){
background = &w->style->bg [GTK_STATE_SELECTED];
@@ -118,33 +276,58 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
gdk_draw_rectangle (drawable, text_view->gc, TRUE,
rect.x, rect.y, rect.width, rect.height);
gdk_gc_set_foreground (text_view->gc, foreground);
- gdk_draw_string (drawable, text_view->font, text_view->gc,
- x1 + xoff, y2 - text_view->font->descent - ((y2-y1-height)/2), str);
- }
-}
-static void
-e_cell_text_start_editing (ECellText *ect, int col, int row)
-{
- printf ("Starting to edit %d %d\n", col, row);
+ gdk_draw_string (
+ drawable, font, text_view->gc,
+ x1 + xoff,
+ y2 - font->descent - ((y2-y1-height)/2), str);
+ }
}
+/*
+ * ECell::event method
+ */
static gint
ect_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
{
- ECell *ecell = ecell_view->ecell;
- ECellText *ect = E_CELL_TEXT (ecell);
+ ECellTextView *text_view = (ECellTextView *) ecell_view;
switch (event->type){
case GDK_BUTTON_PRESS:
+ if (text_view->edit){
+ printf ("FIXME: Should handle click here\n");
+ } else
+ e_table_item_enter_edit (text_view->eti, col, row);
+ break;
+
+ case GDK_BUTTON_RELEASE:
return TRUE;
- default:
+ case GDK_KEY_PRESS:
+ if (event->key.keyval == GDK_Escape){
+ ect_cancel_edit (text_view);
+ return TRUE;
+ }
+
+ if (!text_view->edit)
+ e_table_item_enter_edit (text_view->eti, col, row);
+
+ gtk_widget_event (GTK_WIDGET (text_view->edit->entry), event);
+ ect_queue_redraw (text_view, col, row);
+ break;
+
+ case GDK_KEY_RELEASE:
break;
+
+ default:
+ return FALSE;
}
- return FALSE;
+ return TRUE;
}
+/*
+ * ECell::height method
+ */
static int
ect_height (ECellView *ecell_view, int col, int row)
{
@@ -153,6 +336,66 @@ ect_height (ECellView *ecell_view, int col, int row)
return (text_view->font->ascent + text_view->font->descent) + TEXT_PAD;
}
+/*
+ * Callback: invoked when the user pressed "enter" on the GtkEntry
+ */
+static void
+ect_entry_activate (GtkEntry *entry, ECellTextView *text_view)
+{
+ e_table_item_leave_edit (text_view->eti);
+}
+
+/*
+ * ECellView::enter_edit method
+ */
+static void *
+ect_enter_edit (ECellView *ecell_view, int col, int row)
+{
+ ECellTextView *text_view = (ECellTextView *) ecell_view;
+ const char *str = e_table_model_value_at (ecell_view->ecell->table_model, col, row);
+ CellEdit *edit;
+
+ printf ("Entering edit mode! [%d %d]\n", col, row);
+
+ edit = g_new (CellEdit, 1);
+ text_view->edit = edit;
+
+ edit->entry = (GtkEntry *) gtk_entry_new ();
+ gtk_entry_set_text (edit->entry, str);
+ edit->old_text = g_strdup (str);
+ gtk_signal_connect (GTK_OBJECT (edit->entry), "activate",
+ GTK_SIGNAL_FUNC (ect_entry_activate), text_view);
+
+ /*
+ * The hack: create this window off-screen
+ */
+ edit->entry_top = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_container_add (GTK_CONTAINER (edit->entry_top), GTK_WIDGET (edit->entry));
+ gtk_widget_set_uposition (edit->entry_top, 20000, 20000);
+ gtk_widget_show_all (edit->entry_top);
+
+ ect_queue_redraw (text_view, col, row);
+
+ return NULL;
+}
+
+/*
+ * ECellView::leave_edit method
+ */
+static void
+ect_leave_edit (ECellView *ecell_view, int col, int row, void *edit_context)
+{
+ ECellTextView *text_view = (ECellTextView *) ecell_view;
+
+ printf ("Leaving edit mode!\n");
+
+ ect_accept_edits (text_view);
+ ect_stop_editing (text_view);
+}
+
+/*
+ * GtkObject::destroy method
+ */
static void
ect_destroy (GtkObject *object)
{
@@ -170,12 +413,14 @@ e_cell_text_class_init (GtkObjectClass *object_class)
object_class->destroy = ect_destroy;
- ecc->realize = ect_realize;
- ecc->unrealize = ect_unrealize;
- ecc->draw = ect_draw;
- ecc->event = ect_event;
- ecc->height = ect_height;
-
+ ecc->realize = ect_realize;
+ ecc->unrealize = ect_unrealize;
+ ecc->draw = ect_draw;
+ ecc->event = ect_event;
+ ecc->height = ect_height;
+ ecc->enter_edit = ect_enter_edit;
+ ecc->leave_edit = ect_leave_edit;
+
parent_class = gtk_type_class (PARENT_TYPE);
}
diff --git a/widgets/e-table/e-cell.c b/widgets/e-table/e-cell.c
index 9caa31f2ca..2bc49f7a45 100644
--- a/widgets/e-table/e-cell.c
+++ b/widgets/e-table/e-cell.c
@@ -13,7 +13,7 @@
#define PARENT_TYPE gtk_object_get_type()
static ECellView *
-ec_realize (ECell *e_cell, GnomeCanvas *canvas)
+ec_realize (ECell *e_cell, void *view)
{
return NULL;
}
@@ -28,20 +28,20 @@ ec_draw (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected,
int x1, int y1, int x2, int y2)
{
- g_warning ("e-cell-draw invoked\n");
+ g_error ("e-cell-draw invoked\n");
}
static gint
ec_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
{
- g_warning ("e-cell-event invoked\n");
+ g_error ("e-cell-event invoked\n");
return 0;
}
static gint
ec_height (ECellView *ecell_view, int col, int row)
{
- g_warning ("e-cell-event invoked\n");
+ g_error ("e-cell-event invoked\n");
return 0;
}
@@ -98,10 +98,10 @@ e_cell_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
}
ECellView *
-e_cell_realize (ECell *ecell, GnomeCanvas *canvas)
+e_cell_realize (ECell *ecell, void *view)
{
return E_CELL_CLASS (GTK_OBJECT (ecell)->klass)->realize (
- ecell, canvas);
+ ecell, view);
}
void
@@ -125,3 +125,16 @@ e_cell_height (ECellView *ecell_view, int col, int row)
ecell_view, col, row);
}
+void *
+e_cell_enter_edit (ECellView *ecell_view, int col, int row)
+{
+ return E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->enter_edit (
+ ecell_view, col, row);
+}
+
+void
+e_cell_leave_edit (ECellView *ecell_view, int col, int row, void *edit_context)
+{
+ E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->leave_edit (
+ ecell_view, col, row, edit_context);
+}
diff --git a/widgets/e-table/e-cell.h b/widgets/e-table/e-cell.h
index 9cd62f3909..b0f62d020c 100644
--- a/widgets/e-table/e-cell.h
+++ b/widgets/e-table/e-cell.h
@@ -1,7 +1,7 @@
#ifndef _E_CELL_H_
#define _E_CELL_H_
-#include <libgnomeui/gnome-canvas.h>
+#include <gdk/gdktypes.h>
#include "e-table-model.h"
#define E_CELL_TYPE (e_cell_get_type ())
@@ -29,19 +29,22 @@ struct _ECellView {
typedef struct {
GtkObjectClass parent_class;
- ECellView *(*realize) (ECell *, GnomeCanvas *canvas);
- void (*unrealize) (ECellView *);
+ ECellView *(*realize) (ECell *ecell, void *view);
+ void (*unrealize) (ECellView *e_cell_view);
void (*draw) (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected, 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);
- int (*height) (ECellView *ecell, int col, int row);
+ void (*focus) (ECellView *ecell_view, int col, int row, int x1, int y1, int x2, int y2);
+ void (*unfocus) (ECellView *ecell_view);
+ int (*height) (ECellView *ecell_view, int col, int row);
+
+ void *(*enter_edit)(ECellView *ecell_view, int col, int row);
+ void (*leave_edit)(ECellView *ecell_view, int col, int row, void *context);
} ECellClass;
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);
+ECellView *e_cell_realize (ECell *ecell, void *view);
void e_cell_unrealize (ECellView *ecell_view);
void e_cell_draw (ECellView *ecell_view, GdkDrawable *dr,
int col, int row, gboolean selected,
@@ -50,4 +53,7 @@ void e_cell_focus (ECellView *ecell_view, int col, int row, int x1, in
void e_cell_unfocus (ECellView *ecell_view);
int e_cell_height (ECellView *ecell_view, int col, int row);
+void *e_cell_enter_edit(ECellView *ecell_view, int col, int row);
+void e_cell_leave_edit(ECellView *ecell_view, int col, int row, void *edit_context);
+
#endif /* _E_CELL_H_ */
diff --git a/widgets/e-table/e-table-item.c b/widgets/e-table/e-table-item.c
index a561fbfd15..1b98bbfce4 100644
--- a/widgets/e-table/e-table-item.c
+++ b/widgets/e-table/e-table-item.c
@@ -37,6 +37,7 @@ enum {
ARG_TABLE_X,
ARG_TABLE_Y,
ARG_TABLE_DRAW_GRID,
+ ARG_TABLE_DRAW_FOCUS,
ARG_LENGHT_THRESHOLD
};
@@ -51,7 +52,6 @@ enum {
static void
eti_realize_cell_views (ETableItem *eti)
{
- GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti);
int i;
/*
@@ -63,7 +63,7 @@ eti_realize_cell_views (ETableItem *eti)
for (i = 0; i < eti->n_cells; i++){
ETableCol *col = e_table_header_get_column (eti->header, i);
- eti->cell_views [i] = e_cell_realize (col->ecell, item->canvas);
+ eti->cell_views [i] = e_cell_realize (col->ecell, eti);
}
}
@@ -117,12 +117,9 @@ eti_remove_table_model (ETableItem *eti)
gtk_signal_disconnect (GTK_OBJECT (eti->table_model),
eti->table_model_change_id);
- gtk_signal_disconnect (GTK_OBJECT (eti->table_model),
- 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;
}
@@ -284,7 +281,9 @@ eti_row_diff (ETableItem *eti, int start_row, int end_row)
* border as well.
*/
static void
-eti_request_region_redraw (ETableItem *eti, int start_col, int start_row, int end_col, int end_row, int border)
+eti_request_region_redraw (ETableItem *eti,
+ int start_col, int start_row,
+ int end_col, int end_row, int border)
{
GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
int x1, y1, width, height;
@@ -301,10 +300,25 @@ eti_request_region_redraw (ETableItem *eti, int start_col, int start_row, int en
eti->y1 + y1 + height + 1 + border);
}
-static void
-eti_table_model_row_selection (ETableModel *table_model, int row, gboolean selected, ETableItem *eti)
+void
+e_table_item_redraw_range (ETableItem *eti,
+ int start_col, int start_row,
+ int end_col, int end_row)
{
- eti_request_region_redraw (eti, 0, row, eti->cols - 1, row, 0);
+ int border;
+
+ g_return_if_fail (eti != NULL);
+ g_return_if_fail (E_IS_TABLE_ITEM (eti));
+
+ if ((start_col == eti->focused_col) ||
+ (end_col == eti->focused_col) ||
+ (start_row == eti->focused_row) ||
+ (end_row == eti->focused_row))
+ border = 2;
+ else
+ border = 0;
+
+ eti_request_region_redraw (eti, start_col, start_row, end_col, end_row, border);
}
static void
@@ -313,14 +327,11 @@ eti_add_table_model (ETableItem *eti, ETableModel *table_model)
g_assert (eti->table_model == NULL);
eti->table_model = table_model;
- gtk_object_ref (GTK_OBJECT (table_model));
+ gtk_object_ref (GTK_OBJECT (eti->table_model));
eti->table_model_change_id = gtk_signal_connect (
GTK_OBJECT (table_model), "model_changed",
GTK_SIGNAL_FUNC (eti_table_model_changed), eti);
- eti->table_model_selection_id = gtk_signal_connect (
- GTK_OBJECT (table_model), "row_selection",
- GTK_SIGNAL_FUNC (eti_table_model_row_selection), eti);
eti_table_model_changed (table_model, eti);
}
@@ -418,6 +429,11 @@ eti_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
case ARG_TABLE_DRAW_GRID:
eti->draw_grid = GTK_VALUE_BOOL (*arg);
+ break;
+
+ case ARG_TABLE_DRAW_FOCUS:
+ eti->draw_focus = GTK_VALUE_BOOL (*arg);
+ break;
}
eti_update (item, NULL, NULL, 0);
}
@@ -529,7 +545,7 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
int f_x1, f_x2, f_y1, f_y2;
gboolean f_found;
- printf ("Rect: %d %d %d %d\n", x, y, width, height);
+/* printf ("Rect: %d %d %d %d\n", x, y, width, height); */
/*
* Clear the background
*/
@@ -604,7 +620,7 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
height = eti_row_height (eti, row);
xd = x_offset;
- printf ("paint: %d %d\n", yd, yd + height);
+/* printf ("paint: %d %d\n", yd, yd + height); */
selected = g_slist_find (eti->selection, GINT_TO_POINTER (row)) != NULL;
@@ -631,9 +647,7 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
/*
* Draw focus
*/
- if (f_found){
- printf ("FOUD: %d %d %d %d!\n",
- f_x1 - 1, f_y1 - 1, f_x2 - f_x1 + 2 , f_y2 - f_y1 + 2);
+ if (f_found && eti->draw_focus){
gdk_draw_rectangle (
drawable, eti->focus_gc, FALSE,
f_x1 - 1, f_y1 - 1, f_x2 - f_x1 + 2 , f_y2 - f_y1 + 2);
@@ -725,6 +739,8 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
}
case GDK_KEY_PRESS:
+ printf ("KEYPRESS!\n");
+
if (eti->focused_col == -1)
return FALSE;
@@ -781,6 +797,7 @@ eti_row_selection (ETableItem *eti, int row, gboolean selected)
eti->selection = g_slist_prepend (eti->selection, GINT_TO_POINTER (row));
else
eti->selection = g_slist_remove (eti->selection, GINT_TO_POINTER (row));
+
}
static void
@@ -813,6 +830,8 @@ eti_class_init (GtkObjectClass *object_class)
GTK_ARG_WRITABLE, ARG_TABLE_Y);
gtk_object_add_arg_type ("ETableItem::drawgrid", GTK_TYPE_BOOL,
GTK_ARG_WRITABLE, ARG_TABLE_DRAW_GRID);
+ gtk_object_add_arg_type ("ETableItem::drawfocus", GTK_TYPE_BOOL,
+ GTK_ARG_WRITABLE, ARG_TABLE_DRAW_FOCUS);
eti_signals [ROW_SELECTION] =
gtk_signal_new ("row_selection",
@@ -862,6 +881,11 @@ e_table_item_focus (ETableItem *eti, int col, int row)
eti->focused_row = row;
eti_request_region_redraw (eti, col, row, col, row, FOCUSED_BORDER);
+
+ /*
+ * make sure we have the Gtk Focus
+ */
+ gtk_widget_grab_focus (GTK_WIDGET (GNOME_CANVAS_ITEM (eti)->canvas));
}
void
@@ -944,7 +968,7 @@ void
e_table_item_select_row (ETableItem *eti, int row)
{
g_return_if_fail (eti != NULL);
- g_return_if_fail (E_IS_TABLE_ITEM (eti));
+ g_return_if_fail (E_IS_TABLE_ITEM (eti));
switch (eti->selection_mode){
case GTK_SELECTION_SINGLE:
@@ -973,3 +997,28 @@ e_table_item_select_row (ETableItem *eti, int row)
}
}
+
+void
+e_table_item_enter_edit (ETableItem *eti, int col, int row)
+{
+ g_return_if_fail (eti != NULL);
+ g_return_if_fail (E_IS_TABLE_ITEM (eti));
+
+ eti->editing_col = col;
+ eti->editing_row = row;
+
+ eti->edit_ctx = e_cell_enter_edit (eti->cell_views [col], col, row);
+}
+
+void
+e_table_item_leave_edit (ETableItem *eti)
+{
+ g_return_if_fail (eti != NULL);
+ g_return_if_fail (E_IS_TABLE_ITEM (eti));
+
+ e_cell_leave_edit (eti->cell_views [eti->editing_col], eti->editing_col, eti->editing_row, eti->edit_ctx);
+ eti->editing_col = -1;
+ eti->editing_row = -1;
+ eti->edit_ctx = NULL;
+}
+
diff --git a/widgets/e-table/e-table-item.h b/widgets/e-table/e-table-item.h
index 17d422ddf5..02f7beb1ac 100644
--- a/widgets/e-table/e-table-item.h
+++ b/widgets/e-table/e-table-item.h
@@ -28,14 +28,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;
GdkGC *focus_gc;
unsigned int draw_grid:1;
-
+ unsigned int draw_focus:1;
+
int focused_col, focused_row;
/*
@@ -52,6 +52,12 @@ typedef struct {
GSList *selection;
GtkSelectionMode selection_mode;
+
+ /*
+ * During edition
+ */
+ int editing_col, editing_row;
+ void *edit_ctx;
} ETableItem;
typedef struct {
@@ -85,4 +91,11 @@ void e_table_item_set_selection_mode (ETableItem *e_table_Item,
gboolean e_table_item_is_row_selected (ETableItem *e_table_Item,
int row);
+void e_table_item_leave_edit (ETableItem *eti);
+void e_table_item_enter_edit (ETableItem *eti, int col, int row);
+
+void e_table_item_redraw_range (ETableItem *eti,
+ int start_col, int start_row,
+ int end_col, int end_row);
+
#endif /* _E_TABLE_ITEM_H_ */
diff --git a/widgets/e-table/e-table-model.c b/widgets/e-table/e-table-model.c
index 288c20f20e..103bb31b57 100644
--- a/widgets/e-table/e-table-model.c
+++ b/widgets/e-table/e-table-model.c
@@ -61,7 +61,7 @@ e_table_model_value_at (ETableModel *e_table_model, int col, int row)
}
void
-e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, void *data)
+e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, const void *data)
{
g_return_if_fail (e_table_model != NULL);
g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
diff --git a/widgets/e-table/e-table-model.h b/widgets/e-table/e-table-model.h
index ea5d31493d..22339ae484 100644
--- a/widgets/e-table/e-table-model.h
+++ b/widgets/e-table/e-table-model.h
@@ -23,7 +23,7 @@ typedef struct {
const char *(*column_name) (ETableModel *etm, int col);
int (*row_count) (ETableModel *etm);
void *(*value_at) (ETableModel *etm, int col, int row);
- void (*set_value_at) (ETableModel *etm, int col, int row, void *value);
+ void (*set_value_at) (ETableModel *etm, int col, int row, const void *value);
gboolean (*is_cell_editable) (ETableModel *etm, int col, int row);
/*
@@ -40,7 +40,7 @@ int e_table_model_column_count (ETableModel *e_table_model);
const char *e_table_model_column_name (ETableModel *e_table_model, int col);
int e_table_model_row_count (ETableModel *e_table_model);
void *e_table_model_value_at (ETableModel *e_table_model, int col, int row);
-void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, void *data);
+void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, const void *data);
gboolean e_table_model_is_cell_editable (ETableModel *e_table_model, int col, int row);
/*
diff --git a/widgets/e-table/e-table-simple.c b/widgets/e-table/e-table-simple.c
index 16691e5442..2076e06cef 100644
--- a/widgets/e-table/e-table-simple.c
+++ b/widgets/e-table/e-table-simple.c
@@ -47,7 +47,7 @@ simple_value_at (ETableModel *etm, int col, int row)
}
static void
-simple_set_value_at (ETableModel *etm, int col, int row, void *val)
+simple_set_value_at (ETableModel *etm, int col, int row, const void *val)
{
ETableSimple *simple = (ETableSimple *)etm;
diff --git a/widgets/e-table/e-table-simple.h b/widgets/e-table/e-table-simple.h
index 544e681a6c..1f7a17aeff 100644
--- a/widgets/e-table/e-table-simple.h
+++ b/widgets/e-table/e-table-simple.h
@@ -7,7 +7,7 @@ typedef int (*ETableSimpleColumnCountFn) (ETableModel *etm, void *dat
typedef const char *(*ETableSimpleColumnNameFn) (ETableModel *etm, int col, void *data);
typedef int (*ETableSimpleRowCountFn) (ETableModel *etm, void *data);
typedef void *(*ETableSimpleValueAtFn) (ETableModel *etm, int col, int row, void *data);
-typedef void (*ETableSimpleSetValueAtFn) (ETableModel *etm, int col, int row, void *val, void *data);
+typedef void (*ETableSimpleSetValueAtFn) (ETableModel *etm, int col, int row, const void *val, void *data);
typedef gboolean (*ETableSimpleIsCellEditableFn) (ETableModel *etm, int col, int row, void *data);
typedef struct {
diff --git a/widgets/e-table/table-test.c b/widgets/e-table/table-test.c
index 3517ecf692..f677e9e2d1 100644
--- a/widgets/e-table/table-test.c
+++ b/widgets/e-table/table-test.c
@@ -151,7 +151,7 @@ value_at (ETableModel *etc, int col, int row, void *data)
}
static void
-set_value_at (ETableModel *etc, int col, int row, void *val, void *data)
+set_value_at (ETableModel *etc, int col, int row, const void *val, void *data)
{
g_assert (col < cols);
g_assert (row < lines);
@@ -236,6 +236,7 @@ main (int argc, char *argv [])
"x", 10,
"y", 30,
"drawgrid", TRUE,
+ "drawfocus", TRUE,
NULL);
gtk_main ();
diff --git a/widgets/table-test.c b/widgets/table-test.c
index 3517ecf692..f677e9e2d1 100644
--- a/widgets/table-test.c
+++ b/widgets/table-test.c
@@ -151,7 +151,7 @@ value_at (ETableModel *etc, int col, int row, void *data)
}
static void
-set_value_at (ETableModel *etc, int col, int row, void *val, void *data)
+set_value_at (ETableModel *etc, int col, int row, const void *val, void *data)
{
g_assert (col < cols);
g_assert (row < lines);
@@ -236,6 +236,7 @@ main (int argc, char *argv [])
"x", 10,
"y", 30,
"drawgrid", TRUE,
+ "drawfocus", TRUE,
NULL);
gtk_main ();
diff --git a/widgets/table/e-cell-text.c b/widgets/table/e-cell-text.c
index a997d745d3..f0501ab4cb 100644
--- a/widgets/table/e-cell-text.c
+++ b/widgets/table/e-cell-text.c
@@ -8,61 +8,143 @@
*/
#include <config.h>
#include <gtk/gtkenums.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtksignal.h>
+#include <gdk/gdkkeysyms.h>
+#include <libgnomeui/gnome-canvas.h>
#include "e-cell-text.h"
#include "e-util.h"
+#include "e-table-item.h"
#define PARENT_TYPE e_cell_get_type()
#define TEXT_PAD 2
typedef struct {
+ char *old_text;
+ GtkWidget *entry_top;
+ GtkEntry *entry;
+
+ /*
+ * Where the editing is taking place
+ */
+ int col, row;
+} CellEdit;
+
+typedef struct {
ECellView cell_view;
GdkGC *gc;
GdkFont *font;
GnomeCanvas *canvas;
+ ETableItem *eti;
+
+ /*
+ * During edition.
+ */
+ CellEdit *edit;
} ECellTextView;
static ECellClass *parent_class;
+static void
+ect_queue_redraw (ECellTextView *text_view, int col, int row)
+{
+ e_table_item_redraw_range (text_view->eti, col, row, col, row);
+}
+
+/*
+ * Accept the currently edited text
+ */
+static void
+ect_accept_edits (ECellTextView *text_view)
+{
+ const char *text = gtk_entry_get_text (text_view->edit->entry);
+ CellEdit *edit = text_view->edit;
+
+ e_table_model_set_value_at (text_view->eti->table_model, edit->col, edit->row, text);
+}
+
+/*
+ * Shuts down the editing process
+ */
+static void
+ect_stop_editing (ECellTextView *text_view)
+{
+ CellEdit *edit = text_view->edit;
+
+ g_free (edit->old_text);
+ edit->old_text = NULL;
+ gtk_widget_destroy (edit->entry_top);
+ edit->entry_top = NULL;
+ edit->entry = NULL;
+
+ g_free (edit);
+
+ text_view->edit = NULL;
+}
+
+/*
+ * Cancels the edits
+ */
+static void
+ect_cancel_edit (ECellTextView *text_view)
+{
+ ect_queue_redraw (text_view, text_view->edit->col, text_view->edit->row);
+ ect_stop_editing (text_view);
+}
+
+/*
+ * ECell::realize method
+ */
static ECellView *
-ect_realize (ECell *ecell, GnomeCanvas *canvas)
+ect_realize (ECell *ecell, void *view)
{
ECellText *ect = E_CELL_TEXT (ecell);
- ECellTextView *ectv = g_new0 (ECellTextView, 1);
-
- ectv->cell_view.ecell = ecell;
- ectv->gc = gdk_gc_new (GTK_WIDGET (canvas)->window);
+ ECellTextView *text_view = g_new0 (ECellTextView, 1);
+ ETableItem *eti = E_TABLE_ITEM (view);
+ GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
+
+ text_view->cell_view.ecell = ecell;
+ text_view->gc = gdk_gc_new (GTK_WIDGET (canvas)->window);
if (ect->font_name){
GdkFont *f;
f = gdk_fontset_load (ect->font_name);
- ectv->font = f;
+ text_view->font = f;
}
- if (!ectv->font){
- ectv->font = GTK_WIDGET (canvas)->style->font;
+ if (!text_view->font){
+ text_view->font = GTK_WIDGET (canvas)->style->font;
- gdk_font_ref (ectv->font);
+ gdk_font_ref (text_view->font);
}
-
- ectv->canvas = canvas;
- return (ECellView *)ectv;
+ text_view->eti = eti;
+ text_view->canvas = canvas;
+
+ return (ECellView *)text_view;
}
+/*
+ * ECell::unrealize method
+ */
static void
ect_unrealize (ECellView *ecv)
{
- ECellTextView *ectv = (ECellTextView *) ecv;
+ ECellTextView *text_view = (ECellTextView *) ecv;
- gdk_gc_unref (ectv->gc);
- ectv->gc = NULL;
+ gdk_gc_unref (text_view->gc);
+ text_view->gc = NULL;
- gdk_font_unref (ectv->font);
- ectv->font = NULL;
+ gdk_font_unref (text_view->font);
+ text_view->font = NULL;
- g_free (ectv);
+ g_free (text_view);
}
+/*
+ * ECell::draw method
+ */
static void
ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected,
@@ -70,41 +152,117 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
{
ECellText *ect = E_CELL_TEXT (ecell_view->ecell);
ECellTextView *text_view = (ECellTextView *) ecell_view;
+ GtkWidget *w = GTK_WIDGET (text_view->canvas);
GdkRectangle rect;
const char *str = e_table_model_value_at (ecell_view->ecell->table_model, col, row);
- int xoff, w;
+ GdkFont *font = text_view->font;
+ const int height = font->ascent + font->descent;
+ int xoff;
+ gboolean edit_display = FALSE;
+
+ /*
+ * Figure if this cell is being edited
+ */
+ if (text_view->edit){
+ CellEdit *edit = text_view->edit;
+
+ printf ("We are editing a cell [%d %d %d %d]\n", col, row, edit->col, edit->row);
+ if ((edit->col == col) && (edit->row == row))
+ edit_display = TRUE;
+ }
+
+ /*
+ * Be a nice citizen: clip to the region we are supposed to draw on
+ */
rect.x = x1;
rect.y = y1;
rect.width = x2 - x1;
rect.height = y2 - y1;
-
gdk_gc_set_clip_rectangle (text_view->gc, &rect);
- switch (ect->justify){
- case GTK_JUSTIFY_LEFT:
- xoff = 1;
- break;
-
- case GTK_JUSTIFY_RIGHT:
- w = 1 + gdk_text_width (text_view->font, str, strlen (str));
- xoff = (x2 - x1) - w;
- break;
+ if (edit_display){
+ CellEdit *edit = text_view->edit;
+ const char *text = gtk_entry_get_text (edit->entry);
+ GdkWChar *text_wc = g_new (GdkWChar, strlen (text) + 1);
+ int text_wc_len = gdk_mbstowcs (text_wc, text, strlen (text));
+ const int cursor_pos = GTK_EDITABLE (edit->entry)->current_pos;
+ const int left_len = gdk_text_width_wc (text_view->font, text_wc, cursor_pos);
+
+ text_wc [text_wc_len] = 0;
- case GTK_JUSTIFY_CENTER:
- xoff = ((x2 - x1) - gdk_text_width (text_view->font, str, strlen (str))) / 2;
- break;
- default:
+ /*
+ * Find a good spot for painting
+ */
xoff = 0;
- g_warning ("Can not handle GTK_JUSTIFY_FILL");
- break;
- }
+
+ /*
+ * Paint
+ */
+ gdk_gc_set_foreground (text_view->gc, &w->style->base [GTK_STATE_NORMAL]);
+ gdk_draw_rectangle (drawable, text_view->gc, TRUE,
+ rect.x, rect.y, rect.width, rect.height);
+ gdk_gc_set_foreground (text_view->gc, &w->style->text [GTK_STATE_NORMAL]);
+
+ {
+ GdkGC *gc = text_view->gc;
+ const int y = y2 - font->descent - ((y2-y1-height)/2);
+ int px, i;
+
+ px = x1;
+
+ printf ("Cursor at: %d\n", cursor_pos);
+
+ for (i = 0; *text_wc; text_wc++, i++){
+ gdk_draw_text_wc (
+ drawable, font, gc, px, y, text_wc, 1);
+
+ if (i == cursor_pos){
+ gdk_draw_line (
+ drawable, gc,
+ px, y - font->ascent,
+ px, y + font->descent - 1);
+ }
- /* Draw now */
- {
- GtkWidget *w = GTK_WIDGET (text_view->canvas);
+ px += gdk_text_width_wc (font, text_wc, 1);
+ }
+
+ if (i == cursor_pos){
+ gdk_draw_line (
+ drawable, gc,
+ px, y - font->ascent,
+ px, y + font->descent - 1);
+ }
+ }
+ } else {
+ /*
+ * Regular cell
+ */
GdkColor *background, *foreground;
- const int height = text_view->font->ascent + text_view->font->descent;
+ int width;
+
+ /*
+ * Compute draw mode
+ */
+ switch (ect->justify){
+ case GTK_JUSTIFY_LEFT:
+ xoff = 1;
+ break;
+
+ case GTK_JUSTIFY_RIGHT:
+ width = 1 + gdk_text_width (font, str, strlen (str));
+ xoff = (x2 - x1) - width;
+ break;
+
+ case GTK_JUSTIFY_CENTER:
+ xoff = ((x2 - x1) - gdk_text_width (font, str, strlen (str))) / 2;
+ break;
+ default:
+ xoff = 0;
+ g_warning ("Can not handle GTK_JUSTIFY_FILL");
+ break;
+ }
+
if (selected){
background = &w->style->bg [GTK_STATE_SELECTED];
@@ -118,33 +276,58 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
gdk_draw_rectangle (drawable, text_view->gc, TRUE,
rect.x, rect.y, rect.width, rect.height);
gdk_gc_set_foreground (text_view->gc, foreground);
- gdk_draw_string (drawable, text_view->font, text_view->gc,
- x1 + xoff, y2 - text_view->font->descent - ((y2-y1-height)/2), str);
- }
-}
-static void
-e_cell_text_start_editing (ECellText *ect, int col, int row)
-{
- printf ("Starting to edit %d %d\n", col, row);
+ gdk_draw_string (
+ drawable, font, text_view->gc,
+ x1 + xoff,
+ y2 - font->descent - ((y2-y1-height)/2), str);
+ }
}
+/*
+ * ECell::event method
+ */
static gint
ect_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
{
- ECell *ecell = ecell_view->ecell;
- ECellText *ect = E_CELL_TEXT (ecell);
+ ECellTextView *text_view = (ECellTextView *) ecell_view;
switch (event->type){
case GDK_BUTTON_PRESS:
+ if (text_view->edit){
+ printf ("FIXME: Should handle click here\n");
+ } else
+ e_table_item_enter_edit (text_view->eti, col, row);
+ break;
+
+ case GDK_BUTTON_RELEASE:
return TRUE;
- default:
+ case GDK_KEY_PRESS:
+ if (event->key.keyval == GDK_Escape){
+ ect_cancel_edit (text_view);
+ return TRUE;
+ }
+
+ if (!text_view->edit)
+ e_table_item_enter_edit (text_view->eti, col, row);
+
+ gtk_widget_event (GTK_WIDGET (text_view->edit->entry), event);
+ ect_queue_redraw (text_view, col, row);
+ break;
+
+ case GDK_KEY_RELEASE:
break;
+
+ default:
+ return FALSE;
}
- return FALSE;
+ return TRUE;
}
+/*
+ * ECell::height method
+ */
static int
ect_height (ECellView *ecell_view, int col, int row)
{
@@ -153,6 +336,66 @@ ect_height (ECellView *ecell_view, int col, int row)
return (text_view->font->ascent + text_view->font->descent) + TEXT_PAD;
}
+/*
+ * Callback: invoked when the user pressed "enter" on the GtkEntry
+ */
+static void
+ect_entry_activate (GtkEntry *entry, ECellTextView *text_view)
+{
+ e_table_item_leave_edit (text_view->eti);
+}
+
+/*
+ * ECellView::enter_edit method
+ */
+static void *
+ect_enter_edit (ECellView *ecell_view, int col, int row)
+{
+ ECellTextView *text_view = (ECellTextView *) ecell_view;
+ const char *str = e_table_model_value_at (ecell_view->ecell->table_model, col, row);
+ CellEdit *edit;
+
+ printf ("Entering edit mode! [%d %d]\n", col, row);
+
+ edit = g_new (CellEdit, 1);
+ text_view->edit = edit;
+
+ edit->entry = (GtkEntry *) gtk_entry_new ();
+ gtk_entry_set_text (edit->entry, str);
+ edit->old_text = g_strdup (str);
+ gtk_signal_connect (GTK_OBJECT (edit->entry), "activate",
+ GTK_SIGNAL_FUNC (ect_entry_activate), text_view);
+
+ /*
+ * The hack: create this window off-screen
+ */
+ edit->entry_top = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_container_add (GTK_CONTAINER (edit->entry_top), GTK_WIDGET (edit->entry));
+ gtk_widget_set_uposition (edit->entry_top, 20000, 20000);
+ gtk_widget_show_all (edit->entry_top);
+
+ ect_queue_redraw (text_view, col, row);
+
+ return NULL;
+}
+
+/*
+ * ECellView::leave_edit method
+ */
+static void
+ect_leave_edit (ECellView *ecell_view, int col, int row, void *edit_context)
+{
+ ECellTextView *text_view = (ECellTextView *) ecell_view;
+
+ printf ("Leaving edit mode!\n");
+
+ ect_accept_edits (text_view);
+ ect_stop_editing (text_view);
+}
+
+/*
+ * GtkObject::destroy method
+ */
static void
ect_destroy (GtkObject *object)
{
@@ -170,12 +413,14 @@ e_cell_text_class_init (GtkObjectClass *object_class)
object_class->destroy = ect_destroy;
- ecc->realize = ect_realize;
- ecc->unrealize = ect_unrealize;
- ecc->draw = ect_draw;
- ecc->event = ect_event;
- ecc->height = ect_height;
-
+ ecc->realize = ect_realize;
+ ecc->unrealize = ect_unrealize;
+ ecc->draw = ect_draw;
+ ecc->event = ect_event;
+ ecc->height = ect_height;
+ ecc->enter_edit = ect_enter_edit;
+ ecc->leave_edit = ect_leave_edit;
+
parent_class = gtk_type_class (PARENT_TYPE);
}
diff --git a/widgets/table/e-cell.c b/widgets/table/e-cell.c
index 9caa31f2ca..2bc49f7a45 100644
--- a/widgets/table/e-cell.c
+++ b/widgets/table/e-cell.c
@@ -13,7 +13,7 @@
#define PARENT_TYPE gtk_object_get_type()
static ECellView *
-ec_realize (ECell *e_cell, GnomeCanvas *canvas)
+ec_realize (ECell *e_cell, void *view)
{
return NULL;
}
@@ -28,20 +28,20 @@ ec_draw (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected,
int x1, int y1, int x2, int y2)
{
- g_warning ("e-cell-draw invoked\n");
+ g_error ("e-cell-draw invoked\n");
}
static gint
ec_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
{
- g_warning ("e-cell-event invoked\n");
+ g_error ("e-cell-event invoked\n");
return 0;
}
static gint
ec_height (ECellView *ecell_view, int col, int row)
{
- g_warning ("e-cell-event invoked\n");
+ g_error ("e-cell-event invoked\n");
return 0;
}
@@ -98,10 +98,10 @@ e_cell_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
}
ECellView *
-e_cell_realize (ECell *ecell, GnomeCanvas *canvas)
+e_cell_realize (ECell *ecell, void *view)
{
return E_CELL_CLASS (GTK_OBJECT (ecell)->klass)->realize (
- ecell, canvas);
+ ecell, view);
}
void
@@ -125,3 +125,16 @@ e_cell_height (ECellView *ecell_view, int col, int row)
ecell_view, col, row);
}
+void *
+e_cell_enter_edit (ECellView *ecell_view, int col, int row)
+{
+ return E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->enter_edit (
+ ecell_view, col, row);
+}
+
+void
+e_cell_leave_edit (ECellView *ecell_view, int col, int row, void *edit_context)
+{
+ E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->leave_edit (
+ ecell_view, col, row, edit_context);
+}
diff --git a/widgets/table/e-cell.h b/widgets/table/e-cell.h
index 9cd62f3909..b0f62d020c 100644
--- a/widgets/table/e-cell.h
+++ b/widgets/table/e-cell.h
@@ -1,7 +1,7 @@
#ifndef _E_CELL_H_
#define _E_CELL_H_
-#include <libgnomeui/gnome-canvas.h>
+#include <gdk/gdktypes.h>
#include "e-table-model.h"
#define E_CELL_TYPE (e_cell_get_type ())
@@ -29,19 +29,22 @@ struct _ECellView {
typedef struct {
GtkObjectClass parent_class;
- ECellView *(*realize) (ECell *, GnomeCanvas *canvas);
- void (*unrealize) (ECellView *);
+ ECellView *(*realize) (ECell *ecell, void *view);
+ void (*unrealize) (ECellView *e_cell_view);
void (*draw) (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected, 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);
- int (*height) (ECellView *ecell, int col, int row);
+ void (*focus) (ECellView *ecell_view, int col, int row, int x1, int y1, int x2, int y2);
+ void (*unfocus) (ECellView *ecell_view);
+ int (*height) (ECellView *ecell_view, int col, int row);
+
+ void *(*enter_edit)(ECellView *ecell_view, int col, int row);
+ void (*leave_edit)(ECellView *ecell_view, int col, int row, void *context);
} ECellClass;
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);
+ECellView *e_cell_realize (ECell *ecell, void *view);
void e_cell_unrealize (ECellView *ecell_view);
void e_cell_draw (ECellView *ecell_view, GdkDrawable *dr,
int col, int row, gboolean selected,
@@ -50,4 +53,7 @@ void e_cell_focus (ECellView *ecell_view, int col, int row, int x1, in
void e_cell_unfocus (ECellView *ecell_view);
int e_cell_height (ECellView *ecell_view, int col, int row);
+void *e_cell_enter_edit(ECellView *ecell_view, int col, int row);
+void e_cell_leave_edit(ECellView *ecell_view, int col, int row, void *edit_context);
+
#endif /* _E_CELL_H_ */
diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c
index a561fbfd15..1b98bbfce4 100644
--- a/widgets/table/e-table-item.c
+++ b/widgets/table/e-table-item.c
@@ -37,6 +37,7 @@ enum {
ARG_TABLE_X,
ARG_TABLE_Y,
ARG_TABLE_DRAW_GRID,
+ ARG_TABLE_DRAW_FOCUS,
ARG_LENGHT_THRESHOLD
};
@@ -51,7 +52,6 @@ enum {
static void
eti_realize_cell_views (ETableItem *eti)
{
- GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti);
int i;
/*
@@ -63,7 +63,7 @@ eti_realize_cell_views (ETableItem *eti)
for (i = 0; i < eti->n_cells; i++){
ETableCol *col = e_table_header_get_column (eti->header, i);
- eti->cell_views [i] = e_cell_realize (col->ecell, item->canvas);
+ eti->cell_views [i] = e_cell_realize (col->ecell, eti);
}
}
@@ -117,12 +117,9 @@ eti_remove_table_model (ETableItem *eti)
gtk_signal_disconnect (GTK_OBJECT (eti->table_model),
eti->table_model_change_id);
- gtk_signal_disconnect (GTK_OBJECT (eti->table_model),
- 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;
}
@@ -284,7 +281,9 @@ eti_row_diff (ETableItem *eti, int start_row, int end_row)
* border as well.
*/
static void
-eti_request_region_redraw (ETableItem *eti, int start_col, int start_row, int end_col, int end_row, int border)
+eti_request_region_redraw (ETableItem *eti,
+ int start_col, int start_row,
+ int end_col, int end_row, int border)
{
GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
int x1, y1, width, height;
@@ -301,10 +300,25 @@ eti_request_region_redraw (ETableItem *eti, int start_col, int start_row, int en
eti->y1 + y1 + height + 1 + border);
}
-static void
-eti_table_model_row_selection (ETableModel *table_model, int row, gboolean selected, ETableItem *eti)
+void
+e_table_item_redraw_range (ETableItem *eti,
+ int start_col, int start_row,
+ int end_col, int end_row)
{
- eti_request_region_redraw (eti, 0, row, eti->cols - 1, row, 0);
+ int border;
+
+ g_return_if_fail (eti != NULL);
+ g_return_if_fail (E_IS_TABLE_ITEM (eti));
+
+ if ((start_col == eti->focused_col) ||
+ (end_col == eti->focused_col) ||
+ (start_row == eti->focused_row) ||
+ (end_row == eti->focused_row))
+ border = 2;
+ else
+ border = 0;
+
+ eti_request_region_redraw (eti, start_col, start_row, end_col, end_row, border);
}
static void
@@ -313,14 +327,11 @@ eti_add_table_model (ETableItem *eti, ETableModel *table_model)
g_assert (eti->table_model == NULL);
eti->table_model = table_model;
- gtk_object_ref (GTK_OBJECT (table_model));
+ gtk_object_ref (GTK_OBJECT (eti->table_model));
eti->table_model_change_id = gtk_signal_connect (
GTK_OBJECT (table_model), "model_changed",
GTK_SIGNAL_FUNC (eti_table_model_changed), eti);
- eti->table_model_selection_id = gtk_signal_connect (
- GTK_OBJECT (table_model), "row_selection",
- GTK_SIGNAL_FUNC (eti_table_model_row_selection), eti);
eti_table_model_changed (table_model, eti);
}
@@ -418,6 +429,11 @@ eti_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
case ARG_TABLE_DRAW_GRID:
eti->draw_grid = GTK_VALUE_BOOL (*arg);
+ break;
+
+ case ARG_TABLE_DRAW_FOCUS:
+ eti->draw_focus = GTK_VALUE_BOOL (*arg);
+ break;
}
eti_update (item, NULL, NULL, 0);
}
@@ -529,7 +545,7 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
int f_x1, f_x2, f_y1, f_y2;
gboolean f_found;
- printf ("Rect: %d %d %d %d\n", x, y, width, height);
+/* printf ("Rect: %d %d %d %d\n", x, y, width, height); */
/*
* Clear the background
*/
@@ -604,7 +620,7 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
height = eti_row_height (eti, row);
xd = x_offset;
- printf ("paint: %d %d\n", yd, yd + height);
+/* printf ("paint: %d %d\n", yd, yd + height); */
selected = g_slist_find (eti->selection, GINT_TO_POINTER (row)) != NULL;
@@ -631,9 +647,7 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
/*
* Draw focus
*/
- if (f_found){
- printf ("FOUD: %d %d %d %d!\n",
- f_x1 - 1, f_y1 - 1, f_x2 - f_x1 + 2 , f_y2 - f_y1 + 2);
+ if (f_found && eti->draw_focus){
gdk_draw_rectangle (
drawable, eti->focus_gc, FALSE,
f_x1 - 1, f_y1 - 1, f_x2 - f_x1 + 2 , f_y2 - f_y1 + 2);
@@ -725,6 +739,8 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
}
case GDK_KEY_PRESS:
+ printf ("KEYPRESS!\n");
+
if (eti->focused_col == -1)
return FALSE;
@@ -781,6 +797,7 @@ eti_row_selection (ETableItem *eti, int row, gboolean selected)
eti->selection = g_slist_prepend (eti->selection, GINT_TO_POINTER (row));
else
eti->selection = g_slist_remove (eti->selection, GINT_TO_POINTER (row));
+
}
static void
@@ -813,6 +830,8 @@ eti_class_init (GtkObjectClass *object_class)
GTK_ARG_WRITABLE, ARG_TABLE_Y);
gtk_object_add_arg_type ("ETableItem::drawgrid", GTK_TYPE_BOOL,
GTK_ARG_WRITABLE, ARG_TABLE_DRAW_GRID);
+ gtk_object_add_arg_type ("ETableItem::drawfocus", GTK_TYPE_BOOL,
+ GTK_ARG_WRITABLE, ARG_TABLE_DRAW_FOCUS);
eti_signals [ROW_SELECTION] =
gtk_signal_new ("row_selection",
@@ -862,6 +881,11 @@ e_table_item_focus (ETableItem *eti, int col, int row)
eti->focused_row = row;
eti_request_region_redraw (eti, col, row, col, row, FOCUSED_BORDER);
+
+ /*
+ * make sure we have the Gtk Focus
+ */
+ gtk_widget_grab_focus (GTK_WIDGET (GNOME_CANVAS_ITEM (eti)->canvas));
}
void
@@ -944,7 +968,7 @@ void
e_table_item_select_row (ETableItem *eti, int row)
{
g_return_if_fail (eti != NULL);
- g_return_if_fail (E_IS_TABLE_ITEM (eti));
+ g_return_if_fail (E_IS_TABLE_ITEM (eti));
switch (eti->selection_mode){
case GTK_SELECTION_SINGLE:
@@ -973,3 +997,28 @@ e_table_item_select_row (ETableItem *eti, int row)
}
}
+
+void
+e_table_item_enter_edit (ETableItem *eti, int col, int row)
+{
+ g_return_if_fail (eti != NULL);
+ g_return_if_fail (E_IS_TABLE_ITEM (eti));
+
+ eti->editing_col = col;
+ eti->editing_row = row;
+
+ eti->edit_ctx = e_cell_enter_edit (eti->cell_views [col], col, row);
+}
+
+void
+e_table_item_leave_edit (ETableItem *eti)
+{
+ g_return_if_fail (eti != NULL);
+ g_return_if_fail (E_IS_TABLE_ITEM (eti));
+
+ e_cell_leave_edit (eti->cell_views [eti->editing_col], eti->editing_col, eti->editing_row, eti->edit_ctx);
+ eti->editing_col = -1;
+ eti->editing_row = -1;
+ eti->edit_ctx = NULL;
+}
+
diff --git a/widgets/table/e-table-item.h b/widgets/table/e-table-item.h
index 17d422ddf5..02f7beb1ac 100644
--- a/widgets/table/e-table-item.h
+++ b/widgets/table/e-table-item.h
@@ -28,14 +28,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;
GdkGC *focus_gc;
unsigned int draw_grid:1;
-
+ unsigned int draw_focus:1;
+
int focused_col, focused_row;
/*
@@ -52,6 +52,12 @@ typedef struct {
GSList *selection;
GtkSelectionMode selection_mode;
+
+ /*
+ * During edition
+ */
+ int editing_col, editing_row;
+ void *edit_ctx;
} ETableItem;
typedef struct {
@@ -85,4 +91,11 @@ void e_table_item_set_selection_mode (ETableItem *e_table_Item,
gboolean e_table_item_is_row_selected (ETableItem *e_table_Item,
int row);
+void e_table_item_leave_edit (ETableItem *eti);
+void e_table_item_enter_edit (ETableItem *eti, int col, int row);
+
+void e_table_item_redraw_range (ETableItem *eti,
+ int start_col, int start_row,
+ int end_col, int end_row);
+
#endif /* _E_TABLE_ITEM_H_ */
diff --git a/widgets/table/e-table-model.c b/widgets/table/e-table-model.c
index 288c20f20e..103bb31b57 100644
--- a/widgets/table/e-table-model.c
+++ b/widgets/table/e-table-model.c
@@ -61,7 +61,7 @@ e_table_model_value_at (ETableModel *e_table_model, int col, int row)
}
void
-e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, void *data)
+e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, const void *data)
{
g_return_if_fail (e_table_model != NULL);
g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
diff --git a/widgets/table/e-table-model.h b/widgets/table/e-table-model.h
index ea5d31493d..22339ae484 100644
--- a/widgets/table/e-table-model.h
+++ b/widgets/table/e-table-model.h
@@ -23,7 +23,7 @@ typedef struct {
const char *(*column_name) (ETableModel *etm, int col);
int (*row_count) (ETableModel *etm);
void *(*value_at) (ETableModel *etm, int col, int row);
- void (*set_value_at) (ETableModel *etm, int col, int row, void *value);
+ void (*set_value_at) (ETableModel *etm, int col, int row, const void *value);
gboolean (*is_cell_editable) (ETableModel *etm, int col, int row);
/*
@@ -40,7 +40,7 @@ int e_table_model_column_count (ETableModel *e_table_model);
const char *e_table_model_column_name (ETableModel *e_table_model, int col);
int e_table_model_row_count (ETableModel *e_table_model);
void *e_table_model_value_at (ETableModel *e_table_model, int col, int row);
-void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, void *data);
+void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, const void *data);
gboolean e_table_model_is_cell_editable (ETableModel *e_table_model, int col, int row);
/*
diff --git a/widgets/table/e-table-simple.c b/widgets/table/e-table-simple.c
index 16691e5442..2076e06cef 100644
--- a/widgets/table/e-table-simple.c
+++ b/widgets/table/e-table-simple.c
@@ -47,7 +47,7 @@ simple_value_at (ETableModel *etm, int col, int row)
}
static void
-simple_set_value_at (ETableModel *etm, int col, int row, void *val)
+simple_set_value_at (ETableModel *etm, int col, int row, const void *val)
{
ETableSimple *simple = (ETableSimple *)etm;
diff --git a/widgets/table/e-table-simple.h b/widgets/table/e-table-simple.h
index 544e681a6c..1f7a17aeff 100644
--- a/widgets/table/e-table-simple.h
+++ b/widgets/table/e-table-simple.h
@@ -7,7 +7,7 @@ typedef int (*ETableSimpleColumnCountFn) (ETableModel *etm, void *dat
typedef const char *(*ETableSimpleColumnNameFn) (ETableModel *etm, int col, void *data);
typedef int (*ETableSimpleRowCountFn) (ETableModel *etm, void *data);
typedef void *(*ETableSimpleValueAtFn) (ETableModel *etm, int col, int row, void *data);
-typedef void (*ETableSimpleSetValueAtFn) (ETableModel *etm, int col, int row, void *val, void *data);
+typedef void (*ETableSimpleSetValueAtFn) (ETableModel *etm, int col, int row, const void *val, void *data);
typedef gboolean (*ETableSimpleIsCellEditableFn) (ETableModel *etm, int col, int row, void *data);
typedef struct {
diff --git a/widgets/table/table-test.c b/widgets/table/table-test.c
index 3517ecf692..f677e9e2d1 100644
--- a/widgets/table/table-test.c
+++ b/widgets/table/table-test.c
@@ -151,7 +151,7 @@ value_at (ETableModel *etc, int col, int row, void *data)
}
static void
-set_value_at (ETableModel *etc, int col, int row, void *val, void *data)
+set_value_at (ETableModel *etc, int col, int row, const void *val, void *data)
{
g_assert (col < cols);
g_assert (row < lines);
@@ -236,6 +236,7 @@ main (int argc, char *argv [])
"x", 10,
"y", 30,
"drawgrid", TRUE,
+ "drawfocus", TRUE,
NULL);
gtk_main ();