From ba4acdfef1919ae27fc1c6b12822aa605f88676a Mon Sep 17 00:00:00 2001 From: John Ralls Date: Fri, 11 Mar 2016 15:03:19 -0800 Subject: [PATCH 1/5] Ensure that xferData->price_source is always set correctly. If the user doesn't tab out of the price window before pressing return or clicking OK gnc_xfer_price_update_cb isn't called, but it does call gnc_xfer_update_to_amount, which does get called by gnc_xfer_dialog_response_cb. --- src/gnome-utils/dialog-transfer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gnome-utils/dialog-transfer.c b/src/gnome-utils/dialog-transfer.c index 6b72a0a5ae..66d148aecc 100644 --- a/src/gnome-utils/dialog-transfer.c +++ b/src/gnome-utils/dialog-transfer.c @@ -1016,6 +1016,8 @@ gnc_xfer_update_to_amount (XferDialog *xferData) g_return_if_fail(xferData); + xferData->price_source = PRICE_SOURCE_USER_PRICE; + /* Get the amount editing controls of the dialog. */ amount_edit = GNC_AMOUNT_EDIT(xferData->amount_edit); price_edit = GNC_AMOUNT_EDIT(xferData->price_edit); @@ -1056,7 +1058,6 @@ gnc_xfer_price_update_cb(GtkWidget *widget, GdkEventFocus *event, XferDialog *xferData = data; gnc_xfer_update_to_amount (xferData); - xferData->price_source = PRICE_SOURCE_USER_PRICE; xferData->price_type = PRICE_TYPE_TRN; From e26e598cdc8f635d9a7700e8732b401d619e3dd5 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Fri, 11 Mar 2016 15:08:11 -0800 Subject: [PATCH 2/5] Check price_source precedence first to save computation. --- src/gnome-utils/dialog-transfer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gnome-utils/dialog-transfer.c b/src/gnome-utils/dialog-transfer.c index 66d148aecc..5e0b1ec7cb 100644 --- a/src/gnome-utils/dialog-transfer.c +++ b/src/gnome-utils/dialog-transfer.c @@ -1589,6 +1589,12 @@ update_price(XferDialog *xferData, PriceReq *pr) if (gnc_numeric_equal(pr->reverse ? gnc_numeric_invert(value) : value, price_value)) + if (gnc_price_get_source(pr->price) < xferData->price_source) + { + PINFO("Existing price is preferred, so won't supersede."); + gnc_price_unref (pr->price); + return; + } { PINFO("Same price for %s in %s", gnc_commodity_get_mnemonic(pr->from), @@ -1596,12 +1602,6 @@ update_price(XferDialog *xferData, PriceReq *pr) gnc_price_unref (pr->price); return; } - if (gnc_price_get_source(pr->price) < xferData->price_source) - { - PINFO("Existing price is preferred, so won't supersede."); - gnc_price_unref (pr->price); - return; - } gnc_price_begin_edit (pr->price); gnc_price_set_time (pr->price, pr->ts); gnc_price_set_typestr(pr->price, xferData->price_type); From c4ce44df64ed8ad3d83f369d9a0e2856ad3cfd90 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Fri, 11 Mar 2016 15:10:12 -0800 Subject: [PATCH 3/5] Test rounded values, but don't store them, to minimize jitter in prices. --- src/gnome-utils/dialog-transfer.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/gnome-utils/dialog-transfer.c b/src/gnome-utils/dialog-transfer.c index 5e0b1ec7cb..67813f43b6 100644 --- a/src/gnome-utils/dialog-transfer.c +++ b/src/gnome-utils/dialog-transfer.c @@ -1586,15 +1586,21 @@ update_price(XferDialog *xferData, PriceReq *pr) gnc_commodity *to = xferData->to_commodity; gnc_numeric value = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->price_edit)); gnc_numeric price_value = gnc_price_get_value(pr->price); + gnc_numeric rounded_pr_value = round_price(pr->from, pr->to, price_value); + gnc_numeric rounded_value; - if (gnc_numeric_equal(pr->reverse ? gnc_numeric_invert(value) : value, - price_value)) if (gnc_price_get_source(pr->price) < xferData->price_source) { PINFO("Existing price is preferred, so won't supersede."); gnc_price_unref (pr->price); return; } + + if (pr->reverse) + value = swap_commodities(&from, &to, value); + /* Test the rounded values for equality to minimize price-dithering. */ + rounded_value = round_price(from, to, value); + if (gnc_numeric_equal(rounded_value, rounded_pr_value)) { PINFO("Same price for %s in %s", gnc_commodity_get_mnemonic(pr->from), @@ -1605,10 +1611,7 @@ update_price(XferDialog *xferData, PriceReq *pr) gnc_price_begin_edit (pr->price); gnc_price_set_time (pr->price, pr->ts); gnc_price_set_typestr(pr->price, xferData->price_type); - if (pr->reverse) - gnc_price_set_value (pr->price, gnc_numeric_invert(value)); - else - gnc_price_set_value (pr->price, value); + gnc_price_set_value (pr->price, value); gnc_price_commit_edit (pr->price); PINFO("Updated price: 1 %s = %f %s", gnc_commodity_get_mnemonic(pr->from), From 1ca56c9d0df55037a7515f78dd81abed1fe9df95 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Fri, 11 Mar 2016 15:42:53 -0800 Subject: [PATCH 4/5] Ensure price is set when the amount is entered and user doesn't tab out. --- src/gnome-utils/dialog-transfer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gnome-utils/dialog-transfer.c b/src/gnome-utils/dialog-transfer.c index 67813f43b6..7d84370273 100644 --- a/src/gnome-utils/dialog-transfer.c +++ b/src/gnome-utils/dialog-transfer.c @@ -1748,6 +1748,8 @@ gnc_xfer_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data) gnc_xfer_update_to_amount(xferData); price_value = gnc_xfer_dialog_compute_price_value(xferData); + gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->price_edit), + price_value); *(xferData->exch_rate) = gnc_numeric_abs(price_value); } else From a4069037055d92755be154fc72da53ea0dc79fc8 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Fri, 11 Mar 2016 15:43:30 -0800 Subject: [PATCH 5/5] Ensure numerator is positive before checking if the value is < 1. --- src/gnome-utils/dialog-transfer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gnome-utils/dialog-transfer.c b/src/gnome-utils/dialog-transfer.c index 7d84370273..eefc5d1a3e 100644 --- a/src/gnome-utils/dialog-transfer.c +++ b/src/gnome-utils/dialog-transfer.c @@ -1631,6 +1631,7 @@ new_price(XferDialog *xferData, Timespec ts) /* We want to store currency rates such that the rate > 1 and commodity * prices in terms of a currency regardless of value. */ + value = gnc_numeric_abs(value); if (gnc_commodity_is_currency(from) && gnc_commodity_is_currency(to)) { if (value.num < value.denom)