r22735 - gnucash/trunk/src/register/ledger-core - Do a better job of prompting for an exchange rate only when needed.

Mike Alexander mta at code.gnucash.org
Wed Jan 30 00:22:38 EST 2013


Author: mta
Date: 2013-01-30 00:22:38 -0500 (Wed, 30 Jan 2013)
New Revision: 22735
Trac: http://svn.gnucash.org/trac/changeset/22735

Modified:
   gnucash/trunk/src/register/ledger-core/split-register-control.c
   gnucash/trunk/src/register/ledger-core/split-register-load.c
   gnucash/trunk/src/register/ledger-core/split-register-model.c
   gnucash/trunk/src/register/ledger-core/split-register-p.h
   gnucash/trunk/src/register/ledger-core/split-register.c
Log:
Do a better job of prompting for an exchange rate only when needed.
If the debit or credit value of a split changes, prompt for an exchange rate.
Don't prompt for an exchange rate in a register that doesn't have a rate cell
(and fix a bug so that it knows that portfolio registers don't have one).
If the transaction has been autofilled and edited start with a nearby rate
from the prices DB.  If it is an existing transaction start with the exchange
rate it already has.

Modified: gnucash/trunk/src/register/ledger-core/split-register-control.c
===================================================================
--- gnucash/trunk/src/register/ledger-core/split-register-control.c	2013-01-29 20:32:07 UTC (rev 22734)
+++ gnucash/trunk/src/register/ledger-core/split-register-control.c	2013-01-30 05:22:38 UTC (rev 22735)
@@ -220,6 +220,39 @@
     return TRUE;
 }
 
+/* Checks a cell for a debit or credit change to see if a new exchange
+ * rate is needed. */
+
+static gboolean
+gnc_split_register_check_debcred (SplitRegister *reg,
+                                  const char *cell_name)
+{
+    if ((gnc_cell_name_equal (cell_name, DEBT_CELL) &&
+            gnc_table_layout_get_cell_changed (reg->table->layout,
+                                               DEBT_CELL, FALSE)) ||
+         (gnc_cell_name_equal (cell_name, CRED_CELL) &&
+            gnc_table_layout_get_cell_changed (reg->table->layout,
+                                               CRED_CELL, FALSE)))
+    {
+        SRInfo *info = gnc_split_register_get_info (reg);
+        PriceCell *rate_cell = (PriceCell *) gnc_table_layout_get_cell (reg->table->layout,
+                                RATE_CELL);
+        if (gnc_split_reg_has_rate_cell(reg->type) && info->rate_reset != RATE_RESET_DONE)
+        {
+            /* Debit or credit amount changed, get a new exchange rate */
+            info->rate_reset = RATE_RESET_REQD;
+            if (info->auto_complete)
+            {
+                /* It's auto-filled, start with rate from price DB for the date
+                   of the transaction. */
+                gnc_price_cell_set_value (rate_cell, gnc_numeric_zero());
+            }
+        }
+    }
+    
+    return TRUE;
+}
+
 /* Checks a cell for an account change and takes any necessary action if
  * one has occurred. Returns TRUE if the check passes, FALSE if it fails. */
 static gboolean
@@ -228,7 +261,6 @@
 {
     SRInfo *info;
     ComboCell *cell = NULL;
-    PriceCell *rate_cell;
     Account* new_acct;
     char *name;
 
@@ -270,11 +302,11 @@
         return FALSE;
 
     /* See if we need to reset the exchange rate. */
-    rate_cell = (PriceCell *) gnc_table_layout_get_cell (reg->table->layout,
-                RATE_CELL);
-    if (rate_cell)
+    if (gnc_split_reg_has_rate_cell(reg->type))
     {
         Split         *split     = gnc_split_register_get_current_split(reg);
+        PriceCell     *rate_cell = (PriceCell *) gnc_table_layout_get_cell (reg->table->layout,
+                                                                            RATE_CELL);
         Account       *orig_acct = xaccSplitGetAccount(split);
         gnc_commodity *orig_com  = xaccAccountGetCommodity(orig_acct);
         gnc_commodity *last_com  = xaccAccountGetCommodity(info->rate_account);
@@ -294,7 +326,7 @@
 
             gnc_price_cell_set_value (rate_cell, gnc_numeric_zero());
             info->rate_account = new_acct;
-            info->rate_reset = TRUE;
+            info->rate_reset = RATE_RESET_REQD;
         }
         else
         {
@@ -310,14 +342,14 @@
                       gnc_num_dbg_to_string(orig_rate));
                 gnc_price_cell_set_value (rate_cell, orig_rate);
                 info->rate_account = new_acct;
-                info->rate_reset = FALSE;
+                info->rate_reset = RATE_RESET_NOT_REQD;
             }
             else
             {
                 DEBUG("Can't get rate. Using zero.");
                 gnc_price_cell_set_value (rate_cell, gnc_numeric_zero());
                 info->rate_account = new_acct;
-                info->rate_reset = TRUE;
+                info->rate_reset = RATE_RESET_REQD;
             }
         }
     }
@@ -480,7 +512,7 @@
     {
         info->change_confirmed = FALSE;
         info->rate_account = NULL;
-        info->rate_reset = FALSE;
+        info->rate_reset = RATE_RESET_NOT_REQD;
     }
 
     gnc_resume_gui_refresh ();
@@ -1115,6 +1147,13 @@
         LEAVE("account check failed");
         return FALSE;
     }
+    
+    /* See if we are leaving a debit or credit cell */
+    if (!gnc_split_register_check_debcred (reg, cell_name))
+    {
+        LEAVE("debit/credit check failed");
+        return FALSE;
+    }
 
     /* See if we are leaving an action field */
     if ((reg->type == STOCK_REGISTER) ||
@@ -1292,8 +1331,10 @@
     }
 
     /* See if we already have an exchange rate... */
+    info = gnc_split_register_get_info (reg);
     exch_rate = gnc_price_cell_get_value (rate_cell);
-    if (!gnc_numeric_zero_p(exch_rate) && !force_dialog)
+    if (!gnc_numeric_zero_p(exch_rate) && !force_dialog &&
+        info->rate_reset != RATE_RESET_REQD)
     {
         LEAVE("rate already non-zero");
         return FALSE;
@@ -1445,9 +1486,8 @@
      * _not_ the blank split, then return FALSE -- this is a "special"
      * gain/loss stock transaction.
      */
-    info = gnc_split_register_get_info (reg);
     if (gnc_numeric_zero_p(exch_rate) && !force_dialog && split &&
-            !info->rate_reset &&
+            info->rate_reset != RATE_RESET_REQD &&
             split != gnc_split_register_get_blank_split (reg))
     {
         LEAVE("gain/loss split; no exchange rate needed");
@@ -1470,7 +1510,7 @@
     gnc_price_cell_set_value (rate_cell, exch_rate);
     gnc_basic_cell_set_changed (&rate_cell->cell, TRUE);
     info->rate_account = xfer_acc;
-    info->rate_reset = FALSE;
+    info->rate_reset = RATE_RESET_DONE;
     LEAVE("set rate=%s", gnc_num_dbg_to_string(exch_rate));
     return FALSE;
 }
@@ -1672,6 +1712,7 @@
     {
         if (gnc_split_register_auto_completion (reg, dir, p_new_virt_loc))
         {
+            info->auto_complete = TRUE;
             LEAVE("auto-complete");
             return FALSE;
         }

Modified: gnucash/trunk/src/register/ledger-core/split-register-load.c
===================================================================
--- gnucash/trunk/src/register/ledger-core/split-register-load.c	2013-01-29 20:32:07 UTC (rev 22734)
+++ gnucash/trunk/src/register/ledger-core/split-register-load.c	2013-01-30 05:22:38 UTC (rev 22735)
@@ -365,6 +365,7 @@
 
         info->blank_split_guid = *xaccSplitGetGUID (blank_split);
         info->blank_split_edited = FALSE;
+        info->auto_complete = FALSE;
         DEBUG("created new blank_split=%p", blank_split);
 
         gnc_resume_gui_refresh ();

Modified: gnucash/trunk/src/register/ledger-core/split-register-model.c
===================================================================
--- gnucash/trunk/src/register/ledger-core/split-register-model.c	2013-01-29 20:32:07 UTC (rev 22734)
+++ gnucash/trunk/src/register/ledger-core/split-register-model.c	2013-01-30 05:22:38 UTC (rev 22735)
@@ -1137,7 +1137,11 @@
     Split *split, *osplit;
     Transaction *txn;
     gnc_numeric amount, value, convrate;
+    SRInfo *info = gnc_split_register_get_info (reg);
 
+    if (info->rate_reset == RATE_RESET_REQD && info->auto_complete)
+        return "0";
+        
     split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
     if (!split)
         return NULL;
@@ -1583,12 +1587,12 @@
     case TRADING_REGISTER:
     case GENERAL_LEDGER:
     case INCOME_LEDGER:
-    case PORTFOLIO_LEDGER:
     case SEARCH_LEDGER:
         return TRUE;
 
     case STOCK_REGISTER:
     case CURRENCY_REGISTER:
+    case PORTFOLIO_LEDGER:
     case RECEIVABLE_REGISTER:
     case PAYABLE_REGISTER:
     default:

Modified: gnucash/trunk/src/register/ledger-core/split-register-p.h
===================================================================
--- gnucash/trunk/src/register/ledger-core/split-register-p.h	2013-01-29 20:32:07 UTC (rev 22734)
+++ gnucash/trunk/src/register/ledger-core/split-register-p.h	2013-01-30 05:22:38 UTC (rev 22735)
@@ -31,6 +31,13 @@
 
 #define ACTION_BUY_STR  _("Buy")
 #define ACTION_SELL_STR _("Sell")
+
+typedef enum {
+    RATE_RESET_NOT_REQD = 0,
+    RATE_RESET_REQD     = 1,
+    RATE_RESET_DONE     = 2
+} RateReset_t;
+
 struct sr_info
 {
     /* The blank split at the bottom of the register */
@@ -91,8 +98,14 @@
      * split */
     gboolean change_confirmed;
 
-    /* true if the exchange rate has been reset on the current split */
-    gboolean rate_reset;
+    /* RATE_RESET_NOT_REQD => No exchange rate dialog needed for current split
+     * RATE_RESET_REQD => Need new exchange rate for current split
+     * RATE_RESET_DONE => Already got a new exchange rate for current split
+     */
+    RateReset_t rate_reset;
+    
+    /* true if the transaction being edited was auto-filled */
+    gboolean auto_complete;
 
     /* account on the current split when the exchange rate was last set */
     Account *rate_account;

Modified: gnucash/trunk/src/register/ledger-core/split-register.c
===================================================================
--- gnucash/trunk/src/register/ledger-core/split-register.c	2013-01-29 20:32:07 UTC (rev 22734)
+++ gnucash/trunk/src/register/ledger-core/split-register.c	2013-01-30 05:22:38 UTC (rev 22735)
@@ -1000,6 +1000,7 @@
             blank_split = xaccTransGetSplit(trans, 0);
             info->blank_split_guid = *xaccSplitGetGUID (blank_split);
             info->blank_split_edited = TRUE;
+            info->auto_complete = FALSE;
             DEBUG("replacement blank_split=%p", blank_split);
 
             /* NOTE: At this point, the blank transaction virtual cell is still
@@ -1114,6 +1115,7 @@
     {
         DEBUG("deleting blank split");
         info->blank_split_guid = *guid_null();
+        info->auto_complete = FALSE;
     }
     else
     {
@@ -1620,6 +1622,7 @@
                 info->last_date_entered = xaccTransGetDate (trans);
                 info->blank_split_guid = *guid_null ();
                 info->blank_split_edited = FALSE;
+                info->auto_complete = FALSE;
             }
 
             /* We have to clear the pending guid *before* committing the
@@ -1784,6 +1787,7 @@
         if (do_commit)
         {
             info->blank_split_guid = *guid_null ();
+            info->auto_complete = FALSE;
             blank_split = NULL;
             info->last_date_entered = xaccTransGetDate (trans);
         }
@@ -2806,6 +2810,7 @@
             pending_trans = NULL;
         }
         info->blank_split_guid = *guid_null ();
+        info->auto_complete = FALSE;
         blank_split = NULL;
     }
 



More information about the gnucash-changes mailing list