From ed6d71b37f7102db9f35a3c742350de83cefe2e8 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 23 Aug 2007 20:31:16 +0000 Subject: ** Fixes bug #303878 2007-08-23 Matthew Barnes ** Fixes bug #303878 * widgets/text/e-text.h: preedit_pos: new value. * widgets/text/e-text.c: (e_text_get_cursor_locations): New function. Get the cursor locations. (update_im_cursor_position): New function. Set the cursor location to IMContext. (insert_preedit_text): Call update_im_cursor_position when draw preedit text. (e_text_preedit_changed_cb): Set the preedit cursor position to preedit_pos. Patch by Hiroyuki Ikezoe and makuchaku. svn path=/trunk/; revision=34081 --- widgets/ChangeLog | 15 ++++++++++++ widgets/text/e-text.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++--- widgets/text/e-text.h | 1 + 3 files changed, 77 insertions(+), 3 deletions(-) (limited to 'widgets') diff --git a/widgets/ChangeLog b/widgets/ChangeLog index 8ed846152c..7e9017ce92 100644 --- a/widgets/ChangeLog +++ b/widgets/ChangeLog @@ -1,3 +1,18 @@ +2007-08-23 Matthew Barnes + + ** Fixes bug #303878 + + * text/e-text.h: preedit_pos: new value. + * text/e-text.c: (e_text_get_cursor_locations): + New function. Get the cursor locations. + (update_im_cursor_position): New function. + Set the cursor location to IMContext. + (insert_preedit_text): Call update_im_cursor_position when draw + preedit text. + (e_text_preedit_changed_cb): Set the preedit cursor position to + preedit_pos. + Patch by Hiroyuki Ikezoe and makuchaku. + 2007-07-27 Hiroyuki Ikezoe * text/e-text-model-uri.c: diff --git a/widgets/text/e-text.c b/widgets/text/e-text.c index 932144a343..86c68d651f 100644 --- a/widgets/text/e-text.c +++ b/widgets/text/e-text.c @@ -132,6 +132,7 @@ static void e_text_insert(EText *text, const char *string); static void reset_layout_attrs (EText *text); +static void update_im_cursor_position (EText *text); #if 0 /* GtkEditable Methods */ static void e_text_editable_do_insert_text (GtkEditable *editable, @@ -329,6 +330,8 @@ insert_preedit_text (EText *text) pango_layout_set_attributes (text->layout, attrs); pango_attr_list_unref (attrs); } + + update_im_cursor_position (text); } if (preedit_string) @@ -3720,6 +3723,7 @@ e_text_init (EText *text) text->model = e_text_model_new (); text->text = e_text_model_get_text (text->model); text->preedit_len = 0; + text->preedit_pos = 0; text->layout = NULL; text->revert = NULL; @@ -3820,17 +3824,71 @@ e_text_commit_cb (GtkIMContext *context, } } +/* + * Fetch cursor location into Strong or Weak positions so as to + * display the preedit candidate selection window in the right place + */ +static void +e_text_get_cursor_locations (EText *text, + GdkRectangle *strong_pos, + GdkRectangle *weak_pos) +{ + double x1, y1; + PangoRectangle pango_strong_pos; + PangoRectangle pango_weak_pos; + int cx, cy; + gint index; + + gnome_canvas_item_get_bounds (GNOME_CANVAS_ITEM (text), &x1, &y1, NULL, NULL); + + gnome_canvas_get_scroll_offsets (GNOME_CANVAS (GNOME_CANVAS_ITEM (text)->canvas), &cx, &cy); + + index = g_utf8_offset_to_pointer (text->text, text->selection_start) - text->text; + + pango_layout_get_cursor_pos (text->layout, index + text->preedit_pos, + strong_pos ? &pango_strong_pos : NULL, + weak_pos ? &pango_weak_pos : NULL); + + if (strong_pos) { + strong_pos->x = x1 - cx - text->xofs_edit + pango_strong_pos.x / PANGO_SCALE; + strong_pos->y = y1 - cy - text->yofs_edit + pango_strong_pos.y / PANGO_SCALE; + strong_pos->width = 0; + strong_pos->height = pango_strong_pos.height / PANGO_SCALE; + } + + if (weak_pos) { + weak_pos->x = x1 - cx - text->xofs_edit + pango_weak_pos.x / PANGO_SCALE; + weak_pos->y = y1 - cy - text->yofs_edit + pango_weak_pos.y / PANGO_SCALE; + weak_pos->width = 0; + weak_pos->height = pango_weak_pos.height / PANGO_SCALE; + } +} + +/* Update IM's cursor position to display candidate selection window */ +static void +update_im_cursor_position (EText *text) +{ + GdkRectangle area; + + e_text_get_cursor_locations (text, &area, NULL); + + gtk_im_context_set_cursor_location (text->im_context, &area); +} + static void e_text_preedit_changed_cb (GtkIMContext *context, - EText *etext) + EText *etext) { gchar *preedit_string = NULL; + gint cursor_pos; gtk_im_context_get_preedit_string (context, &preedit_string, - NULL, NULL); + NULL, &cursor_pos); + cursor_pos = CLAMP (cursor_pos, 0, g_utf8_strlen (preedit_string, -1)); etext->preedit_len = strlen (preedit_string); - g_free (preedit_string); + etext->preedit_pos = g_utf8_offset_to_pointer (preedit_string, cursor_pos) - preedit_string; + g_free (preedit_string); g_signal_emit (etext, e_text_signals[E_TEXT_KEYPRESS], 0, 0, 0); } diff --git a/widgets/text/e-text.h b/widgets/text/e-text.h index 4d2e4abcf0..174b9e328d 100644 --- a/widgets/text/e-text.h +++ b/widgets/text/e-text.h @@ -109,6 +109,7 @@ struct _EText { const gchar *text; /* Text to display --- from the ETextModel */ gint preedit_len; /* preedit length to display */ + gint preedit_pos; /* preedit cursor position */ PangoLayout *layout; int num_lines; /* Number of lines of text */ -- cgit v1.2.3