gnucash master: Book-Currency Feature step 6

J.Alex Aycinena alex.aycinena at code.gnucash.org
Sun Jul 9 15:25:09 EDT 2017


Updated	 via  https://github.com/Gnucash/gnucash/commit/2020bee0 (commit)
	from  https://github.com/Gnucash/gnucash/commit/a7f1f9cd (commit)



commit 2020bee03b5e92529f0f8377c487e2b163124561
Author: Alex Aycinena <alex.aycinena at gmail.com>
Date:   Sun Jul 9 12:19:36 2017 -0700

    Book-Currency Feature step 6
    
    Modify File->Properties dialog to maintain a default gain/loss account in a book KVP.
    
    The changes made are:
    
            app-utils/app-utils.scm - define items related to book default gain/loss
            acct
            app-utils/business-prefs.scm - define items related to book default
            gain/loss acct;re-arrange sequence of options to make default (neither)
            first
        app-utils/gnc-ui-util.c - refine gnc_book_get_default_gains_policy to check
            for hidden and/or placeholder status
            app-utils/option-util.c & h - define items related to book default gain/loss
            acct
            app-utils/options.scm - add functionality related to book default gain/loss
            acct
        app-utils/test/test-gnc-ui-util.c - for gnc_book_get_default_gains_policy,
            add tests to check for hidden and/or placeholder status
            app-utils/test/test-option-util.cpp - add tests related to book default
            gain/loss acct
            engine/engine.i - define item related to book default gain/loss acct
            gnome-utils/dialog-options.c & h - add functionality related to book default
            gain/loss acct and rearrange dialog layout; make gain/loss acct widget
            refresh on account maintenance
        gnome-utils/gnc-main-window.c - only allow one book-option dialog if called
            from file->properties
            gnome-utils/gtkbuilder/dialog-options.glade - increase dialog height to
            accomodate book default gain/loss acct widget; add tooltip text for
            dialog buttons
        gnome/assistant-hierarchy.c - change sequence of pages: book options before
            currency selection; if book currency selected, currency also selected
        gnome/gtkbuilder/assistant-hierarchy.glade - increase dialog height to
            accomodate book default gain/loss acct widget

diff --git a/src/app-utils/app-utils.scm b/src/app-utils/app-utils.scm
index 295c0fb..f098f9c 100644
--- a/src/app-utils/app-utils.scm
+++ b/src/app-utils/app-utils.scm
@@ -123,9 +123,11 @@
 (export gnc:currency-accounting-option-get-default-curr)
 (export gnc:currency-accounting-option-get-policy-doc-string)
 (export gnc:currency-accounting-option-get-default-policy)
+(export gnc:currency-accounting-option-get-gain-loss-account-doc-string)
 (export gnc:currency-accounting-option-selected-method)
 (export gnc:currency-accounting-option-selected-currency)
 (export gnc:currency-accounting-option-selected-policy)
+(export gnc:currency-accounting-option-selected-gain-loss-account)
 
 (export gnc:color->html)
 (export gnc:color-option->html)
@@ -350,12 +352,14 @@
 (define gnc:*option-name-currency-accounting* OPTION-NAME-CURRENCY-ACCOUNTING)
 (define gnc:*option-name-book-currency* OPTION-NAME-BOOK-CURRENCY)
 (define gnc:*option-name-default-gains-policy* OPTION-NAME-DEFAULT-GAINS-POLICY)
+(define gnc:*option-name-default-gain-loss-account* OPTION-NAME-DEFAULT-GAINS-LOSS-ACCT-GUID)
 (define gnc:*option-name-auto-readonly-days* OPTION-NAME-AUTO-READONLY-DAYS)
 (define gnc:*option-name-num-field-source* OPTION-NAME-NUM-FIELD-SOURCE)
 
 (export gnc:*option-section-accounts* gnc:*option-name-trading-accounts*
-        gnc:*option-name-currency-accounting*
-        gnc:*option-name-book-currency* gnc:*option-name-default-gains-policy*
+        gnc:*option-name-currency-accounting* gnc:*option-name-book-currency*
+        gnc:*option-name-default-gains-policy*
+        gnc:*option-name-default-gain-loss-account*
         gnc:*option-name-auto-readonly-days* gnc:*option-name-num-field-source*)
 
 (define gnc:*option-section-budgeting* OPTION-SECTION-BUDGETING)
diff --git a/src/app-utils/business-prefs.scm b/src/app-utils/business-prefs.scm
index 257438e..93d10ca 100644
--- a/src/app-utils/business-prefs.scm
+++ b/src/app-utils/business-prefs.scm
@@ -151,19 +151,21 @@
     (N_ "Select the currency accounting method to use for transactions involving more than one currency or commodity.")
     'neither
     (list
+      (vector 'neither
+              (N_ "Use neither Trading Accounts nor a Book Currency")
+              (N_ "Check to use neither trading accounts nor a book-currency for transactions involving more than one currency or commodity."))
       (vector 'trading
               (N_ "Use Trading Accounts")
               (N_ "Check to have trading accounts used for transactions involving more than one currency or commodity."))
       (vector 'book-currency
-              (N_ "Use a Book-Currency")
-              (N_ "Check to use a book-currency for transactions involving more than one currency or commodity."))
-      (vector 'neither
-              (N_ "Use neither Trading Accounts nor a Book-Currency")
-              (N_ "Check to use neither trading accounts nor a book-currency for transactions involving more than one currency or commodity.")))
+              (N_ "Use a Book Currency")
+              (N_ "Check to use a book-currency for transactions involving more than one currency or commodity.")))
     (N_ "Select the book-currency which is to be used to track costs of transactions involving currencies or commodities other than the book-currency.")
     (gnc-default-currency)
     (N_ "Select the default gains policy; this policy will be used unless over-ridden at the account level.")
-    'fifo))
+    'fifo
+    (N_ "Select the default gains/loss account (income or expense account, in book-currency, neither placeholder nor hidden); this account will be used unless over-ridden at the account level. If one is not selected, an account will be created as needed."))
+ )
 
   ;; Budgeting Tab
 
diff --git a/src/app-utils/gnc-ui-util.c b/src/app-utils/gnc-ui-util.c
index e09bdb7..05abd1c 100644
--- a/src/app-utils/gnc-ui-util.c
+++ b/src/app-utils/gnc-ui-util.c
@@ -368,7 +368,8 @@ gnc_book_get_default_gains_policy (QofBook *book)
 /** Returns pointer to default gain/loss account for book or NULL; determines
   * that both book-currency and default gain/loss policy KVPs exist and that
   * both are valid, a requirement for the 'book-currency' currency accounting
-  * method to apply. */
+  * method to apply. Also, account must not be hidden or a placeholder, and
+  * must be of same currency as book-currency and income or expense type */
 Account *
 gnc_book_get_default_gain_loss_acct (QofBook *book)
 {
@@ -380,7 +381,20 @@ gnc_book_get_default_gain_loss_acct (QofBook *book)
         gains_account = xaccAccountLookup
                         (qof_book_get_default_gain_loss_acct_guid (book), book);
 
-    return gains_account;
+    if (gains_account &&
+        !xaccAccountGetPlaceholder(gains_account) &&
+        !xaccAccountGetHidden(gains_account) &&
+        (gnc_commodity_equal(xaccAccountGetCommodity(gains_account),
+                                    gnc_book_get_book_currency(book))) &&
+        ((xaccAccountGetType(gains_account) == ACCT_TYPE_INCOME) ||
+            (xaccAccountGetType(gains_account) == ACCT_TYPE_EXPENSE)))
+    {
+        return gains_account;
+    }
+    else
+    {
+        return NULL;
+    }
 }
 
 Account *
diff --git a/src/app-utils/option-util.c b/src/app-utils/option-util.c
index 85eab06..97ca521 100644
--- a/src/app-utils/option-util.c
+++ b/src/app-utils/option-util.c
@@ -114,9 +114,11 @@ struct _Getters
     SCM currency_accounting_option_default_currency;
     SCM currency_accounting_option_policy_doc_string;
     SCM currency_accounting_option_default_policy;
+    SCM currency_accounting_option_gain_loss_account_doc_string;
     SCM currency_accounting_option_method;
     SCM currency_accounting_option_book_currency;
     SCM currency_accounting_option_selected_default_policy;
+    SCM currency_accounting_option_selected_default_gain_loss_account;
 };
 
 
@@ -608,12 +610,16 @@ initialize_getters(void)
         scm_c_eval_string("gnc:currency-accounting-option-get-policy-doc-string");
     getters.currency_accounting_option_default_policy =
         scm_c_eval_string("gnc:currency-accounting-option-get-default-policy");
+    getters.currency_accounting_option_gain_loss_account_doc_string =
+        scm_c_eval_string("gnc:currency-accounting-option-get-gain-loss-account-doc-string");
     getters.currency_accounting_option_method =
         scm_c_eval_string("gnc:currency-accounting-option-selected-method");
     getters.currency_accounting_option_book_currency =
         scm_c_eval_string("gnc:currency-accounting-option-selected-currency");
     getters.currency_accounting_option_selected_default_policy =
         scm_c_eval_string("gnc:currency-accounting-option-selected-policy");
+    getters.currency_accounting_option_selected_default_gain_loss_account =
+        scm_c_eval_string("gnc:currency-accounting-option-selected-gain-loss-account");
 
     getters_initialized = TRUE;
 }
@@ -2788,6 +2794,26 @@ gnc_currency_accounting_option_get_default_policy(GNCOption *option)
 }
 
 
+/********************************************************************\
+ * gnc_currency_accounting_option_gain_loss_account_documentation   *
+ *   returns the malloc'ed documentation string for account         *
+ *   selector of the currency-accounting option, or NULL if it      *
+ *   can't be retrieved.                                            *
+ *                                                                  *
+ * Args: option - the GNCOption                                     *
+ * Returns: malloc'ed char * or NULL                                *
+\********************************************************************/
+char *
+gnc_currency_accounting_option_gain_loss_account_documentation(GNCOption *option)
+{
+    initialize_getters();
+
+    return gnc_scm_call_1_to_string
+              (getters.currency_accounting_option_gain_loss_account_doc_string,
+                                     option->guile_option);
+}
+
+
 /*******************************************************************\
  * gnc_currency_accounting_option_value_get_method                 *
  *   get the currency accounting method of the option as a symbol  *
@@ -2838,6 +2864,25 @@ gnc_currency_accounting_option_value_get_default_policy (SCM option_value)
 }
 
 /*******************************************************************\
+ * gnc_currency_accounting_option_value_get_default_account        *
+ *   get the default gain/loss account if book-currency is the     *
+ *   currency accounting method, if one is specified, of the       *
+ *   option as a symbol                                            *
+ *                                                                 *
+ * Args: option_value - option value to get method of              *
+ * Return: SCM value                                               *
+\*******************************************************************/
+SCM
+gnc_currency_accounting_option_value_get_default_account (SCM option_value)
+{
+    initialize_getters();
+
+    return scm_call_1
+        (getters.currency_accounting_option_selected_default_gain_loss_account,
+          option_value);
+}
+
+/*******************************************************************\
  * gnc_option_db_set_option_selectable_by_name                     *
  *   set the sensitivity of the option widget                      *
  *                                                                 *
diff --git a/src/app-utils/option-util.h b/src/app-utils/option-util.h
index 4366ccb..d3040e5 100644
--- a/src/app-utils/option-util.h
+++ b/src/app-utils/option-util.h
@@ -258,9 +258,11 @@ char * gnc_currency_accounting_option_currency_documentation(GNCOption *option);
 SCM gnc_currency_accounting_option_get_default_currency(GNCOption *option);
 char * gnc_currency_accounting_option_policy_documentation(GNCOption *option);
 SCM gnc_currency_accounting_option_get_default_policy(GNCOption *option);
+char * gnc_currency_accounting_option_gain_loss_account_documentation(GNCOption *option);
 SCM gnc_currency_accounting_option_value_get_method (SCM option_value);
 SCM gnc_currency_accounting_option_value_get_book_currency (SCM option_value);
 SCM gnc_currency_accounting_option_value_get_default_policy (SCM option_value);
+SCM gnc_currency_accounting_option_value_get_default_account (SCM option_value);
 
 void gnc_option_db_set_option_selectable_by_name(SCM guile_options,
         const char *section,
diff --git a/src/app-utils/options.scm b/src/app-utils/options.scm
index 6e4ce70..a0ced62 100644
--- a/src/app-utils/options.scm
+++ b/src/app-utils/options.scm
@@ -1401,6 +1401,7 @@
          default-book-currency-value
          default-cap-gains-policy-documentation-string
          default-cap-gains-policy-value
+         default-gains-loss-account-documentation-string
         )
   (define (legal-val val p-vals)
     (cond ((null? p-vals) #f)
@@ -1433,6 +1434,38 @@
   (define (scm->currency currency)
     (currency-lookup currency))
 
+  (define (valid-gains-loss-account? book-currency gains-loss-account-guid)
+  ;; xaccAccountLookup returns Account if guid valid otherwise NULL; also must
+  ;; be in book-currency, income or expense, and not placeholder nor hidden
+    (let* ((account (xaccAccountLookup gains-loss-account-guid
+                                                    (gnc-get-current-book)))
+           (hidden? (if account
+                        (xaccAccountIsHidden account)
+                        #t))
+           (placeholder? (if account
+                             (xaccAccountGetPlaceholder account)
+                             #t))
+           (account-type (if account
+                             (xaccAccountGetType account)
+                             #f))
+           (income-or-expense? (if (and account account-type)
+                                   (or (= ACCT-TYPE-INCOME account-type)
+                                       (= ACCT-TYPE-EXPENSE account-type))
+                                   #f))
+           (commodity-eq-book-curr? (if account
+                                        (gnc-commodity-equal
+                                          (currency-lookup book-currency)
+                                          (xaccAccountGetCommodity account))
+                                        #f))
+          )
+          (if (and account
+                   (not hidden?)
+                   (not placeholder?)
+                   income-or-expense?
+                   commodity-eq-book-curr?)
+              #t
+              #f)))
+
   (let* ((value (if (eq? 'book-currency default-radiobutton-value)
                     (cons default-radiobutton-value
                           (cons default-book-currency-value
@@ -1446,22 +1479,25 @@
          (book-currency-path (list gnc:*option-section-accounts*
                                    gnc:*option-name-book-currency*))
          (gains-policy-path (list gnc:*option-section-accounts*
-                                  gnc:*option-name-default-gains-policy*)))
+                                  gnc:*option-name-default-gains-policy*))
+         (gains-loss-account-path (list gnc:*option-section-accounts*
+                                  gnc:*option-name-default-gain-loss-account*)))
     (gnc:make-option
      section name sort-tag 'currency-accounting
      radiobutton-documentation-string
-     (lambda () value)
+     (lambda () value) ;; getter
      (lambda (x)
        (if (legal-val (car x) ok-radiobutton-values)
            (set! value x)
-           (gnc:error "Illegal Radiobutton option set")))
+           (gnc:error "Illegal Radiobutton option set"))) ;;setter
      (lambda () (if (eq? 'book-currency default-radiobutton-value)
                     (cons default-radiobutton-value
                           (cons default-book-currency-value
-                                (cons default-cap-gains-policy-value '())))
-                    (cons default-radiobutton-value '())))
+                                (cons default-cap-gains-policy-value
+                                      (cons '() '()))))
+                    (cons default-radiobutton-value '()))) ;; default-getter
      (gnc:restore-form-generator value->string)
-     (lambda (b p)
+     (lambda (b p) ;; scm->kvp
        (if (eq? 'book-currency (car value))
            (begin
              ;; Currency = selected currency
@@ -1473,11 +1509,17 @@
              (qof-book-set-option
                 b
                 (symbol->string (caddr value))
-                gains-policy-path))
+                gains-policy-path)
+             ;; Default Gains Account = if selected, selected account
+             (if (car (cdddr value))
+                 (qof-book-set-option
+                    b
+                    (car (cdddr value))
+                    gains-loss-account-path)))
            (if (eq? 'trading (car value))
                ;; Use Trading Accounts = "t"
                (qof-book-set-option b "t" trading-accounts-path))))
-     (lambda (b p)
+     (lambda (b p) ;; kvp->scm
        (let* ((trading-option-path-kvp?
                        (qof-book-get-option
                         b trading-accounts-path))
@@ -1487,6 +1529,7 @@
                             #f))
               (book-currency #f)
               (cap-gains-policy #f)
+              (gains-loss-account-guid #f)
               (v (if trading?
                      'trading
                      (let* ((book-currency-option-path-kvp?
@@ -1495,6 +1538,9 @@
                             (gains-policy-option-path-kvp?
                                  (qof-book-get-option
                                      b gains-policy-path))
+                            (gains-loss-account-option-path-kvp?
+                                 (qof-book-get-option
+                                     b gains-loss-account-path))
                             (book-currency?
                                (if (and book-currency-option-path-kvp?
                                         gains-policy-option-path-kvp?
@@ -1513,24 +1559,37 @@
                                                book-currency-option-path-kvp?)
                                      (set! cap-gains-policy
                                                gains-policy-option-path-kvp?)
+                                     (if gains-loss-account-option-path-kvp?
+                                         (if (valid-gains-loss-account?
+                                               book-currency
+                                               gains-loss-account-option-path-kvp?)
+                                             (set! gains-loss-account-guid
+                                               gains-loss-account-option-path-kvp?)))
                                      #t)
-                                   #f)))
+                                    #f)))
                            (if book-currency?
                                'book-currency
                                'neither)))))
-         (if (and v (symbol? v) (legal-val v ok-radiobutton-values))
-             (set! value (cons v (if (eq? 'book-currency v)
-                                     (list (scm->currency book-currency)
-                                           (string->symbol cap-gains-policy))
-                                     '())))
-             (set! value (cons 'neither '())))))
-     (lambda (x)
+             (if (and v (symbol? v) (legal-val v ok-radiobutton-values))
+                 (set! value (cons v (if (eq? 'book-currency v)
+                                         (list (scm->currency book-currency)
+                                               (string->symbol cap-gains-policy)
+                                               gains-loss-account-guid)
+                                         '())))
+                 (set! value (cons 'neither '())))))
+     (lambda (x) ;; value validator
        (if (list? x)
            (if (legal-val (car x) ok-radiobutton-values)
                (if (eq? 'book-currency (car x))
                    (if (currency? (currency->scm (cadr x)))
                        (if (gnc-valid-policy-name (symbol->string (caddr x)))
-                           (list #t x)
+                           (if (car(cdddr x))
+                               (if (valid-gains-loss-account?
+                                     (currency->scm (cadr x))
+                                     (car(cdddr x)))
+                                   (list #t x)
+                                   (list #f "gains-loss-account-option: illegal value"))
+                               (list #t x)) ;; must be valid if specified, otherwise OK
                            (list #f "cap-gains-policy-option: illegal value"))
                        (list #f "currency-option: illegal value"))
                    (list #t x))
@@ -1539,7 +1598,8 @@
      (vector book-currency-documentation-string
              default-book-currency-value
              default-cap-gains-policy-documentation-string
-             default-cap-gains-policy-value)
+             default-cap-gains-policy-value
+             default-gains-loss-account-documentation-string)
      (vector (lambda () (length ok-radiobutton-values))
              (lambda (x) (vector-ref (list-ref ok-radiobutton-values x) 0))
              (lambda (x) (vector-ref (list-ref ok-radiobutton-values x) 1))
@@ -1561,6 +1621,9 @@
 (define (gnc:get-currency-accounting-option-data-policy-default option-data)
   (vector-ref option-data 3))
 
+(define (gnc:get-currency-accounting-option-data-gain-loss-account-doc-string option-data)
+  (vector-ref option-data 4))
+
 (define (gnc:currency-accounting-option-get-curr-doc-string option)
   (if (eq? (gnc:option-type option) 'currency-accounting)
       (gnc:get-currency-accounting-option-data-curr-doc-string
@@ -1585,6 +1648,12 @@
         (gnc:option-data option))
       (gnc:error "Not a currency accounting option")))
 
+(define (gnc:currency-accounting-option-get-gain-loss-account-doc-string option)
+  (if (eq? (gnc:option-type option) 'currency-accounting)
+      (gnc:get-currency-accounting-option-data-gain-loss-account-doc-string
+        (gnc:option-data option))
+      (gnc:error "Not a currency accounting option")))
+
 (define (gnc:currency-accounting-option-selected-method option-value)
   (car option-value))
 
@@ -1598,6 +1667,11 @@
       (caddr option-value)
       #f))
 
+(define (gnc:currency-accounting-option-selected-gain-loss-account option-value)
+  (if (eq? (car option-value) 'book-currency)
+      (car (cdddr option-value))
+      #f))
+
 ;; Create a new options database
 (define (gnc:new-options)
   (define option-hash (make-hash-table 23))
@@ -1731,11 +1805,11 @@
              (default-value (gnc:option-default-value option))
              (section (gnc:option-section option))
              (name (gnc:option-name option)))
-         (gnc:debug "value: " value "; default: " default-value
-                    "; section: " section "; name: " name)
+;;         (gnc:debug "value: " value "; default: " default-value
+;;                   "; section: " section "; name: " name)
          (if (not (equal? value default-value))
              (let ((save-fcn (gnc:option-scm->kvp option)))
-               (gnc:debug "save-fcn: " save-fcn)
+;;               (gnc:debug "save-fcn: " save-fcn)
                (if save-fcn
                    (save-fcn book (list section name)))))))))
 
diff --git a/src/app-utils/test/test-gnc-ui-util.c b/src/app-utils/test/test-gnc-ui-util.c
index 704171f..b943954 100644
--- a/src/app-utils/test/test-gnc-ui-util.c
+++ b/src/app-utils/test/test-gnc-ui-util.c
@@ -65,6 +65,8 @@ test_book_use_book_currency( Fixture *fixture, gconstpointer pData )
     const gchar *cur;
     const gchar *pol;
     Account *acct, *acc;
+    gnc_commodity *com = gnc_commodity_new(fixture-> book, NULL, NULL, "USD",
+                                NULL, NULL);
 
     g_test_message( "Testing with no currency accounting method selected" );
     cur = gnc_book_get_book_currency_name( fixture-> book );
@@ -233,7 +235,7 @@ test_book_use_book_currency( Fixture *fixture, gconstpointer pData )
     qof_book_destroy( fixture->book );
     fixture->book = qof_book_new();
 
-    g_test_message( "Testing with book-currency, default-gains-policy and default-gain-loss-account-guid set to valid values and no trading accounts flag" );
+     g_test_message( "Testing with book-currency and default-gains-policy set to valid values but default-gain-loss-account-guid set to valid but placeholder account and no trading accounts flag" );
     qof_book_begin_edit (fixture->book);
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "book-currency", "USD",
@@ -242,6 +244,132 @@ test_book_use_book_currency( Fixture *fixture, gconstpointer pData )
 		      "default-gains-policy", "fifo",
 		      NULL);
     acc = get_random_account( fixture-> book );
+    xaccAccountBeginEdit (acc);
+    xaccAccountSetType (acc, ACCT_TYPE_INCOME);
+    xaccAccountSetCommodity (acc, com);
+    xaccAccountSetPlaceholder (acc, TRUE);
+    xaccAccountSetHidden (acc, FALSE);
+    xaccAccountCommitEdit (acc);
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "default-gain-loss-account-guid", qof_entity_get_guid(QOF_INSTANCE(acc)),
+		      NULL);
+    cur = gnc_book_get_book_currency_name( fixture-> book );
+    g_assert_cmpstr( cur, == , "USD" );
+    pol = gnc_book_get_default_gains_policy( fixture-> book );
+    g_assert_cmpstr( pol, == , "fifo" );
+    acct = gnc_book_get_default_gain_loss_acct ( fixture-> book );
+    g_assert (acct == NULL );
+    g_assert( gnc_book_use_book_currency ( fixture-> book ));
+    qof_book_commit_edit (fixture->book);
+
+    qof_book_destroy( fixture->book );
+    fixture->book = qof_book_new();
+
+     g_test_message( "Testing with book-currency and default-gains-policy set to valid values but default-gain-loss-account-guid set to valid but hidden account and no trading accounts flag" );
+    qof_book_begin_edit (fixture->book);
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "book-currency", "USD",
+		      NULL);
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "default-gains-policy", "fifo",
+		      NULL);
+    acc = get_random_account( fixture-> book );
+    xaccAccountBeginEdit (acc);
+    xaccAccountSetType (acc, ACCT_TYPE_INCOME);
+    xaccAccountSetCommodity (acc, com);
+    xaccAccountSetPlaceholder (acc, FALSE);
+    xaccAccountSetHidden (acc, TRUE);
+    xaccAccountCommitEdit (acc);
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "default-gain-loss-account-guid", qof_entity_get_guid(QOF_INSTANCE(acc)),
+		      NULL);
+    cur = gnc_book_get_book_currency_name( fixture-> book );
+    g_assert_cmpstr( cur, == , "USD" );
+    pol = gnc_book_get_default_gains_policy( fixture-> book );
+    g_assert_cmpstr( pol, == , "fifo" );
+    acct = gnc_book_get_default_gain_loss_acct ( fixture-> book );
+    g_assert (acct == NULL );
+    g_assert( gnc_book_use_book_currency ( fixture-> book ));
+    qof_book_commit_edit (fixture->book);
+
+    qof_book_destroy( fixture->book );
+    fixture->book = qof_book_new();
+
+     g_test_message( "Testing with book-currency and default-gains-policy set to valid values but default-gain-loss-account-guid set to valid but asset account and no trading accounts flag" );
+    qof_book_begin_edit (fixture->book);
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "book-currency", "USD",
+		      NULL);
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "default-gains-policy", "fifo",
+		      NULL);
+    acc = get_random_account( fixture-> book );
+    xaccAccountBeginEdit (acc);
+    xaccAccountSetType (acc, ACCT_TYPE_ASSET);
+    xaccAccountSetCommodity (acc, com);
+    xaccAccountSetPlaceholder (acc, FALSE);
+    xaccAccountSetHidden (acc, FALSE);
+    xaccAccountCommitEdit (acc);
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "default-gain-loss-account-guid", qof_entity_get_guid(QOF_INSTANCE(acc)),
+		      NULL);
+    cur = gnc_book_get_book_currency_name( fixture-> book );
+    g_assert_cmpstr( cur, == , "USD" );
+    pol = gnc_book_get_default_gains_policy( fixture-> book );
+    g_assert_cmpstr( pol, == , "fifo" );
+    acct = gnc_book_get_default_gain_loss_acct ( fixture-> book );
+    g_assert (acct == NULL );
+    g_assert( gnc_book_use_book_currency ( fixture-> book ));
+    qof_book_commit_edit (fixture->book);
+
+    qof_book_destroy( fixture->book );
+    fixture->book = qof_book_new();
+
+     g_test_message( "Testing with book-currency and default-gains-policy set to valid values but default-gain-loss-account-guid set to valid but not book-currency account and no trading accounts flag" );
+    qof_book_begin_edit (fixture->book);
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "book-currency", "GBP",
+		      NULL);
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "default-gains-policy", "fifo",
+		      NULL);
+    acc = get_random_account( fixture-> book );
+    xaccAccountBeginEdit (acc);
+    xaccAccountSetType (acc, ACCT_TYPE_ASSET);
+    xaccAccountSetCommodity (acc, com);
+    xaccAccountSetPlaceholder (acc, FALSE);
+    xaccAccountSetHidden (acc, FALSE);
+    xaccAccountCommitEdit (acc);
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "default-gain-loss-account-guid", qof_entity_get_guid(QOF_INSTANCE(acc)),
+		      NULL);
+    cur = gnc_book_get_book_currency_name( fixture-> book );
+    g_assert_cmpstr( cur, == , "GBP" );
+    pol = gnc_book_get_default_gains_policy( fixture-> book );
+    g_assert_cmpstr( pol, == , "fifo" );
+    acct = gnc_book_get_default_gain_loss_acct ( fixture-> book );
+    g_assert (acct == NULL );
+    g_assert( gnc_book_use_book_currency ( fixture-> book ));
+    qof_book_commit_edit (fixture->book);
+
+    qof_book_destroy( fixture->book );
+    fixture->book = qof_book_new();
+
+   g_test_message( "Testing with book-currency, default-gains-policy and default-gain-loss-account-guid set to valid values and no trading accounts flag" );
+    qof_book_begin_edit (fixture->book);
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "book-currency", "USD",
+		      NULL);
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "default-gains-policy", "fifo",
+		      NULL);
+    acc = get_random_account( fixture-> book );
+    xaccAccountBeginEdit (acc);
+    xaccAccountSetType (acc, ACCT_TYPE_INCOME);
+    xaccAccountSetCommodity (acc, com);
+    xaccAccountSetPlaceholder (acc, FALSE);
+    xaccAccountSetHidden (acc, FALSE);
+    xaccAccountCommitEdit (acc);
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "default-gain-loss-account-guid", qof_entity_get_guid(QOF_INSTANCE(acc)),
 		      NULL);
diff --git a/src/app-utils/test/test-option-util.cpp b/src/app-utils/test/test-option-util.cpp
index 7bc7b9b..44f7ce0 100644
--- a/src/app-utils/test/test-option-util.cpp
+++ b/src/app-utils/test/test-option-util.cpp
@@ -29,6 +29,7 @@ extern "C"
 #include <glib.h>
 #include <unittest-support.h>
 #include <qofbookslots.h>
+#include "test-engine-stuff.h"
 #include "../option-util.h"
 }
 
@@ -136,9 +137,18 @@ test_option_load_book_currency (Fixture *fixture, gconstpointer pData)
     SCM symbol_value;
     const gchar *curr = NULL;
     SCM curr_scm;
+    SCM acct_guid_scm = NULL;
     gnc_commodity *commodity;
     QofBook *book = fixture->book;
     GNCOptionDB *odb = gnc_option_db_new_for_type (QOF_ID_BOOK);
+    Account *acct, *acc;
+
+    qof_book_begin_edit (book);
+    acc = get_random_account( book );
+    qof_instance_set (QOF_INSTANCE (book),
+                     "default-gain-loss-account-guid", qof_entity_get_guid(QOF_INSTANCE(acc)),
+                     NULL);
+    qof_book_commit_edit (book);
 
     qof_book_load_options (book, gnc_option_db_load, odb);
     symbol_value = gnc_currency_accounting_option_value_get_method (
@@ -157,6 +167,24 @@ test_option_load_book_currency (Fixture *fixture, gconstpointer pData)
     g_assert_cmpstr (str, ==, "book-currency");
     if (str)
         g_free (str);
+    acct_guid_scm = gnc_currency_accounting_option_value_get_default_account (
+                        gnc_option_db_lookup_option (odb,
+                            OPTION_SECTION_ACCOUNTS,
+                            OPTION_NAME_CURRENCY_ACCOUNTING,
+                            SCM_BOOL_F));
+    if (acct_guid_scm && (scm_is_string(acct_guid_scm)))
+    {
+
+        GncGUID *guid = g_new (GncGUID, 1);
+
+        str = scm_to_utf8_string (acct_guid_scm);
+            if (string_to_guid (str, guid))
+                acct = xaccAccountLookup( guid, book );
+        g_free (guid);
+    }
+    g_assert ( xaccAccountEqual(acct, acc, TRUE) );
+    if (str)
+        g_free (str);
     symbol_value = gnc_currency_accounting_option_value_get_default_policy (
                         gnc_option_db_lookup_option (odb,
                             OPTION_SECTION_ACCOUNTS,
@@ -221,15 +249,31 @@ test_option_save_book_currency (Fixture *fixture, gconstpointer pData)
     QofBook *book = fixture->book;
     GNCOptionDB *odb = gnc_option_db_new_for_type (QOF_ID_BOOK);
     KvpFrame *slots = qof_instance_get_slots (QOF_INSTANCE (book));
+    Account *acct, *acc;
+    gchar *gain_loss_account_guid_str, *gain_loss_account_guid_str2;
+    GncGUID *gain_loss_account_guid;
+    SCM val;
 
+    acc = get_random_account( book );
+    gain_loss_account_guid_str = guid_to_string (xaccAccountGetGUID (acc));
+    val = scm_from_utf8_string (gain_loss_account_guid_str);
     g_assert (gnc_option_db_set_option (odb, OPTION_SECTION_ACCOUNTS,
 						OPTION_NAME_CURRENCY_ACCOUNTING,
 						scm_cons (scm_from_locale_symbol("book-currency"),
                         scm_cons (scm_from_utf8_string("GTQ"),
-                        scm_cons (scm_from_locale_symbol("fifo"), SCM_EOL)))));
+                        scm_cons (scm_from_locale_symbol("fifo"),
+                        scm_cons (val, SCM_EOL))))));
     qof_book_save_options (book, gnc_option_db_save, odb, TRUE);
     g_assert_cmpstr (slots->get_slot("options/Accounts/Book Currency")->get<const char*>(), == , "GTQ");
     g_assert_cmpstr (slots->get_slot("options/Accounts/Default Gains Policy")->get<const char*>(), == , "fifo");
+    gain_loss_account_guid =
+        slots->get_slot("options/Accounts/Default Gain or Loss Account")->get<GncGUID*>();
+    gain_loss_account_guid_str2 = guid_to_string (gain_loss_account_guid);
+    g_assert_cmpstr (gain_loss_account_guid_str2, == , gain_loss_account_guid_str);
+    if (gain_loss_account_guid_str)
+        g_free (gain_loss_account_guid_str);
+    if (gain_loss_account_guid_str2)
+        g_free (gain_loss_account_guid_str2);
 
     gnc_option_db_destroy (odb);
 }
diff --git a/src/engine/engine.i b/src/engine/engine.i
index 55a158d..5c364eb 100644
--- a/src/engine/engine.i
+++ b/src/engine/engine.i
@@ -368,6 +368,7 @@ void qof_book_set_string_option(QofBook* book, const char* opt_name, const char*
     SET_ENUM("OPTION-NAME-CURRENCY-ACCOUNTING");
     SET_ENUM("OPTION-NAME-BOOK-CURRENCY");
     SET_ENUM("OPTION-NAME-DEFAULT-GAINS-POLICY");
+    SET_ENUM("OPTION-NAME-DEFAULT-GAINS-LOSS-ACCT-GUID");
     SET_ENUM("OPTION-NAME-AUTO-READONLY-DAYS");
     SET_ENUM("OPTION-NAME-NUM-FIELD-SOURCE");
 
diff --git a/src/gnome-utils/dialog-options.c b/src/gnome-utils/dialog-options.c
index 39ca25f..bf3fcf3 100644
--- a/src/gnome-utils/dialog-options.c
+++ b/src/gnome-utils/dialog-options.c
@@ -38,6 +38,7 @@
 #include "glib-helpers.h"
 #include "gnc-account-sel.h"
 #include "gnc-tree-view-account.h"
+#include "gnc-tree-model-account.h"
 #include "gnc-combott.h"
 #include "gnc-commodity-edit.h"
 #include "gnc-component-manager.h"
@@ -67,6 +68,7 @@
 static QofLogModule log_module = GNC_MOD_GUI;
 
 #define DIALOG_OPTIONS_CM_CLASS "dialog-options"
+#define DIALOG_BOOK_OPTIONS_CM_CLASS "dialog-book-options"
 
 /*
  * Point where preferences switch control method from a set of
@@ -80,6 +82,8 @@ static QofLogModule log_module = GNC_MOD_GUI;
 /* A Hash-table of GNCOptionDef_t keyed with option names. */
 static GHashTable *optionTable = NULL;
 
+static int gain_loss_accounts_in_filter = 0;
+
 struct gnc_option_win
 {
     GtkWidget  * dialog;
@@ -100,6 +104,9 @@ struct gnc_option_win
 
     /* Hold onto this for a complete reset */
     GNCOptionDB *		option_db;
+
+    /* Hold on to this to unregister the right class */
+    const char *component_class;
 };
 
 typedef enum
@@ -117,6 +124,29 @@ enum page_tree
     NUM_COLUMNS
 };
 
+typedef struct
+{
+    GtkWidget *gnc_currency_radiobutton_0;
+    GtkWidget *gnc_currency_radiobutton_1;
+    GtkWidget *gnc_currency_radiobutton_2;
+    GtkWidget *book_currency_widget;
+    GtkWidget *default_cost_policy_widget;
+    GtkWidget *default_gain_loss_account_widget;
+    GtkWidget *book_currency_table;
+    GtkWidget *book_currency_vbox;
+    GtkWidget *gain_loss_account_del_button;
+    GtkWidget *gain_loss_account_table;
+    GtkWidget *default_gain_loss_account_text;
+    GNCOption *option;
+    gnc_commodity *retrieved_book_currency;
+    SCM retrieved_policy_scm;
+    SCM retrieved_gain_loss_acct_guid_scm;
+    Account *prior_gain_loss_account;
+
+} currency_accounting_data;
+
+static currency_accounting_data *book_currency_data = NULL;
+
 static GNCOptionWinCallback global_help_cb = NULL;
 gpointer global_help_cb_data = NULL;
 
@@ -125,7 +155,14 @@ void gnc_options_dialog_response_cb(GtkDialog *dialog, gint response,
 static void gnc_options_dialog_reset_cb(GtkWidget * w, gpointer data);
 void gnc_options_dialog_list_select_cb (GtkTreeSelection *selection,
                                         gpointer data);
-GList * gnc_option_get_ui_widgets_currency_accounting(GtkWidget *widget);
+void gnc_set_book_currency_widget(void);
+void gnc_set_default_cost_policy_widget(SCM list_symbol);
+void gnc_set_default_gain_loss_account_widget(gnc_commodity *commodity);
+void gnc_option_changed_book_currency_widget_cb(GtkWidget *widget);
+void gnc_option_changed_gain_loss_account_widget_cb(GtkTreeSelection *selection,
+                                                    gpointer data);
+void gnc_option_changed_gain_loss_account_del_button_widget_cb (GtkButton *button,
+                                                    gpointer data);
 
 GtkWidget *
 gnc_option_get_gtk_widget (GNCOption *option)
@@ -386,69 +423,6 @@ gnc_option_set_selectable_internal (GNCOption *option, gboolean selectable)
     gtk_widget_set_sensitive (widget, selectable);
 }
 
-GList *
-gnc_option_get_ui_widgets_currency_accounting (GtkWidget *widget)
-{
-    GList *list1, *list2, *list3;
-    GList *list = NULL;
-    GList *return_list = NULL;
-    GtkWidget *book_currency_widget= NULL;
-    GtkWidget *default_cost_policy_widget= NULL;
-    GtkWidget *book_currency_vbox_widget= NULL;
-    GtkWidget *default_cost_policy_vbox_widget= NULL;
-
-    /* children of the frame, the 1st of which is 1 vbox1 */
-    list1 = gtk_container_get_children (GTK_CONTAINER (widget));
-    /* children of vbox1 which are 3 hbox's */
-    list2 = gtk_container_get_children (GTK_CONTAINER (list1->data));
-    g_list_free(list1);
-    /* create list of button widgets */
-    for (list3 = list2; list3; list3 = list3->next)
-    {
-        GList *vbox2list = NULL;
-        /* children of each hbox, the 1st of which is a vbox2 */
-        vbox2list = gtk_container_get_children
-                                   (GTK_CONTAINER (list3->data));
-        /* children of 1st vbox2, the 1st of which is a button */
-        list1 = gtk_container_get_children
-                               (GTK_CONTAINER (vbox2list->data));
-        list = g_list_append (list, list1->data);
-        g_list_free(vbox2list);
-        g_list_free(list1);
-    }
-    return_list = g_list_append (return_list, list);
-    /* point list2 to 2nd hbox, which is for book-currency */
-    list2 = list2->next;
-    /* children of book-currency hbox which is 3 vbox2's */
-    list1 = gtk_container_get_children (GTK_CONTAINER (list2->data));
-    g_list_free(list2);
-    /* point list1 to 2nd vbox2, which is for book-currency widget*/
-    list1 = list1->next;
-    book_currency_vbox_widget = list1->data;
-    /* children of book-currency vbox2 which is a label and the
-       book-currency widget */
-    list2 = gtk_container_get_children (GTK_CONTAINER (list1->data));
-    list2 = list2->next;
-    book_currency_widget = list2->data;
-    return_list = g_list_append (return_list, book_currency_widget);
-    g_list_free(list2);
-    /* point list1 to 3rd vbox2, which is for policy widget*/
-    list1 = list1->next;
-    default_cost_policy_vbox_widget = list1->data;
-    /* children of policy vbox2 which is a label and the
-       policy multichoice widget */
-    list2 = gtk_container_get_children (GTK_CONTAINER (list1->data));
-    list2 = list2->next;
-    default_cost_policy_widget = list2->data;
-    return_list = g_list_append (return_list, default_cost_policy_widget);
-    return_list = g_list_append (return_list, book_currency_vbox_widget);
-    return_list = g_list_append (return_list, default_cost_policy_vbox_widget);
-    g_list_free(list2);
-    g_list_free(list1);
-
-    return return_list;
-}
-
 static void
 gnc_option_default_cb(GtkWidget *widget, GNCOption *option)
 {
@@ -502,124 +476,486 @@ gnc_option_radiobutton_cb(GtkWidget *w, gpointer data)
     gnc_option_changed_widget_cb(widget, option);
 }
 
-static void
-gnc_option_currency_accounting_set_sensitivity(GNCOption *option,
-                                               gboolean set_sensitivity)
+static gboolean
+gnc_gain_loss_account_view_filter (Account  *account, gpointer  data)
 {
-    GtkWidget *option_widget;
-    GtkWidget *book_currency_widget;
-    GtkWidget *default_cost_policy_widget;
-    GtkWidget *book_currency_vbox_widget;
-    GtkWidget *default_cost_policy_vbox_widget;
-    GList *list = NULL;
-    GList *sub_widgets = NULL;
-
-    option_widget = gnc_option_get_gtk_widget (option);
-    sub_widgets = gnc_option_get_ui_widgets_currency_accounting (option_widget);
-    list = sub_widgets->data; /* save this to be able to free it */
-    sub_widgets = sub_widgets->next;
-    book_currency_widget = sub_widgets->data;
-    sub_widgets = sub_widgets->next;
-    default_cost_policy_widget = sub_widgets->data;
-    sub_widgets = sub_widgets->next;
-    book_currency_vbox_widget = sub_widgets->data;
-    sub_widgets = sub_widgets->next;
-    default_cost_policy_vbox_widget = sub_widgets->data;
-    g_list_free(sub_widgets);
-    g_list_free(list);
-    if (set_sensitivity)
-    {
-        SCM curr_scm;
-        SCM list_symbol;
-        gnc_commodity *commodity;
-        int index;
-        GList *list_of_policies = NULL;
+    GNCAccountType type = xaccAccountGetType(account);
 
-        curr_scm = gnc_currency_accounting_option_get_default_currency(option);
-        commodity = gnc_scm_to_commodity (curr_scm);
-        if (commodity)
+    /* gain/loss accts must be an Income or Expense accts and not hidden;
+       placeholder accounts must be included, irrespective of their currency,
+       so their children are available to be considered */
+    if (((type == ACCT_TYPE_INCOME) || (type == ACCT_TYPE_EXPENSE)) &&
+        (!xaccAccountIsHidden(account)))
+    {
+        if (xaccAccountGetPlaceholder(account))
         {
-            gnc_currency_edit_set_currency
-                (GNC_CURRENCY_EDIT(book_currency_widget), commodity);
+            GList *placeholder_children = gnc_account_get_children (account);
+
+            if(placeholder_children)
+            { /* determine if any children qualify; just need one but don't
+                 double count in gain_loss_accounts_in_filter */
+                int saved_gain_loss_accounts_in_filter =
+                                                gain_loss_accounts_in_filter;
+                gboolean child_pass_filter = FALSE;
+                GList *l = NULL;
+                for (l = placeholder_children; l != NULL; l = l->next)
+                {
+                    Account  *child_account = l->data;
+                    child_pass_filter =
+                        gnc_gain_loss_account_view_filter(child_account, NULL);
+                    if (child_pass_filter)
+                        break;
+                }
+                g_list_free(placeholder_children);
+                gain_loss_accounts_in_filter =
+                                           saved_gain_loss_accounts_in_filter;
+                return child_pass_filter;
+            }
+            else return FALSE; // no children, not interested
         }
         else
         {
-            gnc_currency_edit_set_currency
-                (GNC_CURRENCY_EDIT(book_currency_widget), gnc_default_currency());
+            gnc_commodity *commodity = NULL;
+
+            /* gain/loss accts must be in book-currency; if a book currency has been
+               specified in the widget, use it to filter */
+            if (book_currency_data->book_currency_widget)
+                commodity = gnc_currency_edit_get_currency(
+                                GNC_CURRENCY_EDIT(
+                                    book_currency_data->book_currency_widget));
+            if (commodity)
+            {
+                if (gnc_commodity_equal(xaccAccountGetCommodity(account),
+                                    commodity))
+                {
+                    gain_loss_accounts_in_filter++;
+                    return TRUE;
+                }
+                else return FALSE;
+            }
+            /* else use the default currency */
+            else if (gnc_commodity_equal(xaccAccountGetCommodity(account),
+                                gnc_default_currency()))
+            {
+                gain_loss_accounts_in_filter++;
+                return TRUE;
+            }
+            else return FALSE;
         }
-        gtk_widget_set_sensitive(book_currency_vbox_widget, TRUE);
+    }
+    else return FALSE;
+}
 
-        list_of_policies = gnc_get_valid_policy_list();
-        if (list_of_policies)
+static gboolean
+gnc_gain_loss_account_all_fail_filter (Account  *account, gpointer  data)
+{
+    return FALSE;
+}
+
+void
+gnc_set_book_currency_widget()
+{
+    g_signal_connect(G_OBJECT(book_currency_data->book_currency_widget),
+                        "changed",
+                        G_CALLBACK(gnc_option_changed_book_currency_widget_cb),
+                        NULL);
+    gtk_table_attach (GTK_TABLE(book_currency_data->book_currency_table),
+                        book_currency_data->book_currency_widget,
+                        1, 2, // left, right attach
+                        0, 1, // top, bottom attach
+                        GTK_FILL|GTK_EXPAND, GTK_FILL, // x,y
+                        0, 0);
+}
+
+void
+gnc_set_default_cost_policy_widget(SCM list_symbol)
+{
+    GList *list_of_policies = gnc_get_valid_policy_list();
+
+    if (list_of_policies)
+    {
+        GList *l = NULL;
+        gint i = 0;
+        for (l = list_of_policies; l != NULL; l = l->next)
         {
-            GList *l = NULL;
-            gint i = 0;
-            list_symbol =
-                gnc_currency_accounting_option_get_default_policy(option);
-            for (l = list_of_policies; l != NULL; l = l->next)
-            {
-                /* First item in policy_list is internal name of policy */
-                GNCPolicy *pcy = l->data;
-                if (g_strcmp0(PolicyGetName (pcy),
+            GNCPolicy *pcy = l->data;
+            if (g_strcmp0(PolicyGetName (pcy),
                                gnc_scm_symbol_to_locale_string(list_symbol))
                                == 0)
+            {
+                /* GtkComboBox per-item tooltip changes needed below */
+                gnc_combott_set_active(
+                    GNC_COMBOTT(
+                        book_currency_data->default_cost_policy_widget), i);
+            }
+            i++;
+        }
+        g_list_free(list_of_policies);
+    }
+    else
+    {
+        gnc_combott_set_active (
+            GNC_COMBOTT(book_currency_data->default_cost_policy_widget), -1);
+    }
+}
+
+void
+gnc_set_default_gain_loss_account_widget(gnc_commodity *commodity)
+{
+    if (book_currency_data->default_gain_loss_account_widget)
+    {
+        gtk_widget_destroy (
+                    book_currency_data->default_gain_loss_account_widget);
+        book_currency_data->default_gain_loss_account_widget = NULL;
+        book_currency_data->prior_gain_loss_account = NULL;
+        gain_loss_accounts_in_filter = 0;
+    }
+    if (book_currency_data->gain_loss_account_del_button)
+    {
+        gtk_widget_destroy (
+                    book_currency_data->gain_loss_account_del_button);
+        book_currency_data->gain_loss_account_del_button = NULL;
+    }
+    if (book_currency_data->default_gain_loss_account_text)
+    {
+        gtk_widget_destroy (
+                    book_currency_data->default_gain_loss_account_text);
+        book_currency_data->default_gain_loss_account_text = NULL;
+    }
+    if (gnc_is_new_book())
+    {
+        book_currency_data->default_gain_loss_account_text =
+                    gtk_label_new( _("Because no accounts have " \
+                        "been set up yet,\nyou will need to return to this " \
+                        "dialog\n(via File->Properties), after account setup, " \
+                        "if\nyou want to set a default gain/loss account.") );
+        gtk_table_attach (GTK_TABLE(
+                        book_currency_data->gain_loss_account_table),
+                        book_currency_data->default_gain_loss_account_text,
+                        1, 3, // left, right attach
+                        1, 2, // top, bottom attach
+                        GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, // x,y
+                        0, 0);
+    }
+    else
+    {
+        GtkTreeSelection *selection = NULL;
+        book_currency_data->default_gain_loss_account_widget =
+                            GTK_WIDGET(gnc_tree_view_account_new(FALSE));
+        gain_loss_accounts_in_filter = 0;
+        selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(
+                        book_currency_data->default_gain_loss_account_widget));
+        if (!commodity) // that means not book currency
+        {
+            /* set the default_gain_loss_account_widget to be blank with a
+               no-acct filter */
+            gnc_tree_view_account_set_filter(GNC_TREE_VIEW_ACCOUNT (
+                        book_currency_data->default_gain_loss_account_widget),
+                        gnc_gain_loss_account_all_fail_filter,
+                        NULL,  /* user data */
+                        NULL  /* destroy callback */ );
+            gtk_tree_selection_unselect_all (selection);
+        }
+        else // that means book currency
+        {
+            /* see if there are any accounts after filter */
+            gnc_tree_view_account_set_filter(GNC_TREE_VIEW_ACCOUNT (
+                        book_currency_data->default_gain_loss_account_widget),
+                        gnc_gain_loss_account_view_filter,
+                        NULL, /* user data */
+                        NULL  /* destroy callback */);
+            if (gain_loss_accounts_in_filter > 0)
+            {   /* there are accounts; find out if one is selected */
+                Account *gain_loss_account = NULL;
+                Account *selected_account = NULL;
+                GtkTreeViewColumn *col;
+
+                book_currency_data->gain_loss_account_del_button =
+                        gtk_button_new_with_label( _("Select no account") );
+                g_signal_connect (GTK_BUTTON (
+                        book_currency_data->gain_loss_account_del_button),
+                        "clicked",
+                        G_CALLBACK (
+                            gnc_option_changed_gain_loss_account_del_button_widget_cb),
+                        NULL);
+                gtk_table_attach (GTK_TABLE(
+                        book_currency_data->gain_loss_account_table),
+                        book_currency_data->gain_loss_account_del_button,
+                        2, 3, // left, right attach
+                        0, 1, // top, bottom attach
+                        GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, // x,y
+                        0, 0);
+                gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(
+                        book_currency_data->default_gain_loss_account_widget),
+                        TRUE);
+                col = 
+                    gnc_tree_view_add_text_column(GNC_TREE_VIEW(
+                        book_currency_data->default_gain_loss_account_widget),
+                         _("Currency"), /* title */
+                        "commodity", /* pref name */
+                        NULL,
+                        "Currency--", /* sizing text */
+                        GNC_TREE_MODEL_ACCOUNT_COL_COMMODITY,
+                        GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
+                        NULL);
+                g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE,
+                    GINT_TO_POINTER(1));
+                col =
+                    gnc_tree_view_add_toggle_column(GNC_TREE_VIEW(
+                        book_currency_data->default_gain_loss_account_widget),
+                        _("Placeholder"),
+                        /* Translators: This string has a context prefix; the
+                           translation must only contain the part after
+                           the | character. */
+                        Q_("Column letter for 'Placeholder'|P"),
+                        "placeholder",
+                        GNC_TREE_MODEL_ACCOUNT_COL_PLACEHOLDER,
+                        GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
+                        NULL,
+                        NULL);
+                g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE,
+                    GINT_TO_POINTER(1));
+                gnc_tree_view_configure_columns (GNC_TREE_VIEW(
+                        book_currency_data->default_gain_loss_account_widget));
+                gnc_tree_view_set_show_column_menu(GNC_TREE_VIEW(
+                        book_currency_data->default_gain_loss_account_widget),
+                        FALSE);
+                if (book_currency_data->retrieved_gain_loss_acct_guid_scm &&
+                    (scm_is_string(
+                        book_currency_data->retrieved_gain_loss_acct_guid_scm)))
                 {
-                    /* GtkComboBox per-item tooltip changes needed below */
-                    gnc_combott_set_active(
-                                    GNC_COMBOTT(default_cost_policy_widget), i);
+                    GncGUID *guid= g_new (GncGUID, 1);
+
+                    if (string_to_guid (
+                        gnc_scm_to_utf8_string(
+                        book_currency_data->retrieved_gain_loss_acct_guid_scm),
+                        guid))
+                    gain_loss_account =
+                                xaccAccountLookup(guid, gnc_get_current_book());
+                    g_free (guid);
+                }
+                if (gain_loss_account)
+                {
+                    (gnc_tree_view_account_set_selected_account
+                        (GNC_TREE_VIEW_ACCOUNT(
+                          book_currency_data->default_gain_loss_account_widget),
+                        gain_loss_account));
+                    selected_account =
+                        gnc_tree_view_account_get_selected_account(
+                            GNC_TREE_VIEW_ACCOUNT (
+                            book_currency_data->default_gain_loss_account_widget));
+                }
+                if (selected_account)
+                {
+                    book_currency_data->prior_gain_loss_account =
+                        selected_account;
+                    gtk_widget_set_sensitive(
+                        book_currency_data->gain_loss_account_del_button,
+                        TRUE);
+                }
+                else /* none selected */
+                {
+                    gtk_tree_selection_unselect_all (selection);
+                    gtk_widget_set_sensitive(
+                        book_currency_data->gain_loss_account_del_button,
+                        FALSE);
                 }
-                i++;
             }
-            g_list_free(list_of_policies);
+            else /* no accts in widget?; replace widget with text */
+            {
+                gtk_widget_destroy (
+                    book_currency_data->default_gain_loss_account_widget);
+                book_currency_data->default_gain_loss_account_widget = NULL;
+                book_currency_data->prior_gain_loss_account = NULL;
+                gain_loss_accounts_in_filter = 0;
+                book_currency_data->default_gain_loss_account_text =
+                    gtk_label_new( _("There are no income " \
+                        "or expense accounts of the specified\n" \
+                        "book currency; you will have to return to this " \
+                        "dialog\n(via File->Properties), after account setup, " \
+                        "to select a\ndefault gain/loss account.") );
+                gtk_table_attach (GTK_TABLE(book_currency_data->gain_loss_account_table),
+                        book_currency_data->default_gain_loss_account_text,
+                        1, 3, // left, right attach
+                        1, 2, // top, bottom attach
+                        GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, // x,y
+                        0, 0);
+            }
         }
-        else
+        if (book_currency_data->default_gain_loss_account_widget)
         {
-           gnc_combott_set_active
-                    (GNC_COMBOTT(default_cost_policy_widget), -1);
+
+            g_signal_connect (G_OBJECT (selection),
+                        "changed",
+                        G_CALLBACK (gnc_option_changed_gain_loss_account_widget_cb),
+                        NULL);
+            gtk_table_attach (GTK_TABLE(book_currency_data->gain_loss_account_table),
+                        book_currency_data->default_gain_loss_account_widget,
+                        1, 3, // left, right attach
+                        1, 2, // top, bottom attach
+                        GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, // x,y
+                        0, 0);
         }
-        gtk_widget_set_sensitive(default_cost_policy_vbox_widget, TRUE);
     }
-    else
-    {
-        GtkWidget *new_book_currency_widget = NULL;
+}
+
+void
+gnc_option_changed_book_currency_widget_cb(GtkWidget *widget)
+{
+    /* Once the book currency widget is set, need to set the
+       default_gain_loss_account_widget and/or del-button or text*/
+
+    gnc_commodity *commodity = gnc_currency_edit_get_currency(
+                                GNC_CURRENCY_EDIT(
+                                    book_currency_data->book_currency_widget));
+    gnc_set_default_gain_loss_account_widget(commodity);
+    gtk_widget_show_all(book_currency_data->book_currency_vbox);
+    gnc_option_changed_widget_cb(widget, book_currency_data->option);
+}
 
-        /* since there is no 'gnc_currency_edit_set_currency(widget, -1)' like
-           there is for 'gnc_combott_set_active', do this as a work around so
-           the dialog is cleared of currency when switched out of 'book-
-           currency' choice */
-        gtk_widget_destroy (book_currency_widget);
-        new_book_currency_widget = gnc_currency_edit_new();
-        g_signal_connect(G_OBJECT(new_book_currency_widget),
-                         "changed",
-                         G_CALLBACK(gnc_option_changed_widget_cb),
-                         option);
-        gtk_box_pack_start (GTK_BOX (book_currency_vbox_widget),
-                            new_book_currency_widget, FALSE, FALSE, 0);
-        gtk_widget_show_all(book_currency_vbox_widget);
-        gtk_widget_set_sensitive(book_currency_vbox_widget, FALSE);
-        gnc_combott_set_active(GNC_COMBOTT(default_cost_policy_widget), -1);
-        gtk_widget_set_sensitive(default_cost_policy_vbox_widget, FALSE);
+void
+gnc_option_changed_gain_loss_account_widget_cb (GtkTreeSelection *selection,
+                                                    gpointer data)
+{
+    Account *account = NULL;
+    gboolean new_eq_prior_acct = FALSE;
+
+    g_return_if_fail (book_currency_data->default_gain_loss_account_widget);
+    account = gnc_tree_view_account_get_selected_account (
+                    GNC_TREE_VIEW_ACCOUNT (
+                        book_currency_data->default_gain_loss_account_widget));
+    if (account && book_currency_data->prior_gain_loss_account)
+        new_eq_prior_acct = xaccAccountEqual(account,
+                                book_currency_data->prior_gain_loss_account,
+                                TRUE);
+    if (account && (!new_eq_prior_acct))
+    { /* a new account has been selected */
+        if (!xaccAccountGetPlaceholder(account))
+        {
+            GtkWidget *option_widget =
+                        gnc_option_get_gtk_widget (book_currency_data->option);
+            book_currency_data->prior_gain_loss_account = account;
+            gtk_widget_set_sensitive(
+                    book_currency_data->gain_loss_account_del_button, TRUE);
+            gtk_widget_show_all(book_currency_data->book_currency_vbox);
+            gnc_option_changed_option_cb(option_widget, book_currency_data->option);
+        }
+        else /*  new account, but placeholder */
+        {
+            const char *message = _("You have selected a placeholder " \
+                        "account, which is shown so that child accounts " \
+                        "are displayed, but is invalid. Please select " \
+                        "another account. (You can expand the tree below " \
+                        "the placeholder account by clicking on the arrow " \
+                        "to the left.)");
+
+            gnc_error_dialog(NULL, "%s", message);
+            if (book_currency_data->prior_gain_loss_account)
+            {
+                (gnc_tree_view_account_set_selected_account
+                    (GNC_TREE_VIEW_ACCOUNT(
+                          book_currency_data->default_gain_loss_account_widget),
+                        book_currency_data->prior_gain_loss_account));
+            }
+            else
+            {
+                gtk_tree_selection_unselect_all (selection);
+            }
+        }
+    }
+    else /* a new account has not been selected */
+    {
+        if (book_currency_data->prior_gain_loss_account == NULL)
+        {
+            gtk_tree_selection_unselect_all (selection);
+            if (book_currency_data->gain_loss_account_del_button)
+            {
+                gtk_widget_set_sensitive(
+                    book_currency_data->gain_loss_account_del_button, FALSE);
+            }
+        }
     }
 }
 
+void
+gnc_option_changed_gain_loss_account_del_button_widget_cb (GtkButton *button, gpointer data)
+{
+    GtkTreeSelection *selection = NULL;
+    GtkWidget *option_widget =
+                        gnc_option_get_gtk_widget (book_currency_data->option);
+
+    g_return_if_fail (book_currency_data->default_gain_loss_account_widget);
+    g_return_if_fail (book_currency_data->gain_loss_account_del_button);
+
+    selection = gtk_tree_view_get_selection (
+                    GTK_TREE_VIEW (
+                        book_currency_data->default_gain_loss_account_widget));
+    gtk_tree_selection_unselect_all (selection);
+    book_currency_data->prior_gain_loss_account = NULL;
+    gtk_widget_set_sensitive(
+                    book_currency_data->gain_loss_account_del_button, FALSE);
+    gnc_option_changed_option_cb(option_widget, book_currency_data->option);
+}
+
 static void
 gnc_option_currency_accounting_non_book_cb(GtkWidget *widget, gpointer data)
 {
-    /* widget is the radiobutton */
-    GNCOption *option = data;
-
-    gnc_option_currency_accounting_set_sensitivity (option, FALSE);
-    gnc_option_radiobutton_cb(widget, data);
+    /* since there is no 'gnc_currency_edit_set_currency(widget, -1)' like
+       there is for 'gnc_combott_set_active', do this as a work around so
+       the dialog is cleared of currency when switched out of 'book-
+       currency' choice */
+    gtk_widget_destroy (book_currency_data->book_currency_widget);
+    book_currency_data->book_currency_widget = gnc_currency_edit_new();
+    gnc_set_book_currency_widget();
+    gnc_combott_set_active(GNC_COMBOTT(
+                                book_currency_data->default_cost_policy_widget),
+                                -1);
+    gnc_set_default_gain_loss_account_widget(NULL);
+    gtk_widget_show_all(book_currency_data->book_currency_vbox);
+    gtk_widget_set_sensitive(book_currency_data->book_currency_vbox, FALSE);
+    gnc_option_radiobutton_cb(widget, (gpointer) book_currency_data->option);
 }
 
 static void
 gnc_option_currency_accounting_book_cb(GtkWidget *widget, gpointer data)
 {
-    /* widget is the radiobutton */
-    GNCOption *option = data;
+    SCM list_symbol =
+            gnc_currency_accounting_option_get_default_policy(
+                                                    book_currency_data->option);
+    SCM curr_scm = gnc_currency_accounting_option_get_default_currency(
+                                                    book_currency_data->option);
+    gnc_commodity *commodity = gnc_scm_to_commodity (curr_scm);
 
-    gnc_option_currency_accounting_set_sensitivity (option, TRUE);
-    gnc_option_radiobutton_cb(widget, data);
+    if (book_currency_data->retrieved_book_currency)
+    {
+        gnc_currency_edit_set_currency
+                (GNC_CURRENCY_EDIT(book_currency_data->book_currency_widget),
+                    book_currency_data->retrieved_book_currency);
+    }
+    else if (commodity)
+    {
+        gnc_currency_edit_set_currency
+                (GNC_CURRENCY_EDIT(book_currency_data->book_currency_widget),
+                    commodity);
+    }
+    else
+    {
+        gnc_currency_edit_set_currency
+                (GNC_CURRENCY_EDIT(book_currency_data->book_currency_widget),
+                    gnc_default_currency());
+    }
+    if (book_currency_data->retrieved_policy_scm)
+    {
+        gnc_set_default_cost_policy_widget(
+                                      book_currency_data->retrieved_policy_scm);
+    }
+    else
+    {
+        gnc_set_default_cost_policy_widget(list_symbol);
+    }
+    gtk_widget_show_all(book_currency_data->book_currency_vbox);
+    gtk_widget_set_sensitive(book_currency_data->book_currency_vbox, TRUE);
+    gnc_option_radiobutton_cb(widget, (gpointer) book_currency_data->option);
 }
 
 static GtkWidget *
@@ -855,30 +1191,30 @@ gnc_option_create_radiobutton_widget(char *name, GNCOption *option)
 static GtkWidget *
 gnc_option_create_currency_accounting_widget (char *name, GNCOption *option)
 {
-    GtkWidget *frame = NULL, *vbox1 = NULL;
-    GtkWidget *widget = NULL;
-    int num_values;
+    GtkWidget *frame = NULL,
+              *widget = NULL,
+              *vbox = NULL;
     int i;
-
-    num_values = gnc_option_num_permissible_values(option);
+    int num_values = gnc_option_num_permissible_values(option);
 
     g_return_val_if_fail(num_values == 3, NULL);
+    book_currency_data = g_new0 (currency_accounting_data, 1);
+    book_currency_data->option = option;
 
-    /* Create our button frame */
+    /* Create the button frame */
     frame = gtk_frame_new (name);
 
     /* Create the verticle button box */
-    vbox1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (vbox1), FALSE);
-
-    gtk_container_add (GTK_CONTAINER (frame), vbox1);
+    vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
+    gtk_box_set_homogeneous (GTK_BOX (vbox), FALSE);
+    gtk_container_add (GTK_CONTAINER (frame), vbox);
 
     /* Iterate over the three options and create a radio button for each one */
     for (i = 0; i < num_values; i++)
     {
         char *label;
         char *tip;
-        GtkWidget *vbox2 = NULL, *hbox = NULL;
+        GtkWidget *table = NULL;
 
         label = gnc_option_permissible_value_name(option, i);
         tip = gnc_option_permissible_value_description(option, i);
@@ -890,67 +1226,136 @@ gnc_option_create_currency_accounting_widget (char *name, GNCOption *option)
                     label && *label ? _(label) : "");
         g_object_set_data (G_OBJECT (widget), "gnc_radiobutton_index",
                            GINT_TO_POINTER (i));
-        gtk_widget_set_tooltip_text(widget, tip && *tip ? _(tip) : "");
-        /* Use hbox & vbox2 for all buttons so they are all at the same level;
-           easier to get in set/get ui functions */
-        hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-        gtk_box_set_homogeneous (GTK_BOX (hbox), FALSE);
+        switch (i)
+        {
+        case 0:
+            book_currency_data->gnc_currency_radiobutton_0 = widget;
+            break;
 
-        vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
-        gtk_box_set_homogeneous (GTK_BOX (vbox2), FALSE);
+        case 1:
+            book_currency_data->gnc_currency_radiobutton_1 = widget;
+            break;
 
-        gtk_box_pack_start (GTK_BOX (vbox2), widget, FALSE, FALSE, 0);
-        gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
-        if (i == 1) /* book-currency */
-        {
-            GtkWidget *widget_label;
-            GtkWidget *book_currency_widget = NULL,
-                      *default_cost_policy_widget = gnc_cost_policy_select_new();
+        case 2:
+            book_currency_data->gnc_currency_radiobutton_2 = widget;
+            break;
 
+        default:
+            break;
+        }
+        gtk_widget_set_tooltip_text(widget, tip && *tip ? _(tip) : "");
+        if (g_strcmp0(gnc_option_permissible_value_name(option, i),
+                                                    "Use a Book Currency") == 0)
+        {
+            GtkWidget *widget_label,
+                      *alignm = gtk_alignment_new (.5, .5, 1.0, 1.0),
+                      *policy_table = gtk_table_new (1, 2, FALSE);
+
+            book_currency_data->book_currency_widget = gnc_currency_edit_new();
+            book_currency_data->default_cost_policy_widget =
+                                    gnc_cost_policy_select_new();
+            book_currency_data->default_gain_loss_account_widget = NULL;
+            book_currency_data->gain_loss_account_del_button = NULL;
+            book_currency_data->default_gain_loss_account_text = NULL;
+            book_currency_data->prior_gain_loss_account = NULL;
+            book_currency_data->book_currency_table =
+                                    gtk_table_new (1, 2, FALSE);
+            book_currency_data->book_currency_vbox = gtk_vbox_new (FALSE, 0);
+            book_currency_data->gain_loss_account_table =
+                                            gtk_table_new (2, 3, FALSE);
+            table = gtk_table_new (2, 2, FALSE);
+            gtk_table_attach_defaults (GTK_TABLE (table), widget, 0, 2, 0, 1);
             g_signal_connect(G_OBJECT(widget),
                          "toggled",
                          G_CALLBACK(gnc_option_currency_accounting_book_cb),
-                         option);
+                         book_currency_data);
+            gtk_table_set_row_spacings (
+                        GTK_TABLE (book_currency_data->book_currency_table),
+                        6);
+            gtk_table_set_col_spacings (
+                        GTK_TABLE (book_currency_data->book_currency_table),
+                        6);
+            gtk_table_set_row_spacings (GTK_TABLE (policy_table), 6);
+            gtk_table_set_col_spacings (GTK_TABLE (policy_table), 6);
+            gtk_table_set_row_spacings (
+                        GTK_TABLE (book_currency_data->gain_loss_account_table),
+                        6);
+            gtk_table_set_col_spacings (
+                        GTK_TABLE (book_currency_data->gain_loss_account_table),
+                        6);
             tip = gnc_currency_accounting_option_currency_documentation(option);
-            widget_label = gtk_label_new( _("Book Currency") );
-            book_currency_widget = gnc_currency_edit_new();
-            g_signal_connect(G_OBJECT(book_currency_widget),
-                         "changed",
-                         G_CALLBACK(gnc_option_changed_widget_cb),
-                         option);
-            vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
-            gtk_box_set_homogeneous (GTK_BOX (vbox2), FALSE);
-
-            gtk_widget_set_tooltip_text(vbox2, tip && *tip ? _(tip) : "");
-            gtk_box_pack_start (GTK_BOX (vbox2), widget_label, FALSE, FALSE, 0);
-            gtk_box_pack_start (GTK_BOX (vbox2),
-                                book_currency_widget, FALSE, FALSE, 0);
-            gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
-            if (default_cost_policy_widget)
-            {
-                g_signal_connect(G_OBJECT(default_cost_policy_widget), "changed",
-                                 G_CALLBACK(gnc_option_multichoice_cb), option);
-            }
+            widget_label = gtk_label_new( _("Book currency:") );
+            gtk_widget_set_tooltip_text(book_currency_data->book_currency_table,
+                        tip && *tip ? _(tip) : "");
+            gtk_table_attach (
+                        GTK_TABLE(book_currency_data->book_currency_table),
+                        widget_label,
+                        0, 1, // left, right attach
+                        0, 1, // top, bottom attach
+                        GTK_FILL, GTK_FILL, // x,y
+                        0, 0);
+            gnc_set_book_currency_widget();
+            gtk_box_pack_start (
+                        GTK_BOX (book_currency_data->book_currency_vbox),
+                        book_currency_data->book_currency_table,
+                        FALSE, FALSE, 0);
             tip = gnc_currency_accounting_option_policy_documentation(option);
-            widget_label = gtk_label_new( _("Default Gains Policy") );
-
-            vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
-            gtk_box_set_homogeneous (GTK_BOX (vbox2), FALSE);
-
-            gtk_widget_set_tooltip_text(vbox2, tip && *tip ? _(tip) : "");
-            gtk_box_pack_start (GTK_BOX (vbox2), widget_label, FALSE, FALSE, 0);
-            gtk_box_pack_start (GTK_BOX (vbox2),
-                                 default_cost_policy_widget, FALSE, FALSE, 0);
-            gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
+            widget_label = gtk_label_new( _("Default lot tracking policy:") );
+            gtk_widget_set_tooltip_text(
+                        policy_table, tip && *tip ? _(tip) : "");
+            gtk_table_attach (GTK_TABLE(policy_table), widget_label,
+                        0, 1, // left, right attach
+                        0, 1, // top, bottom attach
+                        GTK_FILL, GTK_FILL, // x,y
+                        0, 0);
+            g_signal_connect(G_OBJECT(
+                                book_currency_data->default_cost_policy_widget),
+                        "changed",
+                        G_CALLBACK(gnc_option_multichoice_cb), option);
+            gtk_table_attach (GTK_TABLE(policy_table),
+                                book_currency_data->default_cost_policy_widget,
+                                1, 2, // left, right attach
+                                0, 1, // top, bottom attach
+                                GTK_FILL|GTK_EXPAND, GTK_FILL, // x,y
+                                0, 0);
+            gtk_box_pack_start (
+                        GTK_BOX (book_currency_data->book_currency_vbox),
+                        policy_table, FALSE, FALSE, 0);
+            tip =
+                gnc_currency_accounting_option_gain_loss_account_documentation(
+                        option);
+            widget_label = gtk_label_new( _("Default gain/loss account:") );
+            gtk_misc_set_alignment (GTK_MISC(widget_label), 0.0, 0.5);
+            gtk_widget_set_tooltip_text(
+                        book_currency_data->gain_loss_account_table,
+                        tip && *tip ? _(tip) : "");
+            gtk_table_attach (
+                        GTK_TABLE(book_currency_data->gain_loss_account_table),
+                        widget_label,
+                        0, 2, // left, right attach
+                        0, 1, // top, bottom attach
+                        GTK_FILL, GTK_FILL, // x,y
+                        0, 6);
+            widget_label = NULL;
+            gtk_box_pack_start (
+                        GTK_BOX (book_currency_data->book_currency_vbox),
+                        book_currency_data->gain_loss_account_table,
+                        FALSE, FALSE, 0);
+            gtk_alignment_set_padding (GTK_ALIGNMENT (alignm), 0, 0, 36, 0);
+            gtk_container_add (GTK_CONTAINER (alignm),
+                        book_currency_data->book_currency_vbox);
+            gtk_table_attach_defaults (GTK_TABLE (table), alignm, 0, 2, 1, 2);
         }
         else /* trading or neither */
         {
+            table = gtk_table_new (1, 2, FALSE);
+            gtk_table_attach_defaults (GTK_TABLE (table), widget, 0, 2, 0, 1);
             g_signal_connect(G_OBJECT(widget),
-                         "toggled",
-                         G_CALLBACK(gnc_option_currency_accounting_non_book_cb),
-                         option);
+                        "toggled",
+                        G_CALLBACK(gnc_option_currency_accounting_non_book_cb),
+                        book_currency_data);
         }
-        gtk_box_pack_start (GTK_BOX (vbox1), hbox, FALSE, FALSE, 0);
+        gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
 
         if (label)
             free (label);
@@ -1486,7 +1891,7 @@ gnc_options_dialog_build_contents (GNCOptionWin *propertybox,
 }
 
 /********************************************************************\
- * gnc_options_dialog_build_contents                                *
+ * gnc_options_dialog_build_contents_full                                *
  *   builds an options dialog given a property box and an options   *
  *   database and make the dialog visible depending on the          *
  *   show_dialog flag                                               *
@@ -1692,6 +2097,29 @@ component_close_handler (gpointer data)
     gtk_dialog_response(GTK_DIALOG(window->dialog), GTK_RESPONSE_CANCEL);
 }
 
+static void
+refresh_handler (GHashTable *changes, gpointer user_data)
+{
+    GNCOptionWin *retval = user_data;
+    gnc_commodity *commodity = NULL;
+    GtkTreeIter iter;
+
+    /* The default_gain_loss_account_widget needs to be refreshed if any
+       changes have been made via account maintenance, if it exists and
+       if the book currency widget has a selection */
+
+    if (book_currency_data->default_gain_loss_account_widget &&
+        gtk_combo_box_get_active_iter(
+            GTK_COMBO_BOX(book_currency_data->book_currency_widget), &iter))
+    {
+        commodity = gnc_currency_edit_get_currency(
+                                GNC_CURRENCY_EDIT(
+                                    book_currency_data->book_currency_widget));
+        gnc_set_default_gain_loss_account_widget(commodity);
+        gtk_widget_show_all(book_currency_data->book_currency_vbox);
+    }
+}
+
 /* gnc_options_dialog_new:
  *
  *   - Opens the dialog-options glade file
@@ -1703,7 +2131,7 @@ component_close_handler (gpointer data)
 GNCOptionWin *
 gnc_options_dialog_new(gchar *title)
 {
-    return gnc_options_dialog_new_modal(FALSE, title);
+    return gnc_options_dialog_new_modal(FALSE, title, NULL);
 }
 
 /* gnc_options_dialog_new_modal:
@@ -1713,9 +2141,15 @@ gnc_options_dialog_new(gchar *title)
  *   - Sets the window's title
  *   - Initializes a new GtkNotebook, and adds it to the window
  *   - If modal TRUE, hides 'apply' button
+ *   - If component_class is provided, it is used, otherwise,
+ *     DIALOG_OPTIONS_CM_CLASS is used; this is used to distinguish the
+ *     book-option dialog from report dialogs. The book-option dialog is a
+ *     singleton, so if a dialog already exists it will be raised to the top of
+ *     the window stack instead of creating a new dialog.
  */
 GNCOptionWin *
-gnc_options_dialog_new_modal(gboolean modal, gchar *title)
+gnc_options_dialog_new_modal(gboolean modal, gchar *title,
+                                                    const char *component_class)
 {
     GNCOptionWin *retval;
     GtkBuilder   *builder;
@@ -1784,11 +2218,20 @@ gnc_options_dialog_new_modal(gboolean modal, gchar *title)
     gtk_widget_show(retval->notebook);
     gtk_box_pack_start(GTK_BOX(hbox), retval->notebook, TRUE, TRUE, 5);
 
-    component_id = gnc_register_gui_component (DIALOG_OPTIONS_CM_CLASS,
-                   NULL, component_close_handler,
-                   retval);
+    retval->component_class =
+                (component_class ? component_class : DIALOG_OPTIONS_CM_CLASS);
+    component_id = gnc_register_gui_component (retval->component_class,
+                    refresh_handler, component_close_handler,
+                    retval);
     gnc_gui_component_set_session (component_id, gnc_get_current_session());
 
+    /* Watch account maintenance events only if book option dialog */
+    if (g_strcmp0(retval->component_class, DIALOG_BOOK_OPTIONS_CM_CLASS) == 0)
+    {
+        gnc_gui_component_watch_entity_type (component_id,
+                                         GNC_ID_ACCOUNT,
+                                         QOF_EVENT_MODIFY | QOF_EVENT_DESTROY);
+    }
     g_object_unref(G_OBJECT(builder));
 
     return retval;
@@ -1844,7 +2287,7 @@ gnc_options_dialog_destroy(GNCOptionWin * win)
 {
     if (!win) return;
 
-    gnc_unregister_gui_component_by_data(DIALOG_OPTIONS_CM_CLASS, win);
+    gnc_unregister_gui_component_by_data(win->component_class, win);
 
     gtk_widget_destroy(win->dialog);
 
@@ -1852,6 +2295,7 @@ gnc_options_dialog_destroy(GNCOptionWin * win)
     win->notebook = NULL;
     win->apply_cb = NULL;
     win->help_cb = NULL;
+    win->component_class = NULL;
 
     g_free(win);
 }
@@ -2447,7 +2891,6 @@ gnc_option_set_ui_widget_dateformat (GNCOption *option, GtkBox *page_box,
     return *enclosing;
 }
 
-
 static void
 gnc_plot_size_option_set_select_method(GNCOption *option, gboolean set_buttons)
 {
@@ -3168,114 +3611,85 @@ gnc_option_set_ui_value_currency_accounting (GNCOption *option,
                 return TRUE;
             else
             {
-                GtkWidget *button;
+                GtkWidget *button = NULL;
                 int i;
                 gpointer val;
-                GList *list = NULL;
-                GList *sub_widgets = NULL;
-
-                sub_widgets =
-                    gnc_option_get_ui_widgets_currency_accounting (widget);
-                list = sub_widgets->data;
-                g_list_free(sub_widgets);
 
-                /* stop when list of buttons is pointing at index */
-                for (i = 0; i < index && list; i++)
-                    list = list->next;
-                g_return_val_if_fail (list, TRUE);
+                switch (index)
+                {
+                    case 0:
+                        button = book_currency_data->gnc_currency_radiobutton_0;
+                        break;
+                    case 1:
+                        button = book_currency_data->gnc_currency_radiobutton_1;
+                        break;
+                    case 2:
+                        button = book_currency_data->gnc_currency_radiobutton_2;
+                        break;
+                    default:
+                        return TRUE;
+                }
 
-                button = list->data; /* this is selected button */
-                g_list_free(list);
                 val = g_object_get_data (G_OBJECT (button),
                                             "gnc_radiobutton_index");
                 g_return_val_if_fail (GPOINTER_TO_INT (val) == index, TRUE);
 
-                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-                /* when an unselected button in a group is clicked the clicked
-                   button receives the “toggled” signal, as does the
-                   previously selected button; however, if the first button
-                   is active when the currency-accounting dialog is created,
-                   that is, it's read from the option, the "toggled" handler
-                   is not called while it is if any other button is active.
-                   To get desired result, that is, to set sensitivity to
-                   FALSE, explicitly call the handler here if first button */
-                if (index == 0)
-                    gnc_option_currency_accounting_non_book_cb(button,
-                        (gpointer) option);
                 if (g_strcmp0(gnc_option_permissible_value_name(option,
                                                                  index),
-                                "Use a Book-Currency") == 0)
+                                "Use a Book Currency") == 0)
                 {
-                    GtkWidget *book_currency_widget;
-                    GtkWidget *default_cost_policy_widget;
-                    SCM curr_scm;
-                    SCM list_symbol;
-                    gnc_commodity *commodity;
-                    GList *list_of_policies = NULL;
-
-                    /* note that we have to call this function again here
-                       because the callback routines called above, or
-                       initiated by GTK, change the widget pointers, so we
-                       can't keep and use those called above */
-                    sub_widgets =
-                        gnc_option_get_ui_widgets_currency_accounting
-                                                                   (widget);
-                    list = sub_widgets->data; // needed just to free button list
-                    sub_widgets = sub_widgets->next;
-                    book_currency_widget = sub_widgets->data;
-                    sub_widgets = sub_widgets->next;
-                    default_cost_policy_widget = sub_widgets->data;
-                    g_list_free(sub_widgets);
-                    g_list_free(list);
-                    curr_scm =
+                    gnc_commodity *commodity = NULL;
+                    SCM curr_scm =
                         gnc_currency_accounting_option_value_get_book_currency
-                        (value);
+                            (value);
+                    SCM list_symbol =
+                        gnc_currency_accounting_option_value_get_default_policy
+                            (value);
+                    SCM acct_guid_scm =
+                        gnc_currency_accounting_option_value_get_default_account
+                            (value);
+
                     commodity = gnc_scm_to_commodity (curr_scm);
                     if (commodity)
                     {
-                        gnc_currency_edit_set_currency
-                            (GNC_CURRENCY_EDIT(book_currency_widget),
-                             commodity);
+                        book_currency_data->retrieved_book_currency = commodity;
                     }
                     else
                     {
-                        gnc_currency_edit_set_currency
-                            (GNC_CURRENCY_EDIT(book_currency_widget),
-                             gnc_default_currency());
+                        book_currency_data->retrieved_book_currency = NULL;
                     }
-                    list_of_policies = gnc_get_valid_policy_list();
-                    if (list_of_policies)
+                    if (list_symbol)
                     {
-                        GList *l = NULL;
-                        gint i = 0;
-                        list_symbol =
-                       gnc_currency_accounting_option_value_get_default_policy
-                            (value);
-                        for (l = list_of_policies; l != NULL; l = l->next)
-                        {
-                            /* First item in policy_list is internal name of
-                               policy */
-                            GNCPolicy *pcy = l->data;
-
-                            if (g_strcmp0(PolicyGetName (pcy),
-                                   gnc_scm_symbol_to_locale_string(list_symbol))
-                                   == 0)
-                            {
-                                /* GtkComboBox per-item tooltip changes needed
-                                   below */
-                                gnc_combott_set_active(
-                                    GNC_COMBOTT(default_cost_policy_widget),
-                                    i);
-                            }
-                            i++;
-                        }
-                        g_list_free(list_of_policies);
+                        book_currency_data->retrieved_policy_scm = list_symbol;
                     }
                     else
                     {
-                        gnc_combott_set_active
-                            (GNC_COMBOTT(default_cost_policy_widget), -1);
+                        book_currency_data->retrieved_policy_scm = NULL;
                     }
+                    if (acct_guid_scm)
+                    {
+                        book_currency_data->retrieved_gain_loss_acct_guid_scm =
+                                                                acct_guid_scm;
+                    }
+                    else
+                    {
+                        book_currency_data->retrieved_gain_loss_acct_guid_scm =
+                                                                        NULL;
+                    }
+                }
+                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+                /* when an unselected button in a group is clicked the clicked
+                   button receives the “toggled” signal, as does the
+                   previously selected button; however, if the first button
+                   is active when the currency-accounting dialog is created,
+                   that is, it's read from the option, the "toggled" handler
+                   is not called while it is if any other button is active.
+                   To get desired result, that is, to set sensitivity to
+                   FALSE, explicitly call the handler here if first button */
+                if (index == 0)
+                {
+                    gnc_option_currency_accounting_non_book_cb(button,
+                        (gpointer) book_currency_data);
                 }
                 return FALSE;
             }
@@ -3285,7 +3699,6 @@ gnc_option_set_ui_value_currency_accounting (GNCOption *option,
     return TRUE;
 }
 
-
 /*************************
  *       GET VALUE       *
  *************************
@@ -3618,7 +4031,8 @@ gnc_option_get_ui_value_plot_size (GNCOption *option, GtkWidget *widget)
 }
 
 static SCM
-gnc_option_get_ui_value_currency_accounting (GNCOption *option, GtkWidget *widget)
+gnc_option_get_ui_value_currency_accounting (
+                                        GNCOption *option, GtkWidget *widget)
 {
     gpointer _index;
     int index;
@@ -3629,35 +4043,52 @@ gnc_option_get_ui_value_currency_accounting (GNCOption *option, GtkWidget *widge
 
     /* build the return list in reverse order */
     if (g_strcmp0(gnc_option_permissible_value_name(option, index),
-                  "Use a Book-Currency") == 0)
+                  "Use a Book Currency") == 0)
     {
-        GtkWidget *book_currency_widget;
-        GtkWidget *default_cost_policy_widget;
-        GList *list = NULL; /* needed just to free the button list */
-        GList *sub_widgets = NULL;
-        gnc_commodity *commodity;
+        gnc_commodity *commodity = NULL;
         int policy_index;
         SCM val;
         GList *list_of_policies = NULL;
         const char *str = NULL;
 
-        sub_widgets = gnc_option_get_ui_widgets_currency_accounting (widget);
-        list = sub_widgets->data;
-        sub_widgets = sub_widgets->next;
-        book_currency_widget = sub_widgets->data;
-        sub_widgets = sub_widgets->next;
-        default_cost_policy_widget = sub_widgets->data;
-        g_list_free(sub_widgets);
-        g_list_free(list);
+        if (book_currency_data->default_gain_loss_account_widget)
+        {
+            /* get account from widget, if one selected */
+            Account *gain_loss_account = NULL;
+
+            gain_loss_account =
+                gnc_tree_view_account_get_selected_account
+                    (GNC_TREE_VIEW_ACCOUNT (
+                        book_currency_data->default_gain_loss_account_widget));
+
+            if (gain_loss_account == NULL)
+            {
+                val = SCM_BOOL_F;
+            }
+            else
+            {
+                gchar *gain_loss_account_guid = guid_to_string (
+                                        xaccAccountGetGUID (gain_loss_account));
+
+                val = scm_from_utf8_string (gain_loss_account_guid);
+                g_free (gain_loss_account_guid);
+            }
+        }
+        else
+        {
+            val = SCM_BOOL_F;
+        }
+        value = scm_cons(val, value);
 
-        /* GtkComboBox per-item tooltip changes needed below */
-        policy_index =
-            gnc_combott_get_active(GNC_COMBOTT(default_cost_policy_widget));
         list_of_policies = gnc_get_valid_policy_list();
-        if (list_of_policies)
+        if (list_of_policies && book_currency_data->default_cost_policy_widget)
         {
             GList *l = NULL;
             gint i = 0;
+            /* GtkComboBox per-item tooltip changes needed below */
+            policy_index =
+                gnc_combott_get_active(GNC_COMBOTT(
+                            book_currency_data->default_cost_policy_widget));
             for (l = list_of_policies; l != NULL; l = l->next)
             {
                 GNCPolicy *pcy = l->data;
@@ -3673,14 +4104,29 @@ gnc_option_get_ui_value_currency_accounting (GNCOption *option, GtkWidget *widge
         }
         else
         {
-            val = SCM_EOL;
+            val = SCM_BOOL_F;
         }
         value = scm_cons(val, value);
 
-        commodity =
-            gnc_currency_edit_get_currency(
-                GNC_CURRENCY_EDIT(book_currency_widget));
-        val = gnc_commodity_to_scm(commodity);
+        if (book_currency_data->book_currency_widget)
+        {
+            commodity =
+                gnc_currency_edit_get_currency(
+                    GNC_CURRENCY_EDIT(
+                        book_currency_data->book_currency_widget));
+            if (commodity)
+            {
+                val = gnc_commodity_to_scm(commodity);
+            }
+            else
+            {
+                val = SCM_BOOL_F;
+            }
+        }
+        else
+        {
+            val = SCM_BOOL_F;
+        }
         value = scm_cons(val, value);
     }
 
diff --git a/src/gnome-utils/dialog-options.h b/src/gnome-utils/dialog-options.h
index 4cdcbb1..2ac3a1e 100644
--- a/src/gnome-utils/dialog-options.h
+++ b/src/gnome-utils/dialog-options.h
@@ -35,7 +35,8 @@ typedef struct gnc_option_win GNCOptionWin;
 
 typedef void (* GNCOptionWinCallback)(GNCOptionWin *, gpointer data);
 
-GNCOptionWin * gnc_options_dialog_new_modal(gboolean modal, gchar *title);
+GNCOptionWin * gnc_options_dialog_new_modal(gboolean modal, gchar *title,
+                                                const char *component_class);
 GNCOptionWin * gnc_options_dialog_new(gchar *title);
 GNCOptionWin * gnc_options_dialog_new_w_dialog(gchar *title, GtkWidget *dialog);
 void gnc_options_dialog_destroy(GNCOptionWin * win);
diff --git a/src/gnome-utils/gnc-main-window.c b/src/gnome-utils/gnc-main-window.c
index c8ea31d..19b90a9 100644
--- a/src/gnome-utils/gnc-main-window.c
+++ b/src/gnome-utils/gnc-main-window.c
@@ -106,6 +106,7 @@ enum
 
 #define GNC_MAIN_WINDOW_NAME "GncMainWindow"
 
+#define DIALOG_BOOK_OPTIONS_CM_CLASS "dialog-book-options"
 
 /* Static Globals *******************************************************/
 
@@ -4030,6 +4031,17 @@ gnc_book_options_dialog_close_cb(GNCOptionWin * optionwin,
     gnc_option_db_destroy(options);
 }
 
+static gboolean
+show_handler (const char *class_name, gint component_id,
+              gpointer user_data, gpointer iter_data)
+{
+    GtkWidget *dialog;
+
+    dialog = GTK_WIDGET(user_data);
+    gtk_window_present(GTK_WINDOW(dialog));
+    return(TRUE);
+}
+
 GtkWidget *
 gnc_book_options_dialog_cb (gboolean modal, gchar *title)
 {
@@ -4041,8 +4053,16 @@ gnc_book_options_dialog_cb (gboolean modal, gchar *title)
     qof_book_load_options (book, gnc_option_db_load, options);
     gnc_option_db_clean (options);
 
+    /* Only allow one Book Options dialog if called from file->properties
+       menu */
+    if (gnc_forall_gui_components(DIALOG_BOOK_OPTIONS_CM_CLASS,
+                                  show_handler, NULL))
+    {
+        return NULL;
+    }
     optionwin = gnc_options_dialog_new_modal (modal,
-                (title ? title : _( "Book Options")));
+                (title ? title : _( "Book Options")),
+                DIALOG_BOOK_OPTIONS_CM_CLASS);
     gnc_options_dialog_build_contents (optionwin, options);
 
     gnc_options_dialog_set_book_options_help_cb (optionwin);
diff --git a/src/gnome-utils/gtkbuilder/dialog-options.glade b/src/gnome-utils/gtkbuilder/dialog-options.glade
index 6dce040..313dceb 100644
--- a/src/gnome-utils/gtkbuilder/dialog-options.glade
+++ b/src/gnome-utils/gtkbuilder/dialog-options.glade
@@ -6,7 +6,7 @@
     <property name="can_focus">False</property>
     <property name="title" translatable="yes">GnuCash Options</property>
     <property name="default_width">400</property>
-    <property name="default_height">400</property>
+    <property name="default_height">625</property>
     <property name="type_hint">dialog</property>
     <signal name="response" handler="gnc_options_dialog_response_cb" swapped="no"/>
     <child internal-child="vbox">
@@ -41,6 +41,7 @@
                 <property name="can_focus">True</property>
                 <property name="can_default">True</property>
                 <property name="receives_default">True</property>
+                <property name="tooltip_text" translatable="yes">Close dialog and make no changes.</property>
                 <property name="use_underline">True</property>
               </object>
               <packing>
@@ -56,6 +57,7 @@
                 <property name="can_focus">True</property>
                 <property name="can_default">True</property>
                 <property name="receives_default">True</property>
+                <property name="tooltip_text" translatable="yes">Apply changes but do not close dialog.</property>
                 <property name="use_underline">True</property>
               </object>
               <packing>
@@ -71,6 +73,7 @@
                 <property name="can_focus">True</property>
                 <property name="can_default">True</property>
                 <property name="receives_default">True</property>
+                <property name="tooltip_text" translatable="yes">Apply changes and close dialog.</property>
                 <property name="use_underline">True</property>
               </object>
               <packing>
diff --git a/src/gnome/assistant-hierarchy.c b/src/gnome/assistant-hierarchy.c
index 122cf94..ed8dd1e 100644
--- a/src/gnome/assistant-hierarchy.c
+++ b/src/gnome/assistant-hierarchy.c
@@ -68,6 +68,7 @@ static QofLogModule log_module = GNC_MOD_IMPORT;
 
 #define GNC_PREFS_GROUP           "dialogs.new-hierarchy"
 #define GNC_PREF_SHOW_ON_NEW_FILE "show-on-new-file"
+#define DIALOG_BOOK_OPTIONS_CM_CLASS "dialog-book-options"
 
 typedef enum
 {
@@ -87,6 +88,7 @@ typedef struct
     gboolean next_ok;
 
     GtkWidget *currency_selector;
+    GtkWidget *currency_selector_label;
 
     GtkTreeView *categories_tree;
     GtkTreeRowReference *initial_category;
@@ -124,6 +126,7 @@ void select_all_clicked (GtkButton       *button,
 void clear_all_clicked (GtkButton       *button,
                         hierarchy_data  *data);
 void on_final_account_prepare (hierarchy_data  *data);
+void on_select_currency_prepare (hierarchy_data  *data);
 void on_cancel (GtkAssistant      *gtkassistant, hierarchy_data *data);
 void on_finish (GtkAssistant  *gtkassistant, hierarchy_data *data);
 
@@ -487,12 +490,16 @@ account_categories_tree_view_prepare (hierarchy_data  *data)
 void on_prepare (GtkAssistant  *assistant, GtkWidget *page,
                  hierarchy_data  *data)
 {
+    const int currency_page = data->new_book ? 2 : 1;
     const int selection_page = data->new_book ? 3 : 2;
     const int final_page = data->new_book ? 4 : 3;
     const int current_page = gtk_assistant_get_current_page (assistant);
 
+    if (current_page == currency_page)
+        on_select_currency_prepare (data);
+
     if (current_page == selection_page)
-        on_choose_account_categories_prepare(data);
+        on_choose_account_categories_prepare (data);
 
     if (current_page == final_page)
         on_final_account_prepare (data);
@@ -1074,14 +1081,8 @@ on_finish (GtkAssistant  *gtkassistant,
         gnc_account_foreach_descendant (data->our_account_tree,
                                         (AccountCb)starting_balance_helper,
                                         data);
-
-
     }
 
-    /* Set book options based on the user's choices */
-    if (data->new_book)
-        gnc_book_options_dialog_apply_helper(data->options);
-
     // delete before we suspend GUI events, and then muck with the model,
     // because the model doesn't seem to handle this correctly.
     if (data->initial_category)
@@ -1112,6 +1113,39 @@ on_finish (GtkAssistant  *gtkassistant,
     LEAVE (" ");
 }
 
+/* If a book currency is selected in prior page, set the currency_selector to
+ * the book currency, make insensitive and modify text. Otherwise, restore the
+ * selector to original condition
+  */
+void
+on_select_currency_prepare (hierarchy_data  *data)
+{
+    /* Set book options based on the user's choices */
+    if (data->new_book)
+    {
+        gnc_book_options_dialog_apply_helper(data->options);
+
+        if (gnc_book_use_book_currency (gnc_get_current_book ()))
+        {
+            gnc_currency_edit_set_currency (GNC_CURRENCY_EDIT(data->currency_selector),
+                gnc_book_get_book_currency (gnc_get_current_book ()));
+            gtk_label_set_text (GTK_LABEL(data->currency_selector_label),
+                ( _("You selected a book currency and it will be used for\n" \
+                    "new accounts. Accounts in other currencies must be\n" \
+                    "added manually.") ));
+            gtk_widget_set_sensitive(data->currency_selector, FALSE);
+        }
+        else
+        {
+            gnc_currency_edit_set_currency (GNC_CURRENCY_EDIT(data->currency_selector),
+                gnc_default_currency());
+            gtk_label_set_text (GTK_LABEL(data->currency_selector_label),
+                ( _("Please choose the currency to use for new accounts.") ));
+            gtk_widget_set_sensitive(data->currency_selector, TRUE);
+        }
+    }
+}
+
 /********************************************************
  * For a new book the assistant will also allow the user
  * to set default book options, because this impacts how
@@ -1139,7 +1173,7 @@ book_options_dialog_close_cb(GNCOptionWin * optionwin,
 }
 
 static void
-assistant_instert_book_options_page (hierarchy_data *data)
+assistant_insert_book_options_page (hierarchy_data *data)
 {
     GtkWidget *options, *parent;
     GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
@@ -1150,7 +1184,8 @@ assistant_instert_book_options_page (hierarchy_data *data)
 			   gnc_option_db_load, data->options);
     gnc_option_db_clean (data->options);
 
-    data->optionwin = gnc_options_dialog_new_modal (TRUE, _("New Book Options"));
+    data->optionwin = gnc_options_dialog_new_modal (TRUE, _("New Book Options"),
+                                                DIALOG_BOOK_OPTIONS_CM_CLASS);
     gnc_options_dialog_build_contents_full (data->optionwin, data->options, FALSE);
 
     gnc_options_dialog_set_close_cb (data->optionwin,
@@ -1171,7 +1206,7 @@ assistant_instert_book_options_page (hierarchy_data *data)
 #endif
 
     gtk_widget_show_all (vbox);
-    gtk_assistant_insert_page (GTK_ASSISTANT(data->dialog), vbox, 2);
+    gtk_assistant_insert_page (GTK_ASSISTANT(data->dialog), vbox, 1);
     gtk_assistant_set_page_title (GTK_ASSISTANT(data->dialog), vbox, _("New Book Options"));
     gtk_assistant_set_page_complete (GTK_ASSISTANT(data->dialog), vbox, TRUE);
 
@@ -1224,9 +1259,12 @@ gnc_create_hierarchy_assistant (gboolean use_defaults, GncHierarchyAssistantFini
 
     /* Currency Page */
     data->currency_selector = gnc_currency_edit_new();
-    gnc_currency_edit_set_currency (GNC_CURRENCY_EDIT(data->currency_selector), gnc_default_currency());
+    gnc_currency_edit_set_currency (GNC_CURRENCY_EDIT(data->currency_selector),
+            gnc_default_currency());
     gtk_widget_show (data->currency_selector);
     box = GTK_WIDGET(gtk_builder_get_object (builder, "currency_chooser_hbox"));
+    data->currency_selector_label = GTK_WIDGET(gtk_builder_get_object (builder,
+                                           "choose_currency_label"));
     gtk_box_pack_start(GTK_BOX(box), data->currency_selector, TRUE, TRUE, 0);
 
     /* Categories Page */
@@ -1243,7 +1281,7 @@ gnc_create_hierarchy_assistant (gboolean use_defaults, GncHierarchyAssistantFini
 
     /* Book options page - only on new books */
     if (data->new_book)
-        assistant_instert_book_options_page (data);
+        assistant_insert_book_options_page (data);
 
     /* Final Accounts Page */
     data->final_account_tree_container = GTK_WIDGET(gtk_builder_get_object (builder, "final_account_tree_box"));
diff --git a/src/gnome/gtkbuilder/assistant-hierarchy.glade b/src/gnome/gtkbuilder/assistant-hierarchy.glade
index 497c7fd..f0d4aad 100644
--- a/src/gnome/gtkbuilder/assistant-hierarchy.glade
+++ b/src/gnome/gtkbuilder/assistant-hierarchy.glade
@@ -6,7 +6,7 @@
     <property name="visible">True</property>
     <property name="can_focus">False</property>
     <property name="border_width">12</property>
-    <property name="default_height">550</property>
+    <property name="default_height">800</property>
     <signal name="cancel" handler="on_cancel" swapped="no"/>
     <signal name="close" handler="on_finish" swapped="no"/>
     <signal name="prepare" handler="on_prepare" swapped="no"/>



Summary of changes:
 src/app-utils/app-utils.scm                     |    8 +-
 src/app-utils/business-prefs.scm                |   14 +-
 src/app-utils/gnc-ui-util.c                     |   18 +-
 src/app-utils/option-util.c                     |   45 +
 src/app-utils/option-util.h                     |    2 +
 src/app-utils/options.scm                       |  116 ++-
 src/app-utils/test/test-gnc-ui-util.c           |  130 ++-
 src/app-utils/test/test-option-util.cpp         |   46 +-
 src/engine/engine.i                             |    1 +
 src/gnome-utils/dialog-options.c                | 1100 ++++++++++++++++-------
 src/gnome-utils/dialog-options.h                |    3 +-
 src/gnome-utils/gnc-main-window.c               |   22 +-
 src/gnome-utils/gtkbuilder/dialog-options.glade |    5 +-
 src/gnome/assistant-hierarchy.c                 |   62 +-
 src/gnome/gtkbuilder/assistant-hierarchy.glade  |    2 +-
 15 files changed, 1198 insertions(+), 376 deletions(-)



More information about the gnucash-changes mailing list