Improve register support for multi-byte character sets.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3319 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Dave Peticolas
2000-12-19 01:47:22 +00:00
parent 05ce50d9f5
commit ee3c0b4864
19 changed files with 747 additions and 336 deletions

View File

@@ -1,10 +1,33 @@
2000-12-18 Dave Peticolas <dave@krondo.com>
* 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 <rgmerk@mira.net>
* 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 <rlb@cs.utexas.edu>

View File

@@ -29,20 +29,23 @@
#include <string.h>
#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 *********************************\

View File

@@ -28,6 +28,7 @@
#include "config.h"
#include <gdk/gdk.h>
#include <glib.h>
@@ -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__ */

View File

@@ -37,8 +37,12 @@
#include <string.h>
#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 ====================== */

View File

@@ -157,6 +157,7 @@
#ifndef __BASIC_CELL_H__
#define __BASIC_CELL_H__
#include <gdk/gdk.h>
#include <glib.h>
#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__ */

View File

@@ -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, "");
}
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -24,18 +24,14 @@
#include "config.h"
#include <gnome.h>
#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

View File

@@ -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;

View File

@@ -24,7 +24,7 @@
*
* Implements gnome dependent quickfill cell functions.
*
* Copyright (C) 2000 Dave Peticolas <peticola@cs.ucdavis.edu>
* Copyright (C) 2000 Dave Peticolas <dave@krondo.com>
*/
#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;

View File

@@ -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;

View File

@@ -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, "");
}
/* ================================================ */

View File

@@ -33,18 +33,20 @@
* Copyright (c) 2000 Dave Peticolas
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "config.h"
#include <ctype.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

View File

@@ -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);

View File

@@ -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);
}
/* ================================================ */

View File

@@ -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",

View File

@@ -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);

View File

@@ -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 ---------------------- */