Scott Oonk's first set of changes for utf-8 support.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/branches/gnucash-gnome2-dev@9843 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
David Hampton
2004-03-03 04:42:53 +00:00
parent 881bc83bdb
commit a5d4c7cfee
23 changed files with 438 additions and 578 deletions

View File

@@ -178,6 +178,7 @@ Bill Nottingham <notting@redhat.com> guile configure patch
Peter O'Gorman <peter@pogma.com> file i/o patches, Mac OS X patches
OmNiBuS <webmaster@obsidian.uia.net> web site graphics & content
Gordon Oliver <gordo@pincoya.com> multiple currency status line patch
Scott Oonk <s.oonk@comcast.net> utf-8 changes.
Alan Orndorff <dwarf@solarisresources.com> Solaris packager
Myroslav Opyr <mopyr@IPM.Lviv.UA> for misc patches
Laurent P{'e}lecq <laurent.pelecq@wanadoo.fr> i18n patches with gettext

View File

@@ -42,6 +42,7 @@ gnc_setup_gettext(void)
#ifdef HAVE_GETTEXT
bindtextdomain (TEXT_DOMAIN, LOCALE_DIR);
textdomain (TEXT_DOMAIN);
bind_textdomain_codeset (TEXT_DOMAIN, "UTF-8");
#endif
}

View File

@@ -25,13 +25,8 @@
#include "config.h"
#include <ctype.h>
#include <string.h>
#ifdef HAVE_WCTYPE_H
#include <wctype.h>
#endif
#include "QuickFill.h"
#include "dialog-utils.h"
#include "gnc-engine.h"
@@ -48,9 +43,8 @@ struct _QuickFill
/** PROTOTYPES ******************************************************/
static void quickfill_insert_recursive (QuickFill *qf, const GdkWChar *text,
int depth, const char *mb_text,
QuickFillSort sort);
static void quickfill_insert_recursive (QuickFill *qf, const char *text,
int depth, QuickFillSort sort);
/* This static indicates the debugging module that this .o belongs to. */
static short module = MOD_REGISTER;
@@ -83,7 +77,7 @@ gnc_quickfill_new (void)
{
QuickFill *qf;
if (sizeof (guint) < sizeof (GdkWChar))
if (sizeof (guint) < sizeof (gunichar))
{
PWARN ("Can't use quickfill");
return NULL;
@@ -143,9 +137,9 @@ gnc_quickfill_string (QuickFill *qf)
/********************************************************************\
\********************************************************************/
QuickFill *
gnc_quickfill_get_char_match (QuickFill *qf, GdkWChar wc)
gnc_quickfill_get_char_match (QuickFill *qf, gunichar uc)
{
guint key = iswlower (wc) ? towupper (wc) : wc;
guint key = g_unichar_toupper (uc);
if (qf == NULL)
return NULL;
@@ -159,19 +153,24 @@ gnc_quickfill_get_char_match (QuickFill *qf, GdkWChar wc)
\********************************************************************/
QuickFill *
gnc_quickfill_get_string_len_match (QuickFill *qf,
const GdkWChar *str, int len)
const char *str, int len)
{
const char *c;
gunichar uc;
if (str == NULL)
return NULL;
while ((*str != 0) && (len > 0))
c = str;
while (*c && (len > 0))
{
if (qf == NULL)
return NULL;
qf = gnc_quickfill_get_char_match (qf, *str);
uc = g_utf8_get_char (c);
qf = gnc_quickfill_get_char_match (qf, uc);
str++;
c = g_utf8_next_char (c);
len--;
}
@@ -181,12 +180,12 @@ gnc_quickfill_get_string_len_match (QuickFill *qf,
/********************************************************************\
\********************************************************************/
QuickFill *
gnc_quickfill_get_string_match (QuickFill *qf, const GdkWChar *str)
gnc_quickfill_get_string_match (QuickFill *qf, const char *str)
{
if (str == NULL)
return NULL;
return gnc_quickfill_get_string_len_match (qf, str, gnc_wcslen (str));
return gnc_quickfill_get_string_len_match (qf, str, g_utf8_strlen (str, -1));
}
/********************************************************************\
@@ -229,65 +228,39 @@ gnc_quickfill_get_unique_len_match (QuickFill *qf, int *length)
void
gnc_quickfill_insert (QuickFill *qf, const char *text, QuickFillSort sort)
{
GdkWChar *wc_text;
gchar *normalized_str;
if (text)
{
if (gnc_mbstowcs (&wc_text, text) < 0)
{
PERR ("bad text conversion");
return;
}
}
else
wc_text = NULL;
if ((qf == NULL) || (text == NULL))
return;
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);
normalized_str = g_utf8_normalize (text, -1, G_NORMALIZE_DEFAULT);
quickfill_insert_recursive (qf, normalized_str, 0, sort);
g_free (normalized_str);
}
/********************************************************************\
\********************************************************************/
static void
quickfill_insert_recursive (QuickFill *qf, const GdkWChar *text, int depth,
const char *mb_text, QuickFillSort sort)
quickfill_insert_recursive (QuickFill *qf, const char *text, int depth,
QuickFillSort sort)
{
guint key;
char *old_text;
QuickFill *match_qf;
int len;
char *key_char;
gunichar key_char_uc;
if (qf == NULL)
return;
if ((text == NULL) || (text[depth] == 0))
if ((text == NULL) || (g_utf8_strlen (text, -1) <= depth))
return;
key = iswlower (text[depth]) ? towupper (text[depth]) : text[depth];
key_char = g_utf8_offset_to_pointer (text, depth);
key_char_uc = g_utf8_get_char (key_char);
key = g_unichar_toupper (key_char_uc);
match_qf = g_hash_table_lookup (qf->matches, GUINT_TO_POINTER (key));
if (match_qf == NULL)
@@ -301,33 +274,33 @@ quickfill_insert_recursive (QuickFill *qf, const GdkWChar *text, int depth,
switch (sort)
{
case QUICKFILL_ALPHA:
if (old_text && (strcoll (mb_text, old_text) >= 0))
if (old_text && (g_utf8_collate (text, old_text) >= 0))
break;
case QUICKFILL_LIFO:
default:
len = gnc_wcslen (text);
len = g_utf8_strlen (text, -1);
/* 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) mb_text);
match_qf->text = g_cache_insert (qf_string_cache, (gpointer) text);
match_qf->len = len;
break;
}
/* Leave prefixes in place */
if ((len > match_qf->len) &&
(strncmp(mb_text, old_text, strlen(old_text)) == 0))
(strncmp(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) mb_text);
match_qf->text = g_cache_insert (qf_string_cache, (gpointer) text);
match_qf->len = len;
break;
}
quickfill_insert_recursive (match_qf, text, ++depth, mb_text, sort);
quickfill_insert_recursive (match_qf, text, ++depth, sort);
}
/********************** END OF FILE *********************************\

View File

@@ -48,20 +48,17 @@ void gnc_quickfill_destroy (QuickFill *qf);
const char * gnc_quickfill_string (QuickFill *qf);
QuickFill * gnc_quickfill_get_char_match (QuickFill *qf, GdkWChar wc);
QuickFill * gnc_quickfill_get_char_match (QuickFill *qf, gunichar c);
QuickFill * gnc_quickfill_get_string_match (QuickFill *qf,
const GdkWChar *str);
const char *str);
QuickFill * gnc_quickfill_get_string_len_match (QuickFill *qf,
const GdkWChar *str, int len);
const char *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 */

View File

@@ -606,12 +606,13 @@ gnc_xfer_description_insert_cb(GtkEntry *entry,
gint *start_pos,
XferDialog *xferData)
{
GdkWChar *change_text_w, *old_text_w, *new_text_w;
int change_text_len, old_text_len, new_text_len, old_pos;
char *new_text;
GString *change_text_gs, *new_text_gs;
glong old_text_chars, new_text_chars;
const char *old_text, *match_str = NULL;
QuickFill *match;
int i;
const char *c;
gunichar uc;
xferData->desc_didquickfill = FALSE;
@@ -622,58 +623,41 @@ gnc_xfer_description_insert_cb(GtkEntry *entry,
if (!old_text)
old_text = "";
old_text_len = gnc_mbstowcs (&old_text_w, old_text);
if (old_text_len < 0)
/* If we are inserting in the middle, do nothing */
old_text_chars = g_utf8_strlen (old_text, -1);
if( *start_pos < old_text_chars )
return;
/* If we are inserting in the middle, do nothing */
if( *start_pos < old_text_len )
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_pos = *start_pos;
change_text_gs = g_string_new_len (insert_text, insert_text_len);
/* Construct what the new value of the text entry will be */
new_text_len = old_text_len + change_text_len;
new_text_w = g_new0 (GdkWChar, new_text_len + 1);
new_text_gs = g_string_new ("");
i = 0;
c = old_text;
//Copy old text up to insert position
while ( *c && ( i < *start_pos ) )
{
uc = g_utf8_get_char ( c );
g_string_append_unichar ( new_text_gs, uc );
c = g_utf8_next_char ( c );
i++;
}
for (i = 0; i < *start_pos; i++)
new_text_w[i] = old_text_w[i];
//Copy inserted text
g_string_append ( new_text_gs, change_text_gs->str );
for (i = *start_pos; i < *start_pos + change_text_len; i++)
new_text_w[i] = change_text_w[i - *start_pos];
//Copy old text after insert position
while ( *c )
{
uc = g_utf8_get_char ( c );
g_string_append_unichar ( new_text_gs, uc );
c = g_utf8_next_char ( c );
}
for (i = *start_pos + change_text_len; i < new_text_len; i++)
new_text_w[i] = old_text_w[i - change_text_len];
new_text_w[new_text_len] = 0;
new_text = gnc_wcstombs (new_text_w);
if( ( match = gnc_quickfill_get_string_match( xferData->qf, new_text_w ) )
if( ( match = gnc_quickfill_get_string_match( xferData->qf, new_text_gs->str ) )
&& ( match_str = gnc_quickfill_string( match ) )
&& safe_strcmp( new_text, old_text ) )
&& safe_strcmp( new_text_gs->str, old_text ) )
{
g_signal_handlers_block_matched (G_OBJECT (entry),
G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, xferData);
@@ -694,15 +678,16 @@ gnc_xfer_description_insert_cb(GtkEntry *entry,
/* Store off data for the key_press_cb or
* the button_release_cb to make use of. */
xferData->desc_cursor_position = new_text_len;
xferData->desc_start_selection = new_text_len;
new_text_chars = g_utf8_strlen (new_text_gs->str, -1);
xferData->desc_cursor_position = new_text_chars;
xferData->desc_start_selection = new_text_chars;
xferData->desc_end_selection = -1;
xferData->desc_didquickfill = TRUE;
}
g_free( new_text );
g_free( new_text_w );
g_string_free (change_text_gs, TRUE);
g_string_free (new_text_gs, TRUE);
}
/* This common post-key press and post-button release handler fixes
@@ -2070,4 +2055,3 @@ void gnc_xfer_dialog_set_txn_cb(XferDialog *xferData,
xferData->transaction_cb = handler;
xferData->transaction_user_data = user_data;
}

View File

@@ -531,24 +531,20 @@ gnc_handle_date_accelerator (GdkEventKey *event,
case GDK_minus:
if ((strlen (date_str) != 0) && (dateSeparator () == '-'))
{
GdkWChar *wcs;
int count;
int len;
int i;
len = gnc_mbstowcs (&wcs, date_str);
if (len < 0)
return FALSE;
const char *c;
gunichar uc;
int count = 0;
/* rough check for existing date */
for (i = count = 0; i < len; i++)
c = date_str;
while (*c)
{
if (wcs[i] == '-')
uc = g_utf8_get_char (c);
if (uc == '-')
count++;
c = g_utf8_next_char (c);
}
g_free (wcs);
if (count < 2)
return FALSE;
}
@@ -985,86 +981,3 @@ gnc_glade_autoconnect_full_func(const gchar *handler_name,
g_signal_connect(signal_object, signal_name, func, user_data);
}
}
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;
}

View File

@@ -138,19 +138,5 @@ void gnc_glade_autoconnect_full_func(const gchar *handler_name,
gboolean after,
gpointer user_data);
/* Multibyte/wide char string helper functions. */
/* Allocate new wide char string in dest_p. Return number of
* wide chars or < 0 if error. */
gint gnc_mbstowcs (GdkWChar **dest_p, const char *src);
/* Return new multibyte string or NULL if failure. */
char * gnc_wcstombs (const GdkWChar *src);
/* Len of wide char string in chars */
gint gnc_wcslen (const GdkWChar *src);
/* Duplicate wide char string */
GdkWChar * gnc_wcsdup (const GdkWChar *src);
#endif

View File

@@ -74,8 +74,7 @@ gnc_basic_cell_clear (BasicCell *cell)
cell->conditionally_changed = FALSE;
cell->value = NULL;
cell->value_w = NULL;
cell->value_len = 0;
cell->value_chars = 0;
cell->set_value = NULL;
cell->enter_cell = NULL;
@@ -100,8 +99,6 @@ gnc_basic_cell_init (BasicCell *cell)
gnc_basic_cell_clear (cell);
cell->value = g_strdup ("");
cell->value_len = gnc_mbstowcs (&cell->value_w, cell->value);
}
void
@@ -119,9 +116,6 @@ gnc_basic_cell_destroy (BasicCell *cell)
g_free (cell->value);
cell->value = NULL;
g_free (cell->value_w);
cell->value_w = NULL;
/* help prevent access to freed memory */
gnc_basic_cell_clear (cell);
@@ -257,23 +251,5 @@ gnc_basic_cell_set_value_internal (BasicCell *cell, const char *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
gnc_basic_cell_set_wcvalue_internal (BasicCell *cell, const GdkWChar *value)
{
if (!value)
{
gnc_basic_cell_set_value_internal (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);
cell->value_chars = g_utf8_strlen(value, -1);
}

View File

@@ -158,9 +158,9 @@ typedef gboolean (*CellEnterFunc) (BasicCell *cell,
int *end_selection);
typedef void (*CellModifyVerifyFunc) (BasicCell *cell,
const GdkWChar *add_str,
const char *add_str,
int add_str_len,
const GdkWChar *new_value,
const char *new_value,
int new_value_len,
int *cursor_position,
int *start_selection,
@@ -192,10 +192,7 @@ struct basic_cell
char * cell_name;
char * value; /* current value */
GdkWChar * value_w; /* value as wide chars */
gint value_len; /* length of wide chars value */
guint value_chars; /* number of characters in value */
gboolean changed; /* true if value modified */
gboolean conditionally_changed; /* true if value modified conditionally */
@@ -260,7 +257,4 @@ void gnc_basic_cell_set_conditionally_changed (BasicCell *cell,
void gnc_basic_cell_set_value_internal (BasicCell *bcell,
const char *value);
void gnc_basic_cell_set_wcvalue_internal (BasicCell *bcell,
const GdkWChar *value);
#endif /* BASIC_CELL_H */

View File

@@ -21,9 +21,6 @@
#include "config.h"
#include <ctype.h>
#include <string.h>
#include "gnc-engine-util.h"
#include "gnc-ui-util.h"
@@ -44,9 +41,9 @@ static void gnc_formula_cell_leave( BasicCell *_cell );
#endif
static void gnc_formula_cell_modify_verify( BasicCell *_cell,
const GdkWChar *change,
const char *change,
int change_len,
const GdkWChar *newval,
const char *newval,
int newval_len,
int *cursor_position,
int *start_selection,
@@ -115,10 +112,10 @@ gnc_formula_cell_leave( BasicCell *_cell )
static
void
gnc_formula_cell_modify_verify( BasicCell *_cell,
const GdkWChar *change,
gnc_formula_cell_modify_verify( BasicCell *_cell,
const char *change,
int change_len,
const GdkWChar *newval,
const char *newval,
int newval_len,
int *cursor_position,
int *start_selection,
@@ -129,7 +126,8 @@ gnc_formula_cell_modify_verify( BasicCell *_cell,
const char *toks = "+-*/=()_";
unsigned char decimal_point;
unsigned char thousands_sep;
int i;
const char *c;
gunichar uc;
DEBUG( "%s, %d, %s, %d, %d, %d, %d",
(gchar *)change, change_len, (gchar *)newval, newval_len,
@@ -138,7 +136,7 @@ gnc_formula_cell_modify_verify( BasicCell *_cell,
/* accept the newval string if user action was delete */
if (change == NULL)
{
gnc_basic_cell_set_wcvalue_internal( &cell->cell, newval );
gnc_basic_cell_set_value_internal( &cell->cell, newval );
return;
}
@@ -152,16 +150,21 @@ gnc_formula_cell_modify_verify( BasicCell *_cell,
else
thousands_sep = lc->thousands_sep[0];
for (i = 0; i < change_len; i++)
if (!isdigit(change[i]) &&
!isspace(change[i]) &&
!isalpha(change[i]) &&
(decimal_point != change[i]) &&
(thousands_sep != change[i]) &&
(strchr (toks, change[i]) == NULL))
return;
c = change;
while (*c)
{
uc = g_utf8_get_char (c);
if (!g_unichar_isdigit (uc) &&
!g_unichar_isspace (uc) &&
!g_unichar_isalpha (uc) &&
(decimal_point != uc) &&
(thousands_sep != uc) &&
(g_utf8_strchr (toks, -1, uc) == NULL))
return;
c = g_utf8_next_char (c);
}
gnc_basic_cell_set_wcvalue_internal( &cell->cell, newval );
gnc_basic_cell_set_value_internal( &cell->cell, newval );
}
static

View File

@@ -50,7 +50,7 @@ typedef struct _FormulaCell
GNCPrintAmountInfo print_info;
/** The user-entered formula. **/
GdkWChar *formula;
char *formula;
} FormulaCell;
/* installs a callback to handle date recording */

View File

@@ -73,9 +73,9 @@ gnc_parse_num (const char *string, long int *num)
static void
gnc_num_cell_modify_verify (BasicCell *_cell,
const GdkWChar *change,
const char *change,
int change_len,
const GdkWChar *newval,
const char *newval,
int new_val_len,
int *cursor_position,
int *start_selection,
@@ -85,12 +85,16 @@ gnc_num_cell_modify_verify (BasicCell *_cell,
gboolean accel = FALSE;
gboolean is_num;
long int number = 0;
gunichar uc;
glong change_chars;
change_chars = g_utf8_strlen (change, -1);
if ((change == NULL) || (change_len == 0) || /* if we are deleting */
(change_len > 1)) /* or entering > 1 char */
if ((change == NULL) || (change_chars == 0) || /* if we are deleting */
(change_chars > 1)) /* or entering > 1 char */
/* then just accept the proposed change */
{
gnc_basic_cell_set_wcvalue_internal (&cell->cell, newval);
gnc_basic_cell_set_value_internal (&cell->cell, newval);
return;
}
@@ -101,7 +105,8 @@ gnc_num_cell_modify_verify (BasicCell *_cell,
if (is_num && (number < 0))
is_num = FALSE;
switch (change[0])
uc = g_utf8_get_char (change);
switch (uc)
{
case '+':
case '=':
@@ -155,7 +160,7 @@ gnc_num_cell_modify_verify (BasicCell *_cell,
return;
}
gnc_basic_cell_set_wcvalue_internal (&cell->cell, newval);
gnc_basic_cell_set_value_internal (&cell->cell, newval);
}
BasicCell *

View File

@@ -34,11 +34,9 @@
#include "config.h"
#include <ctype.h>
#include <glib.h>
#include <locale.h>
#include <string.h>
#include <string.h>
#include "gnc-exp-parser.h"
#include "gnc-engine-util.h"
@@ -69,10 +67,10 @@ gnc_price_cell_enter (BasicCell *_cell,
}
static void
gnc_price_cell_modify_verify (BasicCell *_cell,
const GdkWChar *change,
gnc_price_cell_modify_verify (BasicCell *_cell,
const char *change,
int change_len,
const GdkWChar *newval,
const char *newval,
int newval_len,
int *cursor_position,
int *start_selection,
@@ -83,12 +81,13 @@ gnc_price_cell_modify_verify (BasicCell *_cell,
const char *toks = "+-*/=()_";
unsigned char decimal_point;
unsigned char thousands_sep;
int i;
const char *c;
gunichar uc;
/* accept the newval string if user action was delete */
if (change == NULL)
{
gnc_basic_cell_set_wcvalue_internal (_cell, newval);
gnc_basic_cell_set_value_internal (_cell, newval);
cell->need_to_parse = TRUE;
return;
}
@@ -103,16 +102,21 @@ gnc_price_cell_modify_verify (BasicCell *_cell,
else
thousands_sep = lc->thousands_sep[0];
for (i = 0; i < change_len; i++)
if (!isdigit(change[i]) &&
!isspace(change[i]) &&
!isalpha(change[i]) &&
(decimal_point != change[i]) &&
(thousands_sep != change[i]) &&
(strchr (toks, change[i]) == NULL))
c = change;
while (*c)
{
uc = g_utf8_get_char (c);
if (!g_unichar_isdigit (uc) &&
!g_unichar_isspace (uc) &&
!g_unichar_isalpha (uc) &&
(decimal_point != uc) &&
(thousands_sep != uc) &&
(g_utf8_strchr (toks, -1, uc) == NULL))
return;
c = g_utf8_next_char (c);
}
gnc_basic_cell_set_wcvalue_internal (_cell, newval);
gnc_basic_cell_set_value_internal (_cell, newval);
cell->need_to_parse = TRUE;
}

View File

@@ -35,16 +35,11 @@
#include "config.h"
#include <ctype.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_WCTYPE_H
#include <wctype.h>
#endif
#include "basiccell.h"
#include "dialog-utils.h"
#include "gnc-ui-util.h"
@@ -52,12 +47,12 @@
static void gnc_quickfill_cell_set_original (QuickFillCell *cell,
const GdkWChar *original);
const char *original);
static void
static void
gnc_quickfill_cell_set_value_internal (BasicCell *_cell,
const char *val)
const char *val)
{
QuickFillCell *cell = (QuickFillCell *) _cell;
gnc_quickfill_cell_set_value (cell, val);
@@ -81,71 +76,74 @@ gnc_quickfill_cell_enter (BasicCell *_cell,
return TRUE;
}
/* by definition, all text is valid text. So accept
* all modifications */
static gboolean
wcstrcaseequal (const GdkWChar *s1, const GdkWChar *s2)
utf8_caseequal (const char *s1, const char *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 = iswlower (s1[i]) ? towupper (s1[i]) : s1[i];
b = iswlower (s2[i]) ? towupper (s2[i]) : s2[i];
if (a != b)
char *s1new;
char *s2new;
gboolean equal = FALSE;
if (s1 == s2)
return TRUE;
if (!s1 || !s2)
return FALSE;
}
return TRUE;
s1new = g_utf8_casefold(s1, -1);
s2new = g_utf8_casefold(s2, -1);
if (g_utf8_collate(s1new, s2new) == 0)
equal = TRUE;
g_free (s1new);
g_free (s2new);
return equal;
}
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)
utf8_caseequal_len (const char *s1, const char *s2, guint len)
{
char *s1new;
char *s2new;
glong s1chars;
glong s2chars;
gboolean equal = FALSE;
if (len == 0)
return TRUE;
if (s1 == s2)
return TRUE;
if (!s1 || !s2)
return FALSE;
a = iswlower (s1[i]) ? towupper (s1[i]) : s1[i];
b = iswlower (s2[i]) ? towupper (s2[i]) : s2[i];
s1chars = g_utf8_strlen (s1, -1);
s2chars = g_utf8_strlen (s2, -1);
if ( (s1chars < len) || (s2chars < len) )
return FALSE;
s1new = g_new0 (gchar, strlen (s1));
s2new = g_new0 (gchar, strlen (s2));
if (a != b)
return FALSE;
}
g_utf8_strncpy (s1new, s1, len);
g_utf8_strncpy (s2new, s2, len);
return TRUE;
equal = utf8_caseequal (s1new, s2new);
g_free (s1new);
g_free (s2new);
return equal;
}
static void
gnc_quickfill_cell_modify_verify (BasicCell *_cell,
const GdkWChar *change,
const char *change,
int change_len,
const GdkWChar *newval,
const char *newval,
int newval_len,
int *cursor_position,
int *start_selection,
@@ -155,52 +153,54 @@ gnc_quickfill_cell_modify_verify (BasicCell *_cell,
const char *match_str;
QuickFill *match;
glong newval_chars;
glong change_chars;
newval_chars = g_utf8_strlen(newval, newval_len);
change_chars = g_utf8_strlen(change, change_len);
/* If deleting, just accept */
if (change == NULL)
{
/* 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 >= newval_len) &&
if ((*cursor_position >= newval_chars) &&
(cell->original != NULL) &&
(gnc_wcslen (cell->original) >= newval_len) &&
wcstrncaseequal (cell->original, newval, newval_len))
cell->original[newval_len] = 0;
(g_utf8_strlen (cell->original, -1) >= newval_chars) &&
utf8_caseequal_len (cell->original, newval, newval_chars))
{
gchar *temp = g_strndup (cell->original, newval_len);
gnc_quickfill_cell_set_original (cell, temp);
g_free (temp);
}
else
gnc_quickfill_cell_set_original (cell, NULL);
gnc_basic_cell_set_wcvalue_internal (&cell->cell, newval);
gnc_basic_cell_set_value_internal (&cell->cell, newval);
return;
}
/* If we are inserting in the middle, just accept */
if (*cursor_position < _cell->value_len)
if (*cursor_position < _cell->value_chars)
{
gnc_basic_cell_set_wcvalue_internal (&cell->cell, newval);
gnc_basic_cell_set_value_internal (&cell->cell, newval);
gnc_quickfill_cell_set_original (cell, NULL);
return;
}
if (cell->original == NULL)
cell->original = gnc_wcsdup (newval);
else if (wcstrcaseequal (cell->original, _cell->value_w))
cell->original = g_strdup (newval);
else if (utf8_caseequal (cell->original, _cell->value))
{
int orig_len = gnc_wcslen (cell->original);
GdkWChar *original;
int i;
GString *original;
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;
original = g_string_new (cell->original);
g_string_append (original, change);
g_free (cell->original);
cell->original = original;
cell->original = g_strdup (original->str);
g_string_free (original, TRUE);
}
else
{
@@ -219,13 +219,13 @@ gnc_quickfill_cell_modify_verify (BasicCell *_cell,
*cursor_position = -1;
gnc_basic_cell_set_wcvalue_internal (&cell->cell, newval);
gnc_basic_cell_set_value_internal (&cell->cell, newval);
return;
}
*start_selection = newval_len;
*start_selection = newval_chars;
*end_selection = -1;
*cursor_position += change_len;
*cursor_position += change_chars;
gnc_basic_cell_set_value_internal (&cell->cell, match_str);
}
@@ -237,7 +237,7 @@ gnc_quickfill_cell_leave (BasicCell * _cell)
{
QuickFillCell *cell = (QuickFillCell *) _cell;
gnc_quickfill_insert_wc (cell->qf, _cell->value_w, cell->sort);
gnc_quickfill_insert (cell->qf, _cell->value, cell->sort);
}
static void
@@ -293,7 +293,7 @@ gnc_quickfill_cell_set_value (QuickFillCell *cell, const char * value)
return;
gnc_basic_cell_set_value_internal (&cell->cell, value);
gnc_quickfill_insert_wc (cell->qf, cell->cell.value_w, cell->sort);
gnc_quickfill_insert (cell->qf, value, cell->sort);
}
void
@@ -306,7 +306,7 @@ gnc_quickfill_cell_set_sort (QuickFillCell *cell, QuickFillSort sort)
}
static void
gnc_quickfill_cell_set_original (QuickFillCell *cell, const GdkWChar *original)
gnc_quickfill_cell_set_original (QuickFillCell *cell, const char *original)
{
if (cell == NULL)
return;
@@ -314,7 +314,7 @@ gnc_quickfill_cell_set_original (QuickFillCell *cell, const GdkWChar *original)
g_free (cell->original);
if ((original != NULL) && (*original != 0))
cell->original = gnc_wcsdup (original);
cell->original = strdup (original);
else
cell->original = NULL;
}

View File

@@ -58,7 +58,7 @@ typedef struct
QuickFillSort sort; /* determines order of strings matched.
* default is QUICKFILL_LIFO. */
GdkWChar *original; /* original string entered in original case */
char *original; /* original string entered in original case */
} QuickFillCell;
BasicCell * gnc_quickfill_cell_new (void);

View File

@@ -1184,9 +1184,9 @@ gnc_table_confirm_change (Table *table, VirtualLocation virt_loc)
const char *
gnc_table_modify_update (Table *table,
VirtualLocation virt_loc,
const GdkWChar *change,
const char *change,
int change_len,
const GdkWChar *newval,
const char *newval,
int newval_len,
int *cursor_position,
int *start_selection,
@@ -1242,9 +1242,7 @@ gnc_table_modify_update (Table *table,
cursor_position, start_selection, end_selection);
else
{
char *newval_mb = gnc_wcstombs (newval);
gnc_basic_cell_set_value (cell, newval_mb);
g_free (newval_mb);
gnc_basic_cell_set_value (cell, newval);
}
if (safe_strcmp (old_value, cell->value) != 0)

View File

@@ -344,9 +344,9 @@ gboolean gnc_table_confirm_change(Table *table, VirtualLocation virt_loc);
const char * gnc_table_modify_update(Table *table,
VirtualLocation virt_loc,
const GdkWChar *change,
const char *change,
int change_len,
const GdkWChar *newval,
const char *newval,
int newval_len,
int *cursor_position,
int *start_selection,

View File

@@ -424,9 +424,9 @@ gnc_combo_cell_set_value (ComboCell *cell, const char *str)
static void
gnc_combo_cell_modify_verify (BasicCell *_cell,
const GdkWChar *change,
const char *change,
int change_len,
const GdkWChar *newval,
const char *newval,
int newval_len,
int *cursor_position,
int *start_selection,
@@ -437,10 +437,15 @@ gnc_combo_cell_modify_verify (BasicCell *_cell,
const char *match_str;
QuickFill *match;
gboolean pop_list;
glong newval_chars;
glong change_chars;
newval_chars = g_utf8_strlen (newval, newval_len);
change_chars = g_utf8_strlen (change, change_len);
if (box->in_list_select)
{
gnc_basic_cell_set_wcvalue_internal (_cell, newval);
gnc_basic_cell_set_value_internal (_cell, newval);
*cursor_position = -1;
*start_selection = 0;
@@ -452,14 +457,14 @@ gnc_combo_cell_modify_verify (BasicCell *_cell,
/* If deleting, just accept */
if (change == NULL)
{
gnc_basic_cell_set_wcvalue_internal (_cell, newval);
gnc_basic_cell_set_value_internal (_cell, newval);
return;
}
/* If we are inserting in the middle, just accept */
if (*cursor_position < _cell->value_len)
if (*cursor_position < _cell->value_chars)
{
gnc_basic_cell_set_wcvalue_internal (_cell, newval);
gnc_basic_cell_set_value_internal (_cell, newval);
return;
}
@@ -469,7 +474,7 @@ gnc_combo_cell_modify_verify (BasicCell *_cell,
if ((match == NULL) || (match_str == NULL))
{
gnc_basic_cell_set_wcvalue_internal (_cell, newval);
gnc_basic_cell_set_value_internal (_cell, newval);
block_list_signals (cell);
gnc_item_list_select (box->item_list, NULL);
@@ -478,9 +483,9 @@ gnc_combo_cell_modify_verify (BasicCell *_cell,
return;
}
*start_selection = newval_len;
*start_selection = newval_chars;
*end_selection = -1;
*cursor_position += change_len;
*cursor_position += change_chars;
if (!box->list_popped)
pop_list = auto_pop_combos;
@@ -539,7 +544,7 @@ gnc_combo_cell_direct_update (BasicCell *bcell,
return FALSE;
match = gnc_quickfill_get_string_len_match
(box->qf, bcell->value_w, *cursor_position);
(box->qf, bcell->value, *cursor_position);
if (match == NULL)
return TRUE;
@@ -580,28 +585,34 @@ gnc_combo_cell_direct_update (BasicCell *bcell,
if (event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK))
return FALSE;
if ((*cursor_position < bcell->value_len) &&
((*end_selection < bcell->value_len) ||
if ((*cursor_position < bcell->value_chars) &&
((*end_selection < bcell->value_chars) ||
(*cursor_position < *start_selection)))
return FALSE;
if ((*cursor_position == bcell->value_len) &&
if ((*cursor_position == bcell->value_chars) &&
(*start_selection != *end_selection) &&
(*end_selection < bcell->value_len))
(*end_selection < bcell->value_chars))
return FALSE;
find_pos = -1;
if (*cursor_position < bcell->value_len)
if (*cursor_position < bcell->value_chars)
{
int i = *cursor_position;
while (bcell->value_w[i])
const char *c;
gunichar uc;
c = g_utf8_offset_to_pointer (bcell->value, i);
while (*c)
{
if (bcell->value_w[i++] == box->complete_char)
{
find_pos = i;
break;
}
uc = g_utf8_get_char (c);
if (uc == box->complete_char)
{
find_pos = (i + 1);
break;
}
c = g_utf8_next_char (c);
i++;
}
}
@@ -614,12 +625,12 @@ gnc_combo_cell_direct_update (BasicCell *bcell,
}
else
{
new_pos = bcell->value_len;
new_pos = bcell->value_chars;
extra_colon = TRUE;
}
match = gnc_quickfill_get_string_len_match (box->qf,
bcell->value_w, new_pos);
bcell->value, new_pos);
if (match == NULL)
return FALSE;

View File

@@ -32,7 +32,6 @@
#include "config.h"
#include <ctype.h>
#include <gnome.h>
#include <stdio.h>
#include <stdlib.h>
@@ -72,9 +71,9 @@ static void gnc_date_cell_move (BasicCell *bcell);
static void gnc_date_cell_gui_destroy (BasicCell *bcell);
static void gnc_date_cell_destroy (BasicCell *bcell);
static void gnc_date_cell_modify_verify (BasicCell *_cell,
const GdkWChar *change,
const char *change,
int change_len,
const GdkWChar *newval,
const char *newval,
int newval_len,
int *cursor_position,
int *start_selection,
@@ -449,9 +448,9 @@ gnc_date_cell_direct_update (BasicCell *bcell,
static void
gnc_date_cell_modify_verify (BasicCell *_cell,
const GdkWChar *change,
const char *change,
int change_len,
const GdkWChar *newval,
const char *newval,
int newval_len,
int *cursor_position,
int *start_selection,
@@ -463,9 +462,7 @@ gnc_date_cell_modify_verify (BasicCell *_cell,
if (box->in_date_select)
{
char *newval_mb = gnc_wcstombs (newval);
gnc_basic_cell_set_value (_cell, newval_mb);
g_free (newval_mb);
gnc_basic_cell_set_value (_cell, newval);
return;
}
@@ -476,26 +473,40 @@ gnc_date_cell_modify_verify (BasicCell *_cell,
accept = TRUE;
else
{
int i, count = 0;
int count = 0;
unsigned char separator = dateSeparator ();
gboolean ok = TRUE;
for (i = 0; i < change_len; i++)
const gchar *c;
gunichar uc;
/* accept only numbers or a date separator. Note that the
* separator of '-' (for DATE_FORMAT_ISO) takes precedence
* over the accelerator below! */
c = change;
while (*c)
{
/* accept only numbers or a date separator. Note that the
* separator of '-' (for DATE_FORMAT_ISO) takes precedence
* over the accelerator below! */
if (!isdigit (change[i]) && (separator != change[i]))
uc = g_utf8_get_char (c);
if (!g_unichar_isdigit (uc) && (separator != uc))
ok = FALSE;
if (separator == change[i])
if (separator == uc)
count++;
c = g_utf8_next_char (c);
}
c = _cell->value;
while (*c)
{
uc = g_utf8_get_char (c);
if (separator == uc)
count++;
c = g_utf8_next_char (c);
}
for (i = 0; i < _cell->value_len; i++)
if (separator == _cell->value_w[i])
count++;
if (2 < count)
ok = FALSE;
@@ -506,11 +517,9 @@ gnc_date_cell_modify_verify (BasicCell *_cell,
/* keep a copy of the new value */
if (accept)
{
char *newval_mb = gnc_wcstombs (newval);
gnc_basic_cell_set_wcvalue_internal (&cell->cell, newval);
gnc_parse_date (&(box->date), newval_mb);
g_free (newval_mb);
gnc_basic_cell_set_value_internal (&cell->cell, newval);
gnc_parse_date (&(box->date), newval);
if (!box->date_picker)
return;

View File

@@ -21,9 +21,9 @@
/* formulacell-gnome.c
*
* Implements Gnome-dependent formula-cell functions :
*
* Often the decimal key in the keypad is not mapped to the correct locale
* decimal point, the function PriceDirect handle this case.
*
* Often the decimal key in the keypad is not mapped to the correct locale
* decimal point, the function PriceDirect handle this case.
*/
#include "config.h"
@@ -53,9 +53,11 @@ gnc_formula_cell_direct_update( BasicCell *bcell,
GdkEventKey *event = gui_data;
char decimal_point;
struct lconv *lc;
GdkWChar *newval;
GString *newval_gs;
gboolean is_return;
int i;
const gchar *c;
gunichar uc;
if (event->type != GDK_KEY_PRESS)
return FALSE;
@@ -95,28 +97,38 @@ gnc_formula_cell_direct_update( BasicCell *bcell,
else
decimal_point = lc->decimal_point[0];
/* allocate space for newval_ptr : oldval + one letter ( the
decimal_point ) */
newval = g_new( GdkWChar, bcell->value_len + 2 );
/* copy oldval up to the cursor position */
for (i = 0; i < *cursor_position; i++)
newval[i] = bcell->value_w[i];
newval_gs = g_string_new ("");
c = bcell->value;
i = 0;
/* copy original value up to cursor position */
while (*c && (i < *cursor_position))
{
uc = g_utf8_get_char (c);
g_string_append_unichar (newval_gs, uc);
c = g_utf8_next_char (c);
i++;
}
/* insert the decimal_point at cursor position */
newval[*cursor_position] = decimal_point;
for (i = *cursor_position + 1; i < bcell->value_len + 1; i++)
newval[i] = bcell->value_w[i - 1];
newval[bcell->value_len + 1] = 0;
g_string_append_c (newval_gs, decimal_point);
i++;
c = g_utf8_next_char (c);
/* copy rest of original value */
while (*c)
{
uc = g_utf8_get_char (c);
g_string_append_unichar (newval_gs, uc);
c = g_utf8_next_char (c);
}
/* update the cursor position */
(*cursor_position)++;
gnc_basic_cell_set_wcvalue_internal( bcell, newval );
gnc_basic_cell_set_value_internal( bcell, newval_gs->str );
g_free (newval);
g_string_free (newval_gs, TRUE);
return TRUE;
}

View File

@@ -702,7 +702,6 @@ 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;
@@ -722,21 +721,15 @@ gnucash_sheet_modify_current_cell (GnucashSheet *sheet, const gchar *new_text)
cursor_position = gtk_editable_get_position (editable);
gtk_editable_get_selection_bounds (editable, &start_sel, &end_sel);
new_text_len = gnc_mbstowcs (&new_text_wc, new_text);
if (new_text_len < 0)
{
g_warning ("bad text: %s", new_text ? new_text : "(null)");
return NULL;
}
new_text_len = strlen (new_text);
retval = gnc_table_modify_update (table, virt_loc,
new_text_wc, new_text_len,
new_text_wc, new_text_len,
new_text, new_text_len,
new_text, new_text_len,
&cursor_position,
&start_sel, &end_sel,
NULL);
g_free (new_text_wc);
if (retval) {
gnc_item_edit_reset_offset (GNC_ITEM_EDIT(sheet->item_editor));
@@ -796,9 +789,8 @@ 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;
char *change_text;
GString *change_text_gs;
int new_text_len;
int old_text_len;
@@ -807,10 +799,13 @@ gnucash_sheet_insert_cb (GtkWidget *widget,
const char *old_text;
const char *retval;
char *new_text;
GString *new_text_gs;
int start_sel, end_sel;
int old_position;
int i;
const char *c;
gunichar uc;
select_info *info;
if (sheet->input_cancelled)
@@ -831,67 +826,54 @@ gnucash_sheet_insert_cb (GtkWidget *widget,
if (gnc_table_model_read_only (table->model))
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)
{
g_warning ("bad change text conversion");
g_free (change_text_w);
return;
}
change_text_gs = g_string_new_len (insert_text, insert_text_len);
old_text = gtk_entry_get_text (GTK_ENTRY(sheet->entry));
if (old_text == NULL)
old_text = "";
old_text_len = gnc_mbstowcs (&old_text_w, old_text);
if (old_text_len < 0)
{
g_warning ("bad old text conversion");
g_free (change_text_w);
return;
}
old_text_len = strlen (old_text);
old_position = *position;
/* we set new_text_w to what the entry contents would be if
/* we set new_text_gs to what the entry contents would be if
the insert was processed */
new_text_len = old_text_len + change_text_len;
new_text_w = g_new0 (GdkWChar, new_text_len + 1);
new_text_gs = g_string_new ("");
i = 0;
c = old_text;
//Copy old text up to insert position
while (*c && (i < old_position))
{
uc = g_utf8_get_char (c);
g_string_append_unichar (new_text_gs, uc);
c = g_utf8_next_char (c);
i++;
}
for (i = 0; i < old_position; i++)
new_text_w[i] = old_text_w[i];
for (i = old_position; i < old_position + change_text_len; i++)
new_text_w[i] = change_text_w[i - old_position];
for (i = old_position + change_text_len; i < new_text_len; i++)
new_text_w[i] = old_text_w[i - change_text_len];
new_text_w[new_text_len] = 0;
new_text = gnc_wcstombs (new_text_w);
//Copy inserted text
g_string_append (new_text_gs, change_text_gs->str);
//Copy old text after insert position
while (*c)
{
uc = g_utf8_get_char (c);
g_string_append_unichar (new_text_gs, uc);
c = g_utf8_next_char (c);
}
new_text = new_text_gs->str;
new_text_len = new_text_gs->len;
change_text = change_text_gs->str;
change_text_len = change_text_gs->len;
editable = GTK_EDITABLE (sheet->entry);
gtk_editable_get_selection_bounds (editable, &start_sel, &end_sel);
retval = gnc_table_modify_update (table, virt_loc,
change_text_w, change_text_len,
new_text_w, new_text_len,
change_text, change_text_len,
new_text, new_text_len,
position, &start_sel, &end_sel,
&sheet->input_cancelled);
@@ -924,9 +906,8 @@ gnucash_sheet_insert_cb (GtkWidget *widget,
gtk_signal_emit_stop_by_name (GTK_OBJECT (sheet->entry),
"insert_text");
}
if (*position < 0)
*position = gnc_mbstowcs(NULL, retval);
*position = g_utf8_strlen(retval, -1);
#if GTK_ALLOWED_SELECTION_WITHIN_INSERT_SIGNAL
gtk_editable_select_region (editable, start_sel, end_sel);
@@ -941,11 +922,8 @@ gnucash_sheet_insert_cb (GtkWidget *widget,
info);
}
#endif
g_free (change_text_w);
g_free (old_text_w);
g_free (new_text_w);
g_free (new_text);
g_string_free (new_text_gs, TRUE);
g_string_free (change_text_gs, TRUE);
}
@@ -959,18 +937,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;
const char *retval;
char *new_text;
GString *new_text_gs;
int cursor_position = start_pos;
int start_sel, end_sel;
int i;
const char *c;
gunichar uc;
if (end_pos <= start_pos)
return;
@@ -987,31 +965,35 @@ gnucash_sheet_delete_cb (GtkWidget *widget,
if (!old_text)
old_text = "";
old_text_len = gnc_mbstowcs (&old_text_w, old_text);
if (old_text_len < 0)
return;
new_text_gs = g_string_new ("");
i = 0;
c = old_text;
while (*c && (i < start_pos))
{
uc = g_utf8_get_char (c);
g_string_append_unichar (new_text_gs, uc);
c = g_utf8_next_char (c);
i++;
}
new_text_len = old_text_len - (end_pos - start_pos);
new_text_w = g_new0 (GdkWChar, new_text_len + 1);
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);
c = g_utf8_offset_to_pointer (old_text, end_pos);
while (*c)
{
uc = g_utf8_get_char (c);
g_string_append_unichar (new_text_gs, uc);
c = g_utf8_next_char (c);
}
new_text = new_text_gs->str;
new_text_len = new_text_gs->len;
editable = GTK_EDITABLE (sheet->entry);
gtk_editable_get_selection_bounds (editable, &start_sel, &end_sel);
retval = gnc_table_modify_update (table, virt_loc,
NULL, 0,
new_text_w, new_text_len,
new_text, new_text_len,
&cursor_position,
&start_sel, &end_sel,
&sheet->input_cancelled);
@@ -1046,9 +1028,7 @@ gnucash_sheet_delete_cb (GtkWidget *widget,
if (start_sel != end_sel)
gtk_editable_select_region(editable, start_sel, end_sel);
g_free (old_text_w);
g_free (new_text_w);
g_free (new_text);
g_string_free (new_text_gs, TRUE);
}

View File

@@ -48,9 +48,11 @@ gnc_price_cell_direct_update (BasicCell *bcell,
GdkEventKey *event = gui_data;
char decimal_point;
struct lconv *lc;
GdkWChar *newval;
GString *newval_gs;
gboolean is_return;
int i;
const char *c;
gunichar uc;
if (event->type != GDK_KEY_PRESS)
return FALSE;
@@ -118,27 +120,38 @@ gnc_price_cell_direct_update (BasicCell *bcell,
/* allocate space for newval_ptr : oldval + one letter ( the
decimal_point ) */
newval = g_new (GdkWChar, bcell->value_len + 2);
newval_gs = g_string_new("");
/* copy oldval up to the cursor position */
for (i = 0; i < *cursor_position; i++)
newval[i] = bcell->value_w[i];
i = 0;
c = bcell->value;
while (*c && (i < *cursor_position))
{
uc = g_utf8_get_char (c);
g_string_append_unichar (newval_gs, uc);
c = g_utf8_next_char (c);
i++;
}
/* insert the decimal_point at cursor position */
newval[*cursor_position] = decimal_point;
for (i = *cursor_position + 1; i < bcell->value_len + 1; i++)
newval[i] = bcell->value_w[i - 1];
newval[bcell->value_len + 1] = 0;
g_string_append_c (newval_gs, decimal_point);
i++;
c = g_utf8_next_char (c);
/* copy oldval after cursor position */
while (*c)
{
uc = g_utf8_get_char (c);
g_string_append_unichar (newval_gs, uc);
c = g_utf8_next_char (c);
}
/* update the cursor position */
(*cursor_position)++;
gnc_basic_cell_set_wcvalue_internal (bcell, newval);
g_free (newval);
gnc_basic_cell_set_value_internal (bcell, newval_gs->str);
g_string_free (newval_gs, TRUE);
cell->need_to_parse = TRUE;
return TRUE;

View File

@@ -72,7 +72,7 @@ gnc_quickfill_cell_direct_update (BasicCell *bcell,
(*start_selection >= *cursor_position))
*cursor_position = *end_selection;
match = gnc_quickfill_get_string_len_match (cell->qf, bcell->value_w,
match = gnc_quickfill_get_string_len_match (cell->qf, bcell->value,
*cursor_position);
if (match == NULL)