aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/text/e-text.c
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2007-08-24 04:31:16 +0800
committerMatthew Barnes <mbarnes@src.gnome.org>2007-08-24 04:31:16 +0800
commited6d71b37f7102db9f35a3c742350de83cefe2e8 (patch)
tree39a82c72eb272eedb9aaff96a00035de2b0db90a /widgets/text/e-text.c
parent97bd5a69718feac9d233b2758556a86cee9b1fec (diff)
downloadgsoc2013-evolution-ed6d71b37f7102db9f35a3c742350de83cefe2e8.tar.gz
gsoc2013-evolution-ed6d71b37f7102db9f35a3c742350de83cefe2e8.tar.zst
gsoc2013-evolution-ed6d71b37f7102db9f35a3c742350de83cefe2e8.zip
** Fixes bug #303878
2007-08-23 Matthew Barnes <mbarnes@redhat.com> ** 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
Diffstat (limited to 'widgets/text/e-text.c')
-rw-r--r--widgets/text/e-text.c64
1 files changed, 61 insertions, 3 deletions
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);
}