Index: e-text.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-text/e-text.c,v
retrieving revision 1.158
diff -u -r1.158 e-text.c
--- e-text.c	30 Aug 2004 17:58:34 -0000	1.158
+++ e-text.c	1 Nov 2004 10:43:15 -0000
@@ -283,71 +283,21 @@
 		g_object_unref (text->im_context);
 		text->im_context = NULL;
 	}
+	if (text->im_preedit) {
+		g_free (text->im_preedit);
+		text->im_preedit = NULL;
+	}
+	if (text->im_preedit_attrs != NULL) {
+		pango_attr_list_unref (text->im_preedit_attrs);
+		text->im_preedit_attrs = NULL;
+	}
+	text->im_preedit_start = 0;
 
 	if (G_OBJECT_CLASS (parent_class)->dispose)
 		(* G_OBJECT_CLASS (parent_class)->dispose) (object);
 }
 
 static void
-insert_preedit_text (EText *text)
-{
-	PangoAttrList *attrs = NULL;
-	PangoAttrList *preedit_attrs = NULL;
-	gchar *preedit_string = NULL;
-	GString *tmp_string = g_string_new (NULL);
-	gint length = 0, cpos = 0, preedit_length = 0;
-	gboolean new_attrs = FALSE;
-
-	if (text->layout == NULL || !GTK_IS_IM_CONTEXT (text->im_context))
-		return;
-
-	text->text = e_text_model_get_text(text->model);
-	length = strlen (text->text);
-
-	g_string_prepend_len (tmp_string, text->text,length); 
-
-	if (text->preedit_len)
-		gtk_im_context_get_preedit_string (text->im_context,
-					   &preedit_string, &preedit_attrs,
-					   NULL);
-
-	if (preedit_string && g_utf8_validate (preedit_string, -1, NULL))
-		text->preedit_len = preedit_length = strlen (preedit_string);
-	else
-		text->preedit_len  = preedit_length = 0;
-
-	cpos = g_utf8_offset_to_pointer (text->text, text->selection_start) - text->text;	
-
-	if (preedit_length) {
-		g_string_insert (tmp_string, cpos, preedit_string);
-
-		reset_layout_attrs (text);
-
-		attrs = pango_layout_get_attributes (text->layout);
-		if (!attrs) {
-			attrs = pango_attr_list_new ();
-			new_attrs = TRUE;
-		}
-
-		pango_layout_set_text (text->layout, tmp_string->str, tmp_string->len);
-
-		pango_attr_list_splice (attrs, preedit_attrs, cpos, preedit_length);
-
-		if (new_attrs) {
-			pango_layout_set_attributes (text->layout, attrs);
-			pango_attr_list_unref (attrs);
-		}
-	}
-
-	if (preedit_string)
-		g_free (preedit_string);
-	if (preedit_attrs)
-		pango_attr_list_unref (preedit_attrs);
-	if (tmp_string)
-		g_string_free (tmp_string, TRUE);
-}
-
-static void
 reset_layout_attrs (EText *text)
 {
 	PangoAttrList *attrs = NULL;
@@ -394,6 +344,19 @@
 			pango_attr_list_insert_before (attrs, attr);
 		}
 	}
+
+	if (text->im_preedit_attrs) {
+		gint prelen = g_utf8_offset_to_pointer (text->text, MAX (text->selection_start, text->selection_end)) - text->text - strlen (text->im_preedit);
+
+		g_assert (prelen >= 0);
+
+		if (!attrs)
+			attrs = pango_attr_list_new ();
+
+		pango_attr_list_splice (attrs, text->im_preedit_attrs, prelen, strlen (text->im_preedit));
+		text->im_preedit_start = MAX (text->selection_start, text->selection_end) - g_utf8_strlen(text->im_preedit, -1);
+	}
+
 	pango_layout_set_attributes (text->layout, attrs);
 	if (attrs)
 		pango_attr_list_unref (attrs);
@@ -1502,9 +1465,6 @@
 		}
 	}
 
-
-	insert_preedit_text (text);	
-
 	if (!pango_layout_get_text (text->layout))
 		return;
 
@@ -1627,7 +1587,7 @@
 				PangoRectangle strong_pos, weak_pos;
 				char *offs = g_utf8_offset_to_pointer (text->text, text->selection_start);
 
-				pango_layout_get_cursor_pos (text->layout, offs - text->text + text->preedit_len, &strong_pos, &weak_pos);
+				pango_layout_get_cursor_pos (text->layout, offs - text->text, &strong_pos, &weak_pos);
 				draw_pango_rectangle (drawable, main_gc, xpos, ypos, strong_pos);
 				if (strong_pos.x != weak_pos.x ||
 				    strong_pos.y != weak_pos.y ||
@@ -2222,7 +2182,7 @@
 				 * for text, we are saving text for 
 				 * disconnecting in the next focus_in.
 				 */
-				if (!text->preedit_len && text->im_context) {
+				if (!text->im_preedit && text->im_context) {
 					g_signal_handlers_disconnect_matched (text->im_context,
 									      G_SIGNAL_MATCH_DATA,
 									      0, 0, NULL,
@@ -2251,6 +2211,13 @@
 		break;
 	case GDK_KEY_PRESS: 
 
+		if (text->editing) {
+			if (text->im_context && gtk_im_context_filter_keypress (text->im_context, (GdkEventKey*)event)) {
+				text->need_im_reset = TRUE;
+				return 1;
+			}
+		}
+
 		/* Handle S-F10 key binding here. */
 
 		if (event->key.keyval == GDK_F10 
@@ -2274,11 +2241,6 @@
 			GdkEventKey key;
 			gint ret;
 
-			if (text->im_context && gtk_im_context_filter_keypress (text->im_context, (GdkEventKey*)event)) {
-				text->need_im_reset = TRUE;
-				return 1;
-			}
-
 			key = event->key;
 			e_tep_event.key.time = key.time;
 			e_tep_event.key.state = key.state;
@@ -3202,6 +3164,21 @@
 			g_timer_reset(text->timer);
 		}
 
+		if( text->im_preedit && strlen (text->im_preedit) > 0 ) {
+			gint insert_pos = text->selection_start;
+			e_text_model_delete (text->model, text->im_preedit_start, g_utf8_strlen (text->im_preedit, -1));
+			if (text->selection_start > text->im_preedit_start + g_utf8_strlen (text->im_preedit, -1)) {
+				insert_pos -= g_utf8_strlen (text->im_preedit, -1);
+			}
+			if (insert_pos > g_utf8_strlen (text->text, -1)) {
+				insert_pos = g_utf8_strlen (text->text, -1);
+			}
+			e_text_model_insert_length (text->model, insert_pos, text->im_preedit, g_utf8_strlen(text->im_preedit, -1));
+			text->im_preedit_start = insert_pos;
+			text->selection_start = insert_pos + g_utf8_strlen (text->im_preedit, -1);
+			text->selection_end = text->selection_start;
+		}
+
 		use_start = TRUE;
 		break;
 	case E_TEP_SELECT:
@@ -3713,7 +3690,6 @@
 {
 	text->model                   = e_text_model_new ();
 	text->text                    = e_text_model_get_text (text->model);
-	text->preedit_len	      = 0;
 	text->layout                  = NULL;
 
 	text->revert                  = NULL;
@@ -3790,6 +3766,9 @@
 	text->queued_requests         = NULL;
 
 	text->im_context              = NULL;
+	text->im_preedit              = NULL;
+	text->im_preedit_attrs        = NULL;
+	text->im_preedit_start        = 0;
 	text->need_im_reset           = FALSE;
 	text->im_context_signals_registered = FALSE;
 
@@ -3826,7 +3805,12 @@
 	if (g_utf8_validate (str, strlen (str), NULL)) {
 		if (text->selection_end != text->selection_start)
 			e_text_delete_selection (text);
-		e_text_insert (text, str);
+
+		if (text->im_preedit && strlen (text->im_preedit) > 0 ) {
+			e_text_model_insert_length (text->model, text->im_preedit_start, str, g_utf8_strlen (str, -1));
+		} else {
+			e_text_insert (text, str);
+		}
 		g_signal_emit (text, e_text_signals[E_TEXT_KEYPRESS], 0, 0, 0);
 	}
 }
@@ -3836,11 +3820,30 @@
 				EText        *etext)
 {
 	gchar *preedit_string = NULL;
+	PangoAttrList *attrs = NULL;
+	gint cursor = 0;
 
 	gtk_im_context_get_preedit_string (context, &preedit_string, 
-					NULL, NULL);
+					&attrs, &cursor);
+
+	if (etext->im_preedit) {
+		gint len = g_utf8_strlen (etext->im_preedit, -1);
+		e_text_model_delete (etext->model, etext->im_preedit_start, len);     
+	}
+
+	if (etext->im_preedit) {
+		g_free (etext->im_preedit);
+	}
+	etext->im_preedit = preedit_string;
+
+	if (etext->im_preedit_attrs) {
+		pango_attr_list_unref (etext->im_preedit_attrs);
+	}
+	etext->im_preedit_attrs = attrs;
+
+	etext->im_preedit_start = MAX (etext->selection_start, etext->selection_end);
 
-	etext->preedit_len = strlen (preedit_string);
+	e_text_model_insert_length(etext->model, MAX (etext->selection_start, etext->selection_end), preedit_string, g_utf8_strlen(preedit_string, -1));
 
 	g_signal_emit (etext, e_text_signals[E_TEXT_KEYPRESS], 0, 0, 0);
 }
Index: e-text.h
===================================================================
RCS file: /cvs/gnome/gal/gal/e-text/e-text.h,v
retrieving revision 1.60
diff -u -r1.60 e-text.h
--- e-text.h	26 Aug 2004 04:52:17 -0000	1.60
+++ e-text.h	1 Nov 2004 10:43:15 -0000
@@ -108,7 +108,6 @@
 	gint model_repos_signal_id;
 
 	const gchar *text;              /* Text to display --- from the ETextModel */
-	gint preedit_len;      		/* preedit length to display */
 	PangoLayout *layout;
 	int num_lines;			/* Number of lines of text */
 
@@ -210,7 +209,10 @@
 	GdkAtom  last_selection_request;  /* The time of the last selection request. */
 	GList   *queued_requests;         /* Queued selection requests. */
 
-	GtkIMContext *im_context;
+	GtkIMContext  *im_context;        /* IM context */
+	gint          im_preedit_start;   /* Preedit text insert point */
+	gchar         *im_preedit;        /* Preedit text */
+	PangoAttrList *im_preedit_attrs;  /* Preedit text attributes */
 	gboolean      need_im_reset;
 	gboolean      im_context_signals_registered;
 
