r22931 - gnucash/trunk - Register rewrite Update, this adds the schedule option with some other changes.

Geert Janssens gjanssens at code.gnucash.org
Thu May 2 10:41:57 EDT 2013


Author: gjanssens
Date: 2013-05-02 10:41:56 -0400 (Thu, 02 May 2013)
New Revision: 22931
Trac: http://svn.gnucash.org/trac/changeset/22931

Added:
   gnucash/trunk/src/gnome/dialog-sx-editor2.c
   gnucash/trunk/src/gnome/dialog-sx-editor2.h
Modified:
   gnucash/trunk/po/POTFILES.in
   gnucash/trunk/src/engine/Transaction.c
   gnucash/trunk/src/gnome-utils/gnc-cell-renderer-popup-entry.c
   gnucash/trunk/src/gnome-utils/gnc-embedded-window.c
   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-util-split-reg.c
   gnucash/trunk/src/gnome-utils/gnc-tree-util-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/Makefile.am
   gnucash/trunk/src/gnome/dialog-sx-since-last-run.c
   gnucash/trunk/src/gnome/gnc-plugin-page-register2.c
   gnucash/trunk/src/gnome/gnc-plugin-page-sx-list.c
   gnucash/trunk/src/gnome/gnc-split-reg2.c
   gnucash/trunk/src/gnome/ui/gnc-plugin-page-sx-list-ui.xml
   gnucash/trunk/src/register/ledger-core/gnc-ledger-display2.c
Log:
Register rewrite Update, this adds the schedule option with some other changes.

This update adds the schedule option. The schedule editor files have been duplicated and used to edit the schedule with the template displaying in the tree view. This is accessed from additional menu options on the Scheduled Transactions plugin page under Schedule, New 2 and Edit 2.
Other changes are to the date renderer, FuturePostedDate function, fix the split collapse option and move some functions around.
Author: Robert Fewell

Modified: gnucash/trunk/po/POTFILES.in
===================================================================
--- gnucash/trunk/po/POTFILES.in	2013-04-24 09:10:29 UTC (rev 22930)
+++ gnucash/trunk/po/POTFILES.in	2013-05-02 14:41:56 UTC (rev 22931)
@@ -190,6 +190,7 @@
 src/gnome/dialog-print-check.c
 src/gnome/dialog-progress.c
 src/gnome/dialog-sx-editor.c
+src/gnome/dialog-sx-editor2.c
 src/gnome/dialog-sx-from-trans.c
 src/gnome/dialog-sx-since-last-run.c
 src/gnome/dialog-tax-info.c

Modified: gnucash/trunk/src/engine/Transaction.c
===================================================================
--- gnucash/trunk/src/engine/Transaction.c	2013-04-24 09:10:29 UTC (rev 22930)
+++ gnucash/trunk/src/engine/Transaction.c	2013-05-02 14:41:56 UTC (rev 22931)
@@ -2216,16 +2216,13 @@
 
 gboolean xaccTransInFutureByPostedDate (const Transaction *trans)
 {
-    GDate date_now;
-    GDate trans_date;
+    time64 present;
     gboolean result;
     g_assert(trans);
 
-    trans_date = xaccTransGetDatePostedGDate (trans);
+    present = gnc_time64_get_today_end ();
 
-    gnc_gdate_set_time64 (&date_now, gnc_time (NULL));
-
-    if (g_date_compare (&trans_date, &date_now) > 0)
+    if (trans->date_posted.tv_sec > present)
         result = TRUE;
     else
         result = FALSE;

Modified: gnucash/trunk/src/gnome/Makefile.am
===================================================================
--- gnucash/trunk/src/gnome/Makefile.am	2013-04-24 09:10:29 UTC (rev 22930)
+++ gnucash/trunk/src/gnome/Makefile.am	2013-05-02 14:41:56 UTC (rev 22931)
@@ -41,6 +41,7 @@
   dialog-print-check2.c \
   dialog-progress.c \
   dialog-sx-editor.c \
+  dialog-sx-editor2.c \
   dialog-sx-from-trans.c \
   dialog-sx-since-last-run.c \
   dialog-tax-info.c \
@@ -85,6 +86,7 @@
   dialog-print-check2.h \
   dialog-progress.h \
   dialog-sx-editor.h \
+  dialog-sx-editor2.h \
   dialog-sx-from-trans.h \
   dialog-sx-since-last-run.h \
   gnc-budget-view.h \

Added: gnucash/trunk/src/gnome/dialog-sx-editor2.c
===================================================================
--- gnucash/trunk/src/gnome/dialog-sx-editor2.c	                        (rev 0)
+++ gnucash/trunk/src/gnome/dialog-sx-editor2.c	2013-05-02 14:41:56 UTC (rev 22931)
@@ -0,0 +1,1798 @@
+/********************************************************************\
+ * dialog-sx-editor2.c : dialog for scheduled transaction editing   *
+ * Copyright (C) 2001,2002,2006 Joshua Sled <jsled at asynchronous.org>*
+ * Copyright (C) 2011 Robert Fewell                                 *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of version 2 and/or version 3 of the   *
+ * GNU General Public License as published by the Free Software     *
+ * Foundation.                                                      *
+ *                                                                  *
+ * As a special exception, permission is granted to link the binary *
+ * module resultant from this code with the OpenSSL project's       *
+ * "OpenSSL" library (or modified versions of it that use the same  *
+ * license as the "OpenSSL" library), and distribute the linked     *
+ * executable.  You must obey the GNU General Public License in all *
+ * respects for all of the code used other than "OpenSSL". If you   *
+ * modify this file, you may extend this exception to your version  *
+ * of the file, but you are not obligated to do so. If you do not   *
+ * wish to do so, delete this exception statement from your version *
+ * of this file.                                                    *
+ *                                                                  *
+ * 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 <locale.h>
+
+#include <gnc-gdate-utils.h>
+#include "qof.h"
+#include "Account.h"
+#include "SchedXaction.h"
+#include "SX-book.h"
+#include "dialog-preferences.h"
+#include "dialog-sx-editor2.h"
+#include "dialog-utils.h"
+#include "gnc-component-manager.h"
+#include "gnc-date.h"
+#include "gnc-date-edit.h"
+#include "gnc-dense-cal.h"
+#include "gnc-dense-cal-store.h"
+#include "gnc-embedded-window.h"
+#include "gnc-engine.h"
+#include "gnc-frequency.h"
+#include "gnc-gconf-utils.h"
+#include "gnc-gui-query.h"
+#include "gnc-hooks.h"
+#include "gnc-ledger-display.h"
+#include "gnc-plugin-page.h"
+#include "gnc-plugin-page-register2.h"
+#include "gnc-ui.h"
+#include "gnc-ui-util.h"
+#include "gnc-tree-model-split-reg.h"
+#include "gnc-tree-control-split-reg.h"
+
+#include "gnc-sx-instance-model.h"
+#include "dialog-sx-since-last-run.h"
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "gnc.gui.sx.editor"
+
+static QofLogModule log_module = GNC_MOD_GUI_SX;
+
+static gint _sx_engine_event_handler_id = -1;
+
+#define END_NEVER_OPTION 0
+#define END_DATE_OPTION  1
+#define NUM_OCCUR_OPTION 2
+
+#define NUM_LEDGER_LINES_DEFAULT 6
+
+#define EX_CAL_NUM_MONTHS 6
+#define EX_CAL_MO_PER_COL 3
+
+#define GNC_D_WIDTH 25
+#define GNC_D_BUF_WIDTH 26
+
+/** Datatypes ***********************************************************/
+
+typedef enum _EndTypeEnum
+{
+    END_NEVER,
+    END_DATE,
+    END_OCCUR,
+} EndType;
+
+typedef enum { NO_END, DATE_END, COUNT_END } END_TYPE;
+
+struct _GncSxEditorDialog2
+{
+    GtkWidget    *dialog;
+    GtkBuilder   *builder;
+    GtkNotebook  *notebook;
+    SchedXaction *sx;
+    /* If this is a new scheduled transaction or not. */
+    int newsxP;
+
+    /* The various widgets in the dialog */
+    GNCLedgerDisplay2 *ledger;
+
+    GncFrequency     *gncfreq;
+    GncDenseCalStore *dense_cal_model;
+    GncDenseCal      *example_cal;
+
+    GtkEditable *nameEntry;
+
+    GtkLabel *lastOccurLabel;
+
+    GtkToggleButton *enabledOpt;
+    GtkToggleButton *autocreateOpt;
+    GtkToggleButton *notifyOpt;
+    GtkToggleButton *advanceOpt;
+    GtkSpinButton   *advanceSpin;
+    GtkToggleButton *remindOpt;
+    GtkSpinButton   *remindSpin;
+
+    GtkToggleButton *optEndDate;
+    GtkToggleButton *optEndNone;
+    GtkToggleButton *optEndCount;
+    GtkEntry        *endCountSpin;
+    GtkEntry        *endRemainSpin;
+    GNCDateEdit     *endDateEntry;
+
+    char *sxGUIDstr;
+
+    GncEmbeddedWindow *embed_window;
+    GncPluginPage     *plugin_page;
+};
+
+/** Prototypes **********************************************************/
+
+static void schedXact_editor_create_freq_sel (GncSxEditorDialog2 *sxed);
+static void schedXact_editor_create_ledger (GncSxEditorDialog2 *sxed);
+static void schedXact_editor_populate (GncSxEditorDialog2 *);
+static void gnc_sxed_record_size (GncSxEditorDialog2 *sxed);
+static void endgroup_rb_toggled_cb (GtkButton *b, gpointer d);
+static void set_endgroup_toggle_states (GncSxEditorDialog2 *sxed, EndType t);
+static void advance_toggled_cb (GtkButton *b, GncSxEditorDialog2 *sxed);
+static void remind_toggled_cb (GtkButton *b, GncSxEditorDialog2 *sxed);
+static gboolean gnc_sxed_check_consistent (GncSxEditorDialog2 *sxed);
+static gboolean gnc_sxed_check_changed (GncSxEditorDialog2 *sxed);
+static void gnc_sxed_save_sx (GncSxEditorDialog2 *sxed);
+static void gnc_sxed_freq_changed (GncFrequency *gf, gpointer ud);
+static void sxed_excal_update_adapt_cb (GtkObject *o, gpointer ud);
+static void gnc_sxed_update_cal (GncSxEditorDialog2 *sxed);
+static void on_sx_check_toggled_cb (GtkWidget *togglebutton, gpointer user_data);
+//void on_sx_check_toggled_cb (GtkWidget *togglebutton, gpointer user_data);
+static void gnc_sxed_reg_check_close (GncSxEditorDialog2 *sxed);
+static gboolean sxed_delete_event (GtkWidget *widget, GdkEvent *event, gpointer ud);
+static gboolean sxed_confirmed_cancel (GncSxEditorDialog2 *sxed);
+static gboolean editor_component_sx_equality (gpointer find_data, gpointer user_data);
+
+static GtkActionEntry gnc_sxed_menu_entries [] =
+{
+    { "EditAction", NULL, N_("_Edit"), NULL, NULL, NULL },
+    { "TransactionAction", NULL, N_("_Transaction"), NULL, NULL, NULL },
+    { "ViewAction", NULL, N_("_View"), NULL, NULL, NULL },
+    { "ActionsAction", NULL, N_("_Actions"), NULL, NULL, NULL },
+};
+static guint gnc_sxed_menu_n_entries = G_N_ELEMENTS (gnc_sxed_menu_entries);
+
+/** Implementations *****************************************************/
+
+static void
+sxed_close_handler(gpointer user_data)
+{
+    GncSxEditorDialog2 *sxed = user_data;
+
+    gnc_sxed_reg_check_close(sxed);
+    gnc_sxed_record_size(sxed);
+    gtk_widget_destroy(sxed->dialog);
+    /* The data will be cleaned up in the destroy handler. */
+}
+
+
+/**
+ * @return TRUE if the user does want to cancel, FALSE if not.  If TRUE is
+ * returned, the register's changes have been cancelled.
+ **/
+static gboolean
+sxed_confirmed_cancel (GncSxEditorDialog2 *sxed)
+{
+    GncTreeViewSplitReg *view;
+
+    view = gnc_ledger_display2_get_split_view_register (sxed->ledger);
+    /* check for changes */
+    if (gnc_sxed_check_changed (sxed))
+    {
+        const char *sx_changed_msg =
+            _( "This Scheduled Transaction has changed; are you "
+               "sure you want to cancel?" );
+        if (!gnc_verify_dialog (sxed->dialog, FALSE, "%s", sx_changed_msg))
+        {
+            return FALSE;
+        }
+    }
+    /* cancel ledger changes */
+    gnc_tree_view_split_reg_cancel_edit (view, TRUE);
+    return TRUE;
+}
+
+
+/**********************************
+ * Dialog Action Button functions *
+ *********************************/
+static void
+editor_cancel_button_clicked_cb (GtkButton *b, GncSxEditorDialog2 *sxed)
+{
+    /* close */
+    if (!sxed_confirmed_cancel (sxed))
+        return;
+
+    gnc_close_gui_component_by_data (DIALOG_SCHEDXACTION2_EDITOR_CM_CLASS,
+                                     sxed);
+}
+
+
+static void
+editor_help_button_clicked_cb (GtkButton *b, GncSxEditorDialog2 *sxed)
+{
+    gnc_gnome_help (HF_HELP, HL_SXEDITOR);
+}
+
+
+static void
+editor_ok_button_clicked_cb (GtkButton *b, GncSxEditorDialog2 *sxed)
+{
+    QofBook *book;
+    SchedXactions *sxes;
+
+    if (!gnc_sxed_check_consistent (sxed))
+        return;
+
+    gnc_sxed_save_sx (sxed);
+
+    /* add to list */
+    // @@fixme -- forget 'new'-flag: check for existance of the SX [?]
+    if ( sxed->newsxP )
+    {
+        book = gnc_get_current_book ();
+        sxes = gnc_book_get_schedxactions (book);
+        gnc_sxes_add_sx (sxes, sxed->sx);
+        sxed->newsxP = FALSE;
+    }
+
+    /* cleanup */
+    gnc_close_gui_component_by_data (DIALOG_SCHEDXACTION2_EDITOR_CM_CLASS,
+                                     sxed);
+}
+
+
+/*************************************************************************
+ * Checks to see if the SX has been modified from it's previously-saved
+ * state.
+ * @return TRUE if this is a 'new' SX, or if the SX has changed from it's
+ *   previous configuration.
+ ************************************************************************/
+static gboolean
+gnc_sxed_check_changed (GncSxEditorDialog2 *sxed)
+{
+    if (sxed->newsxP)
+        return TRUE;
+
+    /* name */
+    {
+        char *name;
+
+        name = gtk_editable_get_chars (GTK_EDITABLE (sxed->nameEntry), 0, -1);
+        if (strlen (name) == 0)
+        {
+            return TRUE;
+
+        }
+        if ((xaccSchedXactionGetName (sxed->sx) == NULL)
+                || (strcmp( xaccSchedXactionGetName (sxed->sx),
+                            name ) != 0))
+        {
+            return TRUE;
+        }
+    }
+
+    /* end options */
+    {
+        /* dialog says... no end */
+        if (gtk_toggle_button_get_active (sxed->optEndNone))
+        {
+            if (xaccSchedXactionHasEndDate (sxed->sx)
+                    || xaccSchedXactionHasOccurDef (sxed->sx))
+            {
+                return TRUE;
+            }
+        }
+
+        /* dialog says... end date */
+        if (gtk_toggle_button_get_active (sxed->optEndDate))
+        {
+            GDate sxEndDate, dlgEndDate;
+
+            if (!xaccSchedXactionHasEndDate (sxed->sx))
+            {
+                return TRUE;
+            }
+            sxEndDate = *xaccSchedXactionGetEndDate (sxed->sx);
+            gnc_gdate_set_time64 (&dlgEndDate,
+                               gnc_date_edit_get_date( sxed->
+                                       endDateEntry));
+
+            if (g_date_compare (&sxEndDate, &dlgEndDate) != 0)
+            {
+                return TRUE;
+            }
+        }
+
+        /* dialog says... num occur */
+        if (gtk_toggle_button_get_active (sxed->optEndCount))
+        {
+            gint sxNumOccur, sxNumRem, dlgNumOccur, dlgNumRem;
+
+            if (!xaccSchedXactionGetNumOccur (sxed->sx))
+            {
+                return TRUE;
+            }
+
+            dlgNumOccur  =
+                gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (sxed->endCountSpin));
+
+            dlgNumRem =
+                gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (sxed->endRemainSpin));
+
+            sxNumOccur = xaccSchedXactionGetNumOccur (sxed->sx);
+            sxNumRem = xaccSchedXactionGetRemOccur (sxed->sx);
+
+            if ((dlgNumOccur != sxNumOccur)
+                    || (dlgNumRem != sxNumRem))
+            {
+                return TRUE;
+            }
+        }
+    }
+
+    /* SX options [autocreate, notify, reminder, advance] */
+    {
+        gboolean dlgEnabled,
+                 dlgAutoCreate,
+                 dlgNotify,
+                 sxEnabled,
+                 sxAutoCreate,
+                 sxNotify;
+        gint dlgAdvance, sxAdvance;
+        gint dlgRemind, sxRemind;
+
+        dlgEnabled =
+            gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sxed->
+                                          enabledOpt));
+        dlgAutoCreate =
+            gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sxed->
+                                          autocreateOpt));
+        dlgNotify =
+            gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sxed->
+                                          notifyOpt));
+
+        sxEnabled = xaccSchedXactionGetEnabled (sxed->sx);
+        if (!((dlgEnabled == sxEnabled)))
+        {
+            return TRUE;
+        }
+
+        xaccSchedXactionGetAutoCreate (sxed->sx, &sxAutoCreate, &sxNotify);
+        if (!((dlgAutoCreate == sxAutoCreate)
+                && (dlgNotify == sxNotify)))
+        {
+            return TRUE;
+        }
+
+        dlgAdvance = 0;
+        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sxed->advanceOpt)))
+        {
+            dlgAdvance =
+                gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (sxed->
+                                                  advanceSpin));
+        }
+        sxAdvance = xaccSchedXactionGetAdvanceCreation (sxed->sx);
+        if (dlgAdvance != sxAdvance)
+        {
+            return TRUE;
+        }
+
+        dlgRemind = 0;
+        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sxed->remindOpt)))
+        {
+            dlgRemind =
+                gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (sxed->remindSpin));
+        }
+        sxRemind = xaccSchedXactionGetAdvanceReminder (sxed->sx);
+        if (dlgRemind != sxRemind)
+        {
+            return TRUE;
+        }
+    }
+
+    {
+        GList *dialog_schedule = NULL;
+        GDate dialog_start_date, sx_start_date;
+        gchar *dialog_schedule_str, *sx_schedule_str;
+        gboolean schedules_are_the_same, start_dates_are_the_same;
+
+        g_date_clear (&dialog_start_date, 1);
+        gnc_frequency_save_to_recurrence (sxed->gncfreq, &dialog_schedule, &dialog_start_date);
+        dialog_schedule_str = recurrenceListToString (dialog_schedule);
+        recurrenceListFree (&dialog_schedule);
+
+        sx_start_date = *xaccSchedXactionGetStartDate (sxed->sx);
+        sx_schedule_str = recurrenceListToString (gnc_sx_get_schedule (sxed->sx));
+
+        g_debug ("dialog schedule [%s], sx schedule [%s]",
+                dialog_schedule_str, sx_schedule_str);
+
+        schedules_are_the_same = (strcmp (dialog_schedule_str, sx_schedule_str) == 0);
+        g_free (dialog_schedule_str);
+        g_free (sx_schedule_str);
+
+        start_dates_are_the_same = (g_date_compare (&dialog_start_date, &sx_start_date) == 0);
+
+        if (!schedules_are_the_same || !start_dates_are_the_same)
+            return TRUE;
+    }
+
+    /* template transactions */
+    {
+        GncTreeViewSplitReg *view = gnc_ledger_display2_get_split_view_register (sxed->ledger);
+        /* Make sure we have finished the edit */
+        gnc_tree_view_split_reg_finish_edit (view);
+        if (gnc_tree_view_split_reg_get_dirty_trans (view) != NULL)
+            return TRUE;
+    }
+    return FALSE;
+}
+
+
+/*****************************************************************************
+ * Holds the credit- and debit-sum for a given Transaction, as used in
+ * gnc_sxed_check_consistent.
+ ****************************************************************************/
+typedef struct _txnCreditDebitSums
+{
+    gnc_numeric creditSum;
+    gnc_numeric debitSum;
+} txnCreditDebitSums;
+
+
+static
+void
+set_sums_to_zero (gpointer key,
+                  gpointer val,
+                  gpointer ud)
+{
+    txnCreditDebitSums *tcds = (txnCreditDebitSums*)val;
+    tcds->creditSum = gnc_numeric_zero();
+    tcds->debitSum  = gnc_numeric_zero();
+}
+
+
+static void
+check_credit_debit_balance (gpointer key,
+                            gpointer val,
+                            gpointer ud)
+{
+    txnCreditDebitSums *tcds = (txnCreditDebitSums*)val;
+    gboolean *unbalanced = (gboolean*)ud;
+    *unbalanced |= !(gnc_numeric_zero_p (
+                         gnc_numeric_sub_fixed (tcds->debitSum,
+                                 tcds->creditSum)));
+
+    if (qof_log_check (G_LOG_DOMAIN, QOF_LOG_DEBUG))
+    {
+        if (gnc_numeric_zero_p (gnc_numeric_sub_fixed (tcds->debitSum,
+                                 tcds->creditSum)))
+        {
+            g_debug ("%p | true [%s - %s = %s]",
+                     key,
+                     gnc_numeric_to_string (tcds->debitSum),
+                     gnc_numeric_to_string (tcds->creditSum),
+                     gnc_numeric_to_string (gnc_numeric_sub_fixed (tcds->debitSum,
+                                           tcds->creditSum)));
+        }
+        else
+        {
+            g_debug ("%p | false [%s - %s = %s]",
+                     key,
+                     gnc_numeric_to_string (tcds->debitSum),
+                     gnc_numeric_to_string (tcds->creditSum),
+                     gnc_numeric_to_string (gnc_numeric_sub_fixed (tcds->debitSum,
+                                           tcds->creditSum)));
+        }
+    }
+}
+
+
+/*******************************************************************************
+ * Checks to make sure that the SX is in a reasonable state to save.
+ * @return true if checks out okay, false otherwise.
+ ******************************************************************************/
+static gboolean
+gnc_sxed_check_consistent (GncSxEditorDialog2 *sxed)
+{
+    gboolean multi_commodity = FALSE;
+    gnc_commodity *base_cmdty = NULL;
+    gint ttVarCount, splitCount;
+    GList *schedule = NULL;
+
+    /* Do checks on validity and such, interrupting the user if
+     * things aren't right.
+     *
+     * Features...
+     * X support formulas [?!]
+     * X balancing the SX if contain numeric-only formula data.
+     *   X agreement with create-automagically/notification controls
+     * X the 'will ever be valid' check should take num-occur vals into
+     *   account.
+     * X SX name is unique
+     * X SX has a name
+     * X "weekly" FS has some days set.
+     * X "once" with reasonable start/end dates.
+     *   X This doesn't work at the time the 'weekly' one was fixed with
+     *     user-confirmation, below; the once SX is always valid.
+     * [X more generically, creating a "not scheduled" SX is probably not
+     *   right... ]
+     */
+
+    ttVarCount = 0;
+    splitCount = 0;
+    {
+        static const int NUM_ITERS_WITH_VARS = 5;
+        static const int NUM_ITERS_NO_VARS = 1;
+        int numIters, i;
+        GHashTable *vars, *txns;
+        GList *splitList = NULL;
+        char *str;
+        kvp_frame *f;
+        kvp_value *v;
+        Split *s;
+        Transaction *t;
+        gnc_numeric tmp;
+        gboolean unbalanceable;
+        gpointer unusedKey, unusedValue;
+
+        unbalanceable = FALSE; /* innocent until proven guilty */
+        vars = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)gnc_sx_variable_free);
+        txns = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
+        numIters = NUM_ITERS_NO_VARS;
+        /**
+         * Plan:
+         * . Do a first pass to get the variables.
+         * . Set each variable to random values.
+         * . see if we balance after that
+         *   . true: all good
+         *   . false: indicate to user, allow decision.
+         */
+
+        /* numeric-formulas-get-balanced determination */
+        gnc_sx_get_variables (sxed->sx, vars);
+
+        ttVarCount = g_hash_table_size (vars);
+        if (ttVarCount != 0)
+        {
+            /* balance with random variable bindings some number
+             * of times in an attempt to ferret out
+             * un-balanceable transactions.
+             *
+             * NOTE: The Real Way to do this is with some
+             * symbolic math to eliminate the variables.  This is
+             * hard, and we don't do it.  This solution will
+             * suffice for now, and perhaps for the lifetime of
+             * the software. --jsled */
+            numIters = NUM_ITERS_WITH_VARS;
+        }
+
+        for (i = 0; i < numIters && !unbalanceable; i++)
+        {
+            gnc_sx_randomize_variables (vars);
+            g_hash_table_foreach (txns, set_sums_to_zero, NULL);
+            tmp = gnc_numeric_zero();
+
+            splitList = xaccSchedXactionGetSplits (sxed->sx);
+            splitCount += g_list_length (splitList);
+
+            for (; splitList; splitList = splitList->next)
+            {
+                GncGUID *acct_guid;
+                Account *acct;
+                gnc_commodity *split_cmdty;
+                txnCreditDebitSums *tcds;
+
+                s = (Split*)splitList->data;
+                t = xaccSplitGetParent (s);
+
+                if (!(tcds =
+                            (txnCreditDebitSums*)g_hash_table_lookup (txns,
+                                    (gpointer)t)))
+                {
+                    tcds = g_new0 (txnCreditDebitSums, 1 );
+                    tcds->creditSum = gnc_numeric_zero();
+                    tcds->debitSum  = gnc_numeric_zero();
+                    g_hash_table_insert (txns, (gpointer)t, (gpointer)tcds);
+                }
+
+                f = xaccSplitGetSlots (s);
+
+                /* contains the guid of the split's actual account. */
+                v = kvp_frame_get_slot_path (f,
+                                            GNC_SX_ID,
+                                            GNC_SX_ACCOUNT,
+                                            NULL);
+                acct_guid = kvp_value_get_guid (v);
+                acct = xaccAccountLookup (acct_guid, gnc_get_current_book ());
+                split_cmdty = xaccAccountGetCommodity (acct);
+                if (base_cmdty == NULL)
+                {
+                    base_cmdty = split_cmdty;
+                }
+                multi_commodity |= !gnc_commodity_equal (split_cmdty, base_cmdty);
+
+                v = kvp_frame_get_slot_path (f,
+                                             GNC_SX_ID,
+                                             GNC_SX_CREDIT_FORMULA,
+                                             NULL);
+                if (v
+                        && (str = kvp_value_get_string (v))
+                        && strlen( str ) != 0)
+                {
+                    if (gnc_sx_parse_vars_from_formula (str, vars, &tmp ) < 0)
+                    {
+                        GString *errStr;
+
+                        errStr = g_string_sized_new (32);
+                        g_string_printf (errStr,
+                                         _( "Couldn't parse credit formula for "
+                                            "split \"%s\"."),
+                                         xaccSplitGetMemo (s));
+                        gnc_error_dialog (GTK_WIDGET (sxed->dialog), "%s",
+                                          errStr->str);
+                        g_string_free (errStr, TRUE);
+
+                        return FALSE;
+                    }
+                    tcds->creditSum =
+                        gnc_numeric_add (tcds->creditSum, tmp, 100,
+                                         (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD));
+                    tmp = gnc_numeric_zero();
+                }
+                v = kvp_frame_get_slot_path (f,
+                                             GNC_SX_ID,
+                                             GNC_SX_DEBIT_FORMULA,
+                                             NULL);
+                if (v
+                        && (str = kvp_value_get_string (v))
+                        && strlen(str) != 0 )
+                {
+                    if (gnc_sx_parse_vars_from_formula (str, vars, &tmp ) < 0)
+                    {
+                        GString *errStr;
+
+                        errStr = g_string_sized_new (32);
+                        g_string_printf (errStr,
+                                         _( "Couldn't parse debit formula for "
+                                            "split \"%s\"."),
+                                         xaccSplitGetMemo (s));
+                        gnc_error_dialog (GTK_WIDGET (sxed->dialog), "%s",
+                                          (gchar*)errStr->str);
+                        g_string_free (errStr, TRUE);
+
+                        return FALSE;
+                    }
+                    tcds->debitSum = gnc_numeric_add (tcds->debitSum, tmp, 100,
+                                                      (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD));
+                    tmp = gnc_numeric_zero();
+                }
+            }
+
+            g_hash_table_foreach (txns,
+                                  check_credit_debit_balance,
+                                  &unbalanceable);
+        }
+
+        /* Subtract out pre-defined vars */
+        if (g_hash_table_lookup_extended (vars, "i",
+                                         &unusedKey,
+                                         &unusedValue))
+        {
+            ttVarCount -= 1;
+        }
+
+        g_hash_table_destroy (vars);
+        g_hash_table_destroy (txns);
+
+        if (unbalanceable
+                && !gnc_verify_dialog (sxed->dialog, FALSE,
+                                       "%s",
+                                       _("The Scheduled Transaction Editor "
+                                         "cannot automatically balance "
+                                         "this transaction. "
+                                         "Should it still be "
+                                         "entered?")))
+        {
+            return FALSE;
+        }
+    }
+
+    /* read out data back into SchedXaction object. */
+    /* FIXME: this is getting too deep; split out. */
+    {
+        gchar *name, *nameKey;
+        gboolean nameExists, nameHasChanged;
+        GList *sxList;
+
+        name = gtk_editable_get_chars (GTK_EDITABLE (sxed->nameEntry), 0, -1);
+        if (strlen (name) == 0 )
+        {
+            const char *sx_has_no_name_msg =
+                _("Please name the Scheduled Transaction.");
+            gnc_error_dialog (sxed->dialog, "%s", sx_has_no_name_msg);
+            g_free (name);
+            return FALSE;
+
+        }
+
+        nameExists = FALSE;
+        nameKey = g_utf8_collate_key (name, -1);
+        nameHasChanged =
+            (xaccSchedXactionGetName (sxed->sx) == NULL)
+            || (strcmp (xaccSchedXactionGetName (sxed->sx), name) != 0);
+        for ( sxList =
+                    gnc_book_get_schedxactions (gnc_get_current_book())->sx_list;
+                nameHasChanged && !nameExists && sxList;
+                sxList = sxList->next )
+        {
+            char *existingName, *existingNameKey;
+            existingName =
+                xaccSchedXactionGetName ((SchedXaction*)sxList->data);
+            existingNameKey = g_utf8_collate_key (existingName, -1);
+            nameExists |= (strcmp (nameKey, existingNameKey) == 0);
+            g_free (existingNameKey);
+        }
+        if (nameHasChanged && nameExists)
+        {
+            const char *sx_has_existing_name_msg =
+                _("A Scheduled Transaction with the "
+                   "name \"%s\" already exists. "
+                   "Are you sure you want to name "
+                   "this one the same?");
+            if (!gnc_verify_dialog (sxed->dialog, FALSE,
+                                      sx_has_existing_name_msg,
+                                      name))
+            {
+                g_free (nameKey);
+                g_free (name);
+                return FALSE;
+            }
+        }
+        g_free (nameKey);
+        g_free (name);
+    }
+
+    // @@FIXME: similar to below, check the commodities involved, and disallow autocreation
+    {
+        gboolean autocreateState;
+
+        autocreateState =
+            gtk_toggle_button_get_active (
+                GTK_TOGGLE_BUTTON (sxed->autocreateOpt));
+
+        if (((ttVarCount > 0) || multi_commodity) && autocreateState)
+        {
+            gnc_warning_dialog (sxed->dialog, "%s",
+                               _("Scheduled Transactions with variables "
+                                 "cannot be automatically created."));
+            return FALSE;
+        }
+
+        /* Fix for part of Bug#121740 -- auto-create transactions are
+         * only valid if there's actually a transaction to create. */
+        if (autocreateState && splitCount == 0)
+        {
+            gnc_warning_dialog (sxed->dialog, "%s",
+                               _("Scheduled Transactions without a template "
+                                 "transaction cannot be automatically created."));
+            return FALSE;
+        }
+    }
+
+    /* deal with time. */
+    {
+        GDate startDate, endDate, nextDate;
+
+        if (!gtk_toggle_button_get_active (sxed->optEndDate)
+                && !gtk_toggle_button_get_active (sxed->optEndCount)
+                && !gtk_toggle_button_get_active (sxed->optEndNone) )
+        {
+            const char *sx_end_spec_msg =
+                _("Please provide a valid end selection.");
+            gnc_error_dialog (sxed->dialog, "%s", sx_end_spec_msg);
+            return FALSE;
+        }
+
+        if (gtk_toggle_button_get_active (sxed->optEndCount))
+        {
+            gint occur, rem;
+
+            occur  =
+                gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (sxed->endCountSpin));
+
+            rem =
+                gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (sxed->endRemainSpin));
+
+            if (occur == 0)
+            {
+                const char *sx_occur_count_zero_msg =
+                    _("There must be some number of occurrences.");
+                gnc_error_dialog (sxed->dialog, "%s",
+                                  sx_occur_count_zero_msg);
+                return FALSE;
+            }
+
+            if (rem > occur)
+            {
+                const char *sx_occur_counts_wrong_msg =
+                    _("The number of remaining occurrences "
+                       "(%d) is greater than the number of "
+                       "total occurrences (%d).");
+                gnc_error_dialog (sxed->dialog,
+                                  sx_occur_counts_wrong_msg,
+                                  rem, occur);
+                return FALSE;
+            }
+
+        }
+
+        g_date_clear (&endDate, 1);
+        if ( gtk_toggle_button_get_active(sxed->optEndDate))
+        {
+            gnc_gdate_set_time64 (&endDate,
+                               gnc_date_edit_get_date (sxed->
+                                       endDateEntry));
+        }
+
+        g_date_clear (&nextDate, 1);
+        gnc_frequency_save_to_recurrence (sxed->gncfreq, &schedule, &startDate);
+        if (g_list_length (schedule) > 0)
+        {
+            g_date_subtract_days (&startDate, 1);
+            recurrenceListNextInstance (schedule, &startDate, &nextDate);
+        }
+        recurrenceListFree (&schedule);
+
+        if (!g_date_valid (&nextDate)
+                || (g_date_valid (&endDate) && (g_date_compare (&nextDate, &endDate) > 0)))
+        {
+            const char *invalid_sx_check_msg =
+                _("You have attempted to create a Scheduled "
+                  "Transaction which will never run. Do you "
+                  "really want to do this?");
+            if (!gnc_verify_dialog (sxed->dialog, FALSE,
+                                   "%s", invalid_sx_check_msg))
+                return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+
+/******************************************************************************
+ * Saves the contents of the SX.  This assumes that gnc_sxed_check_consistent
+ * has returned true.
+ *****************************************************************************/
+static void
+gnc_sxed_save_sx (GncSxEditorDialog2 *sxed )
+{
+    gnc_sx_begin_edit (sxed->sx);
+
+    /* name */
+    {
+        char *name;
+
+        name = gtk_editable_get_chars (sxed->nameEntry, 0, -1);
+        xaccSchedXactionSetName (sxed->sx, name);
+        g_free (name);
+    }
+
+    /* date */
+    {
+        GDate gdate;
+
+        if (gtk_toggle_button_get_active (sxed->optEndDate))
+        {
+            /* get the end date data */
+            gnc_gdate_set_time64 (&gdate,
+                               gnc_date_edit_get_date (
+                                   sxed->endDateEntry));
+            xaccSchedXactionSetEndDate (sxed->sx, &gdate);
+            /* set the num occurrences data */
+            xaccSchedXactionSetNumOccur (sxed->sx, 0);
+        }
+        else if (gtk_toggle_button_get_active (sxed->optEndCount))
+        {
+            gint num;
+
+            /* get the occurrences data */
+            num  =
+                gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (sxed->endCountSpin));
+            xaccSchedXactionSetNumOccur (sxed->sx, num);
+
+            num =
+                gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (sxed->endRemainSpin));
+            xaccSchedXactionSetRemOccur (sxed->sx, num );
+
+            g_date_clear (&gdate, 1);
+            xaccSchedXactionSetEndDate (sxed->sx, &gdate);
+        }
+        else if (gtk_toggle_button_get_active (sxed->optEndNone))
+        {
+            xaccSchedXactionSetNumOccur (sxed->sx, 0);
+            g_date_clear (&gdate, 1);
+            xaccSchedXactionSetEndDate (sxed->sx, &gdate);
+        }
+        else
+        {
+            g_critical ("no valid end specified\n");
+        }
+    }
+
+    /* Enabled states */
+    {
+        gboolean enabledState;
+
+        enabledState = gtk_toggle_button_get_active (sxed->enabledOpt);
+        xaccSchedXactionSetEnabled (sxed->sx, enabledState);
+    }
+
+    /* Auto-create/notification states */
+    {
+        gboolean autocreateState, notifyState;
+
+        autocreateState = gtk_toggle_button_get_active (sxed->autocreateOpt);
+        notifyState = gtk_toggle_button_get_active (sxed->notifyOpt);
+        /* "Notify" only makes sense if AutoCreate is actived;
+         * enforce that here. */
+        xaccSchedXactionSetAutoCreate (sxed->sx,
+                                       autocreateState,
+                                       (autocreateState & notifyState));
+    }
+
+    /* days in advance */
+    {
+        int daysInAdvance;
+
+        daysInAdvance = 0;
+        if (gtk_toggle_button_get_active (sxed->advanceOpt))
+        {
+            daysInAdvance =
+                gtk_spin_button_get_value_as_int (sxed->advanceSpin);
+        }
+        xaccSchedXactionSetAdvanceCreation (sxed->sx, daysInAdvance);
+
+        daysInAdvance = 0;
+        if (gtk_toggle_button_get_active (sxed->remindOpt))
+        {
+            daysInAdvance =
+                gtk_spin_button_get_value_as_int (sxed->remindSpin);
+        }
+        xaccSchedXactionSetAdvanceReminder (sxed->sx, daysInAdvance);
+    }
+
+    /* start date and freq spec */
+    {
+        GDate gdate;
+        GList *schedule = NULL;
+
+        gnc_frequency_save_to_recurrence (sxed->gncfreq, &schedule, &gdate);
+        gnc_sx_set_schedule (sxed->sx, schedule);
+        {
+            gchar *recurrence_str = recurrenceListToCompactString (schedule);
+            g_debug("recurrences parsed [%s]", recurrence_str);
+            g_free (recurrence_str);
+        }
+
+        /* now that we have it, set the start date */
+        xaccSchedXactionSetStartDate (sxed->sx, &gdate);
+    }
+
+    gnc_sx_commit_edit (sxed->sx);
+}
+
+
+static void
+enabled_toggled_cb (GtkObject *o, GncSxEditorDialog2 *sxed)
+{
+    return;
+}
+
+
+static void
+autocreate_toggled_cb (GtkObject *o, GncSxEditorDialog2 *sxed)
+{
+    if ( !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(o)))
+    {
+        gtk_toggle_button_set_active (sxed->notifyOpt, FALSE);
+    }
+    gtk_widget_set_sensitive (GTK_WIDGET (sxed->notifyOpt),
+                              gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(o)));
+}
+
+
+static void
+advance_toggled_cb (GtkButton *o, GncSxEditorDialog2 *sxed)
+{
+
+    gtk_widget_set_sensitive(GTK_WIDGET (sxed->advanceSpin),
+                              gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sxed->advanceOpt)));
+    gtk_editable_set_editable(GTK_EDITABLE (sxed->advanceSpin), TRUE);
+}
+
+
+static void
+remind_toggled_cb (GtkButton *o, GncSxEditorDialog2 *sxed)
+{
+
+    gtk_widget_set_sensitive (GTK_WIDGET (sxed->remindSpin),
+                              gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sxed->remindOpt)));
+    gtk_editable_set_editable (GTK_EDITABLE (sxed->remindSpin), TRUE);
+}
+
+
+/* Local destruction of dialog */
+static void
+scheduledxaction_editor_dialog_destroy (GtkObject *object, gpointer data)
+{
+    GncSxEditorDialog2 *sxed = data;
+
+    if (sxed == NULL)
+        return;
+
+    gnc_unregister_gui_component_by_data
+    (DIALOG_SCHEDXACTION2_EDITOR_CM_CLASS, sxed);
+
+    gnc_embedded_window_close_page (sxed->embed_window, sxed->plugin_page);
+    gtk_widget_destroy (GTK_WIDGET (sxed->embed_window));
+    sxed->embed_window = NULL;
+    sxed->plugin_page = NULL;
+    sxed->ledger = NULL;
+
+    g_free (sxed->sxGUIDstr);
+    sxed->sxGUIDstr = NULL;
+
+    if ( sxed->newsxP )
+    {
+        /* FIXME: WTF???
+         *
+         * "WTF" explaination: in the "new" click from the caller, we
+         * set this flag.  When "ok" is pressed on the dialog, we set
+         * this flag to false, and thus leave the SX live.  If
+         * "Cancel" is clicked, the flag will still be true, and this
+         * SX will be cleaned, here. -- jsled
+         */
+        gnc_sx_begin_edit (sxed->sx);
+        xaccSchedXactionDestroy (sxed->sx);
+    }
+    sxed->sx = NULL;
+
+    g_free (sxed);
+}
+
+
+static
+gboolean
+sxed_delete_event (GtkWidget *widget, GdkEvent *event, gpointer ud)
+{
+    GncSxEditorDialog2 *sxed = (GncSxEditorDialog2*)ud;
+
+    /* We've already processed the SX, likely because of "ok" being
+     * clicked. */
+    if (sxed->sx == NULL)
+    {
+        return FALSE;
+    }
+
+    if (!sxed_confirmed_cancel (sxed))
+    {
+        return TRUE;
+    }
+    return FALSE;
+}
+
+
+/*************************************
+ * Create the Schedule Editor Dialog *
+ ************************************/
+GncSxEditorDialog2 *
+gnc_ui_scheduled_xaction_editor_dialog_create2 (SchedXaction *sx,
+					       gboolean newSX)
+{
+    GncSxEditorDialog2 *sxed;
+    GtkBuilder *builder;
+    GtkWidget *button;
+    int i;
+    GList *dlgExists = NULL;
+
+    static struct widgetSignalCallback
+    {
+        char     *name;
+        char     *signal;
+        void     (*fn)();
+        gpointer objectData;
+    } widgets[] =
+    {
+        { "ok_button",      "clicked",       editor_ok_button_clicked_cb,     NULL },
+        { "cancel_button",  "clicked",       editor_cancel_button_clicked_cb, NULL },
+        { "help_button",    "clicked",       editor_help_button_clicked_cb,   NULL },
+        { "rb_noend",       "toggled",       endgroup_rb_toggled_cb,          GINT_TO_POINTER(END_NEVER_OPTION) },
+        { "rb_enddate",     "toggled",       endgroup_rb_toggled_cb,          GINT_TO_POINTER(END_DATE_OPTION) },
+        { "rb_num_occur",   "toggled",       endgroup_rb_toggled_cb,          GINT_TO_POINTER(NUM_OCCUR_OPTION) },
+        { "remain_spin" ,   "value-changed", sxed_excal_update_adapt_cb,      NULL },
+        { "enabled_opt",    "toggled",       enabled_toggled_cb,              NULL },
+        { "autocreate_opt", "toggled",       autocreate_toggled_cb,           NULL },
+        { "advance_opt",    "toggled",       advance_toggled_cb,              NULL },
+        { "remind_opt",     "toggled",       remind_toggled_cb,               NULL },
+        { NULL,             NULL,            NULL,                            NULL }
+    };
+
+    dlgExists = gnc_find_gui_components (DIALOG_SCHEDXACTION2_EDITOR_CM_CLASS,
+                                         editor_component_sx_equality,
+                                         sx);
+    if (dlgExists != NULL)
+    {
+        g_debug ("dialog already exists; using that one.");
+        sxed = (GncSxEditorDialog2*)dlgExists->data;
+        gtk_window_present (GTK_WINDOW (sxed->dialog));
+        g_list_free (dlgExists);
+        return sxed;
+    }
+
+    sxed = g_new0 (GncSxEditorDialog2, 1);
+
+    sxed->sx     = sx;
+    sxed->newsxP = newSX;
+
+    /* Load up Glade file */
+    builder = gtk_builder_new();
+    gnc_builder_add_from_file (builder, "dialog-sx.glade", "advance_days_adj");
+    gnc_builder_add_from_file (builder, "dialog-sx.glade", "remind_days_adj");
+    gnc_builder_add_from_file (builder, "dialog-sx.glade", "end_spin_adj");
+    gnc_builder_add_from_file (builder, "dialog-sx.glade", "remain_spin_adj");
+    gnc_builder_add_from_file (builder, "dialog-sx.glade", "Scheduled Transaction Editor");
+
+    sxed->builder = builder;
+
+    /* Connect the Widgets */
+    sxed->dialog = GTK_WIDGET (gtk_builder_get_object (builder, "Scheduled Transaction Editor"));
+    sxed->notebook = GTK_NOTEBOOK (gtk_builder_get_object (builder, "editor_notebook"));
+    sxed->nameEntry = GTK_EDITABLE (gtk_builder_get_object (builder, "sxe_name"));
+    sxed->enabledOpt = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "enabled_opt"));
+    sxed->autocreateOpt = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "autocreate_opt"));
+    sxed->notifyOpt = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "notify_opt"));
+    sxed->advanceOpt = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "advance_opt"));
+    sxed->advanceSpin = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "advance_days"));
+    sxed->remindOpt = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "remind_opt"));
+    sxed->remindSpin = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "remind_days"));
+    sxed->lastOccurLabel = GTK_LABEL (gtk_builder_get_object (builder, "last_occur_label"));
+    sxed->optEndNone = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "rb_noend"));
+    sxed->optEndDate = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "rb_enddate"));
+    sxed->optEndCount = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "rb_num_occur"));
+    sxed->endCountSpin = GTK_ENTRY (gtk_builder_get_object (builder, "end_spin"));
+    sxed->endRemainSpin = GTK_ENTRY (gtk_builder_get_object (builder, "remain_spin"));
+
+    /* Setup the end-date GNC widget */
+    {
+        GtkWidget *endDateBox = GTK_WIDGET (gtk_builder_get_object (builder, "end_date_hbox"));
+        sxed->endDateEntry = GNC_DATE_EDIT (gnc_date_edit_new (gnc_time (NULL),
+							      FALSE, FALSE));
+        gtk_widget_show (GTK_WIDGET (sxed->endDateEntry));
+        g_signal_connect (sxed->endDateEntry, "date-changed",
+                          G_CALLBACK (sxed_excal_update_adapt_cb), sxed);
+        gtk_box_pack_start (GTK_BOX (endDateBox), GTK_WIDGET (sxed->endDateEntry),
+                            TRUE, TRUE, 0 );
+    }
+
+    gnc_register_gui_component (DIALOG_SCHEDXACTION2_EDITOR_CM_CLASS,
+                                NULL, /* no refresh handler */
+                                sxed_close_handler,
+                                sxed);
+
+    g_signal_connect (sxed->dialog, "delete_event",
+                      G_CALLBACK (sxed_delete_event), sxed);
+    g_signal_connect (sxed->dialog, "destroy",
+                      G_CALLBACK (scheduledxaction_editor_dialog_destroy),
+                      sxed );
+
+    for (i = 0; widgets[i].name != NULL; i++)
+    {
+        button = GTK_WIDGET (gtk_builder_get_object (builder, widgets[i].name));
+        if (widgets[i].objectData != NULL)
+        {
+            g_object_set_data (G_OBJECT (button), "whichOneAmI",
+                               widgets[i].objectData);
+        }
+        g_signal_connect (button, widgets[i].signal,
+                          G_CALLBACK (widgets[i].fn ), sxed);
+    }
+
+    /* Set sensitivity settings  */
+    gtk_widget_set_sensitive (GTK_WIDGET (sxed->notifyOpt), FALSE );
+    gtk_widget_set_sensitive (GTK_WIDGET (sxed->advanceSpin), FALSE );
+    gtk_widget_set_sensitive (GTK_WIDGET (sxed->remindSpin), FALSE );
+    gtk_widget_set_sensitive (GTK_WIDGET (sxed->endCountSpin), FALSE );
+    gtk_widget_set_sensitive (GTK_WIDGET (sxed->endRemainSpin), FALSE );
+    gtk_editable_set_editable (GTK_EDITABLE (sxed->advanceSpin), TRUE );
+    gtk_editable_set_editable (GTK_EDITABLE (sxed->remindSpin), TRUE );
+
+    /* Allow resize */
+    gtk_window_set_resizable (GTK_WINDOW (sxed->dialog), TRUE);
+    gnc_restore_window_size (SXED_GCONF_SECTION, GTK_WINDOW (sxed->dialog));
+
+    /* create the frequency-selection widget and example [dense-]calendar. */
+    schedXact_editor_create_freq_sel (sxed);
+
+    /* create the template-transaction ledger window */
+    schedXact_editor_create_ledger (sxed);
+
+    /* populate */
+    schedXact_editor_populate (sxed);
+
+    /* Do not call show_all here. Screws up the gtkuimanager code */
+    gtk_widget_show (sxed->dialog);
+    gtk_notebook_set_current_page (GTK_NOTEBOOK (sxed->notebook), 0);
+
+    /* Refresh the cal and the ledger */
+    gtk_widget_queue_resize (GTK_WIDGET (sxed->example_cal));
+
+    gnc_ledger_display2_refresh (sxed->ledger);
+
+    /* Move keyboard focus to the name entry */
+    gtk_widget_grab_focus (GTK_WIDGET (sxed->nameEntry));
+
+    gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, sxed);
+    g_object_unref (G_OBJECT (builder));
+
+    return sxed;
+}
+
+
+static
+void
+gnc_sxed_record_size (GncSxEditorDialog2 *sxed)
+{
+    gnc_save_window_size (SXED_GCONF_SECTION, GTK_WINDOW (sxed->dialog));
+}
+
+
+static
+void
+schedXact_editor_create_freq_sel (GncSxEditorDialog2 *sxed)
+{
+    GtkBox *b;
+
+    b = GTK_BOX (gtk_builder_get_object (sxed->builder, "gncfreq_hbox"));
+
+    sxed->gncfreq =
+        GNC_FREQUENCY (gnc_frequency_new_from_recurrence (gnc_sx_get_schedule (sxed->sx),
+                      xaccSchedXactionGetStartDate (sxed->sx)));
+    g_assert (sxed->gncfreq);
+    g_signal_connect (sxed->gncfreq, "changed",
+                      G_CALLBACK (gnc_sxed_freq_changed),
+                      sxed );
+    gtk_container_add (GTK_CONTAINER (b), GTK_WIDGET (sxed->gncfreq) );
+
+    b = GTK_BOX(gtk_builder_get_object (sxed->builder, "example_cal_hbox" ));
+    sxed->dense_cal_model = gnc_dense_cal_store_new (EX_CAL_NUM_MONTHS * 31);
+    sxed->example_cal = GNC_DENSE_CAL (gnc_dense_cal_new_with_model (GNC_DENSE_CAL_MODEL (sxed->dense_cal_model)));
+    g_assert (sxed->example_cal);
+    gnc_dense_cal_set_num_months (sxed->example_cal, EX_CAL_NUM_MONTHS);
+    gnc_dense_cal_set_months_per_col( sxed->example_cal, EX_CAL_MO_PER_COL);
+    gtk_container_add (GTK_CONTAINER (b), GTK_WIDGET (sxed->example_cal));
+    gtk_widget_show (GTK_WIDGET (sxed->example_cal));
+}
+
+
+static
+void
+schedXact_editor_create_ledger (GncSxEditorDialog2 *sxed)
+{
+    GncTreeModelSplitReg *model;
+    GtkWidget *main_vbox;
+    GtkWidget *label;
+
+    /* Create the ledger */
+    /* THREAD-UNSAFE */
+    sxed->sxGUIDstr = g_strdup (guid_to_string (xaccSchedXactionGetGUID (sxed->sx)));
+    sxed->ledger = gnc_ledger_display2_template_gl (sxed->sxGUIDstr);
+    model = gnc_ledger_display2_get_split_model_register (sxed->ledger);
+
+    /* First the embedded window */
+    main_vbox = GTK_WIDGET (gtk_builder_get_object (sxed->builder, "register_vbox" ));
+    sxed->embed_window =
+        gnc_embedded_window_new ("SXWindowActions",
+                                gnc_sxed_menu_entries,
+                                gnc_sxed_menu_n_entries,
+                                "gnc-sxed-window-ui.xml",
+                                sxed->dialog,
+                                FALSE, /* no accelerators */
+                                sxed);
+
+    gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (sxed->embed_window), TRUE, TRUE, 0);
+
+    label = gtk_label_new (_("Note: If you have already accepted changes to the Template, Cancel will not revoke them."));
+    gtk_box_pack_end (GTK_BOX (main_vbox), GTK_WIDGET (label), FALSE, TRUE, 0);
+    gtk_widget_show (label);
+
+    /* Now create the register plugin page. */
+    sxed->plugin_page = gnc_plugin_page_register2_new_ledger (sxed->ledger);
+    gnc_plugin_page_set_ui_description (sxed->plugin_page,
+                                        "gnc-sxed-window-ui-full.xml");
+    gnc_plugin_page_register2_set_options (sxed->plugin_page,
+                                          NUM_LEDGER_LINES_DEFAULT, FALSE );
+
+    gnc_embedded_window_open_page (sxed->embed_window, sxed->plugin_page);
+
+    /* configure... */
+    /* use double-line, so scheduled transaction Notes can be edited */
+    gnc_tree_model_split_reg_config (model, model->type, model->style, TRUE);
+}
+
+
+
+static
+void
+schedXact_editor_populate (GncSxEditorDialog2 *sxed)
+{
+    char *name;
+    time64 tmpDate;
+    GncTreeModelSplitReg *model;
+    struct tm *tmpTm;
+    const GDate *gd;
+    gint daysInAdvance;
+    gboolean enabledState, autoCreateState, notifyState;
+
+    name = xaccSchedXactionGetName (sxed->sx);
+    if (name != NULL)
+    {
+        gtk_entry_set_text (GTK_ENTRY (sxed->nameEntry), name);
+    }
+    {
+        gd = xaccSchedXactionGetLastOccurDate (sxed->sx);
+        if (g_date_valid (gd))
+        {
+            gchar dateBuf[ MAX_DATE_LENGTH+1 ];
+            qof_print_gdate (dateBuf, MAX_DATE_LENGTH, gd);
+            gtk_label_set_text (sxed->lastOccurLabel, dateBuf);
+        }
+        else
+        {
+            gtk_label_set_text (sxed->lastOccurLabel, _("(never)"));
+        }
+        gd = NULL;
+    }
+
+    gd = xaccSchedXactionGetEndDate (sxed->sx);
+    if ( g_date_valid (gd))
+    {
+        gtk_toggle_button_set_active (sxed->optEndDate, TRUE);
+        tmpDate = gnc_time64_get_day_start_gdate (gd);
+        gnc_date_edit_set_time (sxed->endDateEntry, tmpDate);
+
+        set_endgroup_toggle_states (sxed, END_DATE);
+    }
+    else if (xaccSchedXactionHasOccurDef (sxed->sx))
+    {
+        gint numOccur = xaccSchedXactionGetNumOccur (sxed->sx);
+        gint numRemain = xaccSchedXactionGetRemOccur (sxed->sx);
+
+        gtk_toggle_button_set_active (sxed->optEndCount, TRUE);
+
+        gtk_spin_button_set_value (GTK_SPIN_BUTTON (sxed->endCountSpin), numOccur);
+        gtk_spin_button_set_value (GTK_SPIN_BUTTON (sxed->endRemainSpin), numRemain);
+
+        set_endgroup_toggle_states (sxed, END_OCCUR);
+    }
+    else
+    {
+        gtk_toggle_button_set_active (sxed->optEndNone, TRUE);
+        set_endgroup_toggle_states (sxed, END_NEVER);
+    }
+
+    enabledState = xaccSchedXactionGetEnabled (sxed->sx);
+    gtk_toggle_button_set_active (sxed->enabledOpt, enabledState);
+
+    /* Do auto-create/notify setup */
+    if (sxed->newsxP)
+    {
+        autoCreateState =
+            gnc_gconf_get_bool (SXED_GCONF_SECTION, KEY_CREATE_AUTO, NULL);
+        notifyState =
+            gnc_gconf_get_bool (SXED_GCONF_SECTION, KEY_NOTIFY, NULL);
+    }
+    else
+    {
+        xaccSchedXactionGetAutoCreate (sxed->sx,
+                                       &autoCreateState,
+                                       &notifyState);
+    }
+    gtk_toggle_button_set_active (sxed->autocreateOpt, autoCreateState);
+    if (!autoCreateState)
+    {
+        notifyState = FALSE;
+    }
+    gtk_toggle_button_set_active( sxed->notifyOpt, notifyState );
+
+    /* Do days-in-advance-to-create widget[s] setup. */
+    if ( sxed->newsxP )
+    {
+        daysInAdvance =
+            gnc_gconf_get_float (SXED_GCONF_SECTION, KEY_CREATE_DAYS, NULL);
+    }
+    else
+    {
+        daysInAdvance =
+            xaccSchedXactionGetAdvanceCreation (sxed->sx);
+    }
+    if (daysInAdvance != 0)
+    {
+        gtk_toggle_button_set_active (sxed->advanceOpt, TRUE);
+        gtk_spin_button_set_value (sxed->advanceSpin,
+                                   (gfloat)daysInAdvance);
+    }
+
+    /* Do days-in-advance-to-remind widget[s] setup. */
+    if (sxed->newsxP)
+    {
+        daysInAdvance =
+            gnc_gconf_get_float (SXED_GCONF_SECTION, KEY_REMIND_DAYS, NULL);
+    }
+    else
+    {
+        daysInAdvance =
+            xaccSchedXactionGetAdvanceReminder (sxed->sx);
+    }
+    if (daysInAdvance != 0)
+    {
+        gtk_toggle_button_set_active (sxed->remindOpt, TRUE);
+        gtk_spin_button_set_value (sxed->remindSpin,
+                                   (gfloat)daysInAdvance);
+    }
+
+    if (sxed->newsxP)
+    {
+        gnc_sx_set_instance_count (sxed->sx, 1);
+    }
+
+    /* populate the ledger */
+    {
+        /* create the split list */
+        GList        *splitList;
+
+        splitList = xaccSchedXactionGetSplits (sxed->sx);
+        if (splitList != NULL)
+        {
+            model = gnc_ledger_display2_get_split_model_register (sxed->ledger);
+            gnc_tree_model_split_reg_load (model, splitList, NULL );
+        } /* otherwise, use the existing stuff. */
+    }
+
+    /* Update the example cal */
+    gnc_sxed_update_cal (sxed);
+}
+
+
+static
+void
+set_endgroup_toggle_states (GncSxEditorDialog2 *sxed, EndType type)
+{
+    gtk_widget_set_sensitive (GTK_WIDGET (sxed->endDateEntry), (type == END_DATE) );
+    gtk_widget_set_sensitive (GTK_WIDGET (sxed->endCountSpin), (type == END_OCCUR) );
+    gtk_widget_set_sensitive (GTK_WIDGET (sxed->endRemainSpin), (type == END_OCCUR) );
+}
+
+
+static
+void
+endgroup_rb_toggled_cb (GtkButton *b, gpointer d)
+{
+    /* figure out which one */
+    GncSxEditorDialog2 *sxed;
+    gint id;
+
+    sxed = (GncSxEditorDialog2*)d;
+    id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "whichOneAmI"));
+
+    switch (id)
+    {
+    case END_NEVER_OPTION:
+        set_endgroup_toggle_states (sxed, END_NEVER);
+        break;
+    case END_DATE_OPTION:
+        set_endgroup_toggle_states (sxed, END_DATE);
+        break;
+    case NUM_OCCUR_OPTION:
+        set_endgroup_toggle_states (sxed, END_OCCUR);
+        break;
+    default:
+        g_critical ("Unknown id %d", id);
+        break;
+    }
+    gnc_sxed_update_cal (sxed);
+}
+
+
+/********************************************************************\
+ * gnc_register_check_close                                         *
+ *                                                                  *
+ * Args:   regData - the data struct for this register              *
+ * Return: none                                                     *
+\********************************************************************/
+static void
+gnc_sxed_reg_check_close (GncSxEditorDialog2 *sxed)
+{
+    GncTreeViewSplitReg *view;
+    Transaction *dirty_trans;
+
+    const char *message =
+        _("The current template transaction "
+          "has been changed. "
+          "Would you like to record the changes?");
+
+    view = gnc_ledger_display2_get_split_view_register (sxed->ledger);
+
+    dirty_trans = gnc_tree_view_split_reg_get_dirty_trans (view);
+
+    if (dirty_trans == NULL)
+        return;
+
+    if (gnc_verify_dialog (sxed->dialog, TRUE, "%s", message))
+    {
+        /* Save the template transactions changes */
+        xaccTransCommitEdit (dirty_trans);
+        gnc_tree_view_split_reg_set_dirty_trans (view, NULL);
+        return;
+    }
+    else
+    {
+        /* Cancel the template transactions changes */
+        gnc_tree_view_split_reg_cancel_edit (view, TRUE);
+    }
+}
+
+
+static gboolean
+editor_component_sx_equality (gpointer find_data,
+                              gpointer user_data)
+{
+    return ((SchedXaction*)find_data
+             == ((GncSxEditorDialog2*)user_data)->sx);
+}
+/*
+typedef enum { NO_END, DATE_END, COUNT_END } END_TYPE;
+*/
+
+static void
+gnc_sxed_update_cal (GncSxEditorDialog2 *sxed)
+{
+    GList *recurrences = NULL;
+    GDate start_date, first_date;
+
+    g_date_clear (&start_date, 1);
+
+    gnc_frequency_save_to_recurrence (sxed->gncfreq, &recurrences, &start_date);
+    g_date_subtract_days (&start_date, 1);
+    recurrenceListNextInstance (recurrences, &start_date, &first_date);
+
+    /* Deal with the fact that this SX may have been run before [the
+     * calendar should only show upcoming instances]... */
+    {
+        const GDate *last_sx_inst;
+
+        last_sx_inst = xaccSchedXactionGetLastOccurDate (sxed->sx);
+        if (g_date_valid (last_sx_inst)
+                && g_date_valid (&first_date)
+                && g_date_compare (last_sx_inst, &first_date) != 0)
+        {
+            start_date = *last_sx_inst;
+            recurrenceListNextInstance (recurrences, &start_date, &first_date);
+        }
+    }
+
+    if (!g_date_valid (&first_date))
+    {
+        /* Nothing to do. */
+        gnc_dense_cal_store_clear (sxed->dense_cal_model);
+        goto cleanup;
+    }
+
+    gnc_dense_cal_store_update_name (sxed->dense_cal_model, xaccSchedXactionGetName (sxed->sx));
+    {
+        gchar *schedule_desc = recurrenceListToCompactString (recurrences);
+        gnc_dense_cal_store_update_info (sxed->dense_cal_model, schedule_desc);
+        g_free (schedule_desc);
+    }
+
+    //gnc_dense_cal_set_month(sxed->example_cal, g_date_get_month(&first_date));
+    //gnc_dense_cal_set_year(sxed->example_cal, g_date_get_year(&first_date));
+
+    /* figure out the end restriction */
+    if (gtk_toggle_button_get_active (sxed->optEndDate))
+    {
+        GDate end_date;
+        g_date_clear (&end_date, 1);
+        gnc_gdate_set_time64 (&end_date, gnc_date_edit_get_date (sxed->endDateEntry));
+        gnc_dense_cal_store_update_recurrences_date_end (sxed->dense_cal_model, &first_date, recurrences, &end_date);
+    }
+    else if (gtk_toggle_button_get_active (sxed->optEndNone))
+    {
+        gnc_dense_cal_store_update_recurrences_no_end (sxed->dense_cal_model, &first_date, recurrences);
+    }
+    else if (gtk_toggle_button_get_active (sxed->optEndCount))
+    {
+        gint num_remain
+        = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (sxed->endRemainSpin));
+        gnc_dense_cal_store_update_recurrences_count_end (sxed->dense_cal_model, &first_date, recurrences, num_remain);
+    }
+    else
+    {
+        g_error ("unknown end condition");
+    }
+
+cleanup:
+    recurrenceListFree (&recurrences);
+}
+
+
+static void
+gnc_sxed_freq_changed (GncFrequency *gf, gpointer ud)
+{
+    gnc_sxed_update_cal ((GncSxEditorDialog2*)ud);
+}
+
+
+static void
+sxed_excal_update_adapt_cb (GtkObject *o, gpointer ud)
+{
+    gnc_sxed_update_cal ((GncSxEditorDialog2*)ud);
+}
+
+
+static void
+on_sx_check_toggled_cb (GtkWidget *togglebutton,
+                        gpointer user_data)
+{
+    GtkWidget *widget_create, *widget_notify;
+    gboolean active; // , notify;
+    GHashTable *table;
+
+    PINFO("Togglebutton is %p and user_data is %p", togglebutton, user_data);
+    PINFO("Togglebutton builder name is %s", gtk_buildable_get_name (GTK_BUILDABLE (togglebutton)));
+
+    /* We need to use the hash table to find the required widget to activate. */
+    table = g_object_get_data (G_OBJECT (user_data), "widget_hash");
+    widget_create = g_hash_table_lookup (table, "gconf/dialogs/scheduled_trans/transaction_editor/create_auto");
+    widget_notify = g_hash_table_lookup (table, "gconf/dialogs/scheduled_trans/transaction_editor/notify");
+
+    active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget_create));
+    if (active)
+        gtk_widget_set_sensitive (widget_notify, TRUE);
+    else
+        gtk_widget_set_sensitive (widget_notify, FALSE);
+}
+
+
+/* ------------------------------------------------------------ */
+/* sx app engine;  move to somewhere appropriate. :/            */
+
+typedef struct _acct_deletion_handler_data
+{
+    GList *affected_sxes;
+    GtkWidget *dialog;
+} acct_deletion_handler_data;
+
+
+static void
+_open_editors (GtkDialog *dialog, gint response_code, gpointer data)
+{
+    acct_deletion_handler_data *adhd = (acct_deletion_handler_data *)data;
+    gtk_widget_hide (adhd->dialog);
+    {
+        GList *sx_iter;
+        for (sx_iter = adhd->affected_sxes; sx_iter; sx_iter = sx_iter->next)
+        {
+            gnc_ui_scheduled_xaction_editor_dialog_create2 ((SchedXaction*)sx_iter->data,
+                    FALSE);
+        }
+    }
+    g_list_free (adhd->affected_sxes);
+    gtk_widget_destroy (GTK_WIDGET (adhd->dialog));
+    g_free (adhd);
+}
+
+
+static void
+_sx_engine_event_handler (QofInstance *ent, QofEventId event_type, gpointer user_data, gpointer evt_data)
+{
+    Account *acct;
+    QofBook *book;
+    GList *affected_sxes;
+
+    if (!(event_type & QOF_EVENT_DESTROY))
+        return;
+    if (!GNC_IS_ACCOUNT(ent))
+        return;
+    acct = GNC_ACCOUNT(ent);
+    book = qof_instance_get_book (QOF_INSTANCE (acct));
+    affected_sxes = gnc_sx_get_sxes_referencing_account (book, acct);
+
+    if (g_list_length (affected_sxes) == 0)
+        return;
+
+    {
+        GList *sx_iter;
+        acct_deletion_handler_data *data;
+        GtkBuilder *builder;
+        GtkWidget *dialog;
+        GtkListStore *name_list;
+        GtkTreeView *list;
+        GtkTreeViewColumn *name_column;
+        GtkCellRenderer *renderer;
+
+        builder = gtk_builder_new();
+        gnc_builder_add_from_file (builder, "dialog-sx.glade", "Account Deletion");
+
+        dialog = GTK_WIDGET (gtk_builder_get_object (builder, "Account Deletion"));
+
+        list = GTK_TREE_VIEW (gtk_builder_get_object (builder, "sx_list"));
+
+        data = (acct_deletion_handler_data*)g_new0 (acct_deletion_handler_data, 1);
+        data->dialog = dialog;
+        data->affected_sxes = affected_sxes;
+        name_list = gtk_list_store_new (1, G_TYPE_STRING);
+        for (sx_iter = affected_sxes; sx_iter != NULL; sx_iter = sx_iter->next)
+        {
+            SchedXaction *sx;
+            GtkTreeIter iter;
+            gchar *sx_name;
+
+            sx = (SchedXaction*)sx_iter->data;
+            sx_name = xaccSchedXactionGetName (sx);
+            gtk_list_store_append (name_list, &iter);
+            gtk_list_store_set (name_list, &iter, 0, sx_name, -1);
+        }
+        gtk_tree_view_set_model (list, GTK_TREE_MODEL (name_list));
+        g_object_unref (G_OBJECT (name_list));
+
+        renderer = gtk_cell_renderer_text_new();
+        name_column = gtk_tree_view_column_new_with_attributes (_("Name"),
+                      renderer,
+                      "text", 0, NULL);
+        gtk_tree_view_append_column (list, name_column);
+
+        g_signal_connect (G_OBJECT (dialog), "response",
+                         G_CALLBACK (_open_editors), data);
+
+        gtk_widget_show_all (GTK_WIDGET (dialog));
+        gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, data);
+        g_object_unref (G_OBJECT (builder));
+    }
+}
+
+
+void
+gnc_ui_sx_initialize2 (void) //FIXME need to remove the 2 when live
+{
+    _sx_engine_event_handler_id = qof_event_register_handler (_sx_engine_event_handler, NULL);
+
+    gnc_hook_add_dangler (HOOK_BOOK_OPENED,
+                         (GFunc)gnc_sx_sxsincelast_book_opened, NULL);
+
+    /* Add page to preferences page for Sheduled Transactions */
+    /* The parameters are; glade file, items to add from glade file - last being the dialog, preference tab name */
+    gnc_preferences_add_page ("dialog-sx.glade",
+                              "create_days_adj,remind_days_adj,sx_prefs",
+                              _("Scheduled Transactions"));
+}

Added: gnucash/trunk/src/gnome/dialog-sx-editor2.h
===================================================================
--- gnucash/trunk/src/gnome/dialog-sx-editor2.h	                        (rev 0)
+++ gnucash/trunk/src/gnome/dialog-sx-editor2.h	2013-05-02 14:41:56 UTC (rev 22931)
@@ -0,0 +1,50 @@
+/********************************************************************\
+ * dialog-sx-editor2.h : dialog for scheduled transaction editing    *
+ * Copyright (C) 2001,2006 Joshua Sled <jsled at asynchronous.org>     *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of version 2 and/or version 3 of the   *
+ * GNU General Public License as published by the Free Software     *
+ * Foundation.                                                      *
+ *                                                                  *
+ * 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 DIALOG_SX_EDITOR2_H
+#define DIALOG_SX_EDITOR2_H
+
+#include "SchedXaction.h"
+
+#define DIALOG_SCHEDXACTION2_CM_CLASS "dialog-scheduledtransactions"
+#define DIALOG_SCHEDXACTION2_EDITOR_CM_CLASS "dialog-scheduledtransaction-editor"
+
+#define SXED_GCONF_SECTION "dialogs/scheduled_trans/transaction_editor"
+#define KEY_CREATE_AUTO "create_auto"
+#define KEY_NOTIFY "notify"
+#define KEY_CREATE_DAYS	"create_days"
+#define KEY_REMIND_DAYS	"remind_days"
+
+typedef struct _GncSxEditorDialog2 GncSxEditorDialog2;
+
+GncSxEditorDialog2* gnc_ui_scheduled_xaction_editor_dialog_create2 (SchedXaction *sx,
+        gboolean newSX);
+
+void gnc_ui_scheduled_xaction_editor_dialog_destroy2 (GncSxEditorDialog2 *sxd);
+
+/**
+ * Sets up a book opened hook.  The function called may open a "since
+ * last run" dialog based upon the user's preferences.
+ **/
+void gnc_ui_sx_initialize2 (void);
+
+#endif

Modified: gnucash/trunk/src/gnome/dialog-sx-since-last-run.c
===================================================================
--- gnucash/trunk/src/gnome/dialog-sx-since-last-run.c	2013-04-24 09:10:29 UTC (rev 22930)
+++ gnucash/trunk/src/gnome/dialog-sx-since-last-run.c	2013-05-02 14:41:56 UTC (rev 22931)
@@ -44,8 +44,10 @@
 #include "gnc-ui-util.h"
 #include "Query.h"
 #include "qof.h"
-#include "gnc-ledger-display.h"
-#include "gnc-plugin-page-register.h"
+/*################## Added for Reg2 #################*/
+#include "gnc-ledger-display2.h"
+#include "gnc-plugin-page-register2.h"
+/*################## Added for Reg2 #################*/
 #include "gnc-main-window.h"
 #include "gnc-component-manager.h"
 #include "gnc-gconf-utils.h"
@@ -1004,7 +1006,7 @@
 static void
 _show_created_transactions(GncSxSinceLastRunDialog *app_dialog, GList *created_txn_guids)
 {
-    GNCLedgerDisplay *ledger;
+    GNCLedgerDisplay2 *ledger;
     GncPluginPage *page;
     Query *book_query, *guid_query, *query;
     GList *guid_iter;
@@ -1017,11 +1019,12 @@
         xaccQueryAddGUIDMatch(guid_query, (GncGUID*)guid_iter->data, GNC_ID_TRANS, QOF_QUERY_OR);
     }
     query = qof_query_merge(book_query, guid_query, QOF_QUERY_AND);
-
+/*################## Added for Reg2 #################*/
     // inspired by dialog-find-transactions:do_find_cb:
-    ledger = gnc_ledger_display_query(query, SEARCH_LEDGER, REG_STYLE_JOURNAL);
-    gnc_ledger_display_refresh(ledger);
-    page = gnc_plugin_page_register_new_ledger(ledger);
+    ledger = gnc_ledger_display2_query(query, SEARCH_LEDGER2, REG2_STYLE_JOURNAL);
+    gnc_ledger_display2_refresh(ledger);
+    page = gnc_plugin_page_register2_new_ledger(ledger);
+/*################## Added for Reg2 #################*/
     g_object_set(G_OBJECT(page), "page-name", _("Created Transactions"), NULL);
     gnc_main_window_open_page(NULL, page);
 

Modified: gnucash/trunk/src/gnome/gnc-plugin-page-register2.c
===================================================================
--- gnucash/trunk/src/gnome/gnc-plugin-page-register2.c	2013-04-24 09:10:29 UTC (rev 22930)
+++ gnucash/trunk/src/gnome/gnc-plugin-page-register2.c	2013-05-02 14:41:56 UTC (rev 22931)
@@ -61,6 +61,9 @@
 #include "dialog-utils.h"
 #include "SX-book.h"
 #include "dialog-sx-editor.h"
+/*################## Added for Reg2 #################*/
+#include "dialog-sx-editor2.h"
+/*################## Added for Reg2 #################*/
 #include "dialog-sx-from-trans.h"
 #include "assistant-stock-split.h"
 #include "gnc-gconf-utils.h"
@@ -79,7 +82,6 @@
 #include "gnc-window.h"
 #include "gnc-main-window.h"
 #include "gnc-session.h"
-#include "gnucash-sheet.h"
 #include "dialog-lot-viewer.h"
 #include "Scrub.h"
 #include "qof.h"
@@ -1120,12 +1122,10 @@
         gnc_ppr_update_date_filter (page, FALSE);
     }
 
-//    gnc_ledger_display2_refresh (priv->ledger);
+    /* This sets the default selection on load, not required for templates */
+    if (!gnc_tree_model_split_reg_get_template (model))
+       gnc_tree_view_split_reg_default_selection (view);
 
-    /* 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)
     {
@@ -3059,7 +3059,7 @@
 
     ENTER("(action %p, plugin_page %p)", action, plugin_page);
 
-    g_return_if_fail (GTK_IS_ACTION(action));
+    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);
@@ -3074,6 +3074,10 @@
 
         // This will re-display the view.
         gnc_tree_view_split_reg_set_format (view);
+
+        // This will update the row colors in anything but ledgers
+        if (model->style != REG2_STYLE_LEDGER)
+            gnc_tree_view_split_reg_change_vis_rows (view);
     }
     LEAVE(" ");
 }
@@ -3506,7 +3510,7 @@
 
                 if (theSX)
                 {
-                    gnc_ui_scheduled_xaction_editor_dialog_create (theSX, FALSE);
+                    gnc_ui_scheduled_xaction_editor_dialog_create2 (theSX, FALSE);
                     LEAVE(" ");
                     return;
                 }

Modified: gnucash/trunk/src/gnome/gnc-plugin-page-sx-list.c
===================================================================
--- gnucash/trunk/src/gnome/gnc-plugin-page-sx-list.c	2013-04-24 09:10:29 UTC (rev 22930)
+++ gnucash/trunk/src/gnome/gnc-plugin-page-sx-list.c	2013-05-02 14:41:56 UTC (rev 22931)
@@ -52,6 +52,9 @@
 #include "Split.h"
 #include "Transaction.h"
 #include "dialog-sx-editor.h"
+/*################## Added for Reg2 #################*/
+#include "dialog-sx-editor2.h"
+/*################## Added for Reg2 #################*/
 #include "dialog-utils.h"
 #include "gnc-commodity.h"
 #include "gnc-component-manager.h"
@@ -116,6 +119,10 @@
 
 static void gnc_plugin_page_sx_list_cmd_new(GtkAction *action, GncPluginPageSxList *page);
 static void gnc_plugin_page_sx_list_cmd_edit(GtkAction *action, GncPluginPageSxList *page);
+/*################## Added for Reg2 #################*/
+static void gnc_plugin_page_sx_list_cmd_new2(GtkAction *action, GncPluginPageSxList *page);
+static void gnc_plugin_page_sx_list_cmd_edit2(GtkAction *action, GncPluginPageSxList *page);
+/*################## Added for Reg2 #################*/
 static void gnc_plugin_page_sx_list_cmd_delete(GtkAction *action, GncPluginPageSxList *page);
 
 /* Command callbacks */
@@ -126,11 +133,23 @@
         "SxListNewAction", GNC_STOCK_NEW_ACCOUNT, N_("_New"), NULL,
         N_("Create a new scheduled transaction"), G_CALLBACK(gnc_plugin_page_sx_list_cmd_new)
     },
+/*################## Added for Reg2 #################*/
     {
+        "SxListNewAction2", GNC_STOCK_NEW_ACCOUNT, N_("_New 2"), NULL,
+        N_("Create a new scheduled transaction 2"), G_CALLBACK(gnc_plugin_page_sx_list_cmd_new2)
+    },
+/*################## Added for Reg2 #################*/
+    {
         "SxListEditAction", GNC_STOCK_EDIT_ACCOUNT, N_("_Edit"), NULL,
         N_("Edit the selected scheduled transaction"), G_CALLBACK(gnc_plugin_page_sx_list_cmd_edit)
     },
+/*################## Added for Reg2 #################*/
     {
+        "SxListEditAction2", GNC_STOCK_EDIT_ACCOUNT, N_("_Edit 2"), NULL,
+        N_("Edit the selected scheduled transaction 2"), G_CALLBACK(gnc_plugin_page_sx_list_cmd_edit2)
+    },
+/*################## Added for Reg2 #################*/
+    {
         "SxListDeleteAction", GNC_STOCK_DELETE_ACCOUNT, N_("_Delete"), NULL,
         N_("Delete the selected scheduled transaction"), G_CALLBACK(gnc_plugin_page_sx_list_cmd_delete)
     },
@@ -562,13 +581,43 @@
     gnc_ui_scheduled_xaction_editor_dialog_create(new_sx, new_sx_flag);
 }
 
+/*################## Added for Reg2 #################*/
+static void
+gnc_plugin_page_sx_list_cmd_new2 (GtkAction *action, GncPluginPageSxList *page)
+{
+    SchedXaction *new_sx;
+    gboolean new_sx_flag = TRUE;
 
+    new_sx = xaccSchedXactionMalloc (gnc_get_current_book());
+    {
+        GDate now;
+        Recurrence *r = g_new0 (Recurrence, 1);
+        GList *schedule;
+
+        g_date_clear (&now, 1);
+        gnc_gdate_set_today (&now);
+        recurrenceSet(r, 1, PERIOD_MONTH, &now, WEEKEND_ADJ_NONE);
+        schedule = gnc_sx_get_schedule (new_sx);
+        schedule = g_list_append (schedule, r);
+        gnc_sx_set_schedule (new_sx, schedule);
+    }
+    gnc_ui_scheduled_xaction_editor_dialog_create2 (new_sx, new_sx_flag);
+}
+/*################## Added for Reg2 #################*/
+
 static void
 _edit_sx(gpointer data, gpointer user_data)
 {
     gnc_ui_scheduled_xaction_editor_dialog_create((SchedXaction*)data, FALSE);
 }
 
+/*################## Added for Reg2 #################*/
+static void
+_edit_sx2 (gpointer data, gpointer user_data)
+{
+    gnc_ui_scheduled_xaction_editor_dialog_create2 ((SchedXaction*)data, FALSE);
+}
+/*################## Added for Reg2 #################*/
 
 static SchedXaction*
 _argument_reorder_fn(GtkTreePath* list_path_data, GncTreeViewSxList* user_tree_view)
@@ -602,7 +651,34 @@
     g_list_free(selected_paths);
 }
 
+/*################## Added for Reg2 #################*/
+static void
+gnc_plugin_page_sx_list_cmd_edit2 (GtkAction *action, GncPluginPageSxList *page)
+{
+    GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE (page);
+    GtkTreeSelection *selection;
+    GList *selected_paths, *to_edit;
+    GtkTreeModel *model;
 
+    selection = gtk_tree_view_get_selection (priv->tree_view);
+    selected_paths = gtk_tree_selection_get_selected_rows (selection, &model);
+    if (g_list_length (selected_paths) == 0)
+    {
+        g_warning ("no selection edit.");
+        return;
+    }
+
+    to_edit = gnc_g_list_map (selected_paths,
+                             (GncGMapFunc)_argument_reorder_fn,
+                             priv->tree_view);
+    g_list_foreach(to_edit, (GFunc)_edit_sx2, NULL);
+    g_list_free (to_edit);
+    g_list_foreach (selected_paths, (GFunc)gtk_tree_path_free, NULL);
+    g_list_free (selected_paths);
+}
+/*################## Added for Reg2 #################*/
+
+
 static void
 gppsl_row_activated_cb(GtkTreeView *tree_view,
                        GtkTreePath *path,

Modified: gnucash/trunk/src/gnome/gnc-split-reg2.c
===================================================================
--- gnucash/trunk/src/gnome/gnc-split-reg2.c	2013-04-24 09:10:29 UTC (rev 22930)
+++ gnucash/trunk/src/gnome/gnc-split-reg2.c	2013-05-02 14:41:56 UTC (rev 22931)
@@ -281,7 +281,7 @@
 
     gnc_tree_view_configure_columns (GNC_TREE_VIEW (view));
 
-    if (ledger_type == LD2_GL)
+    if (ledger_type == LD2_GL && model->type == GENERAL_LEDGER2)
         gnc_tree_view_set_show_column_menu (GNC_TREE_VIEW (view), TRUE);
     else
         gnc_tree_view_set_show_column_menu (GNC_TREE_VIEW (view), FALSE);

Modified: gnucash/trunk/src/gnome/ui/gnc-plugin-page-sx-list-ui.xml
===================================================================
--- gnucash/trunk/src/gnome/ui/gnc-plugin-page-sx-list-ui.xml	2013-04-24 09:10:29 UTC (rev 22930)
+++ gnucash/trunk/src/gnome/ui/gnc-plugin-page-sx-list-ui.xml	2013-05-02 14:41:56 UTC (rev 22931)
@@ -3,7 +3,9 @@
     <placeholder name="AdditionalMenusPlaceholder">
       <menu action="SxListAction">
         <menuitem name="SxListNew" action="SxListNewAction"/>
+        <menuitem name="SxListNew2" action="SxListNewAction2"/>
         <menuitem name="SxListEdit" action="SxListEditAction"/>
+        <menuitem name="SxListEdit2" action="SxListEditAction2"/>
         <menuitem name="SxListDelete" action="SxListDeleteAction"/>
       </menu>
     </placeholder>

Modified: gnucash/trunk/src/gnome-utils/gnc-cell-renderer-popup-entry.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-cell-renderer-popup-entry.c	2013-04-24 09:10:29 UTC (rev 22930)
+++ gnucash/trunk/src/gnome-utils/gnc-cell-renderer-popup-entry.c	2013-05-02 14:41:56 UTC (rev 22931)
@@ -193,6 +193,7 @@
             return FALSE;
 
         gtk_entry_set_text (entry, qof_print_date (gnc_mktime (&when)));
+        gtk_widget_grab_focus (GTK_WIDGET (entry));
         return TRUE;
     }
     return FALSE;
@@ -204,7 +205,9 @@
 {
 	GncPopupEntry *widget = GNC_POPUP_ENTRY (box);
 	GdkEvent       tmp_event;
-	
+
+	gtk_widget_grab_focus (widget->entry);
+
 	if (key_event->keyval == GDK_Escape) {
 		widget->editing_canceled = TRUE;
 
@@ -214,8 +217,18 @@
 		return TRUE;
 	}
 
-	gtk_widget_grab_focus (widget->entry);
+        if (key_event->keyval == GDK_Left)
+        {
+            gtk_editable_set_position (GTK_EDITABLE (widget->entry), 0);
+            return TRUE;
+        }
 
+        if (key_event->keyval == GDK_Right)
+        {
+            gtk_editable_set_position (GTK_EDITABLE (widget->entry), -1);
+            return TRUE;
+        }
+
 	/* Hackish :/ Synthesize a key press event for the entry. */
 	memcpy (&tmp_event, key_event, sizeof (GdkEventKey));
 

Modified: gnucash/trunk/src/gnome-utils/gnc-embedded-window.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-embedded-window.c	2013-04-24 09:10:29 UTC (rev 22930)
+++ gnucash/trunk/src/gnome-utils/gnc-embedded-window.c	2013-05-02 14:41:56 UTC (rev 22931)
@@ -326,7 +326,7 @@
 
     priv->menu_dock = gtk_vbox_new (FALSE, 0);
     gtk_widget_show (priv->menu_dock);
-    gtk_box_pack_start (GTK_BOX (window), priv->menu_dock, TRUE, TRUE, 0);
+    gtk_box_pack_start (GTK_BOX (window), priv->menu_dock, FALSE, TRUE, 0);
 
     priv->statusbar = gtk_statusbar_new ();
     gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR(priv->statusbar), FALSE);

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-24 09:10:29 UTC (rev 22930)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-control-split-reg.c	2013-05-02 14:41:56 UTC (rev 22931)
@@ -527,85 +527,6 @@
 }
 
 
-
-#ifdef skip
-
-/**
- * Schedules the current transaction for recurring-entry.
- * If the selected transaction was created from a scheduled transaction,
- * opens the editor for that Scheduled Transaction.
- **/
-void
-gnc_tree_control_split_reg_schedule_current_trans (GncTreeViewSplitReg *view)
-{
-    Transaction *trans;
-
-    trans = gnc_tree_view_split_reg_get_current_trans (view);
-
-    if (trans == NULL)
-        return;
-
-    /* See if we were asked to schedule a blank trans. */
-    if (trans == gnc_tree_control_split_reg_get_blank_trans (view))
-        return;
-
-    /* Test for read only */
-    if (gtc_is_trans_readonly_and_warn (view, trans))
-        return;
-
-    /* See if we are being edited in another register */
-    if (gtc_trans_test_for_edit (view, trans))
-        return;
-
-    /* Make sure we ask to commit any changes before we procede */
-    if (gtc_trans_open_and_warn (view, trans))
-        return;
-
-    /* If the transaction has a sched-xact KVP frame, then go to the editor
-     * for the existing SX; otherwise, do the sx-from-trans dialog. */
-    {
-        kvp_frame *txn_frame;
-        kvp_value *kvp_val;
-        /* set a kvp-frame element in the transaction indicating and
-         * pointing-to the SX this was created from. */
-        txn_frame = xaccTransGetSlots (trans);
-        if ( txn_frame != NULL )
-        {
-            kvp_val = kvp_frame_get_slot (txn_frame, "from-sched-xaction");
-            if (kvp_val)
-            {
-                GncGUID *fromSXId = kvp_value_get_guid (kvp_val);
-                SchedXaction *theSX = NULL;
-                GList *sxElts;
-
-                /* Get the correct SX */
-                for ( sxElts = gnc_book_get_schedxactions (gnc_get_current_book())->sx_list;
-                        (!theSX) && sxElts;
-                        sxElts = sxElts->next )
-                {
-                    SchedXaction *sx = (SchedXaction*)sxElts->data;
-                    theSX =
-                        ( ( guid_equal (xaccSchedXactionGetGUID (sx), fromSXId))
-                          ? sx : NULL );
-                }
-
-                if (theSX)
-                {
-                    gnc_ui_scheduled_xaction_editor_dialog_create (theSX, FALSE);
-                    return;
-                }
-            }
-        }
-    }
-    gnc_sx_create_from_trans(pending_trans);
-}
-
-
-#endif
-
-
-
-
 /* Void current transaction */
 void
 gnc_tree_control_split_reg_void_current_trans (GncTreeViewSplitReg *view, const char *reason)
@@ -2049,6 +1970,9 @@
     gconf_section = gnc_tree_view_get_gconf_section (GNC_TREE_VIEW (view));
     gnc_gconf_set_int (gconf_section, "sort_depth", view->sort_depth, NULL);
 
+    /* scroll when view idle */
+    g_idle_add ((GSourceFunc) gnc_tree_view_split_reg_scroll_to_cell, view);
+
     LEAVE("sort_col %d, sort_direction is %d  sort_depth is %d", view->sort_col, view->sort_direction, view->sort_depth );
 }
 

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-24 09:10:29 UTC (rev 22930)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-model-split-reg.c	2013-05-02 14:41:56 UTC (rev 22931)
@@ -94,36 +94,25 @@
 /** The instance private data for the split register tree model. */
 struct GncTreeModelSplitRegPrivate
 {
-    QofBook *book;              // GNC Book
-    Account *anchor;            // Account of register
+    QofBook *book;                   // GNC Book
+    Account *anchor;                 // Account of register
 
-    GList *tlist;               // List of unique transactions derived from the query slist in same order
+    GList *tlist;                    // List of unique transactions derived from the query slist in same order
 
-    Transaction *btrans;        // The Blank transaction
+    Transaction *btrans;             // The Blank transaction
 
-    Split *bsplit;              // The Blank split
-    GList *bsplit_node;         // never added to any list, just for representation of the iter
-    GList *bsplit_parent_node;  // this equals the tnode of the transaction with the blank split
+    Split *bsplit;                   // The Blank split
+    GList *bsplit_node;              // never added to any list, just for representation of the iter
+    GList *bsplit_parent_node;       // this equals the tnode of the transaction with the blank split
 
+    gboolean display_subacc;         // Are we displaying subaccounts
+    gboolean display_gl;             // Is this the General ledger
 
-    gboolean display_subacc;    // Are we displaying subaccounts
-    gboolean display_gl;        // Is this the General ledger
+    const GncGUID *template_account; // The template account which template transaction should belong to
 
+    gpointer             user_data;  // User data for users of SplitRegisters, used to get parent window
+    SRGetParentCallback2 get_parent; // hook to get parent widget, used to get parent window
 
-
-/* vvvv ### This is stuff I have dumped here from old reg #### vvvv */
-
-    /* The template account which template transaction should belong to */
-    GncGUID template_account;
-
-    /* User data for users of SplitRegisters */
-    gpointer user_data; //FIXME This is used to get parent window, maybe move to view
-
-    /* hook to get parent widget */
-    SRGetParentCallback2 get_parent; //FIXME This is used to get parent window, maybe move to view
-
-/* ^^^^ #### This is stuff I have dumped here from old reg #### ^^^^ */
-
     GtkListStore *description_list;  // description field autocomplete list
     GtkListStore *notes_list;        // notes field autocomplete list
     GtkListStore *memo_list;         // memo field autocomplete list
@@ -495,10 +484,9 @@
     return model;
 }
 
-
-/* ForEach function to remove all model entries */
+/* ForEach function to walk the list of model entries */
 static gboolean
-gtm_remove_foreach_func (GtkTreeModel *model,
+gtm_split_reg_foreach_func (GtkTreeModel *model,
               GtkTreePath  *path,
               GtkTreeIter  *iter,
               GList       **rowref_list)
@@ -513,6 +501,39 @@
 }
 
 
+/* Emit change signal for all visable model entries */
+void
+gnc_tree_model_split_reg_change_vis_rows (GncTreeModelSplitReg *model, GtkTreePath *start_path, GtkTreePath *end_path)
+{
+    GList *rr_list = NULL;    /* list of GtkTreeRowReferences */
+    GList *node;
+    GtkTreeIter iter;
+
+    gtk_tree_model_foreach (GTK_TREE_MODEL(model), (GtkTreeModelForeachFunc)gtm_split_reg_foreach_func, &rr_list);
+
+    for ( node = rr_list;  node != NULL;  node = node->next )
+    {
+        GtkTreePath *path;
+        path = gtk_tree_row_reference_get_path ((GtkTreeRowReference*)node->data);
+
+        if ((path) && gnc_tree_model_split_reg_get_iter (GTK_TREE_MODEL (model), &iter, path))
+        {
+            PINFO("path is - '%s'", gtk_tree_path_to_string (path));
+
+            // Only emit change if path > start_path and < end_path
+            if ((gtk_tree_path_compare (path, end_path) == -1) && (gtk_tree_path_compare (start_path, path) == -1))
+            {
+                PINFO("row_changed at path - '%s'", gtk_tree_path_to_string (path));
+                gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
+            }
+            gtk_tree_path_free (path);
+        }
+    }
+    g_list_foreach (rr_list, (GFunc) gtk_tree_row_reference_free, NULL);
+    g_list_free (rr_list);
+}
+
+
 /* Remove all model entries */
 static void
 gtm_remove_all_rows (GncTreeModelSplitReg *model)
@@ -520,7 +541,7 @@
     GList *rr_list = NULL;    /* list of GtkTreeRowReferences to remove */
     GList *node;
 
-    gtk_tree_model_foreach (GTK_TREE_MODEL(model), (GtkTreeModelForeachFunc)gtm_remove_foreach_func, &rr_list);
+    gtk_tree_model_foreach (GTK_TREE_MODEL(model), (GtkTreeModelForeachFunc)gtm_split_reg_foreach_func, &rr_list);
 
     rr_list = g_list_reverse (rr_list);
 
@@ -573,18 +594,39 @@
 }
 
 
-/*FIXME Not sure about this */
+/* Set the template account for this register. */
 void
 gnc_tree_model_split_reg_set_template_account (GncTreeModelSplitReg *model, Account *template_account)
 {
     GncTreeModelSplitRegPrivate *priv;
 
-//g_print("gnc_tree_model_split_reg_set_template_account\n");
     priv = model->priv;
-    priv->template_account = *xaccAccountGetGUID (template_account);
+    priv->template_account = xaccAccountGetGUID (template_account);
 }
 
 
+/* Return the template account for this register. */
+Account *
+gnc_tree_model_split_reg_get_template_account (GncTreeModelSplitReg *model)
+{
+    GncTreeModelSplitRegPrivate *priv;
+    Account *acct;
+
+    priv = model->priv;
+
+    acct = xaccAccountLookup (priv->template_account, priv->book);
+    return acct;
+}
+
+
+/* Return TRUE if this is a template register. */
+gboolean
+gnc_tree_model_split_reg_get_template (GncTreeModelSplitReg *model)
+{
+    return model->is_template;
+}
+
+
 /* Destroy the model */
 void
 gnc_tree_model_split_reg_destroy (GncTreeModelSplitReg *model)
@@ -1749,7 +1791,27 @@
     return TRUE;
 }
 
+/* Return TRUE if blank_split is on trans */
+gboolean
+gnc_tree_model_split_reg_is_blank_split_parent (GncTreeModelSplitReg *model, Transaction *trans)
+{
+    GncTreeModelSplitRegPrivate *priv;
+    GList *node;
 
+    priv = model->priv;
+
+    node = priv->bsplit_parent_node;
+
+    if (node == NULL)
+        return FALSE;
+
+    if (trans == priv->bsplit_parent_node->data)
+        return TRUE;
+    else
+        return FALSE;
+}
+
+
 /* Return the tree path of trans and split
    if trans and split NULL, return last in list */
 GtkTreePath *
@@ -2838,9 +2900,14 @@
 
             if (!g_list_find (priv->tlist, trans) && priv->display_gl)
             {
-                DEBUG("Insert trans %p for gl (%s)", trans, name);
-                gtm_insert_trans (model, trans);
-                g_signal_emit_by_name (model, "refresh_trans", trans);
+                gnc_commodity *split_com;
+                split_com = xaccAccountGetCommodity (acc);
+                if (!g_strcmp0 (gnc_commodity_get_namespace (split_com), "template") == 0)
+                {
+                    DEBUG("Insert trans %p for gl (%s)", trans, name);
+                    gtm_insert_trans (model, trans);
+                    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 ))
             {

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-24 09:10:29 UTC (rev 22930)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-model-split-reg.h	2013-05-02 14:41:56 UTC (rev 22931)
@@ -121,7 +121,7 @@
     SplitRegisterStyle2          style;                 /**<FIXME ? This may be the wrong place for these, may be the view ? */
     gboolean                     use_double_line;       /**<FIXME ? As above, whether to use two lines per transaction */
 
-    gboolean                     is_template;
+    gboolean                     is_template;           /**< Are we using a template */
 
     gboolean                     use_accounting_labels; /**< whether to use accounting Labels */
     gboolean                     separator_changed;     /**< whether the separator has changed */ 
@@ -134,7 +134,6 @@
     time64                       filter_start_time;     // Start time for Filter.
     time64                       filter_end_time;       // End time for Filter.
 
-
 }GncTreeModelSplitReg;
 
 
@@ -178,9 +177,15 @@
 /** Load the model from a slist and set default account for register. */
 void gnc_tree_model_split_reg_load (GncTreeModelSplitReg *model, GList * slist, Account *default_account);
 
-/** FIXME Not sure what this is for yet. */
+/** Sets the template account. */
 void gnc_tree_model_split_reg_set_template_account (GncTreeModelSplitReg *model, Account *template_account);
 
+/** Returns the template account. */
+Account * gnc_tree_model_split_reg_get_template_account (GncTreeModelSplitReg *model);
+
+/** Return TRUE if this is a template register. */
+gboolean gnc_tree_model_split_reg_get_template (GncTreeModelSplitReg *model);
+
 /** Destroy the model. */
 void gnc_tree_model_split_reg_destroy (GncTreeModelSplitReg *model);
 
@@ -237,6 +242,9 @@
 /* Return the blank split */
 Split * gnc_tree_model_split_get_blank_split (GncTreeModelSplitReg *model);
 
+/* Return TRUE if blank_split is on trans */
+gboolean gnc_tree_model_split_reg_is_blank_split_parent (GncTreeModelSplitReg *model, Transaction *trans);
+
 /* Return the blank trans */
 Transaction * gnc_tree_model_split_get_blank_trans (GncTreeModelSplitReg *model);
 
@@ -265,6 +273,10 @@
 /* Returns TRUE if iter is a blank transaction */
 gboolean gnc_tree_model_split_reg_is_blank_trans (GncTreeModelSplitReg *model, GtkTreeIter *iter);
 
+/* Emit change signal for all visable model entries */
+void gnc_tree_model_split_reg_change_vis_rows (GncTreeModelSplitReg *model,
+               GtkTreePath *start_path, GtkTreePath *end_path);
+
 /*****************************************************************************/
 
 G_END_DECLS

Modified: gnucash/trunk/src/gnome-utils/gnc-tree-util-split-reg.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-tree-util-split-reg.c	2013-04-24 09:10:29 UTC (rev 22930)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-util-split-reg.c	2013-05-02 14:41:56 UTC (rev 22931)
@@ -236,6 +236,45 @@
 }
 
 
+/* Returns the value denom */
+static int
+gtu_split_reg_get_value_denom (Split *split)
+{
+    gnc_commodity *currency;
+    int denom;
+
+    currency = xaccTransGetCurrency (xaccSplitGetParent (split));
+    denom = gnc_commodity_get_fraction (currency);
+    if (denom == 0)
+    {
+        gnc_commodity *commodity = gnc_default_currency ();
+        denom = gnc_commodity_get_fraction (commodity);
+        if (denom == 0)
+            denom = 100;
+    }
+    return denom;
+}
+
+
+/* Returns the amount denom */
+static int
+gtu_split_reg_get_amount_denom (Split *split)
+{
+    int denom;
+
+    denom = xaccAccountGetCommoditySCU (xaccSplitGetAccount (split));
+    if (denom == 0)
+    {
+        gnc_commodity *commodity = gnc_default_currency ();
+        denom = gnc_commodity_get_fraction (commodity);
+        if (denom == 0)
+            denom = 100;
+    }
+    return denom;
+}
+
+
+
 /*###########################################################################*/
 
 
@@ -353,10 +392,61 @@
 }
 
 
+/* Return the string entry for transfer column when template */
+const char *
+gnc_tree_util_split_reg_template_get_transfer_entry (Split *split)
+{
+    static char *name = NULL;
 
+    kvp_frame *kvpf;
 
+    if (!split)
+        return NULL;
 
+    kvpf = xaccSplitGetSlots (split);
 
+    g_free (name);
+
+    if (kvpf)
+    {
+        Account *account;
+        GncGUID *guid;
+
+        guid = kvp_value_get_guid(
+                   kvp_frame_get_slot_path (kvpf, "sched-xaction", "account", NULL));
+
+        account = xaccAccountLookup (guid, gnc_get_current_book ());
+
+        name = account ? gnc_get_account_name_for_register (account) : NULL;
+    }
+    else
+        name = NULL;
+
+    return name;
+}
+
+
+const char *
+gnc_tree_util_split_reg_template_get_fdebt_entry (Split *split)
+{
+    kvp_frame *kvpf = xaccSplitGetSlots (split);
+
+    return kvp_value_get_string(
+               kvp_frame_get_slot_path (kvpf, "sched-xaction", "debit-formula", NULL));
+}
+
+
+const char *
+gnc_tree_util_split_reg_template_get_fcred_entry (Split *split)
+{
+    kvp_frame *kvpf = xaccSplitGetSlots (split);
+
+    return kvp_value_get_string(
+               kvp_frame_get_slot_path (kvpf, "sched-xaction", "credit-formula", NULL));
+}
+
+
+
 /*###########################################################################*/
 
 /* returns TRUE if you need to convert the split's value to the local
@@ -766,7 +856,345 @@
 
 
 
+/* Takes the input with column and sets the price / amount / value so they are consistent */
+void
+gnc_tree_util_set_number_for_input (GncTreeViewSplitReg *view, Transaction *trans, Split *split, gnc_numeric input, gint viewcol)
+{
+    GncTreeModelSplitReg *model;
+    gnc_numeric  price;
+    gnc_numeric  amount;
+    gnc_numeric  value;
 
+    gboolean price_changed = FALSE;   // Price of each share
+    gboolean value_changed = FALSE;   // Total value of shares
+    gboolean amount_changed = FALSE;  // No of shares
 
+    gboolean recalc_amount = FALSE;
+    gboolean recalc_price = FALSE;
+    gboolean recalc_value = FALSE;
+    gboolean expanded = FALSE;
+    int denom;
+    Account *account;
 
+    ENTER("trans %p and split %p and input is %s and viewcol is %d", trans, split, gnc_numeric_to_string (input), viewcol);
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    account = gnc_tree_model_split_reg_get_anchor (model);
+
+    expanded = gnc_tree_view_split_reg_trans_expanded (view, trans);
+
+    if (!account)
+        account = xaccSplitGetAccount (split);
+
+    if (!xaccAccountIsPriced (account))
+        return;
+
+    /* If we are using commodity trading accounts then the value may
+       not really be the value.  Punt if so. */
+    if (xaccTransUseTradingAccounts (xaccSplitGetParent (split)))
+    {
+        gnc_commodity *acc_commodity;
+        acc_commodity = xaccAccountGetCommodity (account);
+        if (!(xaccAccountIsPriced (account) || !gnc_commodity_is_iso (acc_commodity)))
+            return;
+    }
+
+    if (gnc_numeric_zero_p (input))
+    {
+        xaccSplitSetValue (split, input);
+        xaccSplitSetAmount (split, input);
+        LEAVE("zero");
+        return;
+    }
+
+    amount = xaccSplitGetAmount (split);
+    value = xaccSplitGetValue (split);
+
+    if (viewcol == COL_AMTVAL && !expanded)
+    {
+        value_changed = TRUE;
+        if (gnc_numeric_zero_p (amount))
+        {
+            xaccSplitSetValue (split, input);
+            xaccSplitSetAmount (split, input);
+            LEAVE("");
+            return;
+        }
+    }
+    else if (viewcol == COL_AMTVAL && expanded)
+    {
+        amount_changed = TRUE;
+        if (gnc_numeric_zero_p (value))
+        {
+            xaccSplitSetValue (split, input);
+            xaccSplitSetAmount (split, input);
+            LEAVE("");
+            return;
+        }
+    }
+
+    if (viewcol == COL_PRICE)
+    {
+        price_changed = TRUE;
+        if (gnc_numeric_zero_p (value))
+        {
+            amount = gnc_numeric_create (1,1);
+            value = gnc_numeric_mul (input, amount, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND);
+            xaccSplitSetValue (split, input);
+            xaccSplitSetAmount (split, amount);
+            LEAVE("");
+            return;
+        }
+    }
+
+    if ((viewcol == COL_CREDIT || viewcol == COL_DEBIT) && !expanded)
+    {
+        amount_changed = TRUE;
+        if (gnc_numeric_zero_p (value))
+        {
+            xaccSplitSetValue (split, input);
+            xaccSplitSetAmount (split, input);
+            LEAVE("");
+            return;
+        }
+    }
+    else if ((viewcol == COL_CREDIT || viewcol == COL_DEBIT) && expanded)
+    {
+        value_changed = TRUE;
+        if (gnc_numeric_zero_p (value))
+        {
+            xaccSplitSetValue (split, input);
+            xaccSplitSetAmount (split, input);
+            LEAVE("");
+            return;
+        }
+    }
+
+    DEBUG("value_changed %d, price_changed %d, amount_changed %d", value_changed, price_changed, amount_changed);
+
+    {
+        int choice;
+        int default_value;
+        GList *node;
+        GList *radio_list = NULL;
+        const char *title = _("Recalculate Transaction");
+        const char *message = _("The values entered for this transaction "
+                                "are inconsistent. Which value would you "
+                                "like to have recalculated?");
+
+        if (amount_changed)
+            radio_list = g_list_append (radio_list,
+                                        g_strdup_printf ("%s (%s)",
+                                                _("_Shares"), _("Changed")));
+        else
+            radio_list = g_list_append (radio_list, g_strdup (_("_Shares")));
+
+        if (price_changed)
+            radio_list = g_list_append (radio_list,
+                                        g_strdup_printf ("%s (%s)",
+                                                _("_Price"), _("Changed")));
+        else
+            radio_list = g_list_append (radio_list, g_strdup (_("_Price")));
+
+        if (value_changed)
+            radio_list = g_list_append (radio_list,
+                                        g_strdup_printf ("%s (%s)",
+                                                _("_Value"), _("Changed")));
+        else
+            radio_list = g_list_append (radio_list, g_strdup (_("_Value")));
+
+        if (price_changed)
+            default_value = 0;  /* change the amount / shares */
+        else
+            default_value = 1;  /* change the value */
+
+        choice = gnc_choose_radio_option_dialog
+                 (gnc_tree_view_split_reg_get_parent (view),
+                  title,
+                  message,
+                  _("_Recalculate"),
+                  default_value,
+                  radio_list);
+
+        for (node = radio_list; node; node = node->next)
+            g_free (node->data);
+
+        g_list_free (radio_list);
+
+        switch (choice)
+        {
+        case 0: /* Modify number of shares */
+            recalc_amount = TRUE;
+            break;
+        case 1: /* Modify the share price */
+            recalc_price = TRUE;
+            break;
+        case 2: /* Modify total value */
+            recalc_value = TRUE;
+            break;
+        default: /* Cancel */
+            LEAVE(" " );
+            return;
+        }
+    }
+
+    DEBUG("recalc_value %d, recalc_price %d, recalc_amount %d", recalc_value, recalc_price, recalc_amount);
+
+    if (recalc_amount)
+    {
+        denom = gtu_split_reg_get_amount_denom (split);
+
+        if (amount_changed)
+        {
+            LEAVE("");
+            return;
+        }
+
+        if (price_changed)
+            price = input;
+        else
+            price = gnc_numeric_div (value, amount, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT);
+
+        if (value_changed)
+        {
+            xaccSplitSetValue (split, input);
+            amount = gnc_numeric_div (input, price, denom, GNC_HOW_RND_ROUND_HALF_UP);
+            xaccSplitSetAmount (split, amount);
+        }
+        else
+        {
+            amount = gnc_numeric_div (value, price, denom, GNC_HOW_RND_ROUND_HALF_UP);
+            xaccSplitSetAmount (split, amount);
+        }
+    }
+
+    if (recalc_price)
+    {
+        if (price_changed)
+        {
+            LEAVE("");
+            return;
+        }
+
+        if (amount_changed)
+        {
+            xaccSplitSetAmount (split, input);
+            xaccSplitSetValue (split, value);
+        }
+
+        if (value_changed)
+        {
+            xaccSplitSetValue (split, input);
+            xaccSplitSetAmount (split, amount);
+        }
+    }
+
+    if (recalc_value)
+    {
+        denom = gtu_split_reg_get_value_denom (split);
+
+        if (value_changed)
+        {
+            LEAVE("");
+            return;
+        }
+
+        if (price_changed)
+            price = input;
+        else
+            price = gnc_numeric_div (value, amount, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT);
+
+        if (amount_changed)
+        {
+            xaccSplitSetAmount (split, input);
+            value = gnc_numeric_mul (input, price, denom, GNC_HOW_RND_ROUND_HALF_UP);
+            xaccSplitSetValue (split, value);
+        }
+        else
+        {
+            value = gnc_numeric_mul (amount, price, denom, GNC_HOW_RND_ROUND_HALF_UP);
+            xaccSplitSetValue (split, value);
+        }
+    }
+
+    /* If the number of splits is two, change other split to balance */
+    if (!gnc_tree_util_split_reg_is_multi (split) && expanded)
+    {
+        Split *osplit;
+        gnc_commodity *osplit_com;
+
+        osplit = xaccSplitGetOtherSplit (split);
+
+        value = xaccSplitGetValue (split);
+
+        osplit_com = xaccAccountGetCommodity (xaccSplitGetAccount (osplit));
+
+        if (gnc_commodity_is_currency (osplit_com))
+        {
+            xaccSplitSetValue (osplit, gnc_numeric_neg (value));
+            xaccSplitSetAmount (osplit, gnc_numeric_neg (value));
+        }
+    }
+    LEAVE("");
+}
+
+
+/* Set the value for the given input amount */
+void
+gnc_tree_util_set_value_for_amount (GncTreeViewSplitReg *view, Transaction *trans, Split *split, gnc_numeric input)
+{
+    gnc_numeric  split_rate;
+    gnc_numeric  amount;
+    gnc_numeric  value, new_value;
+    int denom;
+
+    ENTER("trans %p and split %p and input is %s", trans, split, gnc_numeric_to_string (input));
+
+    if (gnc_numeric_zero_p (input))
+    {
+        xaccSplitSetValue (split, input);
+        xaccSplitSetAmount (split, input);
+        LEAVE("zero");
+        return;
+    }
+
+    amount = xaccSplitGetAmount (split);
+    value = xaccSplitGetValue (split);
+
+    denom = gtu_split_reg_get_value_denom (split);
+
+    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 (100,100);
+
+    new_value = gnc_numeric_mul (input, split_rate, denom, GNC_HOW_RND_ROUND_HALF_UP);
+
+    xaccSplitSetValue (split, new_value);
+    xaccSplitSetAmount (split, input);
+
+    LEAVE("");
+}
+
+
+/* Get the rate */
+gnc_numeric
+gnc_tree_util_get_rate_for (GncTreeViewSplitReg *view, Transaction *trans, Split *split, gboolean is_blank)
+{
+    gnc_numeric num;
+
+    ENTER("trans %p and split %p is_blank %d", trans, split, is_blank);
+
+    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("split %p and return num is %s", split, gnc_numeric_to_string (num));
+    return num;
+}
+
+
 /*****************************************************************************/

Modified: gnucash/trunk/src/gnome-utils/gnc-tree-util-split-reg.h
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-tree-util-split-reg.h	2013-04-24 09:10:29 UTC (rev 22930)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-util-split-reg.h	2013-05-02 14:41:56 UTC (rev 22931)
@@ -42,6 +42,14 @@
 
 const char * gnc_tree_util_split_reg_get_transfer_entry (Split *split, gboolean *is_multi);
 
+const char * gnc_tree_util_split_reg_template_get_transfer_entry (Split *split);
+
+const char * gnc_tree_util_split_reg_template_get_fdebt_entry (Split *split);
+
+const char * gnc_tree_util_split_reg_template_get_fcred_entry (Split *split);
+
+
+
 gboolean gnc_tree_util_split_reg_is_multi (Split *split);
 
 gboolean gnc_tree_util_split_reg_needs_amount (GncTreeViewSplitReg *view, Split *split);
@@ -61,8 +69,14 @@
                                                     gboolean is_blank,gnc_numeric *ret_num,
                                                     GNCPrintAmountInfo *ret_print_info);
 
+void gnc_tree_util_set_number_for_input (GncTreeViewSplitReg *view, Transaction *trans,
+                                         Split *split, gnc_numeric input, gint viewcol);
 
+void gnc_tree_util_set_value_for_amount (GncTreeViewSplitReg *view, Transaction *trans,
+                                         Split *split, gnc_numeric input);
 
+gnc_numeric gnc_tree_util_get_rate_for (GncTreeViewSplitReg *view, Transaction *trans,
+                                        Split *split, gboolean is_blank);
 
 /*****************************************************************************/
 

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-24 09:10:29 UTC (rev 22930)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-view-split-reg.c	2013-05-02 14:41:56 UTC (rev 22931)
@@ -44,6 +44,7 @@
 #include "engine-helpers.h"
 #include "Scrub.h"
 #include "gnc-exp-parser.h"
+#include "SchedXaction.h"
 
 #include "gnc-amount-edit.h"
 
@@ -85,9 +86,17 @@
 static void control_cdf0 (GtkTreeViewColumn *col, GtkCellRenderer *renderer,
                                  GtkTreeModel *s_model, GtkTreeIter *s_iter, gpointer user_data);
 
+static void gtv_split_reg_titles (GncTreeViewSplitReg *view, RowDepth depth);
+
 static void gtv_split_reg_edited_cb (GtkCellRendererText *cell, const gchar *path_string,
-                          	const gchar *new_text, gpointer _model);
+				const gchar *new_text, gpointer user_data);
 
+static void gtv_split_reg_edited_normal_cb (GtkCellRendererText *cell, const gchar *path_string,
+                                const gchar *new_text, gpointer user_data);
+
+static void gtv_split_reg_edited_template_cb (GtkCellRendererText *cell, const gchar *path_string,
+                                const gchar *new_text, gpointer user_data);
+
 static void start_edit (GtkCellRenderer *cr, GtkCellEditable *editable,
 				const gchar *path, gpointer user_data); //FIXME This may not be needed
 
@@ -95,7 +104,7 @@
 
 static void gtv_finish_edit (GncTreeViewSplitReg *view);
 
-static void gtv_get_editable_start_editing_cb (GtkCellRenderer *cr, GtkCellEditable *editable,
+static void gtv_split_reg_editable_start_editing_cb (GtkCellRenderer *cr, GtkCellEditable *editable,
    				const gchar *path, gpointer user_data);
 
 static void gtv_split_reg_editing_canceled_cb (GtkCellRenderer *cr, gpointer user_data);
@@ -127,6 +136,7 @@
 
 static gboolean transaction_changed_confirm (GncTreeViewSplitReg *view, Transaction *new_trans);
 
+
 typedef struct {
     ViewCol viewcol;
     gint modelcol;
@@ -147,78 +157,78 @@
     {COL_DATE, GNC_TREE_MODEL_SPLIT_REG_COL_DATE,
      "Date", "date", "00/00/0000xxx",
      GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 1,
-     gtv_split_reg_edited_cb, gtv_get_editable_start_editing_cb,
+     gtv_split_reg_edited_cb, gtv_split_reg_editable_start_editing_cb,
      gnc_tree_control_split_reg_sort_by_date},
 
     {COL_DUEDATE, GNC_TREE_MODEL_SPLIT_REG_COL_DUEDATE,
      "Due Date", "duedate", "00/00/0000xxx",
      GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 1,
-     gtv_split_reg_edited_cb, gtv_get_editable_start_editing_cb, NULL},
+     gtv_split_reg_edited_cb, gtv_split_reg_editable_start_editing_cb, NULL},
 
     {COL_NUMACT, GNC_TREE_MODEL_SPLIT_REG_COL_NUMACT,
      "Num / Act / Act", "numact", "0000xxx",
      GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 0,
-     gtv_split_reg_edited_cb, gtv_get_editable_start_editing_cb,
+     gtv_split_reg_edited_cb, gtv_split_reg_editable_start_editing_cb,
      gnc_tree_control_split_reg_sort_by_numact},
 
     {COL_DESCNOTES, GNC_TREE_MODEL_SPLIT_REG_COL_DESCNOTES,
      "Description / Notes / Memo", "descnotes", "xxxxxxxxxxxxxxxxxxx",
      GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 1,
-     gtv_split_reg_edited_cb, gtv_get_editable_start_editing_cb,
+     gtv_split_reg_edited_cb, gtv_split_reg_editable_start_editing_cb,
      gnc_tree_control_split_reg_sort_by_dnm},
 
     {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,
+     gtv_split_reg_edited_cb, gtv_split_reg_editable_start_editing_cb,
      gnc_tree_control_split_reg_sort_by_account},
 
     {COL_RECN, GNC_TREE_MODEL_SPLIT_REG_COL_RECN,
      "R", "recn", "xxx",
      GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 0,
-     gtv_split_reg_edited_cb, gtv_get_editable_start_editing_cb,
+     gtv_split_reg_edited_cb, gtv_split_reg_editable_start_editing_cb,
      gnc_tree_control_split_reg_sort_by_recn},
 
     {COL_TYPE, -1,
      "Type", "type", "x",
      GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 0,
-     gtv_split_reg_edited_cb, gtv_get_editable_start_editing_cb, NULL},
+     gtv_split_reg_edited_cb, gtv_split_reg_editable_start_editing_cb, NULL},
 
     {COL_VALUE, -1,
      "Value", "value", "xxxxxxxx",
      GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 0,
-     gtv_split_reg_edited_cb, gtv_get_editable_start_editing_cb, NULL},
+     gtv_split_reg_edited_cb, gtv_split_reg_editable_start_editing_cb, NULL},
 
     {COL_AMOUNT, -1,
      "Amount", "amount", "xxxxxxxx",
      GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 0,
-     gtv_split_reg_edited_cb, gtv_get_editable_start_editing_cb, NULL},
+     gtv_split_reg_edited_cb, gtv_split_reg_editable_start_editing_cb, NULL},
 
     {COL_AMTVAL, -1,
      "Amount / Value", "amtval", "xxxxxxxx",
      GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 1,
-     gtv_split_reg_edited_cb, gtv_get_editable_start_editing_cb, NULL},
+     gtv_split_reg_edited_cb, gtv_split_reg_editable_start_editing_cb, NULL},
 
     {COL_RATE, -1,
      "Rate", "rate", "xxxxxxxx",
      GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 0,
-     gtv_split_reg_edited_cb, gtv_get_editable_start_editing_cb, NULL},
+     gtv_split_reg_edited_cb, gtv_split_reg_editable_start_editing_cb, NULL},
 
     {COL_PRICE, -1,
      "Price", "price", "xxxxxxxx",
      GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 1,
-     gtv_split_reg_edited_cb, gtv_get_editable_start_editing_cb, NULL},
+     gtv_split_reg_edited_cb, gtv_split_reg_editable_start_editing_cb, NULL},
 
     {COL_DEBIT, GNC_TREE_MODEL_SPLIT_REG_COL_DEBIT,
-     "Debit", "debit", "xxxxxxxxxx",
+     "Debit", "debit", "xxxxxxxxxxxxx",
      GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 1,
-     gtv_split_reg_edited_cb, gtv_get_editable_start_editing_cb,
+     gtv_split_reg_edited_cb, gtv_split_reg_editable_start_editing_cb,
      gnc_tree_control_split_reg_sort_by_value},
 
     {COL_CREDIT, GNC_TREE_MODEL_SPLIT_REG_COL_CREDIT,
-     "Credit", "credit", "xxxxxxxxxx",
+     "Credit", "credit", "xxxxxxxxxxxxx",
      GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 1,
-     gtv_split_reg_edited_cb, gtv_get_editable_start_editing_cb,
+     gtv_split_reg_edited_cb, gtv_split_reg_editable_start_editing_cb,
      gnc_tree_control_split_reg_sort_by_value},
 
     {COL_BALANCE, -1,
@@ -458,6 +468,29 @@
     gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (f_model));
 }
 
+
+/* Change all visable view entries */
+void
+gnc_tree_view_split_reg_change_vis_rows (GncTreeViewSplitReg *view)
+{
+    GncTreeModelSplitReg *model;
+    GtkTreePath *start_path, *end_path;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    if (gtk_tree_view_get_visible_range (GTK_TREE_VIEW (view), &start_path, &end_path))
+    {
+        PINFO("start_path is - '%s' and end_path is - %s", gtk_tree_path_to_string (start_path),
+                                                           gtk_tree_path_to_string (end_path));
+
+        gnc_tree_model_split_reg_change_vis_rows (model, start_path, end_path);
+
+        gtk_tree_path_free (start_path);
+        gtk_tree_path_free (end_path);
+    }
+}
+
+
 /*****************************************************************************/
 
 static void
@@ -517,6 +550,13 @@
         view->priv->current_ref = NULL;
     }
 
+    gnc_gconf_general_remove_cb ("draw_horizontal_lines",
+                                gnc_tree_view_split_reg_gconf_changed,
+                                view);
+    gnc_gconf_general_remove_cb ("draw_vertical_lines",
+                                gnc_tree_view_split_reg_gconf_changed,
+                                view);
+
     if (G_OBJECT_CLASS (parent_class)->dispose)
         (* G_OBJECT_CLASS (parent_class)->dispose) (object);
 
@@ -683,7 +723,7 @@
         {
         static ViewCol col_list[] = {
         COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSFERVOID, COL_RECN,
-        COL_STATUS, COL_RATE, COL_DEBIT, COL_CREDIT, -1};
+        COL_STATUS, COL_DEBIT, COL_CREDIT, -1};
         return col_list;
         }
         break;
@@ -1180,6 +1220,9 @@
     /* Refilter the tree view register */
     gnc_tree_view_split_reg_refilter (view);
 
+    /* Update the titles */
+    gtv_split_reg_titles (view, view->priv->current_depth);
+
     /* Set the view format */
     g_idle_add ((GSourceFunc) gnc_tree_view_split_reg_set_format, view);
 
@@ -1224,8 +1267,11 @@
 
     anchor = gnc_tree_model_split_reg_get_anchor (model);
 
-    if (xaccTransCountSplits (trans) == 0)
-        return gnc_tree_model_split_get_blank_split (model);
+    if (xaccTransCountSplits (trans) == 0) // this may be a blank or a reinit trans.
+    {
+        if (gnc_tree_model_split_reg_is_blank_split_parent (model, trans))
+            return gnc_tree_model_split_get_blank_split (model);
+    }
 
     for (i = 0; (split = xaccTransGetSplit (trans, i)); i++) {
         if (anchor == xaccSplitGetAccount (split))
@@ -1235,382 +1281,6 @@
 }
 
 
-/* Returns the value denom */
-static int
-gnc_tree_view_split_reg_get_value_denom (Split *split)
-{
-    gnc_commodity *currency;
-    int denom;
-
-    currency = xaccTransGetCurrency (xaccSplitGetParent (split));
-    denom = gnc_commodity_get_fraction (currency);
-    if (denom == 0)
-    {
-        gnc_commodity *commodity = gnc_default_currency ();
-        denom = gnc_commodity_get_fraction (commodity);
-        if (denom == 0)
-            denom = 100;
-    }
-    return denom;
-}
-
-
-/* Returns the amount denom */
-static int
-gnc_tree_view_split_reg_get_amount_denom (Split *split)
-{
-    int denom;
-
-    denom = xaccAccountGetCommoditySCU (xaccSplitGetAccount (split));
-    if (denom == 0)
-    {
-        gnc_commodity *commodity = gnc_default_currency ();
-        denom = gnc_commodity_get_fraction (commodity);
-        if (denom == 0)
-            denom = 100;
-    }
-    return denom;
-}
-
-
-/* Takes the input with column and sets the price / amount / value so they are consistent */
-static void
-set_number_for_input (GncTreeViewSplitReg *view, Transaction *trans, Split *split, gnc_numeric input, gint viewcol)
-{
-    GncTreeModelSplitReg *model;
-    gnc_numeric  price;
-    gnc_numeric  amount;
-    gnc_numeric  value;
-
-    gboolean price_changed = FALSE;   // Price of each share
-    gboolean value_changed = FALSE;   // Total value of shares
-    gboolean amount_changed = FALSE;  // No of shares
-
-    gboolean recalc_amount = FALSE;
-    gboolean recalc_price = FALSE;
-    gboolean recalc_value = FALSE;
-    int denom;
-    Account *account;
-
-    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);
-
-    model = gnc_tree_view_split_reg_get_model_from_view (view);
-
-    account = gnc_tree_model_split_reg_get_anchor (model);
-
-    if (!account)
-        account = xaccSplitGetAccount (split);
-
-    if (!xaccAccountIsPriced (account))
-        return;
-
-    /* If we are using commodity trading accounts then the value may
-       not really be the value.  Punt if so. */
-    if (xaccTransUseTradingAccounts (xaccSplitGetParent (split)))
-    {
-        gnc_commodity *acc_commodity;
-        acc_commodity = xaccAccountGetCommodity (account);
-        if (!(xaccAccountIsPriced (account) || !gnc_commodity_is_iso (acc_commodity)))
-            return;
-    }
-
-    if (gnc_numeric_zero_p (input))
-    {
-        xaccSplitSetValue (split, input);
-        xaccSplitSetAmount (split, input);
-        LEAVE("zero");
-        return;
-    }
-
-    amount = xaccSplitGetAmount (split);
-    value = xaccSplitGetValue (split);
-
-    if (viewcol == COL_AMTVAL && !view->priv->expanded)
-    {
-        value_changed = TRUE;
-        if (gnc_numeric_zero_p (amount))
-        {
-            xaccSplitSetValue (split, input);
-            xaccSplitSetAmount (split, input);
-            LEAVE("");
-            return;
-        }
-    }
-    else if (viewcol == COL_AMTVAL && view->priv->expanded)
-    {
-        amount_changed = TRUE;
-        if (gnc_numeric_zero_p (value))
-        {
-            xaccSplitSetValue (split, input);
-            xaccSplitSetAmount (split, input);
-            LEAVE("");
-            return;
-        }
-    }
-
-    if (viewcol == COL_PRICE)
-    {
-        price_changed = TRUE;
-        if (gnc_numeric_zero_p (value))
-        {
-            amount = gnc_numeric_create (1,1);
-            value = gnc_numeric_mul (input, amount, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND);
-            xaccSplitSetValue (split, input);
-            xaccSplitSetAmount (split, amount);
-            LEAVE("");
-            return;
-        }
-    }
-
-    if ((viewcol == COL_CREDIT || viewcol == COL_DEBIT) && !view->priv->expanded)
-    {
-        amount_changed = TRUE;
-        if (gnc_numeric_zero_p (value))
-        {
-            xaccSplitSetValue (split, input);
-            xaccSplitSetAmount (split, input);
-            LEAVE("");
-            return;
-        }
-    }
-    else if ((viewcol == COL_CREDIT || viewcol == COL_DEBIT) && view->priv->expanded)
-    {
-        value_changed = TRUE;
-        if (gnc_numeric_zero_p (value))
-        {
-            xaccSplitSetValue (split, input);
-            xaccSplitSetAmount (split, input);
-            LEAVE("");
-            return;
-        }
-    }
-
-    DEBUG("value_changed %d, price_changed %d, amount_changed %d", value_changed, price_changed, amount_changed);
-
-    {
-        int choice;
-        int default_value;
-        GList *node;
-        GList *radio_list = NULL;
-        const char *title = _("Recalculate Transaction");
-        const char *message = _("The values entered for this transaction "
-                                "are inconsistent. Which value would you "
-                                "like to have recalculated?");
-
-        if (amount_changed)
-            radio_list = g_list_append (radio_list,
-                                        g_strdup_printf ("%s (%s)",
-                                                _("_Shares"), _("Changed")));
-        else
-            radio_list = g_list_append (radio_list, g_strdup (_("_Shares")));
-
-        if (price_changed)
-            radio_list = g_list_append (radio_list,
-                                        g_strdup_printf ("%s (%s)",
-                                                _("_Price"), _("Changed")));
-        else
-            radio_list = g_list_append (radio_list, g_strdup (_("_Price")));
-
-        if (value_changed)
-            radio_list = g_list_append (radio_list,
-                                        g_strdup_printf ("%s (%s)",
-                                                _("_Value"), _("Changed")));
-        else
-            radio_list = g_list_append (radio_list, g_strdup (_("_Value")));
-
-        if (price_changed)
-            default_value = 0;  /* change the amount / shares */
-        else
-            default_value = 1;  /* change the value */
-
-        choice = gnc_choose_radio_option_dialog
-                 (gnc_tree_view_split_reg_get_parent (view),
-                  title,
-                  message,
-                  _("_Recalculate"),
-                  default_value,
-                  radio_list);
-
-        for (node = radio_list; node; node = node->next)
-            g_free (node->data);
-
-        g_list_free (radio_list);
-
-        switch (choice)
-        {
-        case 0: /* Modify number of shares */
-            recalc_amount = TRUE;
-            break;
-        case 1: /* Modify the share price */
-            recalc_price = TRUE;
-            break;
-        case 2: /* Modify total value */
-            recalc_value = TRUE;
-            break;
-        default: /* Cancel */
-            LEAVE(" " );
-            return;
-        }
-    }
-
-    DEBUG("recalc_value %d, recalc_price %d, recalc_amount %d", recalc_value, recalc_price, recalc_amount);
-
-    if (recalc_amount)
-    {
-        denom = gnc_tree_view_split_reg_get_amount_denom (split);
-
-        if (amount_changed)
-        {
-            LEAVE("");
-            return;
-        }
-
-        if (price_changed)
-            price = input;
-        else
-            price = gnc_numeric_div (value, amount, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT);
-
-        if (value_changed)
-        {
-            xaccSplitSetValue (split, input);
-            amount = gnc_numeric_div (input, price, denom, GNC_HOW_RND_ROUND_HALF_UP);
-            xaccSplitSetAmount (split, amount);
-        }
-        else
-        {
-            amount = gnc_numeric_div (value, price, denom, GNC_HOW_RND_ROUND_HALF_UP);
-            xaccSplitSetAmount (split, amount);
-        }
-    }
-
-    if (recalc_price)
-    {
-        if (price_changed)
-        {
-            LEAVE("");
-            return;
-        }
-
-        if (amount_changed)
-        {
-            xaccSplitSetAmount (split, input);
-            xaccSplitSetValue (split, value);
-        }
-
-        if (value_changed)
-        {
-            xaccSplitSetValue (split, input);
-            xaccSplitSetAmount (split, amount);
-        }
-    }
-
-    if (recalc_value)
-    {
-        denom = gnc_tree_view_split_reg_get_value_denom (split);
-
-        if (value_changed)
-        {
-            LEAVE("");
-            return;
-        }
-
-        if (price_changed)
-            price = input;
-        else
-            price = gnc_numeric_div (value, amount, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT);
-
-        if (amount_changed)
-        {
-            xaccSplitSetAmount (split, input);
-            value = gnc_numeric_mul (input, price, denom, GNC_HOW_RND_ROUND_HALF_UP);
-            xaccSplitSetValue (split, value);
-        }
-        else
-        {
-            value = gnc_numeric_mul (amount, price, denom, GNC_HOW_RND_ROUND_HALF_UP);
-            xaccSplitSetValue (split, value);
-        }
-    }
-
-    /* If the number of splits is two, change other split to balance */
-    if (!gnc_tree_util_split_reg_is_multi (split) && view->priv->expanded)
-    {
-        Split *osplit;
-        gnc_commodity *osplit_com;
-
-        osplit = xaccSplitGetOtherSplit (split);
-
-        value = xaccSplitGetValue (split);
-
-        osplit_com = xaccAccountGetCommodity (xaccSplitGetAccount (osplit));
-
-        if (gnc_commodity_is_currency (osplit_com))
-        {
-            xaccSplitSetValue (osplit, gnc_numeric_neg (value));
-            xaccSplitSetAmount (osplit, gnc_numeric_neg (value));
-        }
-    }
-    LEAVE("");
-}
-
-
-/* Set the value for the given input amount */
-static void
-set_value_for_amount (GncTreeViewSplitReg *view, Transaction *trans, Split *split, gnc_numeric input)
-{
-    gnc_numeric  split_rate;
-    gnc_numeric  amount;
-    gnc_numeric  value, new_value;
-    int denom;
-
-    ENTER("set_value_for_amount trans %p and split %p and input is %s", trans, split, gnc_numeric_to_string (input));
-
-    if (gnc_numeric_zero_p (input))
-    {
-        xaccSplitSetValue (split, input);
-        xaccSplitSetAmount (split, input);
-        LEAVE("zero");
-        return;
-    }
-
-    amount = xaccSplitGetAmount (split);
-    value = xaccSplitGetValue (split);
-
-    denom = gnc_tree_view_split_reg_get_value_denom (split);
-
-    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 (100,100);
-
-    new_value = gnc_numeric_mul (input, split_rate, denom, GNC_HOW_RND_ROUND_HALF_UP);
-
-    xaccSplitSetValue (split, new_value);
-    xaccSplitSetAmount (split, input);
-
-    LEAVE("");
-}
-
-
-/* Get the rate */
-static gnc_numeric
-get_rate_for (GncTreeViewSplitReg *view, Transaction *trans, Split *split, gboolean is_blank)
-{
-    gnc_numeric num;
-
-    ENTER("get_rate_for trans %p and split %p is_blank %d", trans, split, is_blank);
-
-    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;
-}
-
-
 /* The returned Splits may be newly created and not yet belong to trans. */
 static gboolean
 get_split_pair (GncTreeViewSplitReg *view, Transaction *trans, Split **osplit, Split **split)
@@ -1687,7 +1357,7 @@
 
 /* Only allow changes to values if we have valid split accounts */
 static gboolean
-have_account (GncTreeViewSplitReg *view, RowDepth depth, gboolean expanded, Transaction *trans, Split *split)
+have_account (GncTreeViewSplitReg *view, RowDepth depth, gboolean expanded, gboolean is_template, Transaction *trans, Split *split)
 {
     gboolean have_account = FALSE;
 
@@ -1704,19 +1374,27 @@
 
     if (depth == SPLIT3)
     {
-        Account *acc;
-        acc = xaccSplitGetAccount (split);
-        if (acc != NULL)
+        if (!is_template) // Are we using a template
         {
-            if (xaccAccountGetType (acc) != ACCT_TYPE_TRADING)
-                have_account = TRUE; // normal split
-            else
-                have_account = FALSE; // trading split
-        }
+            Account *acc = xaccSplitGetAccount (split);
+            if (acc != NULL)
+            {
+                if (xaccAccountGetType (acc) != ACCT_TYPE_TRADING)
+                    have_account = TRUE; // normal split
+                else
+                    have_account = FALSE; // trading split
+            }
+         }
+         else
+         {
+             if (gnc_tree_util_split_reg_template_get_transfer_entry (split) != NULL)
+                 have_account = TRUE;
+         }
     }
     return have_account;
 }
 
+/*###########################################################################*/
 
 /* This cellDataFunc is to set the cell-background property of the control columns. */
 static void
@@ -1778,7 +1456,6 @@
     GtkTreeIter m_iter, f_iter;
     GtkTreeModel *f_model;
     GtkTreePath *mpath, *spath;
-    GtkTreePath *path;
     ViewCol viewcol;
     Transaction *trans;
     Split *split;
@@ -1786,6 +1463,7 @@
     gboolean editable = FALSE, expanded = FALSE;
     gboolean read_only = FALSE;
     gboolean open_edited = FALSE;
+    gboolean is_template = FALSE;
     gnc_numeric num;
     const gchar *s = "";
     const gchar *row_color;
@@ -1822,6 +1500,16 @@
 
     row_color = gnc_tree_model_split_reg_get_row_color (model, is_trow1, is_trow2, is_split, indices[0]);
 
+    /* Lets see if the splits are expanded */
+    if (is_trow1 || is_trow2) // transaction
+    {
+        if (is_trow1)
+            gtk_tree_path_down (spath); /* Move the path down to trow2 */
+        expanded = gtk_tree_view_row_expanded (GTK_TREE_VIEW (view), spath);
+    }
+    else
+        expanded = TRUE; // splits are always expanded
+
     gtk_tree_path_free (spath);
     gtk_tree_path_free (mpath);
 
@@ -1838,17 +1526,8 @@
         open_edited = TRUE;
     }
 
-    /* Lets see if the splits are expanded */
-    if (is_trow1 || is_trow2)
-    {
-        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 */
-        expanded = gtk_tree_view_row_expanded (GTK_TREE_VIEW (view), path);
-        gtk_tree_path_free (path);
-    }
-    else
-        expanded = TRUE;
+    /* Is this a template */
+    is_template = gnc_tree_model_split_reg_get_template (model);
 
     switch (viewcol) {
     case COL_DATE:
@@ -1892,6 +1571,18 @@
             editable = FALSE;
         }
 
+        /* Is this a template */
+        if (is_template && is_trow1)
+        {
+            s =  _(" Scheduled ");
+            editable = FALSE;
+        }
+        else if (is_template && is_trow2 && SHOW_ENTERED_DATE)
+        {
+            s = "";
+            editable = FALSE;
+        }
+
         editable = (read_only == TRUE) ? FALSE : editable;
 
         /* This will remove the calander buttons if FALSE */
@@ -2013,25 +1704,34 @@
         }
         if (is_split)
         {
-            Account *acct = xaccSplitGetAccount (split);
+            if (!is_template) // Are we using a template
+            {
+                Account *acct = xaccSplitGetAccount (split);
 
-            if ((xaccTransCountSplits (trans) == 0) && model->type != GENERAL_LEDGER2 && model->type != SEARCH_LEDGER2) // First split on blank transaction
-                acct = anchor;
+                if ((xaccTransCountSplits (trans) == 0) && model->type != GENERAL_LEDGER2 && model->type != SEARCH_LEDGER2) // First split on blank transaction
+                    acct = anchor;
 
-            if (acct != NULL)
-            {
-                if (view->priv->acct_short_names)
-                    s = xaccAccountGetName (acct);
+                if (acct != NULL)
+                {
+                    if (view->priv->acct_short_names)
+                        s = xaccAccountGetName (acct);
+                    else
+                        s = gnc_account_get_full_name (acct);
+                }
                 else
-                    s = gnc_account_get_full_name (acct);
+                    s = "";
+
+                if (anchor == acct && model->type != GENERAL_LEDGER2 && model->type != SEARCH_LEDGER2)
+                    editable = FALSE;
+                else
+                    editable = TRUE;
             }
             else
-                s = "";
+            {
+                s = gnc_tree_util_split_reg_template_get_transfer_entry (split);
+                editable = TRUE;
+            }
 
-            if (anchor == acct && model->type != GENERAL_LEDGER2 && model->type != SEARCH_LEDGER2)
-                editable = FALSE;
-            else
-                editable = TRUE;
         }
 
         editable = (read_only == TRUE) ? FALSE : editable;
@@ -2041,27 +1741,32 @@
 
     case COL_RECN:
         /* Column is RECN */
-        if (is_trow1 && !expanded) {
-            char rec = xaccSplitGetReconcile (get_this_split (view, trans));
-            if (rec == VREC || rec == FREC)
-                editable = FALSE;
-            else
-                editable = TRUE;
+        editable = FALSE;
+        s = "";
+        if (is_trow1 && !expanded)
+        {
+            Split *this_split;
+            char rec;
 
-            if (rec != ' ')
-                s = gnc_get_reconcile_str (rec);
-            else
-                s = gnc_get_reconcile_str (NREC);
+            this_split = get_this_split (view, trans);
 
-            g_object_set (cell, "text", s, NULL);
+            if (this_split != NULL) // this could be a blank trans
+            {
+                rec = xaccSplitGetReconcile (this_split);
+                if (rec == VREC || rec == FREC)
+                    editable = FALSE;
+                else
+                    editable = TRUE;
 
-        } else {
-            s = "";
-            editable = FALSE;
-            g_object_set (cell, "text", s, NULL);
+                if (rec != ' ')
+                    s = gnc_get_reconcile_str (rec);
+                else
+                    s = gnc_get_reconcile_str (NREC);
+            }
         }
 
-        if (is_split) {
+        if (is_split)
+        {
             char rec = xaccSplitGetReconcile (split);
             if (rec == VREC || rec == FREC)
                 editable = FALSE;
@@ -2072,13 +1777,11 @@
                 s = gnc_get_reconcile_str (rec);
             else
                 s = gnc_get_reconcile_str (NREC);
-
-            g_object_set (cell, "text", s, NULL);
         }
 
         editable = (read_only == TRUE) ? FALSE : editable;
 
-        g_object_set (cell, "editable", editable, NULL);
+        g_object_set (cell, "text", s, "editable", editable, NULL);
         break;
 
     case COL_TYPE:
@@ -2151,7 +1854,7 @@
             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);
+            num = gnc_numeric_convert (gnc_tree_util_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, print_info);
@@ -2274,7 +1977,7 @@
         }
 
         /* Only allow changes to entries if we have a valid split accounts */
-        editable = have_account (view, depth, expanded, trans, split);
+        editable = have_account (view, depth, expanded, is_template, trans, split);
 
         editable = (read_only == TRUE) ? FALSE : editable;
 
@@ -2296,26 +1999,36 @@
         }
         else if (is_trow1)
         {
-            if (anchor)
+            if (expanded)
             {
-                Split *this_split;
+                s = "";
+                editable = FALSE;
+            }
+            else
+            {
+                if (anchor)
+                {
+                    Split *this_split;
 
-                this_split = get_this_split (view, trans);
+                    this_split = get_this_split (view, trans);
+                    if (this_split != NULL) // this could be a blank split
+                    {
+                        if (gnc_tree_util_split_reg_is_multi (this_split))
+                            num = gnc_numeric_zero();
+                        else
+                            num = xaccSplitGetSharePrice (this_split);
 
-                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);
 
-                editable = !expanded && !gnc_tree_util_split_reg_is_multi (this_split);
-
-                if (expanded)
-                    s = "";
-                else 
-                {
-                    if (gnc_numeric_check (num) == GNC_ERROR_OK)
-                    {
-                        s = xaccPrintAmount (num, gnc_split_amount_print_info (split, SHOW_SYMBOL));
+                        if (gnc_numeric_check (num) == GNC_ERROR_OK)
+                        {
+                            s = xaccPrintAmount (num, gnc_split_amount_print_info (split, SHOW_SYMBOL));
+                        }
+                        else
+                        {
+                            s = "";
+                            editable = FALSE;
+                        }
                     }
                     else
                     {
@@ -2324,11 +2037,6 @@
                     }
                 }
             }
-            else
-            {
-                s = "";
-                editable = FALSE;
-            }
         }
 
         if (is_split)
@@ -2362,7 +2070,7 @@
         }
 
         /* Only allow changes to entries if we have a valid split accounts */
-        editable = have_account (view, depth, expanded, trans, split);
+        editable = have_account (view, depth, expanded, is_template, trans, split);
 
         editable = (read_only == TRUE) ? FALSE : editable;
 
@@ -2373,54 +2081,72 @@
     case COL_CREDIT:
         /* Column is CREDIT and DEBIT */
         {
-            GNCPrintAmountInfo print_info;
-            print_info = gnc_account_print_info (anchor, SHOW_SYMBOL);
-
-            if (is_split)
+            if (!is_template) // Is this a template
             {
-                if (!gnc_tree_util_split_reg_get_debcred_entry (view, trans, split, is_blank, &num, &print_info))
-                    num = gnc_numeric_zero();
+                GNCPrintAmountInfo print_info;
+                print_info = gnc_account_print_info (anchor, SHOW_SYMBOL);
 
-                editable = TRUE;
-                if (get_imbalance (trans))
-                    g_object_set (cell, "cell-background", PINKCELL, (gchar*)NULL);
-            }
-            else if (is_trow1)
-            {
-                if (anchor)
+                if (is_split)
                 {
-                    editable = !expanded && !gnc_tree_util_split_reg_is_multi (get_this_split (view, trans));
-                    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 = "";
+                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)
+                        s = "";
+                    else
+                        s = xaccPrintAmount (gnc_numeric_abs (num), print_info);
+                }
             }
             else
             {
-                if ((is_trow1 || is_trow2) && expanded)
+                editable = TRUE;
+
+                if (is_trow1 || is_trow2)
+                {
                     s = "";
+                    editable = FALSE;
+                }
+                else if (is_split && viewcol == COL_DEBIT)
+                    s = gnc_tree_util_split_reg_template_get_fdebt_entry (split);
                 else
-                    s = xaccPrintAmount (gnc_numeric_abs (num), print_info);
+                    s = gnc_tree_util_split_reg_template_get_fcred_entry (split);
             }
+
+            /* Only allow changes to entries if we have a valid split accounts */
+            editable = have_account (view, depth, expanded, is_template, trans, split);
         }
-        /* Only allow changes to entries if we have a valid split accounts */
-        editable = have_account (view, depth, expanded, trans, split);
 
         editable = (read_only == TRUE) ? FALSE : editable;
 
@@ -2498,7 +2224,6 @@
     GtkTreeIter m_iter, f_iter;
     GtkTreeModel *f_model;
     GtkTreePath *mpath, *spath;
-    GtkTreePath *path;
     ViewCol viewcol;
     Transaction *trans;
     Split *split;
@@ -2542,6 +2267,16 @@
 
     row_color = gnc_tree_model_split_reg_get_row_color (model, is_trow1, is_trow2, is_split, indices[0]);
 
+    /* Lets see if the splits are expanded */
+    if (is_trow1 || is_trow2) // transaction
+    {
+        if (is_trow1)
+            gtk_tree_path_down (spath); /* Move the path down to trow2 */
+        expanded = gtk_tree_view_row_expanded (GTK_TREE_VIEW (view), spath);
+    }
+    else
+        expanded = TRUE; // splits are always expanded
+
     gtk_tree_path_free (spath);
     gtk_tree_path_free (mpath);
 
@@ -2558,18 +2293,6 @@
         open_edited = TRUE;
     }
 
-    /* Lets see if the splits are expanded */
-    if (is_trow1 || is_trow2)
-    {
-        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 */
-        expanded = gtk_tree_view_row_expanded (GTK_TREE_VIEW (view), path);
-        gtk_tree_path_free (path);
-    }
-    else
-        expanded = TRUE;
-
     switch (viewcol) {
     case COL_DATE:
         /* Column is DATE */
@@ -2620,7 +2343,6 @@
             s = "XZ";
         }
 
-
         editable = (read_only == TRUE) ? FALSE : editable;
 
         g_object_set (cell, "text", s, "editable", editable, NULL);
@@ -2686,9 +2408,109 @@
 }
 
 
-/*####################################################################
-          vvvvv    edit function call backs      vvvvvv
-#####################################################################*/
+/*###########################################################################*/
+
+/* Returns TRUE if dialog was canceled or discarded.
+   Does nothing if 'new_trans' is the dirty trans. */
+static gboolean
+transaction_changed_confirm (GncTreeViewSplitReg *view,
+                            Transaction *new_trans)
+{
+    GtkWidget            *dialog, *window;
+    GncTreeModelSplitReg *model;
+    Split                *split;
+    gint response;
+    const char *title = _("Save the changed transaction?");
+    const char *message = _(
+        "The current transaction has changed.  Would you like to "
+        "record the changes, or discard the changes?");
+
+    // Look for dirty_trans not being new_trans.
+    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;
+
+    window = gnc_tree_view_split_reg_get_parent (view);
+    dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                    GTK_DIALOG_DESTROY_WITH_PARENT,
+                                    GTK_MESSAGE_QUESTION,
+                                    GTK_BUTTONS_NONE,
+                                    "%s", title);
+    gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                                             "%s", message);
+
+    gtk_dialog_add_buttons (GTK_DIALOG(dialog),_("_Discard Changes"), GTK_RESPONSE_REJECT,
+                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                            _("_Record Changes"), GTK_RESPONSE_ACCEPT, NULL);
+
+    response = gnc_dialog_run (GTK_DIALOG (dialog), "transaction_changed");
+    gtk_widget_destroy (dialog);
+
+    switch (response)
+    {
+    case GTK_RESPONSE_ACCEPT:
+        g_object_set_data (G_OBJECT (view), "data-edited", GINT_TO_POINTER (FALSE));
+        xaccTransCommitEdit (view->priv->dirty_trans);
+        split = gnc_tree_model_split_get_blank_split (model);
+        xaccSplitReinit (split); // Clear the blank split
+        view->priv->dirty_trans = NULL;
+        view->change_allowed = FALSE;
+        view->priv->auto_complete = FALSE;
+        view->priv->trans_confirm = ACCEPT;
+        return FALSE;
+        break;
+
+    case GTK_RESPONSE_REJECT:
+        if (view->priv->dirty_trans && xaccTransIsOpen (view->priv->dirty_trans))
+        {
+            // Move selection to trans - selection is blocked
+            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);
+
+            split = gnc_tree_model_split_get_blank_split (model);
+            xaccSplitReinit (split); // Clear the blank split
+            view->change_allowed = FALSE;
+            view->priv->auto_complete = FALSE;
+            view->priv->trans_confirm = DISCARD;
+        }
+        return TRUE;
+        break;
+
+    case GTK_RESPONSE_CANCEL:
+        view->priv->trans_confirm = CANCEL;
+        return TRUE;
+        break;
+
+    default:
+        return FALSE;
+    }
+    return FALSE;
+}
+
+
+/*###########################################################################
+             vvvvv    edit function call backs      vvvvvv
+#############################################################################*/
 static void
 start_edit (GtkCellRenderer *cr, GtkCellEditable *editable,
            const gchar *path_string, gpointer user_data)
@@ -2701,7 +2523,7 @@
 
     model = gnc_tree_view_split_reg_get_model_from_view (view);
 
-    gtv_get_editable_start_editing_cb (cr, editable, path_string, user_data);
+    gtv_split_reg_editable_start_editing_cb (cr, editable, path_string, user_data);
 /*    g_signal_connect(G_OBJECT(editable), "editing-done", (GCallback) editing_done_cb, view); */
 
 //FIXME this could be the sort path instead of model path / check !!
@@ -2715,7 +2537,6 @@
 }
 
 
-
 //FIXME I am not sure if we need the split here at all ???????
 /* Open Transaction for editing and set the default currency */
 static void
@@ -2753,7 +2574,7 @@
 
 /* Call back to remove date widget */
 static void
-remove_edit_date (GtkCellEditable *ce, gpointer user_data)
+gtv_remove_edit_date (GtkCellEditable *ce, gpointer user_data)
 {
     GncTreeViewSplitReg *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
     GncPopupEntry *popup_entry;
@@ -2805,7 +2626,7 @@
 
 /* Call back to remove combo widget */
 static void
-remove_edit_combo (GtkCellEditable *ce, gpointer user_data)
+gtv_remove_edit_combo (GtkCellEditable *ce, gpointer user_data)
 {
     GncTreeViewSplitReg *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
     GtkEntry *entry; 
@@ -2842,7 +2663,7 @@
 
 /* Call back to remove entry widget */
 static void
-remove_edit_entry (GtkCellEditable *ce, gpointer user_data)
+gtv_remove_edit_entry (GtkCellEditable *ce, gpointer user_data)
 {
     GncTreeViewSplitReg *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
     const gchar *new_string; 
@@ -2923,149 +2744,8 @@
    return FALSE;
 }
 
+/*###########################################################################*/
 
-/* Returns TRUE if dialog was canceled or discarded.
-   Does nothing if 'new_trans' is the dirty trans. */
-static gboolean
-transaction_changed_confirm (GncTreeViewSplitReg *view,
-                            Transaction *new_trans)
-{
-    GtkWidget            *dialog, *window;
-    GncTreeModelSplitReg *model;
-    Split                *split;
-    gint response;
-    const char *title = _("Save the changed transaction?");
-    const char *message = _(
-        "The current transaction has changed.  Would you like to "
-        "record the changes, or discard the changes?");
-
-    // Look for dirty_trans not being new_trans. 
-    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;
-
-    window = gnc_tree_view_split_reg_get_parent (view);
-    dialog = gtk_message_dialog_new (GTK_WINDOW (window),
-                                    GTK_DIALOG_DESTROY_WITH_PARENT,
-                                    GTK_MESSAGE_QUESTION,
-                                    GTK_BUTTONS_NONE,
-                                    "%s", title);
-    gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
-                                             "%s", message);
-
-    gtk_dialog_add_buttons (GTK_DIALOG(dialog),_("_Discard Changes"), GTK_RESPONSE_REJECT,
-                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                            _("_Record Changes"), GTK_RESPONSE_ACCEPT, NULL);
-
-    response = gnc_dialog_run (GTK_DIALOG (dialog), "transaction_changed");
-    gtk_widget_destroy (dialog);
-
-    switch (response)
-    {
-    case GTK_RESPONSE_ACCEPT:
-        g_object_set_data (G_OBJECT (view), "data-edited", GINT_TO_POINTER (FALSE));
-        xaccTransCommitEdit (view->priv->dirty_trans);
-        split = gnc_tree_model_split_get_blank_split (model);
-        xaccSplitReinit (split); // Clear the blank split
-        view->priv->dirty_trans = NULL;
-        view->change_allowed = FALSE;
-        view->priv->auto_complete = FALSE;
-        view->priv->trans_confirm = ACCEPT;
-        return FALSE;
-        break;
-
-    case GTK_RESPONSE_REJECT:
-        if (view->priv->dirty_trans && xaccTransIsOpen (view->priv->dirty_trans))
-        {
-            // Move selection to trans - selection is blocked
-            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);
-
-            split = gnc_tree_model_split_get_blank_split (model);
-            xaccSplitReinit (split); // Clear the blank split
-            view->change_allowed = FALSE;
-            view->priv->auto_complete = FALSE;
-            view->priv->trans_confirm = DISCARD;
-        }
-        return TRUE;
-        break;
-
-    case GTK_RESPONSE_CANCEL:
-        view->priv->trans_confirm = CANCEL;
-        return TRUE;
-        break;
-
-    default:
-        return FALSE;
-    }
-    return FALSE;
-}
-
-
-/* Return the credit and debit titles of those columns */
-const char *
-gnc_tree_view_split_reg_get_credit_debit_string (GncTreeViewSplitReg *view, gboolean credit)
-{
-    GtkCellRenderer *cr0;
-    GList *renderers;
-    GList *columns;
-    GList  *column;
-    gint i;
-    const char *title = NULL;
-
-    columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (view));
-
-    for ( column = columns, i = 1; column; column = g_list_next (column), i++)
-    {
-        GtkTreeViewColumn *tvc;
-        ViewCol viewcol;
-
-        tvc = column->data;
-
-        // Get the first renderer, it has the view-column value.
-        renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (tvc));
-        cr0 = g_list_nth_data (renderers, 0);
-        g_list_free (renderers);
-
-        viewcol = GPOINTER_TO_INT (g_object_get_data (G_OBJECT(cr0), "view_column"));
-
-        DEBUG("viewcol is %d", viewcol);
-
-        if (viewcol == COL_CREDIT && credit)
-            title = gtk_tree_view_column_get_title (tvc);
-
-        if (viewcol == COL_DEBIT && !credit)
-            title = gtk_tree_view_column_get_title (tvc);
-    }
-    g_list_free (columns);
-    return title;
-}
-
-
-/*####################################################################
-          ^^^^^    edit function call backs      ^^^^^
-          vvvvvv   gtv function call backs       vvvvv
-#####################################################################*/
 /* Set the column titles based on register type and depth */
 static void
 gtv_split_reg_titles (GncTreeViewSplitReg *view, RowDepth depth)
@@ -3077,12 +2757,15 @@
     GList  *column;
     gint i;
     RowDepth temp_depth;
+    gboolean is_template;
 
     ENTER("title depth is %d and sort_depth %d, sort_col is %d", depth, view->sort_depth, view->sort_col);
 
     model = gnc_tree_view_split_reg_get_model_from_view (view);
     columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (view));
 
+    is_template = gnc_tree_model_split_reg_get_template (model);
+
     for ( column = columns, i = 1; column; column = g_list_next (column), i++)
     {
         GtkTreeViewColumn *tvc;
@@ -3405,6 +3088,16 @@
                         gtk_tree_view_column_set_title (tvc, _("Funds Out"));
                     break;
 
+                case SEARCH_LEDGER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                {
+                    if (!is_template)
+                        gtk_tree_view_column_set_title (tvc, _("Funds Out"));
+                    else
+                        gtk_tree_view_column_set_title (tvc, _("Credit Formula"));
+                }
+                    break;
+
                 default:
                     if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
                         gtk_tree_view_column_set_title (tvc, _("Credit"));
@@ -3476,6 +3169,16 @@
                         gtk_tree_view_column_set_title (tvc, _("Funds In"));
                     break;
 
+                case SEARCH_LEDGER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                {
+                    if (!is_template)
+                        gtk_tree_view_column_set_title (tvc, _("Funds In"));
+                    else
+                        gtk_tree_view_column_set_title (tvc, _("Debit Formula"));
+                }
+                    break;
+
                 default:
                 if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
                         gtk_tree_view_column_set_title (tvc, _("Debit"));
@@ -3733,6 +3436,7 @@
     g_signal_emit_by_name (view, "help_signal", NULL);
 }
 
+/*###########################################################################*/
 
 /* Move the selection to the blank split when expanded */
 static gboolean
@@ -3882,6 +3586,7 @@
     return FALSE;
 }
 
+/*###########################################################################*/
 
 /* This is the callback for the mouse click */
 static gboolean
@@ -4116,6 +3821,7 @@
     }
 }
 
+/*###########################################################################*/
 
 /* Callback for selection move */
 static void
@@ -4159,9 +3865,6 @@
         /* Use depth to determine if it is a split or transaction */
         depth = gtk_tree_path_get_depth (mpath);
 
-        /* Update the tree view titles */
-        gtv_split_reg_titles (view, depth);
-
         gtk_tree_path_free (mpath);
 
         gnc_tree_model_split_reg_get_split_and_trans (
@@ -4169,6 +3872,10 @@
 
         DEBUG("Get model trans %p, split %p, is_split %d, is_blank %d\n", trans, split, is_split, is_blank);
 
+        /* Update the titles if depth changes, we change rows */
+        if (depth != view->priv->current_depth)
+            gtv_split_reg_titles (view, depth);
+
         /* Move the blank split */ 
         gnc_tree_model_split_reg_set_blank_split_parent (model, trans, FALSE);
 
@@ -4237,6 +3944,7 @@
     LEAVE(" ");
 }
 
+/*###########################################################################*/
 
 /* Connected to "edited" from cellrenderer. For reference, see
    split-register-model-save.c */
@@ -4247,14 +3955,6 @@
     GncTreeViewSplitReg  *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
     GncTreeModelSplitReg *model;
     GtkCellEditable      *editable;
-    GtkTreeIter           m_iter;
-    Split                *split;
-    Transaction          *trans;
-    gboolean              is_trow1, is_trow2, is_split, is_blank;
-    ViewCol               viewcol;
-    char                 *error_loc = NULL;
-    Account              *anchor = view->priv->anchor;
-    const char           *bsplit_action = NULL;
 
     editable = g_object_get_data (G_OBJECT (cell), "cell-editable");
 
@@ -4274,6 +3974,38 @@
     if (g_strcmp0 (g_object_get_data (G_OBJECT (cell), "current-string"), new_text) == 0) // No change, return
         return;
 
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+    g_return_if_fail (model);
+
+    /* Are we using a template or not */
+    if (!gnc_tree_model_split_reg_get_template (model))
+        gtv_split_reg_edited_normal_cb (cell, path_string, new_text, view);
+    else
+        gtv_split_reg_edited_template_cb (cell, path_string, new_text, view);
+}
+
+
+/* This is used for the normal registers */
+static void
+gtv_split_reg_edited_normal_cb (GtkCellRendererText *cell, const gchar *path_string,
+               const gchar *new_text, gpointer user_data)
+{
+    GncTreeViewSplitReg  *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+    GncTreeModelSplitReg *model;
+    GtkCellEditable      *editable;
+    GtkTreeIter           m_iter;
+    Split                *split;
+    Transaction          *trans;
+    gboolean              is_trow1, is_trow2, is_split, is_blank;
+    ViewCol               viewcol;
+    char                 *error_loc = NULL;
+    Account              *anchor = view->priv->anchor;
+    const char           *bsplit_action = NULL;
+
+    editable = g_object_get_data (G_OBJECT (cell), "cell-editable");
+
+    DEBUG("cell is %p editable pointer is %p", cell, editable);
+
     g_return_if_fail (gtv_get_model_iter_from_view_string (view, path_string, &m_iter));
 
     viewcol = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cell), "view_column"));
@@ -4339,7 +4071,6 @@
              * xaccSplitSetAction with these arguments */
             gnc_set_num_action (NULL, split, NULL, new_text);
         }
-
         break;
 
     case COL_DESCNOTES:
@@ -4367,30 +4098,19 @@
         /* Column is RECONCILE */
         gtv_begin_edit (view, NULL, trans);
 
-        if (new_text != NULL)
         {
             char rec = 'n';
-            rec = new_text[0];
+            if (new_text != NULL)
+                rec = new_text[0];
 
             if (is_trow1) 
                 xaccSplitSetReconcile (get_this_split (view, trans), rec);
             if (is_split)
                 xaccSplitSetReconcile (split, rec);
         }
-        else
-        {
-            char rec = 'n';
-
-            if (is_trow1) 
-                xaccSplitSetReconcile (get_this_split (view, trans), rec);
-            if (is_split)
-                xaccSplitSetReconcile (split, rec);
-        }
-
         break;
 
     case COL_TYPE:
-
         break;
 
     case COL_TRANSFERVOID:
@@ -4413,7 +4133,7 @@
             {
                 if (!get_split_pair (view, trans, &osplit, &split))
                 {
-                    PERR("couldn't get split pair");
+                    DEBUG("couldn't get split pair");
                     break;
                 }
             }
@@ -4424,7 +4144,10 @@
                 acct = gnc_tree_control_split_reg_get_account_by_name (view, new_text);
                 if (acct == NULL)
                 {
-                    PERR("Account is NULL");
+                    DEBUG("Account is NULL");
+                    xaccSplitReinit(split);
+                    if (osplit)
+                        xaccSplitDestroy (osplit);
                     break;
                 }
 
@@ -4525,14 +4248,14 @@
             // If we are at trasaction level, column is value, split level is amount
             if (viewcol == COL_AMTVAL)
             {
-                set_number_for_input (view, trans, split, input, COL_AMTVAL);
+                gnc_tree_util_set_number_for_input (view, trans, split, input, COL_AMTVAL);
                 input_used = TRUE;
             }
 
             // The price of stock / shares
             if (viewcol == COL_PRICE)
             {
-                set_number_for_input (view, trans, split, input, COL_PRICE);
+                gnc_tree_util_set_number_for_input (view, trans, split, input, COL_PRICE);
                 input_used = TRUE;
             }
 
@@ -4541,7 +4264,7 @@
             {
                 if (!gnc_commodity_is_currency (xaccAccountGetCommodity (acct)))
                 {
-                    set_number_for_input (view, trans, split, input, viewcol);
+                    gnc_tree_util_set_number_for_input (view, trans, split, input, viewcol);
                     input_used = TRUE;
                 }
             }
@@ -4552,7 +4275,7 @@
                 if (gnc_commodity_is_currency (xaccAccountGetCommodity (acct)))
                     gnc_tree_util_split_reg_set_value_for (view, trans, split, input, force);
                 else
-                    set_value_for_amount (view, trans, split, input);
+                    gnc_tree_util_set_value_for_amount (view, trans, split, input);
             }
 
             // If this is the blank split, promote it.
@@ -4573,7 +4296,7 @@
                 if (gnc_commodity_is_currency (xaccAccountGetCommodity (acct)))
                     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)));
+                    gnc_tree_util_set_value_for_amount (view, trans, osplit, gnc_numeric_neg (xaccSplitGetValue (split)));
             }
         }
         break;
@@ -4585,10 +4308,316 @@
 }
 
 
+/* This is used for the template registers */
+static void
+gtv_split_reg_edited_template_cb (GtkCellRendererText *cell, const gchar *path_string,
+               const gchar *new_text, gpointer user_data)
+{
+    GncTreeViewSplitReg  *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+    GncTreeModelSplitReg *model;
+    GtkCellEditable      *editable;
+    GtkTreeIter           m_iter;
+    Split                *split;
+    Transaction          *trans;
+    gboolean              is_trow1, is_trow2, is_split, is_blank;
+    ViewCol               viewcol;
+    char                 *error_loc = NULL;
+    Account              *anchor = view->priv->anchor;
+    const char           *bsplit_action = NULL;
+
+    editable = g_object_get_data (G_OBJECT (cell), "cell-editable");
+
+    DEBUG("cell is %p editable pointer is %p", cell, editable);
+
+    g_return_if_fail (gtv_get_model_iter_from_view_string (view, path_string, &m_iter));
+
+    viewcol = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cell), "view_column"));
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+    g_return_if_fail (model);
+
+    gnc_tree_model_split_reg_get_split_and_trans (
+        model, &m_iter, &is_trow1, &is_trow2, &is_split, &is_blank, &split, &trans);
+
+    switch (viewcol) {
+    case COL_NUMACT:
+        /* Column is NUM / ACT */
+        gtv_begin_edit (view, NULL, trans);
+        if (is_trow1)
+        {
+            /* set per book option */
+            gnc_set_num_action (trans, get_this_split (view, trans),
+                                                                new_text, NULL);
+
+            if (!qof_book_use_split_action_for_num_field (gnc_get_current_book()))
+            {
+                // Set the last number value for this account.
+                if (gnc_strisnum (new_text) && anchor != NULL)
+                    xaccAccountSetLastNum (anchor, new_text);
+            }
+        }
+        if (is_trow2)
+        {
+            /* set per book option */
+            gnc_set_num_action (trans, get_this_split (view, trans),
+                                                                NULL, new_text);
+
+            if (qof_book_use_split_action_for_num_field (gnc_get_current_book()))
+            {
+                // Set the last number value for this account.
+                if (gnc_strisnum (new_text) && anchor != NULL)
+                    xaccAccountSetLastNum (anchor, new_text);
+            }
+        }
+        if (is_split)
+        {
+            /* Set split-action with gnc_set_num_action which is the same as
+             * xaccSplitSetAction with these arguments */
+            gnc_set_num_action (NULL, split, NULL, new_text);
+        }
+        break;
+
+    case COL_DESCNOTES:
+        /* Column is DESCRIPTION / NOTES / MEMO */
+        gtv_begin_edit (view, NULL, trans);
+        if (is_trow1)
+        {
+            xaccTransSetDescription (trans, new_text);
+            // This will potentially fill in the rest of the transaction.
+            if (view->priv->auto_complete == FALSE)
+            {
+                gnc_tree_control_auto_complete (view, trans, new_text);
+                view->priv->auto_complete = TRUE;
+            }
+        }
+        if (is_trow2)
+            xaccTransSetNotes (trans, new_text);
+
+        if (is_split)
+            xaccSplitSetMemo (split, new_text);
+
+        break;
+
+    case COL_RECN:
+        /* Column is RECONCILE */
+        gtv_begin_edit (view, NULL, trans);
+
+        {
+            char rec = 'n';
+            if (new_text != NULL)
+                rec = new_text[0];
+
+            if (is_trow1)
+                xaccSplitSetReconcile (get_this_split (view, trans), rec);
+            if (is_split)
+                xaccSplitSetReconcile (split, rec);
+        }
+        break;
+
+    case COL_TRANSFERVOID:
+    case COL_DEBIT:
+    case COL_CREDIT:
+        {
+
+            gtv_begin_edit (view, NULL, trans);
+
+            /* Setup the account field */
+            if (viewcol == COL_TRANSFERVOID)
+            {
+                Account *template_acc;
+                const GncGUID *acctGUID;
+                kvp_frame *kvpf;
+                Account *acct;
+
+                /* save the account GncGUID into the kvp_data. */
+                acct = gnc_tree_control_split_reg_get_account_by_name (view, new_text);
+                if (!acct)
+                {
+                    PERR ("unknown account");
+                    break;
+                }
+
+                acctGUID = xaccAccountGetGUID (acct);
+                kvpf = xaccSplitGetSlots (split);
+                kvp_frame_set_slot_path (kvpf, kvp_value_new_guid (acctGUID),
+                             GNC_SX_ID, GNC_SX_ACCOUNT, NULL);
+
+                template_acc = gnc_tree_model_split_reg_get_template_account (model);
+
+                /* set the actual account to the fake account for these templates */
+                xaccAccountInsertSplit (template_acc, split);
+            }
+
+            /* 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)));
+                else
+                    xaccTransSetCurrency (trans, gnc_default_currency());
+            }
+
+            // if non currency register, we set the trans currency to the first currency split
+            if (xaccTransGetCurrency (trans))
+            {
+                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)));
+                }
+            }
+
+            /* Setup the debit and credit fields */
+            if (viewcol == COL_DEBIT)
+            {
+                kvp_frame *kvpf;
+                char *error_loc;
+                gnc_numeric new_value;
+                gboolean parse_result;
+
+                kvpf = xaccSplitGetSlots (split);
+
+                DEBUG ("kvp_frame debit before: %s\n", kvp_frame_to_string (kvpf));
+
+                /* Setup the debit formula */
+                kvp_frame_set_slot_path (kvpf, kvp_value_new_string (new_text),
+                                         GNC_SX_ID,
+                                         GNC_SX_DEBIT_FORMULA,
+                                         NULL);
+
+                /* If the value can be parsed into a numeric result, store that
+                 * numeric value additionally. See above comment.*/
+                parse_result = gnc_exp_parser_parse_separate_vars (new_text, &new_value, &error_loc, NULL);
+                if (!parse_result)
+                {
+                    new_value = gnc_numeric_zero();
+                }
+                kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_value),
+                                         GNC_SX_ID,
+                                         GNC_SX_DEBIT_NUMERIC,
+                                         NULL);
+
+                DEBUG ("kvp_frame debit after: %s\n", kvp_frame_to_string (kvpf));
+
+                /* Blank the credit formula */
+                kvp_frame_set_slot_path (kvpf, kvp_value_new_string (NULL),
+                                         GNC_SX_ID,
+                                         GNC_SX_CREDIT_FORMULA,
+                                         NULL);
+
+                /* If the value can be parsed into a numeric result (without any
+                 * further variable definitions), store that numeric value
+                 * additionally in the kvp. Otherwise store a zero numeric
+                 * there.*/
+                parse_result = gnc_exp_parser_parse_separate_vars (NULL, &new_value, &error_loc, NULL);
+                if (!parse_result)
+                {
+                    new_value = gnc_numeric_zero();
+                }
+                kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_value),
+                                         GNC_SX_ID,
+                                         GNC_SX_CREDIT_NUMERIC,
+                                         NULL);
+            }
+
+            /* Setup the debit and credit fields */
+            if (viewcol == COL_CREDIT)
+            {
+                kvp_frame *kvpf;
+                char *error_loc;
+                gnc_numeric new_value;
+                gboolean parse_result;
+
+                kvpf = xaccSplitGetSlots (split);
+
+                DEBUG ("kvp_frame credit before: %s\n", kvp_frame_to_string (kvpf));
+
+                /* Setup the credit formula */
+                kvp_frame_set_slot_path (kvpf, kvp_value_new_string (new_text),
+                                             GNC_SX_ID,
+                                             GNC_SX_CREDIT_FORMULA,
+                                             NULL);
+
+                /* If the value can be parsed into a numeric result (without any
+                 * further variable definitions), store that numeric value
+                 * additionally in the kvp. Otherwise store a zero numeric
+                 * there.*/
+                parse_result = gnc_exp_parser_parse_separate_vars (new_text, &new_value, &error_loc, NULL);
+                if (!parse_result)
+                {
+                    new_value = gnc_numeric_zero();
+                }
+                kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_value),
+                                         GNC_SX_ID,
+                                         GNC_SX_CREDIT_NUMERIC,
+                                         NULL);
+
+                DEBUG ("kvp_frame credit after: %s\n", kvp_frame_to_string (kvpf));
+
+                /* Blank the debit formula */
+                kvp_frame_set_slot_path (kvpf, kvp_value_new_string (NULL),
+                                         GNC_SX_ID,
+                                         GNC_SX_DEBIT_FORMULA,
+                                         NULL);
+
+                /* If the value can be parsed into a numeric result, store that
+                 * numeric value additionally. See above comment.*/
+                parse_result = gnc_exp_parser_parse_separate_vars (NULL, &new_value, &error_loc, NULL);
+                if (!parse_result)
+                {
+                    new_value = gnc_numeric_zero();
+                }
+                kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_value),
+                                         GNC_SX_ID,
+                                         GNC_SX_DEBIT_NUMERIC,
+                                         NULL);
+            }
+            /* set the amount to an innocuous value */
+            xaccSplitSetValue (split, gnc_numeric_create (0, 1));
+
+            // Set the split parent trans
+            xaccSplitSetParent (split, trans);
+
+            // If this is the blank split, promote it.
+            if (is_blank)
+            {
+                /*FIXME May be this should be a signal - Promote the blank split to a real split */
+                g_idle_add ((GSourceFunc) gnc_tree_model_split_reg_commit_blank_split, gnc_tree_view_split_reg_get_model_from_view (view));
+
+                /* scroll when view idle */
+                g_idle_add ((GSourceFunc) gnc_tree_view_split_reg_scroll_to_cell, view);
+            }
+        }
+        break;
+
+    default:
+        //g_assert_not_reached();
+        break;
+    }
+}
+
+/*###########################################################################*/
+
 /* Parses the string value and returns true if it is a
  * number. In that case, *num is set to the value parsed. */
 static gboolean
-gnc_parse_num (const char *string, long int *num)
+gtv_split_reg_parse_num (const char *string, long int *num)
 {
     long int number;
 
@@ -4644,7 +4673,7 @@
     entered_string = gtk_editable_get_chars (editable, 0, -1);
 
     // Test for number and return it.
-    is_num = gnc_parse_num (entered_string, &number);
+    is_num = gtv_split_reg_parse_num (entered_string, &number);
 
     if (is_num && (number < 0))
         is_num = FALSE;
@@ -4690,7 +4719,7 @@
     {
         if (account != NULL)
         {
-            if (gnc_parse_num (xaccAccountGetLastNum (account), &number))
+            if (gtv_split_reg_parse_num (xaccAccountGetLastNum (account), &number))
                 number = number + 1;
             else
                 number = 1;
@@ -4868,10 +4897,11 @@
     g_signal_stop_emission_by_name (editable, "insert_text");
 }
 
+/*###########################################################################*/
 
 /* The main Start Editing Call back for the TEXT columns */
 static void
-gtv_get_editable_start_editing_cb (GtkCellRenderer *cr, GtkCellEditable *editable,
+gtv_split_reg_editable_start_editing_cb (GtkCellRenderer *cr, GtkCellEditable *editable,
                               const gchar *path_string, gpointer user_data)
 {
     GncTreeViewSplitReg  *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
@@ -4888,7 +4918,7 @@
     GtkEntryCompletion *completion = gtk_entry_completion_new();
     RowDepth depth;
 
-    ENTER("ngtv_get_editable_start_editing_cb Path string is '%s'\n", path_string);
+    ENTER("ngtv_split_reg_editable_start_editing_cb Path string is '%s'\n", path_string);
 
     model = gnc_tree_view_split_reg_get_model_from_view (view);
 
@@ -4917,7 +4947,7 @@
         //Copy the string in the GtkEntry for later comparison
         g_object_set_data (G_OBJECT (cr), "current-string", g_strdup (gtk_entry_get_text (GTK_ENTRY (GNC_POPUP_ENTRY (editable)->entry))));
 
-        g_signal_connect (G_OBJECT (editable), "remove-widget", (GCallback) remove_edit_date, view);
+        g_signal_connect (G_OBJECT (editable), "remove-widget", (GCallback) gtv_remove_edit_date, view);
 
         DEBUG("Current String date is '%s'", g_strdup (gtk_entry_get_text (GTK_ENTRY (GNC_POPUP_ENTRY (editable)->entry))));
     }
@@ -4954,7 +4984,7 @@
         g_signal_connect (G_OBJECT (GTK_ENTRY (entry)), "insert_text", (GCallback) gtv_split_reg_acct_cb, view);
 
 //??        g_signal_connect (G_OBJECT (cr), "changed", (GCallback) gtv_split_reg_changed_cb, view);
-        g_signal_connect (G_OBJECT (editable), "remove-widget", (GCallback) remove_edit_combo, view);
+        g_signal_connect (G_OBJECT (editable), "remove-widget", (GCallback) gtv_remove_edit_combo, view);
 
         DEBUG("Current String tv is '%s'", g_strdup (gtk_entry_get_text (entry)));
     }
@@ -4977,7 +5007,7 @@
 
             view->priv->fo_handler_id = g_signal_connect (G_OBJECT (editable), "focus-out-event", (GCallback) gtv_split_reg_focus_out_cb, view);
 
-            g_signal_connect (G_OBJECT (editable), "remove-widget", (GCallback) remove_edit_entry, view);
+            g_signal_connect (G_OBJECT (editable), "remove-widget", (GCallback) gtv_remove_edit_entry, view);
 
 //??        g_signal_connect (G_OBJECT (cr), "changed", (GCallback)gtv_split_reg_changed_cb, view);
             DEBUG("Current String num is '%s'", g_strdup (gtk_entry_get_text (entry)));
@@ -4993,7 +5023,7 @@
             g_object_set_data (G_OBJECT (cr), "current-string", g_strdup (gtk_entry_get_text (entry)));
 
 //??          g_signal_connect (G_OBJECT (cr), "changed", (GCallback) gtv_split_reg_changed_cb, view);
-            g_signal_connect (G_OBJECT (editable), "remove-widget", (GCallback) remove_edit_combo, view);
+            g_signal_connect (G_OBJECT (editable), "remove-widget", (GCallback) gtv_remove_edit_combo, view);
 
             DEBUG("Current String action is '%s'", g_strdup (gtk_entry_get_text (entry)));
         }
@@ -5039,7 +5069,7 @@
 
         view->priv->fo_handler_id = g_signal_connect (G_OBJECT (editable), "focus-out-event", (GCallback) gtv_split_reg_focus_out_cb, view);
 
-        g_signal_connect (G_OBJECT (editable), "remove-widget", (GCallback) remove_edit_entry, view);
+        g_signal_connect (G_OBJECT (editable), "remove-widget", (GCallback) gtv_remove_edit_entry, view);
 
         DEBUG("Current String dnm is '%s'", g_strdup (gtk_entry_get_text (GTK_ENTRY(editable))));
     }
@@ -5058,7 +5088,7 @@
 
         view->priv->fo_handler_id = g_signal_connect (G_OBJECT (editable), "focus-out-event", (GCallback) gtv_split_reg_focus_out_cb, view);
 
-        g_signal_connect (G_OBJECT (editable), "remove-widget", (GCallback) remove_edit_entry, view);
+        g_signal_connect (G_OBJECT (editable), "remove-widget", (GCallback) gtv_remove_edit_entry, view);
 
 //??        g_signal_connect (G_OBJECT (cr), "changed", (GCallback) gtv_split_reg_changed_cb, view);
         DEBUG("Current String recn is '%s'", g_strdup (gtk_entry_get_text (entry)));
@@ -5076,7 +5106,7 @@
 
         view->priv->fo_handler_id = g_signal_connect (G_OBJECT (editable), "focus-out-event", (GCallback) gtv_split_reg_focus_out_cb, view);
 
-        g_signal_connect (G_OBJECT (editable), "remove-widget", (GCallback) remove_edit_entry, view);
+        g_signal_connect (G_OBJECT (editable), "remove-widget", (GCallback) gtv_remove_edit_entry, view);
 
 //??        g_signal_connect (G_OBJECT (cr), "changed", (GCallback)gtv_split_reg_changed_cb, view);
         DEBUG("Current String rest is '%s'", g_strdup (gtk_entry_get_text (entry)));
@@ -5511,8 +5541,8 @@
 gnc_tree_view_split_reg_collapse_trans (GncTreeViewSplitReg *view, Transaction *trans)
 {
     GncTreeModelSplitReg *model;
-    GtkTreeModel *f_model, *s_model;
     GtkTreePath *temp_spath, *mpath, *spath;
+    GtkTreeIter m_iter;
     gint *indices;
     RowDepth depth;
 
@@ -5520,9 +5550,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));
-
     /* Make sure we have stopped editing */
     gnc_tree_view_split_reg_finish_edit (view);
 
@@ -5560,19 +5587,21 @@
 
         gtk_tree_view_collapse_row (GTK_TREE_VIEW (view), temp_spath);
 
-        /* Update the tree view titles */
-        gtv_split_reg_titles (view, gtk_tree_path_get_depth (temp_spath));
+        /* Get the selection */
+        if (gtv_get_model_iter_from_selection (view, gtk_tree_view_get_selection (GTK_TREE_VIEW (view)), &m_iter))
+        {
+            temp_mpath = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &m_iter);
 
-        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);
+            /* Update the tree view titles */
+            gtv_split_reg_titles (view, gtk_tree_path_get_depth (temp_mpath));
 
-        /* Save the new model path to path ref */
-        gnc_tree_view_split_reg_set_current_path (view, temp_mpath);
+            /* Save the new model path to path ref */
+            gnc_tree_view_split_reg_set_current_path (view, temp_mpath);
 
+            gtk_tree_path_free (temp_mpath);
+        }
+
         gnc_tree_view_split_reg_block_selection (view, FALSE);
-
-        gtk_tree_path_free (temp_mpath);
-        gtk_tree_path_free (temp_fpath);
     }
     else
         gtk_tree_view_collapse_row (GTK_TREE_VIEW (view), temp_spath);
@@ -5633,6 +5662,46 @@
 }
 
 
+/* Return the credit and debit titles of those columns */
+const char *
+gnc_tree_view_split_reg_get_credit_debit_string (GncTreeViewSplitReg *view, gboolean credit)
+{
+    GtkCellRenderer *cr0;
+    GList *renderers;
+    GList *columns;
+    GList  *column;
+    gint i;
+    const char *title = NULL;
+
+    columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (view));
+
+    for ( column = columns, i = 1; column; column = g_list_next (column), i++)
+    {
+        GtkTreeViewColumn *tvc;
+        ViewCol viewcol;
+
+        tvc = column->data;
+
+        // Get the first renderer, it has the view-column value.
+        renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (tvc));
+        cr0 = g_list_nth_data (renderers, 0);
+        g_list_free (renderers);
+
+        viewcol = GPOINTER_TO_INT (g_object_get_data (G_OBJECT(cr0), "view_column"));
+
+        DEBUG("viewcol is %d", viewcol);
+
+        if (viewcol == COL_CREDIT && credit)
+            title = gtk_tree_view_column_get_title (tvc);
+
+        if (viewcol == COL_DEBIT && !credit)
+            title = gtk_tree_view_column_get_title (tvc);
+    }
+    g_list_free (columns);
+    return title;
+}
+
+
 /* Returns the parent Window */
 GtkWidget *
 gnc_tree_view_split_reg_get_parent (GncTreeViewSplitReg *view)

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-24 09:10:29 UTC (rev 22930)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-view-split-reg.h	2013-05-02 14:41:56 UTC (rev 22931)
@@ -162,6 +162,9 @@
 
 void gnc_tree_view_split_reg_refilter (GncTreeViewSplitReg *view);
 
+/* Change all visable view entries */
+void gnc_tree_view_split_reg_change_vis_rows (GncTreeViewSplitReg *view);
+
 /*************************************************************************************/
 
 void gnc_tree_view_split_reg_delete_current_split (GncTreeViewSplitReg *view);

Modified: gnucash/trunk/src/register/ledger-core/gnc-ledger-display2.c
===================================================================
--- gnucash/trunk/src/register/ledger-core/gnc-ledger-display2.c	2013-04-24 09:10:29 UTC (rev 22930)
+++ gnucash/trunk/src/register/ledger-core/gnc-ledger-display2.c	2013-05-02 14:41:56 UTC (rev 22931)
@@ -616,8 +616,11 @@
     splits = qof_query_run (ld->query);
 
 //FIXME Not Needed ?    gnc_ledger_display2_set_watches (ld, splits);
-
-    gnc_ledger_display2_refresh_internal (ld, splits);
+    //gconf changes come this way, we only want a full refresh for SEARCH-LEDGER2
+    if (ld->model->type == SEARCH_LEDGER2)
+        gnc_ledger_display2_refresh_internal (ld, splits);
+    else
+        gnc_tree_view_split_reg_change_vis_rows (ld->view);
     LEAVE(" ");
 }
 
@@ -912,6 +915,7 @@
     {
 	/* This is used for the reloading of registers to refresh them and to update the search_ledger */
         ld->loading = TRUE;
+
 	s_model = gtk_tree_view_get_model (GTK_TREE_VIEW (ld->view)); // this is the sort model
         f_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (s_model)); // this is the filter model
         model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (f_model)); // our model
@@ -921,13 +925,9 @@
         g_object_ref (model);
 
         gnc_tree_view_split_reg_block_selection (ld->view, TRUE); // This blocks the tree selection
-	
         gtk_tree_view_set_model (GTK_TREE_VIEW (ld->view), NULL); // Detach sort model from view
-	
         gnc_tree_model_split_reg_load (ld->model, splits, gnc_ledger_display2_leader (ld)); //reload splits
-
         gtk_tree_view_set_model (GTK_TREE_VIEW (ld->view), GTK_TREE_MODEL (s_model)); // Re-attach sort model to view
-
         gnc_tree_view_split_reg_block_selection (ld->view, FALSE); // This unblocks the tree selection
 
         /* Set the default selection start position */



More information about the gnucash-changes mailing list