diff --git a/ChangeLog b/ChangeLog index 16052cd247..c8ddd780e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,10 +1,33 @@ +2000-12-18 Dave Peticolas + + * src/register/gnome/quickfillcell-gnome.c: add support for mb + char sets + + * src/register/gnome/pricecell-gnome.c: add support for mb char + sets + + * src/register/gnome/gnucash-sheet.c: add support for mb char sets + + * src/register/gnome/datecell-gnome.c: add support for mb char + sets + + * src/register/gnome/combocell-gnome.c: add support for mb char + sets + + * src/register/numcell.c: add support for mb char sets + + * src/register/basiccell.c: add support for mb char sets + + * src/register/QuickFill.c: add support for mb char sets + 2000-12-14 Robert Graham Merkel * src/guile/Makefile.am: replace hardwired g-wrap module dir with value from configure.in. - * src/engine/gnc-associate-account.[ch] : New files with code for associating - income/expense accounts with a stock account. Not yet hooked up to the UI. + * src/engine/gnc-associate-account.[ch] : New files with code for + associating income/expense accounts with a stock account. Not yet + hooked up to the UI. 2000-12-13 Rob Browning diff --git a/src/register/QuickFill.c b/src/register/QuickFill.c index 1aadb57b76..c2db6470b4 100644 --- a/src/register/QuickFill.c +++ b/src/register/QuickFill.c @@ -29,20 +29,23 @@ #include #include "QuickFill.h" +#include "basiccell.h" #include "gnc-engine.h" #include "gnc-engine-util.h" struct _QuickFill { - char * text; /* the first matching text string */ - GHashTable *matches; /* array of children in the tree */ + char *text; /* the first matching text string */ + int len; /* number of chars in text string */ + GHashTable *matches; /* array of children in the tree */ }; /** PROTOTYPES ******************************************************/ -static void quickfill_insert_recursive (QuickFill *qf, const char *text, - int depth, QuickFillSort sort); +static void quickfill_insert_recursive (QuickFill *qf, const GdkWChar *text, + int depth, const char *mb_text, + QuickFillSort sort); /* This static indicates the debugging module that this .o belongs to. */ static short module = MOD_REGISTER; @@ -75,6 +78,12 @@ gnc_quickfill_new (void) { QuickFill *qf; + if (sizeof (guint) < sizeof (GdkWChar)) + { + PWARN ("Can't use quickfill"); + return NULL; + } + /* For now, use the engine cache. */ if (qf_string_cache == NULL) qf_string_cache = gnc_string_cache; @@ -82,6 +91,8 @@ gnc_quickfill_new (void) qf = g_new (QuickFill, 1); qf->text = NULL; + qf->len = 0; + qf->matches = g_hash_table_new (quickfill_hash, quickfill_compare); return qf; @@ -108,8 +119,9 @@ gnc_quickfill_destroy (QuickFill *qf) if (qf->text) g_cache_remove (qf_string_cache, qf->text); qf->text = NULL; + qf->len = 0; - g_free(qf); + g_free (qf); } /********************************************************************\ @@ -126,9 +138,9 @@ gnc_quickfill_string (QuickFill *qf) /********************************************************************\ \********************************************************************/ QuickFill * -gnc_quickfill_get_char_match (QuickFill *qf, char c) +gnc_quickfill_get_char_match (QuickFill *qf, GdkWChar wc) { - guint key = toupper(c); + guint key = islower (wc) ? toupper (wc) : wc; if (qf == NULL) return NULL; @@ -141,12 +153,13 @@ gnc_quickfill_get_char_match (QuickFill *qf, char c) /********************************************************************\ \********************************************************************/ QuickFill * -gnc_quickfill_get_string_len_match (QuickFill *qf, const char *str, int len) +gnc_quickfill_get_string_len_match (QuickFill *qf, + const GdkWChar *str, int len) { if (str == NULL) return NULL; - while ((*str != '\0') && (len > 0)) + while ((*str != 0) && (len > 0)) { if (qf == NULL) return NULL; @@ -163,12 +176,12 @@ gnc_quickfill_get_string_len_match (QuickFill *qf, const char *str, int len) /********************************************************************\ \********************************************************************/ QuickFill * -gnc_quickfill_get_string_match (QuickFill *qf, const char *str) +gnc_quickfill_get_string_match (QuickFill *qf, const GdkWChar *str) { if (str == NULL) return NULL; - return gnc_quickfill_get_string_len_match (qf, str, strlen(str)); + return gnc_quickfill_get_string_len_match (qf, str, gnc_wcslen (str)); } /********************************************************************\ @@ -182,7 +195,7 @@ unique_len_helper (gpointer key, gpointer value, gpointer data) } QuickFill * -gnc_quickfill_get_unique_len_match (QuickFill *qf, int * length) +gnc_quickfill_get_unique_len_match (QuickFill *qf, int *length) { if (length != NULL) *length = 0; @@ -209,28 +222,67 @@ gnc_quickfill_get_unique_len_match (QuickFill *qf, int * length) /********************************************************************\ \********************************************************************/ void -gnc_quickfill_insert (QuickFill *qf, const char * text, QuickFillSort sort) +gnc_quickfill_insert (QuickFill *qf, const char *text, QuickFillSort sort) { - quickfill_insert_recursive (qf, text, 0, sort); + GdkWChar *wc_text; + + if (text) + { + if (gnc_mbstowcs (&wc_text, text) < 0) + { + PERR ("bad text conversion"); + return; + } + } + else + wc_text = NULL; + + quickfill_insert_recursive (qf, wc_text, 0, text, sort); + + g_free (wc_text); +} + +void +gnc_quickfill_insert_wc (QuickFill *qf, const GdkWChar *text, + QuickFillSort sort) +{ + char *mb_text; + + if (text) + { + mb_text = gnc_wcstombs (text); + if (mb_text == NULL) + { + PERR ("bad text conversion"); + return; + } + } + else + mb_text = NULL; + + quickfill_insert_recursive (qf, text, 0, mb_text, sort); + + g_free (mb_text); } /********************************************************************\ \********************************************************************/ static void -quickfill_insert_recursive (QuickFill *qf, const char *text, int depth, - QuickFillSort sort) +quickfill_insert_recursive (QuickFill *qf, const GdkWChar *text, int depth, + const char *mb_text, QuickFillSort sort) { guint key; char *old_text; QuickFill *match_qf; + int len; if (qf == NULL) return; - if ((text == NULL) || (text[depth] == '\0')) + if ((text == NULL) || (text[depth] == 0)) return; - key = toupper(text[depth]); + key = islower (text[depth]) ? toupper (text[depth]) : text[depth]; match_qf = g_hash_table_lookup (qf->matches, GUINT_TO_POINTER (key)); if (match_qf == NULL) @@ -241,32 +293,36 @@ quickfill_insert_recursive (QuickFill *qf, const char *text, int depth, old_text = match_qf->text; - switch(sort) + switch (sort) { case QUICKFILL_ALPHA: - if ((old_text != NULL) && - (safe_strcmp(text, old_text) >= 0)) + if (old_text && (strcoll (mb_text, old_text) >= 0)) break; + case QUICKFILL_LIFO: default: + len = gnc_wcslen (text); + /* If there's no string there already, just put the new one in. */ if (old_text == NULL) { - match_qf->text = g_cache_insert (qf_string_cache, (gpointer) text); + match_qf->text = g_cache_insert (qf_string_cache, (gpointer) mb_text); + match_qf->len = len; break; } /* Leave prefixes in place */ - if ((strlen(text) > strlen(old_text)) && - (strncmp(text, old_text, strlen(old_text)) == 0)) + if ((len > match_qf->len) && + (strncmp(mb_text, old_text, strlen(old_text)) == 0)) break; g_cache_remove (qf_string_cache, old_text); - match_qf->text = g_cache_insert (qf_string_cache, (gpointer) text); + match_qf->text = g_cache_insert (qf_string_cache, (gpointer) mb_text); + match_qf->len = len; break; } - quickfill_insert_recursive (match_qf, text, ++depth, sort); + quickfill_insert_recursive (match_qf, text, ++depth, mb_text, sort); } /********************** END OF FILE *********************************\ diff --git a/src/register/QuickFill.h b/src/register/QuickFill.h index bca24e5a82..a53ef4a84a 100644 --- a/src/register/QuickFill.h +++ b/src/register/QuickFill.h @@ -28,6 +28,7 @@ #include "config.h" +#include #include @@ -47,13 +48,20 @@ void gnc_quickfill_destroy (QuickFill *qf); const char * gnc_quickfill_string (QuickFill *qf); -QuickFill * gnc_quickfill_get_char_match (QuickFill *qf, char c); -QuickFill * gnc_quickfill_get_string_match (QuickFill *qf, const char *str); +QuickFill * gnc_quickfill_get_char_match (QuickFill *qf, GdkWChar wc); + +QuickFill * gnc_quickfill_get_string_match (QuickFill *qf, + const GdkWChar *str); + QuickFill * gnc_quickfill_get_string_len_match (QuickFill *qf, - const char *str, int len); + const GdkWChar *str, int len); + QuickFill * gnc_quickfill_get_unique_len_match (QuickFill *qf, int *len); void gnc_quickfill_insert (QuickFill *qf, const char *text, QuickFillSort sort_code); +void gnc_quickfill_insert_wc (QuickFill *qf, const GdkWChar *text, + QuickFillSort sort_code); + #endif /* __QUICKFILL_H__ */ diff --git a/src/register/basiccell.c b/src/register/basiccell.c index 0d3bc5bfc5..a2b36ccd0f 100644 --- a/src/register/basiccell.c +++ b/src/register/basiccell.c @@ -37,8 +37,12 @@ #include #include "basiccell.h" +#include "gnc-engine-util.h" +/* This static indicates the debugging module that this .o belongs to. */ +static short module = MOD_REGISTER; + /* ===================================================== */ BasicCell * @@ -76,6 +80,9 @@ xaccClearBasicCell (BasicCell *cell) cell->conditionally_changed = 0; cell->value = NULL; + cell->value_w = NULL; + cell->value_len = 0; + cell->blank_help = NULL; cell->set_value = NULL; cell->enter_cell = NULL; @@ -99,6 +106,8 @@ xaccInitBasicCell (BasicCell *cell) cell->value = g_strdup (""); + cell->value_len = gnc_mbstowcs (&cell->value_w, cell->value); + cell->get_help_value = BasicCellHelpValue; } @@ -115,6 +124,9 @@ xaccDestroyBasicCell (BasicCell *cell) g_free (cell->value); cell->value = NULL; + g_free (cell->value_w); + cell->value_w = NULL; + g_free (cell->blank_help); cell->blank_help = NULL; @@ -142,13 +154,7 @@ xaccSetBasicCellValue (BasicCell *cell, const char *val) cell->set_value = cb; } else - { - g_free (cell->value); - if (val) - cell->value = g_strdup (val); - else - cell->value = g_strdup (""); - } + xaccSetBasicCellValueInternal (cell, val); } /* ===================================================== */ @@ -192,4 +198,119 @@ xaccBasicCellSetChanged (BasicCell *cell, gboolean changed) cell->changed = changed ? GNC_CELL_CHANGED : 0; } +/* ===================================================== */ + +void +xaccSetBasicCellValueInternal (BasicCell *cell, const char *value) +{ + if (value == NULL) + value = ""; + + g_free (cell->value); + cell->value = g_strdup (value); + + g_free (cell->value_w); + cell->value_len = gnc_mbstowcs (&cell->value_w, cell->value); +} + +void +xaccSetBasicCellWCValueInternal (BasicCell *cell, const GdkWChar *value) +{ + if (!value) + { + xaccSetBasicCellValueInternal (cell, ""); + return; + } + + g_free (cell->value); + cell->value = gnc_wcstombs (value); + + g_free (cell->value_w); + cell->value_len = gnc_mbstowcs (&cell->value_w, cell->value); +} + +/* ===================================================== */ + +gint +gnc_mbstowcs (GdkWChar **dest_p, const char *src) +{ + GdkWChar *dest; + gint src_len; + gint retval; + + if (!src) + return -1; + + src_len = strlen (src); + + dest = g_new0 (GdkWChar, src_len + 1); + + retval = gdk_mbstowcs (dest, src, src_len); + + if (retval < 0) + { + PERR ("bad multi-byte conversion"); + } + + if (dest_p) + *dest_p = dest; + else + g_free (dest); + + return retval; +} + +char * +gnc_wcstombs (const GdkWChar *src) +{ + char *retval; + + if (!src) + return NULL; + + retval = gdk_wcstombs (src); + if (!retval) + { + PERR ("bad multi-byte conversion"); + } + + return retval; +} + +gint +gnc_wcslen (const GdkWChar *src) +{ + int len = 0; + + if (!src) + return 0; + + while (src[len]) + len++; + + return len; +} + +GdkWChar * +gnc_wcsdup (const GdkWChar *src) +{ + GdkWChar *dest; + int len; + int i; + + if (!src) + return NULL; + + len = gnc_wcslen (src); + + dest = g_new (GdkWChar, len + 1); + + for (i = 0; i < len; i++) + dest[i] = src[i]; + + dest[len] = 0; + + return dest; +} + /* ================== end of file ====================== */ diff --git a/src/register/basiccell.h b/src/register/basiccell.h index e7d24e1ca6..9a8449a3b1 100644 --- a/src/register/basiccell.h +++ b/src/register/basiccell.h @@ -157,6 +157,7 @@ #ifndef __BASIC_CELL_H__ #define __BASIC_CELL_H__ +#include #include #include "gnc-common.h" @@ -177,8 +178,10 @@ typedef gboolean (*CellEnterFunc) (BasicCell *cell, int *end_selection); typedef void (*CellModifyVerifyFunc) (BasicCell *cell, - const char *add_str, - const char *new_value, + const GdkWChar *add_str, + int add_str_len, + const GdkWChar *new_value, + int new_value_len, int *cursor_position, int *start_selection, int *end_selection); @@ -191,8 +194,7 @@ typedef gboolean (*CellDirectUpdateFunc) (BasicCell *cell, typedef void (*CellLeaveFunc) (BasicCell *cell); -typedef void (*CellRealizeFunc) (BasicCell *cell, - gpointer gui_handle); +typedef void (*CellRealizeFunc) (BasicCell *cell, gpointer gui_handle); typedef void (*CellMoveFunc) (BasicCell *cell, VirtualLocation virt_loc); @@ -205,6 +207,10 @@ struct _BasicCell char * value; /* current value */ char * blank_help; /* help when value is blank */ + GdkWChar * value_w; /* value as wide chars */ + + gint value_len; /* length of wide chars value */ + guint32 changed; /* 2^32-1 if value modified */ guint32 conditionally_changed; /* value if modified conditionally */ @@ -243,4 +249,17 @@ char * xaccBasicCellGetHelp (BasicCell *bcell); void xaccBasicCellSetChanged (BasicCell *bcell, gboolean changed); +/* for sub-class use only */ +void xaccSetBasicCellValueInternal (BasicCell *bcell, + const char *value); + +void xaccSetBasicCellWCValueInternal (BasicCell *bcell, + const GdkWChar *value); + +/* helper function, allocates new wide char string for conversion */ +gint gnc_mbstowcs (GdkWChar **dest_p, const char *src); +char * gnc_wcstombs (const GdkWChar *src); +gint gnc_wcslen (const GdkWChar *src); +GdkWChar * gnc_wcsdup (const GdkWChar *src); + #endif /* __BASIC_CELL_H__ */ diff --git a/src/register/gnome/combocell-gnome.c b/src/register/gnome/combocell-gnome.c index ed87a075e7..ecfa482d90 100644 --- a/src/register/gnome/combocell-gnome.c +++ b/src/register/gnome/combocell-gnome.c @@ -75,7 +75,7 @@ typedef struct _PopBox static void block_list_signals (ComboCell *cell); static void unblock_list_signals (ComboCell *cell); -static void realizeCombo (BasicCell *bcell, void *w); +static void realizeCombo (BasicCell *bcell, gpointer w); static void moveCombo (BasicCell *bcell, VirtualLocation virt_loc); static void destroyCombo (BasicCell *bcell); static gboolean enterCombo (BasicCell *bcell, @@ -131,7 +131,7 @@ void xaccInitComboCell (ComboCell *cell) box->strict = TRUE; - box->complete_char = 0; + box->complete_char = '\0'; box->ignore_string = NULL; box->ignore_help = NULL; @@ -427,15 +427,17 @@ xaccAddComboCellMenuItem (ComboCell *cell, char * menustr) void xaccSetComboCellValue (ComboCell *cell, const char *str) { - xaccSetBasicCellValue(&cell->cell, str); + xaccSetBasicCellValue (&cell->cell, str); } /* =============================================== */ static void ComboMV (BasicCell *_cell, - const char *change, - const char *newval, + const GdkWChar *change, + int change_len, + const GdkWChar *newval, + int newval_len, int *cursor_position, int *start_selection, int *end_selection) @@ -448,7 +450,7 @@ ComboMV (BasicCell *_cell, if (box->in_list_select) { - xaccSetBasicCellValue (_cell, newval); + xaccSetBasicCellWCValueInternal (_cell, newval); *cursor_position = -1; *start_selection = 0; @@ -460,14 +462,14 @@ ComboMV (BasicCell *_cell, /* If deleting, just accept */ if (change == NULL) { - xaccSetBasicCellValue (_cell, newval); + xaccSetBasicCellWCValueInternal (_cell, newval); return; } /* If we are inserting in the middle, just accept */ - if (*cursor_position < strlen(_cell->value)) + if (*cursor_position < _cell->value_len) { - xaccSetBasicCellValue (_cell, newval); + xaccSetBasicCellWCValueInternal (_cell, newval); return; } @@ -477,18 +479,18 @@ ComboMV (BasicCell *_cell, if ((match == NULL) || (match_str == NULL)) { - xaccSetBasicCellValue (_cell, newval); + xaccSetBasicCellWCValueInternal (_cell, newval); - block_list_signals(cell); - gnc_item_list_select(box->item_list, NULL); - unblock_list_signals(cell); + block_list_signals (cell); + gnc_item_list_select (box->item_list, NULL); + unblock_list_signals (cell); return; } - *start_selection = strlen(newval); + *start_selection = newval_len; *end_selection = -1; - *cursor_position += strlen(change); + *cursor_position += change_len; if (!box->list_popped) pop_list = auto_pop_combos; @@ -501,11 +503,11 @@ ComboMV (BasicCell *_cell, box->list_popped = TRUE; } - block_list_signals(cell); - gnc_item_list_select(box->item_list, match_str); - unblock_list_signals(cell); + block_list_signals (cell); + gnc_item_list_select (box->item_list, match_str); + unblock_list_signals (cell); - xaccSetBasicCellValue (_cell, match_str); + xaccSetBasicCellValueInternal (_cell, match_str); } /* =============================================== */ @@ -524,16 +526,13 @@ ComboDirect (BasicCell *bcell, gboolean extra_colon; QuickFill *match; const char *match_str; - char *search; int prefix_len; + int find_pos; int new_pos; - int length; if (event->type != GDK_KEY_PRESS) return FALSE; - length = strlen(bcell->value); - switch (event->keyval) { case GDK_slash: if (!(event->state & GDK_MOD1_MASK)) @@ -551,26 +550,30 @@ ComboDirect (BasicCell *bcell, !keep_on_going) return FALSE; - match = gnc_quickfill_get_string_len_match (box->qf, bcell->value, *cursor_position); + match = gnc_quickfill_get_string_len_match + (box->qf, bcell->value_w, *cursor_position); if (match == NULL) return TRUE; - match = gnc_quickfill_get_unique_len_match (match, &prefix_len); + match = gnc_quickfill_get_unique_len_match + (match, &prefix_len); if (match == NULL) return TRUE; match_str = gnc_quickfill_string (match); if ((match_str != NULL) && - (strncmp(match_str, bcell->value, length) == 0) && - (strcmp(match_str, bcell->value) != 0)) + (strncmp (match_str, bcell->value, + strlen (bcell->value)) == 0) && + (strcmp (match_str, bcell->value) != 0)) { - xaccSetBasicCellValue(bcell, match_str); - - block_list_signals(cell); - gnc_item_list_select(box->item_list, match_str); - unblock_list_signals(cell); + xaccSetBasicCellValueInternal (bcell, + match_str); + block_list_signals (cell); + gnc_item_list_select (box->item_list, + match_str); + unblock_list_signals (cell); } *cursor_position += prefix_len; @@ -589,36 +592,47 @@ ComboDirect (BasicCell *bcell, if (event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)) return FALSE; - if ((*cursor_position < length) && - ((*end_selection < length) || + if ((*cursor_position < bcell->value_len) && + ((*end_selection < bcell->value_len) || (*cursor_position < *start_selection))) return FALSE; - if ((*cursor_position == length) && + if ((*cursor_position == bcell->value_len) && (*start_selection != *end_selection) && - (*end_selection < length)) + (*end_selection < bcell->value_len)) return FALSE; - search = NULL; - if (*cursor_position < length) - search = strchr(bcell->value + *cursor_position + 1, - box->complete_char); + find_pos = -1; + if (*cursor_position < bcell->value_len) + { + int i = *cursor_position + 1; + + while (bcell->value_w[i]) + { + if (bcell->value_w[i] == box->complete_char) + { + find_pos = i; + break; + } + i++; + } + } new_pos = *cursor_position; - if (search != NULL) + if (find_pos >= 0) { - new_pos = search - bcell->value; + new_pos = find_pos; extra_colon = FALSE; } else { - new_pos = length; + new_pos = bcell->value_len; extra_colon = TRUE; } match = gnc_quickfill_get_string_len_match (box->qf, - bcell->value, new_pos); + bcell->value_w, new_pos); if (match == NULL) return FALSE; @@ -635,14 +649,14 @@ ComboDirect (BasicCell *bcell, match_str = gnc_quickfill_string (match); if ((match_str != NULL) && - (strncmp(match_str, bcell->value, length) == 0) && - (strcmp(match_str, bcell->value) != 0)) + (strncmp (match_str, bcell->value, strlen (bcell->value)) == 0) && + (strcmp (match_str, bcell->value) != 0)) { - xaccSetBasicCellValue(bcell, match_str); + xaccSetBasicCellValueInternal (bcell, match_str); - block_list_signals(cell); - gnc_item_list_select(box->item_list, match_str); - unblock_list_signals(cell); + block_list_signals (cell); + gnc_item_list_select (box->item_list, match_str); + unblock_list_signals (cell); } *cursor_position = new_pos; @@ -664,14 +678,14 @@ ComboHelpValue(BasicCell *bcell) { if ((box->ignore_string != NULL) && (box->ignore_help != NULL) && - (safe_strcmp(bcell->value, box->ignore_string) == 0)) - return g_strdup(box->ignore_help); + (safe_strcmp (bcell->value, box->ignore_string) == 0)) + return g_strdup (box->ignore_help); - return g_strdup(bcell->value); + return g_strdup (bcell->value); } if (bcell->blank_help != NULL) - return g_strdup(bcell->blank_help); + return g_strdup (bcell->blank_help); return NULL; } @@ -679,11 +693,11 @@ ComboHelpValue(BasicCell *bcell) /* =============================================== */ static void -realizeCombo (BasicCell *bcell, void *data) +realizeCombo (BasicCell *bcell, gpointer data) { GnucashSheet *sheet = data; GnomeCanvasItem *item = sheet->item_editor; - ItemEdit *item_edit = ITEM_EDIT(item); + ItemEdit *item_edit = ITEM_EDIT (item); ComboCell *cell = (ComboCell *) bcell; PopBox *box = cell->cell.gui_private; @@ -691,8 +705,8 @@ realizeCombo (BasicCell *bcell, void *data) box->sheet = sheet; box->item_edit = item_edit; box->item_list = item_edit_new_list(box->item_edit); - gtk_object_ref(GTK_OBJECT(box->item_list)); - gtk_object_sink(GTK_OBJECT(box->item_list)); + gtk_object_ref (GTK_OBJECT(box->item_list)); + gtk_object_sink (GTK_OBJECT(box->item_list)); /* to mark cell as realized, remove the realize method */ cell->cell.realize = NULL; @@ -737,17 +751,17 @@ enterCombo (BasicCell *bcell, (safe_strcmp(bcell->value, box->ignore_string) == 0)) return FALSE; - gnc_combo_sync_edit_list(box); - gnc_combo_sort_edit_list(box); + gnc_combo_sync_edit_list (box); + gnc_combo_sort_edit_list (box); item_edit_set_list(box->item_edit, box->item_list); gnome_canvas_item_set(GNOME_CANVAS_ITEM(box->item_edit), "is_combo", TRUE, NULL); - block_list_signals(cell); - gnc_item_list_select(box->item_list, bcell->value); - unblock_list_signals(cell); + block_list_signals (cell); + gnc_item_list_select (box->item_list, bcell->value); + unblock_list_signals (cell); combo_connect_signals((ComboCell *) bcell); @@ -778,15 +792,15 @@ leaveCombo (BasicCell *bcell) { GList *find; - find = g_list_find_custom(box->menustrings, - bcell->value, - (GCompareFunc) safe_strcmp); + find = g_list_find_custom (box->menustrings, + bcell->value, + (GCompareFunc) safe_strcmp); /* The ignore string is ok, even if it's not in list. */ if (find == NULL && ((box->ignore_string == NULL) || - (safe_strcmp(bcell->value, box->ignore_string) != 0))) - xaccSetBasicCellValue(bcell, ""); + (safe_strcmp (bcell->value, box->ignore_string) != 0))) + xaccSetBasicCellValueInternal (bcell, ""); } } diff --git a/src/register/gnome/datecell-gnome.c b/src/register/gnome/datecell-gnome.c index 9695708381..08a46ac021 100644 --- a/src/register/gnome/datecell-gnome.c +++ b/src/register/gnome/datecell-gnome.c @@ -65,13 +65,15 @@ typedef struct _PopBox static void block_picker_signals (DateCell *cell); static void unblock_picker_signals (DateCell *cell); -static void realizeDate (BasicCell *bcell, void *w); +static void realizeDate (BasicCell *bcell, gpointer w); static void setDateCellValue (BasicCell *bcell, const char *value); static void moveDate (BasicCell *bcell, VirtualLocation virt_loc); static void destroyDate (BasicCell *bcell); static void DateMV (BasicCell *_cell, - const char *change, - const char *newval, + const GdkWChar *change, + int change_len, + const GdkWChar *newval, + int newval_len, int *cursor_position, int *start_selection, int *end_selection); @@ -207,8 +209,7 @@ xaccInitDateCell (DateCell *cell) box->date = *localtime (&secs); printDateCellDate (cell, buff); - g_free (cell->cell.value); - cell->cell.value = g_strdup (buff); + xaccSetBasicCellValueInternal (&cell->cell, buff); } DateCell * @@ -412,8 +413,7 @@ xaccSetDateCellValue (DateCell *cell, int day, int mon, int year) printDate (buff, dada.tm_mday, dada.tm_mon + 1, dada.tm_year + 1900); - g_free (cell->cell.value); - cell->cell.value = g_strdup (buff); + xaccSetBasicCellValueInternal (&cell->cell, buff); if (!box->date_picker) return; @@ -440,8 +440,7 @@ xaccSetDateCellValueSecs (DateCell *cell, time_t secs) box->date.tm_mon + 1, box->date.tm_year + 1900); - g_free (cell->cell.value); - cell->cell.value = g_strdup (buff); + xaccSetBasicCellValueInternal (&cell->cell, buff); if (!box->date_picker) return; @@ -505,8 +504,7 @@ xaccSetDateCellValueSecsL (DateCell *cell, long long secs) box->date.tm_mon + 1, box->date.tm_year + 1900); - g_free (cell->cell.value); - cell->cell.value = g_strdup (buff); + xaccSetBasicCellValueInternal (&cell->cell, buff); if (!box->date_picker) return; @@ -537,8 +535,7 @@ xaccCommitDateCell (DateCell *cell) box->date.tm_mon + 1, box->date.tm_year + 1900); - g_free (cell->cell.value); - cell->cell.value = g_strdup (buff); + xaccSetBasicCellValueInternal (&cell->cell, buff); if (!box->date_picker) return; @@ -555,8 +552,10 @@ xaccCommitDateCell (DateCell *cell) static void DateMV (BasicCell *_cell, - const char *change, - const char *newval, + const GdkWChar *change, + int change_len, + const GdkWChar *newval, + int newval_len, int *cursor_position, int *start_selection, int *end_selection) @@ -569,14 +568,16 @@ DateMV (BasicCell *_cell, if (box->in_date_select) { - xaccSetBasicCellValue (_cell, newval); + char *newval_mb = gnc_wcstombs (newval); + xaccSetBasicCellValue (_cell, newval_mb); + g_free (newval_mb); return; } /* if user hit backspace, accept the change */ if (change == NULL) accept = TRUE; - else if ('\0' == change[0]) + else if (change_len == 0) accept = TRUE; else { @@ -584,7 +585,7 @@ DateMV (BasicCell *_cell, char separator = dateSeparator (); gboolean ok = TRUE; - for (i = 0; '\0' != change[i]; i++) + for (i = 0; i < change_len; i++) { /* accept only numbers or a date separator. Note that the * separator of '-' (for DATE_FORMAT_ISO) takes precedence @@ -596,8 +597,8 @@ DateMV (BasicCell *_cell, count++; } - for (i=0; '\0' != _cell->value[i]; i++) - if (separator == _cell->value[i]) + for (i = 0; i < _cell->value_len; i++) + if (separator == _cell->value_w[i]) count++; if (2 < count) @@ -610,9 +611,11 @@ DateMV (BasicCell *_cell, /* keep a copy of the new value */ if (accept) { - g_free (cell->cell.value); - cell->cell.value = g_strdup (newval); - xaccParseDate (&(box->date), newval); + char *newval_mb = gnc_wcstombs (newval); + + xaccSetBasicCellWCValueInternal (&cell->cell, newval); + xaccParseDate (&(box->date), newval_mb); + g_free (newval_mb); if (!box->date_picker) return; @@ -628,7 +631,7 @@ DateMV (BasicCell *_cell, } /* otherwise, maybe its an accelerator key. */ - if (strlen(change) != 1) + if (change_len != 1) return; date = &(box->date); @@ -710,8 +713,7 @@ DateMV (BasicCell *_cell, printDate (buff, date->tm_mday, date->tm_mon + 1, date->tm_year + 1900); - g_free (cell->cell.value); - cell->cell.value = g_strdup (buff); + xaccSetBasicCellValueInternal (&cell->cell, buff); if (!box->date_picker) return; @@ -843,8 +845,7 @@ setDateCellValue (BasicCell *_cell, const char *str) box->date.tm_mon + 1, box->date.tm_year + 1900); - g_free (cell->cell.value); - cell->cell.value = g_strdup (buff); + xaccSetBasicCellValueInternal (_cell, buff); if (!box->date_picker) return; diff --git a/src/register/gnome/gnucash-sheet.c b/src/register/gnome/gnucash-sheet.c index 17e6facc56..eb380075ec 100644 --- a/src/register/gnome/gnucash-sheet.c +++ b/src/register/gnome/gnucash-sheet.c @@ -42,6 +42,10 @@ #define DEFAULT_REGISTER_HEIGHT 400 #define DEFAULT_REGISTER_WIDTH 630 + +/* This static indicates the debugging module that this .o belongs to. */ +static short module = MOD_GTK_REG; + static guint gnucash_register_initial_rows = 15; static void gnucash_sheet_start_editing_at_cursor (GnucashSheet *sheet); @@ -710,6 +714,8 @@ gnucash_sheet_modify_current_cell(GnucashSheet *sheet, const gchar *new_text) GtkEditable *editable; Table *table = sheet->table; VirtualLocation virt_loc; + GdkWChar *new_text_wc; + int new_text_len; const char *retval; @@ -728,11 +734,21 @@ gnucash_sheet_modify_current_cell(GnucashSheet *sheet, const gchar *new_text) end_sel = MAX(editable->selection_start_pos, editable->selection_end_pos); + new_text_len = gnc_mbstowcs (&new_text_wc, new_text); + if (new_text_len < 0) + { + PERR ("bad text: %s", new_text); + return NULL; + } + retval = gnc_table_modify_update (table, virt_loc, - new_text, new_text, + new_text_wc, new_text_len, + new_text_wc, new_text_len, &cursor_position, &start_sel, &end_sel); + g_free (new_text_wc); + if (retval) { gtk_signal_handler_block (GTK_OBJECT (sheet->entry), sheet->insert_signal); @@ -758,8 +774,8 @@ gnucash_sheet_modify_current_cell(GnucashSheet *sheet, const gchar *new_text) static void gnucash_sheet_insert_cb (GtkWidget *widget, - const gchar *new_text, - const gint new_text_length, + const gchar *insert_text, + const gint insert_text_len, gint *position, GnucashSheet *sheet) { @@ -767,16 +783,23 @@ gnucash_sheet_insert_cb (GtkWidget *widget, Table *table = sheet->table; VirtualLocation virt_loc; + GdkWChar *new_text_w; + GdkWChar *old_text_w; + GdkWChar *change_text_w; + + int new_text_len; + int old_text_len; + int change_text_len; + const char *old_text; - char *newval = NULL; - char *change = NULL; const char *retval; + char *new_text; int start_sel, end_sel; int old_position; - int old_len; + int i; - if (!new_text_length) + if (insert_text_len <= 0) return; gnucash_cursor_get_virt (GNUCASH_CURSOR(sheet->cursor), &virt_loc); @@ -784,36 +807,76 @@ gnucash_sheet_insert_cb (GtkWidget *widget, if (!gnc_table_virtual_loc_valid (table, virt_loc, FALSE)) return; + /* insert_text is not NULL-terminated, how annoying */ + { + char *temp; + + temp = g_new (char, insert_text_len + 1); + strncpy (temp, insert_text, insert_text_len); + temp[insert_text_len] = '\0'; + + change_text_w = g_new0 (GdkWChar, insert_text_len + 1); + change_text_len = gdk_mbstowcs (change_text_w, temp, + insert_text_len); + + g_free (temp); + } + + if (change_text_len < 0) + { + PERR ("bad change text conversion"); + g_free (change_text_w); + return; + } + old_text = gtk_entry_get_text (GTK_ENTRY(sheet->entry)); if (old_text == NULL) old_text = ""; - old_len = strlen(old_text); + + old_text_len = gnc_mbstowcs (&old_text_w, old_text); + if (old_text_len < 0) + { + PERR ("bad old text conversion"); + g_free (change_text_w); + return; + } + old_position = *position; - /* we set newval to what the entry contents would be if + /* we set new_text_w to what the entry contents would be if the insert was processed */ - newval = g_new0(char, strlen(old_text) + new_text_length + 1); + new_text_len = old_text_len + change_text_len; + new_text_w = g_new0 (GdkWChar, new_text_len + 1); - strncat (newval, old_text, *position); - strncat (newval, new_text, new_text_length); - strncat (newval, &old_text[*position], old_len - *position); + for (i = 0; i < old_position; i++) + new_text_w[i] = old_text_w[i]; - change = g_new0 (char, new_text_length + 1); - strncpy (change, new_text, new_text_length); + for (i = old_position; i < old_position + change_text_len; i++) + new_text_w[i] = change_text_w[i - old_position]; - editable = GTK_EDITABLE(sheet->entry); + for (i = old_position + change_text_len; i < new_text_len; i++) + new_text_w[i] = old_text_w[i - change_text_len]; - start_sel = MIN(editable->selection_start_pos, - editable->selection_end_pos); - end_sel = MAX(editable->selection_start_pos, - editable->selection_end_pos); + new_text_w[new_text_len] = 0; - retval = gnc_table_modify_update (table, virt_loc, change, newval, + new_text = gnc_wcstombs (new_text_w); + + editable = GTK_EDITABLE (sheet->entry); + + start_sel = MIN (editable->selection_start_pos, + editable->selection_end_pos); + end_sel = MAX (editable->selection_start_pos, + editable->selection_end_pos); + + retval = gnc_table_modify_update (table, virt_loc, + change_text_w, change_text_len, + new_text_w, new_text_len, position, &start_sel, &end_sel); if (retval && - ((safe_strcmp (retval, newval) != 0) || - (*position != old_position))) { + ((safe_strcmp (retval, new_text) != 0) || + (*position != old_position))) + { gtk_signal_handler_block (GTK_OBJECT (sheet->entry), sheet->insert_signal); @@ -831,21 +894,24 @@ gnucash_sheet_insert_cb (GtkWidget *widget, gtk_signal_emit_stop_by_name (GTK_OBJECT(sheet->entry), "insert_text"); } - else if (retval == NULL) { + else if (retval == NULL) + { retval = old_text; /* the entry was disallowed, so we stop the insert signal */ - gtk_signal_emit_stop_by_name (GTK_OBJECT(sheet->entry), + gtk_signal_emit_stop_by_name (GTK_OBJECT (sheet->entry), "insert_text"); } if (*position < 0) - *position = strlen(retval); + *position = strlen (retval); - gtk_entry_select_region(GTK_ENTRY(sheet->entry), start_sel, end_sel); + gtk_entry_select_region (GTK_ENTRY(sheet->entry), start_sel, end_sel); - g_free (change); - g_free (newval); + g_free (change_text_w); + g_free (old_text_w); + g_free (new_text_w); + g_free (new_text); } @@ -859,12 +925,18 @@ gnucash_sheet_delete_cb (GtkWidget *widget, Table *table = sheet->table; VirtualLocation virt_loc; + GdkWChar *new_text_w; + GdkWChar *old_text_w; + int new_text_len; + int old_text_len; + const char *old_text; - char *newval = NULL; - const char *retval = NULL; + const char *retval; + char *new_text; int cursor_position = start_pos; int start_sel, end_sel; + int i; if (end_pos <= start_pos) return; @@ -875,28 +947,42 @@ gnucash_sheet_delete_cb (GtkWidget *widget, return; old_text = gtk_entry_get_text (GTK_ENTRY(sheet->entry)); - - if (old_text == NULL) + if (!old_text) old_text = ""; - newval = g_new0 (char, strlen(old_text) - (end_pos - start_pos) + 1); + old_text_len = gnc_mbstowcs (&old_text_w, old_text); + if (old_text_len < 0) + return; - strncat (newval, old_text, start_pos); - strcat (newval, &old_text[end_pos]); + new_text_len = old_text_len - (end_pos - start_pos); - editable = GTK_EDITABLE(sheet->entry); + new_text_w = g_new0 (GdkWChar, new_text_len + 1); - start_sel = MIN(editable->selection_start_pos, - editable->selection_end_pos); - end_sel = MAX(editable->selection_start_pos, - editable->selection_end_pos); + for (i = 0; i < start_pos; i++) + new_text_w[i] = old_text_w[i]; + + for (i = end_pos; i < old_text_len; i++) + new_text_w[i - (end_pos - start_pos)] = old_text_w[i]; + + new_text_w[new_text_len] = 0; + + new_text = gnc_wcstombs (new_text_w); + + editable = GTK_EDITABLE (sheet->entry); + + start_sel = MIN (editable->selection_start_pos, + editable->selection_end_pos); + end_sel = MAX (editable->selection_start_pos, + editable->selection_end_pos); retval = gnc_table_modify_update (table, virt_loc, - NULL, newval, + NULL, 0, + new_text_w, new_text_len, &cursor_position, &start_sel, &end_sel); - if (retval && (safe_strcmp (retval, newval) != 0)) { + if (retval && (safe_strcmp (retval, new_text) != 0)) + { gtk_signal_handler_block (GTK_OBJECT (sheet->entry), sheet->insert_signal); @@ -914,7 +1000,8 @@ gnucash_sheet_delete_cb (GtkWidget *widget, gtk_signal_emit_stop_by_name (GTK_OBJECT(sheet->entry), "delete_text"); } - else if (retval == NULL) { + else if (retval == NULL) + { /* the entry was disallowed, so we stop the delete signal */ gtk_signal_emit_stop_by_name (GTK_OBJECT(sheet->entry), "delete_text"); @@ -923,7 +1010,9 @@ gnucash_sheet_delete_cb (GtkWidget *widget, gtk_editable_set_position (editable, cursor_position); gtk_entry_select_region(GTK_ENTRY(sheet->entry), start_sel, end_sel); - g_free (newval); + g_free (old_text_w); + g_free (new_text_w); + g_free (new_text); } diff --git a/src/register/gnome/gnucash-style.c b/src/register/gnome/gnucash-style.c index 11b7ce46de..e1894bb085 100644 --- a/src/register/gnome/gnucash-style.c +++ b/src/register/gnome/gnucash-style.c @@ -24,18 +24,14 @@ #include "config.h" +#include + #include "gnucash-color.h" #include "gnucash-grid.h" #include "gnucash-item-edit.h" #include "gnucash-style.h" #include "messages.h" -#include "date.h" - - -#define DEFAULT_FONT _("register-default-font:-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*"+22) -#define HINT_FONT _("register-hint-font:-adobe-helvetica-medium-o-normal--*-120-*-*-*-*-*-*"+19) - #define DEFAULT_STYLE_WIDTH 680 @@ -48,6 +44,7 @@ static char *register_hint_font_name = NULL; static gboolean use_vertical_lines = TRUE; static gboolean use_horizontal_lines = TRUE; + static char * style_get_key (SheetBlockStyle *style) { @@ -737,58 +734,66 @@ gnucash_style_unref (SheetBlockStyle *style) } void -gnucash_style_set_register_font_name(const char *name) +gnucash_style_set_register_font_name (const char *name) { - g_free(register_font_name); - register_font_name = g_strdup(name); + g_free (register_font_name); + register_font_name = g_strdup (name); if (gnucash_register_font != NULL) { - gdk_font_unref(gnucash_register_font); + gdk_font_unref (gnucash_register_font); gnucash_register_font = NULL; } if (register_font_name != NULL) - gnucash_register_font = gdk_fontset_load(register_font_name); + gnucash_register_font = gdk_fontset_load (register_font_name); if (gnucash_register_font == NULL) { - g_free(register_font_name); + const char *name = + gnucash_style_get_default_register_font_name (); + + g_free (register_font_name); register_font_name = NULL; - gnucash_register_font = gdk_fontset_load(DEFAULT_FONT); + + gnucash_register_font = gdk_fontset_load (name); } - g_assert(gnucash_register_font != NULL); + g_assert (gnucash_register_font != NULL); - gdk_font_ref(gnucash_register_font); + gdk_font_ref (gnucash_register_font); } void -gnucash_style_set_register_hint_font_name(const char *name) +gnucash_style_set_register_hint_font_name (const char *name) { - g_free(register_hint_font_name); - register_hint_font_name = g_strdup(name); + g_free (register_hint_font_name); + register_hint_font_name = g_strdup (name); if (gnucash_register_hint_font != NULL) { - gdk_font_unref(gnucash_register_hint_font); + gdk_font_unref (gnucash_register_hint_font); gnucash_register_hint_font = NULL; } if (register_hint_font_name != NULL) gnucash_register_hint_font = - gdk_fontset_load(register_hint_font_name); + gdk_fontset_load (register_hint_font_name); if (gnucash_register_hint_font == NULL) { - g_free(register_hint_font_name); + const char *name = + gnucash_style_get_default_register_hint_font_name (); + + g_free (register_hint_font_name); register_hint_font_name = NULL; - gnucash_register_hint_font = gdk_fontset_load(HINT_FONT); + + gnucash_register_hint_font = gdk_fontset_load (name); } - g_assert(gnucash_register_hint_font != NULL); + g_assert (gnucash_register_hint_font != NULL); - gdk_font_ref(gnucash_register_hint_font); + gdk_font_ref (gnucash_register_hint_font); } void @@ -867,19 +872,15 @@ gnucash_sheet_set_header_widths (GnucashSheet *sheet, int *header_widths) } const char * -gnucash_style_get_default_register_font_name(void) +gnucash_style_get_default_register_font_name (void) { - /* same as DEFAULT_FONT */ - /* repeated here so gettext will pick it up */ - return _("register-default-font:-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*"+22); + return _("register-default-font:-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*") + 22; } const char * -gnucash_style_get_default_register_hint_font_name(void) +gnucash_style_get_default_register_hint_font_name (void) { - /* same as HINT_FONT */ - /* repeated here so gettext will pick it up */ - return _("register-hint-font:-adobe-helvetica-medium-o-normal--*-120-*-*-*-*-*-*"+19); + return _("register-hint-font:-adobe-helvetica-medium-o-normal--*-120-*-*-*-*-*-*") + 19; } void diff --git a/src/register/gnome/pricecell-gnome.c b/src/register/gnome/pricecell-gnome.c index a07741bdea..14de2d03aa 100644 --- a/src/register/gnome/pricecell-gnome.c +++ b/src/register/gnome/pricecell-gnome.c @@ -47,12 +47,15 @@ PriceDirect (BasicCell *bcell, PriceCell *cell = (PriceCell *) bcell; GdkEventKey *event = gui_data; char decimal_point; - struct lconv *lc = gnc_localeconv(); - char *newval; + struct lconv *lc; + GdkWChar *newval; + int i; if (event->type != GDK_KEY_PRESS) return FALSE; + lc = gnc_localeconv (); + switch (event->keyval) { case GDK_Return: @@ -94,23 +97,26 @@ PriceDirect (BasicCell *bcell, /* allocate space for newval_ptr : oldval + one letter ( the decimal_point ) */ - newval = g_new (char, strlen(bcell->value) + 2); + newval = g_new (GdkWChar, bcell->value_len + 2); /* copy oldval up to the cursor position */ - strncpy (newval, bcell->value, *cursor_position); + for (i = 0; i < *cursor_position; i++) + newval[i] = bcell->value_w[i]; /* insert the decimal_point at cursor position */ newval[*cursor_position] = decimal_point; - /* copy the end of oldval : */ - strcpy (newval + (*cursor_position) + 1, - bcell->value + (*cursor_position)); + for (i = *cursor_position + 1; i < bcell->value_len + 1; i++) + newval[i] = bcell->value_w[i - 1]; + + newval[bcell->value_len + 1] = 0; /* update the cursor position */ (*cursor_position)++; - g_free (bcell->value); - bcell->value = newval; + xaccSetBasicCellWCValueInternal (bcell, newval); + + g_free (newval); cell->need_to_parse = TRUE; diff --git a/src/register/gnome/quickfillcell-gnome.c b/src/register/gnome/quickfillcell-gnome.c index 29849e048d..f365111565 100644 --- a/src/register/gnome/quickfillcell-gnome.c +++ b/src/register/gnome/quickfillcell-gnome.c @@ -24,7 +24,7 @@ * * Implements gnome dependent quickfill cell functions. * - * Copyright (C) 2000 Dave Peticolas + * Copyright (C) 2000 Dave Peticolas */ #include "config.h" @@ -71,7 +71,7 @@ QuickFillDirect (BasicCell *bcell, (*start_selection >= *cursor_position)) *cursor_position = *end_selection; - match = gnc_quickfill_get_string_len_match (cell->qf, bcell->value, + match = gnc_quickfill_get_string_len_match (cell->qf, bcell->value_w, *cursor_position); if (match == NULL) @@ -84,9 +84,9 @@ QuickFillDirect (BasicCell *bcell, match_str = gnc_quickfill_string (match); if ((match_str != NULL) && - (strncmp(match_str, bcell->value, strlen(bcell->value)) == 0) && - (strcmp(match_str, bcell->value) != 0)) - xaccSetBasicCellValue(bcell, match_str); + (strncmp (match_str, bcell->value, strlen (bcell->value)) == 0) && + (strcmp (match_str, bcell->value) != 0)) + xaccSetBasicCellValue (bcell, match_str); *cursor_position += prefix_len; *start_selection = *cursor_position; diff --git a/src/register/numcell.c b/src/register/numcell.c index c14a776e7f..d6139cd1ac 100644 --- a/src/register/numcell.c +++ b/src/register/numcell.c @@ -71,8 +71,10 @@ parse_num(const char *string, long int *num) /* ================================================ */ static void NumMV (BasicCell *_cell, - const char *change, - const char *newval, + const GdkWChar *change, + int change_len, + const GdkWChar *newval, + int new_val_len, int *cursor_position, int *start_selection, int *end_selection) @@ -82,18 +84,17 @@ NumMV (BasicCell *_cell, gboolean is_num; long int number = 0; - if ((change == NULL) || (change[0] == 0) || /* if we are deleting */ - (strlen(change) > 1)) /* or entering > 1 char */ + if ((change == NULL) || (change_len == 0) || /* if we are deleting */ + (change_len > 1)) /* or entering > 1 char */ /* then just accept the proposed change */ { - g_free (cell->cell.value); - cell->cell.value = g_strdup (newval); + xaccSetBasicCellWCValueInternal (&cell->cell, newval); return; } /* otherwise, it may be an accelerator key. */ - is_num = parse_num(_cell->value, &number); + is_num = parse_num (_cell->value, &number); if (is_num && (number < 0)) is_num = FALSE; @@ -139,22 +140,20 @@ NumMV (BasicCell *_cell, if (!is_num) number = cell->next_num; - strcpy(buff, ""); - snprintf(buff, sizeof(buff), "%ld", number); + strcpy (buff, ""); + snprintf (buff, sizeof(buff), "%ld", number); if (safe_strcmp(buff, "") == 0) return; - g_free (cell->cell.value); - cell->cell.value = g_strdup (buff); + xaccSetBasicCellValueInternal (&cell->cell, buff); *cursor_position = -1; return; } - g_free (cell->cell.value); - cell->cell.value = g_strdup (newval); + xaccSetBasicCellWCValueInternal (&cell->cell, newval); } /* ================================================ */ @@ -191,15 +190,14 @@ setNumCellValue (BasicCell *_cell, const char *str) cell->next_num = number + 1; } - g_free (cell->cell.value); - cell->cell.value = g_strdup (str); + xaccSetBasicCellValueInternal (_cell, str); } /* ================================================ */ void xaccSetNumCellValue (NumCell *cell, const char *str) { - setNumCellValue(&cell->cell, str); + setNumCellValue (&cell->cell, str); } /* ================================================ */ @@ -208,7 +206,7 @@ xaccSetNumCellLastNum (NumCell *cell, const char *str) { long int number; - if (parse_num(str, &number)) + if (parse_num (str, &number)) { cell->next_num = number + 1; cell->next_num_set = TRUE; diff --git a/src/register/pricecell.c b/src/register/pricecell.c index c752f9e8e3..9cdce9148d 100644 --- a/src/register/pricecell.c +++ b/src/register/pricecell.c @@ -53,17 +53,10 @@ extern void xaccPriceGUIInit (PriceCell *cell); static void xaccInitPriceCell (PriceCell *cell); -static void PriceSetValue (BasicCell *bcell, const char *); +static void PriceSetValue (BasicCell *bcell, const char *value); static const char * xaccPriceCellPrintValue (PriceCell *cell); -/* ================================================ */ - -#define SET(cell,str) { \ - g_free ((cell)->value); \ - (cell)->value = g_strdup (str); \ -} - /* ================================================ */ static gboolean @@ -85,14 +78,16 @@ PriceEnter (BasicCell *_cell, static void PriceMV (BasicCell *_cell, - const char *change, - const char *newval, + const GdkWChar *change, + int change_len, + const GdkWChar *newval, + int newval_len, int *cursor_position, int *start_selection, int *end_selection) { PriceCell *cell = (PriceCell *) _cell; - struct lconv *lc = gnc_localeconv(); + struct lconv *lc = gnc_localeconv (); const char *toks = "+-*/=()"; char decimal_point; char thousands_sep; @@ -101,7 +96,7 @@ PriceMV (BasicCell *_cell, /* accept the newval string if user action was delete */ if (change == NULL) { - SET ((&(cell->cell)), newval); + xaccSetBasicCellWCValueInternal (_cell, newval); cell->need_to_parse = TRUE; return; } @@ -116,7 +111,7 @@ PriceMV (BasicCell *_cell, else thousands_sep = lc->thousands_sep[0]; - for (i = 0; change[i] != '\0'; i++) + for (i = 0; i < change_len; i++) if (!isdigit(change[i]) && !isspace(change[i]) && (decimal_point != change[i]) && @@ -124,7 +119,7 @@ PriceMV (BasicCell *_cell, (strchr (toks, change[i]) == NULL)) return; - SET ((&(cell->cell)), newval); + xaccSetBasicCellWCValueInternal (_cell, newval); cell->need_to_parse = TRUE; } @@ -154,14 +149,14 @@ PriceParse (PriceCell *cell) else cell->amount = gnc_numeric_zero (); - newval = xaccPriceCellPrintValue(cell); + newval = xaccPriceCellPrintValue (cell); /* If they are identical do nothing */ if (strcmp(newval, oldval) == 0) return; /* Otherwise, change it */ - SET ((&(cell->cell)), newval); + xaccSetBasicCellValueInternal (&cell->cell, newval); } /* ================================================ */ @@ -185,11 +180,11 @@ PriceHelp (BasicCell *bcell) help_str = bcell->value; - return g_strdup(help_str); + return g_strdup (help_str); } if (bcell->blank_help != NULL) - return g_strdup(bcell->blank_help); + return g_strdup (bcell->blank_help); return NULL; } @@ -223,8 +218,6 @@ xaccInitPriceCell (PriceCell *cell) cell->need_to_parse = FALSE; - SET (&(cell->cell), ""); - cell->cell.enter_cell = PriceEnter; cell->cell.modify_verify = PriceMV; cell->cell.leave_cell = PriceLeave; @@ -282,7 +275,7 @@ xaccSetPriceCellValue (PriceCell * cell, gnc_numeric amount) buff = xaccPriceCellPrintValue (cell); cell->need_to_parse = FALSE; - SET (&(cell->cell), buff); + xaccSetBasicCellValueInternal (&cell->cell, buff); } /* ================================================ */ @@ -307,7 +300,7 @@ xaccSetPriceCellBlank (PriceCell *cell) cell->amount = gnc_numeric_zero (); cell->need_to_parse = FALSE; - SET (&(cell->cell), ""); + xaccSetBasicCellValueInternal (&cell->cell, ""); } /* ================================================ */ diff --git a/src/register/quickfillcell.c b/src/register/quickfillcell.c index 3ea65f5201..eb6d7c3f8e 100644 --- a/src/register/quickfillcell.c +++ b/src/register/quickfillcell.c @@ -33,18 +33,20 @@ * Copyright (c) 2000 Dave Peticolas */ -#include -#include -#include +#include "config.h" + +#include #include +#include +#include +#include #include "basiccell.h" #include "quickfillcell.h" -#define SET(cell,str) { \ - g_free ((cell)->value); \ - (cell)->value = g_strdup (str); \ -} + +static void xaccSetQuickFillCellOriginal (QuickFillCell *cell, + const GdkWChar *original); /* ================================================ */ @@ -71,7 +73,7 @@ quick_enter (BasicCell *_cell, *start_selection = 0; *end_selection = -1; - xaccSetQuickFillCellOriginal(cell, NULL); + xaccSetQuickFillCellOriginal (cell, NULL); return TRUE; } @@ -80,10 +82,70 @@ quick_enter (BasicCell *_cell, /* by definition, all text is valid text. So accept * all modifications */ +static gboolean +wcstrcaseequal (const GdkWChar *s1, const GdkWChar *s2) +{ + int i; + + if (s1 == s2) + return TRUE; + + if (!s1 || !s2) + return FALSE; + + for (i = 0; TRUE; i++) + { + GdkWChar a; + GdkWChar b; + + if (s1[i] == 0 || s2[i] == 0) + return s1[i] == s2[i]; + + a = islower (s1[i]) ? toupper (s1[i]) : s1[i]; + b = islower (s2[i]) ? toupper (s2[i]) : s2[i]; + + if (a != b) + return FALSE; + } + + return TRUE; +} + +static gboolean +wcstrncaseequal (const GdkWChar *s1, const GdkWChar *s2, int len) +{ + int i; + + if (s1 == s2) + return TRUE; + + if (!s1 || !s2) + return FALSE; + + for (i = 0; i < len; i++) + { + GdkWChar a; + GdkWChar b; + + if (s1[i] == 0 || s2[i] == 0) + return FALSE; + + a = islower (s1[i]) ? toupper (s1[i]) : s1[i]; + b = islower (s2[i]) ? toupper (s2[i]) : s2[i]; + + if (a != b) + return FALSE; + } + + return TRUE; +} + static void quick_modify (BasicCell *_cell, - const char *change, - const char *newval, + const GdkWChar *change, + int change_len, + const GdkWChar *newval, + int newval_len, int *cursor_position, int *start_selection, int *end_selection) @@ -98,37 +160,50 @@ quick_modify (BasicCell *_cell, /* if the new value is a prefix of the original modulo case, * just truncate the end of the original. Otherwise, set it * to NULL */ - if ((*cursor_position >= strlen(newval)) && + if ((*cursor_position >= newval_len) && (cell->original != NULL) && - (strlen(cell->original) >= strlen(newval)) && - (strncasecmp(cell->original, newval, strlen(newval)) == 0)) - cell->original[strlen(newval)] = '\0'; + (gnc_wcslen (cell->original) >= newval_len) && + wcstrncaseequal (cell->original, newval, newval_len)) + cell->original[newval_len] = 0; else xaccSetQuickFillCellOriginal(cell, NULL); - SET (&(cell->cell), newval); + xaccSetBasicCellWCValueInternal (&cell->cell, newval); return; } /* If we are inserting in the middle, just accept */ - if (*cursor_position < strlen(_cell->value)) + if (*cursor_position < _cell->value_len) { - SET (&(cell->cell), newval); + xaccSetBasicCellWCValueInternal (&cell->cell, newval); xaccSetQuickFillCellOriginal(cell, NULL); return; } if (cell->original == NULL) - cell->original = g_strdup(newval); - else if (strcasecmp(cell->original, _cell->value) == 0) + cell->original = gnc_wcsdup (newval); + else if (wcstrcaseequal (cell->original, _cell->value_w)) { - char *original = g_strconcat(cell->original, change, NULL); - g_free(cell->original); + int orig_len = gnc_wcslen (cell->original); + GdkWChar *original; + int i; + + original = g_new0 (GdkWChar, orig_len + change_len + 1); + + for (i = 0; i < orig_len; i++) + original[i] = cell->original[i]; + + for (i = orig_len; i < orig_len + change_len; i++) + original[i] = change[i - orig_len]; + + original[orig_len + change_len] = 0; + + g_free (cell->original); cell->original = original; } else { - g_free(cell->original); + g_free (cell->original); cell->original = NULL; } @@ -143,15 +218,15 @@ quick_modify (BasicCell *_cell, *cursor_position = -1; - SET (&(cell->cell), newval); + xaccSetBasicCellWCValueInternal (&cell->cell, newval); return; } - *start_selection = strlen(newval); + *start_selection = newval_len; *end_selection = -1; - *cursor_position += strlen(change); + *cursor_position += change_len; - SET (&(cell->cell), match_str); + xaccSetBasicCellValueInternal (&cell->cell, match_str); } /* ================================================ */ @@ -162,7 +237,7 @@ quick_leave (BasicCell * _cell) { QuickFillCell *cell = (QuickFillCell *) _cell; - gnc_quickfill_insert (cell->qf, _cell->value, cell->sort); + gnc_quickfill_insert_wc (cell->qf, _cell->value_w, cell->sort); } /* ================================================ */ @@ -206,7 +281,7 @@ xaccDestroyQuickFillCell (QuickFillCell *cell) gnc_quickfill_destroy (cell->qf); cell->qf = NULL; - g_free(cell->original); + g_free (cell->original); cell->original = NULL; cell->cell.enter_cell = NULL; @@ -225,8 +300,8 @@ xaccSetQuickFillCellValue (QuickFillCell *cell, const char * value) if (cell == NULL) return; - gnc_quickfill_insert (cell->qf, value, cell->sort); - SET (&(cell->cell), value); + xaccSetBasicCellValueInternal (&cell->cell, value); + gnc_quickfill_insert_wc (cell->qf, cell->cell.value_w, cell->sort); } /* ================================================ */ @@ -242,16 +317,16 @@ xaccSetQuickFillCellSort (QuickFillCell *cell, QuickFillSort sort) /* ================================================ */ -void -xaccSetQuickFillCellOriginal (QuickFillCell *cell, const char *original) +static void +xaccSetQuickFillCellOriginal (QuickFillCell *cell, const GdkWChar *original) { if (cell == NULL) return; - g_free(cell->original); + g_free (cell->original); - if ((original != NULL) && (*original != '\0')) - cell->original = g_strdup(original); + if ((original != NULL) && (*original != 0)) + cell->original = gnc_wcsdup (original); else cell->original = NULL; } diff --git a/src/register/quickfillcell.h b/src/register/quickfillcell.h index c408e95305..da39c595f8 100644 --- a/src/register/quickfillcell.h +++ b/src/register/quickfillcell.h @@ -58,7 +58,7 @@ typedef struct _QuickFillCell QuickFillSort sort; /* determines order of strings matched. * default is QUICKFILL_LIFO. */ - char *original; /* original string entered in original case */ + GdkWChar *original; /* original string entered in original case */ } QuickFillCell; QuickFillCell * xaccMallocQuickFillCell (void); @@ -69,8 +69,6 @@ void xaccSetQuickFillCellValue (QuickFillCell *cell, const char *value); void xaccSetQuickFillCellSort (QuickFillCell *cell, QuickFillSort sort); -void xaccSetQuickFillCellOriginal (QuickFillCell *cell, - const char *original); void xaccQuickFillAddCompletion (QuickFillCell *cell, const char *completion); diff --git a/src/register/recncell.c b/src/register/recncell.c index 559a036de2..4b6b0cd42e 100644 --- a/src/register/recncell.c +++ b/src/register/recncell.c @@ -114,9 +114,9 @@ RecnEnter (BasicCell *_cell, static void xaccInitRecnCell (RecnCell *cell) { - xaccInitBasicCell(&cell->cell); + xaccInitBasicCell (&cell->cell); - xaccRecnCellSetFlag(cell, NREC); + xaccRecnCellSetFlag (cell, NREC); cell->cell.enter_cell = RecnEnter; cell->cell.set_value = RecnSetValue; @@ -146,8 +146,7 @@ RecnSetValue (BasicCell *_cell, const char *value) if (!value || *value == '\0') { cell->reconciled_flag = NREC; - g_free (_cell->value); - _cell->value = g_strdup (""); + xaccSetBasicCellValueInternal (_cell, ""); return; } @@ -186,10 +185,9 @@ xaccRecnCellSetFlag (RecnCell *cell, char reconciled_flag) cell->reconciled_flag = reconciled_flag; - string = RecnCellGetString(reconciled_flag); + string = RecnCellGetString (reconciled_flag); - g_free (cell->cell.value); - cell->cell.value = g_strdup (string); + xaccSetBasicCellValueInternal (&cell->cell, string); } /* ================================================ */ diff --git a/src/register/table-allgui.c b/src/register/table-allgui.c index 80f9254487..8313ce1aa4 100644 --- a/src/register/table-allgui.c +++ b/src/register/table-allgui.c @@ -940,8 +940,10 @@ gnc_table_leave_update(Table *table, VirtualLocation virt_loc) const char * gnc_table_modify_update(Table *table, VirtualLocation virt_loc, - const char *change, - const char *newval, + const GdkWChar *change, + int change_len, + const GdkWChar *newval, + int newval_len, int *cursor_position, int *start_selection, int *end_selection) @@ -970,14 +972,19 @@ gnc_table_modify_update(Table *table, cell = cb_cell->cell; mv = cell->modify_verify; - old_value = g_strdup(cell->value); + old_value = g_strdup (cell->value); if (mv) - mv (cell, change, newval, cursor_position, start_selection, end_selection); + mv (cell, change, change_len, newval, newval_len, + cursor_position, start_selection, end_selection); else - xaccSetBasicCellValue (cell, newval); + { + char *newval_mb = gnc_wcstombs (newval); + xaccSetBasicCellValue (cell, newval_mb); + g_free (newval_mb); + } - if (safe_strcmp(old_value, cell->value) != 0) + if (safe_strcmp (old_value, cell->value) != 0) { changed = TRUE; cell->changed = GNC_CELL_CHANGED; @@ -989,11 +996,11 @@ gnc_table_modify_update(Table *table, { char *help_str; - help_str = xaccBasicCellGetHelp(cell); + help_str = xaccBasicCellGetHelp (cell); - table->set_help(table, help_str); + table->set_help (table, help_str); - g_free(help_str); + g_free (help_str); } LEAVE ("change %d %d (relrow=%d relcol=%d) val=%s\n", diff --git a/src/register/table-allgui.h b/src/register/table-allgui.h index d2dc9d422f..6e886b40b0 100644 --- a/src/register/table-allgui.h +++ b/src/register/table-allgui.h @@ -413,8 +413,10 @@ void gnc_table_leave_update(Table *table, VirtualLocation virt_loc); const char * gnc_table_modify_update(Table *table, VirtualLocation virt_loc, - const char *change, - const char *newval, + const GdkWChar *change, + int change_len, + const GdkWChar *newval, + int newval_len, int *cursor_position, int *start_selection, int *end_selection); diff --git a/src/register/textcell.c b/src/register/textcell.c index b84e7a6285..e989b6bc5e 100644 --- a/src/register/textcell.c +++ b/src/register/textcell.c @@ -44,15 +44,15 @@ static void TextMV (struct _BasicCell *_cell, - const char *change, - const char *newval, + const GdkWChar *change, + int change_len, + const GdkWChar *newval, + int newval_len, int *cursor_position, int *start_selection, int *end_selection) { - BasicCell *cell = (BasicCell *) _cell; - - xaccSetBasicCellValue (cell, newval); + xaccSetBasicCellWCValueInternal (_cell, newval); } /* ================================================ */ @@ -60,10 +60,12 @@ TextMV (struct _BasicCell *_cell, BasicCell * xaccMallocTextCell (void) { - BasicCell *cell; - cell = xaccMallocBasicCell(); - xaccInitTextCell (cell); - return cell; + BasicCell *cell; + + cell = xaccMallocBasicCell (); + xaccInitTextCell (cell); + + return cell; } /* ================================================ */ @@ -71,7 +73,7 @@ xaccMallocTextCell (void) void xaccInitTextCell (BasicCell *cell) { - cell->modify_verify = TextMV; + cell->modify_verify = TextMV; } /* ================================================ */ @@ -79,8 +81,8 @@ xaccInitTextCell (BasicCell *cell) void xaccDestroyTextCell (BasicCell *cell) { - cell->modify_verify = NULL; - xaccDestroyBasicCell (cell); + cell->modify_verify = NULL; + xaccDestroyBasicCell (cell); } /* --------------- end of file ---------------------- */