r22920 - gnucash/trunk - Register rewrite Update, this adds the trading accounts option with some other changes.

Geert Janssens gjanssens at code.gnucash.org
Sat Apr 20 12:45:56 EDT 2013


Author: gjanssens
Date: 2013-04-20 12:45:56 -0400 (Sat, 20 Apr 2013)
New Revision: 22920
Trac: http://svn.gnucash.org/trac/changeset/22920

Added:
   gnucash/trunk/src/gnome-utils/gnc-tree-util-split-reg.c
   gnucash/trunk/src/gnome-utils/gnc-tree-util-split-reg.h
Modified:
   gnucash/trunk/po/POTFILES.in
   gnucash/trunk/src/engine/Transaction.c
   gnucash/trunk/src/engine/Transaction.h
   gnucash/trunk/src/gnome-utils/Makefile.am
   gnucash/trunk/src/gnome-utils/gnc-tree-control-split-reg.c
   gnucash/trunk/src/gnome-utils/gnc-tree-model-split-reg.c
   gnucash/trunk/src/gnome-utils/gnc-tree-model-split-reg.h
   gnucash/trunk/src/gnome-utils/gnc-tree-view-split-reg.c
   gnucash/trunk/src/gnome-utils/gnc-tree-view-split-reg.h
   gnucash/trunk/src/gnome/gnc-plugin-page-register2.c
   gnucash/trunk/src/gnome/gnc-split-reg2.c
   gnucash/trunk/src/register/ledger-core/gnc-ledger-display2.c
Log:
Register rewrite Update, this adds the trading accounts option with some other changes.

This update adds the trading accounts option. Also included is a fix for the way the model is loaded and changes the way it the view gets refreshed. There are also some minor changes to transaction confirmation. Two new files have been added and some functions moved to these with more to follow.
Author: Robert Fewell

Modified: gnucash/trunk/po/POTFILES.in
===================================================================
--- gnucash/trunk/po/POTFILES.in	2013-04-19 20:20:22 UTC (rev 22919)
+++ gnucash/trunk/po/POTFILES.in	2013-04-20 16:45:56 UTC (rev 22920)
@@ -319,6 +319,7 @@
 src/gnome-utils/gnc-tree-model-owner.c
 src/gnome-utils/gnc-tree-model-price.c
 src/gnome-utils/gnc-tree-model-split-reg.c
+src/gnome-utils/gnc-tree-util-split-reg.c
 src/gnome-utils/gnc-tree-view-account.c
 src/gnome-utils/gnc-tree-view.c
 src/gnome-utils/gnc-tree-view-commodity.c

Modified: gnucash/trunk/src/engine/Transaction.c
===================================================================
--- gnucash/trunk/src/engine/Transaction.c	2013-04-19 20:20:22 UTC (rev 22919)
+++ gnucash/trunk/src/engine/Transaction.c	2013-04-20 16:45:56 UTC (rev 22920)
@@ -646,7 +646,7 @@
  *   Neither 'from_trans', nor 'from_acc', nor any of 'from's splits may
  *   be modified in any way.
  *
- *   'no_date' if TRUE will not copy the date posted.
+ *   'no_start' if TRUE will not copy the date posted or Num.
  *
  *   The 'to_trans' transaction will end up with valid copies of from's
  *   splits.  In addition, the copies of any of from's splits that were
@@ -654,7 +654,7 @@
 \********************************************************************/
 void
 xaccTransCopyFromClipBoard(const Transaction *from_trans, Transaction *to_trans,
-                           const Account *from_acc, Account *to_acc, gboolean no_date)
+                           const Account *from_acc, Account *to_acc, gboolean no_start)
 {
     Timespec ts = {0,0};
     gboolean change_accounts = FALSE;
@@ -670,10 +670,11 @@
 
     xaccTransSetCurrency(to_trans, xaccTransGetCurrency(from_trans));
     xaccTransSetDescription(to_trans, xaccTransGetDescription(from_trans));
-    xaccTransSetNum(to_trans, xaccTransGetNum(from_trans));
+
     xaccTransSetNotes(to_trans, xaccTransGetNotes(from_trans));
-    if(!no_date)
+    if(!no_start)
     {
+        xaccTransSetNum(to_trans, xaccTransGetNum(from_trans));
         xaccTransGetDatePostedTS(from_trans, &ts);
         xaccTransSetDatePostedTS(to_trans, &ts);
     }

Modified: gnucash/trunk/src/engine/Transaction.h
===================================================================
--- gnucash/trunk/src/engine/Transaction.h	2013-04-19 20:20:22 UTC (rev 22919)
+++ gnucash/trunk/src/engine/Transaction.h	2013-04-20 16:45:56 UTC (rev 22920)
@@ -244,14 +244,14 @@
  *   Neither 'from_trans', nor 'from_acc', nor any of 'from's splits may be modified
  *   in any way.
  *
- *   'no_date' if TRUE will not copy the date posted.
+ *   'no_start' if TRUE will not copy the date posted or Num.
  *
  *   The 'to_trans' transaction will end up with valid copies of from's
  *   splits.  In addition, the copies of any of from's splits that were
  *   in from_acc (or at least claimed to be) will end up in to_acc.
  */
 void xaccTransCopyFromClipBoard(const Transaction *from_trans, Transaction *to_trans,
-                           const Account *from_acc, Account *to_acc, gboolean no_date);
+                           const Account *from_acc, Account *to_acc, gboolean no_start);
 
 /*################## Added for Reg2 #################*/
 

Modified: gnucash/trunk/src/gnome/gnc-plugin-page-register2.c
===================================================================
--- gnucash/trunk/src/gnome/gnc-plugin-page-register2.c	2013-04-19 20:20:22 UTC (rev 22919)
+++ gnucash/trunk/src/gnome/gnc-plugin-page-register2.c	2013-04-20 16:45:56 UTC (rev 22920)
@@ -1120,9 +1120,12 @@
         gnc_ppr_update_date_filter (page, FALSE);
     }
 
-    gnc_ledger_display2_refresh (priv->ledger);
+//    gnc_ledger_display2_refresh (priv->ledger);
 
+    /* This sets the default selection on load */
+    gnc_tree_view_split_reg_default_selection (view);
 
+
     plugin_page->summarybar = gsr2_create_summary_bar(priv->gsr);
     if (plugin_page->summarybar)
     {
@@ -3041,8 +3044,6 @@
     value = gtk_radio_action_get_current_value (current);
     gnc_split_reg2_change_style (priv->gsr, value);
 
-    gtk_tree_view_collapse_all (GTK_TREE_VIEW (gnc_ledger_display2_get_split_view_register (priv->ledger)));
-
     gnc_plugin_page_register2_ui_update (NULL, plugin_page);
     LEAVE(" ");
 }
@@ -3058,10 +3059,10 @@
 
     ENTER("(action %p, plugin_page %p)", action, plugin_page);
 
-    g_return_if_fail(GTK_IS_ACTION(action));
-    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+    g_return_if_fail (GTK_IS_ACTION(action));
+    g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
 
-    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (plugin_page);
     model = gnc_ledger_display2_get_split_model_register (priv->ledger);
 
     view = gnc_ledger_display2_get_split_view_register (priv->ledger);
@@ -3070,8 +3071,9 @@
     if (use_double_line != model->use_double_line)
     {
         gnc_tree_model_split_reg_config (model, model->type, model->style, use_double_line);
-        gtk_tree_view_collapse_all (GTK_TREE_VIEW(view));
-        gnc_ledger_display2_refresh (priv->ledger);
+
+        // This will re-display the view.
+        gnc_tree_view_split_reg_set_format (view);
     }
     LEAVE(" ");
 }
@@ -3086,11 +3088,11 @@
 
     ENTER("(action %p, plugin_page %p)", action, page);
 
-    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+    g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
 
     account = gnc_plugin_page_register2_get_account (page);
-    gnc_window = GNC_WINDOW(GNC_PLUGIN_PAGE (page)->window);
-    window = GTK_WIDGET(gnc_window_get_gtk_window(gnc_window));
+    gnc_window = GNC_WINDOW (GNC_PLUGIN_PAGE (page)->window);
+    window = GTK_WIDGET (gnc_window_get_gtk_window (gnc_window));
     gnc_xfer_dialog (window, account);
     LEAVE(" ");
 }
@@ -3728,29 +3730,26 @@
 }
 
 static void
-gnc_plugin_page_register2_refresh_cb (GHashTable *changes, gpointer user_data)
+gnc_plugin_page_register2_refresh_cb (GHashTable *changes, gpointer user_data) //this works
 {
     GncPluginPageRegister2 *page = user_data;
     GncPluginPageRegister2Private *priv;
     GncTreeViewSplitReg *view;
 
-// Not sure what this really is but it gets fired from preference changes.
-
-//g_print("gnc_plugin_page_register2_refresh_cb\n");
     g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (page));
     priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
     view = gnc_ledger_display2_get_split_view_register (priv->ledger);
-//g_print("gnc_plugin_page_register2_refresh_cb 0\n");
+
     if (changes)
     {
         const EventInfo* ei;
-//g_print("gnc_plugin_page_register2_refresh_cb 1\n");
-        ei = gnc_gui_get_entity_events(changes, &priv->key);
+
+        ei = gnc_gui_get_entity_events (changes, &priv->key);
         if (ei)
         {
             if (ei->event_mask & QOF_EVENT_DESTROY)
             {
-                gnc_main_window_close_page(GNC_PLUGIN_PAGE(page));
+                gnc_main_window_close_page (GNC_PLUGIN_PAGE (page));
                 return;
             }
             if (ei->event_mask & QOF_EVENT_MODIFY)
@@ -3760,10 +3759,8 @@
     }
     else
     {
-//g_print("gnc_plugin_page_register2_refresh_cb 2\n");
         /* Force updates */
         gnc_tree_view_split_reg_refresh_from_gconf (view);
-        gtk_widget_queue_draw (priv->widget);
     }
     gnc_plugin_page_register2_ui_update (NULL, page);
 }

Modified: gnucash/trunk/src/gnome/gnc-split-reg2.c
===================================================================
--- gnucash/trunk/src/gnome/gnc-split-reg2.c	2013-04-19 20:20:22 UTC (rev 22919)
+++ gnucash/trunk/src/gnome/gnc-split-reg2.c	2013-04-20 16:45:56 UTC (rev 22920)
@@ -271,10 +271,10 @@
 
     /* Restore the sort order from gconf */
     sort_string = gnc_gconf_get_string (gconf_key, "sort_order", NULL);
-    if (g_strcmp0 ("ascending", sort_string) == 0)
+    if (g_strcmp0 ("descending", sort_string) == 0)
+        view->sort_direction = -1;
+    else
         view->sort_direction = 1;
-    else
-        view->sort_direction = -1;
 
     g_object_set (G_OBJECT (view), "gconf-section", gconf_key, 
                  "show-column-menu", FALSE, NULL);
@@ -755,7 +755,9 @@
         return;
 
     gnc_tree_model_split_reg_config (model, model->type, style, model->use_double_line);
-    gnc_ledger_display2_refresh (gsr->ledger);
+
+    // This will re-display the view.
+    gnc_tree_view_split_reg_set_format (gnc_ledger_display2_get_split_view_register (gsr->ledger));
 }
 
 void
@@ -803,7 +805,9 @@
         return;
 
     gnc_tree_model_split_reg_config (model, model->type, model->style, use_double_line);
-    gnc_ledger_display2_refresh (gsr->ledger);
+
+    // This will re-display the view.
+    gnc_tree_view_split_reg_set_format (gnc_ledger_display2_get_split_view_register (gsr->ledger));
 }
 
 static

Modified: gnucash/trunk/src/gnome-utils/Makefile.am
===================================================================
--- gnucash/trunk/src/gnome-utils/Makefile.am	2013-04-19 20:20:22 UTC (rev 22919)
+++ gnucash/trunk/src/gnome-utils/Makefile.am	2013-04-20 16:45:56 UTC (rev 22920)
@@ -92,6 +92,7 @@
   gnc-tree-model-commodity.c \
   gnc-tree-model-price.c \
   gnc-tree-model-split-reg.c \
+  gnc-tree-util-split-reg.c \
   gnc-tree-view-account.c \
   gnc-tree-view-commodity.c \
   gnc-tree-view-owner.c \
@@ -170,6 +171,7 @@
   gnc-tree-model-commodity.h \
   gnc-tree-model-price.h \
   gnc-tree-model-split-reg.h \
+  gnc-tree-util-split-reg.h \
   gnc-tree-view-account.h \
   gnc-tree-view-commodity.h \
   gnc-tree-view-owner.h \

Modified: gnucash/trunk/src/gnome-utils/gnc-tree-control-split-reg.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-tree-control-split-reg.c	2013-04-19 20:20:22 UTC (rev 22919)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-control-split-reg.c	2013-04-20 16:45:56 UTC (rev 22920)
@@ -33,6 +33,7 @@
 
 #include "gnc-tree-control-split-reg.h"
 #include "gnc-tree-model-split-reg.h"
+#include "gnc-tree-util-split-reg.h"
 #include "gnc-tree-view-split-reg.h"
 #include "gnc-component-manager.h"
 #include "gnc-ui.h"
@@ -266,8 +267,6 @@
     window = gnc_tree_view_split_reg_get_parent (view);
     model = gnc_tree_view_split_reg_get_model_from_view (view);
 
-//FIXME ## Trading ## Copied from split-register-control, needs testing
-
     if (xaccTransUseTradingAccounts (trans))
     {
         MonetaryList *imbal_list;
@@ -297,7 +296,6 @@
     }
     else
         multi_currency = FALSE;
-//FIXME
 
     split = xaccTransGetSplit (trans, 0);
     other_split = xaccSplitGetOtherSplit (split);
@@ -452,6 +450,14 @@
 
     window = gnc_tree_view_split_reg_get_parent (view);
 
+    /* Make sure we NEED this for this type of register */
+    if (!gnc_tree_util_split_reg_has_rate (view))
+    {
+        message = _("This register does not support editing exchange rates.");
+        gnc_error_dialog(window, "%s", message);
+        return;
+    }
+
     /* If the anchor commodity is not a currency, cancel */
     if (anchor && !gnc_commodity_is_currency (xaccAccountGetCommodity (anchor)))
     {
@@ -461,7 +467,7 @@
     }
 
     /* If we're not expanded AND number of splits greater than two, nothing to do */
-    if ((num_splits > 2) && !expanded)
+    if ((gnc_tree_util_split_reg_is_multi (xaccTransGetSplit (trans, 0))) && !expanded)
     {
         message = _("You need to expand the transaction in order to modify its "
                     "exchange rates.");
@@ -469,9 +475,13 @@
         return;
     }
 
-    if (num_splits == 2 && anchor != NULL && !expanded)
+    if (!gnc_tree_util_split_reg_is_multi (xaccTransGetSplit (trans, 0)) && anchor != NULL && !expanded)
     {
         split = gnc_tree_control_split_reg_get_current_trans_split (view);
+
+        if (xaccAccountGetType (xaccSplitGetAccount (split)) == ACCT_TYPE_TRADING) // trading split
+            return;
+
         osplit = xaccSplitGetOtherSplit (split);
 
         value = xaccSplitGetValue (split);
@@ -480,9 +490,9 @@
         xaccTransBeginEdit (trans);
 
         if (txn_com == xaccAccountGetCommodity (xaccSplitGetAccount(split)))
-           gnc_tree_view_split_reg_set_value_for (view, trans, osplit, gnc_numeric_neg (value), TRUE);
+           gnc_tree_util_split_reg_set_value_for (view, trans, osplit, gnc_numeric_neg (value), TRUE);
         else
-           gnc_tree_view_split_reg_set_value_for (view, trans, split, value, TRUE);
+           gnc_tree_util_split_reg_set_value_for (view, trans, split, value, TRUE);
 
         xaccTransCommitEdit (trans);
         gnc_tree_view_split_reg_set_dirty_trans (view, NULL);
@@ -492,6 +502,9 @@
     {
         split = gnc_tree_view_split_reg_get_current_split (view);
 
+        if (xaccAccountGetType (xaccSplitGetAccount (split)) == ACCT_TYPE_TRADING) // trading split
+            return;
+
         value = xaccSplitGetValue (split);
 
         if (txn_com == xaccAccountGetCommodity (xaccSplitGetAccount(split)))
@@ -505,7 +518,7 @@
             gnc_tree_view_split_reg_set_dirty_trans (view, trans);
             xaccTransBeginEdit (trans);
 
-            gnc_tree_view_split_reg_set_value_for (view, trans, split, value, TRUE);
+            gnc_tree_util_split_reg_set_value_for (view, trans, split, value, TRUE);
 
             xaccTransCommitEdit (trans);
             gnc_tree_view_split_reg_set_dirty_trans (view, NULL);
@@ -839,7 +852,7 @@
 {
     GncTreeModelSplitReg *model;
     GtkTreePath *mpath, *spath;
-    GtkTreePath *new_spath;
+    GtkTreePath  *new_mpath, *new_spath;
     gint *indices;
 
     ENTER("Move relative, view is %p, relative is %d", view, relative);
@@ -867,8 +880,17 @@
     gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), new_spath, NULL, FALSE);
 
     if (relative == 0)
+    {
         gnc_tree_view_split_reg_block_selection (view, FALSE);
 
+        /* Get the new model path we are pointing at */
+        new_mpath = gnc_tree_view_split_reg_get_model_path_from_sort_path (view, new_spath);
+
+        /* As we are not emitting selection change, we need to save the current path ref */
+        gnc_tree_view_split_reg_set_current_path (view, new_mpath);
+        gtk_tree_path_free (new_mpath);
+    }
+
     LEAVE("new_spath is %s", gtk_tree_path_to_string (new_spath));
 
     gtk_tree_path_free (new_spath);
@@ -2018,10 +2040,10 @@
 
     view->sort_col = sortcol - 1;
 
-    if (type == GTK_SORT_ASCENDING)
+    if (type == GTK_SORT_DESCENDING)
+        view->sort_direction = -1;
+    else
         view->sort_direction = 1;
-    else
-        view->sort_direction = -1;
 
     /* Save the sort depth to gconf */
     gconf_section = gnc_tree_view_get_gconf_section (GNC_TREE_VIEW (view));

Modified: gnucash/trunk/src/gnome-utils/gnc-tree-model-split-reg.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-tree-model-split-reg.c	2013-04-19 20:20:22 UTC (rev 22919)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-model-split-reg.c	2013-04-20 16:45:56 UTC (rev 22920)
@@ -49,7 +49,7 @@
 /* Signal codes */
 enum
 {
-    REFRESH_VIEW,
+    REFRESH_TRANS,
     REFRESH_STATUS_BAR,
     SELECTION_MOVE_DELETE,
     SELECTION_MOVE_FILTER,
@@ -288,14 +288,16 @@
     o_class->finalize = gnc_tree_model_split_reg_finalize;
     o_class->dispose = gnc_tree_model_split_reg_dispose;
 
-    gnc_tree_model_split_reg_signals[REFRESH_VIEW] =
-        g_signal_new("refresh_view",
+    gnc_tree_model_split_reg_signals[REFRESH_TRANS] =
+        g_signal_new("refresh_trans",
                      G_TYPE_FROM_CLASS (o_class),
-                     G_SIGNAL_RUN_LAST,
-                     G_STRUCT_OFFSET (GncTreeModelSplitRegClass, refresh_view),
+                     G_SIGNAL_RUN_FIRST,
+                     G_STRUCT_OFFSET (GncTreeModelSplitRegClass, refresh_trans),
                      NULL, NULL,
-                     g_cclosure_marshal_VOID__VOID,
-                     G_TYPE_NONE, 0);
+                     g_cclosure_marshal_VOID__POINTER,
+                     G_TYPE_NONE,
+                     1,
+                     G_TYPE_POINTER);
 
     gnc_tree_model_split_reg_signals[REFRESH_STATUS_BAR] =
         g_signal_new("refresh_status_bar",
@@ -328,7 +330,7 @@
                      1,
                      G_TYPE_POINTER);
 
-    klass->refresh_view = NULL;
+    klass->refresh_trans = NULL;
     klass->refresh_status_bar = NULL;
     klass->selection_move_delete = NULL;
     klass->selection_move_filter = NULL;
@@ -558,6 +560,9 @@
     /* Add the blank transaction to the tlist */
     priv->tlist = g_list_append (priv->tlist, priv->btrans);
 
+    PINFO("Register for Account '%s' has %d transactions and %d splits",
+          default_account ? xaccAccountGetName (default_account) : "NULL", g_list_length (priv->tlist), g_list_length (slist));
+
     /* Update the completion model liststores */
     gnc_tree_model_split_reg_update_completion (model);
 
@@ -744,7 +749,7 @@
     case GNC_TREE_MODEL_SPLIT_REG_COL_DUEDATE:
     case GNC_TREE_MODEL_SPLIT_REG_COL_NUMACT:
     case GNC_TREE_MODEL_SPLIT_REG_COL_DESCNOTES:
-    case GNC_TREE_MODEL_SPLIT_REG_COL_TRANSVOID:
+    case GNC_TREE_MODEL_SPLIT_REG_COL_TRANSFERVOID:
     case GNC_TREE_MODEL_SPLIT_REG_COL_RECN:
     case GNC_TREE_MODEL_SPLIT_REG_COL_DEBIT:
     case GNC_TREE_MODEL_SPLIT_REG_COL_CREDIT:
@@ -1201,7 +1206,7 @@
     case GNC_TREE_MODEL_SPLIT_REG_COL_DESCNOTES:
         break;
 
-    case GNC_TREE_MODEL_SPLIT_REG_COL_TRANSVOID:
+    case GNC_TREE_MODEL_SPLIT_REG_COL_TRANSFERVOID:
         break;
 
     case GNC_TREE_MODEL_SPLIT_REG_COL_RECN:
@@ -2788,7 +2793,7 @@
                 gtm_insert_row_at (model, &iter1);
                 iter2 = gtm_make_iter (model, TROW2 | BLANK, tnode, NULL);
                 gtm_insert_row_at (model, &iter2);
-                g_signal_emit_by_name (model, "refresh_view", NULL);
+                g_signal_emit_by_name (model, "refresh_trans", priv->btrans);
             }
 
             if (get_iter (model, trans, NULL, &iter1, &iter2))
@@ -2796,7 +2801,7 @@
                 DEBUG ("change trans %p (%s)", trans, name);
                 gtm_changed_row_at (model, &iter1);
                 gtm_changed_row_at (model, &iter2);
-                g_signal_emit_by_name (model, "refresh_view", NULL);
+                g_signal_emit_by_name (model, "refresh_trans", trans);
             }
             break;
         case QOF_EVENT_DESTROY:
@@ -2815,7 +2820,6 @@
                 DEBUG("destroy trans %p (%s)", trans, name);
                 g_signal_emit_by_name (model, "selection_move_delete", trans);
                 gtm_delete_trans (model, trans);
-                g_signal_emit_by_name (model, "refresh_view", NULL);
             }
             break;
         default:
@@ -2836,13 +2840,13 @@
             {
                 DEBUG("Insert trans %p for gl (%s)", trans, name);
                 gtm_insert_trans (model, trans);
-                g_signal_emit_by_name (model, "refresh_view", NULL);
+                g_signal_emit_by_name (model, "refresh_trans", trans);
             }
             else if (!g_list_find (priv->tlist, trans) && ((xaccAccountHasAncestor (acc, priv->anchor) && priv->display_subacc) || acc == priv->anchor ))
             {
                 DEBUG("Insert trans %p (%s)", trans, name);
                 gtm_insert_trans (model, trans);
-                g_signal_emit_by_name (model, "refresh_view", NULL);
+                g_signal_emit_by_name (model, "refresh_trans", trans);
             }
             break;
         default:

Modified: gnucash/trunk/src/gnome-utils/gnc-tree-model-split-reg.h
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-tree-model-split-reg.h	2013-04-19 20:20:22 UTC (rev 22919)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-model-split-reg.h	2013-04-20 16:45:56 UTC (rev 22920)
@@ -86,25 +86,25 @@
 
 typedef enum
 {
-    GNC_TREE_MODEL_SPLIT_REG_COL_GUID,      //0
-    GNC_TREE_MODEL_SPLIT_REG_COL_DATE,      //1
-    GNC_TREE_MODEL_SPLIT_REG_COL_DUEDATE,   //2
-    GNC_TREE_MODEL_SPLIT_REG_COL_NUMACT,    //3
-    GNC_TREE_MODEL_SPLIT_REG_COL_DESCNOTES, //4
-    GNC_TREE_MODEL_SPLIT_REG_COL_TRANSVOID, //5
-    GNC_TREE_MODEL_SPLIT_REG_COL_RECN,      //6
-    GNC_TREE_MODEL_SPLIT_REG_COL_DEBIT,     //7
-    GNC_TREE_MODEL_SPLIT_REG_COL_CREDIT,    //8
+    GNC_TREE_MODEL_SPLIT_REG_COL_GUID,         //0
+    GNC_TREE_MODEL_SPLIT_REG_COL_DATE,         //1
+    GNC_TREE_MODEL_SPLIT_REG_COL_DUEDATE,      //2
+    GNC_TREE_MODEL_SPLIT_REG_COL_NUMACT,       //3
+    GNC_TREE_MODEL_SPLIT_REG_COL_DESCNOTES,    //4
+    GNC_TREE_MODEL_SPLIT_REG_COL_TRANSFERVOID, //5
+    GNC_TREE_MODEL_SPLIT_REG_COL_RECN,         //6
+    GNC_TREE_MODEL_SPLIT_REG_COL_DEBIT,        //7
+    GNC_TREE_MODEL_SPLIT_REG_COL_CREDIT,       //8
 
     GNC_TREE_MODEL_SPLIT_REG_COL_LAST_VISIBLE = GNC_TREE_MODEL_SPLIT_REG_COL_CREDIT, //8
 
     /* internal hidden columns */
-    GNC_TREE_MODEL_SPLIT_REG_COL_RO,        //9
-    GNC_TREE_MODEL_SPLIT_REG_COL_FILTER_VIS,//10
-    GNC_TREE_MODEL_SPLIT_REG_COL_NUM_VIS,   //11
-    GNC_TREE_MODEL_SPLIT_REG_COL_ACT_VIS,   //12
+    GNC_TREE_MODEL_SPLIT_REG_COL_RO,           //9
+    GNC_TREE_MODEL_SPLIT_REG_COL_FILTER_VIS,   //10
+    GNC_TREE_MODEL_SPLIT_REG_COL_NUM_VIS,      //11
+    GNC_TREE_MODEL_SPLIT_REG_COL_ACT_VIS,      //12
 
-    GNC_TREE_MODEL_SPLIT_REG_NUM_COLUMNS    //13
+    GNC_TREE_MODEL_SPLIT_REG_NUM_COLUMNS       //13
 } GncTreeModelSplitRegColumn;
 
 /* typedefs & structures */
@@ -143,8 +143,9 @@
 {
     GncTreeModelClass gnc_tree_model;                   /**< The parent object data. */
 
-    /* This signal is emitted to refresh the view */
-    void (*refresh_view) (GncTreeModelSplitReg *model, gpointer user_data);
+    /* This signal is emitted to refresh the transaction view, the pointer has
+       the transaction */
+    void (*refresh_trans) (GncTreeModelSplitReg *model, gpointer item);
 
     /* This signal is emitted to refresh the status bar */
     void (*refresh_status_bar) (GncTreeModelSplitReg *model, gpointer user_data);

Added: gnucash/trunk/src/gnome-utils/gnc-tree-util-split-reg.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-tree-util-split-reg.c	                        (rev 0)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-util-split-reg.c	2013-04-20 16:45:56 UTC (rev 22920)
@@ -0,0 +1,772 @@
+/********************************************************************\
+ * gnc-tree-util-split-reg.c -- GtkTreeView implementation          *
+ *                     to display registers in a GtkTreeView.       *
+ *                                                                  *
+ * Copyright (C) 2006-2007 Chris Shoemaker <c.shoemaker at cox.net>    *
+ * Copyright (C) 2012 Robert Fewell                                 *
+ *                                                                  *
+ * 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:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gnc-tree-util-split-reg.h"
+#include "gnc-tree-model-split-reg.h"
+#include "gnc-tree-view-split-reg.h"
+
+#include "gnc-ui.h"
+#include "dialog-utils.h"
+#include "dialog-transfer.h"
+#include "engine-helpers.h"
+#include "Transaction.h"
+
+
+#define SPLIT_TRANS_STR _("-- Split Transaction --")
+#define STOCK_SPLIT_STR _("-- Stock Split --")
+
+/** Static Globals *******************************************************/
+static QofLogModule log_module = GNC_MOD_LEDGER;
+
+/*****************************************************************************/
+
+
+/* Is current split a security account */
+static gboolean
+gtu_split_reg_use_security (GncTreeViewSplitReg *view)
+{
+    RowDepth depth;
+    Account *account = NULL;
+    Split *split;
+
+    split = gnc_tree_view_split_reg_get_current_split (view);
+
+    depth = gnc_tree_view_reg_get_selected_row_depth (view);
+
+    if (!split)
+        return TRUE;
+
+    if (depth != SPLIT3)
+        return TRUE;
+
+    if (!account)
+        account = xaccSplitGetAccount (split);
+
+    if (!account)
+        return TRUE;
+
+    if (xaccTransUseTradingAccounts (xaccSplitGetParent (split)))
+    {
+        if (!gnc_commodity_is_iso (xaccAccountGetCommodity (account)))
+            return TRUE;
+    }
+
+    return xaccAccountIsPriced (account);
+}
+
+
+/* Get the rate from the price db */
+static gnc_numeric
+gtu_split_reg_get_rate_from_db (gnc_commodity *from, gnc_commodity *to)
+{
+    GNCPrice *prc;
+    gnc_numeric rate_split;
+    gboolean have_rate = FALSE;
+    QofBook *book = gnc_get_current_book ();
+
+    /* Do we have a rate allready */
+    prc = gnc_pricedb_lookup_latest (gnc_pricedb_get_db (book), from, to);
+    if (prc)
+    {
+        rate_split = gnc_price_get_value (prc);
+        gnc_price_unref (prc);
+        have_rate = TRUE;
+    }
+
+    /* Lets try reversing the commodities */
+    if (!have_rate)
+    {
+        prc = gnc_pricedb_lookup_latest (gnc_pricedb_get_db (book), to, from);
+        if (prc)
+        {
+            rate_split = gnc_numeric_div (gnc_numeric_create (100, 100), gnc_price_get_value (prc),
+                                 GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
+
+            gnc_price_unref (prc);
+            have_rate = TRUE;
+        }
+    }
+
+    /* No rate, set to 1/1 */
+    if (!have_rate)
+        rate_split = gnc_numeric_create (100, 100);
+
+    return rate_split;
+}
+
+
+/* Do we need an exchange rate */
+static gboolean
+gtu_split_reg_needs_exchange_rate (GncTreeViewSplitReg *view, Transaction *trans, Split *split)
+{
+    gnc_commodity *split_com, *txn_curr, *reg_com;
+
+    ENTER("gtu_split_reg_needs_exchange_rate - trans %p and split %p", trans, split);
+
+    txn_curr = xaccTransGetCurrency (trans);
+    split_com = xaccAccountGetCommodity (xaccSplitGetAccount (split));
+    if (split_com && txn_curr && !gnc_commodity_equiv (split_com, txn_curr))
+    {
+        LEAVE("gtu_split_reg_needs_exchange_rate split_com to txn_curr return TRUE");
+        return TRUE;
+    }
+
+    reg_com = gnc_tree_view_split_reg_get_reg_commodity (view);
+    if (split_com && reg_com && !gnc_commodity_equiv (split_com, reg_com))
+    {
+        LEAVE("gtu_split_reg_needs_exchange_rate split_com and reg_com return TRUE");
+        return TRUE;
+    }
+    LEAVE("No Exchange rate needed");
+    return FALSE;
+}
+
+
+/* Either sets the value and amount for split and returns TRUE, or
+   does nothing and returns FALSE. */
+static gboolean
+gtu_split_reg_handle_exchange_rate (GncTreeViewSplitReg *view, gnc_numeric amount, Transaction *trans, Split *split, gboolean force)
+{
+    GncTreeModelSplitReg *model;
+    XferDialog *xfer;
+    gboolean rate_split_ok, rate_reg_ok;
+    gnc_numeric rate_split, rate_reg, value;
+    Account *reg_acc;
+    gnc_commodity *xfer_comm = xaccAccountGetCommodity (xaccSplitGetAccount (split));
+    gnc_commodity *reg_comm = gnc_tree_view_split_reg_get_reg_commodity (view);
+    gnc_commodity *trans_curr = xaccTransGetCurrency (trans);
+    gboolean expanded;
+    gboolean have_rate = TRUE;
+
+    ENTER("handle_exchange_rate amount %s, trans %p and split %p force %d", gnc_numeric_to_string (amount), trans, split, force);
+
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    reg_acc = gnc_tree_model_split_reg_get_anchor (model);
+
+    /* Rate from trans-curr to split-comm */
+    rate_split_ok = xaccTransGetRateForCommodity (trans, xfer_comm, split, &rate_split);
+    DEBUG("rate_split_ok %d and xfer_comm %s", rate_split_ok, gnc_commodity_get_fullname (xfer_comm));
+
+    /* Rate from trans-curr to reg-comm */
+    rate_reg_ok = xaccTransGetRateForCommodity (trans, reg_comm, split, &rate_reg);
+    DEBUG("rate_reg_ok %d and reg_comm %s", rate_reg_ok, gnc_commodity_get_fullname (reg_comm));
+
+    /* Are we expanded */
+    expanded = gnc_tree_view_split_reg_trans_expanded (view, trans);
+
+    if (gnc_commodity_equal (trans_curr, xfer_comm) && rate_split_ok)
+    {
+        xaccSplitSetAmount (split, amount);
+        xaccSplitSetValue (split, amount);
+        return TRUE;
+    }
+
+    if (rate_reg_ok && rate_split_ok && !force)
+    {
+        value = gnc_numeric_div (amount, rate_reg, gnc_commodity_get_fraction (trans_curr), GNC_HOW_DENOM_REDUCE);
+        amount = gnc_numeric_mul (value, rate_split, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND);
+    }
+    else
+    {
+        if (!rate_split_ok)
+            rate_split = gtu_split_reg_get_rate_from_db (reg_comm, xfer_comm);
+
+        /* create the exchange-rate dialog */
+        xfer = gnc_xfer_dialog (NULL, NULL);
+
+        gnc_xfer_dialog_is_exchange_dialog (xfer, &rate_split);
+
+        /* fill in the dialog entries */
+        gnc_xfer_dialog_set_description (xfer, xaccTransGetDescription (trans));
+        gnc_xfer_dialog_set_memo (xfer, xaccSplitGetMemo (split));
+
+        /* Get per book option */
+        gnc_xfer_dialog_set_num (xfer, gnc_get_num_action (trans, split));
+        gnc_xfer_dialog_set_date (xfer, timespecToTime64 (xaccTransRetDatePostedTS (trans)));
+
+        value = amount;
+        if (gnc_xfer_dialog_run_exchange_dialog (xfer, &rate_split, value, reg_acc, trans, xfer_comm, expanded))
+        {
+            if (!rate_split_ok)
+                rate_split = gnc_numeric_create (1, 1);
+            have_rate = FALSE;
+        }
+        else
+            have_rate = TRUE;
+
+        amount = gnc_numeric_mul (value, rate_split, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND);
+    }
+    xaccSplitSetAmount (split, amount);
+    xaccSplitSetValue (split, value);
+
+    LEAVE("handle_exchange_rate set split %p amt=%s; and val=%s", split, gnc_numeric_to_string (amount), gnc_numeric_to_string (value));
+    return have_rate;
+}
+
+
+/*###########################################################################*/
+
+
+
+/* return TRUE if we have a RATE; return FALSE if we do not. */
+gboolean
+gnc_tree_util_split_reg_has_rate (GncTreeViewSplitReg *view)
+{
+    GncTreeModelSplitReg *model;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    switch (model->type)
+    {
+    case BANK_REGISTER2:
+    case CASH_REGISTER2:
+    case ASSET_REGISTER2:
+    case CREDIT_REGISTER2:
+    case LIABILITY_REGISTER2:
+    case INCOME_REGISTER2:
+    case EXPENSE_REGISTER2:
+    case EQUITY_REGISTER2:
+    case TRADING_REGISTER2:
+    case GENERAL_LEDGER2:
+    case INCOME_LEDGER2:
+    case SEARCH_LEDGER2:
+        return TRUE;
+
+    case STOCK_REGISTER2:
+    case CURRENCY_REGISTER2:
+    case PORTFOLIO_LEDGER2:
+    case RECEIVABLE_REGISTER2:
+    case PAYABLE_REGISTER2:
+    default:
+        return FALSE;
+    }
+}
+
+
+/* Is this split part of a multi split transaction */
+gboolean
+gnc_tree_util_split_reg_is_multi (Split *split)
+{
+    gboolean multi = FALSE;
+    Split *osplit;
+
+    if (!split)
+        return FALSE;
+
+    osplit = xaccSplitGetOtherSplit (split);
+
+    if (osplit)
+            multi = FALSE;
+    else
+    {
+        /* For multi-split transactions and stock splits,
+         * use a special value. */
+        osplit = xaccTransGetSplit (xaccSplitGetParent (split), 1);
+
+        if (osplit)
+            multi = TRUE;
+        else if (g_strcmp0 ("stock-split", xaccSplitGetType (split)) == 0)
+            multi = TRUE;
+        else
+            multi = FALSE;
+    }
+    return multi;
+}
+
+
+/* Return the string entry for transfer column and if multi */
+const char *
+gnc_tree_util_split_reg_get_transfer_entry (Split *split, gboolean *is_multi)
+{
+    static char *name = NULL;
+    gboolean multi = FALSE;
+
+    Split *osplit;
+
+    if (is_multi)
+        *is_multi = multi;
+
+    if (!split)
+        return NULL;
+
+    osplit = xaccSplitGetOtherSplit (split);
+
+    g_free (name);
+
+    if (osplit)
+        name = gnc_get_account_name_for_register (xaccSplitGetAccount (osplit));
+    else
+    {
+        /* For multi-split transactions and stock splits,
+         * use a special value. */
+        osplit = xaccTransGetSplit (xaccSplitGetParent (split), 1);
+        if (osplit)
+        {
+            name = g_strdup (SPLIT_TRANS_STR);
+            multi = TRUE;
+        }
+        else if (g_strcmp0 ("stock-split", xaccSplitGetType (split)) == 0)
+        {
+            name = g_strdup (STOCK_SPLIT_STR);
+            multi = TRUE;
+        }
+        else
+            name = g_strdup ("");
+    }
+
+    if (is_multi)
+        *is_multi = multi;
+
+    return name;
+}
+
+
+
+
+
+
+/*###########################################################################*/
+
+/* returns TRUE if you need to convert the split's value to the local
+ * (account) display currency.  Returns FALSE if you can just use the
+ * split->value directly.
+ */
+gboolean
+gnc_tree_util_split_reg_needs_conv_rate (GncTreeViewSplitReg *view,
+                                    Transaction *trans, Account *acc)
+{
+    gnc_commodity *trans_cur, *acc_com;
+
+    /* If there is not a RATE_CELL, then don't do anything */
+    if (!gnc_tree_util_split_reg_has_rate (view))
+        return FALSE;
+
+    /* if txn->currency == acc->commodity, then return FALSE */
+    acc_com = xaccAccountGetCommodity (acc);
+    trans_cur = xaccTransGetCurrency (trans);
+    if (trans_cur && acc_com && gnc_commodity_equal (trans_cur, acc_com))
+        return FALSE;
+
+    return TRUE;
+}
+
+
+gboolean
+gnc_tree_util_split_reg_needs_amount (GncTreeViewSplitReg *view, Split *split)
+{
+    Transaction *txn = xaccSplitGetParent (split);
+    Account *acc = xaccSplitGetAccount (split);
+
+    return gnc_tree_util_split_reg_needs_conv_rate (view, txn, acc);
+}
+
+/*###########################################################################*/
+
+gnc_numeric
+gnc_tree_util_split_reg_get_value_for (GncTreeViewSplitReg *view, Transaction *trans, Split *split, gboolean is_blank)
+{
+    gnc_numeric        ret_num;
+    GNCPrintAmountInfo ret_print_info;
+
+    if (gnc_tree_util_split_reg_get_debcred_entry (view, trans, split, is_blank, &ret_num, &ret_print_info))
+        return ret_num;
+    else
+        return gnc_numeric_zero();
+}
+
+
+gboolean
+gnc_tree_util_split_reg_get_debcred_entry (GncTreeViewSplitReg *view,
+                                      Transaction *trans, Split *split,
+                                      gboolean is_blank, gnc_numeric *ret_num,
+                                      GNCPrintAmountInfo *ret_print_info)
+
+{
+    GncTreeModelSplitReg *model;
+    gnc_commodity *currency;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    currency = xaccTransGetCurrency (trans);
+    if (!currency)
+        currency = gnc_default_currency ();
+
+    if (is_blank)
+    {
+        gnc_numeric imbalance;
+        Account *acc;
+
+        imbalance = xaccTransGetImbalanceValue (trans);
+
+        if (gnc_numeric_zero_p (imbalance))
+            return FALSE;
+
+        if (xaccTransUseTradingAccounts (trans))
+        {
+            MonetaryList *imbal_list;
+            gnc_monetary *imbal_mon;
+            imbal_list = xaccTransGetImbalance (trans);
+
+            if (!imbal_list)
+            {
+                /* No commodity imbalance, there shouldn't be a value imablance. */
+                return FALSE;
+            }
+
+            if (imbal_list->next)
+            {
+                /* Multiple currency imbalance. */
+                gnc_monetary_list_free (imbal_list);
+                return FALSE;
+            }
+
+            imbal_mon = imbal_list->data;
+            if (!gnc_commodity_equal (gnc_monetary_commodity (*imbal_mon), currency))
+            {
+                /* Imbalance is in wrong currency */
+                gnc_monetary_list_free (imbal_list);
+                return FALSE;
+            }
+
+            if (!gnc_numeric_equal (gnc_monetary_value (*imbal_mon), imbalance))
+            {
+                /* Value and commodity imbalances differ */
+                gnc_monetary_list_free (imbal_list);
+                return FALSE;
+            }
+
+            /* Done with the imbalance list */
+            gnc_monetary_list_free (imbal_list);
+        }
+
+        imbalance = gnc_numeric_neg (imbalance);
+
+        acc = gnc_tree_model_split_reg_get_anchor (model);
+
+        if (gnc_tree_util_split_reg_needs_conv_rate (view, trans, acc))
+        {
+            imbalance = gnc_numeric_mul (imbalance,
+                                         xaccTransGetAccountConvRate (trans, acc),
+                                         gnc_commodity_get_fraction (currency),
+                                         GNC_HOW_RND_ROUND_HALF_UP);
+        }
+        else
+        {
+            imbalance = gnc_numeric_convert (imbalance,
+                                             gnc_commodity_get_fraction (currency),
+                                             GNC_HOW_RND_ROUND_HALF_UP);
+        }
+
+        *ret_num = imbalance;
+        *ret_print_info = gnc_account_print_info (acc, FALSE);
+         return TRUE;
+    }
+
+    {
+        gnc_numeric amount;
+        gnc_commodity *split_commodity;
+        GNCPrintAmountInfo print_info;
+        Account *account;
+        gnc_commodity *commodity;
+
+        account = gnc_tree_model_split_reg_get_anchor (model);
+
+        commodity = xaccAccountGetCommodity (account);
+        split_commodity = xaccAccountGetCommodity (xaccSplitGetAccount (split));
+
+        if (xaccTransUseTradingAccounts (trans))
+        {
+            gboolean use_symbol, is_current = FALSE;
+            Split *current_split = gnc_tree_view_split_reg_get_current_split (view);
+            RowDepth depth = gnc_tree_view_reg_get_selected_row_depth (view);
+
+            if ((split == current_split) && (depth == SPLIT3))
+                is_current = TRUE;
+
+            if (model->type == STOCK_REGISTER2 ||
+                    model->type == CURRENCY_REGISTER2 ||
+                    model->type == PORTFOLIO_LEDGER2)
+            {
+                gnc_commodity *amount_commodity;
+                /* security register.  If this split has price and shares columns,
+                   use the value, otherwise use the amount.  */
+                if (gtu_split_reg_use_security (view))
+                {
+                    amount = xaccSplitGetValue (split);
+                    amount_commodity = currency;
+                }
+                else
+                {
+                    amount = xaccSplitGetAmount (split);
+                    amount_commodity = split_commodity;
+                }
+                /* Show the currency if it is not the default currency */
+                if (is_current ||
+                        gnc_commodity_equiv (amount_commodity, gnc_default_currency ()))
+                    use_symbol = FALSE;
+                else
+                    use_symbol = TRUE;
+                print_info = gnc_commodity_print_info (amount_commodity, use_symbol);
+            }
+            else
+            {
+                /* non-security register, always use the split amount. */
+                amount = xaccSplitGetAmount (split);
+                if (is_current ||
+                        gnc_commodity_equiv (split_commodity, commodity))
+                    use_symbol = FALSE;
+                else
+                    use_symbol = TRUE;
+                print_info = gnc_commodity_print_info (split_commodity, use_symbol);
+            }
+        }
+        else
+        {
+            /* If this account is not a stock/mutual/currency account, and
+            * currency != the account commodity, then use the SplitAmount
+            * instead of the SplitValue.
+            */
+            switch (model->type)
+            {
+            case STOCK_REGISTER2:
+            case CURRENCY_REGISTER2:
+            case PORTFOLIO_LEDGER2:
+                amount = xaccSplitGetValue (split);
+                print_info = gnc_commodity_print_info (currency, FALSE);
+                break;
+
+            default:
+                if (commodity && !gnc_commodity_equal (commodity, currency))
+                    /* Convert this to the "local" value */
+                    amount = xaccSplitConvertAmount (split, account);
+                else
+                    amount = xaccSplitGetValue (split);
+                print_info = gnc_account_print_info (account, FALSE);
+                break;
+            }
+        }
+
+        if (gnc_numeric_zero_p (amount))
+            return FALSE;
+
+        *ret_num = amount;
+        *ret_print_info = print_info;
+         return TRUE;
+    }
+}
+
+/*###########################################################################*/
+
+void
+gnc_tree_util_split_reg_set_value_for (GncTreeViewSplitReg *view, Transaction *trans, Split *split, gnc_numeric input, gboolean force)
+{
+    GncTreeModelSplitReg *model;
+    GtkWidget *window;
+    Account *anchor;
+    Account *acct = xaccSplitGetAccount (split);
+    gnc_commodity *currency;
+    gnc_numeric value, amount, rate;
+
+    ENTER("set_value_for trans %p and split %p input %s force %d", trans, split, gnc_numeric_to_string (input), force);
+
+    currency = xaccTransGetCurrency (trans);
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    anchor = gnc_tree_model_split_reg_get_anchor (model);
+
+    if (gnc_numeric_zero_p (input))
+    {
+        xaccSplitSetValue (split, input);
+        xaccSplitSetAmount (split, input);
+        LEAVE("input is zero");
+        return;
+    }
+
+    window = gnc_tree_view_split_reg_get_parent (view);
+
+    if (gtu_split_reg_needs_exchange_rate (view, trans, split))
+    {
+        if (gtu_split_reg_handle_exchange_rate (view, input, trans, split, force))
+        {
+            ; //FIXME ??????
+        }
+        else
+        {
+            gnc_error_dialog (window, "%s",
+                         _("Exchange Rate Canceled, using existing rate or default 1 to 1 rate if this is a new transaction."));
+        }
+        LEAVE("used exchange rate");
+        return;
+    }
+
+    gnc_tree_util_split_reg_save_amount_values (view, trans, split, input);
+
+    LEAVE(" ");
+}
+
+void
+gnc_tree_util_split_reg_save_amount_values (GncTreeViewSplitReg *view, Transaction *trans, Split *split, gnc_numeric input)
+{
+    GncTreeModelSplitReg *model;
+    Account *acc;
+    gnc_numeric new_amount, convrate, amtconv, value;
+    gnc_commodity *curr, *reg_com, *xfer_com;
+    Account *xfer_acc;
+
+    ENTER("View is %p, trans is %p, split is %p, input is %s", view, trans, split, gnc_numeric_to_string (input));
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    new_amount = input;
+
+    acc = gnc_tree_model_split_reg_get_anchor (model);
+
+    xfer_acc = xaccSplitGetAccount (split);
+    xfer_com = xaccAccountGetCommodity (xfer_acc);
+    reg_com = xaccAccountGetCommodity (acc);
+    curr = xaccTransGetCurrency (trans);
+
+    if (!xaccTransGetRateForCommodity (trans, reg_com, NULL, &convrate))
+        convrate = gnc_numeric_create (100, 100);
+
+    amtconv = convrate;
+
+    if (gnc_tree_util_split_reg_needs_conv_rate (view, trans, acc))
+    {
+
+        /* If we are in an expanded register and the xfer_acc->comm !=
+        * reg_acc->comm then we need to compute the convrate here.
+        * Otherwise, we _can_ use the rate_cell!
+        */
+        if (gnc_commodity_equal (reg_com, xfer_com))
+            amtconv = xaccTransGetAccountConvRate (trans, acc);
+    }
+
+    if (xaccTransUseTradingAccounts (trans))
+    {
+        /* Using currency accounts, the amount is probably really the
+           amount and not the value. */
+        gboolean is_amount;
+
+        if (model->type == STOCK_REGISTER2 ||
+                model->type == CURRENCY_REGISTER2 ||
+                model->type == PORTFOLIO_LEDGER2)
+        {
+            if (xaccAccountIsPriced (xfer_acc) ||
+                    !gnc_commodity_is_iso (xaccAccountGetCommodity (xfer_acc)))
+                is_amount = FALSE;
+            else
+                is_amount = TRUE;
+        }
+        else
+        {
+            is_amount = TRUE;
+        }
+
+        if (is_amount)
+        {
+            xaccSplitSetAmount (split, new_amount);
+            if (gnc_tree_util_split_reg_needs_amount (view, split))
+            {
+                value = gnc_numeric_div (new_amount, amtconv,
+                                        gnc_commodity_get_fraction (curr),
+                                        GNC_HOW_RND_ROUND_HALF_UP);
+                xaccSplitSetValue (split, value);
+            }
+            else
+                xaccSplitSetValue (split, new_amount);
+        }
+        else
+        {
+            xaccSplitSetValue (split, new_amount);
+        }
+        LEAVE(" ");
+        return;
+    }
+
+    /* How to interpret new_amount depends on our view of this
+     * transaction.  If we're sitting in an account with the same
+     * commodity as the transaction, then we can set the Value and then
+     * compute the amount.  Otherwise we are setting the "converted
+     * value".  This means we need to convert new_amount to the actual
+     * 'value' by dividing by the convrate in order to set the value.
+     */
+
+    /* Now compute/set the split value.  Amount is in the register
+     * currency but we need to convert to the txn currency.
+     */
+    if (gnc_tree_util_split_reg_needs_conv_rate (view, trans, acc))
+    {
+        /* convert the amount to the Value ... */
+        value = gnc_numeric_div (new_amount, amtconv,
+                                 gnc_commodity_get_fraction (curr),
+                                 GNC_HOW_RND_ROUND_HALF_UP);
+        xaccSplitSetValue (split, value);
+    }
+    else
+    {
+        xaccSplitSetValue (split, new_amount);
+    }
+
+    /* Now re-compute the Amount from the Value.  We may need to convert
+     * from the Value back to the amount here using the convrate from
+     * earlier.
+     */
+    value = xaccSplitGetValue (split);
+
+    if (gnc_tree_util_split_reg_needs_amount (view, split))
+    {
+        acc = xaccSplitGetAccount (split);
+        new_amount = gnc_numeric_mul (value, convrate,
+                                      xaccAccountGetCommoditySCU (acc),
+                                      GNC_HOW_RND_ROUND_HALF_UP);
+        xaccSplitSetAmount (split, new_amount);
+    }
+    else
+    {
+        xaccSplitSetAmount (split, value);
+    }
+    LEAVE(" ");
+}
+
+/*###########################################################################*/
+
+
+
+
+
+
+/*****************************************************************************/

Added: gnucash/trunk/src/gnome-utils/gnc-tree-util-split-reg.h
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-tree-util-split-reg.h	                        (rev 0)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-util-split-reg.h	2013-04-20 16:45:56 UTC (rev 22920)
@@ -0,0 +1,71 @@
+/********************************************************************\
+ * gnc-tree-util-split-reg.h -- GtkTreeView implementation          *
+ *                     to display registers   in a GtkTreeView.     *
+ *                                                                  *
+ * Copyright (C) 2006-2007 Chris Shoemaker <c.shoemaker at cox.net>    *
+ * Copyright (C) 2012 Robert Fewell                                 *
+ *                                                                  *
+ * 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:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+#ifndef __GNC_TREE_UTIL_SPLIT_REG_H
+#define __GNC_TREE_UTIL_SPLIT_REG_H
+
+#include "gnc-tree-model-split-reg.h"
+#include "gnc-tree-view-split-reg.h"
+
+G_BEGIN_DECLS
+
+
+/*****************************************************************************/
+
+gboolean gnc_tree_util_split_reg_has_rate (GncTreeViewSplitReg *view);
+
+gboolean gnc_tree_util_split_reg_needs_conv_rate (GncTreeViewSplitReg *view,
+                                    Transaction *trans, Account *acc);
+
+const char * gnc_tree_util_split_reg_get_transfer_entry (Split *split, gboolean *is_multi);
+
+gboolean gnc_tree_util_split_reg_is_multi (Split *split);
+
+gboolean gnc_tree_util_split_reg_needs_amount (GncTreeViewSplitReg *view, Split *split);
+
+
+void gnc_tree_util_split_reg_set_value_for (GncTreeViewSplitReg *view, Transaction *trans,
+                                            Split *split, gnc_numeric input, gboolean force);
+
+void gnc_tree_util_split_reg_save_amount_values (GncTreeViewSplitReg *view, Transaction *trans,
+                                                 Split *split, gnc_numeric input);
+
+gnc_numeric gnc_tree_util_split_reg_get_value_for (GncTreeViewSplitReg *view, Transaction *trans,
+                                                   Split *split, gboolean is_blank);
+
+gboolean gnc_tree_util_split_reg_get_debcred_entry (GncTreeViewSplitReg *view,
+                                                    Transaction *trans, Split *split,
+                                                    gboolean is_blank,gnc_numeric *ret_num,
+                                                    GNCPrintAmountInfo *ret_print_info);
+
+
+
+
+/*****************************************************************************/
+
+G_END_DECLS
+
+#endif /* __GNC_TREE_UTIL_SPLIT_REG_H */

Modified: gnucash/trunk/src/gnome-utils/gnc-tree-view-split-reg.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-tree-view-split-reg.c	2013-04-19 20:20:22 UTC (rev 22919)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-view-split-reg.c	2013-04-20 16:45:56 UTC (rev 22920)
@@ -36,6 +36,7 @@
 #include "gnc-tree-view-split-reg.h"
 #include "gnc-tree-model-split-reg.h"
 #include "gnc-tree-control-split-reg.h"
+#include "gnc-tree-util-split-reg.h"
 #include "gnc-ui.h"
 #include "dialog-utils.h"
 #include "gnc-gconf-utils.h"
@@ -43,7 +44,7 @@
 #include "engine-helpers.h"
 #include "Scrub.h"
 #include "gnc-exp-parser.h"
-#include "dialog-transfer.h"
+
 #include "gnc-amount-edit.h"
 
 
@@ -73,6 +74,8 @@
 
 static guint gnc_tree_view_split_reg_signals[LAST_SIGNAL] = {0};
 
+static void gnc_tree_view_split_reg_gconf_changed (GConfEntry *entry, gpointer user_data);
+
 static void cdf0 (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *s_model,
 				GtkTreeIter *s_iter, gpointer user_data);
 
@@ -115,7 +118,7 @@
 
 static void gtv_split_reg_motion_cb (GtkTreeSelection *sel, gpointer user_data);
 
-static void gtv_split_reg_refresh_cb (GncTreeModelSplitReg *model, gpointer user_data);
+static void gtv_split_reg_refresh_trans_cb (GncTreeModelSplitReg *model, gpointer item, gpointer user_data);
 
 static void gtv_split_reg_double_click_cb (GtkTreeView *treeview,
                                              GtkTreePath       *path,
@@ -164,8 +167,8 @@
      gtv_split_reg_edited_cb, gtv_get_editable_start_editing_cb,
      gnc_tree_control_split_reg_sort_by_dnm},
 
-    {COL_TRANSVOID, GNC_TREE_MODEL_SPLIT_REG_COL_TRANSVOID,
-     "Transfer / Void", "transvoid", "xxxxxxxxxxxxxxxxxxx",
+    {COL_TRANSFERVOID, GNC_TREE_MODEL_SPLIT_REG_COL_TRANSFERVOID,
+     "Transfer / Void", "transfervoid", "xxxxxxxxxxxxxxxxxxx",
      GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 1,
      gtv_split_reg_edited_cb, gtv_get_editable_start_editing_cb,
      gnc_tree_control_split_reg_sort_by_account},
@@ -257,12 +260,11 @@
     gboolean             double_line;         // Use double line mode
     gboolean             expanded;            // Are we expanded to splits
     gboolean             auto_complete;       // Whether auto complete has run
-
+    gboolean             negative_in_red;     // Display negative numbers in red
+    gboolean             use_horizontal_lines;// Draw horizontal lines
+    gboolean             use_vertical_lines;  // Draw vertical lines
 };
 
-
-#define SPLIT_TRANS_STR _("-- Split Transaction --")
-
 /* Define some cell colors */
 #define PINKCELL "#F8BEC6"
 #define REDCELL "#F34943"
@@ -318,7 +320,7 @@
 
 
 static void
-gnc_tree_view_split_reg_class_init(GncTreeViewSplitRegClass *klass)
+gnc_tree_view_split_reg_class_init (GncTreeViewSplitRegClass *klass)
 {
     GObjectClass *o_class;
 
@@ -329,7 +331,7 @@
     o_class->dispose =  gnc_tree_view_split_reg_dispose;
     o_class->finalize = gnc_tree_view_split_reg_finalize;
 
-    g_type_class_add_private(klass, sizeof(GncTreeViewSplitRegPrivate));
+    g_type_class_add_private (klass, sizeof(GncTreeViewSplitRegPrivate));
 
     gnc_tree_view_split_reg_signals[UPDATE_SIGNAL] =
         g_signal_new("update_signal",
@@ -449,7 +451,7 @@
 {
     GtkTreeModel *f_model, *s_model;
 
-    g_return_if_fail(GNC_IS_TREE_VIEW_SPLIT_REG(view));
+    g_return_if_fail (GNC_IS_TREE_VIEW_SPLIT_REG (view));
 
     s_model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
     f_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (s_model));
@@ -469,10 +471,24 @@
     view->reg_closing = FALSE;
     view->priv->fo_handler_id = 0;
     view->sort_depth = 1;
+    view->sort_direction = 1;
     view->priv->auto_complete = FALSE;
     view->priv->trans_confirm = RESET;
 
     view->priv->acct_short_names = gnc_gconf_get_bool (GCONF_GENERAL_REGISTER, "show_leaf_account_names", NULL);
+    view->priv->negative_in_red = gnc_gconf_get_bool (GCONF_GENERAL, KEY_NEGATIVE_IN_RED, NULL);
+    view->priv->use_horizontal_lines = gnc_gconf_get_bool (GCONF_GENERAL_REGISTER,
+                                  "draw_horizontal_lines", NULL);
+
+    view->priv->use_vertical_lines = gnc_gconf_get_bool (GCONF_GENERAL_REGISTER,
+                                "draw_vertical_lines", NULL);
+
+    gnc_gconf_general_register_cb ("draw_horizontal_lines",
+                                  gnc_tree_view_split_reg_gconf_changed,
+                                  view);
+    gnc_gconf_general_register_cb ("draw_vertical_lines",
+                                  gnc_tree_view_split_reg_gconf_changed,
+                                  view);
 }
 
 
@@ -529,7 +545,7 @@
 
 /* Update some settings from gconf */
 void
-gnc_tree_view_split_reg_refresh_from_gconf (GncTreeViewSplitReg *view) //FIXME Need to test and change.
+gnc_tree_view_split_reg_refresh_from_gconf (GncTreeViewSplitReg *view)
 {
     GncTreeModelSplitReg *model;
 
@@ -545,11 +561,47 @@
     model->alt_colors_by_txn = gnc_gconf_get_bool (GCONF_GENERAL_REGISTER,
                                "alternate_color_by_transaction", NULL);
 
-//    sheet->use_horizontal_lines = gnc_gconf_get_bool(GCONF_GENERAL_REGISTER,
-//                                  "draw_horizontal_lines", NULL);
+    view->priv->negative_in_red = gnc_gconf_get_bool (GCONF_GENERAL,
+                               KEY_NEGATIVE_IN_RED, NULL);
+}
 
-//    sheet->use_vertical_lines = gnc_gconf_get_bool(GCONF_GENERAL_REGISTER,
-//                                "draw_vertical_lines", NULL);
+
+static void
+gnc_tree_view_split_reg_gconf_changed (GConfEntry *entry, gpointer user_data)
+{
+    GncTreeViewSplitReg *view = user_data;
+
+    g_return_if_fail (entry && entry->key);
+
+    if (view == NULL)
+        return;
+
+//g_print("gnc_tree_view_split_reg_gconf_changed\n");
+
+    if (g_str_has_suffix (entry->key, "draw_horizontal_lines") || g_str_has_suffix (entry->key, "draw_vertical_lines"))
+    {
+        view->priv->use_horizontal_lines = gnc_gconf_get_bool (GCONF_GENERAL_REGISTER,
+                                  "draw_horizontal_lines", NULL);
+
+        view->priv->use_vertical_lines = gnc_gconf_get_bool (GCONF_GENERAL_REGISTER,
+                                "draw_vertical_lines", NULL);
+
+        if (view->priv->use_horizontal_lines)
+        {
+            if (view->priv->use_vertical_lines)
+                gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_BOTH);
+            else
+                gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_HORIZONTAL);
+        }
+        else if (view->priv->use_vertical_lines)
+            gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_VERTICAL);
+        else
+            gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_NONE);
+    }
+    else
+    {
+        g_warning("gnc_tree_view_split_reg_gconf_changed: Unknown gconf key %s", entry->key);
+    }
 }
 
 
@@ -585,7 +637,7 @@
     case INCOME_LEDGER2:
         {
         static ViewCol col_list[] = {
-        COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSVOID, COL_RECN,
+        COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSFERVOID, COL_RECN,
         COL_STATUS, COL_DEBIT, COL_CREDIT, COL_BALANCE, -1};
         return col_list;
         }
@@ -594,7 +646,7 @@
     case GENERAL_LEDGER2:
         {
         static ViewCol col_list[] = {
-        COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSVOID, COL_RECN,
+        COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSFERVOID, COL_RECN,
         COL_STATUS, COL_COMM, COL_VALUE, COL_RATE, COL_AMOUNT, COL_DEBIT, COL_CREDIT, -1};
         return col_list;
         }
@@ -604,7 +656,7 @@
     case CURRENCY_REGISTER2:
         {
         static ViewCol col_list[] = {
-        COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSVOID, COL_RECN,
+        COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSFERVOID, COL_RECN,
         COL_STATUS, COL_AMTVAL, COL_PRICE, COL_DEBIT, COL_CREDIT, COL_BALANCE, -1};
         return col_list;
         }
@@ -614,7 +666,7 @@
     case PAYABLE_REGISTER2:
         {
         static ViewCol col_list[] = {
-        COL_DATE, COL_TYPE, COL_DUEDATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSVOID,
+        COL_DATE, COL_TYPE, COL_DUEDATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSFERVOID,
         COL_STATUS, COL_DEBIT, COL_CREDIT, COL_BALANCE, -1};
         return col_list;
         }
@@ -622,7 +674,7 @@
      case PORTFOLIO_LEDGER2:
         {
         static ViewCol col_list[] = {
-        COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSVOID, COL_RECN,
+        COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSFERVOID, COL_RECN,
         COL_STATUS, COL_AMOUNT, COL_PRICE, COL_DEBIT, COL_CREDIT, -1};
         return col_list;
         }
@@ -630,7 +682,7 @@
     case SEARCH_LEDGER2:
         {
         static ViewCol col_list[] = {
-        COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSVOID, COL_RECN,
+        COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSFERVOID, COL_RECN,
         COL_STATUS, COL_RATE, COL_DEBIT, COL_CREDIT, -1};
         return col_list;
         }
@@ -639,7 +691,7 @@
     default:
         {
         static ViewCol col_list[] = {
-        COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSVOID, COL_RECN, COL_STATUS,
+        COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSFERVOID, COL_RECN, COL_STATUS,
         COL_VALUE, COL_AMOUNT, COL_RATE, COL_PRICE, COL_DEBIT, COL_CREDIT,
         COL_BALANCE, -1};
         return col_list;
@@ -678,7 +730,7 @@
             i++;
             continue;
         }
-        if (col_list[i] == COL_TRANSVOID) {
+        if (col_list[i] == COL_TRANSFERVOID) {
 
             col = gnc_tree_view_add_combo_column (
                 GNC_TREE_VIEW (view), def.title, def.pref_name, def.sizer,
@@ -789,7 +841,7 @@
     g_signal_connect (G_OBJECT (model), "selection_move_filter", G_CALLBACK (gtv_split_reg_selection_move_filter_cb), view);
 
     // This will refresh the view.
-    g_signal_connect (G_OBJECT (model), "refresh_view", G_CALLBACK (gtv_split_reg_refresh_cb), view);
+    g_signal_connect (G_OBJECT (model), "refresh_trans", G_CALLBACK (gtv_split_reg_refresh_trans_cb), view);
 
     // This is for key navigation, tabbing...
     g_signal_connect (G_OBJECT (view), "key-press-event", G_CALLBACK (gtv_split_reg_key_press_cb), NULL);
@@ -802,12 +854,11 @@
 
 
 /* Set up the view */
-static gboolean
+gboolean
 gnc_tree_view_split_reg_set_format (GncTreeViewSplitReg *view)
 {
     GncTreeViewSplitRegPrivate *priv;
     GncTreeModelSplitReg *model;
-    GtkTreeModel *f_model, *s_model;
     GtkTreePath *mpath, *spath;
     gint total_num = 0;
 
@@ -815,10 +866,6 @@
 
     model = gnc_tree_view_split_reg_get_model_from_view (view);
 
-
-    s_model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
-    f_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (s_model));
-
     priv = view->priv;
 
     total_num = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), NULL);
@@ -849,7 +896,7 @@
                     if (index != total_num -1)
                         gtk_tree_view_expand_row (GTK_TREE_VIEW (view), path, TRUE); // all rows a part from last
                     else if (indices[0] != total_num -1)
-                        gtk_tree_view_expand_to_path (GTK_TREE_VIEW (view), path); // selection not on balnk trans
+                        gtk_tree_view_expand_to_path (GTK_TREE_VIEW (view), path); // selection not on blank trans
                     else
                         gtk_tree_view_expand_row (GTK_TREE_VIEW (view), path, TRUE); // selection on blank trans
                 }
@@ -935,18 +982,69 @@
 }
 
 
+/* Set up the view for this transaction */
+static gboolean
+gnc_tree_view_split_reg_format_trans (GncTreeViewSplitReg *view, Transaction *trans)
+{
+    GncTreeViewSplitRegPrivate *priv;
+    GncTreeModelSplitReg *model;
+    GtkTreePath *mpath, *spath;
+
+    ENTER(" ");
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    priv = view->priv;
+
+    mpath = gnc_tree_model_split_reg_get_path_to_split_and_trans (model, NULL, trans);
+
+    spath = gnc_tree_view_split_reg_get_sort_path_from_model_path (view, mpath);
+
+    if ((!model->use_double_line) && (model->style != REG2_STYLE_JOURNAL))
+    {
+        gtk_tree_view_collapse_row (GTK_TREE_VIEW (view), spath);
+        LEAVE("single line transaction foramt");
+    }
+
+    if ((model->use_double_line) && (model->style != REG2_STYLE_JOURNAL))
+    {
+        gtk_tree_view_expand_to_path (GTK_TREE_VIEW (view), spath);
+        gtk_tree_path_down (spath);
+        gtk_tree_view_collapse_row (GTK_TREE_VIEW (view), spath);
+        gtk_tree_path_up (spath);
+        LEAVE("double line transaction format");
+    }
+
+    /* This expands to split from top level auto.. */
+    if ((model->style == REG2_STYLE_AUTO_LEDGER) || (model->style == REG2_STYLE_JOURNAL))
+    {
+        gtk_tree_view_expand_row (GTK_TREE_VIEW (view), spath, TRUE);
+        priv->expanded = TRUE;
+        LEAVE("auto expand line transaction format");
+    }
+
+    gtk_tree_path_free (mpath);
+    gtk_tree_path_free (spath);
+
+    /* This updates the plugin page gui */
+    if (view->moved_cb)
+        (view->moved_cb)(view, view->moved_cb_data);
+
+    return (FALSE);
+}
+
+
 /* Callback to update the view after transactions are added or deleted */
 static void
-gtv_split_reg_refresh_cb (GncTreeModelSplitReg *model, gpointer user_data)
+gtv_split_reg_refresh_trans_cb (GncTreeModelSplitReg *model, gpointer item, gpointer user_data)
 {
     GncTreeViewSplitReg *view = user_data;
+    Transaction *trans = item;
 
     /* Refilter the tree view register */
-    gnc_tree_view_split_reg_refilter (view);
+    gnc_tree_view_split_reg_refilter (view); //FIXME is this needed ???
 
-    if (view->reg_closing != TRUE)
-        /* Set the view format */
-        g_idle_add ((GSourceFunc)gnc_tree_view_split_reg_set_format, view);
+    gnc_tree_view_split_reg_format_trans (view, trans);
 }
 
 
@@ -997,14 +1095,14 @@
     gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), TRUE);
 
     /* TreeView Grid lines */
-    if (gnc_gconf_get_bool (GCONF_GENERAL_REGISTER, "draw_horizontal_lines", NULL))
+    if (view->priv->use_horizontal_lines)
     {
-        if (gnc_gconf_get_bool (GCONF_GENERAL_REGISTER, "draw_vertical_lines", NULL))
+        if (view->priv->use_vertical_lines)
             gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_BOTH);
         else
             gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_HORIZONTAL);
     }
-    else if (gnc_gconf_get_bool (GCONF_GENERAL_REGISTER, "draw_vertical_lines", NULL))
+    else if (view->priv->use_vertical_lines)
             gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_VERTICAL);
     else
         gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_NONE);
@@ -1091,6 +1189,7 @@
     LEAVE(" ");
 }
 
+/*###########################################################################*/
 
 /* Sets read only flag */
 void
@@ -1104,320 +1203,14 @@
 }
 
 
-/* Do we need an exchange rate */
-static gboolean
-needs_exchange_rate (GncTreeViewSplitReg *view, Transaction *trans, Split *split)
+/* Return the register commodity */
+gnc_commodity *
+gnc_tree_view_split_reg_get_reg_commodity (GncTreeViewSplitReg *view)
 {
-    gnc_commodity *split_com, *txn_curr, *reg_com;
-
-    ENTER("needs_exchange_rate - trans %p and split %p", trans, split);
-
-    txn_curr = xaccTransGetCurrency (trans);
-    split_com = xaccAccountGetCommodity (xaccSplitGetAccount (split));
-    if (split_com && txn_curr && !gnc_commodity_equiv (split_com, txn_curr))
-    {
-        LEAVE("needs_exchange_rate split_com to txn_curr return TRUE");
-        return TRUE;
-    }
-
-    reg_com = view->priv->reg_comm;
-    if (split_com && reg_com && !gnc_commodity_equiv (split_com, reg_com))
-    {
-        LEAVE("needs_exchange_rate split_com and reg_com return TRUE");
-        return TRUE;
-    }
-    LEAVE("No Exchange rate needed");
-    return FALSE;
+    return view->priv->reg_comm;
 }
 
 
-/* Get the rate from the price db */
-static gnc_numeric
-gtv_get_rate_from_db (gnc_commodity *from, gnc_commodity *to)
-{
-    GNCPrice *prc;
-    gnc_numeric rate_split;
-    gboolean have_rate = FALSE;
-    QofBook *book = gnc_get_current_book ();
-
-    /* Do we have a rate allready */
-    prc = gnc_pricedb_lookup_latest (gnc_pricedb_get_db (book), from, to);
-    if (prc)
-    {
-        rate_split = gnc_price_get_value (prc);
-        gnc_price_unref (prc);
-        have_rate = TRUE;
-    }
-
-    /* Lets try reversing the commodities */
-    if (!have_rate)
-    {
-        prc = gnc_pricedb_lookup_latest (gnc_pricedb_get_db (book), to, from);
-        if (prc)
-        {
-            rate_split = gnc_numeric_div (gnc_numeric_create (1, 1), gnc_price_get_value (prc),
-                                 GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
-
-            gnc_price_unref (prc);
-            have_rate = TRUE;
-        }
-    }
-
-    /* No rate, set to 1/1 */
-    if (!have_rate)
-        rate_split = gnc_numeric_create (1, 1);
-
-    return rate_split;
-}
-
-
-/* Either sets the value and amount for split and returns TRUE, or
-   does nothing and returns FALSE. */
-static gboolean
-handle_exchange_rate (GncTreeViewSplitReg *view, gnc_numeric amount, Transaction *trans, Split *split, gboolean force)
-{
-    XferDialog *xfer;
-    gboolean rate_split_ok, rate_reg_ok;
-    gnc_numeric rate_split, rate_reg, value;
-    Account *reg_acc = view->priv->anchor;
-    gnc_commodity *xfer_comm = xaccAccountGetCommodity (xaccSplitGetAccount (split));
-    gnc_commodity *reg_comm = view->priv->reg_comm;
-    gnc_commodity *trans_curr = xaccTransGetCurrency (trans);
-    gboolean expanded;
-    gboolean have_rate = TRUE;
-
-
-    ENTER("handle_exchange_rate amount %s, trans %p and split %p force %d", gnc_numeric_to_string (amount), trans, split, force);
-
-    /* Rate from trans-curr to split-comm */
-    rate_split_ok = xaccTransGetRateForCommodity (trans, xfer_comm, split, &rate_split);
-    DEBUG("rate_split_ok %d and xfer_comm %s", rate_split_ok, gnc_commodity_get_fullname (xfer_comm));
-
-    /* Rate from trans-curr to reg-comm */
-    rate_reg_ok = xaccTransGetRateForCommodity (trans, reg_comm, split, &rate_reg);
-    DEBUG("rate_reg_ok %d and reg_comm %s", rate_reg_ok, gnc_commodity_get_fullname (reg_comm));
-
-    /* Are we expanded */
-    expanded = view->priv->expanded;
-
-    if (gnc_commodity_equal (trans_curr, xfer_comm) && rate_split_ok)
-    {
-        xaccSplitSetAmount (split, amount);
-        xaccSplitSetValue (split, amount);
-        return TRUE;
-    }
-
-    if (rate_reg_ok && rate_split_ok && !force)
-    {
-        value = gnc_numeric_div (amount, rate_reg, gnc_commodity_get_fraction (trans_curr), GNC_HOW_DENOM_REDUCE);
-        amount = gnc_numeric_mul (value, rate_split, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND);
-    }
-    else
-    {
-        if (!rate_split_ok)
-            rate_split = gtv_get_rate_from_db (reg_comm, xfer_comm);
-
-        /* create the exchange-rate dialog */
-        xfer = gnc_xfer_dialog (NULL, NULL);
-
-        gnc_xfer_dialog_is_exchange_dialog (xfer, &rate_split);
-
-        /* fill in the dialog entries */
-        gnc_xfer_dialog_set_description (xfer, xaccTransGetDescription (trans));
-        gnc_xfer_dialog_set_memo (xfer, xaccSplitGetMemo (split));
-
-        /* Get per book option */
-        gnc_xfer_dialog_set_num (xfer, gnc_get_num_action (trans, split));
-        gnc_xfer_dialog_set_date (xfer, timespecToTime64 (xaccTransRetDatePostedTS (trans)));
-
-        value = amount;
-        if (gnc_xfer_dialog_run_exchange_dialog (xfer, &rate_split, value, reg_acc, trans, xfer_comm, expanded))
-        {
-            if (!rate_split_ok)
-                rate_split = gnc_numeric_create (1, 1);
-            have_rate = FALSE;
-        }
-        else
-            have_rate = TRUE;
-
-        amount = gnc_numeric_mul (value, rate_split, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND);
-    }
-    xaccSplitSetAmount (split, amount);
-    xaccSplitSetValue (split, value);
-
-    LEAVE("handle_exchange_rate set split %p amt=%s; and val=%s", split, gnc_numeric_to_string (amount), gnc_numeric_to_string (value));
-    return have_rate;
-}
-
-
-#define set_value_for gnc_tree_view_split_reg_set_value_for
-void
-gnc_tree_view_split_reg_set_value_for (GncTreeViewSplitReg *view, Transaction *trans, Split *split, gnc_numeric input, gboolean force)
-{
-    GtkWidget *window;
-    Account *anchor = view->priv->anchor;
-    Account *acct = xaccSplitGetAccount (split);
-    gnc_commodity *currency;
-    gnc_numeric value, amount, rate;
-
-    ENTER("set_value_for trans %p and split %p input %s force %d", trans, split, gnc_numeric_to_string (input), force);
-
-    currency = xaccTransGetCurrency (trans);
-
-    if (gnc_numeric_zero_p (input))
-    {
-        xaccSplitSetValue (split, input);
-        xaccSplitSetAmount (split, input);
-        LEAVE("input is zero");
-        return;
-    }
-
-    window = gnc_tree_view_split_reg_get_parent (view);
-
-    if (needs_exchange_rate (view, trans, split))
-    {
-        if (handle_exchange_rate (view, input, trans, split, force))
-        {
-            ; //FIXME ??????
-        }
-        else
-        {
-            gnc_error_dialog (window, "%s",
-                         _("Exchange Rate Canceled, using existing rate or default 1 to 1 rate if this is a new transaction."));
-        }
-        LEAVE("used exchange rate");
-        return;
-    }
-
-    /* Context determines the interpretation of the input.  If the
-       treeview is anchored to an account then the input is
-       interpreted as being in the Account's commodity.  Otherwise,
-       it's interpreted as being in the Transaction's currency. */
-    if (anchor)
-    {
-        gnc_commodity *reg_com = view->priv->reg_comm;
-        gnc_commodity *split_com = xaccAccountGetCommodity (acct);
-
-        /* Convert from the anchor account's commodity to trans currency */
-        if (gnc_commodity_equiv (currency, reg_com))
-            value = input;
-        else 
-        {
-            if (!xaccTransGetRateForCommodity (trans, reg_com, NULL, &rate))
-            {
-                LEAVE("");
-                return;
-            }
-
-            if (gnc_numeric_zero_p (rate))
-            {
-                xaccTransSetCurrency (trans, reg_com);
-                value = input;
-            }
-            else
-            {
-                value = gnc_numeric_div (
-                    input, rate,
-                    GNC_DENOM_AUTO, //?
-                    //gnc_commodity_get_fraction(currency),
-                    GNC_HOW_RND_ROUND);
-            }
-        }
-        xaccSplitSetValue (split, value);
-
-        if (gnc_commodity_equiv (split_com, reg_com))
-        {
-            amount = input;
-        }
-        else
-        {
-            rate = xaccTransGetAccountConvRate (trans, acct);
-            amount = gnc_numeric_mul (value, rate, xaccAccountGetCommoditySCU (acct), GNC_HOW_RND_ROUND);
-        }
-        xaccSplitSetAmount (split, amount);
-    }
-    else
-    {
-        value = input;
-        xaccSplitSetValue (split, value);
-
-        rate = xaccTransGetAccountConvRate (trans, acct);
-        amount = gnc_numeric_mul (value, rate, xaccAccountGetCommoditySCU (acct), GNC_HOW_RND_ROUND);
-        if (gnc_numeric_check (amount) == GNC_ERROR_OK)
-        {
-            xaccSplitSetAmount (split, amount);
-        }
-    }
-    LEAVE(" ");
-}
-
-
-/* Returns a value for display. */
-static gnc_numeric
-get_value_for (GncTreeViewSplitReg *view, Transaction *trans, Split *split, gboolean is_blank)
-{
-    gnc_commodity *currency = xaccTransGetCurrency (trans);
-    gnc_numeric total;
-
-    ENTER("get_value_for trans %p and split %p is_blank %d", trans, split, is_blank);
-
-    total = xaccSplitGetValue (split);
-
-    if (is_blank && gnc_numeric_zero_p (total)) //blank split and total zero
-    {
-        gnc_numeric rate;
-        total = gnc_numeric_neg (xaccTransGetImbalanceValue (trans));
-        if (!gnc_numeric_zero_p (total))
-        {
-            if (!xaccTransGetRateForCommodity (trans, view->priv->reg_comm, NULL, &rate))
-            {
-                LEAVE("zero");
-                return gnc_numeric_zero();
-            }
-
-            total = gnc_numeric_mul (
-                total, rate,
-                gnc_commodity_get_fraction (currency),
-                GNC_HOW_RND_ROUND);
-        }
-    }
-    else
-    {
-        if (!gnc_numeric_zero_p (total) && gnc_numeric_check (total) == GNC_ERROR_OK)
-        {
-            /* if needs conversion? */
-            gnc_commodity *commodity = view->priv->reg_comm;
-            if (commodity && gnc_commodity_is_currency (view->priv->reg_comm)) //test for a currency register
-            {
-                if (!gnc_commodity_equiv (commodity, currency))
-                {
-                    total = xaccSplitConvertAmount (split, view->priv->anchor);
-                }
-            }
-        }
-    }
-    LEAVE("return value is %s", gnc_numeric_to_string (total));
-    return total;
-}
-
-
-/* Returns the other Split based on the current Account */
-/* Only used with two split transactions */
-static Split *
-get_other_split (GncTreeViewSplitReg *view, Transaction *trans)
-{
-    int i;
-    Split *split = NULL;
-    Account *anchor = view->priv->anchor;
-
-    for (i = 0; (split = xaccTransGetSplit(trans, i)); i++) {
-        if (anchor == xaccSplitGetAccount(split))
-            return xaccSplitGetOtherSplit(split);
-    }
-    return NULL;
-}
-
-
 /* Returns a Split that matches the current Account */
 static Split *
 get_this_split (GncTreeViewSplitReg *view, Transaction *trans)
@@ -1425,10 +1218,12 @@
     GncTreeModelSplitReg *model;
     int i;
     Split *split = NULL;
-    Account *anchor = view->priv->anchor;
+    Account *anchor;
 
     model = gnc_tree_view_split_reg_get_model_from_view (view);
 
+    anchor = gnc_tree_model_split_reg_get_anchor (model);
+
     if (xaccTransCountSplits (trans) == 0)
         return gnc_tree_model_split_get_blank_split (model);
 
@@ -1499,9 +1294,6 @@
 
     ENTER("set_number_for_input trans %p and split %p and input is %s and viewcol is %d", trans, split, gnc_numeric_to_string (input), viewcol);
 
-
-//FIXME ## Trading ## Copied from split-register, needs testing
-
     model = gnc_tree_view_split_reg_get_model_from_view (view);
 
     account = gnc_tree_model_split_reg_get_anchor (model);
@@ -1521,7 +1313,6 @@
         if (!(xaccAccountIsPriced (account) || !gnc_commodity_is_iso (acc_commodity)))
             return;
     }
-//FIXME
 
     if (gnc_numeric_zero_p (input))
     {
@@ -1742,12 +1533,12 @@
     }
 
     /* If the number of splits is two, change other split to balance */
-    if ((xaccTransCountSplits (trans) == 2) && view->priv->expanded)
+    if (!gnc_tree_util_split_reg_is_multi (split) && view->priv->expanded)
     {
         Split *osplit;
         gnc_commodity *osplit_com;
 
-        osplit = get_other_split (view, trans);
+        osplit = xaccSplitGetOtherSplit (split);
 
         value = xaccSplitGetValue (split);
 
@@ -1755,16 +1546,8 @@
 
         if (gnc_commodity_is_currency (osplit_com))
         {
-            if (!gnc_numeric_negative_p (value))
-            {
-                xaccSplitSetValue (osplit, gnc_numeric_neg (value));
-                xaccSplitSetAmount (osplit, gnc_numeric_neg (value));
-            }
-            else
-            {
-                xaccSplitSetValue (osplit, value);
-                xaccSplitSetAmount (osplit, value);
-            }
+            xaccSplitSetValue (osplit, gnc_numeric_neg (value));
+            xaccSplitSetAmount (osplit, gnc_numeric_neg (value));
         }
     }
     LEAVE("");
@@ -1797,7 +1580,7 @@
 
     split_rate = gnc_numeric_div (value, amount, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT);
     if (gnc_numeric_check (split_rate) != GNC_ERROR_OK)
-        split_rate = gnc_numeric_create (1,1);
+        split_rate = gnc_numeric_create (100,100);
 
     new_value = gnc_numeric_mul (input, split_rate, denom, GNC_HOW_RND_ROUND_HALF_UP);
 
@@ -1816,9 +1599,14 @@
 
     ENTER("get_rate_for trans %p and split %p is_blank %d", trans, split, is_blank);
 
-    num = get_value_for (view, trans, split, is_blank);
-    num = gnc_numeric_div ( xaccSplitGetAmount (split), num, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND);
-    LEAVE("get_rate_for split amount is %s and return num is %s", gnc_numeric_to_string (xaccSplitGetAmount (split)), gnc_numeric_to_string (num));
+    num = gnc_tree_util_split_reg_get_value_for (view, trans, split, is_blank);
+//FIXME Not sure about this...
+    if (xaccTransUseTradingAccounts (trans))
+        num = gnc_numeric_div (num, xaccSplitGetValue (split), GNC_DENOM_AUTO, GNC_HOW_RND_ROUND);
+    else
+        num = gnc_numeric_div (xaccSplitGetAmount (split), num, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND);
+
+    LEAVE("get_rate_for split %p and return num is %s", split, gnc_numeric_to_string (num));
     return num;
 }
 
@@ -1845,26 +1633,30 @@
         *osplit = xaccMallocSplit (book);
         xaccSplitSetParent (*osplit, trans);
     }
-    else if (count == 2)
+    else
     {
         int i;
-        Split *s;
+        Split *s, *first_split;
 
-        for (i = 0; (s = xaccTransGetSplit (trans, i)); i++)
+        first_split = xaccTransGetSplit (trans, 0);
+
+        if (gnc_tree_util_split_reg_is_multi (first_split)) // multi trans
+            return FALSE;
+        else // two split trans
         {
-            if (anchor == xaccSplitGetAccount (s))
+            for (i = 0; (s = xaccTransGetSplit (trans, i)); i++)
             {
-                *split = s;
-                break;
+                if (anchor == xaccSplitGetAccount (s))
+                {
+                    *split = s;
+                    break;
+                }
             }
+            g_assert (*split);
+            *osplit = xaccSplitGetOtherSplit(*split);
+            g_assert (*osplit);
         }
-        //*split = get_this_split (view, trans);
-        g_assert (*split);
-        *osplit = get_other_split (view, trans);
-        g_assert (*osplit);
     }
-    else
-        return FALSE;
     DEBUG("get_split_pair return - trans is %p, osplit is %p and split %p is set to anchor %p", trans, *osplit, *split, anchor);
     return TRUE;
 }
@@ -1901,21 +1693,27 @@
 
     DEBUG("have_account trans %p, split %p, expanded %d, depth %d", trans, split, expanded, depth);
 
-    if ((depth == TRANS1) && !expanded && (xaccTransCountSplits (trans) == 2)) // normal trans
+    if ((depth == TRANS1) && !expanded && !gnc_tree_util_split_reg_is_multi (split)) // normal trans
     {
-        if (xaccSplitGetAccount (get_other_split (view, trans)) != NULL)
+        if (xaccSplitGetAccount (xaccSplitGetOtherSplit (split)) != NULL)
             have_account = TRUE;
     }
 
     if ((depth == SPLIT3) && (xaccTransCountSplits (trans) == 0)) // blank trans, blank split
         have_account = TRUE;
 
-    if (depth == SPLIT3) // normal split
+    if (depth == SPLIT3)
     {
-        if (xaccSplitGetAccount (split) != NULL)
-            have_account = TRUE;
+        Account *acc;
+        acc = xaccSplitGetAccount (split);
+        if (acc != NULL)
+        {
+            if (xaccAccountGetType (acc) != ACCT_TYPE_TRADING)
+                have_account = TRUE; // normal split
+            else
+                have_account = FALSE; // trading split
+        }
     }
-
     return have_account;
 }
 
@@ -1988,7 +1786,6 @@
     gboolean editable = FALSE, expanded = FALSE;
     gboolean read_only = FALSE;
     gboolean open_edited = FALSE;
-    gint num_of_splits = 0;
     gnc_numeric num;
     const gchar *s = "";
     const gchar *row_color;
@@ -2041,10 +1838,9 @@
         open_edited = TRUE;
     }
 
-    /* Lets see if the splits are expanded and count them */
+    /* Lets see if the splits are expanded */
     if (is_trow1 || is_trow2)
     {
-        num_of_splits = xaccTransCountSplits (trans);
         path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &m_iter);
         if (is_trow1)
             gtk_tree_path_down (path); /* Move the path down to trow2 */
@@ -2052,10 +1848,7 @@
         gtk_tree_path_free (path);
     }
     else
-    {
-        num_of_splits = xaccTransCountSplits (trans);
         expanded = TRUE;
-    }
 
     switch (viewcol) {
     case COL_DATE:
@@ -2189,7 +1982,7 @@
         g_object_set (cell, "text", s, "editable", editable, NULL);
         break;
 
-    case COL_TRANSVOID:
+    case COL_TRANSFERVOID:
         /* Column is TRANSFER / VOID */
         /* Not sure if this will stay here, this sets the combo column
            0 for short account names, 1 for long */
@@ -2201,28 +1994,17 @@
         if (is_trow1)
         {
             if (expanded)
-                s = ""; /* blank-out if splits are visible */
-            else if (num_of_splits == 2)
             {
-                Account *acct;
-                Split *osplit;
-                osplit = get_other_split (view, trans);
-                acct = xaccSplitGetAccount (osplit);
-                if (view->priv->acct_short_names)
-                    s = xaccAccountGetName (acct);
-                else
-                    s = gnc_account_get_full_name (acct);
+                s = ""; /* blank-out if splits are visible */
+                editable = FALSE;
             }
-            else if (num_of_splits == 0)
+            else
             {
-                s = "";
+                gboolean is_multi;
+                s = gnc_tree_util_split_reg_get_transfer_entry (get_this_split (view, trans), &is_multi);
+
+                editable = anchor && !expanded && !is_multi;
             }
-                    
-            if (num_of_splits > 2)
-            {
-                s = SPLIT_TRANS_STR;
-            }
-            editable = anchor && !expanded && (num_of_splits < 3);
         }
         if (is_trow2)
         {
@@ -2329,8 +2111,8 @@
         /* Column is VALUE */
         if (is_split)
         {
-            gnc_numeric val = xaccSplitGetValue (split);
-            s = xaccPrintAmount (val, gnc_commodity_print_info (xaccTransGetCurrency (trans), SHOW_SYMBOL));
+            num = xaccSplitGetValue (split);
+            s = xaccPrintAmount (num, gnc_commodity_print_info (xaccTransGetCurrency (trans), SHOW_SYMBOL));
             editable = FALSE;
 
             if (get_imbalance (trans))
@@ -2344,6 +2126,12 @@
 
         editable = (read_only == TRUE) ? FALSE : editable;
 
+        // Display negative numbers in red by gconf
+        if (gnc_numeric_negative_p (num) && view->priv->negative_in_red)
+            g_object_set (cell, "foreground", "red", (gchar*)NULL);
+        else
+            g_object_set (cell, "foreground", NULL, (gchar*)NULL);
+
         g_object_set (cell, "text", s, "editable", editable, NULL);
         break;
 
@@ -2356,20 +2144,22 @@
         }
         else
         {
+            GNCPrintAmountInfo print_info;
+
             gnc_commodity *split_com = xaccAccountGetCommodity (xaccSplitGetAccount (split));
-            num = get_rate_for (view, trans, split, is_blank);
+
+            print_info = gnc_default_price_print_info();
+            print_info.min_decimal_places = 2;
+
+            num = gnc_numeric_convert (get_rate_for (view, trans, split, is_blank), 1000000, GNC_HOW_RND_ROUND_HALF_UP);
+
             if (gnc_numeric_check (num) == GNC_ERROR_OK)
-            {
-                s = xaccPrintAmount (num, gnc_split_amount_print_info (split, SHOW_SYMBOL));
-                editable = !gnc_numeric_zero_p (num) && gnc_commodity_equiv (split_com, view->priv->reg_comm);
-                editable = FALSE;
-            }
+                s = xaccPrintAmount (num, print_info);
             else
-            {
                 s = "";
-                editable = FALSE;
-            }
 
+            editable = FALSE;
+
             if (get_imbalance (trans))
                 g_object_set (cell, "cell-background", PINKCELL, (gchar*)NULL);
         }
@@ -2383,8 +2173,8 @@
         /* Column is AMOUNT */
         if (is_split && (anchor == NULL))
         {
-            gnc_numeric amt = xaccSplitGetAmount (split);
-            s = xaccPrintAmount (amt, gnc_account_print_info (xaccSplitGetAccount (split), SHOW_SYMBOL));
+            num = xaccSplitGetAmount (split);
+            s = xaccPrintAmount (num, gnc_account_print_info (xaccSplitGetAccount (split), SHOW_SYMBOL));
             editable = FALSE;
 
             if (get_imbalance (trans))
@@ -2397,8 +2187,8 @@
 
             if (!gnc_commodity_is_currency (split_comm) || (is_blank))
             {
-                gnc_numeric amt = xaccSplitGetAmount (split);
-                s = xaccPrintAmount (amt, gnc_account_print_info (xaccSplitGetAccount (split), SHOW_SYMBOL));
+                num = xaccSplitGetAmount (split);
+                s = xaccPrintAmount (num, gnc_account_print_info (xaccSplitGetAccount (split), SHOW_SYMBOL));
                 editable = FALSE;
             }
 
@@ -2413,6 +2203,12 @@
 
         editable = (read_only == TRUE) ? FALSE : editable;
 
+        // Display negative numbers in red by gconf
+        if (gnc_numeric_negative_p (num) && view->priv->negative_in_red)
+            g_object_set (cell, "foreground", "red", (gchar*)NULL);
+        else
+            g_object_set (cell, "foreground", NULL, (gchar*)NULL);
+
         g_object_set (cell, "text", s, "editable", editable, NULL);
         break;
 
@@ -2423,16 +2219,22 @@
             s = "";
             editable = FALSE;
         }
-        else if (is_trow1)
+        else if (is_trow1) // Value
         {
             if (anchor)
             {
-                gnc_numeric val = xaccSplitGetValue (get_this_split (view, trans));
-                editable = !expanded && (num_of_splits < 3);
+                Split *this_split;
+
+                this_split = get_this_split (view, trans);
+
+                num = xaccTransGetAccountValue (trans, anchor);
+
+                editable = !expanded && !gnc_tree_util_split_reg_is_multi (this_split);
+
                 if (expanded)
                     s = "";
                 else
-                    s = xaccPrintAmount (val, gnc_commodity_print_info (xaccTransGetCurrency (trans), SHOW_SYMBOL));
+                    s = xaccPrintAmount (num, gnc_commodity_print_info (xaccTransGetCurrency (trans), SHOW_SYMBOL));
             }
             else
             {
@@ -2441,12 +2243,12 @@
             }
         }
 
-        if (is_split)
+        if (is_split) // Amount
         {
             if (anchor == NULL)
             {
-                gnc_numeric amt = xaccSplitGetAmount (split);
-                s = xaccPrintAmount (amt, gnc_account_print_info (xaccSplitGetAccount (split), SHOW_SYMBOL));
+                num = xaccSplitGetAmount (split);
+                s = xaccPrintAmount (num, gnc_account_print_info (xaccSplitGetAccount (split), SHOW_SYMBOL));
                 editable = TRUE;
             }
             else if (anchor)
@@ -2456,8 +2258,8 @@
 
                 if (!gnc_commodity_is_currency (split_comm) || (is_blank))
                 {
-                    gnc_numeric amt = xaccSplitGetAmount (split);
-                    s = xaccPrintAmount (amt, gnc_account_print_info (xaccSplitGetAccount (split), SHOW_SYMBOL));
+                    num = xaccSplitGetAmount (split);
+                    s = xaccPrintAmount (num, gnc_account_print_info (xaccSplitGetAccount (split), SHOW_SYMBOL));
                     editable = TRUE;
                 }
             }
@@ -2476,6 +2278,12 @@
 
         editable = (read_only == TRUE) ? FALSE : editable;
 
+        // Display negative numbers in red by gconf
+        if (gnc_numeric_negative_p (num) && view->priv->negative_in_red)
+            g_object_set (cell, "foreground", "red", (gchar*)NULL);
+        else
+            g_object_set (cell, "foreground", NULL, (gchar*)NULL);
+
         g_object_set (cell, "text", s, "editable", editable, NULL);
         break;
 
@@ -2490,8 +2298,17 @@
         {
             if (anchor)
             {
-                num = xaccSplitGetSharePrice (get_this_split (view, trans));
-                editable = !expanded && (num_of_splits < 3);
+                Split *this_split;
+
+                this_split = get_this_split (view, trans);
+
+                if (gnc_tree_util_split_reg_is_multi (this_split))
+                    num = gnc_numeric_zero();
+                else
+                    num = xaccSplitGetSharePrice (this_split);
+
+                editable = !expanded && !gnc_tree_util_split_reg_is_multi (this_split);
+
                 if (expanded)
                     s = "";
                 else 
@@ -2555,48 +2372,53 @@
     case COL_DEBIT:
     case COL_CREDIT:
         /* Column is CREDIT and DEBIT */
-        if (is_split)
         {
-            num = get_value_for (view, trans, split, is_blank);
-            editable = TRUE;
-            if (get_imbalance (trans))
-                g_object_set (cell, "cell-background", PINKCELL, (gchar*)NULL);
-        }
-        else if (is_trow1)
-        {
-            if (anchor)
+            GNCPrintAmountInfo print_info;
+            print_info = gnc_account_print_info (anchor, SHOW_SYMBOL);
+
+            if (is_split)
             {
-                editable = !expanded && (num_of_splits < 3 );
-                num = xaccTransGetAccountAmount (trans, anchor);
+                if (!gnc_tree_util_split_reg_get_debcred_entry (view, trans, split, is_blank, &num, &print_info))
+                    num = gnc_numeric_zero();
+
+                editable = TRUE;
+                if (get_imbalance (trans))
+                    g_object_set (cell, "cell-background", PINKCELL, (gchar*)NULL);
             }
-            else
+            else if (is_trow1)
             {
+                if (anchor)
+                {
+                    editable = !expanded && !gnc_tree_util_split_reg_is_multi (get_this_split (view, trans));
+                    num = xaccTransGetAccountAmount (trans, anchor);
+                }
+                else
+                {
+                    editable = FALSE;
+                    num = gnc_numeric_zero();
+                }
+            }
+            else if (is_trow2)
+            {
                 editable = FALSE;
                 num = gnc_numeric_zero();
             }
-        }
-        else if (is_trow2)
-        {
-            editable = FALSE;
-            num = gnc_numeric_zero();
-        }
 
-        if ((gnc_numeric_check(num) != GNC_ERROR_OK) ||
-             gnc_numeric_zero_p(num) ||
-            (gnc_numeric_negative_p(num) && viewcol == COL_DEBIT) ||
-            (gnc_numeric_positive_p(num) && viewcol == COL_CREDIT))
-        {
-            s = "";
-        }
-        else
-        {
-            if ((is_trow1 || is_trow2) && expanded)
+            if ((gnc_numeric_check(num) != GNC_ERROR_OK) ||
+                 gnc_numeric_zero_p(num) ||
+                (gnc_numeric_negative_p(num) && viewcol == COL_DEBIT) ||
+                (gnc_numeric_positive_p(num) && viewcol == COL_CREDIT))
+            {
                 s = "";
+            }
             else
-                s = xaccPrintAmount (gnc_numeric_abs (num),
-                                gnc_account_print_info (anchor, SHOW_SYMBOL));
+            {
+                if ((is_trow1 || is_trow2) && expanded)
+                    s = "";
+                else
+                    s = xaccPrintAmount (gnc_numeric_abs (num), print_info);
+            }
         }
-
         /* Only allow changes to entries if we have a valid split accounts */
         editable = have_account (view, depth, expanded, trans, split);
 
@@ -2615,8 +2437,9 @@
             if (gnc_reverse_balance (anchor))
                 num = gnc_numeric_neg (num);
             s = xaccPrintAmount (num, gnc_account_print_info(anchor, FALSE));
-            if (gnc_numeric_negative_p (num)
-                && gnc_gconf_get_bool (GCONF_GENERAL, KEY_NEGATIVE_IN_RED, NULL))
+
+            // Display negative numbers in red by gconf
+            if (gnc_numeric_negative_p (num) && view->priv->negative_in_red)
                 g_object_set (cell, "foreground", "red", (gchar*)NULL);
             else
                 g_object_set (cell, "foreground", NULL, (gchar*)NULL);
@@ -2683,7 +2506,6 @@
     gboolean editable = FALSE, expanded = FALSE;
     gboolean read_only = FALSE;
     gboolean open_edited = FALSE;
-    gint num_of_splits = 0;
     gnc_numeric num;
     const gchar *s = "";
     const gchar *row_color;
@@ -2736,10 +2558,9 @@
         open_edited = TRUE;
     }
 
-    /* Lets see if the splits are expanded and count them */
+    /* Lets see if the splits are expanded */
     if (is_trow1 || is_trow2)
     {
-        num_of_splits = xaccTransCountSplits (trans);
         path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &m_iter);
         if (is_trow1)
             gtk_tree_path_down (path); /* Move the path down to trow2 */
@@ -2747,10 +2568,7 @@
         gtk_tree_path_free (path);
     }
     else
-    {
-        num_of_splits = xaccTransCountSplits (trans);
         expanded = TRUE;
-    }
 
     switch (viewcol) {
     case COL_DATE:
@@ -2812,7 +2630,7 @@
         /* Column is DESCRIPTION / NOTES */
         break;
 
-    case COL_TRANSVOID:
+    case COL_TRANSFERVOID:
         /* Column is TRANSFER / VOID */
         break;
 
@@ -2919,18 +2737,6 @@
         xaccTransBeginEdit (trans);
         view->priv->dirty_trans = trans;
 
-        if (!xaccTransGetCurrency (trans))
-        {
-            if (gnc_commodity_is_currency (view->priv->reg_comm))
-            {
-                xaccTransSetCurrency (trans, view->priv->reg_comm);
-            }
-            else
-            {
-                xaccTransSetCurrency (trans, gnc_default_currency());
-            }
-        }
-
         if (ts.tv_sec == 0)
         {
             //If the time returned by xaccTransGetDatePostedTS is 0 then assume it
@@ -3137,12 +2943,25 @@
     if (!view->priv->dirty_trans || view->priv->dirty_trans == new_trans)
         return FALSE;
 
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    // If using trading accounts, lets scrub them to make them work.
+    if (xaccTransUseTradingAccounts (view->priv->dirty_trans))
+    {
+        Account *default_account = gnc_tree_model_split_reg_get_anchor (model);
+        if (default_account != NULL)
+            xaccTransScrubImbalance (view->priv->dirty_trans, gnc_account_get_root(default_account), NULL);
+        else
+        {
+            Account *root = gnc_book_get_root_account (gnc_get_current_book());
+            xaccTransScrubImbalance (view->priv->dirty_trans, root, NULL);
+        }
+    }
+
     // Test if the transaction is balanced.
     if (gnc_tree_control_split_reg_balance_trans (view, view->priv->dirty_trans))
         return TRUE;
 
-    model = gnc_tree_view_split_reg_get_model_from_view (view);
-
     window = gnc_tree_view_split_reg_get_parent (view);
     dialog = gtk_message_dialog_new (GTK_WINDOW (window),
                                     GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -3177,8 +2996,7 @@
         if (view->priv->dirty_trans && xaccTransIsOpen (view->priv->dirty_trans))
         {
             // Move selection to trans - selection is blocked
-            if (new_trans == NULL) // This is NULL for keyboard and enter...
-                gnc_tree_control_split_reg_goto_rel_trans_row (view, 0);
+            gnc_tree_control_split_reg_goto_rel_trans_row (view, 0);
 
             g_object_set_data (G_OBJECT (view), "data-edited", GINT_TO_POINTER (FALSE));
             xaccTransRollbackEdit (view->priv->dirty_trans);
@@ -3404,7 +3222,7 @@
             }
             break;
 
-        case COL_TRANSVOID:
+        case COL_TRANSFERVOID:
             switch (model->type)
             {
             case RECEIVABLE_REGISTER2:
@@ -3789,7 +3607,7 @@
         }
         break;
 
-    case COL_TRANSVOID:
+    case COL_TRANSFERVOID:
         switch(model->type)
         {
         default:
@@ -4272,6 +4090,14 @@
                         gnc_tree_view_split_reg_collapse_trans (view, view->priv->dirty_trans);
 
                     gnc_tree_view_split_reg_block_selection (view, FALSE);
+
+                    /* Remove the blank split and re-add - done so we keep it last in list */
+                    gnc_tree_model_split_reg_set_blank_split_parent (model, view->priv->dirty_trans, TRUE);
+                    gnc_tree_model_split_reg_set_blank_split_parent (model, view->priv->dirty_trans, FALSE);
+
+                    // Set the transaction to show correct view
+                    gnc_tree_view_split_reg_format_trans (view, view->priv->dirty_trans);
+
                     view->priv->dirty_trans = NULL;
                 }
             }
@@ -4306,14 +4132,15 @@
     RowDepth depth = 0;
     GtkTreeIter m_iter;
 
-//g_print ("\n** gtv_split_reg_motion_cb start\n");
-
     model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    ENTER("View is %p and Model is %p", view, model);
+
     s_model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
     f_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (s_model));
 
-//g_print("Motion - ** model is %p and view is %p dirty_trans is %p **\n", model, view, view->priv->dirty_trans);
-//g_print("Motion - ** o_trans is %p o_split is %p o_depth %d **\n", view->priv->current_trans, view->priv->current_split, view->priv->current_depth);
+    DEBUG("Current trans %p, Split %p, Depth %d and Dirty Trans %p", view->priv->current_trans, view->priv->current_split,
+                                                                     view->priv->current_depth, view->priv->dirty_trans);
 
     /* Reset help text */
     view->help_text = " ";
@@ -4324,20 +4151,10 @@
         mpath = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &m_iter);
         spath = gnc_tree_view_split_reg_get_sort_path_from_model_path (view, mpath);
 
-//g_print ("Motion - mpath is %s spath is %s\n\n", gtk_tree_path_to_string (mpath), gtk_tree_path_to_string (spath));
+        DEBUG("Valid Selection - mpath is %s,  spath is %s", gtk_tree_path_to_string (mpath), gtk_tree_path_to_string (spath));
 
-//g_print("Motion - current_ref is valid %d\n", gtk_tree_row_reference_valid (view->priv->current_ref));
-
-//if (gtk_tree_row_reference_valid (view->priv->current_ref))
-//    g_print("Motion - Old Current Path is '%s'\n", gtk_tree_path_to_string (gtk_tree_row_reference_get_path (view->priv->current_ref)));
-
         /* save the current path */
-        if(view->priv->current_ref != NULL)
-        {
-            gtk_tree_row_reference_free (view->priv->current_ref);
-            view->priv->current_ref = NULL;
-        }
-        view->priv->current_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (model), mpath);
+        gnc_tree_view_split_reg_set_current_path (view, mpath);
 
         /* Use depth to determine if it is a split or transaction */
         depth = gtk_tree_path_get_depth (mpath);
@@ -4347,13 +4164,10 @@
 
         gtk_tree_path_free (mpath);
 
-//if (gtk_tree_row_reference_valid (view->priv->current_ref))
-//    g_print("Motion - Current Path is '%s'\n", gtk_tree_path_to_string (gtk_tree_row_reference_get_path (view->priv->current_ref)));
-
         gnc_tree_model_split_reg_get_split_and_trans (
                 GNC_TREE_MODEL_SPLIT_REG (model), &m_iter, &is_trow1, &is_trow2, &is_split, &is_blank, &split, &trans);
 
-//g_print("## Motion - get model split %p, trans %p, is_split %d, is_blank %d\n", split, trans, is_split, is_blank);
+        DEBUG("Get model trans %p, split %p, is_split %d, is_blank %d\n", trans, split, is_split, is_blank);
 
         /* Move the blank split */ 
         gnc_tree_model_split_reg_set_blank_split_parent (model, trans, FALSE);
@@ -4364,8 +4178,8 @@
         view->priv->current_split = split;
         view->priv->current_depth = depth;
 
-//g_print("Motion - ** view->priv-> c_trans is %p c_split is %p depth %d, old_trans is %p **\n\n", view->priv->current_trans,
-//             view->priv->current_split, view->priv->current_depth, old_trans);
+        DEBUG("Current trans %p, split %p, depth %d and old_trans %p", view->priv->current_trans, view->priv->current_split,
+                                                                     view->priv->current_depth, old_trans);
 
         /* Auto expand transaction and collapse previous transaction */
         if (old_trans != trans)
@@ -4405,7 +4219,7 @@
     }
     else
     {
-//g_print("Not valid selection\n");
+        DEBUG("Not Valid Selection");
         /* We do not have a valid iter */
         gtv_split_reg_titles (view, 0);
 
@@ -4415,9 +4229,12 @@
         /* Set the default selection start position */
         gnc_tree_view_split_reg_default_selection (view);
     }
+
     /* This updates the plugin page gui */
     if (view->moved_cb)
         (view->moved_cb)(view, view->moved_cb_data);
+
+    LEAVE(" ");
 }
 
 
@@ -4576,7 +4393,7 @@
 
         break;
 
-    case COL_TRANSVOID:
+    case COL_TRANSFERVOID:
     case COL_AMTVAL:
     case COL_PRICE:
     case COL_DEBIT:
@@ -4602,7 +4419,7 @@
             }
 
             /* Setup the account field */
-            if (viewcol == COL_TRANSVOID)
+            if (viewcol == COL_TRANSFERVOID)
             {
                 acct = gnc_tree_control_split_reg_get_account_by_name (view, new_text);
                 if (acct == NULL)
@@ -4649,20 +4466,54 @@
                 }
             }
 
-            /* Set the transaction currency if not set or if this is a non currency register,
-                 this should be same as first currency split */
-            if (!xaccTransGetCurrency (trans) || !gnc_commodity_is_currency (view->priv->reg_comm))
+            /* Set the transaction currency if not set */
+            if (!xaccTransGetCurrency (trans))
             {
                 gnc_commodity *split_commodity;
-                split_commodity = xaccAccountGetCommodity (xaccSplitGetAccount (split));
 
-                if (gnc_commodity_is_currency (split_commodity))
-                    xaccTransSetCurrency (trans, xaccAccountGetCommodity (xaccSplitGetAccount (split)));
+                // set transaction currency to that of register if a currency
+                if (gnc_commodity_is_currency (view->priv->reg_comm))
+                    xaccTransSetCurrency (trans, view->priv->reg_comm);
+                else
+                    xaccTransSetCurrency (trans, gnc_default_currency());
+
+                // We are on General ledger
+                if (!anchor)
+                {
+                    split_commodity = xaccAccountGetCommodity (xaccSplitGetAccount (split));
+
+                    if (gnc_commodity_is_currency (split_commodity))
+                        xaccTransSetCurrency (trans, xaccAccountGetCommodity (xaccSplitGetAccount (split)));
+                    else
+                        xaccTransSetCurrency (trans, gnc_default_currency());
+                }
             }
 
+            // if non currency register, we set the trans currency to the first currency split
+            if (xaccTransGetCurrency (trans) && !gnc_commodity_is_currency (view->priv->reg_comm))
+            {
+                if (!gnc_commodity_is_currency (xaccAccountGetCommodity (xaccSplitGetAccount (xaccTransGetSplit (trans, 0)))))
+                {
+                    int i;
+                    Split *s = NULL;
+                    gboolean currency = FALSE;
+
+                    for (i = 0; (s = xaccTransGetSplit (trans, i)); i++) {
+                        if (gnc_commodity_is_currency (xaccAccountGetCommodity (xaccSplitGetAccount (s))))
+                        {
+                            currency = TRUE;
+                            break;
+                        }
+                    }
+
+                    if (currency == FALSE && gnc_commodity_is_currency (xaccAccountGetCommodity (xaccSplitGetAccount (split))))
+                            xaccTransSetCurrency (trans, xaccAccountGetCommodity (xaccSplitGetAccount (split)));
+                }
+            }
+
             /* This computes the value if we just commit the split after entering account */
             if (!valid_input)
-                input = get_value_for (view, trans, split, is_blank);
+                input = gnc_tree_util_split_reg_get_value_for (view, trans, split, is_blank);
 
             // Negate the input if COL_CREDIT
             if (viewcol == COL_CREDIT)
@@ -4699,7 +4550,7 @@
             if (input_used == FALSE)
             {
                 if (gnc_commodity_is_currency (xaccAccountGetCommodity (acct)))
-                    set_value_for (view, trans, split, input, force);
+                    gnc_tree_util_split_reg_set_value_for (view, trans, split, input, force);
                 else
                     set_value_for_amount (view, trans, split, input);
             }
@@ -4720,7 +4571,7 @@
                 xaccSplitSetParent (osplit, trans);
 
                 if (gnc_commodity_is_currency (xaccAccountGetCommodity (acct)))
-                    set_value_for (view, trans, osplit, gnc_numeric_neg (input), force);
+                    gnc_tree_util_split_reg_set_value_for (view, trans, osplit, gnc_numeric_neg (input), force);
                 else
                     set_value_for_amount (view, trans, osplit, gnc_numeric_neg (xaccSplitGetValue (split)));
             }
@@ -5072,7 +4923,7 @@
     }
 
     /* TRANSFER / VOID COLUMN */
-    else if (viewcol == COL_TRANSVOID)
+    else if (viewcol == COL_TRANSFERVOID)
     {
         GtkEntry *entry;
 
@@ -5255,7 +5106,7 @@
 
 //FIXME g_print("gtv_split_reg_match_selected_cb\n\n");
 
-/* Not sure what I am going to put in here yet */
+/* Not sure what I am going to put in here yet if anything */
 
 }
 
@@ -5269,7 +5120,7 @@
 
 //FIXME g_print("gtv_split_reg_changed_cb path string is '%s'\n\n", path_string);
 
-/* Not sure what I am going to put in here yet */
+/* Not sure what I am going to put in here yet if anything */
 
 }
 
@@ -5394,6 +5245,23 @@
 }
 
 
+/* Sets the current path reference to path */
+void
+gnc_tree_view_split_reg_set_current_path (GncTreeViewSplitReg *view, GtkTreePath *mpath)
+{
+    GncTreeModelSplitReg *model;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    if (view->priv->current_ref != NULL)
+    {
+        gtk_tree_row_reference_free (view->priv->current_ref);
+        view->priv->current_ref = NULL;
+    }
+    view->priv->current_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (model), mpath);
+}
+
+
 /* Reinit transaction / delete the splits */
 void
 gnc_tree_view_split_reg_reinit_trans (GncTreeViewSplitReg *view)
@@ -5534,6 +5402,13 @@
 
             gnc_tree_view_split_reg_block_selection (view, FALSE);
 
+            /* Remove the blank split and re-add - done so we keep it last in list */
+            gnc_tree_model_split_reg_set_blank_split_parent (model, view->priv->dirty_trans, TRUE);
+            gnc_tree_model_split_reg_set_blank_split_parent (model, view->priv->dirty_trans, FALSE);
+
+            // Set the transaction to show correct view
+            gnc_tree_view_split_reg_format_trans (view, view->priv->dirty_trans);
+
             view->priv->dirty_trans = NULL;
         }
     }
@@ -5566,6 +5441,10 @@
 
         // Add the split after rollback so it is last in list.
         gnc_tree_model_split_reg_set_blank_split_parent (model, trans, FALSE);
+
+        // Set the transaction to show correct view
+        gnc_tree_view_split_reg_format_trans (view, view->priv->dirty_trans);
+
         view->priv->dirty_trans = NULL;
 
         split = gnc_tree_model_split_get_blank_split (model);
@@ -5681,16 +5560,14 @@
 
         gtk_tree_view_collapse_row (GTK_TREE_VIEW (view), temp_spath);
 
-        if (view->priv->current_ref != NULL)
-        {
-            gtk_tree_row_reference_free (view->priv->current_ref);
-            view->priv->current_ref = NULL;
-        }
+        /* Update the tree view titles */
+        gtv_split_reg_titles (view, gtk_tree_path_get_depth (temp_spath));
 
         temp_fpath = gtk_tree_model_sort_convert_path_to_child_path (GTK_TREE_MODEL_SORT (s_model), temp_spath);
         temp_mpath = gtk_tree_model_filter_convert_path_to_child_path (GTK_TREE_MODEL_FILTER (f_model), temp_fpath);
 
-        view->priv->current_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (model), temp_mpath);
+        /* Save the new model path to path ref */
+        gnc_tree_view_split_reg_set_current_path (view, temp_mpath);
 
         gnc_tree_view_split_reg_block_selection (view, FALSE);
 

Modified: gnucash/trunk/src/gnome-utils/gnc-tree-view-split-reg.h
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-tree-view-split-reg.h	2013-04-19 20:20:22 UTC (rev 22919)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-view-split-reg.h	2013-04-20 16:45:56 UTC (rev 22920)
@@ -87,23 +87,23 @@
 }RowDepth;
 
 typedef enum {
-    COL_DATE,      //0
-    COL_DUEDATE,   //1
-    COL_NUMACT,    //2
-    COL_DESCNOTES, //3
-    COL_TRANSVOID, //4
-    COL_RECN,      //5
-    COL_TYPE,      //6
-    COL_VALUE,     //7
-    COL_AMOUNT,    //8
-    COL_AMTVAL,    //9
-    COL_RATE,      //10
-    COL_PRICE,     //11
-    COL_DEBIT,     //12
-    COL_CREDIT,    //13
-    COL_BALANCE,   //14
-    COL_STATUS,    //15
-    COL_COMM,      //16
+    COL_DATE,         //0
+    COL_DUEDATE,      //1
+    COL_NUMACT,       //2
+    COL_DESCNOTES,    //3
+    COL_TRANSFERVOID, //4
+    COL_RECN,         //5
+    COL_TYPE,         //6
+    COL_VALUE,        //7
+    COL_AMOUNT,       //8
+    COL_AMTVAL,       //9
+    COL_RATE,         //10
+    COL_PRICE,        //11
+    COL_DEBIT,        //12
+    COL_CREDIT,       //13
+    COL_BALANCE,      //14
+    COL_STATUS,       //15
+    COL_COMM,         //16
 } ViewCol;
 
 /* Standard g_object type */
@@ -115,10 +115,10 @@
 
 void gnc_tree_view_split_reg_default_selection (GncTreeViewSplitReg *view);
 
+gboolean gnc_tree_view_split_reg_set_format (GncTreeViewSplitReg *view);
+
 void gnc_tree_view_split_reg_set_read_only (GncTreeViewSplitReg *view, gboolean read_only);
 
-void gnc_tree_view_split_reg_set_value_for (GncTreeViewSplitReg *view, Transaction *trans, Split *split, gnc_numeric input, gboolean force);
-
 void gnc_tree_view_split_reg_set_dirty_trans (GncTreeViewSplitReg *view, Transaction *trans);
 
 Transaction * gnc_tree_view_split_reg_get_current_trans (GncTreeViewSplitReg *view);
@@ -129,6 +129,8 @@
 
 GtkTreePath * gnc_tree_view_split_reg_get_current_path (GncTreeViewSplitReg *view);
 
+void gnc_tree_view_split_reg_set_current_path (GncTreeViewSplitReg *view, GtkTreePath *mpath);
+
 RowDepth gnc_tree_view_reg_get_selected_row_depth (GncTreeViewSplitReg *view);
 
 void gnc_tree_view_split_reg_moved_cb (GncTreeViewSplitReg *view, GFunc cb, gpointer cb_data);
@@ -145,6 +147,8 @@
 
 const char * gnc_tree_view_split_reg_get_credit_debit_string (GncTreeViewSplitReg *view, gboolean credit);
 
+gnc_commodity * gnc_tree_view_split_reg_get_reg_commodity (GncTreeViewSplitReg *view);
+
 /*************************************************************************************/
 /* Get sort model path from the model path */
 GtkTreePath * gnc_tree_view_split_reg_get_sort_path_from_model_path (GncTreeViewSplitReg *view, GtkTreePath *mpath);

Modified: gnucash/trunk/src/register/ledger-core/gnc-ledger-display2.c
===================================================================
--- gnucash/trunk/src/register/ledger-core/gnc-ledger-display2.c	2013-04-19 20:20:22 UTC (rev 22919)
+++ gnucash/trunk/src/register/ledger-core/gnc-ledger-display2.c	2013-04-20 16:45:56 UTC (rev 22920)
@@ -94,7 +94,7 @@
 
 static void gnc_ledger_display2_refresh_internal (GNCLedgerDisplay2 *ld, GList *splits);
 
-static void gnc_ledger_display2_refresh_cb (GncTreeModelSplitReg *model, gpointer user_data);
+static void gnc_ledger_display2_refresh_cb (GncTreeModelSplitReg *model, gpointer item, gpointer user_data);
 
 
 /** Implementations *************************************************/
@@ -827,7 +827,7 @@
     gnc_tree_model_split_reg_set_data (ld->model, ld, gnc_ledger_display2_parent);
 
     // This sets up a call back for the search_ledger2 to reload after changes
-    g_signal_connect (G_OBJECT (ld->model), "refresh_view",
+    g_signal_connect (G_OBJECT (ld->model), "refresh_trans",
                       G_CALLBACK (gnc_ledger_display2_refresh_cb), ld );
 
     splits = qof_query_run (ld->query);
@@ -890,18 +890,6 @@
     return ledger_display;
 }
 
-#ifdef skip
-GNCLedgerDisplay2 *
-gnc_ledger_display2_find_by_query (Query *q)
-{
-    if (!q)
-        return NULL;
-
-    return gnc_find_first_gui_component (REGISTER_GL_CM_CLASS, find_by_query, q);
-}
-#endif
-
-
 /********************************************************************\
  * refresh only the indicated register window                       *
 \********************************************************************/
@@ -1036,7 +1024,7 @@
 
 /* This is used for the search_ledger2 reload after any changes made */
 static void
-gnc_ledger_display2_refresh_cb (GncTreeModelSplitReg *model, gpointer user_data)
+gnc_ledger_display2_refresh_cb (GncTreeModelSplitReg *model, gpointer item, gpointer user_data)
 {
     GNCLedgerDisplay2 *ld = user_data;
 



More information about the gnucash-changes mailing list