r18713 - gnucash/trunk/src/register/register-gnome - Bug #605802: Fix input of Japanese characters in register with SCIM, IIIMF and XIM
Christian Stimming
cstim at code.gnucash.org
Tue Feb 23 15:46:41 EST 2010
Author: cstim
Date: 2010-02-23 15:46:41 -0500 (Tue, 23 Feb 2010)
New Revision: 18713
Trac: http://svn.gnucash.org/trac/changeset/18713
Modified:
gnucash/trunk/src/register/register-gnome/gnucash-item-edit.c
gnucash/trunk/src/register/register-gnome/gnucash-sheet.c
gnucash/trunk/src/register/register-gnome/gnucash-sheet.h
Log:
Bug #605802: Fix input of Japanese characters in register with SCIM, IIIMF and XIM
Patch by Yasuaki Taniguchi. Revised and extended version of r18638.
The main functions are as follows:
(1) synchronization of preedit string between the register window and
sheet->entry,
(2) application to pango attributes to preedit string in the register window,
(3) include scroll offset patch (id=153514),
(4) include preedit string rollback patch (id=153518),
(5) fix formula and account cells input problem which Christian pointed out,
(6) surpress quick-fill when preedit string exists,
(7) fix Windows IME problem.
(8) Fix quick-fill problem.
Modified: gnucash/trunk/src/register/register-gnome/gnucash-item-edit.c
===================================================================
--- gnucash/trunk/src/register/register-gnome/gnucash-item-edit.c 2010-02-23 20:28:20 UTC (rev 18712)
+++ gnucash/trunk/src/register/register-gnome/gnucash-item-edit.c 2010-02-23 20:46:41 UTC (rev 18713)
@@ -184,8 +184,10 @@
const gchar *text;
PangoRectangle strong_pos;
PangoAttribute *attr;
- PangoAttrList *attr_list;
+ PangoAttrList *attr_list;
+ GnucashSheet *sheet;
+ sheet = GNUCASH_SHEET (item_edit->sheet);
style = item_edit->style;
table = item_edit->sheet->table;
@@ -233,6 +235,17 @@
info->layout = gtk_widget_create_pango_layout (GTK_WIDGET (item_edit->sheet), text);
+ /* IMContext attributes*/
+ if (sheet->preedit_length && sheet->preedit_attrs != NULL) {
+ PangoAttrList *tmp_attrs = pango_attr_list_new ();
+ pango_attr_list_splice (tmp_attrs, sheet->preedit_attrs,
+ g_utf8_offset_to_pointer (text, sheet->preedit_start_position) - text ,
+ g_utf8_offset_to_pointer (text, sheet->preedit_start_position + sheet->preedit_char_length) - text);
+ pango_layout_set_attributes (info->layout, tmp_attrs);
+ pango_attr_list_unref (tmp_attrs);
+ }
+
+
/* Selection */
if (start_pos != end_pos)
{
@@ -298,6 +311,18 @@
}
gnc_item_edit_update_offset (item_edit, info);
+
+ /* Calcurate IMContext aux window position */
+ {
+ gint xoff, yoff;
+ GdkRectangle rect;
+ rect = info->cursor_rect;
+ gnome_canvas_get_scroll_offsets(GNOME_CANVAS(sheet), &xoff, &yoff);
+ rect.x += (x - xoff + item_edit->x_offset);
+ rect.y += (y - yoff);
+ gtk_im_context_set_cursor_location (sheet->im_context, &rect);
+ }
+
}
static void
Modified: gnucash/trunk/src/register/register-gnome/gnucash-sheet.c
===================================================================
--- gnucash/trunk/src/register/register-gnome/gnucash-sheet.c 2010-02-23 20:28:20 UTC (rev 18712)
+++ gnucash/trunk/src/register/register-gnome/gnucash-sheet.c 2010-02-23 20:46:41 UTC (rev 18713)
@@ -40,6 +40,7 @@
#include "gnucash-style.h"
#include "gnucash-header.h"
#include "gnucash-item-edit.h"
+#include "split-register.h"
#include "gnc-engine.h" // For debugging, e.g. ENTER(), LEAVE()
#define DEFAULT_REGISTER_HEIGHT 400
@@ -83,8 +84,20 @@
static void gnucash_sheet_activate_cursor_cell (GnucashSheet *sheet,
gboolean changed_cells);
static void gnucash_sheet_stop_editing (GnucashSheet *sheet);
+static void gnucash_sheet_im_context_reset (GnucashSheet *sheet);
+static void gnucash_sheet_commit_cb (GtkIMContext *context, const gchar *str,
+ GnucashSheet *sheet);
+static void gnucash_sheet_preedit_changed_cb (GtkIMContext *context,
+ GnucashSheet *sheet);
+static gboolean gnucash_sheet_retrieve_surrounding_cb (GtkIMContext *context,
+ GnucashSheet *sheet);
+static gboolean gnucash_sheet_delete_surrounding_cb (GtkIMContext *context,
+ gint offset,
+ gint n_chars,
+ GnucashSheet *sheet);
+static gboolean gnucash_sheet_check_direct_update_cell(GnucashSheet *sheet,
+ const VirtualLocation virt_loc);
-
/** Implementation *****************************************************/
void
@@ -191,15 +204,35 @@
static void
gnucash_sheet_stop_editing (GnucashSheet *sheet)
{
+ /* Rollback an uncommitted string if it exists *
+ * *before* disconnecting signal handlers. */
+ gnucash_sheet_im_context_reset(sheet);
+
if (sheet->insert_signal != 0)
g_signal_handler_disconnect (G_OBJECT(sheet->entry),
sheet->insert_signal);
if (sheet->delete_signal != 0)
g_signal_handler_disconnect (G_OBJECT(sheet->entry),
sheet->delete_signal);
-
+ if (sheet->commit_signal != 0)
+ g_signal_handler_disconnect (G_OBJECT(sheet->im_context),
+ sheet->commit_signal);
+ if (sheet->preedit_changed_signal != 0)
+ g_signal_handler_disconnect (G_OBJECT(sheet->im_context),
+ sheet->preedit_changed_signal);
+ if (sheet->retrieve_surrounding_signal != 0)
+ g_signal_handler_disconnect (G_OBJECT(sheet->im_context),
+ sheet->retrieve_surrounding_signal);
+ if (sheet->delete_surrounding_signal != 0)
+ g_signal_handler_disconnect (G_OBJECT(sheet->im_context),
+ sheet->delete_surrounding_signal);
sheet->insert_signal = 0;
sheet->delete_signal = 0;
+ sheet->commit_signal = 0;
+ sheet->preedit_changed_signal = 0;
+ sheet->retrieve_surrounding_signal = 0;
+ sheet->delete_surrounding_signal = 0;
+ sheet->direct_update_cell = FALSE;
gnucash_sheet_hide_editing_cursor (sheet);
@@ -270,11 +303,12 @@
gnucash_sheet_redraw_block (sheet, virt_loc.vcell_loc);
else
{
+ gnucash_sheet_im_context_reset(sheet);
gnucash_sheet_start_editing_at_cursor (sheet);
-
gtk_editable_set_position (editable, cursor_pos);
-
gtk_editable_select_region (editable, start_sel, end_sel);
+ sheet->direct_update_cell =
+ gnucash_sheet_check_direct_update_cell (sheet, virt_loc);
}
gtk_widget_grab_focus (GTK_WIDGET(sheet));
@@ -657,6 +691,10 @@
if (G_OBJECT_CLASS (sheet_parent_class)->finalize)
(*G_OBJECT_CLASS (sheet_parent_class)->finalize)(object);
+ /* Clean up IMContext and unref */
+ gnucash_sheet_im_context_reset(sheet);
+ g_object_unref (sheet->im_context);
+
/* This has to come after the parent destroy, so the item edit
destruction can do its disconnects. */
g_object_unref (sheet->entry);
@@ -674,6 +712,8 @@
window = widget->window;
gdk_window_set_back_pixmap (GTK_LAYOUT (widget)->bin_window,
NULL, FALSE);
+ gtk_im_context_set_client_window( GNUCASH_SHEET (widget)->im_context,
+ window);
}
@@ -947,29 +987,63 @@
{
retval = old_text;
+ /* reset IMContext if disallowed chars and clear preedit*/
+ gnucash_sheet_im_context_reset(sheet);
/* the entry was disallowed, so we stop the insert signal */
g_signal_stop_emission_by_name (G_OBJECT (sheet->entry),
"insert_text");
}
- if (*position < 0)
- *position = g_utf8_strlen(retval, -1);
+ /* sync cursor position and selection to preedit if it exists */
+ if (sheet->preedit_length) {
+ gtk_editable_set_position (editable,
+ sheet->preedit_start_position
+ + sheet->preedit_cursor_position);
+ }
+ else if (*position < 0)
+ *position = g_utf8_strlen(retval, -1);
+
#if GTK_ALLOWED_SELECTION_WITHIN_INSERT_SIGNAL
- gtk_editable_select_region (editable, start_sel, end_sel);
-#else
- {
- select_info *info;
- if (start_sel != end_sel) {
- info = g_malloc(sizeof(*info));
- info->editable = editable;
- info->start_sel = start_sel;
- info->end_sel = end_sel;
- g_timeout_add(/*ASAP*/ 1,
- (GSourceFunc)gnucash_sheet_select_data_cb,
- info);
- }
- }
-#endif
+ if (sheet->preedit_length
+ && sheet->preedit_selection_length != 0) {
+ gtk_editable_select_region (editable,
+ sheet->preedit_start_position
+ + sheet->preedit_char_length,
+ sheet->preedit_start_position
+ + sheet->preedit_char_length
+ + sheet->preedit_selection_length);
+ }
+ else
+ gtk_editable_select_region (editable, start_sel, end_sel);
+#else /* !GTK_ALLOWED_SELECTION_WITHIN_INSERT_SIGNAL */
+ if (sheet->preedit_length
+ && sheet->preedit_selection_length != 0) {
+ select_info *info;
+
+ info = g_malloc(sizeof(*info));
+ info->editable = editable;
+ info->start_sel = sheet->preedit_start_position
+ + sheet->preedit_char_length;
+ info->end_sel = sheet->preedit_start_position
+ + sheet->preedit_char_length
+ + sheet->preedit_selection_length;
+ g_timeout_add(/*ASAP*/ 1,
+ (GSourceFunc)gnucash_sheet_select_data_cb,
+ info);
+
+ } else if (start_sel != end_sel) {
+ select_info *info;
+
+ info = g_malloc(sizeof(*info));
+ info->editable = editable;
+ info->start_sel = start_sel;
+ info->end_sel = end_sel;
+ g_timeout_add(/*ASAP*/ 1,
+ (GSourceFunc)gnucash_sheet_select_data_cb,
+ info);
+ }
+#endif /* GTK_ALLOWED_SELECTION_WITHIN_INSERT_SIGNAL */
+
g_string_free (new_text_gs, TRUE);
g_string_free (change_text_gs, TRUE);
}
@@ -1070,10 +1144,28 @@
"delete_text");
}
- gtk_editable_set_position (editable, cursor_position);
- if (start_sel != end_sel)
- gtk_editable_select_region(editable, start_sel, end_sel);
+ /* sync cursor position and selection to preedit if it exists */
+ if (sheet->preedit_length) {
+ gtk_editable_set_position (editable,
+ sheet->preedit_start_position
+ + sheet->preedit_cursor_position);
+ } else {
+ gtk_editable_set_position (editable, cursor_position);
+ }
+
+ if (sheet->preedit_length
+ && sheet->preedit_selection_length != 0) {
+ gtk_editable_select_region (editable,
+ sheet->preedit_start_position
+ + sheet->preedit_char_length,
+ sheet->preedit_start_position
+ + sheet->preedit_char_length
+ + sheet->preedit_selection_length);
+ }
+ else if (start_sel != end_sel)
+ gtk_editable_select_region (editable, start_sel, end_sel);
+
g_string_free (new_text_gs, TRUE);
}
@@ -1136,7 +1228,12 @@
(widget, event);
gnc_item_edit_focus_in (GNC_ITEM_EDIT(sheet->item_editor));
+ gtk_im_context_focus_in(sheet->im_context);
+#ifdef G_OS_WIN32
+ gnucash_sheet_im_context_reset(sheet);
+#endif /* G_OS_WIN32 */
+
return FALSE;
}
@@ -1149,11 +1246,38 @@
(*GTK_WIDGET_CLASS (sheet_parent_class)->focus_out_event)
(widget, event);
+#ifdef G_OS_WIN32
+ gnucash_sheet_im_context_reset(sheet);
+#endif /* G_OS_WIN32 */
+
+ gtk_im_context_focus_out (sheet->im_context);
gnc_item_edit_focus_out (GNC_ITEM_EDIT(sheet->item_editor));
-
return FALSE;
}
+static gboolean
+gnucash_sheet_check_direct_update_cell(GnucashSheet *sheet,
+ const VirtualLocation virt_loc)
+{
+ const gchar *dupdate_list[] =
+ { /* From src/register/ledger-core/split-register.{h.c}
+ src/register/ledger-core/split-register-layout.c */
+ DATE_CELL,
+ DDUE_CELL,
+ NULL,
+ };
+ const gchar *cell_name;
+ int i;
+
+ cell_name = gnc_table_get_cell_name (sheet->table, virt_loc);
+ for (i=0; dupdate_list[i]; i++){
+ if (gnc_cell_name_equal (cell_name,
+ dupdate_list[i]))
+ return TRUE;
+ }
+ return FALSE;
+}
+
static void
gnucash_sheet_start_editing_at_cursor (GnucashSheet *sheet)
{
@@ -1184,8 +1308,26 @@
sheet->delete_signal =
g_signal_connect(G_OBJECT(sheet->entry), "delete_text",
G_CALLBACK(gnucash_sheet_delete_cb), sheet);
+
+ sheet->commit_signal =
+ g_signal_connect (G_OBJECT (sheet->im_context), "commit",
+ G_CALLBACK (gnucash_sheet_commit_cb), sheet);
+ sheet->preedit_changed_signal =
+ g_signal_connect (G_OBJECT (sheet->im_context), "preedit_changed",
+ G_CALLBACK (gnucash_sheet_preedit_changed_cb),
+ sheet);
+ sheet->retrieve_surrounding_signal =
+ g_signal_connect (G_OBJECT (sheet->im_context),
+ "retrieve_surrounding",
+ G_CALLBACK (gnucash_sheet_retrieve_surrounding_cb),
+ sheet);
+ sheet->delete_surrounding_signal =
+ g_signal_connect (G_OBJECT (sheet->im_context), "delete_surrounding",
+ G_CALLBACK (gnucash_sheet_delete_surrounding_cb),
+ sheet);
}
+
static gboolean
gnucash_motion_event (GtkWidget *widget, GdkEventMotion *event)
{
@@ -1645,7 +1787,7 @@
}
static gint
-gnucash_sheet_key_press_event (GtkWidget *widget, GdkEventKey *event)
+gnucash_sheet_key_press_event_internal (GtkWidget *widget, GdkEventKey *event)
{
Table *table;
GnucashSheet *sheet;
@@ -1673,7 +1815,7 @@
/* Don't process any keystrokes where a modifier key (Alt,
* Meta, etc.) is being held down. This should't include
- * MOD2, aka NUM LOCK. */
+ * MOD2, aka NUM LOCK. */
if (event->state & (GDK_MOD1_MASK | GDK_MOD3_MASK |
GDK_MOD4_MASK | GDK_MOD5_MASK))
pass_on = TRUE;
@@ -1771,8 +1913,17 @@
}
/* Forward the keystroke to the input line */
- if (pass_on)
- return gtk_widget_event (sheet->entry, (GdkEvent *) event);
+ if (pass_on) {
+ GValue gval = {0,};
+ gboolean result;
+ g_value_init (&gval, G_TYPE_BOOLEAN);
+ g_value_set_boolean (&gval, TRUE);
+ g_object_set_property (G_OBJECT (sheet->entry), "editable", &gval);
+ result = gtk_widget_event (sheet->entry, (GdkEvent *) event);
+ g_value_set_boolean (&gval, FALSE);
+ g_object_set_property (G_OBJECT (sheet->entry), "editable", &gval);
+ return result;
+ }
abort_move = gnc_table_traverse_update (table, cur_virt_loc,
direction, &new_virt_loc);
@@ -1787,8 +1938,238 @@
return TRUE;
}
+static gint
+gnucash_sheet_key_press_event (GtkWidget *widget, GdkEventKey *event)
+{
+ GnucashSheet *sheet;
+ gint result;
+ g_return_val_if_fail(widget != NULL, TRUE);
+ g_return_val_if_fail(GNUCASH_IS_SHEET(widget), TRUE);
+ g_return_val_if_fail(event != NULL, TRUE);
+
+ sheet = GNUCASH_SHEET (widget);
+
+ if (gtk_im_context_filter_keypress (sheet->im_context, event)) {
+ sheet->need_im_reset = TRUE;
+ return TRUE;
+ }
+
+ return gnucash_sheet_key_press_event_internal (widget, event);
+}
+
+static gint
+gnucash_sheet_key_release_event(GtkWidget *widget, GdkEventKey *event)
+{
+ GnucashSheet *sheet;
+
+ g_return_val_if_fail(widget != NULL, TRUE);
+ g_return_val_if_fail(GNUCASH_IS_SHEET(widget), TRUE);
+ g_return_val_if_fail(event != NULL, TRUE);
+
+ sheet = GNUCASH_SHEET (widget);
+
+ if(gtk_im_context_filter_keypress (sheet->im_context, event)){
+ sheet->need_im_reset = TRUE;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static void
+gnucash_sheet_im_context_reset_flags(GnucashSheet *sheet)
+{
+ sheet->preedit_length = 0;
+ sheet->preedit_char_length = 0;
+ sheet->preedit_start_position = -1;
+ sheet->preedit_cursor_position = 0;
+ sheet->preedit_selection_length = 0;
+}
+
+static void
+gnucash_sheet_im_context_reset(GnucashSheet *sheet)
+{
+ if (sheet->need_im_reset) {
+ if (sheet->preedit_attrs) {
+ pango_attr_list_unref (sheet->preedit_attrs);
+ sheet->preedit_attrs = NULL;
+ }
+ gtk_im_context_reset (sheet->im_context);
+ sheet->need_im_reset = FALSE;
+ }
+ gnucash_sheet_im_context_reset_flags(sheet);
+}
+
+static void
+gnucash_sheet_commit_cb (GtkIMContext *context, const gchar *str,
+ GnucashSheet *sheet)
+{
+ GtkEditable *editable;
+ gint tmp_pos, length, sel_start, sel_end;
+
+ g_return_if_fail(strlen(str) > 0);
+ g_return_if_fail(sheet->editing == TRUE);
+
+ editable = GTK_EDITABLE (sheet->entry);
+
+ if(strlen(str) == 1 && sheet->direct_update_cell) {
+ /* Reconstruct keyevent and direct update */
+ GdkEvent *event;
+ GdkEventKey *keyevent;
+ gboolean result;
+
+ event = gdk_event_new (GDK_KEY_PRESS);
+ keyevent = (GdkEventKey *) event;
+ keyevent->keyval = gdk_unicode_to_keyval(str[0]);
+ result = gnucash_sheet_direct_event(sheet, event);
+ gdk_event_free(event);
+
+ if (result) {
+ gnucash_sheet_im_context_reset_flags(sheet);
+ return;
+ }
+ }
+
+ /* delete preedit string from editable*/
+ if (sheet->preedit_length){
+ g_signal_handler_block (G_OBJECT (sheet->entry),
+ sheet->delete_signal);
+ gtk_editable_delete_text (editable, sheet->preedit_start_position,
+ sheet->preedit_start_position
+ + sheet->preedit_char_length);
+ g_signal_handler_unblock (G_OBJECT (sheet->entry),
+ sheet->delete_signal);
+ }
+
+ if (gtk_editable_get_selection_bounds (editable, &sel_start, &sel_end)){
+ if (sel_start != sel_end) {
+ gtk_editable_delete_selection (editable);
+ sheet->preedit_selection_length = 0;
+ }
+ }
+
+ tmp_pos = (sheet->preedit_start_position == -1)?
+ gtk_editable_get_position (editable)
+ :sheet->preedit_start_position;
+ gtk_editable_insert_text (editable, str, strlen (str), &tmp_pos);
+ gtk_editable_set_position (editable, tmp_pos);
+ gnucash_sheet_im_context_reset_flags(sheet);
+}
+
+static void
+gnucash_sheet_preedit_changed_cb (GtkIMContext *context, GnucashSheet *sheet)
+{
+ gchar *preedit_string;
+ GtkEditable *editable;
+
+ g_return_if_fail(context != NULL);
+ g_return_if_fail(sheet->editing == TRUE);
+
+ editable = GTK_EDITABLE (sheet->entry);
+
+ /* save preedit start position and selection */
+ if(sheet->preedit_length == 0) {
+ int start_pos, end_pos;
+ if ( gtk_editable_get_selection_bounds (editable, &start_pos, &end_pos)) {
+ sheet->preedit_start_position = start_pos;
+ sheet->preedit_selection_length = end_pos - start_pos;
+ } else {
+ sheet->preedit_start_position =
+ gtk_editable_get_position (editable);
+ }
+ }
+#ifdef G_OS_WIN32
+ else {/* sheet->preedit_length != 0 */
+ /* On Windows, gtk_im_context_reset() in gnucash_sheet_key_press_event()
+ * always returns FALSE because Windows IME handles key press at the
+ * top level window. So sheet->need_im_reset = TRUE here. */
+ sheet->need_im_reset = TRUE;
+ }
+#endif /* G_OS_WIN32 */
+
+ if (sheet->preedit_attrs)
+ pango_attr_list_unref (sheet->preedit_attrs);
+
+ gtk_im_context_get_preedit_string (sheet->im_context, &preedit_string,
+ &sheet->preedit_attrs, &(sheet->preedit_cursor_position));
+
+ if (sheet->preedit_length){
+ g_signal_handler_block (G_OBJECT (sheet->entry),
+ sheet->delete_signal);
+ gtk_editable_delete_text (editable, sheet->preedit_start_position,
+ sheet->preedit_start_position
+ + sheet->preedit_char_length);
+ g_signal_handler_unblock (G_OBJECT (sheet->entry),
+ sheet->delete_signal);
+ }
+
+ sheet->preedit_length = strlen (preedit_string);
+ sheet->preedit_char_length = g_utf8_strlen(preedit_string, -1);
+
+ if (sheet->preedit_length) {
+ int tmp_pos = sheet->preedit_start_position;
+ g_signal_handler_block (G_OBJECT (sheet->entry),
+ sheet->insert_signal);
+ gtk_editable_insert_text (editable, preedit_string, sheet->preedit_length,
+ &tmp_pos);
+ g_signal_handler_unblock (G_OBJECT (sheet->entry),
+ sheet->insert_signal);
+
+ gtk_editable_set_position (editable, sheet->preedit_start_position
+ + sheet->preedit_cursor_position);
+
+ if( sheet->preedit_selection_length != 0) {
+ gtk_editable_select_region (editable,
+ sheet->preedit_start_position
+ + sheet->preedit_char_length,
+ sheet->preedit_start_position
+ + sheet->preedit_char_length
+ + sheet->preedit_selection_length);
+ }
+ } else {
+ gnucash_sheet_im_context_reset_flags(sheet);
+ }
+
+ g_free (preedit_string);
+}
+
+static gboolean
+gnucash_sheet_retrieve_surrounding_cb (GtkIMContext *context, GnucashSheet *sheet)
+{
+ GtkEditable *editable;
+ gchar *surrounding;
+ gint cur_pos;
+
+ editable = GTK_EDITABLE (sheet->entry);
+ surrounding = gtk_editable_get_chars (editable, 0, -1);
+ cur_pos = gtk_editable_get_position (editable);
+
+ gtk_im_context_set_surrounding (context,
+ surrounding, strlen (surrounding),
+ g_utf8_offset_to_pointer (surrounding, cur_pos) - surrounding);
+ g_free (surrounding);
+ return TRUE;
+}
+
+static gboolean
+gnucash_sheet_delete_surrounding_cb (GtkIMContext *context, gint offset,
+ gint n_chars, GnucashSheet *sheet)
+{
+ GtkEditable *editable;
+ gint cur_pos;
+
+ editable = GTK_EDITABLE (sheet->entry);
+ cur_pos = gtk_editable_get_position (editable);
+
+ gtk_editable_delete_text (editable,
+ cur_pos + offset,
+ cur_pos + offset + n_chars);
+ return TRUE;
+}
+
+
+static void
gnucash_sheet_goto_virt_loc (GnucashSheet *sheet, VirtualLocation virt_loc)
{
Table *table;
@@ -2237,6 +2618,11 @@
static void
gnucash_sheet_realize_entry (GnucashSheet *sheet, GtkWidget *entry)
{
+ GValue gval = {0,};
+ g_value_init (&gval, G_TYPE_BOOLEAN);
+ g_value_set_boolean (&gval, FALSE);
+ g_object_set_property (G_OBJECT (entry), "editable", &gval);
+
gtk_widget_realize (entry);
}
@@ -2368,6 +2754,7 @@
widget_class->focus_out_event = gnucash_sheet_focus_out_event;
widget_class->key_press_event = gnucash_sheet_key_press_event;
+ widget_class->key_release_event = gnucash_sheet_key_release_event;
widget_class->button_press_event = gnucash_button_press_event;
widget_class->button_release_event = gnucash_button_release_event;
widget_class->motion_notify_event = gnucash_motion_event;
@@ -2412,6 +2799,21 @@
sheet->blocks = g_table_new (sizeof (SheetBlock),
gnucash_sheet_block_construct,
gnucash_sheet_block_destroy, NULL);
+
+ /* setup IMContext */
+ sheet->im_context = gtk_im_multicontext_new ();
+ sheet->preedit_length = 0;
+ sheet->preedit_char_length = 0;
+ sheet->preedit_start_position = -1;
+ sheet->preedit_cursor_position = 0;
+ sheet->preedit_selection_length = 0;
+ sheet->preedit_attrs = NULL;
+ sheet->direct_update_cell = FALSE;
+ sheet->need_im_reset = FALSE;
+ sheet->commit_signal = 0;
+ sheet->preedit_changed_signal = 0;
+ sheet->retrieve_surrounding_signal = 0;
+ sheet->delete_surrounding_signal = 0;
}
Modified: gnucash/trunk/src/register/register-gnome/gnucash-sheet.h
===================================================================
--- gnucash/trunk/src/register/register-gnome/gnucash-sheet.h 2010-02-23 20:28:20 UTC (rev 18712)
+++ gnucash/trunk/src/register/register-gnome/gnucash-sheet.h 2010-02-23 20:46:41 UTC (rev 18713)
@@ -126,6 +126,23 @@
GFunc moved_cb;
gpointer moved_cb_data;
+
+ /* IMContext */
+ GtkIMContext *im_context;
+ gint preedit_length; /* num of bytes */
+ gint preedit_char_length; /* num of chars in UTF-8 */
+ gint preedit_start_position; /* save preedit start position *
+ * combined with selection start */
+ gint preedit_cursor_position; /* save preedit cursor position */
+ gint preedit_selection_length;
+ PangoAttrList *preedit_attrs;
+ gboolean need_im_reset;
+ gboolean direct_update_cell;
+ guint commit_signal;
+ guint preedit_changed_signal;
+ guint retrieve_surrounding_signal;
+ guint delete_surrounding_signal;
+
} GnucashSheet;
More information about the gnucash-changes
mailing list