Make gnc-amount-edit.c use gnc_numerics.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3119 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Dave Peticolas
2000-11-03 08:43:55 +00:00
parent 3e48612a90
commit 134940aab9
5 changed files with 202 additions and 129 deletions

View File

@@ -415,78 +415,42 @@ gnc_default_price_print_info (void)
/* Utility function for printing non-negative amounts */
static int
PrintAmountInternal(char *buf, double val, const GNCPrintAmountInfo *info)
PrintAmountInternal(char *buf, gnc_numeric val, const GNCPrintAmountInfo *info)
{
int i, string_length, num_whole_digits;
int num_whole_digits;
struct lconv *lc = gnc_localeconv();
char decimal_point;
char temp_buf[50];
char temp_buf[64];
gnc_numeric whole;
g_assert (info != NULL);
/* check if we're printing infinity */
if (!finite(val)) {
strcpy (buf, "inf");
return 3;
if (gnc_numeric_check (val))
{
PWARN ("Bad numeric.");
*buf = '\0';
return 0;
}
/* print the absolute value */
if (val < 0.0)
val = ABS(val);
if (gnc_numeric_negative_p (val))
val = gnc_numeric_neg (val);
/* print the value without separators */
util_fptostr(temp_buf, val, info->max_decimal_places);
if (info->monetary)
decimal_point = lc->mon_decimal_point[0];
else
decimal_point = lc->decimal_point[0];
/* fix up the decimal place, if there is one */
string_length = strlen(temp_buf);
num_whole_digits = -1;
for (i = string_length - 1; i >= 0; i--)
if ((temp_buf[i] == '.') ||
(temp_buf[i] == lc->mon_decimal_point[0]) ||
(temp_buf[i] == lc->decimal_point[0]))
{
temp_buf[i] = decimal_point;
num_whole_digits = i;
break;
}
if (num_whole_digits < 0)
num_whole_digits = string_length; /* Can't find decimal place, it's
* a whole number */
/* just a quick check */
g_assert (num_whole_digits > 0);
/* Here we strip off trailing decimal zeros per the argument. */
if (info->max_decimal_places > 0)
/* calculate the integer part and the remainder */
whole = gnc_numeric_create (val.num / val.denom, 1);
val = gnc_numeric_sub (val, whole, val.denom, GNC_RND_NEVER);
if (gnc_numeric_check (val))
{
int max_delete;
char *p;
max_delete = info->max_decimal_places - info->min_decimal_places;
p = temp_buf + strlen(temp_buf) - 1;
while ((*p == '0') && (max_delete > 0))
{
*p-- = '\0';
max_delete--;
}
if (*p == decimal_point)
*p = '\0';
PWARN ("Problem with remainder.");
*buf = '\0';
return 0;
}
/* print the integer part without separators */
sprintf(temp_buf, "%lld", (long long) whole.num);
num_whole_digits = strlen (temp_buf);
if (!info->use_separators)
{
strcpy(buf, temp_buf);
}
strcpy (buf, temp_buf);
else
{
int group_count;
@@ -545,10 +509,72 @@ PrintAmountInternal(char *buf, double val, const GNCPrintAmountInfo *info)
*buf_ptr++ = *temp_ptr;
*buf_ptr = '\0';
g_strreverse(buf);
strcpy(buf_ptr, &temp_buf[num_whole_digits]);
} /* endif */
/* at this point, buf contains the whole part of the number */
/* If it's not decimal, print the fraction as an expression */
if (!is_decimal_fraction (val.denom, NULL))
{
if (!gnc_numeric_zero_p (val))
{
val = gnc_numeric_reduce (val);
printf (temp_buf, " + %lld / %lld",
(long long) val.num,
(long long) val.denom);
strcat (buf, temp_buf);
}
}
else
{
guint8 num_decimal_places = 0;
char *temp_ptr = temp_buf;
*temp_ptr++ = info->monetary ?
lc->mon_decimal_point[0] : lc->decimal_point[0];
while (!gnc_numeric_zero_p (val) && val.denom != 1)
{
gint64 digit;
val.denom = val.denom / 10;
digit = val.num / val.denom;
*temp_ptr++ = digit + '0';
num_decimal_places++;
val.num = val.num - (digit * val.denom);
}
/* add in needed zeros */
while (num_decimal_places < info->min_decimal_places)
{
*temp_ptr++ = '0';
num_decimal_places++;
}
/* cap the end and move to the last character */
*temp_ptr-- = '\0';
/* Here we strip off trailing decimal zeros per the argument. */
while (*temp_ptr == '0' && num_decimal_places > info->min_decimal_places)
{
*temp_ptr-- = '\0';
num_decimal_places--;
}
if (num_decimal_places > info->max_decimal_places)
{
PWARN ("max_decimal_places too small");
}
if (num_decimal_places > 0)
strcat (buf, temp_buf);
}
return strlen(buf);
}
@@ -651,7 +677,10 @@ DxaccSPrintAmount (char * bufp, double val, GNCPrintAmountInfo info)
bufp = gnc_stpcpy(bufp, "(");
/* Now print the value */
bufp += PrintAmountInternal(bufp, ABS(val), &info);
{
gnc_numeric n = double_to_gnc_numeric (ABS (val), 10000, GNC_RND_ROUND);
bufp += PrintAmountInternal(bufp, n, &info);
}
/* Now see if we print parentheses */
if (print_sign && (sign_posn == 0))

View File

@@ -130,15 +130,15 @@ fi_to_gui(FinCalcDialog *fcd)
snprintf(string, sizeof(string), "%u", fcd->financial_info.npp);
gtk_entry_set_text(GTK_ENTRY(fcd->amounts[PAYMENT_PERIODS]), string);
gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT(fcd->amounts[INTEREST_RATE]),
fcd->financial_info.ir);
gnc_amount_edit_set_damount (GNC_AMOUNT_EDIT(fcd->amounts[INTEREST_RATE]),
fcd->financial_info.ir);
gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT(fcd->amounts[PRESENT_VALUE]),
fcd->financial_info.pv);
gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT(fcd->amounts[PERIODIC_PAYMENT]),
fcd->financial_info.pmt);
gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT(fcd->amounts[FUTURE_VALUE]),
-fcd->financial_info.fv);
gnc_amount_edit_set_damount (GNC_AMOUNT_EDIT(fcd->amounts[PRESENT_VALUE]),
fcd->financial_info.pv);
gnc_amount_edit_set_damount (GNC_AMOUNT_EDIT(fcd->amounts[PERIODIC_PAYMENT]),
fcd->financial_info.pmt);
gnc_amount_edit_set_damount (GNC_AMOUNT_EDIT(fcd->amounts[FUTURE_VALUE]),
-fcd->financial_info.fv);
total = fcd->financial_info.npp * fcd->financial_info.pmt;
DxaccSPrintAmount (string, total, gnc_default_print_info (FALSE));
@@ -175,14 +175,14 @@ gui_to_fi(FinCalcDialog *fcd)
string = gtk_entry_get_text(GTK_ENTRY(fcd->amounts[PAYMENT_PERIODS]));
fcd->financial_info.npp = strtol(string, NULL, 10);
fcd->financial_info.ir =
gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(fcd->amounts[INTEREST_RATE]));
gnc_amount_edit_get_damount(GNC_AMOUNT_EDIT(fcd->amounts[INTEREST_RATE]));
fcd->financial_info.pv =
gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(fcd->amounts[PRESENT_VALUE]));
gnc_amount_edit_get_damount(GNC_AMOUNT_EDIT(fcd->amounts[PRESENT_VALUE]));
fcd->financial_info.pmt =
gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(fcd->amounts[PERIODIC_PAYMENT]));
gnc_amount_edit_get_damount(GNC_AMOUNT_EDIT(fcd->amounts[PERIODIC_PAYMENT]));
fcd->financial_info.fv =
gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(fcd->amounts[FUTURE_VALUE]));
gnc_amount_edit_get_damount(GNC_AMOUNT_EDIT(fcd->amounts[FUTURE_VALUE]));
fcd->financial_info.fv = -fcd->financial_info.fv;
i = gnc_option_menu_get_active(fcd->compounding_menu);
@@ -358,7 +358,7 @@ can_calc_value(FinCalcDialog *fcd, FinCalcValue value, int *error_item)
case PRESENT_VALUE:
case PERIODIC_PAYMENT:
case FUTURE_VALUE:
dvalue = gnc_amount_edit_get_amount
dvalue = gnc_amount_edit_get_damount
(GNC_AMOUNT_EDIT (fcd->amounts[INTEREST_RATE]));
if (DEQ(dvalue, 0.0))
{

View File

@@ -266,12 +266,14 @@ gnc_xfer_dialog_curr_acct_activate(XferDialog *xferData)
gtk_combo_set_popdown_strings(GTK_COMBO(xferData->curr_acct_combo),
curr_accts_name_list);
gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->price_edit), 0.0);
gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->price_edit),
gnc_numeric_zero ());
entry = GTK_ENTRY(gnc_amount_edit_gtk_entry
(GNC_AMOUNT_EDIT(xferData->price_edit)));
gtk_entry_set_text(entry, "");
gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->to_amount_edit), 0.0);
gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->to_amount_edit),
gnc_numeric_zero ());
entry = GTK_ENTRY(gnc_amount_edit_gtk_entry
(GNC_AMOUNT_EDIT(xferData->to_amount_edit)));
gtk_entry_set_text(entry, "");
@@ -425,21 +427,19 @@ gnc_xfer_amount_update_cb(GtkWidget *widget, GdkEventFocus *event,
currency = xaccAccountGetCurrency(account);
gnc_amount_edit_set_currency (GNC_AMOUNT_EDIT (xferData->amount_edit),
gnc_commodity_get_printname(currency));
gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->amount_edit));
if((from != NULL) && (to != NULL))
{
if(!xaccAccountsHaveCommonCurrency(from, to))
{
amount = gnc_amount_edit_get_amount
amount = gnc_amount_edit_get_damount
(GNC_AMOUNT_EDIT(xferData->amount_edit));
price = gnc_amount_edit_get_amount
price = gnc_amount_edit_get_damount
(GNC_AMOUNT_EDIT(xferData->price_edit));
to_amount = amount / price;
gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->to_amount_edit),
to_amount);
gnc_amount_edit_set_damount(GNC_AMOUNT_EDIT(xferData->to_amount_edit),
to_amount);
}
}
@@ -462,16 +462,13 @@ gnc_xfer_price_update_cb(GtkWidget *widget, GdkEventFocus *event,
currency = xaccAccountGetCurrency(account);
gnc_amount_edit_set_currency (GNC_AMOUNT_EDIT (xferData->price_edit),
gnc_commodity_get_printname(currency));
gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->price_edit));
amount = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->amount_edit));
price = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->price_edit));
amount = gnc_amount_edit_get_damount(GNC_AMOUNT_EDIT(xferData->amount_edit));
price = gnc_amount_edit_get_damount(GNC_AMOUNT_EDIT(xferData->price_edit));
to_amount = amount / price;
gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->to_amount_edit),
to_amount);
gnc_amount_edit_set_damount(GNC_AMOUNT_EDIT(xferData->to_amount_edit),
to_amount);
return FALSE;
}
@@ -492,16 +489,13 @@ gnc_xfer_to_amount_update_cb(GtkWidget *widget, GdkEventFocus *event,
currency = xaccAccountGetCurrency(account);
gnc_amount_edit_set_currency (GNC_AMOUNT_EDIT (xferData->to_amount_edit),
gnc_commodity_get_printname(currency));
gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->to_amount_edit));
amount = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->amount_edit));
to_amount = gnc_amount_edit_get_amount
amount = gnc_amount_edit_get_damount(GNC_AMOUNT_EDIT(xferData->amount_edit));
to_amount = gnc_amount_edit_get_damount
(GNC_AMOUNT_EDIT(xferData->to_amount_edit));
price = amount / to_amount;
gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->price_edit), price);
gnc_amount_edit_set_damount(GNC_AMOUNT_EDIT(xferData->price_edit), price);
return FALSE;
}
@@ -598,10 +592,8 @@ gnc_xfer_dialog_set_amount(XferDialog *xferData, double amount)
currency = xaccAccountGetCurrency(account);
gnc_amount_edit_set_currency (GNC_AMOUNT_EDIT (xferData->amount_edit),
gnc_commodity_get_printname(currency));
gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (xferData->amount_edit), amount);
gnc_amount_edit_set_damount (GNC_AMOUNT_EDIT (xferData->amount_edit),
amount);
}
@@ -672,7 +664,7 @@ gnc_xfer_dialog_ok_cb(GtkWidget * widget, gpointer data)
curr_trans = !gnc_commodity_equiv(from_currency, to_currency);
amount = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->amount_edit));
amount = gnc_amount_edit_get_damount(GNC_AMOUNT_EDIT(xferData->amount_edit));
time = gnc_date_edit_get_date(GNC_DATE_EDIT(xferData->date_entry));
@@ -718,7 +710,7 @@ gnc_xfer_dialog_ok_cb(GtkWidget * widget, gpointer data)
return;
}
to_amount = gnc_amount_edit_get_amount
to_amount = gnc_amount_edit_get_damount
(GNC_AMOUNT_EDIT(xferData->to_amount_edit));
/* from -> curr transaction */

View File

@@ -122,9 +122,9 @@ static void
gnc_amount_edit_init (GNCAmountEdit *gae)
{
gae->need_to_parse = FALSE;
gae->amount = 0.0;
gae->amount = gnc_numeric_zero ();
gae->print_info = gnc_default_print_info (FALSE);
gae->currency = NULL;
gae->fraction = 0;
gae->evaluate_on_enter = FALSE;
}
@@ -138,9 +138,6 @@ gnc_amount_edit_destroy (GtkObject *object)
gae = GNC_AMOUNT_EDIT (object);
g_free(gae->currency);
gae->currency = NULL;
if (GTK_OBJECT_CLASS (parent_class)->destroy)
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
@@ -249,7 +246,6 @@ gnc_amount_edit_evaluate (GNCAmountEdit *gae)
const char *string;
char *error_loc;
gnc_numeric amount;
double damount;
gboolean ok;
g_return_val_if_fail(gae != NULL, FALSE);
@@ -266,13 +262,16 @@ gnc_amount_edit_evaluate (GNCAmountEdit *gae)
if (ok)
{
damount = gnc_numeric_to_double (amount);
gnc_numeric old_amount = gae->amount;
if (!DEQ(damount, gae->amount))
if (gae->fraction > 0)
amount = gnc_numeric_convert (amount, gae->fraction, GNC_RND_ROUND);
gnc_amount_edit_set_amount (gae, amount);
if (!gnc_numeric_equal (amount, old_amount))
gtk_signal_emit (GTK_OBJECT (gae), amount_edit_signals [AMOUNT_CHANGED]);
gnc_amount_edit_set_amount (gae, damount);
return TRUE;
}
@@ -293,15 +292,35 @@ gnc_amount_edit_evaluate (GNCAmountEdit *gae)
* parsing the epxression if necessary. The result of parsing
* replaces the expression.
*/
double
gnc_numeric
gnc_amount_edit_get_amount (GNCAmountEdit *gae)
{
g_return_val_if_fail(gae != NULL, gnc_numeric_zero ());
g_return_val_if_fail(GNC_IS_AMOUNT_EDIT(gae), gnc_numeric_zero ());
gnc_amount_edit_evaluate (gae);
return gae->amount;
}
/**
* gnc_amount_edit_get_amount:
* @gae: The GNCAmountEdit widget
*
* Returns the amount entered in the GNCAmountEdit widget,
* parsing the epxression if necessary. The result of parsing
* replaces the expression.
*/
double
gnc_amount_edit_get_damount (GNCAmountEdit *gae)
{
g_return_val_if_fail(gae != NULL, 0.0);
g_return_val_if_fail(GNC_IS_AMOUNT_EDIT(gae), 0.0);
gnc_amount_edit_evaluate (gae);
return gae->amount;
return gnc_numeric_to_double (gae->amount);
}
@@ -313,21 +332,48 @@ gnc_amount_edit_get_amount (GNCAmountEdit *gae)
* Returns nothing.
*/
void
gnc_amount_edit_set_amount (GNCAmountEdit *gae, double amount)
gnc_amount_edit_set_amount (GNCAmountEdit *gae, gnc_numeric amount)
{
const char * amount_string;
g_return_if_fail(gae != NULL);
g_return_if_fail(GNC_IS_AMOUNT_EDIT(gae));
g_return_if_fail(!gnc_numeric_check (amount));
gae->amount = amount;
gae->need_to_parse = FALSE;
amount_string = DxaccPrintAmount (amount, gae->print_info);
amount_string = DxaccPrintAmount (gnc_numeric_to_double(amount),
gae->print_info);
gtk_entry_set_text (GTK_ENTRY (gae->amount_entry), amount_string);
}
/**
* gnc_amount_edit_set_amount:
* @gae: The GNCAmountEdit widget
* @amount: The amount to set
*
* Returns nothing.
*/
void
gnc_amount_edit_set_damount (GNCAmountEdit *gae, double damount)
{
gnc_numeric amount;
int fraction;
g_return_if_fail(gae != NULL);
g_return_if_fail(GNC_IS_AMOUNT_EDIT(gae));
if (gae->fraction > 0)
fraction = gae->fraction;
else
fraction = 100000;
amount = double_to_gnc_numeric (damount, fraction, GNC_RND_ROUND);
gnc_amount_edit_set_amount (gae, amount);
}
/**
* gnc_amount_edit_set_print_flags:
@@ -349,20 +395,21 @@ gnc_amount_edit_set_print_info (GNCAmountEdit *gae,
/**
* gnc_amount_edit_set_currency:
* gnc_amount_edit_set_fraction:
* @gae: The GNCAmountEdit widget
* @currency: The currency to set
* @fraction: The fraction to set
*
* Returns nothing.
*/
void
gnc_amount_edit_set_currency (GNCAmountEdit *gae, const char * currency)
gnc_amount_edit_set_fraction (GNCAmountEdit *gae, int fraction)
{
g_return_if_fail(gae != NULL);
g_return_if_fail(GNC_IS_AMOUNT_EDIT(gae));
g_free (gae->currency);
currency = g_strdup (currency);
fraction = MAX (0, fraction);
gae->fraction = fraction;
}

View File

@@ -29,6 +29,7 @@
#include <gnome.h>
#include "gnc-numeric.h"
#include "gnc-ui-util.h"
BEGIN_GNOME_DECLS
@@ -47,9 +48,10 @@ typedef struct
gboolean need_to_parse;
GNCPrintAmountInfo print_info;
char *currency;
double amount;
gnc_numeric amount;
int fraction;
gboolean evaluate_on_enter;
@@ -67,17 +69,20 @@ GtkWidget *gnc_amount_edit_new (void);
GtkWidget *gnc_amount_edit_gtk_entry (GNCAmountEdit *gae);
void gnc_amount_edit_set_amount (GNCAmountEdit *gae, double amount);
void gnc_amount_edit_set_amount (GNCAmountEdit *gae,
gnc_numeric amount);
void gnc_amount_edit_set_damount (GNCAmountEdit *gae,
double amount);
double gnc_amount_edit_get_amount (GNCAmountEdit *gae);
gnc_numeric gnc_amount_edit_get_amount (GNCAmountEdit *gae);
double gnc_amount_edit_get_damount (GNCAmountEdit *gae);
gboolean gnc_amount_edit_evaluate (GNCAmountEdit *gae);
void gnc_amount_edit_set_print_info (GNCAmountEdit *gae,
GNCPrintAmountInfo print_info);
void gnc_amount_edit_set_print_info (GNCAmountEdit *gae,
GNCPrintAmountInfo print_info);
void gnc_amount_edit_set_currency (GNCAmountEdit *gae,
const char * currency);
void gnc_amount_edit_set_fraction (GNCAmountEdit *gae, int fraction);
void gnc_amount_edit_set_evaluate_on_enter (GNCAmountEdit *gae,
gboolean evaluate_on_enter);