Price cells now allow expressions.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3021 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Dave Peticolas 2000-10-05 08:34:40 +00:00
parent b5dce20c69
commit f112a66534
4 changed files with 150 additions and 146 deletions

View File

@ -1520,6 +1520,12 @@ gnucash_sheet_key_press_event (GtkWidget *widget, GdkEventKey *event)
/* Calculate tentative physical values */
switch (event->keyval) {
case GDK_Return:
case GDK_KP_Enter:
gtk_signal_emit_by_name(GTK_OBJECT(sheet->reg),
"activate_cursor");
return TRUE;
break;
case GDK_Tab:
case GDK_ISO_Left_Tab:
if (event->state & GDK_SHIFT_MASK) {
@ -2274,29 +2280,6 @@ gnucash_register_get_type (void)
}
static gint
gnucash_register_key_press_cb(GtkWidget *widget, GdkEventKey *event,
gpointer data)
{
GnucashRegister *reg = GNUCASH_REGISTER(data);
g_return_val_if_fail(widget != NULL, TRUE);
g_return_val_if_fail(GNUCASH_IS_SHEET(widget), TRUE);
g_return_val_if_fail(event != NULL, TRUE);
switch (event->keyval) {
case GDK_Return:
case GDK_KP_Enter:
gtk_signal_emit_by_name(GTK_OBJECT(reg),
"activate_cursor");
return TRUE;
break;
default:
return FALSE;
}
}
void
gnucash_register_attach_popup(GnucashRegister *reg, GtkWidget *popup,
gpointer data)
@ -2325,10 +2308,6 @@ gnucash_register_new (Table *table)
reg->sheet = sheet;
GNUCASH_SHEET(sheet)->reg = widget;
gtk_signal_connect (GTK_OBJECT(sheet), "key_press_event",
GTK_SIGNAL_FUNC(gnucash_register_key_press_cb),
reg);
header_canvas = gnucash_header_new (GNUCASH_SHEET(sheet));
reg->header_canvas = header_canvas;

View File

@ -33,6 +33,7 @@
#include <locale.h>
#include "pricecell.h"
#include "gnc-exp-parser.h"
#include "util.h"
@ -48,13 +49,43 @@ PriceDirect (BasicCell *bcell,
char decimal_point;
struct lconv *lc = gnc_localeconv();
char *newval;
if (event->type != GDK_KEY_PRESS)
return FALSE;
if (event->keyval != GDK_KP_Decimal)
return FALSE;
switch (event->keyval)
{
case GDK_Return:
if (!cell->need_to_parse)
return FALSE;
if (!(event->state &
(GDK_CONTROL_MASK | GDK_MOD1_MASK | GDK_SHIFT_MASK)))
return FALSE;
case GDK_KP_Enter:
{
char *error_loc;
double amount;
if (!cell->need_to_parse)
return FALSE;
if (gnc_exp_parser_parse(cell->cell.value, &amount, &error_loc))
xaccSetPriceCellValue (cell, amount);
else
*cursor_position = error_loc - cell->cell.value;
return TRUE;
}
case GDK_KP_Decimal:
break;
default:
return FALSE;
}
if (cell->monetary)
decimal_point = lc->mon_decimal_point[0];
else
@ -63,14 +94,14 @@ PriceDirect (BasicCell *bcell,
/* Only one decimal point allowed in price : */
if (strchr (bcell->value, decimal_point) != NULL)
return FALSE;
/* allocate space for newval_ptr : oldval + one letter ( the
decimal_point ) */
newval = g_new (char, strlen(bcell->value) + 2);
/* copy oldval up to the cursor position */
strncpy (newval, bcell->value, *cursor_position);
/* insert the decimal_point at cursor position */
newval[*cursor_position] = decimal_point;

View File

@ -33,8 +33,10 @@
#include <ctype.h>
#include <string.h>
#include <locale.h>
#include <string.h>
#include "gnc-common.h"
#include "gnc-exp-parser.h"
#include "util.h"
#include "basiccell.h"
@ -44,7 +46,10 @@
extern void xaccPriceGUIInit (PriceCell *);
static void PriceSetValue (BasicCell *, const char *);
static char * xaccPriceCellPrintValue (PriceCell *cell);
static const char * xaccPriceCellPrintValue (PriceCell *cell);
/* ================================================ */
/* set the color of the text to red, if the value is negative */
/* hack alert -- the actual color should probably be configurable */
@ -63,8 +68,6 @@ static char * xaccPriceCellPrintValue (PriceCell *cell);
(cell)->value = g_strdup (str); \
}
#define PRTBUF 40
/* ================================================ */
static gboolean
@ -92,50 +95,72 @@ PriceMV (BasicCell *_cell,
int *start_selection,
int *end_selection)
{
PriceCell *cell = (PriceCell *) _cell;
struct lconv *lc = gnc_localeconv();
char decimal_point;
char thousands_sep;
PriceCell *cell = (PriceCell *) _cell;
struct lconv *lc = gnc_localeconv();
const char *toks = "+-*/=()";
char decimal_point;
char thousands_sep;
int i;
if (cell->monetary)
decimal_point = lc->mon_decimal_point[0];
else
decimal_point = lc->decimal_point[0];
/* accept the newval string if user action was delete */
if (change == NULL)
{
SET ((&(cell->cell)), newval);
cell->need_to_parse = TRUE;
return;
}
if (cell->monetary)
thousands_sep = lc->mon_thousands_sep[0];
else
thousands_sep = lc->thousands_sep[0];
if (cell->monetary)
decimal_point = lc->mon_decimal_point[0];
else
decimal_point = lc->decimal_point[0];
/* accept the newval string if user action was delete, etc. */
if (change != NULL)
{
int i, count = 0;
if (cell->monetary)
thousands_sep = lc->mon_thousands_sep[0];
else
thousands_sep = lc->thousands_sep[0];
for (i = 0; '\0' != change[i]; i++)
{
/* accept only numbers or a decimal point or a thousands sep */
if (!isdigit(change[i]) &&
(decimal_point != change[i]) &&
(thousands_sep != change[i]) &&
('-' != change[i]))
return;
for (i = 0; change[i] != '\0'; i++)
if (!isdigit(change[i]) &&
!isspace(change[i]) &&
(decimal_point != change[i]) &&
(thousands_sep != change[i]) &&
(strchr (toks, change[i]) == NULL))
return;
if (decimal_point == change[i])
count++;
}
SET ((&(cell->cell)), newval);
cell->need_to_parse = TRUE;
}
for (i = 0; '\0' != _cell->value[i]; i++)
if (decimal_point == _cell->value[i])
count++;
/* ================================================ */
if (1 < count)
return;
}
static void
PriceParse (PriceCell *cell)
{
const char *newval;
char *oldval;
double amount;
/* parse the value and store it */
xaccParseAmount (newval, cell->monetary, &cell->amount, NULL);
SET ((&(cell->cell)), newval);
if (!cell->need_to_parse)
return;
oldval = cell->cell.value;
if (oldval == NULL)
oldval = "";
if (gnc_exp_parser_parse (cell->cell.value, &amount, NULL))
cell->amount = amount;
else
cell->amount = 0.0;
newval = xaccPriceCellPrintValue(cell);
/* If they are identical do nothing */
if (strcmp(newval, oldval) == 0)
return;
/* Otherwise, change it */
SET ((&(cell->cell)), newval);
}
/* ================================================ */
@ -143,29 +168,9 @@ PriceMV (BasicCell *_cell,
static void
PriceLeave (BasicCell *_cell)
{
PriceCell *cell = (PriceCell *) _cell;
char *newval;
char *oldval;
double amount;
PriceCell *cell = (PriceCell *) _cell;
oldval = _cell->value;
if (oldval == NULL)
oldval = "";
if (*oldval == '\0')
amount = 0.0;
else if (!xaccParseAmount (oldval, cell->monetary, &amount, NULL))
amount = 0.0;
cell->amount = amount;
newval = xaccPriceCellPrintValue(cell);
/* If they are identical do nothing */
if (strcmp(newval, oldval) == 0)
return;
/* Otherwise, change it */
SET ((&(cell->cell)), newval);
PriceParse (cell);
}
/* ================================================ */
@ -173,16 +178,11 @@ PriceLeave (BasicCell *_cell)
static char *
PriceHelp (BasicCell *bcell)
{
PriceCell *cell = (PriceCell *) bcell;
if ((bcell->value != NULL) && (bcell->value[0] != 0))
{
char *help_str;
const char *help_str;
if (xaccParseAmount(bcell->value, cell->monetary, NULL, NULL))
help_str = xaccPriceCellPrintValue(cell);
else
help_str = bcell->value;
help_str = bcell->value;
return g_strdup(help_str);
}
@ -220,6 +220,8 @@ xaccInitPriceCell (PriceCell *cell)
cell->is_currency = FALSE;
cell->shares_value = FALSE;
cell->need_to_parse = FALSE;
SET (&(cell->cell), "");
COLORIZE (cell, 0.0);
@ -230,7 +232,7 @@ xaccInitPriceCell (PriceCell *cell)
cell->cell.set_value = PriceSetValue;
cell->cell.get_help_value = PriceHelp;
xaccPriceGUIInit( cell);
xaccPriceGUIInit (cell);
}
/* ================================================ */
@ -244,16 +246,13 @@ xaccDestroyPriceCell (PriceCell *cell)
/* ================================================ */
static char *
static const char *
xaccPriceCellPrintValue (PriceCell *cell)
{
static char buff[PRTBUF];
GNCPrintAmountFlags flags = PRTSEP;
if (cell->blank_zero && DEQ(cell->amount, 0.0)) {
strcpy(buff, "");
return buff;
}
if (cell->blank_zero && DEQ(cell->amount, 0.0))
return "";
if (cell->shares_value)
flags |= PRTSHR;
@ -261,9 +260,7 @@ xaccPriceCellPrintValue (PriceCell *cell)
if (cell->is_currency)
flags |= PRTCUR;
xaccSPrintAmount(buff, cell->amount, flags, NULL);
return buff;
return xaccPrintAmount(cell->amount, flags, NULL);
}
/* ================================================ */
@ -274,24 +271,27 @@ xaccGetPriceCellValue (PriceCell *cell)
if (cell == NULL)
return 0.0;
PriceParse (cell);
return cell->amount;
}
void
xaccSetPriceCellValue (PriceCell * cell, double amount)
{
char *buff;
const char *buff;
if (cell == NULL)
return;
if (cell == NULL)
return;
cell->amount = amount;
buff = xaccPriceCellPrintValue (cell);
cell->amount = amount;
buff = xaccPriceCellPrintValue (cell);
cell->need_to_parse = FALSE;
SET (&(cell->cell), buff);
SET (&(cell->cell), buff);
/* set the cell color to red if the value is negative */
COLORIZE (cell, amount);
/* set the cell color to red if the value is negative */
COLORIZE (cell, amount);
}
void
@ -301,6 +301,7 @@ xaccSetPriceCellBlank (PriceCell *cell)
return;
cell->amount = 0.0;
cell->need_to_parse = FALSE;
SET (&(cell->cell), "");
@ -357,23 +358,14 @@ void xaccSetDebCredCellValue (PriceCell * debit,
PriceCell * credit,
double amount)
{
debit->cell.fg_color = 0xff0000;
credit->cell.fg_color = 0x0;
/* debits are positive, credits are negative */
if (amount > 0.0) {
xaccSetPriceCellValue (debit, amount);
xaccSetPriceCellValue (credit, 0.0);
if (!credit->blank_zero) {
SET(&credit->cell, "");
}
} else {
xaccSetPriceCellValue (debit, 0.0);
if (!debit->blank_zero) {
SET(&debit->cell, "");
}
xaccSetPriceCellValue (credit, -amount);
}
/* debits are positive, credits are negative */
if (amount > 0.0) {
xaccSetPriceCellValue (debit, amount);
xaccSetPriceCellValue (credit, 0.0);
} else {
xaccSetPriceCellValue (debit, 0.0);
xaccSetPriceCellValue (credit, -amount);
}
}
/* ================================================ */
@ -381,16 +373,16 @@ void xaccSetDebCredCellValue (PriceCell * debit,
static void
PriceSetValue (BasicCell *_cell, const char *str)
{
PriceCell *cell = (PriceCell *) _cell;
double amount;
PriceCell *cell = (PriceCell *) _cell;
double amount;
if (str == NULL)
str = "";
if (str == NULL)
str = "";
if (*str == '\0')
xaccSetPriceCellValue (cell, 0.0);
else if (xaccParseAmount (str, cell->monetary, &amount, NULL))
xaccSetPriceCellValue (cell, amount);
if (*str == '\0')
xaccSetPriceCellValue (cell, 0.0);
else if (gnc_exp_parser_parse (str, &amount, NULL))
xaccSetPriceCellValue (cell, amount);
}
/* --------------- end of file ---------------------- */

View File

@ -69,6 +69,8 @@ typedef struct _PriceCell
gboolean monetary; /* controls parsing of values */
gboolean is_currency; /* controls printint of values */
gboolean shares_value; /* true if a shares values */
gboolean need_to_parse; /* internal */
} PriceCell;
/* installs a callback to handle price recording */