gnucash master: Multiple changes pushed

John Ralls jralls at code.gnucash.org
Fri Oct 23 19:54:39 EDT 2015


Updated	 via  https://github.com/Gnucash/gnucash/commit/de264c58 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/e3da1c42 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/b723578c (commit)
	 via  https://github.com/Gnucash/gnucash/commit/39d43a31 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/9fc0c466 (commit)
	from  https://github.com/Gnucash/gnucash/commit/49cd6826 (commit)



commit de264c5832cea7cda9ef2242aa7c799e4780661b
Merge: 49cd682 e3da1c4
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Oct 23 12:14:25 2015 -0700

    Merge branch 'maint'

diff --cc src/libqof/qof/gnc-numeric.cpp
index 8f4ba50,693fdf9..ee63f8d
--- a/src/libqof/qof/gnc-numeric.cpp
+++ b/src/libqof/qof/gnc-numeric.cpp
@@@ -482,11 -1149,7 +482,6 @@@ gnc_numeric_to_decimal(gnc_numeric *a, 
      return TRUE;
  }
  
- gnc_numeric
- gnc_numeric_invert(gnc_numeric num)
- {
-     return static_cast<gnc_numeric>(GncNumeric{num}.inv());
- }
 -
  /* *******************************************************************
   *  double_to_gnc_numeric
   ********************************************************************/

commit e3da1c42474a7e129b64de75a48135941567267a
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Oct 23 12:11:51 2015 -0700

    Revert "Merge branch 'single-price' into maint"
    
    This reverts commit bc9285bbfbb80bb8a38b19fe70117b31874b151f, reversing
    changes made to e921de8b6fe7c47670668019116b7e16155642a5.
    Final step of reverting the single-price changes.

diff --git a/src/app-utils/gnc-sx-instance-model.c b/src/app-utils/gnc-sx-instance-model.c
index cc7dbbf..560fe79 100644
--- a/src/app-utils/gnc-sx-instance-model.c
+++ b/src/app-utils/gnc-sx-instance-model.c
@@ -1170,9 +1170,9 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
                   }
                   else
                   {
-                  exchange = gnc_numeric_invert(gnc_price_get_value(price));
-                  exchange = gnc_numeric_convert(exchange, 1000,
-                                                 GNC_HOW_RND_ROUND_HALF_UP);
+                  exchange = gnc_numeric_div(gnc_numeric_create(1,1),
+                  gnc_price_get_value(price),
+                  1000, GNC_HOW_RND_ROUND_HALF_UP);
                   }
                   }
                   else
@@ -1779,3 +1779,4 @@ GHashTable* gnc_sx_all_instantiate_cashflow_all(GDate range_start, GDate range_e
                                     result_map, NULL);
     return result_map;
 }
+
diff --git a/src/backend/sql/gnc-price-sql.c b/src/backend/sql/gnc-price-sql.c
index 92a5176..d7e6b70 100644
--- a/src/backend/sql/gnc-price-sql.c
+++ b/src/backend/sql/gnc-price-sql.c
@@ -203,7 +203,7 @@ write_price( GNCPrice* p, gpointer data )
     g_return_val_if_fail( p != NULL, FALSE );
     g_return_val_if_fail( data != NULL, FALSE );
 
-    if ( s->is_ok && gnc_price_get_source(p) == PRICE_SOURCE_INVOICE)
+    if ( s->is_ok )
     {
         s->is_ok = save_price( s->be, QOF_INSTANCE(p) );
     }
diff --git a/src/backend/xml/gnc-pricedb-xml-v2.c b/src/backend/xml/gnc-pricedb-xml-v2.c
index 710fa01..fad3ff4 100644
--- a/src/backend/xml/gnc-pricedb-xml-v2.c
+++ b/src/backend/xml/gnc-pricedb-xml-v2.c
@@ -120,7 +120,7 @@ price_parse_xml_sub_node(GNCPrice *p, xmlNodePtr sub_node, QofBook *book)
     {
         char *text = dom_tree_to_text(sub_node);
         if (!text) return FALSE;
-        gnc_price_set_source_string(p, text);
+        gnc_price_set_source(p, text);
         g_free(text);
     }
     else if (g_strcmp0("price:type", (char*)sub_node->name) == 0)
@@ -440,7 +440,7 @@ gnc_price_to_dom_tree(const xmlChar *tag, GNCPrice *price)
     tmpnode = timespec_to_dom_tree("price:time", &timesp);
     if (!add_child_or_kill_parent(price_xml, tmpnode)) return NULL;
 
-    sourcestr = gnc_price_get_source_string(price);
+    sourcestr = gnc_price_get_source(price);
     if (sourcestr && (strlen(sourcestr) != 0))
     {
         tmpnode = text_to_dom_tree("price:source", sourcestr);
diff --git a/src/backend/xml/io-gncxml-v1.c b/src/backend/xml/io-gncxml-v1.c
index 2dff2d0..099ccd6 100644
--- a/src/backend/xml/io-gncxml-v1.c
+++ b/src/backend/xml/io-gncxml-v1.c
@@ -3112,7 +3112,7 @@ price_parse_xml_sub_node(GNCPrice *p, xmlNodePtr sub_node, QofBook *book)
     {
         char *text = dom_tree_to_text(sub_node);
         if (!text) return FALSE;
-        gnc_price_set_source_string(p, text);
+        gnc_price_set_source(p, text);
         g_free(text);
     }
     else if (g_strcmp0("price:type", (char*)sub_node->name) == 0)
diff --git a/src/business/business-gnome/dialog-invoice.c b/src/business/business-gnome/dialog-invoice.c
index 10c4d75..e840742 100644
--- a/src/business/business-gnome/dialog-invoice.c
+++ b/src/business/business-gnome/dialog-invoice.c
@@ -901,8 +901,11 @@ gnc_invoice_post(InvoiceWindow *iw, struct post_invoice_params *post_params)
             gnc_price_set_commodity (convprice, account_currency);
             gnc_price_set_currency (convprice, gncInvoiceGetCurrency (invoice));
             gnc_price_set_time (convprice, postdate);
-            gnc_price_set_source (convprice, PRICE_SOURCE_INVOICE);
-            gnc_price_set_typestr (convprice, PRICE_TYPE_LAST);
+            gnc_price_set_source (convprice, "user:invoice-post");
+
+            /* Yes, magic strings are evil but I can't find any defined constants
+               for this..*/
+            gnc_price_set_typestr (convprice, "last");
             gnc_price_set_value (convprice, exch_rate);
             gncInvoiceAddPrice(invoice, convprice);
             gnc_price_commit_edit (convprice);
@@ -1699,7 +1702,7 @@ gnc_invoice_update_window (InvoiceWindow *iw, GtkWidget *widget)
     }
 
     /* Set the type label */
-    gtk_label_set_text (GTK_LABEL(iw->type_label), iw->is_credit_note ? _("Credit Note")
+    gtk_label_set_text (GTK_LABEL(iw->type_label), iw->is_credit_note ? _("Credit Note") 
                         : gtk_label_get_text (GTK_LABEL(iw->type_label)));
 
     if (iw->owner_choice)
@@ -1817,14 +1820,14 @@ gnc_invoice_update_window (InvoiceWindow *iw, GtkWidget *widget)
             gtk_widget_hide (hide);
             hide = GTK_WIDGET (gtk_builder_get_object (iw->builder, "hide4"));
             gtk_widget_hide (hide);
-
+            
             show = GTK_WIDGET (gtk_builder_get_object (iw->builder, "posted_label"));
             gtk_widget_show (show);
             gtk_widget_show (iw->posted_date_hbox);
             show = GTK_WIDGET (gtk_builder_get_object (iw->builder, "acct_label"));
             gtk_widget_show (show);
             gtk_widget_show (acct_entry);
-
+            
             show = GTK_WIDGET (gtk_builder_get_object (iw->builder, "hide1"));
             gtk_widget_show (show);
             show = GTK_WIDGET (gtk_builder_get_object (iw->builder, "hide2"));
@@ -2344,17 +2347,17 @@ gnc_invoice_create_page (InvoiceWindow *iw, gpointer page)
         {
         case GNC_OWNER_VENDOR:
             gtk_label_set_text (GTK_LABEL(iw->info_label),  _("Bill Information"));
-            gtk_label_set_text (GTK_LABEL(iw->type_label),  _("Bill"));
-            gtk_label_set_text (GTK_LABEL(iw->id_label),  _("Bill ID"));
+            gtk_label_set_text (GTK_LABEL(iw->type_label),  _("Bill")); 
+            gtk_label_set_text (GTK_LABEL(iw->id_label),  _("Bill ID")); 
             break;
         case GNC_OWNER_EMPLOYEE:
             gtk_label_set_text (GTK_LABEL(iw->info_label),  _("Voucher Information"));
             gtk_label_set_text (GTK_LABEL(iw->type_label),  _("Voucher"));
-            gtk_label_set_text (GTK_LABEL(iw->id_label),  _("Voucher ID"));
+            gtk_label_set_text (GTK_LABEL(iw->id_label),  _("Voucher ID")); 
         default:
             break;
         }
-
+    
     entry_ledger = gnc_entry_ledger_new (iw->book, ledger_type);
 
     /* Save the ledger... */
@@ -2427,7 +2430,7 @@ gnc_invoice_window_new_invoice (InvoiceDialogType dialog_type, QofBook *bookp,
     const GncOwner *start_owner;
     GncBillTerm *owner_terms = NULL;
     GncOwnerType owner_type;
-
+    
     g_assert (dialog_type == NEW_INVOICE || dialog_type == MOD_INVOICE || dialog_type == DUP_INVOICE);
 
     if (invoice)
@@ -2510,20 +2513,20 @@ gnc_invoice_window_new_invoice (InvoiceDialogType dialog_type, QofBook *bookp,
     iw->id_label = GTK_WIDGET (gtk_builder_get_object (builder, "label14"));
     iw->info_label = GTK_WIDGET (gtk_builder_get_object (builder, "label1"));
     invoice_radio = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_invoice_type"));
-
+     
     iw->type_hbox = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_type_choice_hbox"));
     iw->type_choice = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_type_invoice"));
-
+    
     /* The default GUI lables are for invoices, so change them if it isn't. */
     owner_type = gncOwnerGetType (&iw->owner);
     switch(owner_type)
     {
         case GNC_OWNER_VENDOR:
             gtk_label_set_text (GTK_LABEL(iw->info_label),  _("Bill Information"));
-            gtk_label_set_text (GTK_LABEL(iw->type_label),  _("Bill"));
+            gtk_label_set_text (GTK_LABEL(iw->type_label),  _("Bill")); 
             gtk_button_set_label (GTK_BUTTON(invoice_radio),  _("Bill"));
             gtk_label_set_text (GTK_LABEL(iw->id_label),  _("Bill ID"));
-
+             
             break;
         case GNC_OWNER_EMPLOYEE:
             gtk_label_set_text (GTK_LABEL(iw->info_label),  _("Voucher Information"));
@@ -2533,7 +2536,7 @@ gnc_invoice_window_new_invoice (InvoiceDialogType dialog_type, QofBook *bookp,
         default:
         break;
     }
-
+    
     /* configure the type related widgets based on dialog type and invoice type */
     switch (dialog_type)
     {
@@ -3303,3 +3306,4 @@ gnc_invoice_remind_bills_due_cb (void)
 
     gnc_invoice_remind_bills_due();
 }
+
diff --git a/src/engine/engine.i b/src/engine/engine.i
index f11d309..bed289b 100644
--- a/src/engine/engine.i
+++ b/src/engine/engine.i
@@ -354,7 +354,7 @@ KvpValue * kvp_frame_get_slot_path_gslist (KvpFrame *frame, GSList *key_path);
     SET_ENUM("TRANS-DATE-POSTED");
     SET_ENUM("TRANS-DESCRIPTION");
     SET_ENUM("TRANS-NUM");
-
+    
     SET_ENUM("KVP-OPTION-PATH");
 
     SET_ENUM("OPTION-SECTION-ACCOUNTS");
@@ -375,15 +375,6 @@ KvpValue * kvp_frame_get_slot_path_gslist (KvpFrame *frame, GSList *key_path);
     SET_ENUM("GNC-HOW-RND-ROUND");
     SET_ENUM("GNC-HOW-RND-NEVER");
 
-    SET_ENUM("PRICE-SOURCE-EDIT-DLG");
-    SET_ENUM("PRICE-SOURCE-FQ");
-    SET_ENUM("PRICE-SOURCE-USER-PRICE");
-    SET_ENUM("PRICE-SOURCE-XFER-DLG-VAL");
-    SET_ENUM("PRICE-SOURCE-SPLIT-REG");
-    SET_ENUM("PRICE-SOURCE-STOCK-SPLIT");
-    SET_ENUM("PRICE-SOURCE-INVOICE");
-    SET_ENUM("PRICE-SOURCE-INVALID");
-
 #undef SET_ENUM
   }
 
diff --git a/src/engine/gnc-pricedb-p.h b/src/engine/gnc-pricedb-p.h
index 8d867da..d93747b 100644
--- a/src/engine/gnc-pricedb-p.h
+++ b/src/engine/gnc-pricedb-p.h
@@ -39,7 +39,7 @@ struct gnc_price_s
     gnc_commodity *commodity;
     gnc_commodity *currency;
     Timespec tmspec;
-    PriceSource source;
+    char *source;
     char *type;
     gnc_numeric value;
 
diff --git a/src/engine/gnc-pricedb.c b/src/engine/gnc-pricedb.c
index bdc8e41..54b7385 100644
--- a/src/engine/gnc-pricedb.c
+++ b/src/engine/gnc-pricedb.c
@@ -58,32 +58,9 @@ gnc_price_init(GNCPrice* price)
     price->refcount = 1;
     price->value = gnc_numeric_zero();
     price->type = NULL;
-    price->source = PRICE_SOURCE_INVALID;
+    price->source = NULL;
 }
 
-/* Array of char constants for converting price-source enums. Be sure to keep in
- * sync with the enum values in gnc-pricedb.h The string user:price-editor is
- * explicitly used by price_to_gui() in dialog-price-editor.c and the string
- * Finance::Quote is explicitly used by fq-results->commod-tz-quote-triples in
- * price-quotes.scm. Take care to keep them in sync if you make changes. Beware
- * that the strings are used to store the enum values in the backends so any
- * changes will affect backward data compatibility.
- */
-static const char* source_names[] =
-{
-    /* sync with price_to_gui in dialog-price-editor.c */
-    "user:price-editor",
-    /* sync with commidity-tz-quote->price in price-quotes.scm */
-    "Finance::Quote",
-    "user:price",
-    /* String retained for backwards compatibility. */
-    "user:xfer-dialog",
-    "user:split-register",
-    "user:stock-split",
-    "user:invoice-post",
-    "invalid"
-};
-
 static void
 gnc_price_dispose(GObject *pricep)
 {
@@ -113,7 +90,7 @@ gnc_price_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec
     switch (prop_id)
     {
     case PROP_SOURCE:
-        g_value_set_string(value, gnc_price_get_source_string(price));
+        g_value_set_string(value, price->source);
         break;
     case PROP_TYPE:
         g_value_set_string(value, price->type);
@@ -149,7 +126,7 @@ gnc_price_set_property(GObject* object, guint prop_id, const GValue* value, GPar
     switch (prop_id)
     {
     case PROP_SOURCE:
-        gnc_price_set_source_string(price, g_value_get_string(value));
+        gnc_price_set_source(price, g_value_get_string(value));
         break;
     case PROP_TYPE:
         gnc_price_set_typestr(price, g_value_get_string(value));
@@ -211,10 +188,10 @@ gnc_price_class_init(GNCPriceClass *klass)
      PROP_SOURCE,
      g_param_spec_string ("source",
                           "Price source",
-                          "The price source is PriceSource enum describing how"
-                          " the price was created. This property works on the"
-                          " string values in source_names for SQL database"
-                          " compatibility.",
+                          "The price source is a string describing the "
+                          "source of a price quote.  It will be something "
+                          "like this: 'Finance::Quote', 'user:misc', "
+                          "'user:foo', etc.",
                           NULL,
                           G_PARAM_READWRITE));
 
@@ -275,6 +252,7 @@ gnc_price_destroy (GNCPrice *p)
     qof_event_gen (&p->inst, QOF_EVENT_DESTROY, NULL);
 
     if (p->type) CACHE_REMOVE(p->type);
+    if (p->source) CACHE_REMOVE(p->source);
 
     /* qof_instance_release (&p->inst); */
     g_object_unref(p);
@@ -461,29 +439,22 @@ gnc_price_set_time(GNCPrice *p, Timespec t)
 }
 
 void
-gnc_price_set_source(GNCPrice *p, PriceSource s)
-{
-    if (!p) return;
-    gnc_price_begin_edit (p);
-    p->source = s;
-    gnc_price_set_dirty(p);
-    gnc_price_commit_edit(p);
-}
-
-void
-gnc_price_set_source_string(GNCPrice *p, const char* str)
+gnc_price_set_source(GNCPrice *p, const char *s)
 {
     if (!p) return;
-    for (PriceSource s = PRICE_SOURCE_EDIT_DLG;
-         s < PRICE_SOURCE_INVALID; ++s)
-        if (strcmp(source_names[s], str) == 0)
-        {
-            gnc_price_set_source(p, s);
-            return;
-        }
-
+    if (g_strcmp0(p->source, s) != 0)
+    {
+        char *tmp;
 
+        gnc_price_begin_edit (p);
+        tmp = CACHE_INSERT((gpointer) s);
+        if (p->source) CACHE_REMOVE(p->source);
+        p->source = tmp;
+        gnc_price_set_dirty(p);
+        gnc_price_commit_edit (p);
+    }
 }
+
 void
 gnc_price_set_typestr(GNCPrice *p, const char* type)
 {
@@ -547,18 +518,11 @@ gnc_price_get_time(const GNCPrice *p)
     return p->tmspec;
 }
 
-PriceSource
+const char *
 gnc_price_get_source(const GNCPrice *p)
 {
-    if (!p) return PRICE_SOURCE_INVALID;
-    return p->source;
-}
-
-const char*
-gnc_price_get_source_string(const GNCPrice *p)
-{
     if (!p) return NULL;
-    return source_names[p->source];
+    return p->source;
 }
 
 const char *
@@ -609,7 +573,8 @@ gnc_price_equal (const GNCPrice *p1, const GNCPrice *p2)
     if (!timespec_equal (&ts1, &ts2))
         return FALSE;
 
-    if (gnc_price_get_source (p1) != gnc_price_get_source (p2))
+    if (g_strcmp0 (gnc_price_get_source (p1),
+                   gnc_price_get_source (p2)) != 0)
         return FALSE;
 
     if (g_strcmp0 (gnc_price_get_typestr (p1),
@@ -1001,18 +966,6 @@ gnc_pricedb_equal (GNCPriceDB *db1, GNCPriceDB *db2)
     return equal_data.equal;
 }
 
-static gboolean
-insert_or_replace_price(GNCPriceDB *db, GNCPrice *p)
-{
-    GNCPrice *old_price = gnc_pricedb_lookup_day (db, p->commodity,
-                                                  p->currency, p->tmspec);
-    if (old_price == NULL)
-        return TRUE;
-    if (p->source < old_price->source)
-        return TRUE;
-    return FALSE;
-
-}
 /* ==================================================================== */
 /* The add_price() function is a utility that only manages the
  * dual hash table instertion */
@@ -1077,12 +1030,6 @@ add_price(GNCPriceDB *db, GNCPrice *p)
         LEAVE (" no price list");
         return FALSE;
     }
-
-    if (!insert_or_replace_price(db, p))
-    {
-        LEAVE("A better price already exists");
-        return FALSE;
-    }
     g_hash_table_insert(currency_hash, currency, price_list);
     p->db = db;
     qof_event_gen (&p->inst, QOF_EVENT_ADD, NULL);
@@ -1245,7 +1192,7 @@ static gboolean
 check_one_price_date (GNCPrice *price, gpointer user_data)
 {
     remove_info *data = user_data;
-    PriceSource source;
+    const gchar *source;
     Timespec pt;
 
     ENTER("price %p (%s), data %p", price,
@@ -1254,7 +1201,7 @@ check_one_price_date (GNCPrice *price, gpointer user_data)
     if (!data->delete_user)
     {
         source = gnc_price_get_source (price);
-        if (source != PRICE_SOURCE_FQ)
+        if (g_strcmp0(source, "Finance::Quote") != 0)
         {
             LEAVE("Not an automatic quote");
             return TRUE;
@@ -2507,8 +2454,8 @@ gnc_price_print(GNCPrice *p, FILE *f, int indent)
     str = str ? str : "(null)";
     fprintf(f, "%s    <cmdty:ref-id>%s</cmdty:ref-id>\n", istr, str);
     fprintf(f, "%s  </pdb:currency>\n", istr);
-    str = source_names[gnc_price_get_source(p)];
-    str = str ? str : "invalid";
+    str = gnc_price_get_source(p);
+    str = str ? str : "(null)";
     fprintf(f, "%s  %s\n", istr, str);
     str = gnc_price_get_typestr(p);
     str = str ? str : "(null)";
diff --git a/src/engine/gnc-pricedb.h b/src/engine/gnc-pricedb.h
index e3966b3..ce077a5 100644
--- a/src/engine/gnc-pricedb.h
+++ b/src/engine/gnc-pricedb.h
@@ -156,26 +156,6 @@ GType gnc_pricedb_get_type(void);
 typedef struct gnc_price_lookup_s GNCPriceLookup;
 typedef GList PriceList;
 
-/** Price source enum. Be sure to keep in sync with the source_name array in
- * gnc-pricedb.c. These are in preference order, so for example a quote with
- * PRICE_SOURCE_EDIT_DLG will overwrite one with PRICE_SOURCE_FQ but not the
- * other way around.
- */
-typedef enum
-{
-    PRICE_SOURCE_EDIT_DLG,         // "user:price-editor"
-    PRICE_SOURCE_FQ,               // "Finance::Quote"
-    PRICE_SOURCE_USER_PRICE,       // "user:price"
-    PRICE_SOURCE_XFER_DLG_VAL,     // "user:xfer-dialog"
-    PRICE_SOURCE_SPLIT_REG,        // "user:split-register"
-    PRICE_SOURCE_STOCK_SPLIT,      // "user:stock-split"
-    PRICE_SOURCE_INVOICE,          // "user:invoice-post"
-    PRICE_SOURCE_INVALID,
-} PriceSource;
-
-#define PRICE_TYPE_LAST "last"
-#define PRICE_TYPE_UNK "unknown"
-#define PRICE_TYPE_TRN "transaction"
 /* ------------------ */
 /** @name Constructors
     @{ */
@@ -222,8 +202,7 @@ void gnc_price_commit_edit (GNCPrice *p);
 void gnc_price_set_commodity(GNCPrice *p, gnc_commodity *c);
 void gnc_price_set_currency(GNCPrice *p, gnc_commodity *c);
 void gnc_price_set_time(GNCPrice *p, Timespec t);
-void gnc_price_set_source(GNCPrice *p, PriceSource source);
-void gnc_price_set_source_string(GNCPrice *p, const char* s);
+void gnc_price_set_source(GNCPrice *p, const char *source);
 void gnc_price_set_typestr(GNCPrice *p, const char* type);
 void gnc_price_set_value(GNCPrice *p, gnc_numeric value);
 /** @} */
@@ -234,14 +213,13 @@ void gnc_price_set_value(GNCPrice *p, gnc_numeric value);
     to the GNCPrice, not copies, so don't free these values.
     @{ */
 
-    GNCPrice *      gnc_price_lookup (const GncGUID *guid, QofBook *book);
+GNCPrice *      gnc_price_lookup (const GncGUID *guid, QofBook *book);
 /*@ dependent @*/
 gnc_commodity * gnc_price_get_commodity(const GNCPrice *p);
 /*@ dependent @*/
 gnc_commodity * gnc_price_get_currency(const GNCPrice *p);
 Timespec        gnc_price_get_time(const GNCPrice *p);
-PriceSource     gnc_price_get_source(const GNCPrice *p);
-const char *    gnc_price_get_source_string(const GNCPrice *p);
+const char *    gnc_price_get_source(const GNCPrice *p);
 const char *    gnc_price_get_typestr(const GNCPrice *p);
 gnc_numeric     gnc_price_get_value(const GNCPrice *p);
 gboolean        gnc_price_equal(const GNCPrice *p1, const GNCPrice *p2);
@@ -256,15 +234,6 @@ gboolean        gnc_price_equal(const GNCPrice *p1, const GNCPrice *p2);
 /** This simple function can be useful for debugging the price code */
 void gnc_price_print(GNCPrice *db, FILE *f, int indent);
 /** @} */
-/** @name Denominator Constants Price policy: In order to avoid rounding
- * problems, currency prices (often called exchange rates) are saved in terms of
- * the smaller currency, so that price > 1, with a fixed denominator of
- * 1/1000. Commodity prices in currency are always expressed as value per unit
- * of the commodity with a fixed denominator of the pricing currency's
- * SCU * 10000.
- */
-#define CURRENCY_DENOM 10000
-#define COMMODITY_DENOM_MULT 10000
 
 /* ================================================================ */
 /** @name GNCPrice lists
diff --git a/src/engine/test-core/test-engine-stuff.c b/src/engine/test-core/test-engine-stuff.c
index 1415b6b..fa63449 100644
--- a/src/engine/test-core/test-engine-stuff.c
+++ b/src/engine/test-core/test-engine-stuff.c
@@ -676,7 +676,6 @@ void
 make_random_changes_to_price (QofBook *book, GNCPrice *p)
 {
     Timespec *ts;
-    PriceSource ps;
     char *string;
     gnc_commodity *c;
 
@@ -694,9 +693,9 @@ make_random_changes_to_price (QofBook *book, GNCPrice *p)
     gnc_price_set_time (p, *ts);
     g_free (ts);
 
-    ps = (PriceSource)get_random_int_in_range((int)PRICE_SOURCE_EDIT_DLG,
-                                              (int)PRICE_SOURCE_INVALID);
-    gnc_price_set_source (p, ps);
+    string = get_random_string ();
+    gnc_price_set_source (p, string);
+    g_free (string);
 
     string = get_random_string ();
     gnc_price_set_typestr (p, string);
diff --git a/src/gnome-utils/dialog-transfer.c b/src/gnome-utils/dialog-transfer.c
index 18e76c4..cd87d46 100644
--- a/src/gnome-utils/dialog-transfer.c
+++ b/src/gnome-utils/dialog-transfer.c
@@ -55,6 +55,8 @@
 #define DIALOG_TRANSFER_CM_CLASS "dialog-transfer"
 #define GNC_PREFS_GROUP "dialogs.transfer"
 
+#define PRECISION 1000000
+
 typedef enum
 {
     XFER_DIALOG_FROM,
@@ -67,62 +69,61 @@ static QofLogModule log_module = GNC_MOD_GUI;
 
 struct _xferDialog
 {
-    GtkWidget *dialog;
-    GtkWidget *amount_edit;
-    GtkWidget *date_entry;
-    GtkWidget *num_entry;
-    GtkWidget *description_entry;
-    GtkWidget *memo_entry;
-    GtkWidget *conv_forward;
-    GtkWidget *conv_reverse;
-
-    GtkWidget *from_window;
+    GtkWidget * dialog;
+
+    GtkWidget * amount_edit;
+    GtkWidget * date_entry;
+    GtkWidget * num_entry;
+    GtkWidget * description_entry;
+    GtkWidget * memo_entry;
+    GtkWidget * conv_forward;
+    GtkWidget * conv_reverse;
+
+    GtkWidget *	from_window;
     GtkTreeView * from_tree_view;
-    gnc_commodity *from_commodity;
-    GtkWidget *to_window;
-    GtkTreeView *to_tree_view;
-    gnc_commodity *to_commodity;
+    gnc_commodity *	from_commodity;
+    GtkWidget *	to_window;
+    GtkTreeView * to_tree_view;
+    gnc_commodity *	to_commodity;
 
-    QuickFill *qf;     /* Quickfill on transfer descriptions,
-                          defaults to matching on the "From" account. */
+    QuickFill * qf;     /* Quickfill on transfer descriptions,
+                         defaults to matching on the "From" account. */
 
-    XferDirection quickfill;    /* direction match on the account instead. */
+    XferDirection quickfill;	/* direction match on the account instead. */
 
     /* stored data for the description quickfill selection function */
     gint desc_start_selection;
     gint desc_end_selection;
     guint desc_selection_source_id;
 
-    GtkWidget *transferinfo_label;
+    GtkWidget * transferinfo_label;
 
-    GtkWidget *from_transfer_label;
-    GtkWidget *to_transfer_label;
+    GtkWidget * from_transfer_label;
+    GtkWidget * to_transfer_label;
 
-    GtkWidget *from_currency_label;
-    GtkWidget *to_currency_label;
+    GtkWidget * from_currency_label;
+    GtkWidget * to_currency_label;
 
-    GtkWidget *from_show_button;
-    GtkWidget *to_show_button;
+    GtkWidget * from_show_button;
+    GtkWidget * to_show_button;
 
-    GtkWidget *curr_xfer_table;
+    GtkWidget * curr_xfer_table;
 
-    GtkWidget *price_edit;
-    GtkWidget *to_amount_edit;
+    GtkWidget * price_edit;
+    GtkWidget * to_amount_edit;
 
-    GtkWidget *price_radio;
-    GtkWidget *amount_radio;
+    GtkWidget * price_radio;
+    GtkWidget * amount_radio;
 
-    GtkWidget *fetch_button;
+    GtkWidget * fetch_button;
 
-    QofBook *book;
-    GNCPriceDB *pricedb;
+    QofBook *	book;
+    GNCPriceDB *	pricedb;
 
     /* Where to store the "exchange_rate" at exit (in lieu of
      * creating a transaction)
      */
-    gnc_numeric *exch_rate;
-    PriceSource price_source;
-    const char *price_type;
+    gnc_numeric * exch_rate;
 
     /* Callback function to notify of the newly created Transaction */
     gnc_xfer_dialog_cb transaction_cb;
@@ -156,11 +157,10 @@ static void gnc_xfer_update_to_amount (XferDialog *xferData);
 static void gnc_xfer_dialog_update_conv_info(XferDialog *xferData);
 
 static Account *gnc_transfer_dialog_get_selected_account (XferDialog *dialog,
-                                                          XferDirection direction);
+        XferDirection direction);
 static void gnc_transfer_dialog_set_selected_account (XferDialog *dialog,
-                                                      Account *account,
-                                                      XferDirection direction);
-static void _gnc_xfer_dialog_set_price_edit(XferDialog*, gnc_numeric);
+        Account *account,
+        XferDirection direction);
 
 void gnc_xfer_description_insert_cb(GtkEditable *editable,
                                     const gchar *insert_text,
@@ -168,11 +168,11 @@ void gnc_xfer_description_insert_cb(GtkEditable *editable,
                                     gint *start_pos,
                                     XferDialog *xferData);
 gboolean gnc_xfer_description_key_press_cb( GtkEntry *entry,
-                                            GdkEventKey *event,
-                                            XferDialog *xferData );
+        GdkEventKey *event,
+        XferDialog *xferData );
 void gnc_xfer_dialog_fetch (GtkButton *button, XferDialog *xferData);
 gboolean gnc_xfer_dialog_inc_exp_filter_func (Account *account,
-                                              gpointer data);
+        gpointer data);
 void price_amount_radio_toggled_cb(GtkToggleButton *togglebutton, gpointer data);
 
 void gnc_xfer_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data);
@@ -181,7 +181,7 @@ void gnc_xfer_dialog_close_cb(GtkDialog *dialog, gpointer data);
 /** Implementations **********************************************/
 
 static gnc_numeric
-gnc_xfer_dialog_compute_price_value (XferDialog *xferData)
+gnc_xfer_dialog_compute_price (XferDialog *xferData)
 {
     gnc_numeric from_amt, to_amt;
     g_return_val_if_fail (xferData != NULL, gnc_numeric_error (GNC_ERROR_ARG));
@@ -192,131 +192,16 @@ gnc_xfer_dialog_compute_price_value (XferDialog *xferData)
     return(gnc_numeric_div(to_amt, from_amt, GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE));
 }
 
-/* Round a price value according to this policy:
- * If both commodities are currencies, round to a fixed denominator.
- * If only one is a currency, round to the currency's scu * a fixed factor.
- * The fixed values are defined in gnc-pricedb.h
- */
-static gnc_numeric
-round_price(gnc_commodity *from, gnc_commodity *to, gnc_numeric value)
-{
-    if (gnc_commodity_is_currency(from) && gnc_commodity_is_currency(to))
-        value = gnc_numeric_convert(value, CURRENCY_DENOM,
-                                    GNC_HOW_RND_ROUND_HALF_UP);
-    else if (gnc_commodity_is_currency(to))
-    {
-        int scu = gnc_commodity_get_fraction (to);
-        value = gnc_numeric_convert(value, scu * COMMODITY_DENOM_MULT,
-                                    GNC_HOW_RND_ROUND_HALF_UP);
-    }
-    else if (gnc_commodity_is_currency(from))
-    {
-        int scu = gnc_commodity_get_fraction (from);
-        value = gnc_numeric_convert(value, scu * COMMODITY_DENOM_MULT,
-                                    GNC_HOW_RND_ROUND_HALF_UP);
-    }
-    return value;
-}
-
-typedef enum
-{
-    SAME_DAY,
-    NEAREST,
-    LATEST
-} PriceDate;
-
-typedef struct
-{
-    GNCPrice *price;
-    GNCPriceDB *pricedb;
-    gnc_commodity *from;
-    gnc_commodity *to;
-    Timespec ts;
-    gboolean reverse;
-} PriceReq;
-
-static void
-price_request_from_xferData(PriceReq *pr, XferDialog *xd)
-{
-    g_return_if_fail (pr != NULL);
-    g_return_if_fail (xd != NULL);
-    pr->price = NULL;
-    pr->pricedb = xd->pricedb;
-    pr->from = xd->from_commodity;
-    pr->to = xd->to_commodity;
-    pr->ts = gnc_date_edit_get_date_ts (GNC_DATE_EDIT (xd->date_entry));
-    pr->reverse = FALSE;
-}
-
-static gboolean
-lookup_price(PriceReq *pr, PriceDate pd)
-{
-    GNCPrice *prc = NULL;
-    g_return_val_if_fail (pr != NULL, FALSE);
-    g_return_val_if_fail (pr->pricedb != NULL, FALSE);
-    g_return_val_if_fail (pr->from != NULL, FALSE);
-    g_return_val_if_fail (pr->to != NULL, FALSE);
-
-    pr->reverse = FALSE;
-    switch (pd)
-    {
-        default:
-        case SAME_DAY:
-            prc = gnc_pricedb_lookup_day (pr->pricedb, pr->from,
-                                          pr->to, pr->ts);
-            if (!prc)
-            {
-                prc = gnc_pricedb_lookup_day (pr->pricedb, pr->to,
-                                              pr->from, pr->ts);
-                pr->reverse = TRUE;
-            }
-        break;
-        case NEAREST:
-            prc = gnc_pricedb_lookup_nearest_in_time (pr->pricedb, pr->from,
-                                                      pr->to, pr->ts);
-            if (!prc)
-            {
-                prc = gnc_pricedb_lookup_nearest_in_time (pr->pricedb, pr->to,
-                                                          pr->from, pr->ts);
-                pr->reverse = TRUE;
-            }
-        break;
-        case LATEST:
-            prc = gnc_pricedb_lookup_latest (pr->pricedb, pr->from, pr->to);
-            if (!prc)
-            {
-                prc = gnc_pricedb_lookup_latest (pr->pricedb, pr->to, pr->from);
-                pr->reverse = TRUE;
-            }
-            break;
-    }
-    if (pr->reverse)
-    {
-        PINFO("Found reverse price: 1 %s = %f %s",
-              gnc_commodity_get_mnemonic(pr->to),
-              gnc_numeric_to_double(gnc_price_get_value(prc)),
-              gnc_commodity_get_mnemonic(pr->from));
-
-    }
-    else
-    {
-        PINFO("Found price: 1 %s = %f %s",
-              gnc_commodity_get_mnemonic(pr->from),
-              gnc_numeric_to_double(gnc_price_get_value(prc)),
-              gnc_commodity_get_mnemonic(pr->to));
-    }
-    if (!prc)
-        return FALSE;
-    pr->price = prc;
-    return TRUE;
-}
-
 /* (maybe) update the price from the pricedb. */
 static void
 gnc_xfer_dialog_update_price (XferDialog *xferData)
 {
-    PriceReq pr;
-    gnc_numeric price_value;
+    GNCPrice *prc;
+    gnc_numeric price;
+    Timespec date;
+    gnc_commodity *from = xferData->from_commodity;
+    gnc_commodity *to = xferData->to_commodity;
+    gboolean reverse;
 
     if (!xferData) return;
     if (!xferData->from_commodity || ! xferData->to_commodity) return;
@@ -324,19 +209,59 @@ gnc_xfer_dialog_update_price (XferDialog *xferData)
         return;
     if (!xferData->pricedb) return;
 
-    price_request_from_xferData(&pr, xferData);
-    if (!lookup_price(&pr, SAME_DAY))
-        if (!lookup_price(&pr, NEAREST))
+    /* when do we update, and when do we NOT update? */
+
+    /* XXX: I'm ALWAYS going to update whenever we get called */
+
+    /* grab the price on the same day or nearest to the DATE out of the pricedb */
+    date = gnc_date_edit_get_date_ts (GNC_DATE_EDIT (xferData->date_entry));
+
+    /* Look for a price on the same day or, failing that, closest in time. */
+    prc = gnc_pricedb_lookup_day (xferData->pricedb, from, to, date);
+    reverse = FALSE;
+
+    if (!prc)
+    {
+        /* Look for reverse price on same day */
+        prc = gnc_pricedb_lookup_day (xferData->pricedb, to, from, date);
+        reverse = TRUE;
+    }
+
+    if (!prc)
+    {
+        /* Didn't find one on the same day, look for nearest in time */
+        prc = gnc_pricedb_lookup_nearest_in_time (xferData->pricedb, from,
+                to, date);
+        reverse = FALSE;
+    }
+
+    if (!prc)
+    {
+        prc = gnc_pricedb_lookup_nearest_in_time (xferData->pricedb, to,
+                from, date);
+        reverse = TRUE;
+    }
+
+    if (!prc)
         return;
 
     /* grab the price from the pricedb */
-    price_value = gnc_price_get_value (pr.price);
-    if (pr.reverse)
-        price_value = gnc_numeric_invert (price_value);
-    gnc_price_unref(pr.price);
+    price = gnc_price_get_value (prc);
+    if (reverse)
+    {
+        PINFO("Found reverse price: 1 %s = %f %s", gnc_commodity_get_mnemonic(to),
+              gnc_numeric_to_double(price), gnc_commodity_get_mnemonic(from));
+        price = gnc_numeric_div (gnc_numeric_create (1, 1), price,
+                                 GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
+    }
+    else
+    {
+        PINFO("Found price: 1 %s = %f %s", gnc_commodity_get_mnemonic(from),
+              gnc_numeric_to_double(price), gnc_commodity_get_mnemonic(to));
+    }
 
     /* and set the price entry */
-    _gnc_xfer_dialog_set_price_edit(xferData, price_value);
+    gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (xferData->price_edit), price);
 
     /* And then update the to_amount */
     gnc_xfer_update_to_amount (xferData);
@@ -385,12 +310,14 @@ gnc_xfer_dialog_set_price_auto (XferDialog *xferData,
 {
     gnc_numeric from_rate;
     gnc_numeric to_rate;
-    gnc_numeric price_value;
+    gnc_numeric price;
 
     if (!currency_active)
     {
         GtkEntry *entry;
-        _gnc_xfer_dialog_set_price_edit(xferData, gnc_numeric_zero());
+
+        gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->price_edit),
+                                   gnc_numeric_zero ());
         entry = GTK_ENTRY(gnc_amount_edit_gtk_entry
                           (GNC_AMOUNT_EDIT(xferData->price_edit)));
         gtk_entry_set_text(entry, "");
@@ -401,7 +328,7 @@ gnc_xfer_dialog_set_price_auto (XferDialog *xferData,
     }
 
     if (!gnc_is_euro_currency (from_currency) ||
-        !gnc_is_euro_currency (to_currency))
+            !gnc_is_euro_currency (to_currency))
     {
         gnc_xfer_dialog_update_price (xferData);
         return;
@@ -413,9 +340,9 @@ gnc_xfer_dialog_set_price_auto (XferDialog *xferData,
     if (gnc_numeric_zero_p (from_rate) || gnc_numeric_zero_p (to_rate))
         gnc_xfer_dialog_update_price (xferData);
 
-    price_value = gnc_numeric_div (to_rate, from_rate, GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
+    price = gnc_numeric_div (to_rate, from_rate, GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
 
-    gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT(xferData->price_edit), price_value);
+    gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT(xferData->price_edit), price);
 
     gnc_xfer_update_to_amount (xferData);
 }
@@ -436,8 +363,8 @@ gnc_xfer_dialog_curr_acct_activate(XferDialog *xferData)
 
     curr_active = (xferData->exch_rate ||
                    ((from_account != NULL) && (to_account != NULL)))
-        && !gnc_commodity_equiv(xferData->from_commodity,
-                                xferData->to_commodity);
+                  && !gnc_commodity_equiv(xferData->from_commodity,
+                                          xferData->to_commodity);
 
     gtk_widget_set_sensitive(xferData->curr_xfer_table, curr_active);
     gtk_widget_set_sensitive(xferData->price_edit,
@@ -514,7 +441,7 @@ gnc_xfer_dialog_reload_quickfill( XferDialog *xferData )
 
 static void
 gnc_xfer_dialog_from_tree_selection_changed_cb (GtkTreeSelection *selection,
-                                                gpointer data)
+        gpointer data)
 {
     XferDialog *xferData = data;
     GNCPrintAmountInfo print_info;
@@ -614,7 +541,7 @@ gnc_xfer_dialog_fill_tree_view(XferDialog *xferData,
 
     g_return_if_fail (xferData != NULL);
     use_accounting_labels = gnc_prefs_get_bool(GNC_PREFS_GROUP_GENERAL,
-                                               GNC_PREF_ACCOUNTING_LABELS);
+                            GNC_PREF_ACCOUNTING_LABELS);
 
     /* In "normal" mode (non accounting terms) the account where the
      * money comes from is displayed on the left side and the account
@@ -630,20 +557,20 @@ gnc_xfer_dialog_fill_tree_view(XferDialog *xferData,
     if (use_accounting_labels)
     {
         button = GTK_WIDGET(gtk_builder_get_object (builder,
-                                                    (direction == XFER_DIALOG_TO) ?
-                                                    "left_show_button" : "right_show_button"));
+                            (direction == XFER_DIALOG_TO) ?
+                            "left_show_button" : "right_show_button"));
         scroll_win = GTK_WIDGET(gtk_builder_get_object (builder,
-                                                        (direction == XFER_DIALOG_TO) ?
-                                                        "left_trans_window" : "right_trans_window"));
+                                (direction == XFER_DIALOG_TO) ?
+                                "left_trans_window" : "right_trans_window"));
     }
     else
     {
         button = GTK_WIDGET(gtk_builder_get_object (builder,
-                                                    (direction == XFER_DIALOG_TO) ?
-                                                    "right_show_button" : "left_show_button"));
+                            (direction == XFER_DIALOG_TO) ?
+                            "right_show_button" : "left_show_button"));
         scroll_win = GTK_WIDGET(gtk_builder_get_object (builder,
-                                                        (direction == XFER_DIALOG_TO) ?
-                                                        "right_trans_window" : "left_trans_window"));
+                                (direction == XFER_DIALOG_TO) ?
+                                "right_trans_window" : "left_trans_window"));
     }
 
 
@@ -759,7 +686,7 @@ gnc_xfer_dialog_quickfill( XferDialog *xferData )
      */
 
     if ( gnc_numeric_zero_p(
-             gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->amount_edit))))
+                gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->amount_edit))))
     {
         gnc_numeric amt;
         DEBUG("updating amount");
@@ -791,7 +718,7 @@ gnc_xfer_dialog_quickfill( XferDialog *xferData )
      * and select that account in the appropriate account tree.
      */
     if ( ( other = xaccSplitGetOtherSplit( split ) ) &&
-         ( other_acct = xaccSplitGetAccount( other ) ) )
+            ( other_acct = xaccSplitGetAccount( other ) ) )
     {
         GNCAccountType other_type;
         GtkWidget *other_button;
@@ -877,8 +804,8 @@ gnc_xfer_description_insert_cb(GtkEditable *editable,
     g_free(prefix);
 
     if ((match = gnc_quickfill_get_string_match(xferData->qf, new_text))
-        && (match_str = gnc_quickfill_string(match))
-        && ((match_str_len = strlen(match_str)) > new_text_len))
+            && (match_str = gnc_quickfill_string(match))
+            && ((match_str_len = strlen(match_str)) > new_text_len))
     {
         g_signal_handlers_block_matched (G_OBJECT (editable),
                                          G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, xferData);
@@ -902,7 +829,7 @@ gnc_xfer_description_insert_cb(GtkEditable *editable,
         xferData->desc_start_selection = *start_pos;
         xferData->desc_end_selection = -1;
         xferData->desc_selection_source_id = g_idle_add(idle_select_region,
-                                                        xferData);
+                                             xferData);
     }
     g_free(new_text);
 }
@@ -984,7 +911,8 @@ gnc_xfer_dialog_update_conv_info (XferDialog *xferData)
         gtk_label_set_text(GTK_LABEL(xferData->conv_forward), string);
         g_free(string);
 
-        rate = gnc_numeric_invert(rate);
+        rate = gnc_numeric_div(gnc_numeric_create (1, 1), rate,
+                               GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
         string = g_strdup_printf("1 %s = %f %s", to_mnemonic,
                                  gnc_numeric_to_double(rate), from_mnemonic);
         gtk_label_set_text(GTK_LABEL(xferData->conv_reverse), string);
@@ -1011,7 +939,7 @@ static void
 gnc_xfer_update_to_amount (XferDialog *xferData)
 {
     GNCAmountEdit *amount_edit, *price_edit, *to_amount_edit;
-    gnc_numeric price_value, to_amount;
+    gnc_numeric price, to_amount;
     Account *account;
     int scu = 0;
 
@@ -1026,7 +954,7 @@ gnc_xfer_update_to_amount (XferDialog *xferData)
     account = gnc_transfer_dialog_get_selected_account(xferData, XFER_DIALOG_TO);
     if (account == NULL)
         account = gnc_transfer_dialog_get_selected_account(xferData,
-                                                           XFER_DIALOG_FROM);
+                  XFER_DIALOG_FROM);
     if (account != NULL)
         scu = xaccAccountGetCommoditySCU(account);
     else if (xferData->to_commodity != NULL)
@@ -1034,11 +962,11 @@ gnc_xfer_update_to_amount (XferDialog *xferData)
 
     /* Determine the amount to transfer. */
     if (!gnc_amount_edit_evaluate(price_edit) ||
-        gnc_numeric_zero_p(price_value = gnc_amount_edit_get_amount(price_edit)))
+            gnc_numeric_zero_p(price = gnc_amount_edit_get_amount(price_edit)))
         to_amount = gnc_numeric_zero();
     else
         to_amount = gnc_numeric_mul(gnc_amount_edit_get_amount(amount_edit),
-                                    price_value, scu, GNC_HOW_RND_ROUND_HALF_UP);
+                                    price, scu, GNC_HOW_RND_ROUND_HALF_UP);
 
     /* Update the dialog. */
     gnc_amount_edit_set_amount(to_amount_edit, to_amount);
@@ -1057,9 +985,6 @@ gnc_xfer_price_update_cb(GtkWidget *widget, GdkEventFocus *event,
     XferDialog *xferData = data;
 
     gnc_xfer_update_to_amount (xferData);
-    xferData->price_source = PRICE_SOURCE_USER_PRICE;
-    xferData->price_type = PRICE_TYPE_TRN;
-
 
     return FALSE;
 }
@@ -1080,15 +1005,18 @@ gnc_xfer_to_amount_update_cb(GtkWidget *widget, GdkEventFocus *event,
                              gpointer data)
 {
     XferDialog *xferData = data;
-    gnc_numeric price_value;
+    gnc_numeric price;
     Account *account;
 
+    account = gnc_transfer_dialog_get_selected_account (xferData, XFER_DIALOG_TO);
+    if (account == NULL)
+        account = gnc_transfer_dialog_get_selected_account (xferData, XFER_DIALOG_FROM);
+
     gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->to_amount_edit));
-    price_value = gnc_xfer_dialog_compute_price_value(xferData);
-    gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->price_edit),
-                               price_value);
-    xferData->price_source = PRICE_SOURCE_XFER_DLG_VAL;
-    xferData->price_type = PRICE_TYPE_TRN;
+
+    price = gnc_xfer_dialog_compute_price(xferData);
+    price = gnc_numeric_convert (price, PRECISION, GNC_HOW_RND_ROUND_HALF_UP);
+    gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->price_edit), price);
     gnc_xfer_dialog_update_conv_info(xferData);
 
     return FALSE;
@@ -1171,18 +1099,18 @@ gnc_xfer_dialog_lock_account_tree(XferDialog *xferData,
 
     switch (direction)
     {
-        case XFER_DIALOG_FROM:
-            tree_view = xferData->from_tree_view;
-            scroll_win = xferData->from_window;
-            show_button = xferData->from_show_button;
-            break;
-        case XFER_DIALOG_TO:
-            tree_view = xferData->to_tree_view;
-            scroll_win = xferData->to_window;
-            show_button = xferData->to_show_button;
-            break;
-        default:
-            return;
+    case XFER_DIALOG_FROM:
+        tree_view = xferData->from_tree_view;
+        scroll_win = xferData->from_window;
+        show_button = xferData->from_show_button;
+        break;
+    case XFER_DIALOG_TO:
+        tree_view = xferData->to_tree_view;
+        scroll_win = xferData->to_window;
+        show_button = xferData->to_show_button;
+        break;
+    default:
+        return;
     }
 
     gtk_widget_set_sensitive( GTK_WIDGET(tree_view), FALSE );
@@ -1271,7 +1199,7 @@ gnc_xfer_dialog_is_exchange_dialog (XferDialog *xferData,
     g_return_if_fail(xferData);
     ENTER("xferData=%p, exch_rate=%p (%s)", xferData, exch_rate,
           exch_rate == NULL ? "NULL" : xaccPrintAmount(*exch_rate,
-                                                       gnc_default_print_info(FALSE)));
+                  gnc_default_print_info(FALSE)));
 
     gtk_widget_set_sensitive (xferData->amount_edit, FALSE);
     gtk_widget_set_sensitive (xferData->date_entry, FALSE);
@@ -1305,15 +1233,15 @@ gnc_xfer_dialog_set_amount(XferDialog *xferData, gnc_numeric amount)
         return;
 
     account = gnc_transfer_dialog_get_selected_account (xferData,
-                                                        XFER_DIALOG_FROM);
+              XFER_DIALOG_FROM);
     if (account == NULL)
         account = gnc_transfer_dialog_get_selected_account (xferData,
-                                                            XFER_DIALOG_TO);
+                  XFER_DIALOG_TO);
 
     gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (xferData->amount_edit), amount);
 }
 void gnc_xfer_dialog_set_amount_sensitive(XferDialog *xferData,
-                                          gboolean is_sensitive)
+        gboolean is_sensitive)
 {
     g_assert(xferData);
     gtk_widget_set_sensitive(gnc_amount_edit_gtk_entry(GNC_AMOUNT_EDIT (xferData->amount_edit)), is_sensitive);
@@ -1324,9 +1252,9 @@ gnc_xfer_dialog_set_fetch_sensitive (GtkWidget *fetch)
 {
     if (gnc_quote_source_fq_installed ())
     {
-        gtk_widget_set_sensitive (fetch, TRUE);
-        gtk_widget_set_tooltip_text (fetch, _("Retrieve the current online quote. This will fail if there is a manually-created price for today."));
-        return;
+	gtk_widget_set_sensitive (fetch, TRUE);
+	gtk_widget_set_tooltip_text (fetch, _("Retrieve the current online quote"));
+	return;
     }
     gtk_widget_set_sensitive (fetch, FALSE);
     gtk_widget_set_tooltip_text (fetch, _("Finance::Quote must be installed to enable this button."));
@@ -1411,279 +1339,38 @@ void gnc_xfer_dialog_set_date_sensitive(XferDialog *xferData,
 }
 
 void
-_gnc_xfer_dialog_set_price_edit(XferDialog *xferData, gnc_numeric price_value)
+gnc_xfer_dialog_set_exchange_rate(XferDialog *xferData, gnc_numeric exchange_rate)
 {
     if (xferData == NULL)
         return;
 
-    if (gnc_numeric_zero_p (price_value))
+    if (gnc_numeric_zero_p (exchange_rate))
         return;
 
     gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (xferData->price_edit),
-                                price_value);
+                                exchange_rate);
 
     gnc_xfer_update_to_amount (xferData);
 }
 
-static gboolean
-check_accounts  (XferDialog* xferData, Account* from_account,
-                 Account* to_account)
-{
-    if ((from_account == NULL) || (to_account == NULL))
-    {
-        const char *message = _("You must specify an account to transfer from, "
-                                "or to, or both, for this transaction. "
-                                "Otherwise, it will not be recorded.");
-        gnc_error_dialog(xferData->dialog, "%s", message);
-        LEAVE("bad account");
-        return FALSE;
-    }
-
-    if (from_account == to_account)
-    {
-        const char *message = _("You can't transfer from and to the same "
-                                "account!");
-        gnc_error_dialog(xferData->dialog, "%s", message);
-        LEAVE("same account");
-        return FALSE;
-    }
-
-    if (xaccAccountGetPlaceholder(from_account) ||
-        xaccAccountGetPlaceholder(to_account))
-    {
-        const char *placeholder_format =
-            _("The account %s does not allow transactions.");
-        char *name;
-
-        if (xaccAccountGetPlaceholder(from_account))
-            name = gnc_account_get_full_name(from_account);
-        else
-            name = gnc_account_get_full_name(to_account);
-        gnc_error_dialog(xferData->dialog, placeholder_format, name);
-        g_free(name);
-        LEAVE("placeholder");
-        return TRUE;
-    }
-
-    if (!gnc_commodity_is_iso (xferData->from_commodity))
-    {
-        const char *message =
-            _("You can't transfer from a non-currency account. "
-              "Try reversing the \"from\" and \"to\" accounts "
-              "and making the \"amount\" negative.");
-        gnc_error_dialog(xferData->dialog, "%s", message);
-        LEAVE("non-currency");
-        return FALSE;
-    }
-    return TRUE;
-}
-
-static gboolean
-check_edit(XferDialog *xferData)
-{
-    if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->price_edit)))
-    {
-        if (gtk_toggle_button_get_active
-            (GTK_TOGGLE_BUTTON(xferData->price_radio)))
-        {
-            gnc_parse_error_dialog (xferData, _("You must enter a valid price."));
-            LEAVE("invalid price");
-            return FALSE;
-        }
-    }
-
-    if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->to_amount_edit)))
-    {
-        if (gtk_toggle_button_get_active
-            (GTK_TOGGLE_BUTTON(xferData->amount_radio)))
-        {
-            gnc_parse_error_dialog (xferData,
-                                    _("You must enter a valid `to' amount."));
-            LEAVE("invalid to amount");
-            return FALSE;
-        }
-    }
-    return TRUE;
-}
-
-static void
-create_transaction(XferDialog *xferData, Timespec *ts,
-                   Account *from_account, Account* to_account,
-                   gnc_numeric amount, gnc_numeric to_amount)
-{
-    Transaction *trans;
-    Split *from_split;
-    Split *to_split;
-    const char *string;
-    /* Create the transaction */
-    trans = xaccMallocTransaction(xferData->book);
-
-    xaccTransBeginEdit(trans);
-
-    xaccTransSetCurrency(trans, xferData->from_commodity);
-    xaccTransSetDatePostedTS(trans, ts);
-
-    /* Trans-Num or Split-Action set with gnc_set_num_action below per book
-     * option */
-
-    string = gtk_entry_get_text(GTK_ENTRY(xferData->description_entry));
-    xaccTransSetDescription(trans, string);
-
-    /* create from split */
-    from_split = xaccMallocSplit(xferData->book);
-    xaccTransAppendSplit(trans, from_split);
-
-    /* create to split */
-    to_split = xaccMallocSplit(xferData->book);
-    xaccTransAppendSplit(trans, to_split);
-
-    xaccAccountBeginEdit(from_account);
-    xaccAccountInsertSplit(from_account, from_split);
-
-    xaccAccountBeginEdit(to_account);
-    xaccAccountInsertSplit(to_account, to_split);
-
-    xaccSplitSetBaseValue(from_split, gnc_numeric_neg (amount),
-                          xferData->from_commodity);
-    xaccSplitSetBaseValue(to_split, amount, xferData->from_commodity);
-    xaccSplitSetBaseValue(to_split, to_amount, xferData->to_commodity);
-
-    /* Set the transaction number or split action field based on book option*/
-    string = gtk_entry_get_text(GTK_ENTRY(xferData->num_entry));
-    gnc_set_num_action (trans, from_split, string, NULL);
-
-    /* Set the memo fields */
-    string = gtk_entry_get_text(GTK_ENTRY(xferData->memo_entry));
-    xaccSplitSetMemo(from_split, string);
-    xaccSplitSetMemo(to_split, string);
-
-    /* finish transaction */
-    xaccTransCommitEdit(trans);
-    xaccAccountCommitEdit(from_account);
-    xaccAccountCommitEdit(to_account);
-
-    /* If there is a registered callback handler that should be
-       notified of the newly created Transaction, call it now. */
-    if (xferData->transaction_cb)
-        xferData->transaction_cb(trans, xferData->transaction_user_data);
-}
-
-static gnc_numeric
-swap_commodities(gnc_commodity **from, gnc_commodity **to, gnc_numeric value)
-{
-    gnc_commodity *tmp = *to;
-
-    *to = *from;
-    *from = tmp;
-    value = gnc_numeric_invert(value);
-    return value;
-}
-
-static void
-create_price(XferDialog *xferData, Timespec ts)
-{
-    PriceReq pr;
-    GNCPrice *price = NULL;
-    gnc_commodity *from = xferData->from_commodity;
-    gnc_commodity *to = xferData->to_commodity;
-    gnc_numeric price_value;
-    gnc_numeric value;
-    gnc_numeric from_amt, to_amt;
-    gboolean swap = FALSE;
-
-/* Bail in the unlikely event that both currencies have joined the Euro. */
-    if (gnc_is_euro_currency (from) && gnc_is_euro_currency (to))
-        return;
-
-    value = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->price_edit));
-
-/* Normally we want to store currency rates such that the rate > 1 and commodity
- * prices in terms of a currency regardless of value. However, if we already
- * have a price in either direction we want to continue using that direction for
- * the rest of the day so that we don't wind up with two prices if the rate
- * shifts to be < 1. */
-
-    price_request_from_xferData(&pr, xferData);
-    if (lookup_price(&pr, SAME_DAY))
-    {
-        price_value = gnc_price_get_value(pr.price);
-        if (gnc_numeric_equal(pr.reverse ? gnc_numeric_invert(value) : value,
-                              price_value))
-        {
-            PINFO("Found price for %s in %s",
-                  gnc_commodity_get_mnemonic(pr.from),
-                  gnc_commodity_get_mnemonic(pr.to));
-            gnc_price_unref (pr.price);
-            return;
-        }
-        if (gnc_price_get_source(pr.price) < xferData->price_source)
-        {
-            PINFO("Existing price is preferred, so won't supersede.");
-            gnc_price_unref (pr.price);
-            return;
-        }
-        if (pr.reverse)
-        {
-            value = swap_commodities(&from, &to, value);
-            xferData->from_commodity = from;
-            xferData->to_commodity = to;
-        }
-        value = round_price(pr.from, pr.to, value);
-        gnc_price_begin_edit (pr.price);
-        gnc_price_set_time (pr.price, ts);
-        gnc_price_set_source (pr.price, xferData->price_source);
-        gnc_price_set_typestr(pr.price, xferData->price_type);
-        gnc_price_set_value (pr.price, value);
-        gnc_price_commit_edit (pr.price);
-        PINFO("Modified price: 1 %s = %f %s",
-              gnc_commodity_get_mnemonic(from),
-              gnc_numeric_to_double(value),
-              gnc_commodity_get_mnemonic(to));
-        gnc_price_unref (pr.price);
-        return;
-    }
-    if (gnc_commodity_is_currency(from) && gnc_commodity_is_currency(to))
-    {
-        if (value.num < value.denom)
-        {
-            value = swap_commodities(&from, &to, value);
-        }
-        value = gnc_numeric_convert(value, CURRENCY_DENOM,
-                                    GNC_HOW_RND_ROUND_HALF_UP);
-    }
-    else if (gnc_commodity_is_currency(from) || gnc_commodity_is_currency(to))
-    {
-        int scu;
-        if (gnc_commodity_is_currency(from))
-            value = swap_commodities(&from, &to, value);
-        scu = gnc_commodity_get_fraction (to);
-        value = gnc_numeric_convert(value, scu * COMMODITY_DENOM_MULT,
-                                    GNC_HOW_RND_ROUND_HALF_UP);
-    }
-    price = gnc_price_create (xferData->book);
-    gnc_price_begin_edit (price);
-    gnc_price_set_commodity (price, from);
-    gnc_price_set_currency (price, to);
-    gnc_price_set_time (price, ts);
-    gnc_price_set_source (price, xferData->price_source);
-    gnc_price_set_typestr (price, xferData->price_type);
-    gnc_price_set_value (price, value);
-    gnc_pricedb_add_price (xferData->pricedb, price);
-    gnc_price_commit_edit (price);
-    PINFO("Created price: 1 %s = %f %s", gnc_commodity_get_mnemonic(from),
-          gnc_numeric_to_double(value), gnc_commodity_get_mnemonic(to));
-    gnc_price_unref (price);
-}
-
 void
 gnc_xfer_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data)
 {
     XferDialog *xferData = data;
     Account *to_account;
     Account *from_account;
+    gnc_commodity *from_commodity;
+    gnc_commodity *to_commodity;
     gnc_numeric amount, to_amount;
+    const char *string;
     Timespec ts;
 
+    gboolean curr_trans;
+
+    Transaction *trans;
+    Split *from_split;
+    Split *to_split;
+
     g_return_if_fail (xferData != NULL);
     ENTER(" ");
 
@@ -1703,9 +1390,54 @@ gnc_xfer_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data)
     from_account = gnc_transfer_dialog_get_selected_account (xferData, XFER_DIALOG_FROM);
     to_account = gnc_transfer_dialog_get_selected_account (xferData, XFER_DIALOG_TO);
 
-    if (xferData->exch_rate == NULL &&
-        !check_accounts(xferData, from_account, to_account))
-        return;
+    if (xferData->exch_rate == NULL)
+    {
+        if ((from_account == NULL) || (to_account == NULL))
+        {
+            const char *message = _("You must specify an account to transfer from, "
+                                    "or to, or both, for this transaction. "
+                                    "Otherwise, it will not be recorded.");
+            gnc_error_dialog(xferData->dialog, "%s", message);
+            LEAVE("bad account");
+            return;
+        }
+
+        if (from_account == to_account)
+        {
+            const char *message = _("You can't transfer from and to the same "
+                                    "account!");
+            gnc_error_dialog(xferData->dialog, "%s", message);
+            LEAVE("same account");
+            return;
+        }
+
+        if (xaccAccountGetPlaceholder(from_account) ||
+                xaccAccountGetPlaceholder(to_account))
+        {
+            const char *placeholder_format =
+                _("The account %s does not allow transactions.");
+            char *name;
+
+            if (xaccAccountGetPlaceholder(from_account))
+                name = gnc_account_get_full_name(from_account);
+            else
+                name = gnc_account_get_full_name(to_account);
+            gnc_error_dialog(xferData->dialog, placeholder_format, name);
+            g_free(name);
+            LEAVE("placeholder");
+            return;
+        }
+
+        if (!gnc_commodity_is_iso (xferData->from_commodity))
+        {
+            const char *message = _("You can't transfer from a non-currency account. "
+                                    "Try reversing the \"from\" and \"to\" accounts "
+                                    "and making the \"amount\" negative.");
+            gnc_error_dialog(xferData->dialog, "%s", message);
+            LEAVE("non-currency");
+            return;
+        }
+    }
 
     if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->amount_edit)))
     {
@@ -1714,6 +1446,11 @@ gnc_xfer_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data)
         return;
     }
 
+    from_commodity = xferData->from_commodity;
+    to_commodity = xferData->to_commodity;
+
+    curr_trans = !gnc_commodity_equiv(from_commodity, to_commodity);
+
     amount = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->amount_edit));
 
     if (gnc_numeric_zero_p (amount))
@@ -1726,12 +1463,33 @@ gnc_xfer_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data)
 
     ts = gnc_date_edit_get_date_ts(GNC_DATE_EDIT(xferData->date_entry));
 
-    if (!gnc_commodity_equiv(xferData->from_commodity, xferData->to_commodity))
+    if (curr_trans)
     {
-        if (!check_edit(xferData))
-            return;
+        if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->price_edit)))
+        {
+            if (gtk_toggle_button_get_active
+                    (GTK_TOGGLE_BUTTON(xferData->price_radio)))
+            {
+                gnc_parse_error_dialog (xferData, _("You must enter a valid price."));
+                LEAVE("invalid price");
+                return;
+            }
+        }
+
+        if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->to_amount_edit)))
+        {
+            if (gtk_toggle_button_get_active
+                    (GTK_TOGGLE_BUTTON(xferData->amount_radio)))
+            {
+                gnc_parse_error_dialog (xferData,
+                                        _("You must enter a valid `to' amount."));
+                LEAVE("invalid to amount");
+                return;
+            }
+        }
+
         to_amount = gnc_amount_edit_get_amount
-            (GNC_AMOUNT_EDIT(xferData->to_amount_edit));
+                    (GNC_AMOUNT_EDIT(xferData->to_amount_edit));
     }
     else
         to_amount = amount;
@@ -1740,7 +1498,7 @@ gnc_xfer_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data)
 
     if (xferData->exch_rate)
     {
-        gnc_numeric price_value;
+        gnc_numeric price;
 
         /* If we've got the price-button set, then make sure we update the
          * to-amount before we use it.
@@ -1748,16 +1506,160 @@ gnc_xfer_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data)
         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(xferData->price_radio)))
             gnc_xfer_update_to_amount(xferData);
 
-        price_value = gnc_xfer_dialog_compute_price_value(xferData);
-        *(xferData->exch_rate) = gnc_numeric_abs(price_value);
+        price = gnc_xfer_dialog_compute_price(xferData);
+        *(xferData->exch_rate) = gnc_numeric_abs(price);
     }
     else
-        create_transaction (xferData, &ts, from_account, to_account,
-                            amount, to_amount);
+    {
+        /* Create the transaction */
+        trans = xaccMallocTransaction(xferData->book);
+
+        xaccTransBeginEdit(trans);
+
+        xaccTransSetCurrency(trans, from_commodity);
+        xaccTransSetDatePostedTS(trans, &ts);
+
+        /* Trans-Num or Split-Action set with gnc_set_num_action below per book
+         * option */
+
+        string = gtk_entry_get_text(GTK_ENTRY(xferData->description_entry));
+        xaccTransSetDescription(trans, string);
+
+        /* create from split */
+        from_split = xaccMallocSplit(xferData->book);
+        xaccTransAppendSplit(trans, from_split);
+
+        /* create to split */
+        to_split = xaccMallocSplit(xferData->book);
+        xaccTransAppendSplit(trans, to_split);
+
+        xaccAccountBeginEdit(from_account);
+        xaccAccountInsertSplit(from_account, from_split);
+
+        xaccAccountBeginEdit(to_account);
+        xaccAccountInsertSplit(to_account, to_split);
+
+        xaccSplitSetBaseValue(from_split, gnc_numeric_neg (amount), from_commodity);
+        xaccSplitSetBaseValue(to_split, amount, from_commodity);
+        xaccSplitSetBaseValue(to_split, to_amount, to_commodity);
+
+        /* Set the transaction number or split action field based on book option*/
+        string = gtk_entry_get_text(GTK_ENTRY(xferData->num_entry));
+        gnc_set_num_action (trans, from_split, string, NULL);
+
+        /* Set the memo fields */
+        string = gtk_entry_get_text(GTK_ENTRY(xferData->memo_entry));
+        xaccSplitSetMemo(from_split, string);
+        xaccSplitSetMemo(to_split, string);
+
+        /* finish transaction */
+        xaccTransCommitEdit(trans);
+        xaccAccountCommitEdit(from_account);
+        xaccAccountCommitEdit(to_account);
+
+        /* If there is a registered callback handler that should be
+           notified of the newly created Transaction, call it now. */
+        if (xferData->transaction_cb)
+            xferData->transaction_cb(trans, xferData->transaction_user_data);
+    }
+
     /* try to save this to the pricedb */
-    if (xferData->pricedb && !gnc_commodity_equal (xferData->from_commodity,
-                                                   xferData->to_commodity))
-        create_price(xferData, ts);
+    if (xferData->pricedb)
+    {
+        gnc_commodity *from = xferData->from_commodity;
+        gnc_commodity *to = xferData->to_commodity;
+
+        /* only continue if the currencies are DIFFERENT and are
+         * not both euroland currencies
+         */
+        if (!gnc_commodity_equal (from, to) &&
+                !(gnc_is_euro_currency (from) && gnc_is_euro_currency (to)))
+        {
+            GNCPrice *price;
+            gnc_numeric price_value;
+            gnc_numeric value;
+            gnc_commodity *tmp;
+            gnc_numeric from_amt, to_amt;
+            gnc_numeric tmp_amt;
+
+            from_amt = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->amount_edit));
+            to_amt = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->to_amount_edit));
+
+            /* compute the price -- maybe we need to swap? */
+
+            value = gnc_numeric_div(to_amt, from_amt, GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
+            value = gnc_numeric_abs (value);
+
+            /* Try to be consistent about how quotes are installed. */
+            if (from == gnc_default_currency() ||
+                    ((to != gnc_default_currency()) &&
+                     (strcmp (gnc_commodity_get_mnemonic(from),
+                              gnc_commodity_get_mnemonic(to)) < 0)))
+            {
+                tmp = from;
+                from = to;
+                to = tmp;
+                tmp_amt = from_amt;
+                from_amt = to_amt;
+                to_amt = tmp_amt;
+                value = gnc_numeric_div (gnc_numeric_create(1, 1), value,
+                                         GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
+            }
+
+            /* First see if the closest entry on the same day has an equivalent rate */
+            price = gnc_pricedb_lookup_day (xferData->pricedb, from, to, ts);
+            if (price)
+            {
+                price_value = gnc_price_get_value(price);
+            }
+            else
+            {
+                price = gnc_pricedb_lookup_day (xferData->pricedb, to, from, ts);
+                if (price)
+                {
+                    price_value = gnc_numeric_div (gnc_numeric_create(1, 1),
+                                                   gnc_price_get_value(price),
+                                                   GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
+                }
+            }
+
+            /* See if we found a good enough price */
+            if (price)
+            {
+                int scu = gnc_commodity_get_fraction (to);
+                if (!gnc_numeric_equal (gnc_numeric_mul (from_amt, price_value,
+                                        scu, GNC_HOW_RND_ROUND_HALF_UP),
+                                        to_amt))
+                {
+                    gnc_price_unref (price);
+                    price = NULL;
+                }
+            }
+
+            if (price)
+            {
+                PINFO("Found price for %s in %s", gnc_commodity_get_mnemonic(from),
+                      gnc_commodity_get_mnemonic(to));
+            }
+            else
+            {
+                price = gnc_price_create (xferData->book);
+                gnc_price_begin_edit (price);
+                gnc_price_set_commodity (price, from);
+                gnc_price_set_currency (price, to);
+                gnc_price_set_time (price, ts);
+                gnc_price_set_source (price, "user:xfer-dialog");
+                gnc_price_set_value (price, value);
+                gnc_pricedb_add_price (xferData->pricedb, price);
+                gnc_price_commit_edit (price);
+                PINFO("Created price: 1 %s = %f %s", gnc_commodity_get_mnemonic(from),
+                      gnc_numeric_to_double(value), gnc_commodity_get_mnemonic(to));
+            }
+
+            gnc_price_unref (price);
+        }
+    }
+
     /* Refresh everything */
     gnc_resume_gui_refresh ();
 
@@ -1811,11 +1713,14 @@ gnc_xfer_dialog_close_cb(GtkDialog *dialog, gpointer data)
 void
 gnc_xfer_dialog_fetch (GtkButton *button, XferDialog *xferData)
 {
+    gnc_numeric rate;
     GNCPrice *prc;
-    PriceReq pr;
+    gnc_commodity *from = xferData->from_commodity;
+    gnc_commodity *to = xferData->to_commodity;
     SCM quotes_func;
     SCM book_scm;
     SCM scm_window;
+    gboolean have_price = FALSE;
 
     g_return_if_fail (xferData);
 
@@ -1850,14 +1755,29 @@ gnc_xfer_dialog_fetch (GtkButton *button, XferDialog *xferData)
     gnc_unset_busy_cursor (NULL);
 
     /*the results should be in the price db now, but don't crash if not. */
-    price_request_from_xferData(&pr, xferData);
-    if (lookup_price(&pr, LATEST))
+
+    prc = gnc_pricedb_lookup_latest(xferData->pricedb, from, to);
+    if (prc)
     {
-        gnc_numeric price_value = gnc_price_get_value(pr.price);
-        if (pr.reverse)
-            price_value = gnc_numeric_invert(price_value);
-         _gnc_xfer_dialog_set_price_edit(xferData, price_value);
-        gnc_price_unref (pr.price);
+        rate = gnc_price_get_value (prc);
+        gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->price_edit), rate);
+        gnc_price_unref (prc);
+        have_price = TRUE;
+    }
+
+    /* Lets try reversing the commodities */
+    if(!have_price)
+    {
+        prc = gnc_pricedb_lookup_latest (xferData->pricedb, to, from);
+        if (prc)
+        {
+            rate = gnc_numeric_div (gnc_numeric_create (1, 1), gnc_price_get_value (prc),
+                                    GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
+
+            gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->price_edit), rate);
+            gnc_price_unref (prc);
+            have_price = TRUE;
+        }
     }
 
     LEAVE("quote retrieved");
@@ -1871,7 +1791,7 @@ gnc_xfer_dialog_create(GtkWidget *parent, XferDialog *xferData)
     gboolean  use_accounting_labels;
 
     use_accounting_labels = gnc_prefs_get_bool(GNC_PREFS_GROUP_GENERAL,
-                                               GNC_PREF_ACCOUNTING_LABELS);
+                            GNC_PREF_ACCOUNTING_LABELS);
 
     ENTER(" ");
     builder = gtk_builder_new();
@@ -2192,7 +2112,7 @@ gnc_xfer_dialog_set_to_account_label( XferDialog *xferData,
 
 void
 gnc_xfer_dialog_set_from_show_button_active( XferDialog *xferData,
-                                             gboolean set_value )
+        gboolean set_value )
 {
     if ( xferData && xferData->from_show_button )
     {
@@ -2203,7 +2123,7 @@ gnc_xfer_dialog_set_from_show_button_active( XferDialog *xferData,
 
 void
 gnc_xfer_dialog_set_to_show_button_active( XferDialog *xferData,
-                                           gboolean set_value )
+        gboolean set_value )
 {
     if ( xferData && xferData->to_show_button )
     {
@@ -2214,16 +2134,16 @@ gnc_xfer_dialog_set_to_show_button_active( XferDialog *xferData,
 
 /* Add a button with a user-specified label and "clicked" callback */
 void gnc_xfer_dialog_add_user_specified_button( XferDialog *xferData,
-                                                const gchar *label,
-                                                GCallback callback,
-                                                gpointer user_data )
+        const gchar *label,
+        GCallback callback,
+        gpointer user_data )
 {
     if ( xferData && label && callback )
     {
         GtkBuilder *builder = g_object_get_data (G_OBJECT (xferData->dialog), "builder");
         GtkWidget *button   = gtk_button_new_with_label( label );
         GtkWidget *box      = GTK_WIDGET(gtk_builder_get_object (builder,
-                                                                 "transfermain-vbox" ));
+                                         "transfermain-vbox" ));
         gtk_box_pack_end( GTK_BOX(box), button, FALSE, FALSE, 0 );
         g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), user_data);
         gtk_widget_show( button );
@@ -2231,7 +2151,7 @@ void gnc_xfer_dialog_add_user_specified_button( XferDialog *xferData,
 }
 
 void gnc_xfer_dialog_toggle_currency_table( XferDialog *xferData,
-                                            gboolean show_table )
+        gboolean show_table )
 {
     if (xferData && xferData->curr_xfer_table)
     {
@@ -2274,8 +2194,8 @@ gboolean gnc_xfer_dialog_run_until_done( XferDialog *xferData )
      * that's bad mojo whole gtk_dialog_run is still in control.
      */
     count = g_signal_handlers_disconnect_by_func(dialog,
-                                                 gnc_xfer_dialog_response_cb,
-                                                 xferData);
+            gnc_xfer_dialog_response_cb,
+            xferData);
     g_assert(count == 1);
 
     while ( TRUE )
@@ -2332,22 +2252,22 @@ gnc_xfer_dialog_quickfill_to_account(XferDialog *xferData,
 
 static Account *
 gnc_transfer_dialog_get_selected_account (XferDialog *dialog,
-                                          XferDirection direction)
+        XferDirection direction)
 {
     GtkTreeView *tree_view;
     Account *account;
 
     switch (direction)
     {
-        case XFER_DIALOG_FROM:
-            tree_view = dialog->from_tree_view;
-            break;
-        case XFER_DIALOG_TO:
-            tree_view = dialog->to_tree_view;
-            break;
-        default:
-            g_assert_not_reached ();
-            return NULL;
+    case XFER_DIALOG_FROM:
+        tree_view = dialog->from_tree_view;
+        break;
+    case XFER_DIALOG_TO:
+        tree_view = dialog->to_tree_view;
+        break;
+    default:
+        g_assert_not_reached ();
+        return NULL;
     }
 
     account = gnc_tree_view_account_get_selected_account  (GNC_TREE_VIEW_ACCOUNT (tree_view));
@@ -2356,8 +2276,8 @@ gnc_transfer_dialog_get_selected_account (XferDialog *dialog,
 
 static void
 gnc_transfer_dialog_set_selected_account (XferDialog *dialog,
-                                          Account *account,
-                                          XferDirection direction)
+        Account *account,
+        XferDirection direction)
 {
     GtkTreeView *tree_view;
     GtkCheckButton *show_button;
@@ -2368,17 +2288,17 @@ gnc_transfer_dialog_set_selected_account (XferDialog *dialog,
 
     switch (direction)
     {
-        case XFER_DIALOG_FROM:
-            tree_view = dialog->from_tree_view;
-            show_button = GTK_CHECK_BUTTON (dialog->from_show_button);
-            break;
-        case XFER_DIALOG_TO:
-            tree_view = dialog->to_tree_view;
-            show_button = GTK_CHECK_BUTTON (dialog->to_show_button);
-            break;
-        default:
-            g_assert_not_reached ();
-            return;
+    case XFER_DIALOG_FROM:
+        tree_view = dialog->from_tree_view;
+        show_button = GTK_CHECK_BUTTON (dialog->from_show_button);
+        break;
+    case XFER_DIALOG_TO:
+        tree_view = dialog->to_tree_view;
+        show_button = GTK_CHECK_BUTTON (dialog->to_show_button);
+        break;
+    default:
+        g_assert_not_reached ();
+        return;
     }
 
     type = xaccAccountGetType (account);
@@ -2387,7 +2307,7 @@ gnc_transfer_dialog_set_selected_account (XferDialog *dialog,
                                   (type == ACCT_TYPE_INCOME));
 
     gnc_tree_view_account_set_selected_account (GNC_TREE_VIEW_ACCOUNT (tree_view),
-                                                account);
+            account);
 }
 
 
@@ -2410,7 +2330,6 @@ gboolean gnc_xfer_dialog_run_exchange_dialog(
     gboolean swap_amounts = FALSE;
     gnc_commodity *txn_cur = xaccTransGetCurrency(txn);
     gnc_commodity *reg_com = xaccAccountGetCommodity(reg_acc);
-    gnc_numeric dialog_rate = *exch_rate;
 
     g_return_val_if_fail(txn_cur, TRUE);
 
@@ -2461,9 +2380,9 @@ gboolean gnc_xfer_dialog_run_exchange_dialog(
         gnc_numeric rate = xaccTransGetAccountConvRate(txn, reg_acc);
 
         /* XXX: should we tell the user we've done the conversion? */
-        amount = gnc_numeric_div(amount, rate,
-                                 gnc_commodity_get_fraction(txn_cur),
-                                 GNC_HOW_DENOM_REDUCE);
+        amount = gnc_numeric_div(
+                     amount, rate,
+                     gnc_commodity_get_fraction(txn_cur), GNC_HOW_DENOM_REDUCE);
     }
 
     /* enter the accounts */
@@ -2472,7 +2391,8 @@ gboolean gnc_xfer_dialog_run_exchange_dialog(
         gnc_xfer_dialog_select_to_currency(xfer, txn_cur);
         gnc_xfer_dialog_select_from_currency(xfer, xfer_com);
         if (!gnc_numeric_zero_p(*exch_rate))
-            dialog_rate = gnc_numeric_invert(*exch_rate);
+            *exch_rate = gnc_numeric_div(gnc_numeric_create(1, 1), *exch_rate,
+                                         GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
         amount = gnc_numeric_neg(amount);
     }
     else
@@ -2496,11 +2416,17 @@ gboolean gnc_xfer_dialog_run_exchange_dialog(
      */
 
     /* Set the exchange rate */
-    _gnc_xfer_dialog_set_price_edit(xfer, dialog_rate);
+    gnc_xfer_dialog_set_exchange_rate(xfer, *exch_rate);
 
     /* and run it... */
     if (gnc_xfer_dialog_run_until_done(xfer) == FALSE)
         return TRUE;
 
+    /* If we swapped the amounts for the dialog, then make sure we swap
+     * it back now...
+     */
+    if (swap_amounts)
+        *exch_rate = gnc_numeric_div(gnc_numeric_create(1, 1), *exch_rate,
+                                     GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
     return FALSE;
 }
diff --git a/src/gnome-utils/gnc-tree-model-price.c b/src/gnome-utils/gnc-tree-model-price.c
index 20a4409..c62b749 100644
--- a/src/gnome-utils/gnc-tree-model-price.c
+++ b/src/gnome-utils/gnc-tree-model-price.c
@@ -786,7 +786,7 @@ gnc_tree_model_price_get_value (GtkTreeModel *tree_model,
         break;
     case GNC_TREE_MODEL_PRICE_COL_SOURCE:
         g_value_init (value, G_TYPE_STRING);
-        g_value_set_string (value, gettext (gnc_price_get_source_string (price)));
+        g_value_set_string (value, gettext (gnc_price_get_source (price)));
         break;
     case GNC_TREE_MODEL_PRICE_COL_TYPE:
         g_value_init (value, G_TYPE_STRING);
diff --git a/src/gnome-utils/gnc-tree-view-price.c b/src/gnome-utils/gnc-tree-view-price.c
index b0dc599..7f3113d 100644
--- a/src/gnome-utils/gnc-tree-view-price.c
+++ b/src/gnome-utils/gnc-tree-view-price.c
@@ -300,7 +300,8 @@ sort_by_source (GtkTreeModel *f_model,
         return sort_ns_or_cm (f_model, f_iter_a, f_iter_b);
 
     /* sort by source first */
-    result = gnc_price_get_source (price_a) < gnc_price_get_source (price_b);
+    result = safe_utf8_collate (gnc_price_get_source (price_a),
+                                gnc_price_get_source (price_b));
     if (result != 0)
         return result;
 
diff --git a/src/gnome/assistant-stock-split.c b/src/gnome/assistant-stock-split.c
index 262df75..7c19634 100644
--- a/src/gnome/assistant-stock-split.c
+++ b/src/gnome/assistant-stock-split.c
@@ -398,8 +398,8 @@ gnc_stock_split_assistant_finish (GtkAssistant *assistant,
         gnc_price_set_commodity (price, xaccAccountGetCommodity (account));
         gnc_price_set_currency (price, gnc_currency_edit_get_currency (ce));
         gnc_price_set_time (price, ts);
-        gnc_price_set_source (price, PRICE_SOURCE_STOCK_SPLIT);
-        gnc_price_set_typestr (price, PRICE_TYPE_UNK);
+        gnc_price_set_source (price, "user:stock-split");
+        gnc_price_set_typestr (price, "unknown");
         gnc_price_set_value (price, amount);
         gnc_price_commit_edit (price);
 
diff --git a/src/gnome/dialog-price-editor.c b/src/gnome/dialog-price-editor.c
index d395903..ac980dc 100644
--- a/src/gnome/dialog-price-editor.c
+++ b/src/gnome/dialog-price-editor.c
@@ -50,6 +50,8 @@
 
 #define DIALOG_PRICE_EDIT_CM_CLASS "dialog-price-edit"
 #define GNC_PREFS_GROUP "dialogs.price-editor"
+#define DIALOG_PRICE_EDIT_SOURCE "user:price-editor"
+
 
 /* This static indicates the debugging module that this .o belongs to.  */
 G_GNUC_UNUSED static QofLogModule log_module = GNC_MOD_GUI;
@@ -161,7 +163,7 @@ price_to_gui (PriceEditDialog *pedit_dialog)
 
         currency = gnc_price_get_currency (pedit_dialog->price);
         date = gnc_price_get_time (pedit_dialog->price);
-        source = gnc_price_get_source_string (pedit_dialog->price);
+        source = gnc_price_get_source (pedit_dialog->price);
         type = gnc_price_get_typestr (pedit_dialog->price);
         value = gnc_price_get_value (pedit_dialog->price);
     }
@@ -170,7 +172,7 @@ price_to_gui (PriceEditDialog *pedit_dialog)
         currency = gnc_default_currency ();
         date.tv_sec = gnc_time (NULL);
         date.tv_nsec = 0;
-        source = "user:price-editor"; //Sync with source_names in gnc-pricedb.c
+        source = DIALOG_PRICE_EDIT_SOURCE;
         type = "";
         value = gnc_numeric_zero ();
     }
@@ -237,7 +239,7 @@ gui_to_price (PriceEditDialog *pedit_dialog)
     gnc_price_set_commodity (pedit_dialog->price, commodity);
     gnc_price_set_currency (pedit_dialog->price, currency);
     gnc_price_set_time (pedit_dialog->price, date);
-    gnc_price_set_source_string (pedit_dialog->price, source);
+    gnc_price_set_source (pedit_dialog->price, source);
     gnc_price_set_typestr (pedit_dialog->price, type);
     gnc_price_set_value (pedit_dialog->price, value);
     gnc_price_commit_edit (pedit_dialog->price);
@@ -551,7 +553,7 @@ gnc_price_edit_dialog (GtkWidget * parent,
             price = gnc_price_clone(price, pedit_dialog->book);
 //  } else {
 //      price = gnc_price_create (pedit_dialog->book);
-            gnc_price_set_source (price, PRICE_SOURCE_EDIT_DLG);
+            gnc_price_set_source (price, DIALOG_PRICE_EDIT_SOURCE);
         }
 
         pedit_dialog->is_new = TRUE;
diff --git a/src/libqof/qof/gnc-numeric.c b/src/libqof/qof/gnc-numeric.c
index 44c6400..693fdf9 100644
--- a/src/libqof/qof/gnc-numeric.c
+++ b/src/libqof/qof/gnc-numeric.c
@@ -1149,26 +1149,7 @@ gnc_numeric_to_decimal(gnc_numeric *a, guint8 *max_decimal_places)
     return TRUE;
 }
 
-gnc_numeric
-gnc_numeric_invert(gnc_numeric num)
-{
-    if (num.num == 0)
-        return gnc_numeric_zero();
-    if (num.denom > 0)
-    {
-        if (num.num < 0)
-            return gnc_numeric_create (-num.denom, -num.num);
-        return gnc_numeric_create (num.denom, num.num);
-    }
-    else /* Negative denominator means multiply instead of divide. */
-    {
-        int64_t mult = (num.num < 0 ? INT64_C(-1) : INT64_C(1));
-        qofint128 denom = mult128(-num.denom, mult * num.num);
-        if (denom.hi)
-            return gnc_numeric_error(GNC_ERROR_OVERFLOW);
-        return gnc_numeric_create (mult, denom.lo);
-    }
-}
+
 /* *******************************************************************
  *  double_to_gnc_numeric
  ********************************************************************/
diff --git a/src/libqof/qof/gnc-numeric.h b/src/libqof/qof/gnc-numeric.h
index 89933c8..bcb70f1 100644
--- a/src/libqof/qof/gnc-numeric.h
+++ b/src/libqof/qof/gnc-numeric.h
@@ -504,13 +504,6 @@ gnc_numeric gnc_numeric_reduce(gnc_numeric n);
  ********************************************************************/
 gboolean gnc_numeric_to_decimal(gnc_numeric * a,
                                 guint8 * max_decimal_places);
-
-/** Invert a gnc_numeric.
- * Much faster than dividing 1 by it.
- * @param num The number to be inverted
- * @return a gnc_numeric that is the inverse of num
- */
-gnc_numeric gnc_numeric_invert (gnc_numeric num);
 /** @} */
 
 /** @name GValue
diff --git a/src/quotes/gnc-fq-dump b/src/quotes/gnc-fq-dump
index 771e2ae..2b1ab1e 100755
--- a/src/quotes/gnc-fq-dump
+++ b/src/quotes/gnc-fq-dump
@@ -166,15 +166,6 @@ if ($exchange eq "currency") {
   while ($#ARGV >= 0) {
     my $to = shift;
     my $result = $q->currency($from, $to);
-    unless (defined($result) && $result >= 1) {
-        my $inv_res = $q->currency($to, $from);
-        if (defined($inv_res)) {
-            my $tmp = $to;
-            $to = $from;
-            $from = $tmp;
-            $result = $inv_res;
-        }
-    }
     if (defined($result)) {
       printf "1 $from = $result $to\n";
     } else {
diff --git a/src/quotes/gnc-fq-helper.in b/src/quotes/gnc-fq-helper.in
index 6af1dee..edb6220 100755
--- a/src/quotes/gnc-fq-helper.in
+++ b/src/quotes/gnc-fq-helper.in
@@ -350,19 +350,6 @@ while(<>) {
     last unless $to_currency;
 
     my $price = $quoter->currency($from_currency, $to_currency);
-    my $inv_price = undef;
-    #Sometimes price quotes are available in only one direction, and if the
-    #direction we asked for results in a quote < 1 we want the other direction
-    #if it's available to get more significant digits.
-    unless (defined($price) && $price > 1) {
-        $inv_price = $quoter->currency($to_currency, $from_currency);
-        if (defined($inv_price)) {
-            my $tmp = $to_currency;
-            $to_currency = $from_currency;
-            $from_currency = $tmp;
-            $price = $inv_price;
-        }
-    }
 
     $quote_data{$from_currency, "success"} = defined($price);
     $quote_data{$from_currency, "symbol"} = $from_currency;
diff --git a/src/register/ledger-core/split-register.c b/src/register/ledger-core/split-register.c
index 3e4eb74..3531633 100644
--- a/src/register/ledger-core/split-register.c
+++ b/src/register/ledger-core/split-register.c
@@ -64,9 +64,8 @@ static QofLogModule log_module = GNC_MOD_LEDGER;
 static CursorClass copied_class = CURSOR_CLASS_NONE;
 static SCM copied_item = SCM_UNDEFINED;
 static GncGUID copied_leader_guid;
-/* A denominator representing number of digits to the right of the decimal point
- * displayed in a price cell. */
-static int PRICE_CELL_DENOM = 1000000;
+
+
 /** static prototypes *****************************************************/
 
 static gboolean gnc_split_register_save_to_scm (SplitRegister *reg,
@@ -2044,8 +2043,7 @@ recalculate_value (Split *split, SplitRegister *reg,
 }
 
 static void
-record_price (SplitRegister *reg, Account *account, gnc_numeric value,
-              PriceSource source)
+record_price (SplitRegister *reg, Account *account, gnc_numeric value)
 {
     Transaction *trans = gnc_split_register_get_current_trans (reg);
     QofBook *book = qof_instance_get_book (QOF_INSTANCE (account));
@@ -2053,11 +2051,8 @@ record_price (SplitRegister *reg, Account *account, gnc_numeric value,
     gnc_commodity *comm = xaccAccountGetCommodity (account);
     gnc_commodity *curr = xaccTransGetCurrency (trans);
     GNCPrice *price;
-    gnc_numeric price_value;
-    int scu = gnc_commodity_get_fraction(curr);
     Timespec ts;
-    BasicCell *cell = gnc_table_layout_get_cell (reg->table->layout, DATE_CELL);
-    gboolean swap = FALSE;
+    BasicCell *cell;
 
     /* Only record the price for account types that don't have a
      * "rate" cell. They'll get handled later by
@@ -2065,58 +2060,14 @@ record_price (SplitRegister *reg, Account *account, gnc_numeric value,
      */
     if (gnc_split_reg_has_rate_cell (reg->type))
         return;
+    cell = gnc_table_layout_get_cell (reg->table->layout, DATE_CELL);
     gnc_date_cell_get_date ((DateCell*)cell, &ts);
-    price = gnc_pricedb_lookup_day (pricedb, comm, curr, ts);
-    if (!price)
-    {
-        price = gnc_pricedb_lookup_day (pricedb, curr, comm, ts);
-        if (price)
-/* It might be better to raise an error here: We shouldn't be creating
- * currency->commodity prices.
- */
-            swap = TRUE;
-    }
-    if (price)
-    {
-        price_value = gnc_price_get_value(price);
-        if (gnc_numeric_equal(swap ? gnc_numeric_invert(value) : value,
-                              price_value))
-        {
-            gnc_price_unref (price);
-            return;
-        }
-        if (gnc_price_get_source(price) < PRICE_SOURCE_XFER_DLG_VAL)
-        {
-            /* Existing price is preferred over this one. */
-            gnc_price_unref(price);
-            return;
-        }
-        if (swap)
-        {
-            value = gnc_numeric_invert(value);
-            scu = gnc_commodity_get_fraction(comm);
-        }
-        value = gnc_numeric_convert(value, scu * COMMODITY_DENOM_MULT,
-                                    GNC_HOW_RND_ROUND_HALF_UP);
-        gnc_price_begin_edit (price);
-        gnc_price_set_time (price, ts);
-        gnc_price_set_source (price, source);
-        gnc_price_set_typestr (price, PRICE_TYPE_TRN);
-        gnc_price_set_value (price, value);
-        gnc_price_commit_edit (price);
-        gnc_price_unref (price);
-        return;
-    }
-
-    value = gnc_numeric_convert(value, scu * COMMODITY_DENOM_MULT,
-                                GNC_HOW_RND_ROUND_HALF_UP);
     price = gnc_price_create (book);
     gnc_price_begin_edit (price);
     gnc_price_set_commodity (price, comm);
     gnc_price_set_currency (price, curr);
     gnc_price_set_time (price, ts);
-    gnc_price_set_source (price, source);
-    gnc_price_set_typestr (price, PRICE_TYPE_TRN);
+    gnc_price_set_source (price, "user:split-register");
     gnc_price_set_value (price, value);
     gnc_pricedb_add_price (pricedb, price);
     gnc_price_commit_edit (price);
@@ -2139,7 +2090,6 @@ gnc_split_register_auto_calc (SplitRegister *reg, Split *split)
     Account *account;
     int denom;
     int choice;
-    PriceSource source = PRICE_SOURCE_USER_PRICE;
 
     if (STOCK_REGISTER    != reg->type &&
         CURRENCY_REGISTER != reg->type &&
@@ -2288,7 +2238,6 @@ gnc_split_register_auto_calc (SplitRegister *reg, Split *split)
     {
         recalculate_price (split, reg, value, amount);
         price_changed = TRUE;
-        source = PRICE_SOURCE_SPLIT_REG;
     }
     if (recalc_value)
         recalculate_value (split, reg, price, amount, shares_changed);
@@ -2299,7 +2248,7 @@ gnc_split_register_auto_calc (SplitRegister *reg, Split *split)
                 PRIC_CELL);
         price = gnc_price_cell_get_value (cell);
 	if (gnc_numeric_positive_p(price))
-	    record_price (reg, account, price, source);
+	    record_price (reg, account, price);
     }
     return TRUE;
 }
@@ -2598,8 +2547,7 @@ gnc_split_register_config_cells (SplitRegister *reg)
     /* Use 6 decimal places for prices and "exchange rates"  */
     gnc_price_cell_set_fraction
     ((PriceCell *)
-     gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL),
-     PRICE_CELL_DENOM);
+     gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL), 1000000);
 
     /* Initialize shares and share balance cells */
     gnc_price_cell_set_print_info
diff --git a/src/scm/price-quotes.scm b/src/scm/price-quotes.scm
index 68c67bf..7daacd0 100644
--- a/src/scm/price-quotes.scm
+++ b/src/scm/price-quotes.scm
@@ -1,17 +1,17 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; price-quotes.scm - manage sub-processes.
 ;;; Copyright 2001 Rob Browning <rlb at cs.utexas.edu>
-;;;
-;;; This program is free software; you can redistribute it and/or
-;;; modify it under the terms of the GNU General Public License as
-;;; published by the Free Software Foundation; either version 2 of
-;;; the License, or (at your option) any later version.
-;;;
-;;; This program is distributed in the hope that it will be useful,
-;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;;; GNU General Public License for more details.
-;;;
+;;; 
+;;; This program is free software; you can redistribute it and/or    
+;;; modify it under the terms of the GNU General Public License as   
+;;; published by the Free Software Foundation; either version 2 of   
+;;; the License, or (at your option) any later version.              
+;;;                                                                  
+;;; This program is distributed in the hope that it will be useful,  
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of   
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    
+;;; GNU General Public License for more details.                     
+;;;                                                                  
 ;;; You should have received a copy of the GNU General Public License
 ;;; along with this program; if not, contact:
 ;;;
@@ -35,7 +35,7 @@
 
 (define (item-list->hash! lst hash
 			  getkey getval
-			  hashref hashset
+			  hashref hashset 
 			  list-duplicates?)
   ;; Takes a list of the form (item item item item) and returns a hash
   ;; formed by traversing the list, and getting the key and val from
@@ -58,7 +58,7 @@
 	  (if existing-val
 	      (hashset hash key (cons val existing-val))
 	      (hashset hash key (list val))))))
-
+  
   (for-each handle-item lst)
   hash)
 
@@ -205,7 +205,7 @@
     ;; a list of the corresponding commodities.  Also perform a bit of
     ;; optimization, merging calls for symbols to the same
     ;; Finance::Quote method.
-    ;;
+    ;; 
     ;; Returns a list of the info needed for a set of calls to
     ;; gnc-fq-helper.  Each item will of the list will be of the
     ;; form:
@@ -223,7 +223,7 @@
 	   (commodity-list #f)
 	   (currency-list (filter
 			   (lambda (a) (not (gnc-commodity-equiv (cadr a) (caddr a))))
-			   (call-with-values
+			   (call-with-values 
                                (lambda () (partition!
                                            (lambda (cmd)
                                              (not (string=? (car cmd) "currency")))
@@ -257,7 +257,7 @@
     ;;
     ;; ("yahoo" (commodity-1 currency-1 tz-1)
     ;;          (commodity-2 currency-2 tz-2) ...)
-    ;;
+    ;; 
     ;; ("yahoo" "IBM" "AMD" ...)
     ;;
 
@@ -370,20 +370,8 @@
                  (string? currency-str)
                  (gnc-commodity-table-lookup commodity-table
                                              "ISO4217"
-                                             (string-upcase currency-str))))
-           (pricedb (gnc-pricedb-get-db book))
-           (saved-price #f)
-           (commodity-str (gnc-commodity-get-printname commodity))
-           )
-      (if (equal? (gnc-commodity-get-printname currency) commodity-str)
-          (let* ((symbol (assq-ref quote-data 'symbol))
-                 (other-curr
-                  (and commodity-table
-                       (string? symbol)
-                       (gnc-commodity-table-lookup commodity-table "ISO4217"
-                                                   (string-upcase symbol)))))
-            (set! commodity other-curr))
-        )
+                                             (string-upcase currency-str)))))
+
       (or-map (lambda (price-sym)
                 (let ((p (assq-ref quote-data price-sym)))
                   (if p
@@ -415,52 +403,27 @@
       (if (not (and commodity currency gnc-time price price-type))
           (string-append
            currency-str ":" (gnc-commodity-get-mnemonic commodity))
-          (begin
-            (set! saved-price (gnc-pricedb-lookup-day pricedb
-                                                      commodity currency
-                                                      gnc-time))
-            (if (null? saved-price)
+          (let ((gnc-price (gnc-price-create book)))
+            (if (not gnc-price)
+                (string-append
+                 currency-str ":" (gnc-commodity-get-mnemonic commodity))
                 (begin
-                  (set! saved-price (gnc-pricedb-lookup-day pricedb currency
-                                                            commodity gnc-time))
-                  (if (not (null? saved-price))
-                      (set! price (gnc-numeric-invert(price))))))
-            (if (not (null? saved-price))
-                (if (> (gnc-price-get-source saved-price) PRICE-SOURCE-FQ)
-                    (begin
-                      (gnc-price-begin-edit saved-price)
-                      (gnc-price-set-time saved-price gnc-time)
-                      (gnc-price-set-source saved-price PRICE-SOURCE-FQ)
-                      (gnc-price-set-typestr saved-price price-type)
-                      (gnc-price-set-value saved-price price)
-                      (gnc-price-commit-edit saved-price)
-                      #f)
-                    #f)
-              (let ((gnc-price (gnc-price-create book)))
-                (if (not gnc-price)
-                    (string-append
-                     currency-str ":" (gnc-commodity-get-mnemonic commodity))
-                    (begin
-                      (gnc-price-begin-edit gnc-price)
-                      (gnc-price-set-commodity gnc-price commodity)
-                      (gnc-price-set-currency gnc-price currency)
-                      (gnc-price-set-time gnc-price gnc-time)
-                      (gnc-price-set-source gnc-price PRICE-SOURCE-FQ)
-                      (gnc-price-set-typestr gnc-price price-type)
-                      (gnc-price-set-value gnc-price price)
-                      (gnc-price-commit-edit gnc-price)
-                      gnc-price)))))
-          )))
+				  (gnc-price-begin-edit gnc-price)
+                  (gnc-price-set-commodity gnc-price commodity)
+                  (gnc-price-set-currency gnc-price currency)
+                  (gnc-price-set-time gnc-price gnc-time)
+                  (gnc-price-set-source gnc-price "Finance::Quote")
+                  (gnc-price-set-typestr gnc-price price-type)
+                  (gnc-price-set-value gnc-price price)
+				  (gnc-price-commit-edit gnc-price)
+                  gnc-price))))))
 
   (define (book-add-prices! book prices)
     (let ((pricedb (gnc-pricedb-get-db book)))
       (for-each
        (lambda (price)
-         (if price
-             (begin
-               (gnc-pricedb-add-price pricedb price)
-               (gnc-price-unref price)
-               #f)))
+         (gnc-pricedb-add-price pricedb price)
+         (gnc-price-unref price))
        prices)))
 
   ;; FIXME: uses of gnc:warn in here need to be cleaned up.  Right

commit b723578c8289921a22e836893390754b875bda76
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Oct 23 11:49:11 2015 -0700

    Revert "Fix rename failure for gnc_xfer_dialog_set_exchange_rate."
    
    This reverts commit 766cf48f45fd649d3db0d2993ee745da019c376e, and
    is step 3 of reverting the single-price changes from maint.

diff --git a/src/business/business-gnome/dialog-invoice.c b/src/business/business-gnome/dialog-invoice.c
index 0a24b69..10c4d75 100644
--- a/src/business/business-gnome/dialog-invoice.c
+++ b/src/business/business-gnome/dialog-invoice.c
@@ -878,7 +878,7 @@ gnc_invoice_post(InvoiceWindow *iw, struct post_invoice_params *post_params)
             {
                 exch_rate = gnc_numeric_div ((gnc_numeric){1, 1}, exch_rate,
                             GNC_DENOM_AUTO, GNC_HOW_RND_ROUND_HALF_UP);
-                gnc_xfer_dialog_set_price_edit (xfer, exch_rate);
+                gnc_xfer_dialog_set_exchange_rate (xfer, exch_rate);
             }
         }
 
diff --git a/src/gnome-utils/dialog-transfer.c b/src/gnome-utils/dialog-transfer.c
index d7ce77e..18e76c4 100644
--- a/src/gnome-utils/dialog-transfer.c
+++ b/src/gnome-utils/dialog-transfer.c
@@ -160,6 +160,7 @@ static Account *gnc_transfer_dialog_get_selected_account (XferDialog *dialog,
 static void gnc_transfer_dialog_set_selected_account (XferDialog *dialog,
                                                       Account *account,
                                                       XferDirection direction);
+static void _gnc_xfer_dialog_set_price_edit(XferDialog*, gnc_numeric);
 
 void gnc_xfer_description_insert_cb(GtkEditable *editable,
                                     const gchar *insert_text,
@@ -335,7 +336,7 @@ gnc_xfer_dialog_update_price (XferDialog *xferData)
     gnc_price_unref(pr.price);
 
     /* and set the price entry */
-    gnc_xfer_dialog_set_price_edit(xferData, price_value);
+    _gnc_xfer_dialog_set_price_edit(xferData, price_value);
 
     /* And then update the to_amount */
     gnc_xfer_update_to_amount (xferData);
@@ -389,7 +390,7 @@ gnc_xfer_dialog_set_price_auto (XferDialog *xferData,
     if (!currency_active)
     {
         GtkEntry *entry;
-        gnc_xfer_dialog_set_price_edit(xferData, gnc_numeric_zero());
+        _gnc_xfer_dialog_set_price_edit(xferData, gnc_numeric_zero());
         entry = GTK_ENTRY(gnc_amount_edit_gtk_entry
                           (GNC_AMOUNT_EDIT(xferData->price_edit)));
         gtk_entry_set_text(entry, "");
@@ -1410,7 +1411,7 @@ void gnc_xfer_dialog_set_date_sensitive(XferDialog *xferData,
 }
 
 void
-gnc_xfer_dialog_set_price_edit(XferDialog *xferData, gnc_numeric price_value)
+_gnc_xfer_dialog_set_price_edit(XferDialog *xferData, gnc_numeric price_value)
 {
     if (xferData == NULL)
         return;
@@ -1855,7 +1856,7 @@ gnc_xfer_dialog_fetch (GtkButton *button, XferDialog *xferData)
         gnc_numeric price_value = gnc_price_get_value(pr.price);
         if (pr.reverse)
             price_value = gnc_numeric_invert(price_value);
-         gnc_xfer_dialog_set_price_edit(xferData, price_value);
+         _gnc_xfer_dialog_set_price_edit(xferData, price_value);
         gnc_price_unref (pr.price);
     }
 
@@ -2495,7 +2496,7 @@ gboolean gnc_xfer_dialog_run_exchange_dialog(
      */
 
     /* Set the exchange rate */
-    gnc_xfer_dialog_set_price_edit(xfer, dialog_rate);
+    _gnc_xfer_dialog_set_price_edit(xfer, dialog_rate);
 
     /* and run it... */
     if (gnc_xfer_dialog_run_until_done(xfer) == FALSE)
diff --git a/src/gnome-utils/dialog-transfer.h b/src/gnome-utils/dialog-transfer.h
index 4b4bc84..7a8d6b3 100644
--- a/src/gnome-utils/dialog-transfer.h
+++ b/src/gnome-utils/dialog-transfer.h
@@ -141,11 +141,9 @@ void gnc_xfer_dialog_set_date(XferDialog *xferData, time64 set_time);
 /** Set the "sensitive" state of the date field to the given value */
 void gnc_xfer_dialog_set_date_sensitive(XferDialog *xferData, gboolean is_sensitive);
 
-/** Set the dialog's exchange rate edit.  If price_value is 0, then do
- *  nothing.
- */
-void gnc_xfer_dialog_set_price_edit(XferDialog *xferData,
-				    gnc_numeric price_value);
+/** Set the exchange rate.  If exchange-rate is 0, then do nothing */
+void gnc_xfer_dialog_set_exchange_rate(XferDialog *xferData,
+                                       gnc_numeric exchange_rate);
 
 /** Indicate whether the dialog should quickfill based on the "To" account,
  * rather than the default which is the "From" account.

commit 39d43a31fa539d43d10e7dff73fcdb4c34866dfe
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Oct 23 11:44:57 2015 -0700

    Revert "Fix price-reading crash if the price needs to be inverted."
    
    This reverts commit 027080a830029e219dbe3592c4cc8f9cb06200eb,
    and is step 2 in reverting the single-price changes.

diff --git a/src/scm/price-quotes.scm b/src/scm/price-quotes.scm
index ededd0e..68c67bf 100644
--- a/src/scm/price-quotes.scm
+++ b/src/scm/price-quotes.scm
@@ -419,12 +419,12 @@
             (set! saved-price (gnc-pricedb-lookup-day pricedb
                                                       commodity currency
                                                       gnc-time))
-            (if (null? saved-price) ;;See if there's a reversed price.
+            (if (null? saved-price)
                 (begin
                   (set! saved-price (gnc-pricedb-lookup-day pricedb currency
                                                             commodity gnc-time))
                   (if (not (null? saved-price))
-                      (set! price (gnc-numeric-invert price)))))
+                      (set! price (gnc-numeric-invert(price))))))
             (if (not (null? saved-price))
                 (if (> (gnc-price-get-source saved-price) PRICE-SOURCE-FQ)
                     (begin

commit 9fc0c4667c09e487d74f2745c51508a05273f083
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Oct 23 11:43:03 2015 -0700

    Revert "Bug 756339 - Prices table not updated"
    
    This reverts commit 0baf078b6f2b33b607ccb1b022feee2ff7f0501a,
    and is step 1 in reverting out the single-price changes and
    moving them to master.

diff --git a/src/backend/sql/gnc-price-sql.c b/src/backend/sql/gnc-price-sql.c
index 83c5f3d..92a5176 100644
--- a/src/backend/sql/gnc-price-sql.c
+++ b/src/backend/sql/gnc-price-sql.c
@@ -203,7 +203,7 @@ write_price( GNCPrice* p, gpointer data )
     g_return_val_if_fail( p != NULL, FALSE );
     g_return_val_if_fail( data != NULL, FALSE );
 
-    if ( s->is_ok && gnc_price_get_source(p) != PRICE_SOURCE_INVOICE)
+    if ( s->is_ok && gnc_price_get_source(p) == PRICE_SOURCE_INVOICE)
     {
         s->is_ok = save_price( s->be, QOF_INSTANCE(p) );
     }



Summary of changes:
 src/app-utils/gnc-sx-instance-model.c        |    7 +-
 src/backend/sql/gnc-price-sql.c              |    2 +-
 src/backend/xml/gnc-pricedb-xml-v2.c         |    4 +-
 src/backend/xml/io-gncxml-v1.cpp             |    2 +-
 src/business/business-gnome/dialog-invoice.c |   36 +-
 src/engine/engine.i                          |   11 +-
 src/engine/gnc-pricedb-p.h                   |    2 +-
 src/engine/gnc-pricedb.c                     |  109 +--
 src/engine/gnc-pricedb.h                     |   37 +-
 src/engine/test-core/test-engine-stuff.cpp   |    7 +-
 src/gnome-utils/dialog-transfer.c            | 1011 ++++++++++++--------------
 src/gnome-utils/dialog-transfer.h            |    8 +-
 src/gnome-utils/gnc-tree-model-price.c       |    2 +-
 src/gnome-utils/gnc-tree-view-price.c        |    3 +-
 src/gnome/assistant-stock-split.c            |    4 +-
 src/gnome/dialog-price-editor.c              |   10 +-
 src/libqof/qof/gnc-numeric.cpp               |    5 -
 src/libqof/qof/gnc-numeric.h                 |    7 -
 src/quotes/gnc-fq-dump                       |    9 -
 src/quotes/gnc-fq-helper.in                  |   13 -
 src/register/ledger-core/split-register.c    |   68 +-
 src/scm/price-quotes.scm                     |  103 +--
 22 files changed, 588 insertions(+), 872 deletions(-)



More information about the gnucash-changes mailing list