Index: src/gnome-utils/gnc-tree-view-split-reg.c
===================================================================
--- src/gnome-utils/gnc-tree-view-split-reg.c	(revision 0)
+++ src/gnome-utils/gnc-tree-view-split-reg.c	(revision 0)
@@ -0,0 +1,1488 @@
+/********************************************************************\
+ * gnc-tree-view-split-reg.c -- GtkTreeView implementation to       *
+ *                     display registers   in a GtkTreeView.        *
+ *                                                                  *
+ * Copyright (C) 2012 Robert Fewell                                 *
+ * Copyright (C) 2006-2007 Chris Shoemaker <c.shoemaker@cox.net>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <string.h>
+
+#include "gnc-tree-view.h"
+#include "gnc-tree-view-split-reg.h"
+#include "gnc-tree-model-split-reg.h"
+#include "gnc-gconf-utils.h"
+#include "Transaction.h"
+
+/** Static Globals *******************************************************/
+static QofLogModule log_module = GNC_MOD_GUI;
+
+static void gnc_tree_view_split_reg_class_init(GncTreeViewSplitRegClass *klass);
+static void gnc_tree_view_split_reg_init(GncTreeViewSplitReg *view);
+static void gnc_tree_view_split_reg_dispose(GObject *object);
+static void gnc_tree_view_split_reg_finalize(GObject *object);
+
+static void cdf (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model,
+                		GtkTreeIter  *iter, gpointer view);
+
+static void gtv_split_reg_edited_cb (GtkCellRendererText *cell, const gchar *path_string,
+                          	const gchar *new_text, gpointer _model);
+
+static void start_edit (GtkCellRenderer *cr, GtkCellEditable *editable,
+                       		const gchar *path, gpointer user_data);
+
+static void begin_edit(GncTreeViewSplitReg *tv, Split *split, Transaction *trans);
+
+static void get_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);
+
+static void gtv_split_reg_match_selected_cb(GtkEntryCompletion *widget, GtkTreeModel *model,
+                        GtkTreeIter *iter, gpointer user_data);
+
+static void gtv_split_reg_changed_cb(GtkCellRendererCombo *widget, gchar *path_string,
+                        GtkTreeIter *iter, gpointer user_data);
+
+static gboolean gtv_split_reg_key_press_cb (GtkWidget *treeview, GdkEventKey *event, gpointer userdata);
+static void gtv_split_reg_motion_cb(GtkTreeSelection *sel, gpointer data);
+
+
+typedef enum {
+    COL_DATE,
+    COL_NUMACT,
+    COL_DESCNOTES,
+    COL_TRANSVOID,
+    COL_RECN,
+    COL_TYPE,
+    COL_VALUE,
+    COL_AMOUNT,
+    COL_RATE,
+    COL_PRICE,
+    COL_DEBIT,
+    COL_CREDIT,
+    COL_BALANCE,
+} ViewCol;
+
+
+typedef struct {
+    ViewCol viewcol;
+    gint modelcol;
+    gchar *title;
+    gchar *pref_name;
+    gchar *sizer;
+    int visibility_model_col;
+    void (*edited_cb)(GtkCellRendererText *, const gchar *,
+                      const gchar *, gpointer);
+    void (*editing_started_cb)(GtkCellRenderer *, GtkCellEditable *,
+                               const gchar *, gpointer);
+    GtkTreeIterCompareFunc sort_fn;
+} ColDef;
+
+
+static ColDef all_tree_view_split_reg_columns[] = {
+    {COL_DATE, GNC_TREE_MODEL_SPLIT_REG_COL_DATE,
+     "Date", "date", "00/00/0000xxx",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
+     gtv_split_reg_edited_cb, get_editable_start_editing_cb, NULL},
+
+    {COL_NUMACT, GNC_TREE_MODEL_SPLIT_REG_COL_NUMACT,
+     "Num / Act", "numact", "0000xxx",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
+     gtv_split_reg_edited_cb, get_editable_start_editing_cb, NULL},
+
+    {COL_DESCNOTES, GNC_TREE_MODEL_SPLIT_REG_COL_DESCNOTES,
+     "Description / Notes / Memo", "descnotes", "xxxxxxxxxxxxxxxxxxx",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
+     gtv_split_reg_edited_cb, get_editable_start_editing_cb, NULL},
+
+    {COL_TRANSVOID, GNC_TREE_MODEL_SPLIT_REG_COL_TRANSVOID,
+     "Transfer / Void", "transvoid", "xxxxxxxxxxxxxxxxxxx",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
+     gtv_split_reg_edited_cb, get_editable_start_editing_cb, NULL},
+
+    {COL_RECN, -1,
+     "R", "recn", "x",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
+     gtv_split_reg_edited_cb, NULL, NULL},
+
+    {COL_TYPE, -1,
+     "Type", "type", "x",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
+     NULL, NULL, NULL},
+
+    {COL_VALUE, -1,
+     "Val", "value", "xxxxxxxx",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
+     NULL, NULL, NULL},
+
+    {COL_AMOUNT, -1,
+     "Amt", "amount", "xxxxxxxx",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
+     gtv_split_reg_edited_cb, get_editable_start_editing_cb, NULL},
+
+    {COL_RATE, -1,
+     "Rate", "rate", "xxxxxxxx",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
+     gtv_split_reg_edited_cb, get_editable_start_editing_cb, NULL},
+
+    {COL_PRICE, -1,
+     "Price", "price", "xxxxxxxx",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
+     gtv_split_reg_edited_cb, get_editable_start_editing_cb, NULL},
+
+    {COL_DEBIT, -1,
+     "Debit", "debit", "xxxxxxxx",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
+     gtv_split_reg_edited_cb, get_editable_start_editing_cb, NULL},
+
+    {COL_CREDIT, -1,
+     "Credit", "credit", "xxxxxxxx",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
+     gtv_split_reg_edited_cb, get_editable_start_editing_cb, NULL},
+
+    {COL_BALANCE, -1,
+     "Balance", "balance", "xxxxxxxx",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
+     NULL, NULL, NULL},
+};
+
+
+struct GncTreeViewSplitRegPrivate
+{
+    GtkTreeModel *tree_model;
+    gboolean disposed;
+
+    Account *anchor;
+    gnc_commodity *reg_comm;
+
+    Split *dirty_split;
+    Transaction *dirty_trans;
+
+    gchar *acct_edit_path;    // remember which row's account we're editing
+    GtkCellRenderer *temp_cr; // Temp Cell Renderer reference
+
+    gboolean has_rate;  /* if set, the transfer dialog will never automatically pop-up */
+
+    gboolean acct_short_names;
+    gboolean double_line;
+};
+
+
+#define SPLIT_TRANS_STR _("-- Split Transaction --")
+
+/* This could be a preference setting, The minimum length of the key in order to start completing */
+#define KEY_LENGTH 2
+
+#define GNC_TREE_VIEW_SPLIT_REG_GET_PRIVATE(o)  \
+   (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_TREE_VIEW_SPLIT_REG, GncTreeViewSplitRegPrivate))
+
+static GObjectClass *parent_class = NULL;
+
+GType
+gnc_tree_view_split_reg_get_type(void)
+{
+    static GType gnc_tree_view_split_reg_type = 0;
+
+    if (gnc_tree_view_split_reg_type == 0)
+    {
+        static const GTypeInfo our_info =
+        {
+            sizeof (GncTreeViewSplitRegClass),
+            NULL,
+            NULL,
+            (GClassInitFunc) gnc_tree_view_split_reg_class_init,
+            NULL,
+            NULL,
+            sizeof (GncTreeViewSplitReg),
+            0,
+            (GInstanceInitFunc) gnc_tree_view_split_reg_init
+        };
+
+        gnc_tree_view_split_reg_type = g_type_register_static (GNC_TYPE_TREE_VIEW,
+                                     "GncTreeViewSplitReg",
+                                     &our_info, 0);
+    }
+
+    return gnc_tree_view_split_reg_type;
+}
+
+
+
+static void
+gnc_tree_view_split_reg_class_init(GncTreeViewSplitRegClass *klass)
+{
+    GObjectClass *o_class;
+
+    parent_class = g_type_class_peek_parent (klass);
+
+    o_class = G_OBJECT_CLASS (klass);
+
+    o_class->dispose =  gnc_tree_view_split_reg_dispose;
+    o_class->finalize = gnc_tree_view_split_reg_finalize;
+
+    g_type_class_add_private(klass, sizeof(GncTreeViewSplitRegPrivate));
+}
+
+
+
+static void
+gnc_tree_view_split_reg_init (GncTreeViewSplitReg *view)
+{
+    view->priv = g_new0 (GncTreeViewSplitRegPrivate, 1);
+    view->priv->double_line = gnc_gconf_get_bool(GCONF_GENERAL_REGISTER, "double_line_mode", NULL);
+    view->priv->acct_short_names = gnc_gconf_get_bool(GCONF_GENERAL_REGISTER, "show_leaf_account_names", NULL);
+}
+
+
+
+static void
+gnc_tree_view_split_reg_dispose(GObject *object)
+{
+    GncTreeViewSplitReg *view;
+    GncTreeViewSplitRegPrivate *priv;
+
+    gnc_leave_return_if_fail (object != NULL);
+    gnc_leave_return_if_fail (GNC_IS_TREE_VIEW_SPLIT_REG (object));
+
+    view = GNC_TREE_VIEW_SPLIT_REG (object);
+    priv = GNC_TREE_VIEW_SPLIT_REG_GET_PRIVATE(view);
+
+    if (priv->disposed)
+        return;
+    priv->disposed = TRUE;
+
+    g_object_unref(G_OBJECT(priv->tree_model));
+    priv->tree_model = NULL;
+
+    if (G_OBJECT_CLASS (parent_class)->dispose)
+        (* G_OBJECT_CLASS (parent_class)->dispose) (object);
+}
+
+
+
+static void
+gnc_tree_view_split_reg_finalize(GObject *object)
+{
+    GncTreeViewSplitReg *view;
+
+    gnc_leave_return_if_fail(object != NULL);
+    gnc_leave_return_if_fail(GNC_IS_TREE_VIEW_SPLIT_REG (object));
+
+    view = GNC_TREE_VIEW_SPLIT_REG(object);
+
+    if (G_OBJECT_CLASS(parent_class)->finalize)
+        (* G_OBJECT_CLASS(parent_class)->finalize) (object);
+}
+
+
+
+static GncTreeModelSplitReg *
+get_split_reg_model_from_view(GncTreeViewSplitReg *tv)
+{
+    GtkTreeModelSort *s_model = GTK_TREE_MODEL_SORT(
+        gtk_tree_view_get_model(GTK_TREE_VIEW(tv)));
+    return GNC_TREE_MODEL_SPLIT_REG(gtk_tree_model_sort_get_model(s_model));
+}
+
+
+
+/* Set the grid lines to be solid */
+static const gchar *rc_string =
+{
+"style \"solidTreeLines\"\n"
+"{\n"
+" GtkTreeView::grid-line-pattern = \"\1\"\n"
+" GtkTreeView::grid-line-width = 1\n" 
+"}\n"
+"\n"
+"class \"GtkTreeView\" style \"solidTreeLines\"\n"
+};
+
+static ViewCol col_list[] = {
+    COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSVOID, COL_RECN,
+    COL_TYPE, COL_VALUE, COL_AMOUNT, COL_RATE, COL_PRICE, COL_DEBIT, COL_CREDIT,
+    COL_BALANCE, -1};
+
+/* Creates a treeview with the list of fields */
+static GncTreeViewSplitReg *
+gnc_tree_view_split_reg_set_cols(GncTreeViewSplitReg *tv,
+                                   const ViewCol col_list[])
+{
+    int i = 0;
+
+    GncTreeModelSplitReg *model;
+    model = get_split_reg_model_from_view(tv);
+
+    while (col_list && col_list[i] != -1) {
+        GtkCellRenderer *cr;
+        GtkTreeViewColumn *col;
+        ColDef def;
+        int j, ncol = G_N_ELEMENTS(all_tree_view_split_reg_columns);
+
+        for (j = 0; j < ncol; j++) {
+            if (col_list[i] == all_tree_view_split_reg_columns[j].viewcol) {
+                def = all_tree_view_split_reg_columns[j];
+                break;
+            }
+        }
+        if (j == ncol) {
+            PERR("Failed to find column definition.");
+            i++;
+            continue;
+        }
+
+        if (col_list[i] == COL_TRANSVOID) {
+
+            col = gnc_tree_view_add_combo_column (
+                GNC_TREE_VIEW(tv), def.title, def.pref_name, def.sizer,
+                def.modelcol, def.visibility_model_col,
+                GTK_TREE_MODEL( gnc_tree_model_split_reg_get_acct_list(model)), 0, def.sort_fn);
+
+        } else if (col_list[i] == COL_DATE) {
+            col = gnc_tree_view_add_date_column (
+                GNC_TREE_VIEW(tv), def.title, def.pref_name, NULL, def.sizer,
+                def.modelcol, def.visibility_model_col, def.sort_fn);
+
+        } else if (col_list[i] == COL_NUMACT){ 
+            col = gnc_tree_view_add_combo_column (
+                GNC_TREE_VIEW(tv), def.title, def.pref_name, def.sizer,
+                def.modelcol, def.visibility_model_col,
+                GTK_TREE_MODEL( gnc_tree_model_split_reg_get_numact_list(model)), 0, def.sort_fn);
+
+        } else { 
+            col = gnc_tree_view_add_text_column (
+                GNC_TREE_VIEW(tv), def.title, def.pref_name, NULL, def.sizer,
+                def.modelcol, def.visibility_model_col, def.sort_fn);
+        } 
+
+        g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
+        cr = gnc_tree_view_column_get_renderer(col);
+
+
+        /* Setup cell background color and default alignment */
+        g_object_set( cr, "xalign", 1.0, NULL );
+        gtk_tree_view_column_add_attribute(col, cr, "cell-background", GNC_TREE_MODEL_SPLIT_REG_COL_COLOR);
+
+        if (def.editing_started_cb) {
+            //Store the position of the column in the model
+            g_object_set_data(G_OBJECT(cr), "model_column", GINT_TO_POINTER(def.modelcol));
+            g_signal_connect(G_OBJECT(cr), "editing-started", (GCallback) def.editing_started_cb, tv);
+        }
+
+        //Connect editing-canceled signal so that edit-cancelled can be set appropriately
+        g_signal_connect(G_OBJECT(cr), "editing-canceled", G_CALLBACK(gtv_split_reg_editing_canceled_cb), tv);
+
+        // This can die when prefs are used.
+        g_object_set(G_OBJECT(col), "resizable", TRUE, NULL);
+
+        if (def.edited_cb) {
+            g_object_set(G_OBJECT(cr), "editable", TRUE, NULL);
+            g_signal_connect(G_OBJECT(cr), "edited", (GCallback) def.edited_cb, tv);
+        }
+        g_object_set_data(G_OBJECT(cr), "view_column", GINT_TO_POINTER(def.viewcol));
+        gtk_tree_view_column_set_cell_data_func( col, cr, cdf, tv, NULL);
+        i++;
+    }
+
+    gnc_tree_view_configure_columns(GNC_TREE_VIEW(tv));
+
+    g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)), "changed", G_CALLBACK(gtv_split_reg_motion_cb), tv);
+
+    //Add a data-edited property to keep track of transaction edits
+    g_object_set_data(G_OBJECT(tv), "data-edited", FALSE);
+
+    //???? gtk_tree_selection_set_mode(gtk_tree_view_get_selection(tv), GTK_SELECTION_BROWSE);
+
+/*    g_signal_connect_after(G_OBJECT(tv), "key-press-event", G_CALLBACK(gtv_split_reg_key_press_cb), NULL); */
+    return tv;
+}
+
+
+
+GncTreeViewSplitReg*
+gnc_tree_view_split_reg_new_with_model(GncTreeModelSplitReg *model)
+{
+    GtkTreeModel *s_model;
+    GncTreeViewSplitReg *tv;
+    GtkCellRenderer *cr;
+    GtkTreeViewColumn *col;
+    GtkTreeSelection    *selection;
+
+    gtk_rc_parse_string ( rc_string );
+
+    tv = g_object_new(gnc_tree_view_split_reg_get_type(), NULL);
+    g_object_set(tv, "name", "split_reg_tree", NULL);
+
+    s_model = gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(model));
+/*FIXME  should we  g_object_unref(G_OBJECT(model)); */
+    gnc_tree_view_set_model(GNC_TREE_VIEW(tv), s_model);
+    g_object_unref(G_OBJECT(s_model));
+
+    tv->priv->anchor = gnc_tree_model_split_reg_get_anchor(model);
+    tv->priv->reg_comm = xaccAccountGetCommodity(tv->priv->anchor);
+    tv->priv->has_rate = TRUE;  /*FIXME Not sure what this ????? */
+
+    gnc_tree_view_split_reg_set_cols(tv, col_list);
+
+    /* Set default visibilities */
+    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(tv), TRUE);
+
+    /* TreeView Grid lines */
+    if(gnc_gconf_get_bool(GCONF_GENERAL_REGISTER, "draw_horizontal_lines", NULL))
+    {
+        if(gnc_gconf_get_bool(GCONF_GENERAL_REGISTER, "draw_vertical_lines", NULL))
+            gtk_tree_view_set_grid_lines( GTK_TREE_VIEW(tv), GTK_TREE_VIEW_GRID_LINES_BOTH);
+        else
+            gtk_tree_view_set_grid_lines( GTK_TREE_VIEW(tv), GTK_TREE_VIEW_GRID_LINES_HORIZONTAL);
+    }
+    else if(gnc_gconf_get_bool(GCONF_GENERAL_REGISTER, "draw_vertical_lines", NULL))
+            gtk_tree_view_set_grid_lines( GTK_TREE_VIEW(tv), GTK_TREE_VIEW_GRID_LINES_VERTICAL);
+    else
+        gtk_tree_view_set_grid_lines( GTK_TREE_VIEW(tv), GTK_TREE_VIEW_GRID_LINES_NONE);
+
+
+    /* Expanders off */
+    /* gtk_tree_view_set_show_expanders (GTK_TREE_VIEW(view), FALSE); */
+
+    /* Tree Selection */
+    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv));
+
+    gtk_tree_selection_unselect_all( selection );
+
+/*
+
+    gnc_tree_view_configure_columns(view);
+
+    gtk_widget_show(GTK_WIDGET(view)); */
+    return tv;
+}
+
+
+
+/* Returns a value for display. */
+static gnc_numeric
+get_value_for(GncTreeViewSplitReg *tv, Transaction *trans,
+              Split *split, gboolean is_blank)
+{
+    gnc_commodity *currency = xaccTransGetCurrency(trans);
+    gnc_numeric total;
+
+    total = xaccSplitGetValue(split);
+
+    if (is_blank && gnc_numeric_zero_p(total)) {
+        gnc_numeric rate;
+        total = gnc_numeric_neg(xaccTransGetImbalanceValue(trans));
+        if (!gnc_numeric_zero_p(total)) {
+
+            if (!xaccTransGetRateForCommodity(
+                    trans, tv->priv->reg_comm, NULL, &rate))
+                return gnc_numeric_zero();
+
+            total = gnc_numeric_mul(
+                total, rate,
+                gnc_commodity_get_fraction (currency),
+                GNC_HOW_RND_ROUND);
+        }
+    } else {
+        if (!gnc_numeric_zero_p(total) &&
+            gnc_numeric_check(total) == GNC_ERROR_OK) {
+
+            /* fixme: if needs conversion? */
+            gnc_commodity *commodity = tv->priv->reg_comm;
+/*FIXME  ??          if (commodity && !gnc_commodity_equiv(commodity, currency))
+                total = xaccSplitConvertAmount(split, commodity); */
+        }
+    }
+    return total;
+}
+
+
+
+static gnc_numeric
+get_rate_for(GncTreeViewSplitReg *tv, Transaction *trans,
+              Split *split, gboolean is_blank)
+{
+    gnc_numeric num;
+
+    num = get_value_for(tv, trans, split, is_blank);
+    num = gnc_numeric_div(
+        xaccSplitGetAmount(split), num,
+        GNC_DENOM_AUTO, GNC_HOW_RND_ROUND);
+    return num;
+}
+
+
+
+/* Returns the other Split based on the current Account */
+static Split *
+get_other_split(GncTreeViewSplitReg *tv, Transaction *trans)
+{
+    int i;
+    Split *split = NULL;
+    Account *anchor = tv->priv->anchor;
+
+    for (i = 0; (split = xaccTransGetSplit(trans, i)); i++) {
+        if (anchor == xaccSplitGetAccount(split))
+            return xaccSplitGetOtherSplit(split);
+    }
+    return NULL;
+}
+
+
+
+/* Returns a Split that matches the current Account */
+static Split *
+get_this_split(GncTreeViewSplitReg *tv, Transaction *trans)
+{
+    int i;
+    Split *split = NULL;
+    Account *anchor = tv->priv->anchor;
+
+    for (i = 0; (split = xaccTransGetSplit(trans, i)); i++) {
+        if (anchor == xaccSplitGetAccount(split))
+            return split;
+    }
+    return NULL;
+}
+
+
+
+static gboolean
+get_model_iter_from_selection(GncTreeViewSplitReg *tv,
+                              GtkTreeSelection *sel, GtkTreeIter *iter)
+{
+    GtkTreeModel *s_model;
+    GtkTreeIter s_iter;
+
+    if (gtk_tree_selection_get_selected(sel, &s_model, &s_iter)) {
+        gtk_tree_model_sort_convert_iter_to_child_iter(
+            GTK_TREE_MODEL_SORT(s_model), iter, &s_iter);
+        return TRUE;
+    }
+    return FALSE;
+
+}
+
+
+
+/* Instead of setting a different cellDataFunc for each column, we just
+   collect everything here and use this one func. */
+static void
+cdf(GtkTreeViewColumn *col, GtkCellRenderer *cell, GtkTreeModel *s_model,
+    GtkTreeIter *s_iter, gpointer data)
+{
+    GncTreeViewSplitReg *tv = GNC_TREE_VIEW_SPLIT_REG(data);
+    GncTreeModelSplitReg *model;
+    GtkTreeIter iter;
+    GtkTreePath *path;
+    ViewCol viewcol;
+    gboolean is_split, is_blank, is_trow1, is_trow2;
+    gboolean editable, expanded;
+
+    gchar *cell_color;
+    gint depth, *indices;
+
+    Account *anchor = tv->priv->anchor;
+    Split *split;
+    Transaction *trans;
+
+    gnc_numeric num;
+    const gchar *s = "";
+
+    ENTER("");
+
+    model = get_split_reg_model_from_view(tv);
+
+    gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(s_model), &iter, s_iter);
+
+    viewcol = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cell), "view_column"));
+
+    g_return_if_fail(gnc_tree_model_split_reg_get_split_and_trans(
+                         GNC_TREE_MODEL_SPLIT_REG(model), &iter,
+                          &is_trow1, &is_trow2, &is_split, &is_blank,
+                          &split, &trans));
+
+    depth = gtk_tree_path_get_depth (gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter));
+
+/* g_print(" cdf depth is %d\n", depth); */
+
+    /* This expands to split from top level and you cannot collapse split, may be needed
+    if (depth == 2)
+        gtk_tree_view_expand_to_path (GTK_TREE_VIEW(tv), gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter));
+    */
+
+    /* This gives me double lines, you can not collapse them */
+    if ((tv->priv->double_line) && (depth == 1))
+        gtk_tree_view_expand_to_path (GTK_TREE_VIEW(tv), gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter));
+
+    indices = gtk_tree_path_get_indices (gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter));
+
+/* g_print(" cdf path is %s\n", gtk_tree_path_to_string (gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter))); */
+
+    switch (viewcol) {
+    case COL_DATE:
+        /* Column is DATE */
+        if (is_split)
+            g_object_set(cell, "cell-background", "white", (gchar*)NULL);
+
+        if (is_trow1) {
+            Timespec ts = {0,0};
+            xaccTransGetDatePostedTS (trans, &ts);
+            //If the time returned by xaccTransGetDatePostedTS is 0 then assume it
+            //is a new transaction and set the time to current time to show current
+            //date on new transactions
+            if (ts.tv_sec == 0)
+            {
+                ts.tv_sec = time(NULL);
+                //xaccTransSetDatePostedSecs(trans, ts.tv_sec);
+            }//if
+            s = gnc_print_date(ts);
+            editable = TRUE;
+        }
+        else {
+            s = "";
+            editable = FALSE;
+        }
+        /* This will remove the calander buttons if FALSE, preference may be ? */
+        g_object_set(cell, "use_buttons", TRUE, NULL ); 
+        g_object_set(cell, "text", s, "editable", editable, NULL);
+        break;
+
+    case COL_NUMACT:
+        /* Column is NUM/ACT */
+        /* Override default alignment */
+        g_object_set( cell, "xalign", 0.0, NULL );
+
+        if (is_trow1)
+           s = xaccTransGetNum(trans);
+        else if (is_trow2)
+           s = xaccSplitGetAction(get_this_split(tv, trans));
+        else if (is_split)
+           s = xaccSplitGetAction(split);
+
+        g_object_set(cell, "text", s, "editable", TRUE, NULL);
+        break;
+
+    case COL_DESCNOTES:
+        /* Column is DESCRIPTION / NOTES */
+        /* Override default alignment */
+        g_object_set( cell, "xalign", 0.0, NULL );
+        if (is_trow1)
+            s =  xaccTransGetDescription (trans);
+        else if (is_trow2)
+            s =  xaccTransGetNotes(trans);
+        else if (is_split)
+            s = xaccSplitGetMemo(split);
+
+        g_object_set(cell, "text", s, NULL);
+        break;
+
+    case COL_TRANSVOID:
+        /* Column is TRANSFER / VOID */
+
+        /* Not sure if this will stay here, this sets the combo column
+           0 for short account names, 1 for long */
+        if (tv->priv->acct_short_names)
+            g_object_set(G_OBJECT(cell), "text-column", 0, NULL );
+        else
+            g_object_set(G_OBJECT(cell), "text-column", 1, NULL );
+
+        if (is_trow1) {
+            gint count = xaccTransCountSplits(trans);
+            path = gtk_tree_model_get_path(s_model, s_iter);
+            gtk_tree_path_down (path); /* Move the path down to trow2 */
+            expanded = gtk_tree_view_row_expanded(GTK_TREE_VIEW(tv), path);
+            if (count == 0 || expanded) {
+                s = ""; /* blank-out if splits are visible */
+            } else if (2 == count) {
+                Account *acct;
+                Split *osplit;
+                osplit = get_other_split(tv, trans);
+                acct = xaccSplitGetAccount(osplit);
+                if(tv->priv->acct_short_names)
+                    s = xaccAccountGetName(acct);
+                else
+                    s = gnc_account_get_full_name(acct);
+            } else {
+                s = SPLIT_TRANS_STR;
+            }
+            editable = anchor && !expanded && ((2 == count) || (0 == count));
+            gtk_tree_path_free(path);
+        }
+        if (is_trow2) {
+            s = xaccTransGetVoidReason(trans); /* This is the Void Reason */
+            editable = FALSE;
+        }
+        if (is_split) {
+            Account *acct = xaccSplitGetAccount(split);
+            if(anchor == acct)
+                editable = FALSE;
+            else
+                editable = TRUE;
+            if(tv->priv->acct_short_names)
+                s = xaccAccountGetName(acct);
+            else
+                s = gnc_account_get_full_name(acct);
+        }
+        g_object_set(cell, "text", s, "editable", editable, NULL);
+        break;
+
+    case COL_RECN:
+        /* Column is RECN */
+        if (is_trow1) {
+            static char ss[2];
+            char rec = xaccSplitGetReconcile(get_this_split(tv, trans));
+            if (rec == VREC || rec == FREC || rec == YREC)
+                editable = FALSE;
+            else
+                editable = TRUE;
+
+            ss[0] = rec;
+            ss[1] = '\0';
+            g_object_set(cell, "text", ss, "editable", editable, NULL);
+
+        } else {
+            s = "";
+            editable = FALSE;
+            g_object_set(cell, "text", s, "editable", editable, NULL);
+        }
+
+        if (is_split) {
+            static char ss[2];
+            char rec = xaccSplitGetReconcile(split);
+            if (rec == VREC || rec == FREC || rec == YREC)
+                editable = FALSE;
+            else
+                editable = TRUE;
+
+            ss[0] = rec;
+            ss[1] = '\0';
+            g_object_set(cell, "text", ss, "editable", editable, NULL);
+        }
+
+        break;
+
+    case COL_TYPE:
+        /* Column is TYPE */
+        if (is_trow1) {
+            static char ss[2];
+            char type = xaccTransGetTxnType(trans);
+            if (type == TXN_TYPE_NONE)
+                type = '?';
+
+            ss[0] = type;
+            ss[1] = '\0';
+            g_object_set(cell, "text", ss, NULL);
+        }
+        else
+        {
+            s = "";
+            g_object_set(cell, "text", s, NULL);
+        }
+        break;
+
+    case COL_AMOUNT:
+        /* Column is AMOUNT */
+       if (is_split) {
+            gnc_numeric amt = xaccSplitGetAmount(split);
+            s = xaccPrintAmount(amt, gnc_account_print_info( xaccSplitGetAccount(split), TRUE));
+            editable = TRUE;
+        } else {
+            s = "";
+            editable = FALSE;
+        }
+        g_object_set(cell, "text", s, "editable", editable, NULL);
+        break;
+
+    case COL_VALUE:
+        /* Column is VALUE */
+        if (is_split) {
+            gnc_numeric amt = xaccSplitGetValue(split);
+            s = xaccPrintAmount(amt, gnc_commodity_print_info( xaccTransGetCurrency(trans), TRUE));
+        } else {
+            s = "";
+            editable = FALSE;
+        }
+        g_object_set(cell, "text", s, NULL);
+        break;
+
+    case COL_RATE:
+        /* Column is RATE */
+        if ((is_trow1)||(is_trow2)) {
+            s = "";
+            editable = FALSE;
+        } else {
+            gnc_commodity *split_com = xaccAccountGetCommodity( xaccSplitGetAccount(split));
+            num = get_rate_for(tv, trans, split, is_blank);
+            if (gnc_numeric_check(num) == GNC_ERROR_OK) {
+                s = xaccPrintAmount(num, gnc_split_amount_print_info(split, FALSE));
+                editable = !gnc_numeric_zero_p(num) &&
+                    !gnc_commodity_equiv(split_com, tv->priv->reg_comm);
+            } else {
+                s = "";
+                editable = FALSE;
+            }
+        }
+        g_object_set(cell, "text", s, "editable", editable, NULL);
+        break;
+
+    case COL_PRICE:
+        /* Column is PRICE */
+        if ((is_trow1)||(is_trow2)) {
+            s = "";
+            editable = FALSE;
+        } else {
+            num = xaccSplitGetSharePrice(split);
+
+            if (gnc_numeric_check(num) == GNC_ERROR_OK) {
+                s = xaccPrintAmount(num, gnc_split_amount_print_info(split, FALSE));
+                editable = FALSE;
+            } else {
+                s = "";
+                editable = FALSE;
+            }
+        }
+        g_object_set(cell, "text", s, "editable", editable, NULL);
+        break;
+
+    case COL_DEBIT:
+    case COL_CREDIT:
+        /* Column is CREDIT and DEBIT */
+        if (is_split) {
+            num = get_value_for(tv, trans, split, is_blank);
+            editable = TRUE;
+        } else if (is_trow1) {
+            //comm = xaccTransGetCurrency(trans);
+            if (anchor) {
+                gint count = xaccTransCountSplits(trans);
+                path = gtk_tree_model_get_path(s_model, s_iter);
+                expanded = gtk_tree_view_row_expanded(GTK_TREE_VIEW(tv), path);
+                editable = !expanded && ((2 == count) || (0 == count));
+                num = xaccTransGetAccountAmount(trans, anchor);
+            } else {
+                editable = FALSE;
+                num = gnc_numeric_zero();
+                /* CHECKME: Should trans cred/debit fields in unanchored reg
+                   show imbalances? I don't think so. */
+            }
+        } 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_CREDIT) ||
+            (gnc_numeric_positive_p(num) && viewcol == COL_DEBIT)) {
+            s = "";
+        } else {
+            s = xaccPrintAmount(gnc_numeric_abs(num),
+                                gnc_account_print_info(anchor, TRUE)); //FIXME: TRUE just for debugging maybe
+        }
+        g_object_set(cell, "text", s, "editable", editable, NULL);
+        break;
+
+    case COL_BALANCE:
+        /* Column is BALANCE */
+        if (is_trow1 && anchor) {
+            num = xaccTransGetAccountBalance(trans, anchor);
+            if (gnc_reverse_balance(anchor))
+                num = gnc_numeric_neg(num);
+            s = xaccPrintAmount(num, gnc_account_print_info(anchor, TRUE));
+            if (gnc_numeric_negative_p(num)
+                && gnc_gconf_get_bool(GCONF_GENERAL, KEY_NEGATIVE_IN_RED, NULL))
+                g_object_set(cell, "foreground", "red", (gchar*)NULL);
+            else
+                g_object_set(cell, "foreground", NULL, (gchar*)NULL);
+        } else {
+            s = "";
+        }
+        g_object_set(cell, "text", s, NULL);
+        break;
+
+    default:
+        break;
+    }
+    LEAVE("");
+}
+
+
+
+/*####################################################################
+          vvvvv    edit function call backs      vvvvvv
+#####################################################################*/
+static void
+start_edit(GtkCellRenderer *cr, GtkCellEditable *editable,
+           const gchar *path_string, gpointer user_data)
+{
+    GncTreeViewSplitReg *tv = GNC_TREE_VIEW_SPLIT_REG(user_data);
+g_print("start_edit\n");
+/*FIXME Not sure if this is required, leave for now ? */
+    get_editable_start_editing_cb(cr, editable, path_string, user_data);
+/*    g_signal_connect(G_OBJECT(editable), "editing-done", (GCallback) editing_done_cb, tv); */
+    tv->priv->acct_edit_path = g_strdup(path_string);
+
+    return;
+}
+
+
+/* means: open trans for editing, unless we're editing a Split (split
+   != NULL) AND split doesn't belong to the trans (because it is the
+   blank split) */
+static void
+begin_edit(GncTreeViewSplitReg *tv, Split *split, Transaction *trans)
+{
+g_print("begin edit\n");
+    /* explain me -- this may need changing */
+    if (split && trans != xaccSplitGetParent(split))
+        return;
+    if (trans != tv->priv->dirty_trans) {
+        xaccTransBeginEdit(trans);
+        tv->priv->dirty_trans = trans;
+        if (!xaccTransGetCurrency(trans)) {
+            xaccTransSetCurrency(trans, tv->priv->reg_comm);
+        }
+    }
+}
+
+
+
+static void
+remove_edit_date(GtkCellEditable *ce, gpointer user_data)
+{
+    GncTreeViewSplitReg *tv = GNC_TREE_VIEW_SPLIT_REG(user_data);
+    GncPopupEntry *popup_entry;
+    const gchar *new_string; 
+    const gchar *current_string;
+
+    //These strings are used to determine if cell data was altered so
+    //that keynav works better
+g_print("remove edit date\n");
+
+    popup_entry = GNC_POPUP_ENTRY(g_object_get_data( G_OBJECT(tv->priv->temp_cr), "cell-editable"));
+
+    new_string = g_strdup(gtk_entry_get_text(GTK_ENTRY(popup_entry->entry)));
+g_print("New String is '%s'\n", new_string);	
+
+    current_string = g_object_get_data(G_OBJECT( tv->priv->temp_cr), "current-string");
+g_print("Current String is '%s'\n\n", current_string);
+
+    //If editing wasn't canceled and strings don't match then
+    //cell data was edited
+    if (!g_object_get_data(G_OBJECT(tv->priv->temp_cr), "edit-canceled") 
+             && g_ascii_strcasecmp(new_string, current_string))
+    {
+        g_object_set_data(G_OBJECT(tv), "data-edited", (gpointer)TRUE);
+    }
+
+    g_object_set_data(G_OBJECT(tv->priv->temp_cr), "cell-editable", NULL);
+    tv->priv->temp_cr = NULL;
+    g_free(tv->priv->acct_edit_path);
+    tv->priv->acct_edit_path = NULL;
+}
+
+
+
+static void
+remove_edit_combo(GtkCellEditable *ce, gpointer user_data)
+{
+    GncTreeViewSplitReg *tv = GNC_TREE_VIEW_SPLIT_REG(user_data);
+    GtkEntry *entry; 
+    const gchar *new_string; 
+    const gchar *current_string;
+
+    //These strings are used to determine if cell data was altered so
+    //that keynav works better
+g_print("remove edit combo\n");
+
+    entry = GTK_ENTRY (gtk_bin_get_child(GTK_BIN ( g_object_get_data( G_OBJECT(tv->priv->temp_cr), "cell-editable"))));
+
+    new_string = gtk_entry_get_text(GTK_ENTRY(entry));
+g_print("New String is '%s'\n", new_string);	
+
+    current_string = g_object_get_data(G_OBJECT( tv->priv->temp_cr), "current-string");
+g_print("Current String is '%s'\n\n", current_string);
+
+    //If editing wasn't canceled and strings don't match then
+    //cell data was edited
+    if (!g_object_get_data(G_OBJECT(tv->priv->temp_cr), "edit-canceled") 
+             && g_ascii_strcasecmp(new_string, current_string))
+    {
+        g_object_set_data(G_OBJECT(tv), "data-edited", (gpointer)TRUE);
+    }
+
+    g_object_set_data(G_OBJECT(tv->priv->temp_cr), "cell-editable", NULL);
+    tv->priv->temp_cr = NULL;
+    g_free(tv->priv->acct_edit_path);
+    tv->priv->acct_edit_path = NULL;
+}
+
+
+
+static void
+remove_edit_completion(GtkCellEditable *ce, gpointer user_data)
+{
+    GncTreeViewSplitReg *tv = GNC_TREE_VIEW_SPLIT_REG(user_data);
+    const gchar *new_string; 
+    const gchar *current_string; 
+
+g_print("remove edit completion\n");
+
+    //These strings are used to determine if cell data was altered so
+    //that keynav works better
+    new_string = gtk_entry_get_text(GTK_ENTRY(g_object_get_data( G_OBJECT(tv->priv->temp_cr), "cell-editable")));
+g_print("New String is '%s'\n", new_string);
+
+    current_string = g_object_get_data(G_OBJECT( tv->priv->temp_cr), "current-string");
+g_print("Current String is '%s'\n\n", current_string);
+
+    //If editing wasn't canceled and strings don't match then
+    //cell data was edited
+    if (!g_object_get_data(G_OBJECT(tv->priv->temp_cr), "edit-canceled") 
+             && g_ascii_strcasecmp(new_string, current_string))
+    {
+        g_object_set_data(G_OBJECT(tv), "data-edited", (gpointer)TRUE);
+    }
+
+    g_object_set_data(G_OBJECT(tv->priv->temp_cr), "cell-editable", NULL);
+    tv->priv->temp_cr = NULL;
+    g_free(tv->priv->acct_edit_path);
+    tv->priv->acct_edit_path = NULL;
+}
+
+
+
+/* Explain: GtkEntry has a cursor that blinks upon
+   g_timeout_dispatch().  It complains if it blinks after the GtkEntry
+   loses focus.  So, we can't pop up any dialogs while the blinking
+   cursor is around.  The solution is to force the editing to be
+   finished before raising the dialog.  That finalizes the
+   gtkcelleditable. */
+static void
+finish_edit(GtkTreeViewColumn *col)
+{
+    GtkCellRenderer *cr;
+    GtkCellEditable *ce;
+g_print("finish_edit\n");
+/*FIXME Not used yet, leave for now */
+    if (!col) return;
+    cr = gnc_tree_view_column_get_renderer(col);
+    if ((ce = GTK_CELL_EDITABLE(g_object_get_data(G_OBJECT(cr), "cell-editable")))) {
+        gtk_cell_editable_editing_done(ce);
+    }
+}
+
+
+
+/*####################################################################
+          ^^^^^    edit function call backs      ^^^^^
+          vvvvvv   gtv function call backs       vvvvv
+#####################################################################*/
+static void
+gtv_split_reg_motion_cb(GtkTreeSelection *sel, gpointer data)
+{
+
+    GtkTreeIter iter;
+    GncTreeViewSplitReg *tv = GNC_TREE_VIEW_SPLIT_REG(data);
+    GncTreeModelSplitReg *model; 
+    Split *split = NULL;
+    Transaction *trans = NULL;
+    gboolean is_trow1, is_trow2, is_split, is_blank;
+    GtkTreeViewColumn *numact, *descnotes, *transvoid;
+    gint depth;
+    const gchar *path_string;
+
+    model = get_split_reg_model_from_view(tv);
+
+g_print("gtv_split_reg_motion_cb\n\n");
+
+    numact = gtk_tree_view_get_column(GTK_TREE_VIEW(tv), 1);
+    descnotes = gtk_tree_view_get_column(GTK_TREE_VIEW(tv), 2);
+    transvoid = gtk_tree_view_get_column(GTK_TREE_VIEW(tv), 3);
+
+    if (get_model_iter_from_selection(tv, sel, &iter))
+    {
+        gnc_tree_model_split_reg_get_split_and_trans (
+            GNC_TREE_MODEL_SPLIT_REG(model), &iter, &is_trow1, &is_trow2, &is_split, &is_blank, &split, &trans);
+
+        path_string = gtk_tree_path_to_string (gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter));
+
+g_print("Path is '%s'\n", path_string);
+
+       /* Use depth to determine if it is a split or parent transaction */
+       depth = gtk_tree_path_get_depth(gtk_tree_path_new_from_string(path_string));
+
+       if (depth == 1)
+       {
+           gtk_tree_view_column_set_title(numact, _("Number"));
+           gtk_tree_view_column_set_title(descnotes, _("Description"));
+           gtk_tree_view_column_set_title(transvoid, _("Accounts"));
+       }
+       else if (depth == 2)
+       {
+           gtk_tree_view_column_set_title(numact, _("Action"));
+           gtk_tree_view_column_set_title(descnotes, _("Notes"));
+           gtk_tree_view_column_set_title(transvoid, _("Void"));
+       }     
+       else if (depth == 3)
+       {
+           gtk_tree_view_column_set_title(numact, _("Action"));
+           gtk_tree_view_column_set_title(descnotes, _("Memo"));
+           gtk_tree_view_column_set_title(transvoid, _("Accounts"));
+       }
+    }
+    else
+    {
+        /* We end up here if tree collapse and no row selected */
+        gtk_tree_view_column_set_title(numact, _("Num / Act"));
+        gtk_tree_view_column_set_title(descnotes, _("Description / Notes / Memo"));
+        gtk_tree_view_column_set_title(transvoid, _("Transfer / Void"));
+    }
+}
+
+
+
+/* Connected to "edited" from cellrenderer. For reference, see
+   split-register-model-save.c */
+static void
+gtv_split_reg_edited_cb(GtkCellRendererText *cell, const gchar *path_string,
+               const gchar *new_text, gpointer data)
+{
+    GtkTreeIter iter;
+    GtkTreeIter copy_iter;
+    GtkEntryCompletion *completion;
+    Split *split;
+    Transaction *trans;
+    GncTreeViewSplitReg *tv = GNC_TREE_VIEW_SPLIT_REG(data);
+    ViewCol viewcol;
+    gboolean is_trow1, is_trow2, is_split, is_blank;
+    GncTreeModelSplitReg *model;
+    char *error_loc = NULL;
+    Account *anchor = tv->priv->anchor;
+
+g_print("gtv_split_reg_edited_cb\n\n");
+
+/*    g_return_if_fail(get_model_iter_from_view_string(tv, path_string, &iter)); */
+
+    viewcol = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cell), "view_column"));
+
+    model = get_split_reg_model_from_view(tv);
+    g_return_if_fail(model);
+
+    gnc_tree_model_split_reg_get_split_and_trans (
+        model, &iter, &is_trow1, &is_trow2, &is_split, &is_blank, &split, &trans);
+
+g_print("New text is '%s'\n", new_text);
+
+    switch (viewcol) {
+    case COL_DATE:
+        /* Column is DATE */
+/*FIXME        begin_edit(tv, split, trans); */
+        if (is_trow1)
+        {
+/* New_text would need to be converted to time_t */
+/*            xaccTransSetDatePostedSecs (trans, time); */
+
+        }
+        break;
+
+    case COL_NUMACT:
+        /* Column is NUM / ACT */
+/*FIXME        begin_edit(tv, split, trans); */
+
+        if (is_trow1)
+        {
+/*            xaccTransSetNum(trans, new_text); */
+
+        }
+        if (is_trow2)
+        {
+           /*FIXME Not sure if this will need to be changed */
+/*            xaccSplitSetAction(split, new_text); */
+
+        }
+
+        if (is_split)
+        {
+/*            xaccSplitSetAction(split, new_text); */
+
+        }
+        break;
+
+    case COL_DESCNOTES:
+        /* Column is DESCRIPTION / NOTES */
+/*FIXME        begin_edit(tv, split, trans); */
+        if (is_trow1)
+        {
+/*            xaccTransSetDescription(trans, new_text); */
+/*FIXME May need to add new entries to list **
+            gtk_list_store_append(GTK_LIST_STORE(g_object_get_data(G_OBJECT(tv), "desc_copy")), &copy_iter);
+            gtk_list_store_set(GTK_LIST_STORE(g_object_get_data(G_OBJECT(tv), "desc_copy")), &copy_iter, 0, new_text, -1);
+*/
+        }
+        if (is_trow2)
+        {
+/*            xaccTransSetNotes(trans, new_text); */
+/*FIXME May need to add new entries to list **
+            gtk_list_store_append(GTK_LIST_STORE(g_object_get_data(G_OBJECT(tv), "notes_copy")), &copy_iter);
+            gtk_list_store_set(GTK_LIST_STORE(g_object_get_data(G_OBJECT(tv), "notes_copy")), &copy_iter, 0, new_text, -1); 
+*/
+        }
+        if (is_split)
+        {
+/*            xaccSplitSetMemo(split, new_text); */
+/*FIXME May need to add new entries to list **
+            gtk_list_store_append(GTK_LIST_STORE(g_object_get_data(G_OBJECT(tv), "memo_copy")), &copy_iter);
+            gtk_list_store_set(GTK_LIST_STORE(g_object_get_data(G_OBJECT(tv), "memo_copy")), &copy_iter, 0, new_text, -1); 
+*/
+        }
+        break;
+
+    case COL_TRANSVOID:
+    case COL_RECN:
+    case COL_TYPE:
+    case COL_VALUE:
+    case COL_AMOUNT:
+    case COL_RATE:
+    case COL_PRICE:
+    case COL_DEBIT:
+    case COL_CREDIT:
+        break;
+
+    default:
+        //g_assert_not_reached();
+        break;
+    }
+}
+
+
+
+/* The main Start Editing Call back for the TEXT columns */
+static void
+get_editable_start_editing_cb(GtkCellRenderer *cr, GtkCellEditable *editable,
+                              const gchar *path_string, gpointer user_data)
+{
+    GncTreeViewSplitReg *tv = GNC_TREE_VIEW_SPLIT_REG(user_data);
+    GncTreeModelSplitReg *model;
+
+    GtkListStore *description_list;
+    GtkListStore *memo_list;
+    GtkListStore *notes_list;
+    GtkListStore *acct_list;
+
+    GtkEntryCompletion *completion = gtk_entry_completion_new();
+    gint depth;
+
+    ENTER(" ");
+g_print("get_editable_start_editing_cb\n\n");
+
+    model = get_split_reg_model_from_view(tv);
+
+    description_list = gnc_tree_model_split_reg_get_description_list(model);
+    notes_list = gnc_tree_model_split_reg_get_notes_list(model);
+    memo_list = gnc_tree_model_split_reg_get_memo_list(model);
+    acct_list = gnc_tree_model_split_reg_get_acct_list(model);
+
+g_print("editable Path string is '%s'\n", path_string);
+
+    //Use depth to determine if it is a split or transaction
+    depth = gtk_tree_path_get_depth(gtk_tree_path_new_from_string(path_string));
+
+g_print("editable Depth is %u\n", depth);
+
+    /* DATE COLUMN */
+    if (GNC_TREE_MODEL_SPLIT_REG_COL_DATE 
+        == GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cr), "model_column")))
+    {
+        g_object_set_data(G_OBJECT(cr), "cell-editable", editable);
+        //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, tv);
+
+g_print("Current String is '%s'\n", g_strdup(gtk_entry_get_text(GTK_ENTRY(GNC_POPUP_ENTRY(editable)->entry))));
+
+    }
+
+    /* TRANSFER / VOID COLUMN */
+    if (GNC_TREE_MODEL_SPLIT_REG_COL_TRANSVOID 
+        == GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cr), "model_column")))
+    {
+        GtkEntry *entry;
+
+        entry = GTK_ENTRY (gtk_bin_get_child(GTK_BIN (editable)));
+
+        gtk_entry_set_completion (GTK_ENTRY (entry), completion);
+        gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (acct_list));
+
+        /* This sets which text column to use, 0 for short names, 1 for long */
+        if (tv->priv->acct_short_names)
+            gtk_entry_completion_set_text_column (completion, 0);
+        else
+            gtk_entry_completion_set_text_column (completion, 1);
+
+        gtk_entry_completion_set_popup_completion (completion, TRUE);
+        gtk_entry_completion_set_inline_selection (completion, TRUE);
+        gtk_entry_completion_set_popup_set_width (completion, FALSE);
+        gtk_entry_completion_set_minimum_key_length (completion, KEY_LENGTH);
+/*??        g_signal_connect(G_OBJECT(completion), "match-selected", (GCallback)gtv_split_reg_match_selected_cb, tv); */
+        g_object_unref (completion);
+
+        g_object_set_data(G_OBJECT(cr), "cell-editable", editable);
+        //Copy the string in the GtkEntry for later comparison
+        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, tv);
+        g_signal_connect(G_OBJECT(editable), "remove-widget", (GCallback) remove_edit_combo, tv);
+g_print("Current String is '%s'\n", g_strdup(gtk_entry_get_text(entry)));
+
+    }
+
+    /* NUMBER / ACTION COLUMN */
+    if (GNC_TREE_MODEL_SPLIT_REG_COL_NUMACT 
+        == GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cr), "model_column")))
+    {
+        GtkEntry *entry;
+
+        if (depth == 1)
+            gnc_tree_model_split_reg_get_num_list(model);
+
+        else if (depth == 2)
+            gnc_tree_model_split_reg_get_action_list(model);
+
+        else if (depth == 3)
+            gnc_tree_model_split_reg_get_action_list(model);
+
+        entry = GTK_ENTRY (gtk_bin_get_child(GTK_BIN (editable)));
+
+        g_object_set_data(G_OBJECT(cr), "cell-editable", editable);
+        //Copy the string in the GtkEntry for later comparison
+        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, tv); */
+        g_signal_connect(G_OBJECT(editable), "remove-widget", (GCallback) remove_edit_combo, tv);
+g_print("Current String is '%s'\n", g_strdup(gtk_entry_get_text(entry)));
+
+    }
+
+    /* DESCRIPTION / NOTES / MEMO COLUMN */
+    if (GNC_TREE_MODEL_SPLIT_REG_COL_DESCNOTES 
+        == GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cr), "model_column")))
+    {
+        //Data used for completion is set based on if editing split or not
+        if (depth == 1)
+        {
+            gtk_entry_set_completion (GTK_ENTRY (editable), completion);
+            gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (description_list));
+            gtk_entry_completion_set_text_column (completion, 0);
+        }
+        else if (depth == 2)
+        {
+            gtk_entry_set_completion (GTK_ENTRY (editable), completion);
+            gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (notes_list));
+            gtk_entry_completion_set_text_column (completion, 0);
+        }
+        else if (depth == 3)
+        {
+            gtk_entry_set_completion (GTK_ENTRY (editable), completion);
+            gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (memo_list));
+            gtk_entry_completion_set_text_column (completion, 0);
+        }
+
+        //To emit "match-selected" signal we need to have a list of matches to
+        //select from instead of using inline autocompletion
+        gtk_entry_completion_set_popup_completion (completion, TRUE);
+        gtk_entry_completion_set_inline_selection (completion, TRUE);
+        gtk_entry_completion_set_minimum_key_length (completion, KEY_LENGTH);
+/*??        g_signal_connect(G_OBJECT(completion), "match-selected", (GCallback)gtv_split_reg_match_selected_cb, tv); */
+
+        g_object_unref (completion);
+
+        g_object_set_data(G_OBJECT(cr), "cell-editable", editable);
+        //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(editable))));
+        g_signal_connect(G_OBJECT(editable), "remove-widget", (GCallback) remove_edit_completion, tv);
+g_print("Current String is '%s'\n", g_strdup(gtk_entry_get_text(GTK_ENTRY(editable))));
+
+    }
+
+    tv->priv->temp_cr = cr;
+    //Add edit-canceled property to cr so we can distinguish between
+    //cancelled and actual changes
+    g_object_set_data(G_OBJECT(cr), "edit-canceled", FALSE);
+
+    LEAVE(" ");
+}
+
+
+
+//Handle the "match-selected" signal
+static void
+gtv_split_reg_match_selected_cb(GtkEntryCompletion *widget, GtkTreeModel *model,
+                        GtkTreeIter *iter, gpointer user_data)
+{
+    GncTreeViewSplitReg *tv = GNC_TREE_VIEW_SPLIT_REG(user_data);
+
+    gboolean is_trow1, is_trow2, is_split, is_blank;
+
+g_print("gtv_split_reg_match_selected_cb\n\n");
+
+/* Not sure what I am going to put in here yet */
+
+}
+
+
+//Handle the "changed" signal
+static void
+gtv_split_reg_changed_cb(GtkCellRendererCombo *widget, gchar *path_string,
+                        GtkTreeIter *iter, gpointer user_data)
+{
+    GncTreeViewSplitReg *tv = GNC_TREE_VIEW_SPLIT_REG(user_data);
+
+    gboolean is_trow1, is_trow2, is_split, is_blank;
+
+g_print("gtv_split_reg_changed_cb\n\n");
+g_print("Path String is '%s'\n", path_string);
+
+/* Not sure what I am going to put in here yet */
+
+}
+
+
+//Handle the "editing-canceled" signal
+static void
+gtv_split_reg_editing_canceled_cb(GtkCellRenderer *cr, gpointer user_data)
+{
+    GncTreeViewSplitReg *tv = GNC_TREE_VIEW_SPLIT_REG(user_data);
+g_print("gtv_split_reg_editing_canceled_cb\n\n");
+
+    //Set edit-canceled property
+    g_object_set_data(G_OBJECT(cr), "edit-canceled", (gpointer)TRUE);	
+}
+
+/*####################################################################
+          ^^^^   gtv function call backs    ^^^^
+#####################################################################*/
+
Index: src/gnome-utils/gnc-tree-view-split-reg.h
===================================================================
--- src/gnome-utils/gnc-tree-view-split-reg.h	(revision 0)
+++ src/gnome-utils/gnc-tree-view-split-reg.h	(revision 0)
@@ -0,0 +1,69 @@
+/********************************************************************\
+ * gnc-tree-view-split-reg.c -- GtkTreeView implementation to       *
+ *                     display registers   in a GtkTreeView.        *
+ *                                                                  *
+ * Copyright (C) 2012 Robert Fewell                                 *
+ * Copyright (C) 2006-2007 Chris Shoemaker <c.shoemaker@cox.net>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+
+#ifndef __GNC_TREE_VIEW_SPLIT_REG_H
+#define __GNC_TREE_VIEW_SPLIT_REG_H
+
+#include <gtk/gtk.h>
+#include "gnc-tree-view.h"
+
+#include "gnc-tree-model-split-reg.h"
+#include "gnc-ui-util.h"
+
+G_BEGIN_DECLS
+
+#define GNC_TYPE_TREE_VIEW_SPLIT_REG            (gnc_tree_view_split_reg_get_type ())
+#define GNC_TREE_VIEW_SPLIT_REG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_TREE_VIEW_SPLIT_REG, GncTreeViewSplitReg))
+#define GNC_TREE_VIEW_SPLIT_REG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GNC_TYPE_TREE_VIEW_SPLIT_REG, GncTreeViewSplitRegClass))
+#define GNC_IS_TREE_VIEW_SPLIT_REG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNC_TYPE_TREE_VIEW_SPLIT_REG))
+#define GNC_IS_TREE_VIEW_SPLIT_REG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNC_TYPE_TREE_VIEW_SPLIT_REG))
+#define GNC_TREE_VIEW_SPLIT_REG_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GNC_TYPE_TREE_VIEW_SPLIT_REG, GncTreeViewSplitRegClass))
+
+/* typedefs & structures */
+typedef struct GncTreeViewSplitRegPrivate GncTreeViewSplitRegPrivate;
+
+typedef struct
+{
+    GncTreeView gnc_tree_view;
+    GncTreeViewSplitRegPrivate *priv;
+    int stamp;
+
+} GncTreeViewSplitReg;
+
+typedef struct
+{
+    GncTreeViewClass gnc_tree_view;
+} GncTreeViewSplitRegClass;
+
+/* Standard g_object type */
+GType gnc_tree_view_split_reg_get_type(void);
+
+GncTreeViewSplitReg *gnc_tree_view_split_reg_new_with_model(GncTreeModelSplitReg *model);
+
+G_END_DECLS
+
+#endif /* __GNC_TREE_VIEW_SPLIT_REG_H */
Index: src/gnome-utils/gnc-cell-renderer-popup-entry.c
===================================================================
--- src/gnome-utils/gnc-cell-renderer-popup-entry.c	(revision 0)
+++ src/gnome-utils/gnc-cell-renderer-popup-entry.c	(revision 0)
@@ -0,0 +1,281 @@
+/*************************************************************************
+ * The following code has come from Planner. This code implements a
+ * GtkCalendar in a custom GtkCellEditable popup from GtkCellRenderer.
+ *
+ * These files have been renamed and changed to remove code not required
+ * and to remove a dependency on libplanner.
+ *
+ * Copyright (C) 2012 Robert Fewell
+ *
+ * Copyright (C) 2001-2002 CodeFactory AB
+ * Copyright (C) 2001-2002 Richard Hult <richard@imendio.com>
+ * Copyright (C) 2001-2002 Mikael Hallendal <micke@imendio.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *************************************************************************/
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+#include <string.h>
+
+#include "gnc-cell-renderer-popup-entry.h"
+
+static void     gnc_popup_entry_init       (GncPopupEntry        *entry);
+static void     gnc_popup_entry_class_init (GncPopupEntryClass   *class);
+static void     gpw_cell_editable_init     (GtkCellEditableIface *iface);
+static gboolean gpw_key_press_event        (GtkWidget            *box,
+					    GdkEventKey          *key_event);
+
+enum {
+	ARROW_CLICKED,
+	LAST_SIGNAL
+};
+
+enum {
+  ARG_0,
+  ARG_EDITING_CANCELED
+};
+
+static GtkEventBoxClass *parent_class;
+static guint signals[LAST_SIGNAL];
+
+GtkType
+gnc_popup_entry_get_type (void)
+{
+	static GtkType widget_type = 0;
+	
+	if (!widget_type) {
+		static const GTypeInfo widget_info = {
+			sizeof (GncPopupEntryClass),
+			NULL,		/* base_init */
+			NULL,		/* base_finalize */
+			(GClassInitFunc) gnc_popup_entry_class_init,
+			NULL,		/* class_finalize */
+			NULL,		/* class_data */
+			sizeof (GncPopupEntry),
+			0,              /* n_preallocs */
+			(GInstanceInitFunc) gnc_popup_entry_init,
+		};
+
+		static const GInterfaceInfo cell_editable_info = {
+			(GInterfaceInitFunc) gpw_cell_editable_init,    /* interface_init */
+			NULL,                                           /* interface_finalize */
+			NULL                                            /* interface_data */
+		};
+      
+		widget_type = g_type_register_static (GTK_TYPE_EVENT_BOX,
+						      "GncPopupEntry",
+						      &widget_info,
+						      0);
+		
+		g_type_add_interface_static (widget_type,
+					     GTK_TYPE_CELL_EDITABLE,
+					     &cell_editable_info);
+	}
+	
+	return widget_type;
+}
+
+static void
+gnc_popup_entry_init (GncPopupEntry *widget)
+{
+	GtkWidget *arrow;
+
+	widget->hbox = gtk_hbox_new (FALSE, 0);
+	gtk_widget_show (widget->hbox);
+
+	widget->entry = g_object_new (GTK_TYPE_ENTRY, "has_frame", FALSE, NULL);
+	GTK_ENTRY (widget->entry)->is_cell_renderer = TRUE;
+	gtk_widget_show (widget->entry);
+
+	widget->button = gtk_button_new ();
+	gtk_widget_show (widget->button);
+
+	arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
+	gtk_widget_show (arrow);
+
+	gtk_container_add (GTK_CONTAINER (widget->button), arrow);
+
+	gtk_box_pack_start (GTK_BOX (widget->hbox), widget->entry, TRUE, TRUE, 0);
+	gtk_box_pack_start (GTK_BOX (widget->hbox), widget->button, FALSE, TRUE, 0);
+
+	gtk_container_add (GTK_CONTAINER (widget), widget->hbox);
+
+	GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
+	gtk_widget_add_events (GTK_WIDGET (widget), GDK_KEY_PRESS_MASK);
+	gtk_widget_add_events (GTK_WIDGET (widget), GDK_KEY_RELEASE_MASK);
+}
+
+static void
+gnc_popup_entry_class_init (GncPopupEntryClass *klass)
+{
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+	widget_class->key_press_event = gpw_key_press_event;
+
+        gtk_object_add_arg_type ("GncPopupEntry::editing-canceled", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_EDITING_CANCELED);
+	
+	parent_class = GTK_EVENT_BOX_CLASS (g_type_class_peek_parent (klass));
+
+	signals[ARROW_CLICKED] = g_signal_new
+		("arrow-clicked",
+		 G_TYPE_FROM_CLASS (klass),
+		 G_SIGNAL_RUN_LAST,
+		 0,
+		 NULL, NULL,
+		 g_cclosure_marshal_VOID__VOID,
+		 G_TYPE_NONE, 0);
+
+}
+
+static void
+gpw_arrow_clicked (GtkWidget *button, GncPopupEntry *widget)
+{
+	g_signal_emit (widget, signals[ARROW_CLICKED], 0);
+}
+	
+/* GtkCellEditable method implementations
+ */
+static void
+gtk_cell_editable_entry_activated (GtkEntry *entry, GncPopupEntry *widget)
+{
+	gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (widget));
+	gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (widget));
+}
+
+static gboolean
+gtk_cell_editable_key_press_event (GtkEntry      *entry,
+				   GdkEventKey   *key_event,
+				   GncPopupEntry *widget)
+{
+	if (key_event->keyval == GDK_Escape) {
+		widget->editing_canceled = TRUE;
+		
+		gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (widget));
+		gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (widget));
+		
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static gboolean
+gpw_key_press_event (GtkWidget   *box,
+		     GdkEventKey *key_event)
+{
+	GncPopupEntry *widget = GNC_POPUP_ENTRY (box);
+	GdkEvent       tmp_event;
+	
+	if (key_event->keyval == GDK_Escape) {
+		widget->editing_canceled = TRUE;
+
+		gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (widget));
+		gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (widget));
+		
+		return TRUE;
+	}
+
+	gtk_widget_grab_focus (widget->entry);
+
+	/* Hackish :/ Synthesize a key press event for the entry. */
+	memcpy (&tmp_event, key_event, sizeof (GdkEventKey));
+
+	tmp_event.key.window = widget->entry->window;
+	tmp_event.key.send_event = TRUE;
+	
+	gtk_widget_event (widget->entry, &tmp_event);
+
+	return GTK_WIDGET_CLASS (parent_class)->key_press_event (GTK_WIDGET (widget), 
+								 key_event);
+}
+
+static void
+gpw_start_editing (GtkCellEditable *cell_editable,
+		   GdkEvent        *event)
+{
+	GncPopupEntry *widget = GNC_POPUP_ENTRY (cell_editable);
+
+	gtk_editable_select_region (GTK_EDITABLE (widget->entry), 0, -1);
+
+	g_signal_connect (G_OBJECT (widget->entry),
+			  "activate",
+			  G_CALLBACK (gtk_cell_editable_entry_activated),
+			  widget);
+	g_signal_connect (G_OBJECT (widget->entry),
+			  "key_press_event",
+			  G_CALLBACK (gtk_cell_editable_key_press_event),
+			  widget);
+	g_signal_connect (G_OBJECT (widget->button),
+			  "clicked",
+			  (GCallback) gpw_arrow_clicked,
+			  widget);
+}
+
+static void
+gpw_cell_editable_init (GtkCellEditableIface *iface)
+{
+	iface->start_editing = gpw_start_editing;
+}
+
+void
+gnc_popup_entry_set_text (GncPopupEntry *popup, const gchar *text)
+{
+	g_return_if_fail (GNC_IS_POPUP_ENTRY (popup));
+
+	gtk_entry_set_text (GTK_ENTRY (popup->entry), text ? text : "");
+}
+
+const gchar *
+gnc_popup_entry_get_text (GncPopupEntry *popup)
+{
+	g_return_val_if_fail (GNC_IS_POPUP_ENTRY (popup), NULL);
+
+	return gtk_entry_get_text (GTK_ENTRY (popup->entry));
+}
+
+gint
+gnc_popup_get_button_width (void)
+{
+	GtkWidget *window, *button, *arrow;
+	gint       width;
+
+	GtkRequisition req;
+	
+	window = gtk_window_new (GTK_WINDOW_POPUP);
+	
+	button = gtk_button_new ();
+	gtk_widget_show (button);
+	gtk_container_add (GTK_CONTAINER (window), button);
+
+	arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
+	gtk_widget_show (arrow);
+	gtk_container_add (GTK_CONTAINER (button), arrow);
+
+	gtk_window_move (GTK_WINDOW (window), -500, -500);
+	gtk_widget_show (window);
+
+	gtk_widget_size_request (window, &req);
+	
+	width = req.width;
+
+	gtk_widget_destroy (window);
+
+	return width;
+}
+
Index: src/gnome-utils/gnc-cell-renderer-popup-entry.h
===================================================================
--- src/gnome-utils/gnc-cell-renderer-popup-entry.h	(revision 0)
+++ src/gnome-utils/gnc-cell-renderer-popup-entry.h	(revision 0)
@@ -0,0 +1,74 @@
+/*************************************************************************
+ * The following code has come from Planner. This code implements a
+ * GtkCalendar in a custom GtkCellEditable popup from GtkCellRenderer.
+ *
+ * These files have been renamed and changed to remove code not required
+ * and to remove a dependency on libplanner.
+ *
+ * Copyright (C) 2012 Robert Fewell
+ *
+ * Copyright (C) 2001-2002 CodeFactory AB
+ * Copyright (C) 2001-2002 Richard Hult <richard@imendio.com>
+ * Copyright (C) 2001-2002 Mikael Hallendal <micke@imendio.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *************************************************************************/
+
+#ifndef __GNC_POPUP_ENTRY_H__
+#define __GNC_POPUP_ENTRY_H__
+
+#include <pango/pango.h>
+#include <gtk/gtkeventbox.h>
+
+#define GNC_TYPE_POPUP_ENTRY		(gnc_popup_entry_get_type ())
+#define GNC_POPUP_ENTRY(obj)		(GTK_CHECK_CAST ((obj), GNC_TYPE_POPUP_ENTRY, GncPopupEntry))
+#define GNC_POPUP_ENTRY_CLASS(klass)	(GTK_CHECK_CLASS_CAST ((klass), GNC_TYPE_POPUP_ENTRY, GncPopupEntryClass))
+#define GNC_IS_POPUP_ENTRY(obj)		(GTK_CHECK_TYPE ((obj), GNC_TYPE_POPUP_ENTRY))
+#define GNC_IS_POPUP_ENTRY_CLASS(klass)	(GTK_CHECK_CLASS_TYPE ((obj), GNC_TYPE_POPUP_ENTRY))
+#define GNC_POPUP_ENTRY_GET_CLASS(obj)	(GTK_CHECK_GET_CLASS ((obj), GNC_TYPE_POPUP_ENTRY, GncPopupEntryClass))
+
+typedef struct _GncPopupEntry      GncPopupEntry;
+typedef struct _GncPopupEntryClass GncPopupEntryClass;
+
+struct _GncPopupEntry
+{
+	GtkEventBox  parent;
+
+	GtkWidget   *hbox;
+	GtkWidget   *button;
+	GtkWidget   *entry;
+
+	gboolean     editing_canceled;
+};
+
+struct _GncPopupEntryClass
+{
+	GtkEventBoxClass parent_class;
+};
+
+GtkType      gnc_popup_entry_get_type   (void) G_GNUC_CONST;
+
+GtkWidget   *gnc_popup_entry_new        (void);
+
+void         gnc_popup_entry_set_text   (GncPopupEntry *popup,
+					const gchar  *text);
+
+const gchar *gnc_popup_entry_get_text   (GncPopupEntry *popup);
+
+gint         gnc_popup_get_button_width (void);
+
+
+#endif /* __GNC_POPUP_ENTRY_H__ */
Index: src/gnome-utils/gnc-tree-model-split-reg.c
===================================================================
--- src/gnome-utils/gnc-tree-model-split-reg.c	(revision 0)
+++ src/gnome-utils/gnc-tree-model-split-reg.c	(revision 0)
@@ -0,0 +1,1621 @@
+/********************************************************************\
+ * gnc-tree-model-split-reg.c -- GtkTreeView implementation to      *
+ *                     display registers   in a GtkTreeView.        *
+ *                                                                  *
+ * Copyright (C) 2012 Robert Fewell                                 *
+ * Copyright (C) 2006-2007 Chris Shoemaker <c.shoemaker@cox.net>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <string.h>
+
+#include "gnc-tree-model-split-reg.h"
+#include "gnc-component-manager.h"
+#include "gnc-commodity.h"
+#include "gnc-gconf-utils.h"
+#include "gnc-engine.h"
+#include "gnc-event.h"
+#include "gnc-gobject-utils.h"
+#include "Query.h"
+#include "Transaction.h"
+
+#include "gnc-ui-util.h"
+
+#define TREE_MODEL_SPLIT_REG_CM_CLASS "tree-model-split-reg"
+
+/** Static Globals *******************************************************/
+static QofLogModule log_module = GNC_MOD_GUI;
+
+/** Declarations *********************************************************/
+static void gnc_tree_model_split_reg_class_init (GncTreeModelSplitRegClass *klass);
+static void gnc_tree_model_split_reg_init (GncTreeModelSplitReg *model);
+static void gnc_tree_model_split_reg_finalize (GObject *object);
+static void gnc_tree_model_split_reg_dispose (GObject *object);
+
+/** Implementation of GtkTreeModel  **************************************/
+static void gnc_tree_model_split_reg_tree_model_init (GtkTreeModelIface *iface);
+
+static GtkTreeModelFlags gnc_tree_model_split_reg_get_flags (GtkTreeModel *tree_model);
+static int gnc_tree_model_split_reg_get_n_columns (GtkTreeModel *tree_model);
+static GType gnc_tree_model_split_reg_get_column_type (GtkTreeModel *tree_model, int index);
+static gboolean gnc_tree_model_split_reg_get_iter (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path);
+static GtkTreePath *gnc_tree_model_split_reg_get_path (GtkTreeModel *tree_model, GtkTreeIter *iter);
+static void gnc_tree_model_split_reg_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter, int column, GValue *value);
+static gboolean	gnc_tree_model_split_reg_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter);
+static gboolean	gnc_tree_model_split_reg_iter_children (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent);
+static gboolean	gnc_tree_model_split_reg_iter_has_child (GtkTreeModel *tree_model, GtkTreeIter *iter);
+static int gnc_tree_model_split_reg_iter_n_children (GtkTreeModel *tree_model, GtkTreeIter *iter);
+static gboolean	gnc_tree_model_split_reg_iter_nth_child (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, int n);
+static gboolean	gnc_tree_model_split_reg_iter_parent (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child);
+
+/** Component Manager Callback ******************************************/
+static void gnc_tree_model_split_reg_event_handler (QofInstance *entity, QofEventId event_type, GncTreeModelSplitReg *model, GncEventData *ed);
+
+static void create_completion_models(GncTreeModelSplitReg *model);
+
+/** The instance private data for the split register tree model. */
+struct GncTreeModelSplitRegPrivate
+{
+    QofBook *book;
+    Account *anchor;
+    Query   *query;
+
+    GList *tlist;
+    GList *slist;
+
+    gboolean use_colors;
+    gboolean double_line;
+    gboolean alt_colors_by_txn;
+
+
+    GtkListStore *description_list;
+    GtkListStore *notes_list;
+    GtkListStore *memo_list;
+    GtkListStore *num_list;
+    GtkListStore *numact_list;
+
+    gint event_handler_id;
+};
+
+
+#define GREENROW "#BFDEB9"
+#define TANROW "#F6FFDA"
+#define SPLITROW "#EDE7D3"
+#define YELLOWROW "#FFEF98"
+
+
+#define TROW1 0x1
+#define TROW2 0x2
+#define SPLIT 0x4
+#define BLANK 0x8
+#define IS_TROW1(x) (GPOINTER_TO_INT((x)->user_data) & TROW1)
+#define IS_TROW2(x) (GPOINTER_TO_INT((x)->user_data) & TROW2)
+#define IS_BLANK(x) (GPOINTER_TO_INT((x)->user_data) & BLANK)
+#define IS_SPLIT(x) (GPOINTER_TO_INT((x)->user_data) & SPLIT)
+#define IS_BLANK_SPLIT(x) (IS_BLANK(x) && IS_SPLIT(x))
+#define IS_BLANK_TRANS(x) (IS_BLANK(x) && !IS_SPLIT(x))
+/* Meaning of user_data fields in iter struct:
+ *
+ * user_data:  a bitfield for BLANK, SPLIT, TROW1, TROW2
+ * user_data2: a pointer to a node in a GList of Transactions               
+ * user_data3: a pointer to a node in a GList of Splits.
+ *            
+ */
+
+/* FIXME ***********************
+#define VALID_ITER(model, iter) \
+    (GNC_IS_TREE_MODEL_SPLIT_REG(model) &&                            \
+     ((iter) && (iter)->user_data2) &&                                  \
+     ((iter)->stamp == (model)->stamp) &&                               \
+     (!IS_SPLIT(iter) ^ ((iter)->user_data3 != NULL)) &&                \
+     (!IS_BLANK_SPLIT(iter) ||                                          \
+      ((iter)->user_data2 == (model)->priv->bsplit_parent_node))        \
+     )
+*/
+static GtkTreeIter
+make_iter(GncTreeModelSplitReg *model, gint f, GList *tnode, GList *snode)
+{
+    GtkTreeIter iter, *iter_p;
+    iter_p = &iter;
+    iter.stamp = model->stamp;
+    iter.user_data = GINT_TO_POINTER(f);
+    iter.user_data2 = tnode;
+    iter.user_data3 = snode;
+
+/*    if (!VALID_ITER(model, &iter)) PERR("Making invalid iter"); */
+    return iter;
+}
+
+
+
+#define GNC_TREE_MODEL_SPLIT_REG_GET_PRIVATE(o)  \
+   (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_TREE_MODEL_SPLIT_REG, GncTreeModelSplitRegPrivate))
+
+/************************************************************/
+/*               g_object required functions                */
+/************************************************************/
+
+/** A pointer to the parent class of the split register tree model. */
+static GtkObjectClass *parent_class = NULL;
+
+GType
+gnc_tree_model_split_reg_get_type (void)
+{
+    static GType gnc_tree_model_split_reg_type = 0;
+
+    if (gnc_tree_model_split_reg_type == 0)
+    {
+        static const GTypeInfo our_info =
+        {
+            sizeof (GncTreeModelSplitRegClass),                /* class_size */
+            NULL,                                              /* base_init */
+            NULL,                                              /* base_finalize */
+            (GClassInitFunc) gnc_tree_model_split_reg_class_init,
+            NULL,                                               /* class_finalize */
+            NULL,                                               /* class_data */
+            sizeof (GncTreeModelSplitReg),                      /* */
+            0,                                                  /* n_preallocs */
+            (GInstanceInitFunc) gnc_tree_model_split_reg_init
+        };
+
+        static const GInterfaceInfo tree_model_info =
+        {
+            (GInterfaceInitFunc) gnc_tree_model_split_reg_tree_model_init,
+            NULL,
+            NULL
+        };
+
+        gnc_tree_model_split_reg_type = g_type_register_static (GNC_TYPE_TREE_MODEL,
+                                      GNC_TREE_MODEL_SPLIT_REG_NAME,
+                                      &our_info, 0);
+
+        g_type_add_interface_static (gnc_tree_model_split_reg_type,
+                                     GTK_TYPE_TREE_MODEL,
+                                     &tree_model_info);
+    }
+
+    return gnc_tree_model_split_reg_type;
+}
+
+
+
+static void
+gnc_tree_model_split_reg_class_init (GncTreeModelSplitRegClass *klass)
+{
+    GObjectClass *o_class;
+
+    parent_class = g_type_class_peek_parent (klass);
+
+    o_class = G_OBJECT_CLASS (klass);
+
+    /* GObject signals */
+    o_class->finalize = gnc_tree_model_split_reg_finalize;
+    o_class->dispose = gnc_tree_model_split_reg_dispose;
+}
+
+
+
+static void
+gnc_tree_model_split_reg_init (GncTreeModelSplitReg *model)
+{
+    GncTreeModelSplitRegPrivate *priv;
+
+    ENTER("model %p", model);
+    while (model->stamp == 0)
+    {
+        model->stamp = g_random_int ();
+    }
+
+    model->priv = g_new0 (GncTreeModelSplitRegPrivate, 1);
+    LEAVE(" ");
+}
+
+
+
+static void
+gnc_tree_model_split_reg_finalize (GObject *object)
+{
+    GncTreeModelSplitRegPrivate *priv;
+    GncTreeModelSplitReg *model;
+
+    ENTER("model %p", object);
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (object));
+
+    model = GNC_TREE_MODEL_SPLIT_REG (object);
+    priv = model->priv;
+
+    if (priv->event_handler_id) {
+        qof_event_unregister_handler(priv->event_handler_id);
+        priv->event_handler_id = 0;
+    }
+
+    priv->book = NULL;
+    g_list_free(priv->tlist);
+    priv->tlist = NULL;
+    g_list_free(priv->slist);
+    priv->slist = NULL;
+    qof_query_destroy(priv->query);
+    priv->query = NULL;
+
+/*FIXME Other stuff here */
+
+    g_free(priv);
+
+    if (G_OBJECT_CLASS (parent_class)->finalize)
+        G_OBJECT_CLASS (parent_class)->finalize (object);
+    LEAVE(" ");
+}
+
+
+
+static void
+gnc_tree_model_split_reg_dispose (GObject *object)
+{
+    GncTreeModelSplitRegPrivate *priv;
+    GncTreeModelSplitReg *model;
+
+/* Nor sure about this */
+
+    ENTER("model %p", object);
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (object));
+
+    model = GNC_TREE_MODEL_SPLIT_REG (object);
+    priv = model->priv;
+
+    if (priv->event_handler_id)
+    {
+        qof_event_unregister_handler (priv->event_handler_id);
+        priv->event_handler_id = 0;
+    }
+
+    if (G_OBJECT_CLASS (parent_class)->dispose)
+        G_OBJECT_CLASS (parent_class)->dispose (object);
+    LEAVE(" ");
+}
+
+
+
+/************************************************************/
+/*                   New Model Creation                     */
+/************************************************************/
+static GncTreeModelSplitReg *
+gnc_tree_model_split_reg_new (GList *slist)
+{
+    GncTreeModelSplitReg *model;
+    GncTreeModelSplitRegPrivate *priv;
+    GList *tlist;
+    const GList *item;
+
+    ENTER("Create Model");
+
+/* This needs fixing 
+    item = gnc_gobject_tracking_get_list(GNC_TREE_MODEL_SPLIT_REG_NAME);
+    for ( ; item; item = g_list_next(item))
+    {
+        model = (GncTreeModelSplitReg *)item->data;
+        priv = GNC_TREE_MODEL_SPLIT_REG_GET_PRIVATE(model);
+        if (priv->anchor == anchor)
+        {
+            g_object_ref(G_OBJECT(model));
+            LEAVE("returning existing model %p", model);
+            return model;
+        }
+    }
+*/
+
+
+    model = g_object_new (GNC_TYPE_TREE_MODEL_SPLIT_REG, NULL);
+
+    /* Get a list of Unique Transactions, upsets the list order !! */
+    tlist = xaccSplitListGetUniqueTransactions(slist);
+
+    /* Default Sort Transactions by date */
+    tlist = g_list_sort (tlist, (GCompareFunc) xaccTransOrder );
+
+    priv = model->priv;
+    priv->book = gnc_get_current_book();
+    priv->tlist = tlist;
+
+    priv->use_colors = gnc_gconf_get_bool(GCONF_GENERAL_REGISTER, "use_theme_colors", NULL);
+    priv->double_line = gnc_gconf_get_bool(GCONF_GENERAL_REGISTER, "double_line_mode", NULL);
+    priv->alt_colors_by_txn = gnc_gconf_get_bool(GCONF_GENERAL_REGISTER, "alternate_color_by_transaction", NULL);
+
+    create_completion_models(model);
+
+/* More stuff here ? */
+
+    priv->event_handler_id = qof_event_register_handler
+                             ((QofEventHandler)gnc_tree_model_split_reg_event_handler, model);
+
+    LEAVE("model %p", model);
+    return model;
+}
+
+
+
+GncTreeModelSplitReg *
+gnc_tree_model_split_reg_new_from_query(Query *query)
+{
+    GncTreeModelSplitReg *model;
+    GList *slist;
+/*
+
+Not sure if required or what to put in here
+    slist = 
+    model = gnc_tree_model_split_reg_new(slist);
+    model->priv->query = query;
+*/
+    model = gnc_tree_model_split_reg_new(NULL);
+    return model;
+
+}
+
+
+
+GncTreeModelSplitReg *
+gnc_tree_model_split_reg_new_from_account(Account *acc)
+{
+    GncTreeModelSplitReg *model;
+    Query *q;
+    GSList  *p1, *p2;
+    QofBook *book;
+
+    GList *slist;
+
+    q = qof_query_create_for(GNC_ID_SPLIT);
+    book = gnc_get_current_book();
+    qof_query_set_book (q, book);
+
+    /* Sort by transaction date */
+    p1 = g_slist_prepend (NULL, TRANS_DATE_POSTED);
+    p1 = g_slist_prepend (p1, SPLIT_TRANS);
+    p2 = g_slist_prepend (NULL, QUERY_DEFAULT_SORT);
+    qof_query_set_sort_order (q, p1, p2, NULL);
+
+    xaccQueryAddSingleAccountMatch (q, acc, QOF_QUERY_AND);
+
+    /* Run the query */
+    slist = qof_query_run(q);
+
+    model = gnc_tree_model_split_reg_new(slist);
+    model->priv->anchor = acc;
+    model->priv->query = q;
+    return model;
+}
+
+
+
+/************************************************************/
+/*        Gnc Tree Model Debugging Utility Function         */
+/************************************************************/
+#define ITER_STRING_LEN 128
+
+static const gchar *
+iter_to_string (GtkTreeIter *iter)
+{
+#ifdef G_THREADS_ENABLED
+    static GStaticPrivate gtmits_buffer_key = G_STATIC_PRIVATE_INIT;
+    gchar *string;
+
+    string = g_static_private_get (&gtmits_buffer_key);
+    if (string == NULL)
+    {
+        string = g_malloc(ITER_STRING_LEN + 1);
+        g_static_private_set (&gtmits_buffer_key, string, g_free);
+    }
+#else
+    static char string[ITER_STRING_LEN + 1];
+#endif
+
+    if (iter)
+        snprintf(
+            string, ITER_STRING_LEN,
+            "[stamp:%x data:%d, %p (%p:%s), %p (%p:%s)]",
+            iter->stamp, GPOINTER_TO_INT(iter->user_data),
+            iter->user_data2,
+            iter->user_data2 ? ((GList *) iter->user_data2)->data : 0,
+            iter->user_data2 ?
+            (QOF_INSTANCE(((GList *) iter->user_data2)->data))->e_type : "",
+            iter->user_data3,
+            iter->user_data3 ? ((GList *) iter->user_data3)->data : 0,
+            iter->user_data3 ?
+            (QOF_INSTANCE(((GList *) iter->user_data3)->data))->e_type : "");
+    else
+        strcpy(string, "(null)");
+    return string;
+}
+
+
+
+/************************************************************/
+/*       Gtk Tree Model Required Interface Functions        */
+/************************************************************/
+static void
+gnc_tree_model_split_reg_tree_model_init (GtkTreeModelIface *iface)
+{
+    iface->get_flags       = gnc_tree_model_split_reg_get_flags;
+    iface->get_n_columns   = gnc_tree_model_split_reg_get_n_columns;
+    iface->get_column_type = gnc_tree_model_split_reg_get_column_type;
+    iface->get_iter        = gnc_tree_model_split_reg_get_iter;
+    iface->get_path        = gnc_tree_model_split_reg_get_path;
+    iface->get_value       = gnc_tree_model_split_reg_get_value;
+    iface->iter_next       = gnc_tree_model_split_reg_iter_next;
+    iface->iter_children   = gnc_tree_model_split_reg_iter_children;
+    iface->iter_has_child  = gnc_tree_model_split_reg_iter_has_child;
+    iface->iter_n_children = gnc_tree_model_split_reg_iter_n_children;
+    iface->iter_nth_child  = gnc_tree_model_split_reg_iter_nth_child;
+    iface->iter_parent     = gnc_tree_model_split_reg_iter_parent;
+}
+
+
+
+static GtkTreeModelFlags
+gnc_tree_model_split_reg_get_flags (GtkTreeModel *tree_model)
+{
+    /* Returns a set of flags supported by this interface. The flags
+       are a bitwise combination of GtkTreeModelFlags. The flags supported
+       should not change during the lifecycle of the tree_model. */
+    return 0;
+}
+
+
+
+static int
+gnc_tree_model_split_reg_get_n_columns (GtkTreeModel *tree_model)
+{
+    /* Returns the number of columns supported by tree_model. */
+    g_return_val_if_fail(GNC_IS_TREE_MODEL_SPLIT_REG(tree_model), -1);
+
+    return GNC_TREE_MODEL_SPLIT_REG_NUM_COLUMNS;
+}
+
+
+
+static GType
+gnc_tree_model_split_reg_get_column_type (GtkTreeModel *tree_model,
+                                        int index)
+{
+    /* Returns the type of the column. */
+    g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (tree_model), G_TYPE_INVALID);
+    g_return_val_if_fail ((index < GNC_TREE_MODEL_SPLIT_REG_NUM_COLUMNS) && (index >= 0), G_TYPE_INVALID);
+
+    switch (index)
+    {
+    case GNC_TREE_MODEL_SPLIT_REG_COL_GUID:
+        return G_TYPE_POINTER;
+
+    case GNC_TREE_MODEL_SPLIT_REG_COL_DATE:
+    case GNC_TREE_MODEL_SPLIT_REG_COL_NUMACT:
+    case GNC_TREE_MODEL_SPLIT_REG_COL_DESCNOTES:
+    case GNC_TREE_MODEL_SPLIT_REG_COL_TRANSVOID:
+
+    case GNC_TREE_MODEL_SPLIT_REG_COL_COLOR:
+        return G_TYPE_STRING;
+
+    default:
+        g_assert_not_reached ();
+        return G_TYPE_INVALID;
+    }
+}
+
+
+
+static gboolean
+gnc_tree_model_split_reg_get_iter (GtkTreeModel *tree_model,
+                                 GtkTreeIter *iter,
+                                 GtkTreePath *path)
+{
+    /* Sets iter to a valid iterator pointing to path. */
+    GncTreeModelSplitReg *model = GNC_TREE_MODEL_SPLIT_REG (tree_model);
+    GList *tnode;
+    SplitList *slist;
+    GList *snode;
+    gint depth, *indices, flags;
+
+    g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (tree_model), FALSE);
+
+    {
+        gchar *path_string = gtk_tree_path_to_string(path);
+        ENTER("model %p, iter %p, path %s", tree_model, iter, path_string);
+        g_free(path_string);
+    }
+
+/* g_print("gnc_tree_model_split_reg_get_iter\n"); */
+
+    depth = gtk_tree_path_get_depth (path);
+/* g_print("Depth is %u\n", depth); */
+    indices = gtk_tree_path_get_indices (path);
+
+    tnode = g_list_nth(model->priv->tlist, indices[0]);
+
+    if (!tnode) {
+        DEBUG("path index off end of tlist");
+        goto fail;
+    }
+
+    slist = xaccTransGetSplitList(tnode->data);
+
+/* g_print("Num of Splits is %d\n\n", xaccTransCountSplits(tnode->data)); */
+
+    if(depth != 3 )
+        snode = g_list_nth(slist, 0);
+    else
+        snode = g_list_nth(slist, indices[2]);
+
+    if (!snode) {
+        DEBUG("path index off end of slist");
+        goto fail;
+    }
+
+    if (depth == 1)       /* Trans Row 1 */
+        flags = TROW1;
+
+    else if (depth == 2)  /* Trans Row 2 */
+        flags = TROW2;
+
+    else if (depth == 3)  /* Split */
+        flags = SPLIT;
+
+    else {
+        DEBUG("Invalid path depth");
+        goto fail;
+    }
+
+    *iter = make_iter(model, flags, tnode, snode);
+/*    g_assert(VALID_ITER(model, iter)); */
+    LEAVE("True");
+    return TRUE;
+ fail:
+    iter->stamp = 0;
+    LEAVE("False");
+    return FALSE;
+}
+
+
+
+static GtkTreePath *
+gnc_tree_model_split_reg_get_path (GtkTreeModel *tree_model,
+                                 GtkTreeIter *iter)
+{
+    /* Returns a newly-created GtkTreePath referenced by iter. 
+       This path should be freed with gtk_tree_path_free(). */
+    GncTreeModelSplitReg *model = GNC_TREE_MODEL_SPLIT_REG (tree_model);
+    GtkTreePath *path;
+    gint tpos, spos;
+    GList *tnode, *snode;
+    GList *slist;
+
+    g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (model), NULL);
+
+/* g_print("gnc_tree_model_split_reg_get_path\n"); */
+    ENTER("model %p, iter %s", model, iter_to_string(iter));
+/*    g_assert(VALID_ITER(model, iter)); */
+
+    path = gtk_tree_path_new();
+
+    tnode = iter->user_data2;
+
+    slist = xaccTransGetSplitList(tnode->data);
+    snode = iter->user_data3;
+
+    /* Level 1 */
+    tpos = g_list_position(model->priv->tlist, tnode);
+    if (tpos == -1)
+        goto fail;
+    gtk_tree_path_append_index(path, tpos);
+
+    /* Level 2 - All ways 0 */
+    if(IS_TROW2(iter))
+        gtk_tree_path_append_index(path, 0);
+
+    /* Level 3 */
+    if(IS_SPLIT(iter))
+    {
+        spos = g_list_position(slist, snode);
+
+        if (spos == -1)
+            goto fail;
+        gtk_tree_path_append_index(path, 0); /* Add the Level 2 part */
+        gtk_tree_path_append_index(path, spos);
+    }
+
+    {
+        gchar *path_string = gtk_tree_path_to_string(path);
+/* g_print("Returned get path is %s\n", gtk_tree_path_to_string(path)); */
+        LEAVE("get path  %s", path_string);
+        g_free(path_string);
+    }
+    return path;
+
+ fail:
+    LEAVE("No Valid Path");
+    return NULL;
+}
+
+
+
+static gchar*
+get_row_color(GncTreeModelSplitReg *model, gboolean is_trow1, gboolean is_trow2, gboolean is_split, gint num)
+{
+
+    gchar *cell_color = NULL;
+
+    if(!model->priv->use_colors)
+    {
+        if(model->priv->double_line)
+        {
+            if(model->priv->alt_colors_by_txn)
+            {
+                if(num % 2 == 0)
+                {
+                    if(is_trow1 || is_trow2)
+                        cell_color = (gchar*)GREENROW;
+                }
+                else 
+                {
+                    if(is_trow1 || is_trow2)
+                        cell_color = (gchar*)TANROW;
+                }
+            }
+            else
+            {
+                if(is_trow1)
+                    cell_color = (gchar*)GREENROW;
+                else if(is_trow2)
+                    cell_color = (gchar*)TANROW;
+            }
+        }
+        else
+        {
+            if(num % 2 == 0)
+            {
+                if(is_trow1)
+                    cell_color = (gchar*)GREENROW;
+                else if(is_trow2)
+                    cell_color = (gchar*)TANROW;
+            }
+            else
+            {
+                if(is_trow1)
+                    cell_color = (gchar*)TANROW;
+                else if(is_trow2)
+                    cell_color = (gchar*)GREENROW;
+            }
+        }
+        if(is_split)
+            cell_color = (gchar*)SPLITROW;
+    }
+    else
+        cell_color = (gchar*)NULL;
+
+    return cell_color;
+}
+
+
+
+static void
+gnc_tree_model_split_reg_get_value (GtkTreeModel *tree_model,
+                                  GtkTreeIter *iter,
+                                  int column,
+                                  GValue *value)
+{
+    /* Initializes and sets value to that at column. When done with value,
+       g_value_unset() needs to be called to free any allocated memory. */
+    GncTreeModelSplitReg *model = GNC_TREE_MODEL_SPLIT_REG (tree_model);
+    Account *account;
+    Transaction *trans;
+    Split *split;
+    const GncGUID *guid;
+    GList *tnode, *snode;
+    gint depth, *indices;
+
+    g_return_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (model));
+/* g_print("gnc_tree_model_split_reg_get_value\n"); */
+    ENTER("model %p, iter %s, col %d", tree_model, iter_to_string(iter), column);
+
+    account = model->priv->anchor;
+
+    tnode = (GList *) iter->user_data2;
+    trans = (Transaction *) tnode->data;
+
+    snode = (GList *) iter->user_data3;
+    split = (Split *) snode->data;
+
+    g_value_init(value, gnc_tree_model_split_reg_get_column_type(tree_model, column));
+
+    indices = gtk_tree_path_get_indices (gtk_tree_model_get_path (GTK_TREE_MODEL(model), iter));
+
+    switch (column)
+    {
+    case GNC_TREE_MODEL_SPLIT_REG_COL_GUID:
+        guid = qof_entity_get_guid(QOF_INSTANCE(trans));
+        g_value_set_pointer(value, (gpointer) guid);
+        break;
+
+    case GNC_TREE_MODEL_SPLIT_REG_COL_DATE:
+        break;
+
+    case GNC_TREE_MODEL_SPLIT_REG_COL_COLOR:
+            g_value_set_string (value, get_row_color(model, IS_TROW1(iter), IS_TROW2(iter), IS_SPLIT(iter), indices[0]));
+        break;
+
+    case GNC_TREE_MODEL_SPLIT_REG_COL_NUMACT:
+        break;
+
+    case GNC_TREE_MODEL_SPLIT_REG_COL_DESCNOTES:
+        break;
+
+    case GNC_TREE_MODEL_SPLIT_REG_COL_TRANSVOID:
+        break;
+
+    default:
+        g_assert_not_reached ();
+    }
+
+    LEAVE(" ");
+}
+
+
+
+static gboolean
+gnc_tree_model_split_reg_iter_next (GtkTreeModel *tree_model,
+                                  GtkTreeIter *iter)
+{
+    /* Sets iter to point to the node following it at the current level.
+       If there is no next iter, FALSE is returned and iter is set to be
+       invalid */
+    GncTreeModelSplitReg *model = GNC_TREE_MODEL_SPLIT_REG (tree_model);
+    Transaction *trans;
+    SplitList *slist;
+    GList *tnode, *snode;
+    gint flags = TROW1;
+
+    g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (model), FALSE);
+/* g_print("gnc_tree_model_split_reg_iter_next\n"); */
+    ENTER("model %p, iter %s", tree_model, iter_to_string(iter));
+
+    if (IS_TROW2(iter)) {
+        LEAVE("Transaction row 2 never has a next");
+        goto fail;
+    }
+
+    if (IS_TROW1(iter)) {
+
+        tnode = iter->user_data2;
+        tnode = g_list_next(tnode);
+
+        if (!tnode) {
+           LEAVE("last trans has no next");
+           goto fail;
+        }
+
+        trans = tnode->data;
+
+        slist = xaccTransGetSplitList(trans);
+        snode = g_list_nth(slist, 0);
+
+        flags = TROW1;
+    }
+
+    if (IS_SPLIT(iter)) {
+
+        tnode = iter->user_data2;
+        snode = iter->user_data3;
+        snode = g_list_next(snode);
+
+        if (!snode) {
+           LEAVE("last split has no next");
+           goto fail;
+        }
+
+        flags = SPLIT;
+    }
+
+    *iter = make_iter(model, flags, tnode, snode);
+    LEAVE("iter %s", iter_to_string(iter));
+    return TRUE;
+ fail:
+    iter->stamp = 0;
+    return FALSE;
+}
+
+
+
+static gboolean
+gnc_tree_model_split_reg_iter_children (GtkTreeModel *tree_model,
+                                      GtkTreeIter *iter,
+                                      GtkTreeIter *parent_iter)
+{
+    /* Sets iter to point to the first child of parent. If parent has no children,
+       FALSE is returned and iter is set to be invalid. parent will remain a valid
+       node after this function has been called. */
+    GncTreeModelSplitReg *model = GNC_TREE_MODEL_SPLIT_REG (tree_model);
+    GList *tnode, *snode;
+    gint flags = TROW1;
+    Transaction *trans;
+    SplitList *slist;
+
+    g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (tree_model), FALSE);
+    ENTER("model %p, iter %p (to be filed in), parent %s",
+          tree_model, iter, (parent_iter ? iter_to_string(parent_iter) : "(null)"));
+
+/* g_print("gnc_tree_model_split_reg_iter_children\n"); */
+
+    if (!parent_iter) {
+        /* Get the very first iter */
+        tnode = model->priv->tlist;
+        if (tnode) {
+
+            slist = xaccTransGetSplitList(tnode->data);
+            snode = g_list_nth(slist, 0);
+        
+            *iter = make_iter(model, flags, tnode, snode);
+            LEAVE("iter (2) %s", iter_to_string(iter));
+            return TRUE;
+        } else {
+            PERR("We should never have a NULL trans list.");
+            goto fail;
+        }
+    }
+
+/*    g_assert(VALID_ITER(model, parent_iter)); */
+
+    if(IS_TROW1(parent_iter))
+    {
+        tnode = parent_iter->user_data2;
+        snode = parent_iter->user_data3;
+        flags = TROW2;
+    }
+
+    if(IS_TROW2(parent_iter))
+    {
+        tnode = parent_iter->user_data2;
+
+        slist = xaccTransGetSplitList(tnode->data);
+        snode = g_list_nth(slist, 0);
+        flags = SPLIT;
+    }
+
+    if(IS_SPLIT(parent_iter))
+        goto fail;
+
+    *iter = make_iter(model, flags, tnode, snode);
+    LEAVE("iter %s", iter_to_string(iter));
+    return TRUE;
+ fail:
+    LEAVE("iter has no children");
+    iter->stamp = 0;
+    return FALSE;
+}
+
+
+
+static gboolean
+gnc_tree_model_split_reg_iter_has_child (GtkTreeModel *tree_model,
+                                       GtkTreeIter *iter)
+{
+    /* Returns TRUE if iter has children, FALSE otherwise. */
+    GncTreeModelSplitReg *model = GNC_TREE_MODEL_SPLIT_REG (tree_model);
+    GList *tnode;
+    Transaction *trans;
+
+    g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (tree_model), FALSE);
+
+    ENTER("model %p, iter %s", tree_model, iter_to_string(iter));
+/* g_print("gnc_tree_model_split_reg_iter_has_child\n"); */
+
+    tnode = iter->user_data2;
+    trans = tnode->data;
+
+    if (IS_TROW1(iter))
+    {
+        LEAVE("Transaction Row 1 is yes");
+        return TRUE;
+    }
+
+    if (IS_TROW2(iter))
+    {
+        LEAVE("Transaction Row 2 is yes");
+        return TRUE;
+    }
+
+    LEAVE("We have no child");
+    return FALSE;
+}
+
+
+
+static int
+gnc_tree_model_split_reg_iter_n_children (GtkTreeModel *tree_model,
+                                        GtkTreeIter *iter)
+{
+    /* Returns the number of children that iter has. As a special case,
+       if iter is NULL, then the number of toplevel nodes is returned.  */
+    GncTreeModelSplitReg *model = GNC_TREE_MODEL_SPLIT_REG (tree_model);
+    Transaction *trans;
+    GList *tnode;
+    int i;
+
+    g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (tree_model), FALSE);
+    ENTER("model %p, iter %s", tree_model, iter_to_string(iter));
+/* g_print("gnc_tree_model_split_reg_iter_n_children\n"); */
+
+    if (iter == NULL) {
+        i = g_list_length(model->priv->tlist);
+        LEAVE("toplevel count is %d", i);
+        return i;
+    }
+
+    if(IS_SPLIT(iter))
+        i = 0;
+
+    if(IS_TROW1(iter))
+        i = 1;
+
+    if(IS_TROW2(iter))
+    {
+        tnode = iter->user_data2;
+        trans = tnode->data;
+        i = xaccTransCountSplits(trans);
+    }
+
+    LEAVE("The number of children iter has is %d", i);
+    return i;
+}
+
+
+
+static gboolean
+gnc_tree_model_split_reg_iter_nth_child (GtkTreeModel *tree_model,
+                                       GtkTreeIter *iter,
+                                       GtkTreeIter *parent_iter,
+                                       int n)
+{
+    /* Sets iter to be the child of parent, using the given index. */
+    GncTreeModelSplitReg *model = GNC_TREE_MODEL_SPLIT_REG (tree_model);
+    Transaction *trans;
+    SplitList *slist;
+    GList *tnode, *snode;
+    gint flags = TROW1;
+
+    ENTER("model %p, iter %s, n %d", tree_model, iter_to_string(parent_iter), n);
+    g_return_val_if_fail (GNC_IS_TREE_MODEL_SPLIT_REG (tree_model), FALSE);
+
+/* g_print("gnc_tree_model_split_reg_iter_nth_child %d\n", n); */
+
+    if (parent_iter == NULL) {  /* Top-level */
+        tnode = g_list_nth(model->priv->tlist, n);
+
+        if (!tnode) {
+            PERR("Trans list should never be NULL.");
+            goto fail;
+        }
+        trans = tnode->data;
+
+        slist = xaccTransGetSplitList(trans);
+        snode = g_list_nth(slist, 0);
+
+        *iter = make_iter(model, flags, tnode, snode);
+        LEAVE("iter (2) %s", iter_to_string(iter));
+        return TRUE;
+    }
+
+    DEBUG("parent iter %s", iter_to_string(parent_iter));
+/*    g_assert(VALID_ITER(model, parent_iter)); */
+
+    if (IS_SPLIT(parent_iter))
+        goto fail;  /* Splits have no children */
+
+
+    if(IS_TROW1(parent_iter) && (n != 0))
+        goto fail;
+
+    tnode = parent_iter->user_data2;
+    trans = tnode->data;
+    snode = parent_iter->user_data3;
+    flags = TROW2;
+
+    if(IS_TROW2(parent_iter) && (n > xaccTransCountSplits(trans)))
+        goto fail;
+    else
+    {
+
+        slist = xaccTransGetSplitList(trans);
+        snode = g_list_nth(slist, n);
+        flags = SPLIT;
+    }
+
+    *iter = make_iter(model, flags, tnode, snode);
+    LEAVE("iter of child with index %u is %s", n, iter_to_string(iter));
+    return TRUE;
+ fail:
+    LEAVE("iter has no child with index %u", n);
+    iter->stamp = 0;
+    return FALSE;
+}
+
+
+
+static gboolean
+gnc_tree_model_split_reg_iter_parent (GtkTreeModel *tree_model,
+                                    GtkTreeIter *iter,
+                                    GtkTreeIter *child)
+{
+    /* Sets iter to be the parent of child. If child is at the toplevel,
+       and doesn't have a parent, then iter is set to an invalid iterator
+       and FALSE is returned. child will remain a valid node after this 
+       function has been called. */
+    GncTreeModelSplitReg *model = GNC_TREE_MODEL_SPLIT_REG (tree_model);
+    GList *tnode, *snode;
+    gint flags = TROW1;
+
+    ENTER("model %p, child %s", tree_model, iter_to_string(child));
+
+/* g_print("gnc_tree_model_split_reg_iter_parent\n"); */
+
+/*    g_assert(VALID_ITER(model, child)); */
+
+    tnode = child->user_data2;
+    snode = child->user_data3;
+
+    if(IS_TROW1(child))
+        goto fail;
+
+    if(IS_TROW2(child))
+        flags = TROW1;
+
+    if(IS_SPLIT(child))
+        flags = TROW2;
+
+    *iter = make_iter(model, flags, tnode, snode);
+    LEAVE("parent iter is %s", iter_to_string(iter));
+    return TRUE;
+ fail:
+    LEAVE("we have no parent");
+    iter->stamp = 0;
+    return FALSE;
+}
+
+
+
+
+/*###################################################################*/
+
+gboolean
+gnc_tree_model_split_reg_get_split_and_trans (
+    GncTreeModelSplitReg *model, GtkTreeIter *iter,
+    gboolean *is_trow1, gboolean *is_trow2, gboolean *is_split,
+    gboolean *is_blank, Split **split, Transaction **trans)
+{
+    GList *node;
+
+/*    g_return_val_if_fail(VALID_ITER(model, iter), FALSE); */
+    ENTER("");
+    if (is_trow1)
+        *is_trow1 = !!IS_TROW1(iter);
+    if (is_trow2)
+        *is_trow2 = !!IS_TROW2(iter);
+    if (is_split)
+        *is_split = !!IS_SPLIT(iter);
+    if (is_blank)
+        *is_blank = !!IS_BLANK(iter);
+
+    if (trans) {
+        node = iter->user_data2;
+        *trans = node ? (Transaction *) node->data : NULL;
+    }
+    if (split) {
+        node = iter->user_data3;
+        *split = node ? (Split *) node->data : NULL;
+    }
+    LEAVE("");
+    return TRUE;
+}
+
+
+/*###################################################################*/
+
+Account *
+gnc_tree_model_split_reg_get_anchor(GncTreeModelSplitReg *model)
+{
+    g_return_val_if_fail(GNC_IS_TREE_MODEL_SPLIT_REG(model), NULL);
+    return model->priv->anchor;
+}
+
+
+GtkListStore *
+gnc_tree_model_split_reg_get_description_list(GncTreeModelSplitReg *model)
+{
+    g_return_val_if_fail(GNC_IS_TREE_MODEL_SPLIT_REG(model), NULL);
+    return model->priv->description_list;
+}
+
+
+GtkListStore *
+gnc_tree_model_split_reg_get_notes_list(GncTreeModelSplitReg *model)
+{
+    g_return_val_if_fail(GNC_IS_TREE_MODEL_SPLIT_REG(model), NULL);
+    return model->priv->notes_list;
+}
+
+
+GtkListStore *
+gnc_tree_model_split_reg_get_memo_list(GncTreeModelSplitReg *model)
+{
+    g_return_val_if_fail(GNC_IS_TREE_MODEL_SPLIT_REG(model), NULL);
+    return model->priv->memo_list;
+}
+
+
+GtkListStore *
+gnc_tree_model_split_reg_get_numact_list(GncTreeModelSplitReg *model)
+{
+    g_return_val_if_fail(GNC_IS_TREE_MODEL_SPLIT_REG(model), NULL);
+    return model->priv->numact_list;
+}
+
+
+/* Return TRUE if string all ready exists in the list */
+static gboolean
+check_for_duplicates(GtkListStore *liststore, const gchar *string)
+{
+    GtkTreeIter iter;
+    gboolean valid;
+
+    valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (liststore), &iter);
+    while (valid)
+    {
+        gchar *text;
+        // Walk through the list, reading each row
+        gtk_tree_model_get (GTK_TREE_MODEL (liststore), &iter, 0, &text, -1);
+
+        if(!(g_strcmp0(text, string)))
+        {
+            g_free(text);
+            return TRUE;
+        }
+        g_free(text);
+
+        valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (liststore), &iter);
+    }
+    return FALSE;
+}
+
+
+
+/* Create the Auto Complete List Stores.... */
+static void
+create_completion_models(GncTreeModelSplitReg *model)
+{
+
+    GncTreeModelSplitRegPrivate *priv;
+    GtkListStore *description_list, *notes_list, *memo_list, *num_list;
+    GtkTreeIter d_iter, n_iter, m_iter, num_iter;
+    GList *tlist, *tnode, *slist, *snode;
+    int cnt, nSplits;
+
+    priv = model->priv;
+    tlist = priv->tlist;
+
+    description_list = gtk_list_store_new(1, G_TYPE_STRING);
+    notes_list = gtk_list_store_new(1, G_TYPE_STRING);
+    memo_list = gtk_list_store_new(1, G_TYPE_STRING);
+    num_list = gtk_list_store_new(1, G_TYPE_STRING);
+
+    for (tnode = tlist; tnode; tnode = tnode->next)
+    {
+        Transaction *trans;
+        Split       *split;
+        const gchar *string;
+
+        trans = tnode->data;
+
+        nSplits = xaccTransCountSplits(trans);
+        slist = xaccTransGetSplitList(trans);
+    
+        /* Add to the Description list */
+        string = xaccTransGetDescription(trans);
+        if(g_strcmp0(string, ""))
+        {
+            if(check_for_duplicates(description_list, string) == FALSE)
+            {
+                gtk_list_store_append(description_list, &d_iter);
+                gtk_list_store_set(description_list, &d_iter, 0, string , -1);
+            }
+        }
+
+        /* Add to the Notes list */
+        string = xaccTransGetNotes(trans);
+        if(g_strcmp0(string, ""))
+        {
+            if(check_for_duplicates(notes_list, string) == FALSE)
+            {
+                gtk_list_store_append(notes_list, &n_iter);
+                gtk_list_store_set(notes_list, &n_iter, 0, string, -1);
+            }
+        }
+
+        /* Add to the Num list */
+        string = xaccTransGetNum(trans);
+        if(g_strcmp0(string, ""))
+        {
+            if(check_for_duplicates(num_list, string) == FALSE)
+            {
+                gtk_list_store_prepend(num_list, &num_iter);
+                gtk_list_store_set(num_list, &num_iter, 0, string, -1);
+            }
+        }
+
+        /* Loop through the list of splits for each Transaction - **do not free the list** */
+        snode = slist;
+        cnt = 0;
+        while (cnt < nSplits)
+        {
+            split = snode->data;
+
+            /* Add to the Memo list */
+            string = xaccSplitGetMemo(split);
+            if(g_strcmp0(string, ""))
+            {
+                if(check_for_duplicates(memo_list, string) == FALSE)
+                {
+                    gtk_list_store_append(memo_list, &m_iter);
+                    gtk_list_store_set(memo_list, &m_iter, 0, string, -1);
+                }
+            }
+            cnt++;
+            snode = snode->next;
+         }
+    }
+
+    priv->description_list = description_list;
+    priv->notes_list = notes_list;
+    priv->memo_list = memo_list;
+    priv->num_list = num_list;
+    priv->numact_list = gtk_list_store_new(1, G_TYPE_STRING);
+}
+
+
+/* Update the model with entries for the Number field ... */
+void
+gnc_tree_model_split_reg_get_num_list(GncTreeModelSplitReg *model)
+{
+    GncTreeModelSplitRegPrivate *priv;
+    GtkListStore *store, *num_list;
+    GtkTreeIter iter, num_iter;
+    gboolean valid;
+
+    priv = model->priv;
+
+    store = priv->numact_list;
+    num_list = priv->num_list;
+
+    /* Clear the liststore */
+    gtk_list_store_clear (store);
+
+    valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (num_list), &num_iter);
+    while (valid)
+    {
+        gchar *text;
+
+        // Walk through the list, reading each row
+        gtk_tree_model_get (GTK_TREE_MODEL (num_list), &num_iter, 0, &text, -1);
+
+        gtk_list_store_append (store, &iter);
+        gtk_list_store_set (store, &iter, 0, text, -1);
+        g_free(text);
+
+        valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (num_list), &num_iter);
+    }
+    priv->numact_list = store;
+}
+
+
+/* Update the model with entries for the Action field ... */
+void
+gnc_tree_model_split_reg_get_action_list(GncTreeModelSplitReg *model)
+{
+    GncTreeModelSplitRegPrivate *priv;
+    GtkListStore *store;
+    GtkTreeIter iter;
+
+    priv = model->priv;
+    store = priv->numact_list;
+
+    /* Clear the liststore */
+    gtk_list_store_clear (store);
+
+/*FIXME This is a temp hack to give a value, this would come from ledger ? */
+    model->type = CREDIT_REGISTER2;
+
+    /* setup strings in the action pull-down */
+    switch (model->type)
+    {
+    case BANK_REGISTER2:
+        /* broken ! FIXME bg */
+    case SEARCH_LEDGER2:
+
+        /* Translators: This string has a context prefix; the translation
+        	must only contain the part after the | character. */
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, Q_("Action Column|Deposit"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Withdraw"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Check"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Interest"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("ATM Deposit"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("ATM Draw"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Teller"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Charge"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Payment"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Receipt"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Increase"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Decrease"), -1);
+        /* Action: Point Of Sale */
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("POS"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Phone"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Online"), -1);
+        /* Action: Automatic Deposit ?!? */
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("AutoDep"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Wire"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Credit"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Direct Debit"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Transfer"), -1);
+        break;
+    case CASH_REGISTER2:
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Increase"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Decrease"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Buy"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Sell"), -1);
+        break;
+    case ASSET_REGISTER2:
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Buy"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Sell"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Fee"), -1);
+        break;
+    case CREDIT_REGISTER2:
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("ATM Deposit"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("ATM Draw"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Buy"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Credit"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Fee"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Interest"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Online"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Sell"), -1);
+        break;
+    case LIABILITY_REGISTER2:
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Buy"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Sell"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Loan"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Interest"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Payment"), -1);
+        break;
+    case RECEIVABLE_REGISTER2:
+    case PAYABLE_REGISTER2:
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Invoice"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Payment"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Interest"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Credit"), -1);
+        break;
+    case INCOME_LEDGER2:
+    case INCOME_REGISTER2:
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Increase"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Decrease"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Buy"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Sell"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Interest"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Payment"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Rebate"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Paycheck"), -1);
+        break;
+    case EXPENSE_REGISTER2:
+    case TRADING_REGISTER2:
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Increase"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Decrease"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Buy"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Sell"), -1);
+        break;
+    case GENERAL_LEDGER2:
+    case EQUITY_REGISTER2:
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Buy"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Sell"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Equity"), -1);
+        break;
+    case STOCK_REGISTER2:
+    case PORTFOLIO_LEDGER2:
+    case CURRENCY_REGISTER2:
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Buy"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Sell"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Price"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Fee"), -1);
+        /* Action: Dividend */
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Dividend"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Interest"), -1);
+        /* Action: Long Term Capital Gains */
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("LTCG"), -1);
+        /* Action: Short Term Capital Gains */
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("STCG"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Income"), -1);
+        /* Action: Distribution */
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Dist"), -1);
+        /* Translators: This string has a disambiguation prefix */
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, Q_("Action Column|Split"), -1);
+        break;
+
+    default:
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Increase"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Decrease"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Buy"), -1);
+        gtk_list_store_insert_with_values (store, &iter, 100, 0, _("Sell"), -1);
+        break;
+    }
+    priv->numact_list = store;
+}
+
+
+/* Return the GtkListstore of Accounts */
+GtkListStore *
+gnc_tree_model_split_reg_get_acct_list(GncTreeModelSplitReg *model)
+{
+    GncTreeModelSplitRegPrivate *priv;
+    Account *root;
+    Account *acc;
+    GtkListStore *store;
+    GtkTreeIter iter;
+    GList *accts, *ptr;
+    gboolean valid;
+    const gchar *name, *fname;
+    gint i;
+
+    priv = model->priv;
+
+    /* Store is short name, full name and account pointer */
+    store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER );
+
+    root = gnc_book_get_root_account( gnc_get_current_book());
+/*FIXME This does not look sorted to me, need to look at this */
+    accts = gnc_account_get_descendants_sorted( root );
+
+    for (ptr = accts, i = 0; ptr; ptr = g_list_next(ptr), i++)
+    {
+        acc = ptr->data;
+
+        if(!(acc == model->priv->anchor))
+        {
+            fname = gnc_account_get_full_name(acc);
+            name = xaccAccountGetName(acc);
+            gtk_list_store_append(store, &iter);
+            gtk_list_store_set(store, &iter, 0, name, 1, fname, 2, acc, -1);
+        }
+    }
+
+    g_list_free( accts );
+
+    return store;
+}
+
+
+/*******************************************************************/
+/*   Split Register Tree Model - Engine Event Handling Functions   */
+/*******************************************************************/
+
+/** This function is the handler for all event messages from the
+ *  engine.  Its purpose is to update the account tree model any time
+ *  an account is added to the engine or deleted from the engine.
+ *  This change to the model is then propagated to any/all overlying
+ *  filters and views.  This function listens to the ADD, REMOVE, and
+ *  DESTROY events.
+ *
+ *  @internal
+ *
+ *  @warning There is a "Catch 22" situation here.
+ *  gtk_tree_model_row_deleted() can't be called until after the item
+ *  has been deleted from the real model (which is the engine's
+ *  account tree for us), but once the account has been deleted from
+ *  the engine we have no way to determine the path to pass to
+ *  row_deleted().  This is a PITA, but the only other choice is to
+ *  have this model mirror the engine's accounts instead of
+ *  referencing them directly.
+ *
+ *  @param entity The guid of the affected item.
+ *
+ *  @param type The type of the affected item.  This function only
+ *  cares about items of type "account".
+ *
+ *  @param event type The type of the event. This function only cares
+ *  about items of type ADD, REMOVE, MODIFY, and DESTROY.
+ *
+ *  @param user_data A pointer to the split register tree model.
+ */
+static void
+gnc_tree_model_split_reg_event_handler (QofInstance *entity,
+                                      QofEventId event_type,
+                                      GncTreeModelSplitReg *model,
+                                      GncEventData *event_data)
+{
+    GncTreeModelSplitRegPrivate *priv = model->priv;
+    GncEventData *ed = event_data;
+    GtkTreeIter iter;
+    GtkTreePath *path;
+    Transaction *trans;
+    Split *split = NULL;
+    QofIdType type;
+    const gchar *name = NULL;
+    GList *tnode;
+
+    g_return_if_fail(GNC_IS_TREE_MODEL_SPLIT_REG(model));
+
+    if (qof_instance_get_book(entity) != priv->book)
+        return;
+    type = entity->e_type;
+
+    if (safe_strcmp(type, GNC_ID_SPLIT) == 0) {
+        /* Get the split.*/
+        split = (Split *) entity;
+
+        switch (event_type) {
+        case QOF_EVENT_MODIFY:
+
+            break;
+        default:
+            DEBUG("ignored event for %p (%s)", split, name);
+        }
+    } else if (safe_strcmp(type, GNC_ID_TRANS) == 0) {
+        /* Get the trans.*/
+        trans = (Transaction *) entity;
+
+        switch (event_type) {
+        case GNC_EVENT_ITEM_ADDED:
+            split = (Split *) ed->node;
+
+
+            break;
+        case GNC_EVENT_ITEM_REMOVED:
+            split = (Split *) ed->node;
+
+
+            break;
+        case QOF_EVENT_MODIFY:
+
+
+            break;
+        case QOF_EVENT_DESTROY:
+
+
+            break;
+        default:
+            DEBUG("ignored event for %p (%s)", trans, name);
+        }
+    } else if (safe_strcmp(type, GNC_ID_ACCOUNT) == 0) {
+        switch (event_type) {
+            Account *acc;
+        case GNC_EVENT_ITEM_ADDED:
+            split = (Split *) ed;
+
+            break;
+        default:
+            ;
+        }
+    }
+}
Index: src/gnome-utils/gnc-tree-model-split-reg.h
===================================================================
--- src/gnome-utils/gnc-tree-model-split-reg.h	(revision 0)
+++ src/gnome-utils/gnc-tree-model-split-reg.h	(revision 0)
@@ -0,0 +1,196 @@
+/********************************************************************\
+ * gnc-tree-model-split-reg.h -- GtkTreeView implementation to      *
+ *                     display registers   in a GtkTreeView.        *
+ *                                                                  *
+ * Copyright (C) 2012 Robert Fewell                                 *
+ * Copyright (C) 2006-2007 Chris Shoemaker <c.shoemaker@cox.net>    *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+
+#ifndef __GNC_TREE_MODEL_SPLIT_REG_H
+#define __GNC_TREE_MODEL_SPLIT_REG_H
+
+#include <gtk/gtk.h>
+#include "gnc-tree-model.h"
+
+#include "Query.h"
+
+G_BEGIN_DECLS
+
+/* type macros */
+#define GNC_TYPE_TREE_MODEL_SPLIT_REG            (gnc_tree_model_split_reg_get_type ())
+#define GNC_TREE_MODEL_SPLIT_REG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_TREE_MODEL_SPLIT_REG, GncTreeModelSplitReg))
+#define GNC_TREE_MODEL_SPLIT_REG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GNC_TYPE_TREE_MODEL_SPLIT_REG, GncTreeModelSplitRegClass))
+#define GNC_IS_TREE_MODEL_SPLIT_REG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNC_TYPE_TREE_MODEL_SPLIT_REG))
+#define GNC_IS_TREE_MODEL_SPLIT_REG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNC_TYPE_TREE_MODEL_SPLIT_REG))
+#define GNC_TREE_MODEL_SPLIT_REG_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GNC_TYPE_TREE_MODEL_SPLIT_REG, GncTreeModelSplitRegClass))
+#define GNC_TREE_MODEL_SPLIT_REG_NAME            "GncTreeModelSplitReg"
+
+
+/** @brief Register types
+ *
+ * "registers" are single-account display windows.
+ * "ledgers" are multiple-account display windows */
+typedef enum
+{
+    BANK_REGISTER2,
+    CASH_REGISTER2,
+    ASSET_REGISTER2,
+    CREDIT_REGISTER2,
+    LIABILITY_REGISTER2,
+    INCOME_REGISTER2,
+    EXPENSE_REGISTER2,
+    EQUITY_REGISTER2,
+    STOCK_REGISTER2,
+    CURRENCY_REGISTER2,
+    RECEIVABLE_REGISTER2,
+    PAYABLE_REGISTER2,
+    TRADING_REGISTER2,
+    NUM_SINGLE_REGISTER_TYPES2,
+
+    GENERAL_LEDGER2 = NUM_SINGLE_REGISTER_TYPES2,
+    INCOME_LEDGER2,
+    PORTFOLIO_LEDGER2,
+    SEARCH_LEDGER2,
+
+    NUM_REGISTER_TYPES2
+} SplitRegisterType2;
+
+/** Register styles */
+typedef enum
+{
+    REG_STYLE_LEDGER2,
+    REG_STYLE_AUTO_LEDGER2,
+    REG_STYLE_JOURNAL2
+} SplitRegisterStyle2;
+
+
+typedef enum
+{
+    GNC_TREE_MODEL_SPLIT_REG_COL_GUID,
+    GNC_TREE_MODEL_SPLIT_REG_COL_DATE,
+    GNC_TREE_MODEL_SPLIT_REG_COL_NUMACT,
+    GNC_TREE_MODEL_SPLIT_REG_COL_DESCNOTES,
+    GNC_TREE_MODEL_SPLIT_REG_COL_TRANSVOID,
+
+    GNC_TREE_MODEL_SPLIT_REG_COL_LAST_VISIBLE = GNC_TREE_MODEL_SPLIT_REG_COL_TRANSVOID,
+
+    /* internal hidden columns */
+    GNC_TREE_MODEL_SPLIT_REG_COL_COLOR,
+
+    GNC_TREE_MODEL_SPLIT_REG_NUM_COLUMNS
+} GncTreeModelSplitRegColumn;
+
+/* typedefs & structures */
+typedef struct GncTreeModelSplitRegPrivate GncTreeModelSplitRegPrivate;
+
+/** The instance data structure for an account tree model. */
+typedef struct
+{
+    GncTreeModel gnc_tree_model;    /**< The parent object data. */
+    GncTreeModelSplitRegPrivate *priv;
+    int stamp;                      /**< The state of the model. Any state
+                                     *   change increments this number. */
+
+    SplitRegisterType2 type;       /* This may be the wrong place for these, may be the view ? */
+    SplitRegisterStyle2 style;
+
+
+} GncTreeModelSplitReg;
+
+
+/** The class data structure for an account tree model. */
+typedef struct
+{
+    GncTreeModelClass gnc_tree_model;   /**< The parent object data. */
+} GncTreeModelSplitRegClass;
+
+
+
+/** Get the type of split register tree plugin.
+ *
+ *  @return A GType.
+ */
+GType gnc_tree_model_split_reg_get_type (void);
+
+
+/** @name Split Register Tree Model Constructors
+ @{ */
+
+/** Create a new GtkTreeModel for manipulating gnucash splits.
+ *
+ *  @param The Query
+ */
+GncTreeModelSplitReg *gnc_tree_model_split_reg_new_from_account (Account *acc);
+/** @} */
+
+/** @name Split Register Tree Model Constructors
+ @{ */
+
+/** Create a new GtkTreeModel for manipulating gnucash splits.
+ *
+ *  @param The Query
+ */
+GncTreeModelSplitReg *gnc_tree_model_split_reg_new_from_query (Query *query);
+/** @} */
+
+/** Get the Account of GtkTreeModel.
+ *
+ *  @param The model
+ */
+Account * gnc_tree_model_split_reg_get_anchor(GncTreeModelSplitReg *model);
+/** @} */
+
+GtkListStore *
+gnc_tree_model_split_reg_get_description_list(GncTreeModelSplitReg *model);
+
+GtkListStore *
+gnc_tree_model_split_reg_get_notes_list(GncTreeModelSplitReg *model);
+
+GtkListStore *
+gnc_tree_model_split_reg_get_memo_list(GncTreeModelSplitReg *model);
+
+GtkListStore *
+gnc_tree_model_split_reg_get_numact_list(GncTreeModelSplitReg *model);
+
+GtkListStore *
+gnc_tree_model_split_reg_get_acct_list(GncTreeModelSplitReg *model);
+
+void
+gnc_tree_model_split_reg_get_num_list(GncTreeModelSplitReg *model);
+
+void
+gnc_tree_model_split_reg_get_action_list(GncTreeModelSplitReg *model);
+
+
+gboolean
+gnc_tree_model_split_reg_get_split_and_trans (
+    GncTreeModelSplitReg *model, GtkTreeIter *iter,
+    gboolean *is_trow1, gboolean *is_trow2, gboolean *is_split,
+    gboolean *is_blank, Split **split, Transaction **trans);
+
+
+G_END_DECLS
+
+#endif /* __GNC_TREE_MODEL_SPLIT_REG_H */
+
+/** @} */
+/** @} */
Index: src/gnome-utils/Makefile.am
===================================================================
--- src/gnome-utils/Makefile.am	(revision 22178)
+++ src/gnome-utils/Makefile.am	(working copy)
@@ -49,6 +49,9 @@
   gnc-account-sel.c \
   gnc-amount-edit.c \
   gnc-autosave.c \
+  gnc-cell-renderer-date.c \
+  gnc-cell-renderer-popup.c \
+  gnc-cell-renderer-popup-entry.c \
   gnc-commodity-edit.c \
   gnc-currency-edit.c \
   gnc-date-delta.c \
@@ -86,11 +89,13 @@
   gnc-tree-model-budget.c \
   gnc-tree-model-owner.c \
   gnc-tree-model-commodity.c \
+  gnc-tree-model-split-reg.c \
   gnc-tree-model-price.c \
   gnc-tree-view-account.c \
   gnc-tree-view-commodity.c \
   gnc-tree-view-owner.c \
   gnc-tree-view-price.c \
+  gnc-tree-view-split-reg.c \
   gnc-tree-view-sx-list.c \
   gnc-tree-view.c \
   gnc-window.c \
@@ -122,6 +127,9 @@
   dialog-utils.h \
   gnc-account-sel.h \
   gnc-amount-edit.h \
+  gnc-cell-renderer-date.h \
+  gnc-cell-renderer-popup.h \
+  gnc-cell-renderer-popup-entry.h \
   gnc-commodity-edit.h \
   gnc-currency-edit.h \
   gnc-date-delta.h \
@@ -158,10 +166,12 @@
   gnc-tree-model-owner.h \
   gnc-tree-model-commodity.h \
   gnc-tree-model-price.h \
+  gnc-tree-model-split-reg.h \
   gnc-tree-view-account.h \
   gnc-tree-view-commodity.h \
   gnc-tree-view-owner.h \
   gnc-tree-view-price.h \
+  gnc-tree-view-split-reg.h \
   gnc-tree-view-sx-list.h \
   gnc-tree-view.h \
   gnc-ui.h \
Index: src/gnome-utils/gnc-cell-renderer-popup.c
===================================================================
--- src/gnome-utils/gnc-cell-renderer-popup.c	(revision 0)
+++ src/gnome-utils/gnc-cell-renderer-popup.c	(revision 0)
@@ -0,0 +1,575 @@
+/*************************************************************************
+ * The following code has come from Planner. This code implements a
+ * GtkCalendar in a custom GtkCellEditable popup from GtkCellRenderer.
+ *
+ * These files have been renamed and changed to remove code not required
+ * and to remove a dependency on libplanner.
+ *
+ * Copyright (C) 2012 Robert Fewell
+ *
+ * Copyright (C) 2001-2002 CodeFactory AB
+ * Copyright (C) 2001-2002 Richard Hult <richard@imendio.com>
+ * Copyright (C) 2001-2002 Mikael Hallendal <micke@imendio.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *************************************************************************/
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "gnc-cell-renderer-popup.h"
+#include "gnc-cell-renderer-popup-entry.h"
+
+enum {
+	SHOW_POPUP,
+	HIDE_POPUP,
+	LAST_SIGNAL
+};
+
+static void      gcrp_init               (GncCellRendererPopup      *popup);
+static void      gcrp_class_init         (GncCellRendererPopupClass *class);
+
+static GtkCellEditable *
+gcrp_start_editing                       (GtkCellRenderer          *cell,
+					  GdkEvent                 *event,
+					  GtkWidget                *widget,
+					  const gchar              *path,
+					  GdkRectangle             *background_area,
+					  GdkRectangle             *cell_area,
+					  GtkCellRendererState      flags);
+static void      gcrp_show_popup         (GncCellRendererPopup      *cell,
+					  const gchar              *path,
+					  gint                      x1,
+					  gint                      y1,
+					  gint                      x2,
+					  gint                      y2);
+static void      gcrp_hide_popup         (GncCellRendererPopup      *cell);
+static void      gcrp_get_size           (GtkCellRenderer          *cell,
+					  GtkWidget                *widget,
+					  GdkRectangle             *cell_area,
+					  gint                     *x_offset,
+					  gint                     *y_offset,
+					  gint                     *width,
+					  gint                     *height);
+static void      gcrp_style_set           (GtkWidget               *widget,
+					   GtkStyle                *old_style,
+					   GncCellRendererPopup     *popup);
+static gboolean  gcrp_key_press_event    (GtkWidget                *popup_window,
+					  GdkEventKey              *event,
+					  GncCellRendererPopup      *cell);
+static gboolean  gcrp_button_press_event (GtkWidget                *widget,
+					  GdkEventButton           *event,
+					  GncCellRendererPopup      *popup);
+
+
+void gnc_marshal_VOID__STRING_INT_INT_INT_INT (GClosure     *closure,
+                                               GValue       *return_value,
+                                               guint         n_param_values,
+                                               const GValue *param_values,
+                                               gpointer      invocation_hint,
+                                               gpointer      marshal_data);
+
+
+static GtkCellRendererTextClass *parent_class;
+static guint signals[LAST_SIGNAL];
+
+#define GNC_CELL_RENDERER_POPUP_PATH "gnc-cell-renderer-popup-path"
+
+GType
+gnc_cell_renderer_popup_get_type (void)
+{
+	static GType cell_text_type = 0;
+	
+	if (!cell_text_type) {
+		static const GTypeInfo cell_text_info = {
+			sizeof (GncCellRendererPopupClass),
+			NULL,		/* base_init */
+			NULL,		/* base_finalize */
+			(GClassInitFunc) gcrp_class_init,
+			NULL,		/* class_finalize */
+			NULL,		/* class_data */
+			sizeof (GncCellRendererPopup),
+			0,              /* n_preallocs */
+			(GInstanceInitFunc) gcrp_init,
+		};
+		
+		cell_text_type = g_type_register_static (GTK_TYPE_CELL_RENDERER_TEXT,
+							 "GncCellRendererPopup",
+							 &cell_text_info,
+							 0);
+	}
+	
+	return cell_text_type;
+}
+
+static void
+gcrp_init (GncCellRendererPopup *popup)
+{
+	popup->popup_window = gtk_window_new (GTK_WINDOW_POPUP);
+
+	popup->button_width = -1;
+	
+	g_signal_connect (popup->popup_window,
+			  "button-press-event",
+			  G_CALLBACK (gcrp_button_press_event),
+			  popup);
+
+	g_signal_connect (popup->popup_window,
+			  "key-press-event",
+			  G_CALLBACK (gcrp_key_press_event),
+			  popup);
+
+	g_signal_connect (popup->popup_window,
+			  "style-set",
+			  G_CALLBACK (gcrp_style_set),
+			  popup);
+}
+
+static void
+gcrp_class_init (GncCellRendererPopupClass *class)
+{
+	GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);
+	
+	parent_class = GTK_CELL_RENDERER_TEXT_CLASS (g_type_class_peek_parent (class));
+	
+	cell_class->start_editing = gcrp_start_editing;
+	cell_class->get_size      = gcrp_get_size;
+
+	class->show_popup = gcrp_show_popup;
+	class->hide_popup = gcrp_hide_popup;
+
+	signals[SHOW_POPUP] = g_signal_new (
+		"show-popup",
+		G_TYPE_FROM_CLASS (class),
+		G_SIGNAL_RUN_LAST,
+		G_STRUCT_OFFSET (GncCellRendererPopupClass, show_popup),
+		NULL, NULL,
+		gnc_marshal_VOID__STRING_INT_INT_INT_INT,
+		G_TYPE_NONE, 5,
+		G_TYPE_STRING,
+		G_TYPE_INT,
+		G_TYPE_INT,
+		G_TYPE_INT,
+		G_TYPE_INT);
+
+	signals[HIDE_POPUP] = g_signal_new (
+		"hide-popup",
+		G_TYPE_FROM_CLASS (class),
+		G_SIGNAL_RUN_LAST,
+		G_STRUCT_OFFSET (GncCellRendererPopupClass, hide_popup),
+		NULL, NULL,
+		g_cclosure_marshal_VOID__VOID,
+		G_TYPE_NONE, 0);
+}
+
+static void
+gcrp_editing_done (GtkCellEditable     *editable,
+		   GncCellRendererPopup *cell)
+{
+	gchar       *path;
+	const gchar *new_text;
+
+	if (GNC_POPUP_ENTRY (editable)->editing_canceled ||
+	    cell->editing_canceled) {
+                gtk_cell_renderer_stop_editing (GTK_CELL_RENDERER (cell), TRUE);
+		return;
+	}
+	
+	path = g_object_get_data (G_OBJECT (editable),
+				  GNC_CELL_RENDERER_POPUP_PATH);
+	new_text = gnc_popup_entry_get_text (GNC_POPUP_ENTRY (editable));
+
+	g_signal_emit_by_name (cell,
+			       "edited",
+			       path,
+			       new_text);
+}
+
+static void
+gcrp_style_set (GtkWidget           *widget,
+		GtkStyle            *old_style,
+		GncCellRendererPopup *popup)
+{
+	/* Invalidate the cache. */
+	popup->button_width = -1;
+}
+	
+static gboolean
+gcrp_grab_on_window (GdkWindow *window,
+		     guint32    activate_time)
+{
+	if ((gdk_pointer_grab (window, TRUE,
+			       GDK_BUTTON_PRESS_MASK |
+			       GDK_BUTTON_RELEASE_MASK |
+			       GDK_POINTER_MOTION_MASK,
+			       NULL, NULL, activate_time) == 0)) {
+		if (gdk_keyboard_grab (window, TRUE,
+			       activate_time) == 0)
+			return TRUE;
+		else {
+			gdk_pointer_ungrab (activate_time);
+			return FALSE;
+		}
+	}
+
+	return FALSE;
+}
+
+static void
+gcrp_show_popup (GncCellRendererPopup *cell,
+		 const gchar         *path,
+		 gint                 x1,
+		 gint                 y1,
+		 gint                 x2,
+		 gint                 y2)
+{
+	GtkAllocation alloc;
+	gint          x, y;
+	gint          screen_height, screen_width;
+	gint          button_height;
+
+	cell->shown = TRUE;
+
+	gtk_widget_realize (cell->popup_window);
+
+	/* I'm not sure this is ok to do, but we need to show the window to be
+	 * able to get the allocation right.
+	 */
+	gtk_window_move (GTK_WINDOW (cell->popup_window), -500, -500);
+	gtk_widget_show (cell->popup_window);
+
+	alloc = cell->popup_window->allocation;
+
+	x = x2;
+	y = y2;
+
+	button_height = y2 - y1;
+	
+	screen_height = gdk_screen_height () - y;
+	screen_width = gdk_screen_width ();
+
+	/* Check if it fits in the available height. */
+	if (alloc.height > screen_height) {
+		/* It doesn't fit, so we see if we have the minimum space needed. */
+		if (alloc.height > screen_height && y - button_height > screen_height) {
+			/* We don't, so we show the popup above the cell
+			   instead of below it. */
+			screen_height = y - button_height;
+			y -= (alloc.height + button_height);
+			if (y < 0) {
+				y = 0;
+			}
+		}
+	}
+
+	/* We try to line it up with the right edge of the column, but we don't
+	 * want it to go off the edges of the screen.
+	 */
+	if (x > screen_width) {
+		x = screen_width;
+	}
+
+	x -= alloc.width;
+	if (x < 0) {
+		x = 0;
+	}
+
+	gtk_grab_add (cell->popup_window);
+
+	gtk_window_move (GTK_WINDOW (cell->popup_window), x, y);
+	gtk_widget_show (cell->popup_window);
+
+	gtk_widget_grab_focus (cell->focus_window);
+
+	gcrp_grab_on_window (cell->popup_window->window,
+			     gtk_get_current_event_time ());
+}
+
+static void
+gcrp_hide_popup (GncCellRendererPopup *cell)
+{
+	gtk_grab_remove (cell->popup_window);
+	gtk_widget_hide (cell->popup_window);
+
+	if (cell->editable) {
+		gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (cell->editable));
+	}
+
+	/* This may look weird (the test), but the weak pointer will actually be
+	 * nulled out for some cells, like the date cell.
+	 */
+	if (cell->editable) {
+		gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (cell->editable));
+	}
+	
+	cell->shown = FALSE;
+	cell->editing_canceled = FALSE;
+}
+
+static void
+gcrp_arrow_clicked (GtkCellEditable     *entry,
+		    GncCellRendererPopup *cell)
+{
+	GtkAllocation  alloc;
+	gint           x, y;
+	const gchar   *path;
+	
+	if (cell->shown) {
+		cell->editing_canceled = TRUE;
+		gnc_cell_renderer_popup_hide (cell);
+		return;
+	}
+	
+	path = g_object_get_data (G_OBJECT (entry),
+				  GNC_CELL_RENDERER_POPUP_PATH);
+
+	/* Temporarily grab pointer and keyboard on a window we know exists; we
+	 * do this so that the grab (with owner events == TRUE) affects
+	 * events generated when the window is mapped, such as enter
+	 * notify events on subwidgets. If the grab fails, bail out.
+	 */
+	if (!gcrp_grab_on_window (GTK_WIDGET (entry)->window,
+				  gtk_get_current_event_time ())) {
+		return;
+	}
+	
+	gtk_editable_select_region (GTK_EDITABLE (GNC_POPUP_ENTRY (entry)->entry), 0, 0);
+
+	gdk_window_get_origin (GTK_WIDGET (entry)->window, &x, &y);
+	
+	alloc = GTK_WIDGET (entry)->allocation;
+
+	g_signal_emit (cell, signals[SHOW_POPUP], 0,
+		       path, 
+		       x,
+		       y,
+		       x + alloc.width,
+		       y + alloc.height);
+}
+
+static GtkCellEditable *
+gcrp_start_editing (GtkCellRenderer      *cell,
+		    GdkEvent             *event,
+		    GtkWidget            *widget,
+		    const gchar          *path,
+		    GdkRectangle         *background_area,
+		    GdkRectangle         *cell_area,
+		    GtkCellRendererState  flags)
+{
+	GncCellRendererPopup *popup;
+	GtkWidget           *editable;
+	gchar               *text;
+	
+	popup = GNC_CELL_RENDERER_POPUP (cell);
+
+	/* If the cell isn't editable we return NULL. */
+	if (GTK_CELL_RENDERER_TEXT (popup)->editable == FALSE) {
+		return NULL;
+	}
+	
+	editable = g_object_new (GNC_TYPE_POPUP_ENTRY, NULL);
+
+	text = GTK_CELL_RENDERER_TEXT (cell)->text;
+        popup->cell_text = g_strdup(text);
+
+	gnc_popup_entry_set_text (GNC_POPUP_ENTRY (editable), text ? text : "");
+	
+	g_object_set_data_full (G_OBJECT (editable),
+				GNC_CELL_RENDERER_POPUP_PATH,
+				g_strdup (path),
+				g_free);
+	
+	gtk_widget_show (editable);
+
+	g_signal_connect (editable,
+			  "editing-done",
+			  G_CALLBACK (gcrp_editing_done),
+			  popup);
+
+	g_signal_connect (editable,
+			  "arrow-clicked",
+			  G_CALLBACK (gcrp_arrow_clicked),
+			  popup);
+
+	popup->editable = editable;
+
+	g_object_add_weak_pointer (G_OBJECT (popup->editable),
+				   (gpointer) &popup->editable);
+	
+	return GTK_CELL_EDITABLE (editable);
+}
+
+GtkCellRenderer *
+gnc_cell_renderer_popup_new (void)
+{
+	return GTK_CELL_RENDERER (
+		g_object_new (gnc_cell_renderer_popup_get_type (), NULL));
+}
+
+void
+gnc_cell_renderer_popup_hide (GncCellRendererPopup *cell)
+{ 
+	g_return_if_fail (GNC_IS_CELL_RENDERER_POPUP (cell));
+	
+	g_signal_emit (cell, signals[HIDE_POPUP], 0);
+}
+
+static void
+gcrp_get_size (GtkCellRenderer *cell,
+	       GtkWidget       *widget,
+	       GdkRectangle    *cell_area,
+	       gint            *x_offset,
+	       gint            *y_offset,
+	       gint            *width,
+	       gint            *height)
+{
+	GncCellRendererPopup *popup;
+
+	popup = GNC_CELL_RENDERER_POPUP (cell);
+	
+	if (GTK_CELL_RENDERER_CLASS (parent_class)->get_size) { 
+		(* GTK_CELL_RENDERER_CLASS (parent_class)->get_size) (cell,
+								      widget,
+								      cell_area, 
+								      x_offset,
+								      y_offset,
+								      width,
+								      height);
+	}
+
+	/* We cache this because it takes really long to get the width. */
+	if (popup->button_width == -1) {
+		popup->button_width = gnc_popup_get_button_width ();
+	}
+	
+	*width += popup->button_width;
+}
+
+static gboolean
+gcrp_key_press_event (GtkWidget           *popup_window,
+		      GdkEventKey         *event,
+		      GncCellRendererPopup *cell)
+{
+	if (event->keyval != GDK_Escape &&
+	    event->keyval != GDK_Return &&
+	    event->keyval != GDK_KP_Enter &&
+	    event->keyval != GDK_ISO_Enter &&
+	    event->keyval != GDK_3270_Enter) {
+		return FALSE;
+	}
+	if (event->keyval == GDK_Escape) {
+		cell->editing_canceled = TRUE;
+	} else {
+		cell->editing_canceled = FALSE;
+	}		
+	gnc_cell_renderer_popup_hide (cell);
+
+	return TRUE;
+}
+
+static gboolean
+gcrp_button_press_event (GtkWidget           *widget,
+			 GdkEventButton      *event,
+			 GncCellRendererPopup *popup)
+{
+	GtkAllocation alloc;
+	gdouble       x, y;
+	gint          xoffset, yoffset;
+	gint          x1, y1;
+	gint          x2, y2;
+
+	if (event->button != 1) {
+		return FALSE;
+	}
+	
+	/* If the event happened outside the popup, cancel editing.
+	 */
+
+	/*gdk_event_get_root_coords ((GdkEvent *) event, &x, &y);*/
+	x = event->x_root;
+	y = event->y_root;
+
+	gdk_window_get_root_origin (widget->window,
+				    &xoffset,
+				    &yoffset);
+
+	xoffset += widget->allocation.x;
+	yoffset += widget->allocation.y;
+	
+	alloc = popup->popup_window->allocation;
+	x1 = alloc.x + xoffset;
+	y1 = alloc.y + yoffset;
+	x2 = x1 + alloc.width;
+	y2 = y1 + alloc.height;
+
+	if (x > x1 && x < x2 && y > y1 && y < y2) {
+		return FALSE;
+	}
+	
+	popup->editing_canceled = TRUE;
+	gnc_cell_renderer_popup_hide (popup);
+	
+	return FALSE;
+}
+
+
+#define g_marshal_value_peek_int(v)      (v)->data[0].v_int
+#define g_marshal_value_peek_string(v)   (v)->data[0].v_pointer
+
+void
+gnc_marshal_VOID__STRING_INT_INT_INT_INT (GClosure     *closure,
+                                              GValue       *return_value G_GNUC_UNUSED,
+                                              guint         n_param_values,
+                                              const GValue *param_values,
+                                              gpointer      invocation_hint G_GNUC_UNUSED,
+                                              gpointer      marshal_data)
+{
+  typedef void (*GMarshalFunc_VOID__STRING_INT_INT_INT_INT) (gpointer     data1,
+                                                             gpointer     arg_1,
+                                                             gint         arg_2,
+                                                             gint         arg_3,
+                                                             gint         arg_4,
+                                                             gint         arg_5,
+                                                             gpointer     data2);
+  register GMarshalFunc_VOID__STRING_INT_INT_INT_INT callback;
+  register GCClosure *cc = (GCClosure*) closure;
+  register gpointer data1, data2;
+
+  g_return_if_fail (n_param_values == 6);
+
+  if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+      data1 = closure->data;
+      data2 = g_value_peek_pointer (param_values + 0);
+    }
+  else
+    {
+      data1 = g_value_peek_pointer (param_values + 0);
+      data2 = closure->data;
+    }
+  callback = (GMarshalFunc_VOID__STRING_INT_INT_INT_INT) (marshal_data ? marshal_data : cc->callback);
+
+  callback (data1,
+            g_marshal_value_peek_string (param_values + 1),
+            g_marshal_value_peek_int (param_values + 2),
+            g_marshal_value_peek_int (param_values + 3),
+            g_marshal_value_peek_int (param_values + 4),
+            g_marshal_value_peek_int (param_values + 5),
+            data2);
+}
+
Index: src/gnome-utils/gnc-cell-renderer-popup.h
===================================================================
--- src/gnome-utils/gnc-cell-renderer-popup.h	(revision 0)
+++ src/gnome-utils/gnc-cell-renderer-popup.h	(revision 0)
@@ -0,0 +1,94 @@
+/*************************************************************************
+ * The following code has come from Planner. This code implements a
+ * GtkCalendar in a custom GtkCellEditable popup from GtkCellRenderer.
+ *
+ * These files have been renamed and changed to remove code not required
+ * and to remove a dependency on libplanner.
+ *
+ * Copyright (C) 2012 Robert Fewell
+ *
+ * Copyright (C) 2001-2002 CodeFactory AB
+ * Copyright (C) 2001-2002 Richard Hult <richard@imendio.com>
+ * Copyright (C) 2001-2002 Mikael Hallendal <micke@imendio.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *************************************************************************/
+
+#ifndef __GNC_CELL_RENDERER_POPUP_H__
+#define __GNC_CELL_RENDERER_POPUP_H__
+
+#include <pango/pango.h>
+#include <gtk/gtkcellrenderertext.h>
+
+#define GNC_TYPE_CELL_RENDERER_POPUP		(gnc_cell_renderer_popup_get_type ())
+#define GNC_CELL_RENDERER_POPUP(obj)		(GTK_CHECK_CAST ((obj), GNC_TYPE_CELL_RENDERER_POPUP, GncCellRendererPopup))
+#define GNC_CELL_RENDERER_POPUP_CLASS(klass)	(GTK_CHECK_CLASS_CAST ((klass), GNC_TYPE_CELL_RENDERER_POPUP, GncCellRendererPopupClass))
+#define GNC_IS_CELL_RENDERER_POPUP(obj)		(GTK_CHECK_TYPE ((obj), GNC_TYPE_CELL_RENDERER_POPUP))
+#define GNC_IS_CELL_RENDERER_POPUP_CLASS(klass)	(GTK_CHECK_CLASS_TYPE ((obj), GNC_TYPE_CELL_RENDERER_POPUP))
+#define GNC_CELL_RENDERER_POPUP_GET_CLASS(obj)   (GTK_CHECK_GET_CLASS ((obj), GNC_TYPE_CELL_RENDERER_POPUP, GncCellRendererPopupClass))
+
+typedef struct _GncCellRendererPopup      GncCellRendererPopup;
+typedef struct _GncCellRendererPopupClass GncCellRendererPopupClass;
+
+struct _GncCellRendererPopup
+{
+	GtkCellRendererText  parent;
+
+	/* Cached width of the popup button. */
+	gint                 button_width;
+	
+	/* The popup window. */
+	GtkWidget           *popup_window;
+
+	/* The widget that should grab focus on popup. */
+	GtkWidget           *focus_window;
+
+	/* The editable entry. */
+	GtkWidget           *editable;
+
+	gboolean             shown;
+	gboolean             editing_canceled;
+        gchar                *cell_text;
+};
+
+struct _GncCellRendererPopupClass
+{
+	GtkCellRendererTextClass parent_class;
+	
+	void   (* show_popup) (GncCellRendererPopup *cell,
+			       const gchar         *path,
+			       gint                 x1,
+			       gint                 y1,
+			       gint                 x2,
+			       gint                 y2);
+	
+	void   (* hide_popup) (GncCellRendererPopup *cell);
+};
+
+GtkType          gnc_cell_renderer_popup_get_type (void) G_GNUC_CONST;
+
+GtkCellRenderer *gnc_cell_renderer_popup_new      (void);
+
+void             gnc_cell_renderer_popup_show     (GncCellRendererPopup *cell,
+						  const gchar         *path,
+						  gint                 x1,
+						  gint                 y1,
+						  gint                 x2,
+						  gint                 y2);
+
+void             gnc_cell_renderer_popup_hide     (GncCellRendererPopup *cell);
+
+#endif /* __GNC_CELL_RENDERER_POPUP_H__ */
Index: src/gnome-utils/gnc-cell-renderer-date.c
===================================================================
--- src/gnome-utils/gnc-cell-renderer-date.c	(revision 0)
+++ src/gnome-utils/gnc-cell-renderer-date.c	(revision 0)
@@ -0,0 +1,525 @@
+/*************************************************************************
+ * The following code has come from Planner. This code implements a
+ * GtkCalendar in a custom GtkCellEditable popup from GtkCellRenderer.
+ *
+ * These files have been renamed and changed to remove code not required
+ * and to remove a dependency on libplanner.
+ *
+ * Copyright (C) 2012 Robert Fewell
+ *
+ * Copyright (C) 2005 Imendio AB
+ * Copyright (C) 2001-2002 CodeFactory AB
+ * Copyright (C) 2001-2002 Richard Hult <richard@imendio.com>
+ * Copyright (C) 2001-2002 Mikael Hallendal <micke@imendio.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ **************************************************************************/
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+#include <string.h>
+#include <time.h>
+
+#include "gnc-cell-renderer-date.h"
+#include "gnc-cell-renderer-popup-entry.h"
+#include "gnc-date.h"
+
+enum {
+	PROP_0,
+        PROP_USE_BUTTONS,
+};
+
+static void     gcrd_init                    (GncCellRendererDate      *date);
+
+static void     gcrd_class_init              (GncCellRendererDateClass *class);
+
+static void     gcrd_set_property            (GObject                 *object,
+					      guint                    param_id,
+					      const GValue            *value,
+					      GParamSpec              *pspec);
+
+static void     gcrd_get_property            (GObject                 *object,
+					      guint                    param_id,
+					      GValue                  *value,
+					      GParamSpec              *pspec);
+
+static void     gcrd_today_clicked           (GtkWidget               *button,
+					      GncCellRendererDate *cell);
+
+static void     gcrd_selected_double_click   (GtkWidget               *calendar,
+					      GncCellRendererDate *cell);
+
+static void     gcrd_cancel_clicked          (GtkWidget               *popup_window,
+					      GncCellRendererDate      *cell);
+
+static void     gcrd_ok_clicked              (GtkWidget               *popup_window,
+					      GncCellRendererDate      *cell);
+
+static void     gcrd_day_selected            (GtkWidget               *popup_window,
+					      GncCellRendererDate      *cell);
+
+GtkCellEditable *gcrd_start_editing          (GtkCellRenderer         *cell,
+					      GdkEvent                *event,
+					      GtkWidget               *widget,
+					      const gchar             *path,
+					      GdkRectangle            *background_area,
+					      GdkRectangle            *cell_area,
+					      GtkCellRendererState     flags);
+
+static void     gcrd_show                    (GncCellRendererPopup     *cell,
+					      const gchar             *path,
+					      gint                     x1,
+					      gint                     y1,
+					      gint                     x2,
+					      gint                     y2);
+static void     gcrd_hide                    (GncCellRendererPopup     *cell);
+
+
+/* These two functions are used internally */
+gboolean gcrd_time2dmy ( time_t raw_time, gint *day, gint *month, gint *year);
+static time_t gcrd_dmy2time ( gint day, gint month, gint year);
+
+/* These two functions convert string to date to string */
+static gchar * gcrd_time2dmy_string ( time_t raw_time);
+static time_t gcrd_string_dmy2time ( char *date_string);
+
+
+static GncCellRendererPopupClass *parent_class;
+
+GType
+gnc_cell_renderer_date_get_type (void)
+{
+	static GType cell_text_type = 0;
+	
+	if (!cell_text_type) {
+		static const GTypeInfo cell_text_info = {
+			sizeof (GncCellRendererDateClass),
+			NULL,		/* base_init */
+			NULL,		/* base_finalize */
+			(GClassInitFunc) gcrd_class_init,
+			NULL,		/* class_finalize */
+			NULL,		/* class_data */
+			sizeof (GncCellRendererDate),
+			0,              /* n_preallocs */
+			(GInstanceInitFunc) gcrd_init,
+		};
+		
+		cell_text_type = g_type_register_static (GNC_TYPE_CELL_RENDERER_POPUP,
+							 "GncCellRendererDate",
+							 &cell_text_info,
+							 0);
+	}
+	
+	return cell_text_type;
+}
+
+static void
+gcrd_init (GncCellRendererDate *date)
+{
+	GncCellRendererPopup *popup;
+	GtkWidget                *frame;
+	GtkWidget                *vbox;
+	GtkWidget                *bbox;
+	GtkWidget                *button;
+
+	popup = GNC_CELL_RENDERER_POPUP (date);
+
+	frame = gtk_frame_new (NULL);
+	gtk_container_add (GTK_CONTAINER (popup->popup_window), frame);
+	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
+
+	vbox = gtk_vbox_new (FALSE, 6);
+	gtk_container_add (GTK_CONTAINER (frame), vbox);
+	gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
+	
+	date->calendar = gtk_calendar_new ();
+	popup->focus_window = date->calendar;
+	gtk_box_pack_start (GTK_BOX (vbox), date->calendar, TRUE, TRUE, 0);
+
+        date->button_box = gtk_hbutton_box_new ();
+	gtk_box_set_spacing (GTK_BOX (date->button_box), 6);
+	gtk_box_pack_start (GTK_BOX (vbox), date->button_box, FALSE, FALSE, 0);
+
+	button = gtk_button_new_with_label (_("Cancel"));
+	gtk_container_add (GTK_CONTAINER (date->button_box), button);
+	g_signal_connect (button, "clicked",
+			  G_CALLBACK (gcrd_cancel_clicked),
+			  date);
+
+	date->today_button = gtk_button_new_with_label (_("Today"));
+	gtk_container_add (GTK_CONTAINER (date->button_box), date->today_button);
+	g_signal_connect (date->today_button, "clicked",
+			  G_CALLBACK (gcrd_today_clicked),
+			  date);
+
+	button = gtk_button_new_with_label (_("Select"));
+	gtk_container_add (GTK_CONTAINER (date->button_box), button);
+	g_signal_connect (button, "clicked",
+			  G_CALLBACK (gcrd_ok_clicked),
+			  date);
+
+	g_signal_connect (date->calendar, "day-selected",
+			  G_CALLBACK (gcrd_day_selected),
+			  date);
+	g_signal_connect (date->calendar, "day-selected-double-click", 
+			  G_CALLBACK (gcrd_selected_double_click),
+			  date);
+
+	//Set calendar to show current date when displayed
+	date->time = time(NULL);
+
+        gtk_widget_show_all (frame);
+}
+
+static void
+gcrd_class_init (GncCellRendererDateClass *class)
+{
+	GncCellRendererPopupClass     *popup_class;
+	GtkCellRendererClass          *cell_class;
+	GObjectClass                  *gobject_class;
+
+	popup_class = GNC_CELL_RENDERER_POPUP_CLASS (class);
+	cell_class = GTK_CELL_RENDERER_CLASS (class);	
+	parent_class = GNC_CELL_RENDERER_POPUP_CLASS (g_type_class_peek_parent (class));
+	gobject_class = G_OBJECT_CLASS (class);
+
+	gobject_class->set_property = gcrd_set_property;
+	gobject_class->get_property = gcrd_get_property;
+
+	cell_class->start_editing = gcrd_start_editing;
+		
+	popup_class->show_popup = gcrd_show;
+	popup_class->hide_popup = gcrd_hide;
+
+	g_object_class_install_property (
+		gobject_class,
+                 PROP_USE_BUTTONS,
+                 g_param_spec_boolean ("use-buttons",
+				       NULL,
+				       NULL,
+				       TRUE,
+				       G_PARAM_READWRITE));
+
+}
+
+static void
+gcrd_set_property (GObject      *object,
+		   guint         param_id,
+		   const GValue *value,
+		   GParamSpec   *pspec)
+{
+	GncCellRendererDate *date;
+
+	date = GNC_CELL_RENDERER_DATE (object);
+	
+	switch (param_id) {
+	case PROP_USE_BUTTONS:
+		date->use_buttons = g_value_get_boolean (value);
+
+		if (date->use_buttons)
+			gtk_widget_show (date->button_box);
+		else
+			gtk_widget_hide (date->button_box);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+static void
+gcrd_get_property (GObject    *object,
+		   guint       param_id,
+		   GValue     *value,
+		   GParamSpec *pspec)
+{
+	GncCellRendererDate *date;
+
+	date = GNC_CELL_RENDERER_DATE (object);
+	
+	switch (param_id) {
+	case PROP_USE_BUTTONS:
+		g_value_set_boolean (value, date->use_buttons);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+GtkCellEditable *
+gcrd_start_editing (GtkCellRenderer      *cell,
+		    GdkEvent             *event,
+		    GtkWidget            *widget,
+		    const gchar          *path,
+		    GdkRectangle         *background_area,
+		    GdkRectangle         *cell_area,
+		    GtkCellRendererState  flags)
+{
+	GNC_CELL_RENDERER_POPUP (cell)->editing_canceled = FALSE;
+	
+	if (GTK_CELL_RENDERER_CLASS (parent_class)->start_editing) {
+		return GTK_CELL_RENDERER_CLASS (parent_class)->start_editing (
+							cell,
+							event,
+							widget,
+							path,
+							background_area,
+							cell_area,
+							flags);
+	}
+
+	return NULL;
+}
+
+
+static void
+gcrd_hide (GncCellRendererPopup *cell)
+{
+	if (parent_class->hide_popup) {
+		parent_class->hide_popup (cell);
+	}
+}
+
+static void
+gcrd_show (GncCellRendererPopup *cell,
+	   const gchar              *path,
+	   gint                      x1,
+	   gint                      y1,
+	   gint                      x2,
+	   gint                      y2)
+{
+	GncCellRendererDate *date;
+	gint                     year;
+	gint                     month;
+	gint                     day;
+	gint                     index;
+	gchar                   *text;
+
+	if (parent_class->show_popup) {
+		parent_class->show_popup (cell,
+					  path,
+					  x1, y1,
+					  x2, y2);
+	}
+
+	date = GNC_CELL_RENDERER_DATE (cell);
+
+        if (!(g_strcmp0(cell->cell_text, "")))
+        {
+	    date->time = time(NULL);
+            gcrd_time2dmy ( date->time, &day, &month, &year);
+        }
+        else
+        {
+            date->time = gcrd_string_dmy2time (cell->cell_text);
+            gcrd_time2dmy ( date->time, &day, &month, &year);
+        }
+
+	gtk_calendar_clear_marks (GTK_CALENDAR (date->calendar));
+	gtk_calendar_select_month (GTK_CALENDAR (date->calendar), month - 1, year);
+
+	gtk_calendar_select_day (GTK_CALENDAR (date->calendar), day);
+	gtk_calendar_mark_day (GTK_CALENDAR (date->calendar), day);
+	
+}
+
+GtkCellRenderer *
+gnc_cell_renderer_date_new (gboolean use_buttons)
+{
+	GObject *cell;
+
+	cell = g_object_new (GNC_TYPE_CELL_RENDERER_DATE,
+			     "use-buttons", use_buttons,
+			     NULL);
+	
+	return GTK_CELL_RENDERER (cell);
+}
+
+static void
+gcrd_today_clicked (GtkWidget *button, GncCellRendererDate *cell)
+{
+	time_t  today;
+	gint    year, month, day;
+	
+	today = time(NULL);
+
+        gcrd_time2dmy ( today, &day, &month, &year);
+	
+	gtk_calendar_clear_marks (GTK_CALENDAR (cell->calendar));
+	gtk_calendar_select_month (GTK_CALENDAR (cell->calendar), month - 1, year);
+	gtk_calendar_select_day (GTK_CALENDAR (cell->calendar), day);
+	gtk_calendar_mark_day (GTK_CALENDAR (cell->calendar), day);
+}
+
+static void
+gcrd_selected_double_click (GtkWidget *calendar, GncCellRendererDate *cell)
+{
+	GncCellRendererPopup *popup;
+	
+	popup = GNC_CELL_RENDERER_POPUP (cell);
+
+	gcrd_ok_clicked (popup->popup_window, cell);
+}
+
+static void
+gcrd_cancel_clicked (GtkWidget *popup_window, GncCellRendererDate *cell)
+{
+	GncCellRendererPopup *popup;
+	
+	popup = GNC_CELL_RENDERER_POPUP (cell);
+
+	popup->editing_canceled = TRUE;
+	gnc_cell_renderer_popup_hide (popup);
+}
+
+static void
+gcrd_ok_clicked (GtkWidget *popup_window, GncCellRendererDate *cell)
+{
+	GncCellRendererPopup *popup;
+	
+	popup = GNC_CELL_RENDERER_POPUP (cell);
+
+	gcrd_day_selected (popup_window, cell);
+
+	popup->editing_canceled = FALSE;
+	gnc_cell_renderer_popup_hide (popup);
+}
+
+static void
+gcrd_day_selected (GtkWidget *popup_window, GncCellRendererDate *cell)
+{
+	guint    year;
+	guint    month;
+	guint    day;
+	time_t   t;
+	gchar   *str;
+
+	gtk_calendar_get_date (GTK_CALENDAR (cell->calendar),
+			       &year,
+			       &month,
+			       &day);
+
+        t = gcrd_dmy2time ( day, month + 1, year);
+
+	cell->time = t;
+
+	str = gcrd_time2dmy_string (t);
+
+	gnc_popup_entry_set_text (
+		GNC_POPUP_ENTRY (GNC_CELL_RENDERER_POPUP (cell)->editable), str);
+	g_free (str);
+
+}
+
+static gboolean
+gcrd_grab_on_window (GdkWindow *window,
+		     guint32    activate_time)
+{
+	if ((gdk_pointer_grab (window, TRUE,
+			       GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+			       GDK_POINTER_MOTION_MASK,
+			       NULL, NULL, activate_time) == 0)) {
+		if (gdk_keyboard_grab (window, TRUE,
+			       activate_time) == 0)
+			return TRUE;
+		else {
+			gdk_pointer_ungrab (activate_time);
+			return FALSE;
+		}
+	}
+
+	return FALSE;
+}
+
+
+/* This function converts a time_t value date to separate entities */
+gboolean
+gcrd_time2dmy ( time_t raw_time, gint *day, gint *month, gint *year)
+{
+    struct tm * timeinfo;
+  
+    timeinfo = localtime ( &raw_time );
+ 
+    *day = timeinfo->tm_mday;
+    *month = timeinfo->tm_mon + 1;
+    *year = timeinfo->tm_year + 1900;
+
+    return TRUE;
+}
+
+/* This function converts separate entities to a time_t value */
+static time_t
+gcrd_dmy2time ( gint day, gint month, gint year)
+{
+    struct tm *when;
+
+    time_t raw_time;
+
+    time(&raw_time);
+    when = localtime ( &raw_time );
+
+    when->tm_year = year - 1900;
+    when->tm_mon = month - 1 ;
+    when->tm_mday = day;
+
+    return mktime(when);
+}
+
+
+/* This function converts a time_t value date to a string */
+static gchar *
+gcrd_time2dmy_string ( time_t raw_time)
+{
+    return qof_print_date (raw_time);
+}
+
+
+/* This function converts a string date to a time_t value */
+static time_t
+gcrd_string_dmy2time ( char *date_string)
+{
+    struct tm *when;
+    gint year = 0, month = 0, day = 0;
+
+    time_t raw_time;
+
+    if(qof_scan_date (date_string, &day, &month, &year))
+    {
+        time(&raw_time);
+        when = localtime ( &raw_time );
+
+        when->tm_year = year - 1900;
+        when->tm_mon = month - 1 ;
+        when->tm_mday = day;
+
+        return mktime(when);
+    }
+    else
+    {
+ 	raw_time = time(NULL);
+        return raw_time;
+    }
+}
+
+
+
+
+
Index: src/gnome-utils/gnc-cell-renderer-date.h
===================================================================
--- src/gnome-utils/gnc-cell-renderer-date.h	(revision 0)
+++ src/gnome-utils/gnc-cell-renderer-date.h	(revision 0)
@@ -0,0 +1,71 @@
+/*************************************************************************
+ * The following code has come from Planner. This code implements a
+ * GtkCalendar in a custom GtkCellEditable popup from GtkCellRenderer.
+ *
+ * These files have been renamed and changed to remove code not required
+ * and to remove a dependency on libplanner.
+ *
+ * Copyright (C) 2012 Robert Fewell
+ *
+ * Copyright (C) 2005 Imendio AB
+ * Copyright (C) 2001-2002 CodeFactory AB
+ * Copyright (C) 2001-2002 Richard Hult <richard@imendio.com>
+ * Copyright (C) 2001-2002 Mikael Hallendal <micke@imendio.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ **************************************************************************/
+
+#ifndef __GNC_CELL_RENDERER_DATE_H__
+#define __GNC_CELL_RENDERER_DATE_H__
+
+#include <glib-object.h>
+#include <gtk/gtkwidget.h>
+#include <time.h>
+#include "gnc-cell-renderer-popup.h"
+#include "gnc-cell-renderer-popup-entry.h"
+
+#define GNC_TYPE_CELL_RENDERER_DATE	       (gnc_cell_renderer_date_get_type ())
+#define GNC_CELL_RENDERER_DATE(obj)	       (GTK_CHECK_CAST ((obj), GNC_TYPE_CELL_RENDERER_DATE, GncCellRendererDate))
+#define GNC_CELL_RENDERER_DATE_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNC_TYPE_CELL_RENDERER_DATE, GncCellRendererDateClass))
+#define GNC_IS_CELL_RENDERER_DATE(obj)	       (GTK_CHECK_TYPE ((obj), GNC_TYPE_CELL_RENDERER_DATE))
+#define GNC_IS_CELL_RENDERER_DATE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), GNC_TYPE_CELL_RENDERER_DATE))
+#define GNC_CELL_RENDERER_DATE_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNC_TYPE_CELL_RENDERER_DATE, GncCellRendererDateClass))
+
+typedef struct _GncCellRendererDate      GncCellRendererDate;
+typedef struct _GncCellRendererDateClass GncCellRendererDateClass;
+
+struct _GncCellRendererDate
+{
+	GncCellRendererPopup      parent;
+	GtkWidget                *calendar;
+	GtkWidget                *today_button;
+
+	time_t                    time;
+        gboolean                  use_buttons;
+	GtkWidget                *button_box;
+
+};
+
+struct _GncCellRendererDateClass
+{
+	GncCellRendererPopupClass parent_class;
+};
+
+GType            gnc_cell_renderer_date_get_type (void) G_GNUC_CONST;
+GtkCellRenderer *gnc_cell_renderer_date_new      (gboolean use_buttons);
+
+
+#endif /* __GNC_CELL_RENDERER_DATE_H__ */
Index: src/gnome-utils/gnc-tree-view.c
===================================================================
--- src/gnome-utils/gnc-tree-view.c	(revision 22178)
+++ src/gnome-utils/gnc-tree-view.c	(working copy)
@@ -43,6 +43,7 @@
 #include "gnc-gconf-utils.h"
 #include "gnc-gnome-utils.h"
 #include "gnc-gobject-utils.h"
+#include "gnc-cell-renderer-date.h"
 
 /* The column id refers to a specific column in the tree model.  It is
  * also attached to the side of the tree column to allow lookup of a
@@ -1997,7 +1998,74 @@
     return column;
 }
 
+
+
+/** This function adds a new date column to a GncTreeView base view.
+ *  It takes all the parameters necessary to hook a GtkTreeModel
+ *  column to a GtkTreeViewColumn.  If the tree has a gconf section
+ *  associated with it, this function also wires up the column so that
+ *  its visibility and width are remembered.
+ *
+ *  Parameters are defined in gnc-tree-view.h
+ */
 GtkTreeViewColumn *
+gnc_tree_view_add_date_column (GncTreeView *view,
+                                   const gchar *column_title,
+                                   const gchar *pref_name,
+                                   const gchar *stock_icon_name,
+                                   const gchar *sizing_text,
+                                   gint model_data_column,
+                                   gint model_visibility_column,
+                                   GtkTreeIterCompareFunc column_sort_fn)
+{
+  GtkTreeViewColumn *column;
+  GtkCellRenderer *renderer;
+  PangoLayout* layout;
+  int default_width, title_width;
+
+  g_return_val_if_fail (GNC_IS_TREE_VIEW(view), NULL);
+
+  column = gtk_tree_view_column_new ();
+  gtk_tree_view_column_set_title (column, column_title);
+
+  /* Set up an icon renderer if requested */
+  if (stock_icon_name) {
+    renderer = gtk_cell_renderer_pixbuf_new ();
+    g_object_set (renderer, "stock-id", stock_icon_name, NULL);
+    gtk_tree_view_column_pack_start (column, renderer, FALSE);
+  }
+
+  /* Set up a text renderer and attributes */
+  renderer = gnc_cell_renderer_date_new(TRUE);
+  gtk_tree_view_column_pack_start (column, renderer, TRUE);
+
+  /* Set renderer attributes controlled by the model */
+  if (model_data_column != GNC_TREE_VIEW_COLUMN_DATA_NONE)
+    gtk_tree_view_column_add_attribute (column, renderer,
+					"text", model_data_column);
+  if (model_visibility_column != GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS)
+    gtk_tree_view_column_add_attribute (column, renderer,
+					"visible", model_visibility_column);
+
+  /* Default size is the larger of the column title and the sizing text */
+  layout = gtk_widget_create_pango_layout (GTK_WIDGET(view), column_title);
+  pango_layout_get_pixel_size(layout, &title_width, NULL);
+  g_object_unref(layout);
+  layout = gtk_widget_create_pango_layout (GTK_WIDGET(view), sizing_text);
+  pango_layout_get_pixel_size(layout, &default_width, NULL);
+  g_object_unref(layout);
+  default_width = MAX(default_width, title_width);
+  if (default_width)
+    default_width += 10; /* padding on either side */
+  gnc_tree_view_column_properties (view, column, pref_name, model_data_column,
+				   default_width, TRUE, column_sort_fn);
+
+  gnc_tree_view_append_column (view, column);
+  return column;
+}
+
+
+GtkTreeViewColumn *
 gnc_tree_view_add_combo_column (GncTreeView *view,
                                 const gchar *column_title,
                                 const gchar *pref_name,
Index: src/gnome-utils/gnc-tree-view.h
===================================================================
--- src/gnome-utils/gnc-tree-view.h	(revision 22178)
+++ src/gnome-utils/gnc-tree-view.h	(working copy)
@@ -33,6 +33,7 @@
 #define __GNC_TREE_VIEW_H
 
 #include <gtk/gtk.h>
+#include "gnc-cell-renderer-date.h"
 
 G_BEGIN_DECLS
 
@@ -208,6 +209,22 @@
                                 gint combo_model_text_column,
                                 GtkTreeIterCompareFunc column_sort_fn);
 
+
+/** This function adds a new date column to a GncTreeView base
+ *  view.  The parameters it takes in common with
+ *  gnc_tree_view_add_text_column() behave the same as there.
+ */
+GtkTreeViewColumn *
+gnc_tree_view_add_date_column (GncTreeView *view,
+                                   const gchar *column_title,
+                                   const gchar *pref_name,
+                                   const gchar *stock_icon_name,
+                                   const gchar *sizing_text,
+                                   gint model_data_column,
+                                   gint model_visibility_column,
+                                   GtkTreeIterCompareFunc column_sort_fn);
+
+
 /** This function adds a new numeric column to a GncTreeView base
  *  view.  It takes all the parameters necessary to hook a
  *  GtkTreeModel column to a GtkTreeViewColumn.  If the tree has a
Index: src/engine/Split.h
===================================================================
--- src/engine/Split.h	(revision 22178)
+++ src/engine/Split.h	(working copy)
@@ -343,6 +343,9 @@
 #define      xaccSplitLookupDirect(g,b) xaccSplitLookup(&(g),b)
 
 
+/* Get a GList of unique transactions containing the given list of Splits. */
+GList *xaccSplitListGetUniqueTransactions(const GList *splits);
+
 /**
  * The xaccSplitGetOtherSplit() is a convenience routine that returns
  *    the other of a pair of splits.  If there are more than two
Index: src/engine/Transaction.c
===================================================================
--- src/engine/Transaction.c	(revision 22178)
+++ src/engine/Transaction.c	(working copy)
@@ -953,6 +953,45 @@
     return total;
 }
 
+gboolean
+xaccTransGetRateForCommodity(const Transaction *trans,
+                             const gnc_commodity *split_com,
+                             const Split *split_to_exclude, gnc_numeric *rate)
+{
+    GList *splits;
+    gnc_commodity *trans_curr;
+
+    trans_curr = xaccTransGetCurrency(trans);
+    if (gnc_commodity_equal(trans_curr, split_com)) {
+        if (rate) 
+            *rate = gnc_numeric_create(1, 1);
+        return TRUE;
+    }
+
+    for (splits = trans->splits; splits; splits = splits->next) {
+        Split *s = splits->data;
+        gnc_commodity *comm;
+
+        if (s == split_to_exclude) continue;
+        if (!xaccTransStillHasSplit(trans, s)) continue;
+
+        comm = xaccAccountGetCommodity(xaccSplitGetAccount(s));
+        if (gnc_commodity_equal(split_com, comm)) {
+            gnc_numeric amt = xaccSplitGetAmount(s);
+            gnc_numeric val = xaccSplitGetValue(s);
+
+            if (!gnc_numeric_zero_p(xaccSplitGetValue(s)) &&
+                !gnc_numeric_zero_p(xaccSplitGetValue(s))) {
+                if (rate) 
+                    *rate = gnc_numeric_div(amt, val, GNC_DENOM_AUTO,
+                                            GNC_HOW_DENOM_REDUCE);
+                return TRUE;
+            }
+        }
+    }
+    return FALSE;
+}
+
 gnc_numeric
 xaccTransGetAccountConvRate(const Transaction *txn, const Account *acc)
 {
Index: src/engine/Transaction.h
===================================================================
--- src/engine/Transaction.h	(revision 22178)
+++ src/engine/Transaction.h	(working copy)
@@ -264,11 +264,12 @@
  * See #TXN_TYPE_NONE, #TXN_TYPE_INVOICE and #TXN_TYPE_PAYMENT */
 char	      xaccTransGetTxnType (const Transaction *trans);
 
-
 /** Sets the transaction Number (or ID) field*/
 void          xaccTransSetNum (Transaction *trans, const char *num);
+
 /** Sets the transaction Description */
 void          xaccTransSetDescription (Transaction *trans, const char *desc);
+
 /** Sets the transaction Notes
  *
  The Notes field is only visible in the register in double-line mode */
@@ -318,9 +319,8 @@
     this list when you are done with it. */
 /*@ dependent @*/
 SplitList *   xaccTransGetSplitList (const Transaction *trans);
-gboolean xaccTransStillHasSplit(const Transaction *trans, const Split *s);
+gboolean      xaccTransStillHasSplit(const Transaction *trans, const Split *s);
 
-
 /** Set the transaction to be ReadOnly by setting a non-NULL value as "reason".
  *
  * FIXME: If "reason" is NULL, this function does nothing, instead of removing the
@@ -410,6 +410,13 @@
 gnc_numeric xaccTransGetAccountAmount (const Transaction *trans,
                                        const Account *account);
 
+/* Gets the amt/val rate, i.e. rate from the transaction currency to
+   the 'split_com' */
+gboolean
+xaccTransGetRateForCommodity(const Transaction *trans,
+                             const gnc_commodity *split_com,
+                             const Split *split_to_exclude, gnc_numeric *rate);
+
 /* Compute the conversion rate for the transaction to this account.
  * Any "split value" (which is in the transaction currency),
  * multiplied by this conversion rate, will give you the value you
Index: src/engine/Split.c
===================================================================
--- src/engine/Split.c	(revision 22178)
+++ src/engine/Split.c	(working copy)
@@ -659,7 +659,34 @@
     return TRUE;
 }
 
+
 /********************************************************************
+ * xaccSplitListGetUniqueTransactions
+ ********************************************************************/
+static void
+add_keys_to_list(gpointer key, gpointer val, gpointer list)
+{
+    *(GList **)list = g_list_prepend(*(GList **)list, key);
+}
+
+GList *
+xaccSplitListGetUniqueTransactions(const GList *splits)
+{
+    const GList *node;
+    GList *transList = NULL;
+    GHashTable *transHash = g_hash_table_new(g_direct_hash, g_direct_equal);
+
+    for(node = splits; node; node = node->next) {
+        Transaction *trans = xaccSplitGetParent((Split *)(node->data));
+        g_hash_table_insert(transHash, trans, trans);
+    }
+    g_hash_table_foreach(transHash, add_keys_to_list, &transList);
+    g_hash_table_destroy(transHash);
+    return transList;
+}
+
+
+/********************************************************************
  * Account funcs
  ********************************************************************/
 
Index: src/gnome/gnc-plugin-page-account-tree.c
===================================================================
--- src/gnome/gnc-plugin-page-account-tree.c	(revision 22178)
+++ src/gnome/gnc-plugin-page-account-tree.c	(working copy)
@@ -38,6 +38,7 @@
 #include <glib/gi18n.h>
 #include "gnc-plugin-page-account-tree.h"
 #include "gnc-plugin-page-register.h"
+#include "gnc-plugin-page-register2.h"
 
 #include "Scrub.h"
 #include "Scrub3.h"
@@ -146,6 +147,8 @@
 static void gnc_plugin_page_account_tree_cmd_scrub_sub (GtkAction *action, GncPluginPageAccountTree *page);
 static void gnc_plugin_page_account_tree_cmd_scrub_all (GtkAction *action, GncPluginPageAccountTree *page);
 
+/* Command callback for new Register Test */
+static void gnc_plugin_page_account_tree_cmd_open2_account (GtkAction *action, GncPluginPageAccountTree *page);
 
 static guint plugin_page_signals[LAST_SIGNAL] = { 0 };
 
@@ -172,6 +175,11 @@
         G_CALLBACK (gnc_plugin_page_account_tree_cmd_open_account)
     },
     {
+        "FileOpenAccount2Action", GNC_STOCK_OPEN_ACCOUNT, N_("Open New Register2 _Account"), NULL,
+        N_("Open the New Register2 selected account"),
+        G_CALLBACK (gnc_plugin_page_account_tree_cmd_open2_account)
+    },
+    {
         "FileOpenSubaccountsAction", GNC_STOCK_OPEN_ACCOUNT, N_("Open _Subaccounts"), NULL,
         N_("Open the selected account and all its subaccounts"),
         G_CALLBACK (gnc_plugin_page_account_tree_cmd_open_subaccounts)
@@ -263,6 +271,7 @@
 static const gchar *actions_requiring_account_always[] =
 {
     "FileOpenAccountAction",
+    "FileOpenAccount2Action",
     "FileOpenSubaccountsAction",
     "ActionsLotsAction",
     NULL
@@ -290,6 +299,7 @@
 static action_toolbar_labels toolbar_labels[] =
 {
     { "FileOpenAccountAction", 	    N_("Open") },
+    { "FileOpenAccount2Action", 	    N_("Open2") },
     { "EditEditAccountAction", 	    N_("Edit") },
     { "FileNewAccountAction",    	    N_("New") },
     { "EditDeleteAccountAction", 	    N_("Delete") },
@@ -782,8 +792,29 @@
     gnc_main_window_open_page (GNC_MAIN_WINDOW(window), new_page);
 }
 
+/*#####################################################################*/
+/*                    New Register Common                              */
 static void
-gnc_plugin_page_account_tree_double_click_cb (GtkTreeView        *treeview,
+gppat_open2_account_common (GncPluginPageAccountTree *page,
+                           Account *account,
+                           gboolean include_subs)
+{
+    GncPluginPageAccountTreePrivate *priv;
+    GtkWidget *window;
+    GncPluginPage *new_page;
+
+    if (account == NULL)
+        return;
+
+    priv = GNC_PLUGIN_PAGE_ACCOUNT_TREE_GET_PRIVATE(page);
+    window = GNC_PLUGIN_PAGE (page)->window;
+    new_page = gnc_plugin_page_register2_new (account, include_subs);
+    gnc_main_window_open_page (GNC_MAIN_WINDOW(window), new_page);
+}
+/*######################################################################*/
+
+static void
+gnc_plugin_page_account_tree_double_click_cb (GtkTreeView *treeview,
         GtkTreePath        *path,
         GtkTreeViewColumn  *col,
         GncPluginPageAccountTree *page)
@@ -869,7 +900,21 @@
     gppat_open_account_common (page, account, FALSE);
 }
 
+/*#####################################################################*/
+/*          Register Firing - Single Account to start with             */
 static void
+gnc_plugin_page_account_tree_cmd_open2_account (GtkAction *action,
+        GncPluginPageAccountTree *page)
+{
+    Account *account;
+
+    g_return_if_fail (GNC_IS_PLUGIN_PAGE_ACCOUNT_TREE (page));
+    account = gnc_plugin_page_account_tree_get_current_account (page);
+    gppat_open2_account_common (page, account, FALSE);
+}
+/*#####################################################################*/
+
+static void
 gnc_plugin_page_account_tree_cmd_open_subaccounts (GtkAction *action,
         GncPluginPageAccountTree *page)
 {
Index: src/gnome/top-level.c
===================================================================
--- src/gnome/top-level.c	(revision 22178)
+++ src/gnome/top-level.c	(working copy)
@@ -51,8 +51,10 @@
 #include "gnc-plugin-basic-commands.h" /* FIXME Remove this line*/
 #include "gnc-plugin-file-history.h" /* FIXME Remove this line*/
 #include "gnc-plugin-register.h" /* FIXME Remove this line*/
+#include "gnc-plugin-register2.h" /* FIXME Remove this line*/
 #include "gnc-plugin-budget.h"
 #include "gnc-plugin-page-register.h"
+#include "gnc-plugin-page-register2.h"
 #include "gnc-plugin-manager.h" /* FIXME Remove this line*/
 #include "gnc-html.h"
 #include "gnc-gnome-utils.h"
@@ -419,6 +421,8 @@
         gnc_plugin_manager_get (), gnc_plugin_menu_additions_new ());
     gnc_plugin_manager_add_plugin (
         gnc_plugin_manager_get (), gnc_plugin_register_new ());
+    gnc_plugin_manager_add_plugin (
+        gnc_plugin_manager_get (), gnc_plugin_register2_new ());
     /* I'm not sure why the FIXME note says to remove this.  Maybe
        each module should be adding its own plugin to the manager?
        Anyway... Oh, maybe... nah */
Index: src/gnome/gnc-plugin-page-register2.c
===================================================================
--- src/gnome/gnc-plugin-page-register2.c	(revision 0)
+++ src/gnome/gnc-plugin-page-register2.c	(revision 0)
@@ -0,0 +1,3842 @@
+/**********************************************************************
+ * gnc-plugin-page-register2.c -- register page functions              *
+ *                                                                    *
+ * Copyright (C) 2003 Jan Arne Petersen <jpetersen@uni-bonn.de>       *
+ * Copyright (C) 2003,2005,2006 David Hampton <hampton@employees.org> *
+ * Copyright (C) 2011, Robert Fewell                                  *
+ *                                                                    *
+ * This program is free software; you can redistribute it and/or      *
+ * modify it under the terms of the GNU General Public License as     *
+ * published by the Free Software Foundation; either version 2 of     *
+ * the License, or (at your option) any later version.                *
+ *                                                                    *
+ * This program is distributed in the hope that it will be useful,    *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of     *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *
+ * GNU General Public License for more details.                       *
+ *                                                                    *
+ * You should have received a copy of the GNU General Public License  *
+ * along with this program; if not, contact:                          *
+ *                                                                    *
+ * Free Software Foundation           Voice:  +1-617-542-5942         *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652         *
+ * Boston, MA  02110-1301,  USA       gnu@gnu.org                     *
+ **********************************************************************/
+
+/** @addtogroup ContentPlugins
+    @{ */
+/** @addtogroup RegisterPlugin Register Page
+    @{ */
+/** @file gnc-plugin-page-register.c
+    @brief  Functions providing a register page for the GnuCash UI
+    @author Copyright (C) 2003 Jan Arne Petersen <jpetersen@uni-bonn.de>
+    @author Copyright (C) 2003,2005 David Hampton <hampton@employees.org>
+*/
+
+#include "config.h"
+
+#include <libguile.h>
+#include "guile-mappings.h"
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include "swig-runtime.h"
+
+#include "gnc-plugin-page-register2.h"
+#include "gnc-plugin-register2.h"
+#include "gnc-plugin-menu-additions.h"
+#include "gnc-plugin-page-report.h"
+
+#include "gnc-tree-view.h"
+#include "gnc-tree-view-split-reg.h"
+#include "gnc-tree-model-split-reg.h"
+
+#include "dialog-account.h"
+#include "dialog-find-transactions.h"
+/*#include "dialog-print-check.h" */
+#include "dialog-transfer.h"
+#include "dialog-utils.h"
+#include "assistant-stock-split.h"
+#include "gnc-gconf-utils.h"
+#include "gnc-component-manager.h"
+#include "gnc-date.h"
+#include "gnc-date-edit.h"
+#include "gnc-engine.h"
+#include "gnc-event.h"
+#include "gnc-gconf-utils.h"
+#include "gnc-gnome-utils.h"
+#include "gnc-gobject-utils.h"
+#include "gnc-gui-query.h"
+#include "gnc-icons.h"
+#include "gnc-split-reg.h"
+#include "gnc-ui-util.h"
+#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"
+#include "window-reconcile.h"
+#include "window-autoclear.h"
+#include "window-report.h"
+
+/* This static indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = GNC_MOD_GUI;
+
+#define DEFAULT_LINES_AMOUNT         50
+#define GCONF_SECTION "window/pages/register2"
+
+static void gnc_plugin_page_register2_class_init (GncPluginPageRegister2Class *klass);
+static void gnc_plugin_page_register2_init (GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_finalize (GObject *object);
+
+/* static Account *gnc_plugin_page_register2_get_current_account (GncPluginPageRegister2 *page); */
+
+static GtkWidget *gnc_plugin_page_register2_create_widget (GncPluginPage *plugin_page);
+static void gnc_plugin_page_register2_destroy_widget (GncPluginPage *plugin_page);
+static void gnc_plugin_page_register2_window_changed (GncPluginPage *plugin_page, GtkWidget *window);
+static void gnc_plugin_page_register2_save_page (GncPluginPage *plugin_page, GKeyFile *file, const gchar *group);
+static GncPluginPage *gnc_plugin_page_register2_recreate_page (GtkWidget *window, GKeyFile *file, const gchar *group);
+static void gnc_plugin_page_register2_update_edit_menu (GncPluginPage *page, gboolean hide);
+static gboolean gnc_plugin_page_register2_finish_pending (GncPluginPage *page);
+
+static gchar *gnc_plugin_page_register2_get_tab_name (GncPluginPage *plugin_page);
+static gchar *gnc_plugin_page_register2_get_tab_color (GncPluginPage *plugin_page);
+static gchar *gnc_plugin_page_register2_get_long_name (GncPluginPage *plugin_page);
+
+static void gnc_plugin_page_register2_summarybar_position_changed(GConfEntry *entry, gpointer user_data);
+
+/* Callbacks for the "Sort By" dialog */
+void gnc_plugin_page_register2_sort_button_cb(GtkToggleButton *button, GncPluginPageRegister2 *page);
+void gnc_plugin_page_register2_sort_response_cb(GtkDialog *dialog, gint response, GncPluginPageRegister2 *plugin_page);
+void gnc_plugin_page_register2_sort_order_save_cb(GtkToggleButton *button, GncPluginPageRegister2 *page);
+
+static gchar *gnc_plugin_page_register2_get_sort_order (GncPluginPage *plugin_page);
+void gnc_plugin_page_register2_set_sort_order (GncPluginPage *plugin_page, const gchar *sort_order);
+
+/* Callbacks for the "Filter By" dialog */
+void gnc_plugin_page_register2_filter_select_range_cb(GtkRadioButton *button, GncPluginPageRegister2 *page);
+void gnc_plugin_page_register2_filter_start_cb(GtkWidget *radio, GncPluginPageRegister2 *page);
+void gnc_plugin_page_register2_filter_end_cb(GtkWidget *radio, GncPluginPageRegister2 *page);
+void gnc_plugin_page_register2_filter_response_cb(GtkDialog *dialog, gint response, GncPluginPageRegister2 *plugin_page);
+void gnc_plugin_page_register2_filter_status_all_cb(GtkButton *button, GncPluginPageRegister2 *plugin_page);
+void gnc_plugin_page_register2_filter_status_one_cb(GtkToggleButton *button, GncPluginPageRegister2 *page);
+void gnc_plugin_page_register2_filter_save_cb(GtkToggleButton *button, GncPluginPageRegister2 *page);
+
+static time_t gnc_plugin_page_register2_filter_dmy2time (char *date_string);
+static gchar *gnc_plugin_page_register2_filter_time2dmy (time_t raw_time);
+static gchar *gnc_plugin_page_register2_get_filter (GncPluginPage *plugin_page);
+void gnc_plugin_page_register2_set_filter (GncPluginPage *plugin_page, const gchar *filter);
+
+static void gnc_ppr_update_status_query (GncPluginPageRegister2 *page);
+static void gnc_ppr_update_date_query (GncPluginPageRegister2 *page);
+
+/* Command callbacks */
+static void gnc_plugin_page_register2_cmd_print_check (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_cut (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_copy (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_paste (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_edit_account (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_find_transactions (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_cut_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_copy_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_paste_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_void_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_unvoid_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_reverse_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_shift_transaction_forward (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_view_sort_by (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_view_filter_by (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_style_changed (GtkAction *action, GtkRadioAction *current, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_style_double_line (GtkToggleAction *action, GncPluginPageRegister2 *plugin_page);
+
+static void gnc_plugin_page_register2_cmd_reconcile (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_autoclear (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_transfer (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_stock_split (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_lots (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_enter_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_cancel_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_delete_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_blank_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_duplicate_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_reinitialize_transaction (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_expand_transaction (GtkToggleAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_exchange_rate (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_jump (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_schedule (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_scrub_all (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_scrub_current (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_account_report (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+static void gnc_plugin_page_register2_cmd_transaction_report (GtkAction *action, GncPluginPageRegister2 *plugin_page);
+
+static void gnc_plugin_page_help_changed_cb( GNCSplitReg *gsr, GncPluginPageRegister2 *register_page );
+static void gnc_plugin_page_register2_refresh_cb (GHashTable *changes, gpointer user_data);
+static void gnc_plugin_page_register2_close_cb (gpointer user_data);
+
+static void gnc_plugin_page_register2_ui_update (gpointer various, GncPluginPageRegister2 *page);
+static void gppr_account_destroy_cb (Account *account);
+static void gnc_plugin_page_register2_event_handler (QofInstance *entity,
+        QofEventId event_type,
+        GncPluginPageRegister2 *page,
+        GncEventData *ed);
+
+/************************************************************/
+/*                          Actions                         */
+/************************************************************/
+
+static GtkActionEntry gnc_plugin_page_register2_actions [] =
+{
+    /* File menu */
+
+    {
+        "FilePrintAction", GTK_STOCK_PRINT, N_("_Print Checks..."), "<control>p", NULL,
+        G_CALLBACK (gnc_plugin_page_register2_cmd_print_check)
+    },
+
+    /* Edit menu */
+
+    {
+        "EditCutAction", GTK_STOCK_CUT, N_("Cu_t"), NULL,
+        N_("Cut the current selection and copy it to clipboard"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_cut)
+    },
+    {
+        "EditCopyAction", GTK_STOCK_COPY, N_("_Copy"), NULL,
+        N_("Copy the current selection to clipboard"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_copy)
+    },
+    {
+        "EditPasteAction", GTK_STOCK_PASTE, N_("_Paste"), NULL,
+        N_("Paste the clipboard content at the cursor position"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_paste)
+    },
+    {
+        "EditEditAccountAction", GNC_STOCK_EDIT_ACCOUNT, N_("Edit _Account"), "<control>e",
+        N_("Edit the selected account"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_edit_account)
+    },
+    {
+        "EditFindTransactionsAction", GTK_STOCK_FIND, N_("_Find..."), "<control>f",
+        N_("Find transactions with a search"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_find_transactions)
+    },
+
+    /* Transaction menu */
+
+    {
+        "CutTransactionAction", GTK_STOCK_CUT, N_("Cu_t Transaction"), "",
+        N_("Cut the selected transaction into clipboard"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_cut_transaction)
+    },
+    {
+        "CopyTransactionAction", GTK_STOCK_COPY, N_("_Copy Transaction"), "",
+        N_("Copy the selected transaction into clipboard"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_copy_transaction)
+    },
+    {
+        "PasteTransactionAction", GTK_STOCK_PASTE, N_("_Paste Transaction"), "",
+        N_("Paste the transaction from the clipboard"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_paste_transaction)
+    },
+    {
+        "DuplicateTransactionAction", GTK_STOCK_COPY, N_("Dup_licate Transaction"), "",
+        N_("Make a copy of the current transaction"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_duplicate_transaction)
+    },
+    {
+        "DeleteTransactionAction", GTK_STOCK_DELETE, N_("_Delete Transaction"), NULL,
+        N_("Delete the current transaction"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_delete_transaction)
+    },
+    {
+        "RemoveTransactionSplitsAction", GTK_STOCK_CLEAR, N_("Remo_ve Transaction Splits"), NULL,
+        N_("Remove all splits in the current transaction"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_reinitialize_transaction)
+    },
+    {
+        "RecordTransactionAction", GTK_STOCK_ADD, N_("_Enter Transaction"), NULL,
+        N_("Record the current transaction"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_enter_transaction)
+    },
+    {
+        "CancelTransactionAction", GTK_STOCK_CANCEL, N_("Ca_ncel Transaction"), NULL,
+        N_("Cancel the current transaction"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_cancel_transaction)
+    },
+    {
+        "VoidTransactionAction", NULL, N_("_Void Transaction"), NULL, NULL,
+        G_CALLBACK (gnc_plugin_page_register2_cmd_void_transaction)
+    },
+    {
+        "UnvoidTransactionAction", NULL, N_("_Unvoid Transaction"), NULL, NULL,
+        G_CALLBACK (gnc_plugin_page_register2_cmd_unvoid_transaction)
+    },
+    {
+        "ReverseTransactionAction", NULL, N_("Add _Reversing Transaction"), NULL, NULL,
+        G_CALLBACK (gnc_plugin_page_register2_cmd_reverse_transaction)
+    },
+    {
+        "ShiftTransactionForwardAction", NULL, N_("_Shift Transaction Forward"), NULL, NULL,
+        G_CALLBACK (gnc_plugin_page_register2_cmd_shift_transaction_forward)
+    },
+
+    /* View menu */
+
+    {
+        "ViewSortByAction", NULL, N_("_Sort By..."), NULL, NULL,
+        G_CALLBACK (gnc_plugin_page_register2_cmd_view_sort_by)
+    },
+    {
+        "ViewFilterByAction", NULL, N_("_Filter By..."), NULL, NULL,
+        G_CALLBACK (gnc_plugin_page_register2_cmd_view_filter_by)
+    },
+
+    /* Actions menu */
+
+    {
+        "ActionsTransferAction", GNC_STOCK_TRANSFER, N_("_Transfer..."), "<control>t",
+        N_("Transfer funds from one account to another"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_transfer)
+    },
+    {
+        "ActionsReconcileAction", GTK_STOCK_INDEX, N_("_Reconcile..."), NULL,
+        N_("Reconcile the selected account"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_reconcile)
+    },
+    {
+        "ActionsAutoClearAction", GTK_STOCK_INDEX, N_("_Auto-clear..."), NULL,
+        N_("Automatically clear individual transactions, so as to reach a certain cleared amount"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_autoclear)
+    },
+    {
+        "ActionsStockSplitAction", NULL, N_("Stoc_k Split..."), NULL,
+        N_("Record a stock split or a stock merger"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_stock_split)
+    },
+    {
+        "ActionsLotsAction", NULL, N_("View _Lots..."), NULL,
+        N_("Bring up the lot viewer/editor window"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_lots)
+    },
+    {
+        "BlankTransactionAction", GTK_STOCK_GOTO_BOTTOM, N_("_Blank Transaction"), "<control>Page_Down",
+        N_("Move to the blank transaction at the bottom of the register"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_blank_transaction)
+    },
+    {
+        "EditExchangeRateAction", NULL, N_("Edit E_xchange Rate"), NULL,
+        N_("Edit the exchange rate for the current transaction"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_exchange_rate)
+    },
+    {
+        "JumpTransactionAction", GNC_STOCK_JUMP_TO, N_("_Jump"), NULL,
+        N_("Jump to the corresponding transaction in the other account"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_jump)
+    },
+    {
+        "ScheduleTransactionAction", GNC_STOCK_SCHEDULE, N_("Sche_dule..."), NULL,
+        N_("Create a Scheduled Transaction with the current transaction as a template"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_schedule)
+    },
+    {
+        "ScrubAllAction", NULL, N_("_All transactions"), NULL, NULL,
+        G_CALLBACK (gnc_plugin_page_register2_cmd_scrub_all)
+    },
+    {
+        "ScrubCurrentAction", NULL, N_("_This transaction"), NULL, NULL,
+        G_CALLBACK (gnc_plugin_page_register2_cmd_scrub_current)
+    },
+
+    /* Reports menu */
+
+    {
+        "ReportsAccountReportAction", NULL, N_("Account Report"), NULL,
+        N_("Open a register report for this Account"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_account_report)
+    },
+    {
+        "ReportsAcctTransReportAction", NULL, N_("Account Transaction Report"), NULL,
+        N_("Open a register report for the selected Transaction"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_transaction_report)
+    },
+};
+
+static guint gnc_plugin_page_register2_n_actions = G_N_ELEMENTS (gnc_plugin_page_register2_actions);
+
+static GtkToggleActionEntry toggle_entries[] =
+{
+    {
+        "ViewStyleDoubleLineAction", NULL, N_("_Double Line"), NULL,
+        N_("Show two lines of information for each transaction"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_style_double_line), FALSE
+    },
+
+    {
+        "SplitTransactionAction", GNC_STOCK_SPLIT_TRANS, N_("S_plit Transaction"), NULL,
+        N_("Show all splits in the current transaction"),
+        G_CALLBACK (gnc_plugin_page_register2_cmd_expand_transaction), FALSE
+    },
+};
+
+static guint n_toggle_entries = G_N_ELEMENTS (toggle_entries);
+
+static GtkRadioActionEntry radio_entries_2 [] =
+{
+    /* Translators: This is a menu item in the View menu */
+    {
+        "ViewStyleBasicAction", NULL, N_("_Basic Ledger"), NULL,
+        N_("Show transactions on one or two lines"), REG_STYLE_LEDGER
+    },
+    /* Translators: This is a menu item in the View menu */
+    {
+        "ViewStyleAutoSplitAction", NULL, N_("_Auto-Split Ledger"), NULL,
+        N_("Show transactions on one or two lines and expand the current transaction"), REG_STYLE_AUTO_LEDGER
+    },
+    /* Translators: This is a menu item in the View menu */
+    {
+        "ViewStyleJournalAction", NULL, N_("Transaction _Journal"), NULL,
+        N_("Show expanded transactions with all splits"), REG_STYLE_JOURNAL
+    }
+};
+
+static guint n_radio_entries_2 = G_N_ELEMENTS (radio_entries_2);
+
+/** These are the "important" actions provided by the register page.
+ *  Their labels will appear when the toolbar is set to "Icons and
+ *  important text" (e.g. GTK_TOOLBAR_BOTH_HORIZ) mode. */
+static const gchar *important_actions[] =
+{
+    "SplitTransactionAction",
+    NULL,
+};
+
+/** Actions that require an account to be selected before they are
+ *  enabled. */
+static const gchar *actions_requiring_account[] =
+{
+    "EditEditAccountAction",
+    "ActionsReconcileAction",
+    "ActionsAutoClearAction",
+    "ActionsLotsAction",
+    NULL
+};
+
+/** View Style actions */
+static const gchar *view_style_actions[] =
+{
+    "ViewStyleBasicAction",
+    "ViewStyleAutoSplitAction",
+    "ViewStyleJournalAction",
+    NULL
+};
+
+/** Short labels for use on the toolbar buttons. */
+static action_toolbar_labels toolbar_labels[] =
+{
+    { "ActionsTransferAction", 	  N_("Transfer") },
+    { "RecordTransactionAction", 	  N_("Enter") },
+    { "CancelTransactionAction", 	  N_("Cancel") },
+    { "DeleteTransactionAction", 	  N_("Delete") },
+    { "DuplicateTransactionAction", N_("Duplicate") },
+    { "SplitTransactionAction",     N_("Split") },
+    { "ScheduleTransactionAction",  N_("Schedule") },
+    { "BlankTransactionAction",     N_("Blank") },
+    { "ActionsReconcileAction",     N_("Reconcile") },
+    { "ActionsAutoClearAction",     N_("Auto-clear") },
+    { NULL, NULL },
+};
+
+struct status_action
+{
+    const char *action_name;
+    int value;
+    GtkWidget *widget;
+};
+
+static struct status_action status_actions[] =
+{
+    { "filter_status_reconciled",   CLEARED_RECONCILED, NULL },
+    { "filter_status_cleared",      CLEARED_CLEARED, NULL },
+    { "filter_status_voided",       CLEARED_VOIDED, NULL },
+    { "filter_status_frozen",       CLEARED_FROZEN, NULL },
+    { "filter_status_unreconciled", CLEARED_NO, NULL },
+    { NULL, 0, NULL },
+};
+
+#define CLEARED_VALUE "cleared_value"
+#define DEFAULT_FILTER "0x001f"
+#define DEFAULT_SORT_ORDER "BY_STANDARD"
+
+/************************************************************/
+/*                      Data Structures                     */
+/************************************************************/
+
+typedef struct GncPluginPageRegister2Private
+{
+    GNCLedgerDisplay *ledger;
+    GNCSplitReg *gsr;
+
+    GtkWidget *widget;
+
+
+    GncTreeViewSplitReg *tv;
+
+    gint event_handler_id;
+    gint component_manager_id;
+    GncGUID key;  /* The guid of the Account we're watching */
+
+    gint lines_default;
+    gboolean read_only;
+
+    struct
+    {
+        GtkWidget *dialog;
+        SortType original_sort_type;
+        gboolean original_save_order;
+        gboolean save_order;
+    } sd;
+
+    struct
+    {
+        GtkWidget *dialog;
+        GtkWidget *table;
+        GtkWidget *start_date_choose;
+        GtkWidget *start_date_today;
+        GtkWidget *start_date;
+        GtkWidget *end_date_choose;
+        GtkWidget *end_date_today;
+        GtkWidget *end_date;
+        cleared_match_t original_cleared_match;
+        cleared_match_t cleared_match;
+        time_t original_start_time;
+        time_t original_end_time;
+        time_t start_time;
+        time_t end_time;
+        gboolean original_save_filter;
+        gboolean save_filter;
+    } fd;
+} GncPluginPageRegister2Private;
+
+#define GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(o)  \
+   (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_PLUGIN_PAGE_REGISTER2, GncPluginPageRegister2Private))
+
+static GObjectClass *parent_class = NULL;
+
+/************************************************************/
+/*                      Implementation                      */
+/************************************************************/
+
+GType
+gnc_plugin_page_register2_get_type (void)
+{
+    static GType gnc_plugin_page_register2_type = 0;
+
+    if (gnc_plugin_page_register2_type == 0)
+    {
+        static const GTypeInfo our_info =
+        {
+            sizeof (GncPluginPageRegister2Class),
+            NULL,
+            NULL,
+            (GClassInitFunc) gnc_plugin_page_register2_class_init,
+            NULL,
+            NULL,
+            sizeof (GncPluginPageRegister2),
+            0,
+            (GInstanceInitFunc) gnc_plugin_page_register2_init
+        };
+
+        gnc_plugin_page_register2_type = g_type_register_static (GNC_TYPE_PLUGIN_PAGE,
+                                        GNC_PLUGIN_PAGE_REGISTER2_NAME,
+                                        &our_info, 0);
+    }
+
+    return gnc_plugin_page_register2_type;
+}
+
+/*#################################################################################*/
+/*#################################################################################*/
+static GncPluginPage *
+gnc_plugin_page_register2_new_common (GNCLedgerDisplay *ledger)
+{
+    GncPluginPageRegister2 *register_page;
+    GncPluginPageRegister2Private *priv;
+    GncPluginPage *plugin_page;
+
+    GncTreeModelSplitReg *model; 
+    GtkTreeView *tv; 
+
+    GNCSplitReg *gsr;
+    SplitRegister *reg;
+    const GList *item;
+    GList *book_list;
+    gchar *label;
+    gchar *label_color;
+    QofQuery *q;
+    Account *account;
+
+g_print("Register New Common\n");
+
+    /* Is there an existing page? */
+    gsr = gnc_ledger_display_get_user_data (ledger);
+    if (gsr)
+    {
+        item = gnc_gobject_tracking_get_list(GNC_PLUGIN_PAGE_REGISTER2_NAME);
+        for ( ; item; item = g_list_next(item))
+        {
+            register_page = (GncPluginPageRegister2 *)item->data;
+            priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(register_page);
+            if (priv->gsr == gsr)
+                return GNC_PLUGIN_PAGE(register_page);
+        }
+    }
+
+
+    register_page = g_object_new (GNC_TYPE_PLUGIN_PAGE_REGISTER2, NULL);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(register_page);
+    priv->ledger = ledger;
+    priv->key = *guid_null();
+
+    plugin_page = GNC_PLUGIN_PAGE(register_page);
+    label = gnc_plugin_page_register2_get_tab_name(plugin_page);
+    gnc_plugin_page_set_page_name(plugin_page, label);
+    g_free(label);
+
+    label_color = gnc_plugin_page_register2_get_tab_color(plugin_page);
+    gnc_plugin_page_set_page_color(plugin_page, label_color);
+    g_free(label_color);
+
+    label = gnc_plugin_page_register2_get_long_name(plugin_page);
+    gnc_plugin_page_set_page_long_name(plugin_page, label);
+    g_free(label);
+
+/*FIXME New Stuff here */
+
+    q = gnc_ledger_display_get_query (ledger);
+    book_list = qof_query_get_books (q);
+    for (item = book_list; item; item = g_list_next(item))
+        gnc_plugin_page_add_book (plugin_page, (QofBook *)item->data);
+    // Do not free the list. It is owned by the query.
+
+
+/*
+    reg = gnc_ledger_display_get_split_register(priv->ledger);
+*/
+
+    account = gnc_plugin_page_register2_get_account (register_page);
+
+    model = gnc_tree_model_split_reg_new_from_account(account);
+    priv->tv = gnc_tree_view_split_reg_new_with_model(model);
+
+
+
+/*    g_object_unref(G_OBJECT(model)); */
+
+
+
+
+
+
+    priv->component_manager_id = 0;
+    return plugin_page;
+}
+/*#################################################################################*/
+
+
+
+GncPluginPage *
+gnc_plugin_page_register2_new (Account *account, gboolean subaccounts)
+{
+    GNCLedgerDisplay *ledger;
+    GncPluginPage *page;
+    GncPluginPageRegister2Private *priv;
+
+    ENTER("account=%p, subaccounts=%s", account,
+          subaccounts ? "TRUE" : "FALSE");
+
+    if (subaccounts)
+        ledger = gnc_ledger_display_subaccounts (account);
+    else
+        ledger = gnc_ledger_display_simple (account);
+
+    page = gnc_plugin_page_register2_new_common(ledger);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    priv->key = *xaccAccountGetGUID(account);
+
+    LEAVE("%p", page);
+    return page;
+}
+
+GncPluginPage *
+gnc_plugin_page_register2_new_gl (void)
+{
+    GNCLedgerDisplay *ledger;
+
+    ledger = gnc_ledger_display_gl ();
+    return gnc_plugin_page_register2_new_common(ledger);
+}
+
+GncPluginPage *
+gnc_plugin_page_register2_new_ledger (GNCLedgerDisplay *ledger)
+{
+    return gnc_plugin_page_register2_new_common(ledger);
+}
+
+static void
+gnc_plugin_page_register2_class_init (GncPluginPageRegister2Class *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+    GncPluginPageClass *gnc_plugin_class = GNC_PLUGIN_PAGE_CLASS(klass);
+
+    parent_class = g_type_class_peek_parent (klass);
+
+    object_class->finalize = gnc_plugin_page_register2_finalize;
+
+    gnc_plugin_class->tab_icon        = GNC_STOCK_ACCOUNT;
+    gnc_plugin_class->plugin_name     = GNC_PLUGIN_PAGE_REGISTER2_NAME;
+    gnc_plugin_class->create_widget   = gnc_plugin_page_register2_create_widget;
+    gnc_plugin_class->destroy_widget  = gnc_plugin_page_register2_destroy_widget;
+    gnc_plugin_class->window_changed  = gnc_plugin_page_register2_window_changed;
+    gnc_plugin_class->save_page       = gnc_plugin_page_register2_save_page;
+    gnc_plugin_class->recreate_page   = gnc_plugin_page_register2_recreate_page;
+    gnc_plugin_class->update_edit_menu_actions = gnc_plugin_page_register2_update_edit_menu;
+    gnc_plugin_class->finish_pending  = gnc_plugin_page_register2_finish_pending;
+
+    g_type_class_add_private(klass, sizeof(GncPluginPageRegister2Private));
+
+    gnc_ui_register_account_destroy_callback (gppr_account_destroy_cb);
+}
+
+static void
+gnc_plugin_page_register2_init (GncPluginPageRegister2 *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+    GncPluginPage *parent;
+    GtkActionGroup *action_group;
+    gboolean use_new;
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+
+    /* Init parent declared variables */
+    parent = GNC_PLUGIN_PAGE(plugin_page);
+    use_new = gnc_gconf_get_bool(GCONF_GENERAL_REGISTER, KEY_USE_NEW, NULL);
+    g_object_set(G_OBJECT(plugin_page),
+                 "page-name",      _("General Ledger"),
+                 "page-uri",       "default:",
+                 "ui-description", "gnc-plugin-page-register2-ui.xml",
+                 "use-new-window", use_new,
+                 NULL);
+
+    /* Create menu and toolbar information */
+    action_group =
+        gnc_plugin_page_create_action_group(parent,
+                                            "GncPluginPageRegister2Actions");
+    gtk_action_group_add_actions (action_group, gnc_plugin_page_register2_actions,
+                                  gnc_plugin_page_register2_n_actions, plugin_page);
+    gtk_action_group_add_toggle_actions (action_group,
+                                         toggle_entries, n_toggle_entries,
+                                         plugin_page);
+    gtk_action_group_add_radio_actions (action_group,
+                                        radio_entries_2, n_radio_entries_2,
+                                        REG_STYLE_LEDGER,
+                                        G_CALLBACK(gnc_plugin_page_register2_cmd_style_changed),
+                                        plugin_page);
+
+    gnc_plugin_init_short_names (action_group, toolbar_labels);
+    gnc_plugin_set_important_actions (action_group, important_actions);
+
+    priv->lines_default     = DEFAULT_LINES_AMOUNT;
+    priv->read_only         = FALSE;
+    priv->fd.cleared_match  = CLEARED_ALL;
+}
+
+static void
+gnc_plugin_page_register2_finalize (GObject *object)
+{
+    GncPluginPageRegister2 *page;
+    GncPluginPageRegister2Private *priv;
+
+    g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (object));
+
+    ENTER("object %p", object);
+    page = GNC_PLUGIN_PAGE_REGISTER2 (object);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE (page);
+
+    G_OBJECT_CLASS (parent_class)->finalize (object);
+    LEAVE(" ");
+}
+
+Account *
+gnc_plugin_page_register2_get_account (GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    GNCLedgerDisplayType ledger_type;
+    Account *leader;
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    ledger_type = gnc_ledger_display_type (priv->ledger);
+    leader = gnc_ledger_display_leader (priv->ledger);
+
+    if ((ledger_type == LD_SINGLE) || (ledger_type == LD_SUBACCOUNT))
+        return leader;
+    return NULL;
+}
+
+/* This is the list of actions which are switched inactive in a read-only book. */
+static const char* readonly_inactive_actions[] =
+{
+    "EditCutAction",
+    "EditPasteAction",
+    "CutTransactionAction",
+    "PasteTransactionAction",
+    "DuplicateTransactionAction",
+    "DeleteTransactionAction",
+    "RemoveTransactionSplitsAction",
+    "RecordTransactionAction",
+    "CancelTransactionAction",
+    "UnvoidTransactionAction",
+    "VoidTransactionAction",
+    "ReverseTransactionAction",
+    "ShiftTransactionForwardAction",
+    "ActionsTransferAction",
+    "ActionsReconcileAction",
+    "ActionsStockSplitAction",
+    "ScheduleTransactionAction",
+    "ScrubAllAction",
+    "ScrubCurrentAction",
+    NULL
+};
+
+static void
+gnc_plugin_page_register2_ui_update (gpointer various, GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    SplitRegister *reg;
+    GtkAction *action;
+    gboolean expanded, voided;
+    Transaction *trans;
+
+    /* Set 'Split Transaction' */
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    reg = gnc_ledger_display_get_split_register(priv->ledger);
+    expanded = gnc_split_register_current_trans_expanded(reg);
+    action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page),
+                                         "SplitTransactionAction");
+    gtk_action_set_sensitive (action, reg->style == REG_STYLE_LEDGER);
+    g_signal_handlers_block_by_func
+    (action, gnc_plugin_page_register2_cmd_expand_transaction, page);
+    gtk_toggle_action_set_active (GTK_TOGGLE_ACTION(action), expanded);
+    g_signal_handlers_unblock_by_func
+    (action, gnc_plugin_page_register2_cmd_expand_transaction, page);
+
+    /* Set 'Void' and 'Unvoid' */
+    trans = gnc_split_register_get_current_trans(reg);
+    voided = xaccTransHasSplitsInState(trans, VREC);
+    action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page),
+                                         "VoidTransactionAction");
+    gtk_action_set_sensitive (GTK_ACTION(action), !voided);
+
+    action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page),
+                                         "UnvoidTransactionAction");
+    gtk_action_set_sensitive (GTK_ACTION(action), voided);
+
+    /* If we are in a readonly book, make any modifying action inactive */
+    if (qof_book_is_readonly(gnc_get_current_book()))
+    {
+        const char **iter;
+        for (iter = readonly_inactive_actions; *iter; ++iter)
+        {
+            /* Set the action's sensitivity */
+            GtkAction *action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page), *iter);
+            gtk_action_set_sensitive(action, FALSE);
+        }
+
+    }
+}
+
+static void
+gnc_plugin_page_register2_ui_initial_state (GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv ;
+    GtkActionGroup *action_group;
+    GtkAction *action;
+    Account *account;
+    SplitRegister *reg;
+    GNCLedgerDisplayType ledger_type;
+    int i;
+    gboolean is_readwrite = !qof_book_is_readonly(gnc_get_current_book());
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    account = gnc_plugin_page_register2_get_account (page);
+    action_group = gnc_plugin_page_get_action_group(GNC_PLUGIN_PAGE(page));
+    gnc_plugin_update_actions(action_group, actions_requiring_account,
+                              "sensitive", is_readwrite && account != NULL);
+
+    /* Set "style" radio button */
+    ledger_type = gnc_ledger_display_type(priv->ledger);
+    gnc_plugin_update_actions(action_group, view_style_actions,
+                              "sensitive", ledger_type == LD_SINGLE);
+
+    reg = gnc_ledger_display_get_split_register(priv->ledger);
+    for (i = n_radio_entries_2 - 1; i > 0; i--)
+    {
+        DEBUG(" index %d: comparing %x to %x", i, radio_entries_2[i].value,
+              reg->style);
+        if (radio_entries_2[i].value == reg->style)
+        {
+            DEBUG("match");
+            break;
+        }
+    }
+
+    /* Either a match was found, or fell out with i = 0 */
+    action = gtk_action_group_get_action(action_group, radio_entries_2[i].name);
+    g_signal_handlers_block_by_func(action, gnc_plugin_page_register2_cmd_style_changed, page);
+    gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), TRUE);
+    g_signal_handlers_unblock_by_func(action, gnc_plugin_page_register2_cmd_style_changed, page);
+
+    /* Set "double line" toggle button */
+    action = gtk_action_group_get_action (action_group,
+                                          "ViewStyleDoubleLineAction");
+    g_signal_handlers_block_by_func(action, gnc_plugin_page_register2_cmd_style_double_line, page);
+    gtk_toggle_action_set_active (GTK_TOGGLE_ACTION(action), reg->use_double_line);
+    g_signal_handlers_unblock_by_func(action, gnc_plugin_page_register2_cmd_style_double_line, page);
+}
+
+
+/*#################################################################################*/
+/*#################################################################################*/
+/* Virtual Functions */
+
+static GtkWidget *
+gnc_plugin_page_register2_create_widget (GncPluginPage *plugin_page)
+{
+    GncPluginPageRegister2 *page;
+    GncPluginPageRegister2Private *priv;
+    GNCLedgerDisplayType ledger_type;
+    GncWindow *gnc_window;
+    guint numRows;
+    GtkWidget *gsr;
+
+    GncTreeViewSplitReg *tree_view;
+    GtkWidget *scrolled_window;
+
+    SplitRegister *reg;
+    Account *acct;
+    gchar **filter;
+    gchar *order;
+    int filter_changed = 0;
+
+g_print("Register New Create\n");
+
+    ENTER("page %p", plugin_page);
+    page = GNC_PLUGIN_PAGE_REGISTER2 (plugin_page);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    if (priv->widget != NULL)
+    {
+        LEAVE("existing widget %p", priv->widget);
+        return priv->widget;
+    }
+
+    priv->widget = gtk_vbox_new (FALSE, 0);
+    gtk_widget_show (priv->widget);
+
+    numRows = priv->lines_default;
+    numRows = MIN(numRows, DEFAULT_LINES_AMOUNT);
+
+    gnc_window = GNC_WINDOW(GNC_PLUGIN_PAGE(page)->window);
+/*FIXME Create widget */
+
+    scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled_window),
+                                   GTK_POLICY_AUTOMATIC,
+                                   GTK_POLICY_AUTOMATIC);
+    gtk_widget_show(scrolled_window);
+    gtk_box_pack_start(GTK_BOX (priv->widget), scrolled_window, TRUE, TRUE, 0);
+
+    tree_view = priv->tv;
+    g_object_set(G_OBJECT(tree_view), "gconf-section", GCONF_SECTION, 
+                 "show-column-menu", TRUE, NULL);
+
+    gnc_tree_view_configure_columns(GNC_TREE_VIEW(tree_view));
+
+    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree_view), TRUE);
+    gtk_widget_show(GTK_WIDGET (tree_view));
+    gtk_container_add(GTK_CONTAINER(scrolled_window),
+                      GTK_WIDGET(tree_view));
+    gtk_widget_show(priv->widget);
+
+#ifdef SKIP
+
+    gsr = gnc_split_reg_new(priv->ledger,
+                            gnc_window_get_gtk_window(gnc_window),
+                            numRows, priv->read_only);
+    priv->gsr = (GNCSplitReg *)gsr;
+/*    gtk_widget_show (gsr); */
+/*    gtk_box_pack_start (GTK_BOX (priv->widget), gsr, TRUE, TRUE, 0); */
+
+    g_signal_connect (G_OBJECT (gsr), "help-changed",
+                      G_CALLBACK ( gnc_plugin_page_help_changed_cb ),
+                      page );
+
+    reg = gnc_ledger_display_get_split_register(priv->ledger);
+
+    gnc_split_register_config(reg, reg->type, reg->style,
+                              reg->use_double_line);
+    gnc_ledger_display_refresh(priv->ledger);
+
+#endif
+
+    gnc_plugin_page_register2_ui_initial_state (page);
+    gnc_plugin_page_register2_ui_update (NULL, page);
+
+#ifdef SKIP
+
+    ledger_type = gnc_ledger_display_type (priv->ledger);
+
+
+    if (ledger_type == LD_SINGLE || ledger_type == LD_SUBACCOUNT)
+    {
+        /* Set the sort order for the split register and status of save order button */
+        priv->sd.save_order = FALSE;
+        order = gnc_plugin_page_register2_get_sort_order(plugin_page);
+
+        PINFO("Loaded Sort order is %s", order);
+
+        gnc_split_reg_set_sort_type(priv->gsr, SortTypefromString(order));
+
+        if (order && (g_strcmp0 (order, DEFAULT_SORT_ORDER) != 0))
+            priv->sd.save_order = TRUE;
+
+        priv->sd.original_save_order = priv->sd.save_order;
+        g_free(order);
+
+        /* Set the filter for the split register and status of save filter button */
+        priv->fd.save_filter = FALSE;
+
+        filter = g_strsplit(gnc_plugin_page_register2_get_filter(plugin_page), ",", -1);
+
+        PINFO("Loaded Filter Status is %s", filter[0]);
+
+        priv->fd.cleared_match = (gint)g_ascii_strtoll( filter[0], NULL, 16 );
+
+        if (filter[0] && (g_strcmp0 (filter[0], DEFAULT_FILTER) != 0))
+            filter_changed = filter_changed + 1;
+
+        if (filter[1] && (g_strcmp0 (filter[1], "0") != 0 ))
+        {
+            PINFO("Loaded Filter Start Date is %s", filter[1]);
+
+            priv->fd.start_time = gnc_plugin_page_register2_filter_dmy2time( filter[1] );
+            priv->fd.start_time = gnc_timet_get_day_start(priv->fd.start_time);
+            filter_changed = filter_changed + 1;
+
+            if (filter[2] && (g_strcmp0 (filter[2], "0") != 0 ))
+            {
+                PINFO("Loaded Filter End Date is %s", filter[2]);
+
+                priv->fd.end_time = gnc_plugin_page_register2_filter_dmy2time( filter[2] );
+                priv->fd.end_time = gnc_timet_get_day_end(priv->fd.end_time);
+                filter_changed = filter_changed + 1;
+            }
+        }
+
+        if (filter_changed != 0)
+            priv->fd.save_filter = TRUE;
+
+        priv->fd.original_save_filter = priv->fd.save_filter;
+        g_strfreev(filter);
+
+        /* Update Query with Filter Status and Dates */
+        gnc_ppr_update_status_query (page);
+        gnc_ppr_update_date_query(page);
+    }
+#endif
+
+#ifdef SKIP
+    plugin_page->summarybar = gsr_create_summary_bar(priv->gsr);
+    if (plugin_page->summarybar)
+    {
+        gtk_widget_show_all(plugin_page->summarybar);
+        gtk_box_pack_start(GTK_BOX (priv->widget), plugin_page->summarybar,
+                           FALSE, FALSE, 0);
+        gnc_plugin_page_register2_summarybar_position_changed(NULL, page);
+        gnc_gconf_general_register_cb(KEY_SUMMARYBAR_POSITION,
+                                      gnc_plugin_page_register2_summarybar_position_changed, page);
+    }
+#endif
+
+    priv->event_handler_id = qof_event_register_handler
+                             ((QofEventHandler)gnc_plugin_page_register2_event_handler, page);
+    priv->component_manager_id =
+        gnc_register_gui_component(GNC_PLUGIN_PAGE_REGISTER2_NAME,
+                                   gnc_plugin_page_register2_refresh_cb,
+                                   gnc_plugin_page_register2_close_cb,
+                                   page);
+    gnc_gui_component_set_session (priv->component_manager_id,
+                                   gnc_get_current_session());
+    acct = gnc_plugin_page_register2_get_account(page);
+    if (acct)
+        gnc_gui_component_watch_entity (
+            priv->component_manager_id, xaccAccountGetGUID(acct),
+            QOF_EVENT_DESTROY | QOF_EVENT_MODIFY);
+/*
+    gnc_split_reg_set_moved_cb
+    (priv->gsr, (GFunc)gnc_plugin_page_register2_ui_update, page);
+*/
+    /* DRH - Probably lots of other stuff from regWindowLedger should end up here. */
+    LEAVE(" ");
+    return priv->widget;
+}
+/*#################################################################################*/
+
+
+
+
+
+static void
+gnc_plugin_page_register2_destroy_widget (GncPluginPage *plugin_page)
+{
+    GncPluginPageRegister2 *page;
+    GncPluginPageRegister2Private *priv;
+
+    ENTER("page %p", plugin_page);
+    page = GNC_PLUGIN_PAGE_REGISTER2 (plugin_page);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+
+    gnc_gconf_general_remove_cb(KEY_SUMMARYBAR_POSITION,
+                                gnc_plugin_page_register2_summarybar_position_changed, page);
+
+    if (priv->widget == NULL)
+        return;
+
+    if (priv->component_manager_id)
+    {
+        gnc_unregister_gui_component(priv->component_manager_id);
+        priv->component_manager_id = 0;
+    }
+
+    if (priv->event_handler_id)
+    {
+        qof_event_unregister_handler(priv->event_handler_id);
+        priv->event_handler_id = 0;
+    }
+
+    if (priv->sd.dialog)
+    {
+        gtk_widget_destroy(priv->sd.dialog);
+        memset(&priv->sd, 0, sizeof(priv->sd));
+    }
+
+    if (priv->fd.dialog)
+    {
+        gtk_widget_destroy(priv->fd.dialog);
+        memset(&priv->fd, 0, sizeof(priv->fd));
+    }
+
+    gtk_widget_hide(priv->widget);
+    gnc_ledger_display_close (priv->ledger);
+    priv->ledger = NULL;
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_window_changed (GncPluginPage *plugin_page,
+        GtkWidget *window)
+{
+    GncPluginPageRegister2 *page;
+    GncPluginPageRegister2Private *priv;
+
+    g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page));
+
+    page = GNC_PLUGIN_PAGE_REGISTER2(plugin_page);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+
+/*    priv->gsr->window =
+        GTK_WIDGET(gnc_window_get_gtk_window(GNC_WINDOW(window)));
+*/
+}
+
+static const gchar *style_names[] =
+{
+    "Ledger",
+    "Auto Ledger",
+    "Journal",
+    NULL
+};
+
+#define KEY_REGISTER_TYPE       "RegisterType"
+#define KEY_ACCOUNT_NAME        "AccountName"
+#define KEY_REGISTER_STYLE      "RegisterStyle"
+#define KEY_DOUBLE_LINE         "DoubleLineMode"
+
+#define LABEL_ACCOUNT		"Account"
+#define LABEL_SUBACCOUNT	"SubAccount"
+#define LABEL_GL		"GL"
+#define LABEL_SEARCH		"Search"
+
+
+/** Save enough information about this register page that it can be
+ *  recreated next time the user starts gnucash.
+ *
+ *  @param plugin_page The page to save.
+ *
+ *  @param key_file A pointer to the GKeyFile data structure where the
+ *  page information should be written.
+ *
+ *  @param group_name The group name to use when saving data. */
+static void
+gnc_plugin_page_register2_save_page (GncPluginPage *plugin_page,
+                                    GKeyFile *key_file,
+                                    const gchar *group_name)
+{
+    GncPluginPageRegister2 *page;
+    GncPluginPageRegister2Private *priv;
+    GNCLedgerDisplayType ledger_type;
+    SplitRegister *reg;
+    Account *leader;
+
+    g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+    g_return_if_fail (key_file != NULL);
+    g_return_if_fail (group_name != NULL);
+
+    ENTER("page %p, key_file %p, group_name %s", plugin_page, key_file,
+          group_name);
+
+    page = GNC_PLUGIN_PAGE_REGISTER2(plugin_page);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+
+    reg = gnc_ledger_display_get_split_register(priv->ledger);
+    ledger_type = gnc_ledger_display_type(priv->ledger);
+    if (ledger_type > LD_GL)
+    {
+        LEAVE("Unsupported ledger type");
+        return;
+    }
+    if ((ledger_type == LD_SINGLE) || (ledger_type == LD_SUBACCOUNT))
+    {
+        const gchar *label;
+        gchar* name;
+        label = (ledger_type == LD_SINGLE) ? LABEL_ACCOUNT : LABEL_SUBACCOUNT;
+        leader = gnc_ledger_display_leader(priv->ledger);
+        g_key_file_set_string(key_file, group_name, KEY_REGISTER_TYPE, label);
+        name = gnc_account_get_full_name(leader);
+        g_key_file_set_string(key_file, group_name, KEY_ACCOUNT_NAME, name);
+        g_free(name);
+    }
+    else if (reg->type == GENERAL_LEDGER)
+    {
+        g_key_file_set_string(key_file, group_name, KEY_REGISTER_TYPE,
+                              LABEL_GL);
+    }
+    else if (reg->type == SEARCH_LEDGER)
+    {
+        g_key_file_set_string(key_file, group_name, KEY_REGISTER_TYPE,
+                              LABEL_SEARCH);
+    }
+    else
+    {
+        LEAVE("Unsupported register type");
+        return;
+    }
+
+    g_key_file_set_string(key_file, group_name, KEY_REGISTER_STYLE,
+                          style_names[reg->style]);
+    g_key_file_set_boolean(key_file, group_name, KEY_DOUBLE_LINE,
+                           reg->use_double_line);
+
+    LEAVE(" ");
+}
+
+
+/** Read and restore the edit menu settings on the specified register
+ *  page.  This function will restore the register style (ledger, auto
+ *  ledger, journal) and whether or not the register is in double line
+ *  mode.  It should eventually restore the "filter by" and "sort by
+ *  settings.
+ *
+ *  @param page The register being restored.
+ *
+ *  @param key_file A pointer to the GKeyFile data structure where the
+ *  page information should be read.
+ *
+ *  @param group_name The group name to use when restoring data. */
+static void
+gnc_plugin_page_register2_restore_edit_menu (GncPluginPage *page,
+        GKeyFile *key_file,
+        const gchar *group_name)
+{
+    GncPluginPageRegister2Private *priv;
+    GtkAction *action;
+    GError *error = NULL;
+    gchar *style_name;
+    gint i;
+    gboolean use_double_line;
+
+    ENTER(" ");
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+
+    /* Convert the style name to an index */
+    style_name = g_key_file_get_string(key_file, group_name,
+                                       KEY_REGISTER_STYLE, &error);
+    for (i = 0 ; style_names[i]; i++)
+    {
+        if (g_ascii_strcasecmp(style_name, style_names[i]) == 0)
+        {
+            DEBUG("Found match for style name: %s", style_name);
+            break;
+        }
+    }
+    g_free(style_name);
+
+    /* Update the style menu action for this page */
+    if (i <= REG_STYLE_JOURNAL)
+    {
+        DEBUG("Setting style: %d", i);
+        action = gnc_plugin_page_get_action(page, radio_entries_2[i].name);
+        gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), TRUE);
+    }
+
+    /* Update the  double line action on this page */
+    use_double_line =
+        g_key_file_get_boolean(key_file, group_name, KEY_DOUBLE_LINE, &error);
+    DEBUG("Setting double_line_mode: %d", use_double_line);
+    action = gnc_plugin_page_get_action(page, "ViewStyleDoubleLineAction");
+    gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), use_double_line);
+
+    LEAVE(" ");
+}
+
+
+/** Create a new register page based on the information saved during a
+ *  previous instantiation of gnucash.
+ *
+ *  @param window The window where this page should be installed.
+ *
+ *  @param key_file A pointer to the GKeyFile data structure where the
+ *  page information should be read.
+ *
+ *  @param group_name The group name to use when restoring data. */
+static GncPluginPage *
+gnc_plugin_page_register2_recreate_page (GtkWidget *window,
+                                        GKeyFile *key_file,
+                                        const gchar *group_name)
+{
+    GncPluginPage *page;
+    GError *error = NULL;
+    gchar *reg_type, *acct_name;
+    Account *account;
+    QofBook *book;
+    gboolean include_subs;
+
+    g_return_val_if_fail(key_file, NULL);
+    g_return_val_if_fail(group_name, NULL);
+    ENTER("key_file %p, group_name %s", key_file, group_name);
+
+    /* Create the new page. */
+    reg_type = g_key_file_get_string(key_file, group_name,
+                                     KEY_REGISTER_TYPE, &error);
+    DEBUG("Page type: %s", reg_type);
+    if ((g_ascii_strcasecmp(reg_type, LABEL_ACCOUNT) == 0) ||
+            (g_ascii_strcasecmp(reg_type, LABEL_SUBACCOUNT) == 0))
+    {
+        include_subs = (g_ascii_strcasecmp(reg_type, LABEL_SUBACCOUNT) == 0);
+        DEBUG("Include subs: %d", include_subs);
+        acct_name = g_key_file_get_string(key_file, group_name,
+                                          KEY_ACCOUNT_NAME, &error);
+        book = qof_session_get_book(gnc_get_current_session());
+        account = gnc_account_lookup_by_full_name(gnc_book_get_root_account(book),
+                  acct_name);
+        g_free(acct_name);
+        if (account == NULL)
+        {
+            LEAVE("Bad account name");
+            g_free(reg_type);
+            return NULL;
+        }
+        page = gnc_plugin_page_register2_new (account, include_subs);
+    }
+    else if (g_ascii_strcasecmp(reg_type, LABEL_GL) == 0)
+    {
+        page = gnc_plugin_page_register2_new_gl();
+    }
+    else
+    {
+        LEAVE("Bad ledger type");
+        g_free(reg_type);
+        return NULL;
+    }
+    g_free(reg_type);
+
+    /* Recreate page in given window */
+    gnc_plugin_page_set_use_new_window(page, FALSE);
+
+    /* Install it now so we can them manipulate the created widget */
+    gnc_main_window_open_page(GNC_MAIN_WINDOW(window), page);
+
+    /* Now update the page to the last state it was in */
+    gnc_plugin_page_register2_restore_edit_menu(page, key_file, group_name);
+    LEAVE(" ");
+    return page;
+}
+
+
+/*
+ * Based on code from Epiphany (src/ephy-window.c)
+ */
+static void
+gnc_plugin_page_register2_update_edit_menu (GncPluginPage *page, gboolean hide)
+{
+    GncPluginPageRegister2Private *priv;
+    GncPluginPageRegister2 *reg_page;
+    GtkAction *action;
+    gboolean can_copy = FALSE, can_cut = FALSE, can_paste = FALSE;
+    gboolean has_selection;
+    gboolean is_readwrite = !qof_book_is_readonly(gnc_get_current_book());
+
+    reg_page = GNC_PLUGIN_PAGE_REGISTER2(page);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(reg_page);
+    has_selection = gnucash_register_has_selection (priv->gsr->reg);
+
+    can_copy = has_selection;
+    can_cut = is_readwrite && has_selection;
+    can_paste = is_readwrite;
+
+    action = gnc_plugin_page_get_action (page, "EditCopyAction");
+    gtk_action_set_sensitive (action, can_copy);
+    gtk_action_set_visible (action, !hide || can_copy);
+    action = gnc_plugin_page_get_action (page, "EditCutAction");
+    gtk_action_set_sensitive (action, can_cut);
+    gtk_action_set_visible (action, !hide || can_cut);
+    action = gnc_plugin_page_get_action (page, "EditPasteAction");
+    gtk_action_set_sensitive (action, can_paste);
+    gtk_action_set_visible (action,  !hide || can_paste);
+}
+
+
+static gboolean
+gnc_plugin_page_register2_finish_pending (GncPluginPage *page)
+{
+    GncPluginPageRegister2Private *priv;
+    GncPluginPageRegister2 *reg_page;
+    SplitRegister *reg;
+    GtkWidget *dialog, *window;
+    const gchar *name;
+    gint response;
+
+    reg_page = GNC_PLUGIN_PAGE_REGISTER2(page);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(reg_page);
+    reg = gnc_ledger_display_get_split_register(priv->ledger);
+
+    if (!reg || !gnc_split_register_changed(reg))
+        return TRUE;
+
+    name = gnc_plugin_page_register2_get_tab_name(page);
+    window = gnc_plugin_page_get_window(page);
+    dialog = gtk_message_dialog_new(GTK_WINDOW(window),
+                                    GTK_DIALOG_DESTROY_WITH_PARENT,
+                                    GTK_MESSAGE_WARNING,
+                                    GTK_BUTTONS_NONE,
+                                    /* Translators: %s is the name
+                                       of the tab page */
+                                    _("Save changes to %s?"), name);
+    gtk_message_dialog_format_secondary_text
+    (GTK_MESSAGE_DIALOG(dialog),
+     "%s",
+     _("This register has pending changes to a transaction.  "
+       "Would you like to save the changes to this transaction, "
+       "discard the transaction, or cancel the operation?"));
+    gnc_gtk_dialog_add_button(dialog, _("_Discard Transaction"),
+                              GTK_STOCK_DELETE, GTK_RESPONSE_REJECT);
+    gtk_dialog_add_button(GTK_DIALOG(dialog),
+                          GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+    gnc_gtk_dialog_add_button(dialog, _("_Save Transaction"),
+                              GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT);
+
+    response = gtk_dialog_run(GTK_DIALOG(dialog));
+    gtk_widget_destroy(dialog);
+
+    switch (response)
+    {
+    case GTK_RESPONSE_ACCEPT:
+        gnc_split_register_save(reg, TRUE);
+        return TRUE;
+
+    case GTK_RESPONSE_REJECT:
+        gnc_split_register_cancel_cursor_trans_changes(reg);
+        gnc_split_register_save (reg, TRUE);
+        return TRUE;
+
+    default:
+        return FALSE;
+    }
+}
+
+
+static gchar *
+gnc_plugin_page_register2_get_tab_name (GncPluginPage *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+    GNCLedgerDisplayType ledger_type;
+    GNCLedgerDisplay *ld;
+    SplitRegister *reg;
+    Account *leader;
+
+    g_return_val_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page), _("unknown"));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    ld = priv->ledger;
+    reg = gnc_ledger_display_get_split_register (ld);
+    ledger_type = gnc_ledger_display_type (ld);
+    leader = gnc_ledger_display_leader (ld);
+
+    switch (ledger_type)
+    {
+    case LD_SINGLE:
+        return g_strdup(xaccAccountGetName (leader));
+
+    case LD_SUBACCOUNT:
+        return g_strdup_printf("%s+", xaccAccountGetName (leader));
+
+    case LD_GL:
+        switch (reg->type)
+        {
+        case GENERAL_LEDGER:
+        case INCOME_LEDGER:
+            return g_strdup(_("General Ledger"));
+        case PORTFOLIO_LEDGER:
+            return g_strdup(_("Portfolio"));
+        case SEARCH_LEDGER:
+            return g_strdup(_("Search Results"));
+        default:
+            break;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return g_strdup(_("unknown"));
+}
+
+static gchar *
+gnc_plugin_page_register2_get_tab_color (GncPluginPage *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+    GNCLedgerDisplayType ledger_type;
+    GNCLedgerDisplay *ld;
+    SplitRegister *reg;
+    Account *leader;
+    const char* color;
+
+    g_return_val_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page), _("unknown"));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    ld = priv->ledger;
+    reg = gnc_ledger_display_get_split_register (ld);
+    ledger_type = gnc_ledger_display_type (ld);
+    leader = gnc_ledger_display_leader (ld);
+    color = NULL;
+
+    if ((ledger_type == LD_SINGLE) || (ledger_type == LD_SUBACCOUNT))
+        color = xaccAccountGetColor (leader);
+
+    return g_strdup(color ? color : "Not Set");
+}
+
+static gchar *
+gnc_plugin_page_register2_get_filter (GncPluginPage *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+    GNCLedgerDisplayType ledger_type;
+    GNCLedgerDisplay *ld;
+    SplitRegister *reg;
+    Account *leader;
+    const char* filter;
+
+    g_return_val_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page), _("unknown"));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    ld = priv->ledger;
+    reg = gnc_ledger_display_get_split_register (ld);
+    ledger_type = gnc_ledger_display_type (ld);
+    leader = gnc_ledger_display_leader (ld);
+    filter = NULL;
+
+    if ((ledger_type == LD_SINGLE) || (ledger_type == LD_SUBACCOUNT))
+        filter = xaccAccountGetFilter (leader);
+
+    return filter ? g_strdup(filter) : g_strdup_printf("%s,%s,%s", DEFAULT_FILTER, "0", "0");
+}
+
+void
+gnc_plugin_page_register2_set_filter (GncPluginPage *plugin_page, const gchar *filter )
+{
+    GncPluginPageRegister2Private *priv;
+    GNCLedgerDisplayType ledger_type;
+    GNCLedgerDisplay *ld;
+    SplitRegister *reg;
+    Account *leader;
+    gchar *default_filter;
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    ld = priv->ledger;
+    reg = gnc_ledger_display_get_split_register (ld);
+    ledger_type = gnc_ledger_display_type (ld);
+    leader = gnc_ledger_display_leader (ld);
+
+    if (leader != NULL)
+    {
+        default_filter = g_strdup_printf("%s,%s,%s", DEFAULT_FILTER, "0", "0");
+
+        if (!filter || (g_strcmp0 (filter, default_filter) == 0))
+            xaccAccountSetFilter (leader, NULL);
+        else
+            xaccAccountSetFilter (leader, filter);
+
+        g_free (default_filter);
+    }
+
+    return;
+}
+
+static gchar *
+gnc_plugin_page_register2_get_sort_order (GncPluginPage *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+    GNCLedgerDisplayType ledger_type;
+    GNCLedgerDisplay *ld;
+    SplitRegister *reg;
+    Account *leader;
+    const char* sort_order;
+
+    g_return_val_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page), _("unknown"));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    ld = priv->ledger;
+    reg = gnc_ledger_display_get_split_register (ld);
+    ledger_type = gnc_ledger_display_type (ld);
+    leader = gnc_ledger_display_leader (ld);
+    sort_order = NULL;
+
+    if ((ledger_type == LD_SINGLE) || (ledger_type == LD_SUBACCOUNT))
+        sort_order = xaccAccountGetSortOrder (leader);
+
+    return g_strdup(sort_order ? sort_order : DEFAULT_SORT_ORDER);
+}
+
+void
+gnc_plugin_page_register2_set_sort_order (GncPluginPage *plugin_page, const gchar *sort_order )
+{
+    GncPluginPageRegister2Private *priv;
+    GNCLedgerDisplayType ledger_type;
+    GNCLedgerDisplay *ld;
+    SplitRegister *reg;
+    Account *leader;
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    ld = priv->ledger;
+    reg = gnc_ledger_display_get_split_register (ld);
+    ledger_type = gnc_ledger_display_type (ld);
+    leader = gnc_ledger_display_leader (ld);
+
+    if (leader != NULL)
+    {
+        if (!sort_order || (g_strcmp0 (sort_order, DEFAULT_SORT_ORDER) == 0))
+            xaccAccountSetSortOrder (leader, NULL);
+        else
+            xaccAccountSetSortOrder (leader, sort_order);
+    }
+
+    return;
+}
+
+static gchar *
+gnc_plugin_page_register2_get_long_name (GncPluginPage *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+    GNCLedgerDisplayType ledger_type;
+    GNCLedgerDisplay *ld;
+    SplitRegister *reg;
+    Account *leader;
+
+    g_return_val_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER2 (plugin_page), _("unknown"));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    ld = priv->ledger;
+    reg = gnc_ledger_display_get_split_register (ld);
+    ledger_type = gnc_ledger_display_type (ld);
+    leader = gnc_ledger_display_leader (ld);
+
+    switch (ledger_type)
+    {
+    case LD_SINGLE:
+        return gnc_account_get_full_name (leader);
+
+    case LD_SUBACCOUNT:
+    {
+        gchar *account_full_name = gnc_account_get_full_name (leader);
+        gchar *return_string = g_strdup_printf("%s+", account_full_name);
+        g_free ((gpointer *) account_full_name);
+        return return_string;
+    }
+
+    default:
+        break;
+    }
+
+    return NULL;
+}
+
+static void
+gnc_plugin_page_register2_summarybar_position_changed(GConfEntry *entry,
+        gpointer user_data)
+{
+    GncPluginPage *plugin_page;
+    GncPluginPageRegister2 *page;
+    GncPluginPageRegister2Private *priv;
+    GtkPositionType position = GTK_POS_BOTTOM;
+    gchar *conf_string;
+
+    g_return_if_fail(user_data != NULL);
+
+    plugin_page = GNC_PLUGIN_PAGE(user_data);
+    page = GNC_PLUGIN_PAGE_REGISTER2 (user_data);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+
+    conf_string = gnc_gconf_get_string (GCONF_GENERAL,
+                                        KEY_SUMMARYBAR_POSITION, NULL);
+    if (conf_string)
+    {
+        position = gnc_enum_from_nick (GTK_TYPE_POSITION_TYPE,
+                                       conf_string, GTK_POS_BOTTOM);
+        g_free (conf_string);
+    }
+
+    gtk_box_reorder_child(GTK_BOX(priv->widget),
+                          plugin_page->summarybar,
+                          (position == GTK_POS_TOP ? 0 : -1) );
+}
+
+/************************************************************/
+/*                     "Sort By" Dialog                     */
+/************************************************************/
+
+/** This function is called when the "Sort By..." dialog is closed.
+ *  If the dialog was closed by any method other than clicking the OK
+ *  button, the original sorting order will be restored.
+ *
+ *  @param dialog A pointer to the dialog box.
+ *
+ *  @param response A numerical value indicating why the dialog box was closed.
+ *
+ *  @param page A pointer to the GncPluginPageRegister2 associated with
+ *  this dialog box.
+ */
+void
+gnc_plugin_page_register2_sort_response_cb (GtkDialog *dialog,
+        gint response,
+        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    GncPluginPage *plugin_page;
+    SortType type;
+    const gchar *order;
+
+    g_return_if_fail(GTK_IS_DIALOG(dialog));
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    ENTER(" ");
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    plugin_page = GNC_PLUGIN_PAGE(page);
+
+    if (response != GTK_RESPONSE_OK)
+    {
+        /* Restore the original sort order */
+        gnc_split_reg_set_sort_type(priv->gsr, priv->sd.original_sort_type);
+        priv->sd.save_order = priv->sd.original_save_order;
+    }
+    else
+    {
+        priv->sd.original_save_order = priv->sd.save_order;
+
+        if (priv->sd.save_order)
+        {
+            type = gnc_split_reg_get_sort_type(priv->gsr);
+            order = SortTypeasString(type);
+            gnc_plugin_page_register2_set_sort_order (plugin_page, order);
+        }
+    }
+    priv->sd.dialog = NULL;
+    gtk_widget_destroy(GTK_WIDGET(dialog));
+    LEAVE(" ");
+}
+
+
+/** This function is called when a radio button in the "Sort By..."
+ *  dialog is clicked.
+ *
+ *  @param button The button that was toggled.
+ *
+ *  @param page A pointer to the GncPluginPageRegister2 associated with
+ *  this dialog box.
+ */
+void
+gnc_plugin_page_register2_sort_button_cb (GtkToggleButton *button,
+        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    const gchar *name;
+    SortType type;
+
+    g_return_if_fail(GTK_IS_TOGGLE_BUTTON(button));
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    name = gtk_buildable_get_name(GTK_BUILDABLE(button));
+    ENTER("button %s(%p), page %p", name, button, page);
+    type = SortTypefromString(name);
+    gnc_split_reg_set_sort_type(priv->gsr, type);
+    LEAVE(" ");
+}
+
+
+/** This function is called whenever the save sort order is checked
+ *  or unchecked which allows saving of the sort order.
+ *
+ *  @param button The toggle button that was changed.
+ *
+ *  @param page A pointer to the GncPluginPageRegister2 that is
+ *  associated with this sort order dialog.
+ */
+void
+gnc_plugin_page_register2_sort_order_save_cb (GtkToggleButton *button,
+        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+
+    g_return_if_fail(GTK_IS_CHECK_BUTTON(button));
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    ENTER("Save toggle button (%p), plugin_page %p", button, page);
+
+    /* Compute the new save sort order */
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+
+    if (gtk_toggle_button_get_active(button))
+        priv->sd.save_order = TRUE;
+    else
+        priv->sd.save_order = FALSE;
+    LEAVE(" ");
+}
+
+
+/************************************************************/
+/*                    "Filter By" Dialog                    */
+/************************************************************/
+
+/** This function updates the "cleared match" term of the register
+ *  query.  It unconditionally removes any old "cleared match" query
+ *  term, then adds back a new query term if needed.  There seems to
+ *  be a bug in the current g2 register code such that when the number
+ *  of entries in the register doesn't fill up the window, the blank
+ *  space at the end of the window isn't correctly redrawn.  This
+ *  function works around that problem, but a root cause analysis
+ *  should probably be done.
+ *
+ *  @param page A pointer to the GncPluginPageRegister2 that is
+ *  associated with this filter dialog.
+ */
+static void
+gnc_ppr_update_status_query (GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    GSList *param_list;
+    Query *query;
+
+    ENTER(" ");
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    query = gnc_ledger_display_get_query( priv->ledger );
+    if (!query)
+    {
+        LEAVE("no query found");
+        return;
+    }
+
+    /* Remove the old status match */
+    param_list = qof_query_build_param_list (SPLIT_RECONCILE, NULL);
+    if (param_list)
+    {
+        qof_query_purge_terms (query, param_list);
+        g_slist_free(param_list);
+    }
+
+    /* Install the new status match */
+    if (priv->fd.cleared_match != CLEARED_ALL)
+        xaccQueryAddClearedMatch(query, priv->fd.cleared_match, QOF_QUERY_AND);
+
+    gnc_ledger_display_refresh (priv->ledger);
+    LEAVE(" ");
+}
+
+
+/** This function updates the "date posted" term of the register
+ *  query.  It unconditionally removes any old "date posted" query
+ *  term, then adds back a new query term if needed.  There seems to
+ *  be a bug in the current g2 register code such that when the number
+ *  of entries in the register doesn't fill up the window, the blank
+ *  space at the end of the window isn't correctly redrawn.  This
+ *  function works around that problem, but a root cause analysis
+ *  should probably be done.
+ *
+ *  @param page A pointer to the GncPluginPageRegister2 that is
+ *  associated with this filter dialog.
+ */
+static void
+gnc_ppr_update_date_query (GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    GSList *param_list;
+    Query *query;
+
+    ENTER(" ");
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    if (!priv->ledger)
+    {
+        LEAVE("no ledger");
+        return;
+    }
+
+    query = gnc_ledger_display_get_query( priv->ledger );
+    if (!query)
+    {
+        LEAVE("no query");
+        return;
+    }
+
+    /* Delete any existing old date spec. */
+    param_list = qof_query_build_param_list(SPLIT_TRANS, TRANS_DATE_POSTED, NULL);
+    if (param_list)
+    {
+        qof_query_purge_terms (query, param_list);
+        g_slist_free(param_list);
+    }
+
+    if (priv->fd.start_time || priv->fd.end_time)
+    {
+        /* Build a new spec */
+        xaccQueryAddDateMatchTT(query,
+                                priv->fd.start_time != 0, priv->fd.start_time,
+                                priv->fd.end_time != 0,   priv->fd.end_time,
+                                QOF_QUERY_AND);
+    }
+
+    gnc_ledger_display_refresh (priv->ledger);
+    LEAVE(" ");
+}
+
+
+/* This function converts a time_t value date to a string */
+static gchar *
+gnc_plugin_page_register2_filter_time2dmy ( time_t raw_time)
+{
+    struct tm * timeinfo;
+    gchar date_string[11];
+    gint i;
+
+    timeinfo = localtime ( &raw_time );
+    i = strftime(date_string, 11, "%d-%m-%Y", timeinfo );
+    PINFO("Date string is %s", date_string);
+
+    return g_strdup(date_string);
+}
+
+
+/* This function converts a string date to a time_t value */
+static time_t
+gnc_plugin_page_register2_filter_dmy2time ( char *date_string)
+{
+    struct tm *when;
+    gint yy = 0, mm = 0, dd = 0;
+
+    time_t raw_time;
+
+    PINFO("Date string is %s", date_string);
+
+    sscanf(date_string, "%d-%d-%d", &dd, &mm, &yy );
+
+    time(&raw_time);
+    when = localtime ( &raw_time );
+
+    when->tm_year = yy - 1900;
+    when->tm_mon = mm - 1 ;
+    when->tm_mday = dd;
+
+    return mktime(when);
+}
+
+
+/** This function is called whenever one of the status entries is
+ *  checked or unchecked.  It updates the status value maintained for
+ *  the filter dialog, and calls another function to do the work of
+ *  applying the change to the register itself.
+ *
+ *  @param button The toggle button that was changed.
+ *
+ *  @param page A pointer to the GncPluginPageRegister2 that is
+ *  associated with this filter dialog.
+ */
+void
+gnc_plugin_page_register2_filter_status_one_cb (GtkToggleButton *button,
+        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    const gchar *name;
+    gint i, value;
+
+    g_return_if_fail(GTK_IS_CHECK_BUTTON(button));
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    name = gtk_buildable_get_name(GTK_BUILDABLE(button));
+    ENTER("toggle button %s (%p), plugin_page %p", name, button, page);
+
+    /* Determine what status bit to change */
+    value = CLEARED_NONE;
+    for (i = 0; status_actions[i].action_name; i++)
+    {
+        if (g_strcmp0(name, status_actions[i].action_name) == 0)
+        {
+            value = status_actions[i].value;
+            break;
+        }
+    }
+
+    /* Compute the new match status */
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    if (gtk_toggle_button_get_active(button))
+        priv->fd.cleared_match |= value;
+    else
+        priv->fd.cleared_match &= ~value;
+    gnc_ppr_update_status_query(page);
+    LEAVE(" ");
+}
+
+
+/** This function is called whenever the "select all" status button is
+ *  clicked.  It updates all of the checkbox widgets, then updates the
+ *  query on the register.
+ *
+ *  @param button The button that was clicked.
+ *
+ *  @param page A pointer to the GncPluginPageRegister2 that is
+ *  associated with this filter dialog.
+ */
+void
+gnc_plugin_page_register2_filter_status_all_cb (GtkButton *button,
+        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    GtkWidget *widget;
+    gint i;
+
+    g_return_if_fail(GTK_IS_BUTTON(button));
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    ENTER("(button %p, page %p)", button, page);
+
+    /* Turn on all the check menu items */
+    for (i = 0; status_actions[i].action_name; i++)
+    {
+        widget = status_actions[i].widget;
+        g_signal_handlers_block_by_func(widget, gnc_plugin_page_register2_filter_status_one_cb, page);
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widget), TRUE);
+        g_signal_handlers_unblock_by_func(widget, gnc_plugin_page_register2_filter_status_one_cb, page);
+    }
+
+    /* Set the requested status */
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    priv->fd.cleared_match = CLEARED_ALL;
+    gnc_ppr_update_status_query(page);
+    LEAVE(" ");
+}
+
+
+/** This function computes the starting and ending times for the
+ *  filter by examining the dialog widgets to see which ones are
+ *  selected, and will pull times out of the data entry boxes if
+ *  necessary.  This function must exist to handle the case where the
+ *  "show all" button was Selected, and the user clicks on the "select
+ *  range" button.  Since it exists, it make sense for the rest of the
+ *  callbacks to take advantage of it.
+ *
+ *  @param page A pointer to the GncPluginPageRegister2 that is
+ *  associated with this filter dialog.
+ */
+static void
+get_filter_times(GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    GtkWidget *button, *today, *gde;
+    time_t time_val;
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->fd.start_date_choose)))
+    {
+        time_val = gnc_date_edit_get_date(GNC_DATE_EDIT(priv->fd.start_date));
+        time_val = gnc_timet_get_day_start(time_val);
+        priv->fd.start_time = time_val;
+    }
+    else
+    {
+        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->fd.start_date_today)))
+        {
+            priv->fd.start_time = gnc_timet_get_today_start();
+        }
+        else
+        {
+            priv->fd.start_time = 0;
+        }
+    }
+
+    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->fd.end_date_choose)))
+    {
+        time_val = gnc_date_edit_get_date(GNC_DATE_EDIT(priv->fd.end_date));
+        time_val = gnc_timet_get_day_end(time_val);
+        priv->fd.end_time = time_val;
+    }
+    else
+    {
+        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->fd.start_date_today)))
+        {
+            priv->fd.end_time = gnc_timet_get_today_end();
+        }
+        else
+        {
+            priv->fd.end_time = 0;
+        }
+    }
+}
+
+
+/** This function is called when the "select range" radio button
+ *  changes state.  Since there are only two choices in this radio
+ *  group, this one signal can be used to handle all cases.  This
+ *  function is responsible for setting the sensitivity of the table
+ *  of widgets underneath the "select range" choice, and updating the
+ *  time limitation on the register query.  This is handled by a
+ *  helper function when the radio button is selected (as potentially
+ *  all the widgets in the table need to be inspected), and is trivial
+ *  for the other case.
+ *
+ *  @param button A pointer to the "select range" radio button.
+ *
+ *  @param page A pointer to the GncPluginPageRegister2 that is
+ *  associated with this filter dialog.
+ */
+void
+gnc_plugin_page_register2_filter_select_range_cb (GtkRadioButton *button,
+        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    gboolean active;
+
+    g_return_if_fail(GTK_IS_RADIO_BUTTON(button));
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    ENTER("(button %p, page %p)", button, page);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
+    gtk_widget_set_sensitive(priv->fd.table, active);
+    if (active)
+    {
+        get_filter_times(page);
+    }
+    else
+    {
+        priv->fd.start_time = 0;
+        priv->fd.end_time = 0;
+    }
+    gnc_ppr_update_date_query(page);
+    LEAVE(" ");
+}
+
+
+/** This function is called when one of the start date entry widgets
+ *  is updated.  It simply calls common routines to determine the
+ *  start/end times and update the register query.
+ *
+ *  @param unused A pointer to a GncDateEntry widgets, but it could be
+ *  any widget.
+ *
+ *  @param page A pointer to the GncPluginPageRegister2 that is
+ *  associated with this filter dialog.
+ */
+static void
+gnc_plugin_page_register2_filter_gde_changed_cb (GtkWidget *unused,
+        GncPluginPageRegister2 *page)
+{
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    ENTER("(widget %s(%p), page %p)", gtk_buildable_get_name(GTK_BUILDABLE(unused)), unused, page);
+    get_filter_times(page);
+    gnc_ppr_update_date_query(page);
+    LEAVE(" ");
+}
+
+
+/** This function is called when one of the start date radio buttons
+ *  is selected.  It updates the sensitivity of the date entry widget,
+ *  then calls a common routine to determine the start/end times and
+ *  update the register query.
+ *
+ *  *Note: This function is actually called twice for each new radio
+ *  button selection.  The first time call is to uncheck the old
+ *  button, and the second time to check the new button.  This does
+ *  make a kind of sense, as radio buttons are nothing more than
+ *  linked toggle buttons where only one can be active.
+ *
+ *  @param radio The button whose state is changing.  This will be
+ *  the previously selected button the first of the pair of calls to
+ *  this function, and will be the newly selected button the second
+ *  time.
+ *
+ *  @param page A pointer to the GncPluginPageRegister2 that is
+ *  associated with this filter dialog.
+ */
+void
+gnc_plugin_page_register2_filter_start_cb (GtkWidget *radio,
+        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    const gchar *name;
+    gboolean active;
+
+    g_return_if_fail(GTK_IS_RADIO_BUTTON(radio));
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    ENTER("(radio %s(%p), page %p)", gtk_buildable_get_name(GTK_BUILDABLE(radio)), radio, page);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio)))
+    {
+        LEAVE("1st callback of pair. Defer to 2nd callback.");
+        return;
+    }
+
+    name = gtk_buildable_get_name(GTK_BUILDABLE(radio));
+    active = ( g_strcmp0(name, g_strdup("start_date_choose")) == 0 ? 1 : 0 );
+    gtk_widget_set_sensitive(priv->fd.start_date, active);
+    get_filter_times(page);
+    gnc_ppr_update_date_query(page);
+    LEAVE(" ");
+}
+
+
+/** This function is called when one of the end date radio buttons is
+ *  selected.  It updates the sensitivity of the date entry widget,
+ *  then calls a common routine to determine the start/end times and
+ *  update the register query.
+ *
+ *  *Note: This function is actually called twice for each new radio
+ *  button selection.  The first time call is to uncheck the old
+ *  button, and the second time to check the new button.  This does
+ *  make a kind of sense, as radio buttons are nothing more than
+ *  linked toggle buttons where only one can be active.
+ *
+ *  @param radio The button whose state is changing.  This will be
+ *  the previously selected button the first of the pair of calls to
+ *  this function, and will be the newly selected button the second
+ *  time.
+ *
+ *  @param page A pointer to the GncPluginPageRegister2 that is
+ *  associated with this filter dialog.
+ */
+void
+gnc_plugin_page_register2_filter_end_cb (GtkWidget *radio,
+                                        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    const gchar *name;
+    gboolean active;
+
+    g_return_if_fail(GTK_IS_RADIO_BUTTON(radio));
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    ENTER("(radio %s(%p), page %p)", gtk_buildable_get_name(GTK_BUILDABLE(radio)), radio, page);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio)))
+    {
+        LEAVE("1st callback of pair. Defer to 2nd callback.");
+        return;
+    }
+
+    name = gtk_buildable_get_name(GTK_BUILDABLE(radio));
+    active = ( g_strcmp0(name, g_strdup("end_date_choose")) == 0 ? 1 : 0 );
+    gtk_widget_set_sensitive(priv->fd.end_date, active);
+    get_filter_times(page);
+    gnc_ppr_update_date_query(page);
+    LEAVE(" ");
+}
+
+
+/** This function is called whenever the save status is checked
+ *  or unchecked. It will allow saving of the filter if required.
+ *
+ *  @param button The toggle button that was changed.
+ *
+ *  @param page A pointer to the GncPluginPageRegister2 that is
+ *  associated with this filter dialog.
+ */
+void
+gnc_plugin_page_register2_filter_save_cb (GtkToggleButton *button,
+        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+
+    g_return_if_fail(GTK_IS_CHECK_BUTTON(button));
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    ENTER("Save toggle button (%p), plugin_page %p", button, page);
+
+    /* Compute the new save filter status */
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    if (gtk_toggle_button_get_active(button))
+        priv->fd.save_filter = TRUE;
+    else
+        priv->fd.save_filter = FALSE;
+    LEAVE(" ");
+}
+
+
+/** This function is called when the "Filter By..." dialog is closed.
+ *  If the dialog was closed by any method other than clicking the OK
+ *  button, the original sorting order will be restored.
+ *
+ *  @param dialog A pointer to the dialog box.
+ *
+ *  @param response A numerical value indicating why the dialog box was closed.
+ *
+ *  @param page A pointer to the GncPluginPageRegister2 associated with
+ *  this dialog box.
+ */
+void
+gnc_plugin_page_register2_filter_response_cb (GtkDialog *dialog,
+        gint response,
+        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    GncPluginPage *plugin_page;
+
+    g_return_if_fail(GTK_IS_DIALOG(dialog));
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    ENTER(" ");
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    plugin_page = GNC_PLUGIN_PAGE(page);
+
+    if (response != GTK_RESPONSE_OK)
+    {
+        /* Remove the old status match */
+        priv->fd.cleared_match = priv->fd.original_cleared_match;
+        gnc_ppr_update_status_query(page);
+        priv->fd.start_time = priv->fd.original_start_time;
+        priv->fd.end_time = priv->fd.original_end_time;
+        priv->fd.save_filter = priv->fd.original_save_filter;
+        gnc_ppr_update_date_query(page);
+    }
+    else
+    {
+        priv->fd.original_save_filter = priv->fd.save_filter;
+
+        if (priv->fd.save_filter)
+        {
+            gchar* filter;
+            filter = g_strdup_printf("0x%04x", priv->fd.cleared_match);
+
+            if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->fd.start_date_choose)) && priv->fd.start_time != 0 )
+            {
+                gchar *timeval = gnc_plugin_page_register2_filter_time2dmy(priv->fd.start_time);
+                filter = g_strconcat ( filter, ",", timeval, NULL);
+                g_free (timeval);
+            }
+            else
+                filter = g_strconcat ( filter, ",0", NULL);
+
+            if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->fd.end_date_choose)) && priv->fd.end_time != 0 )
+            {
+                gchar *timeval = gnc_plugin_page_register2_filter_time2dmy(priv->fd.end_time);
+                filter = g_strconcat ( filter, ",", timeval, NULL);
+                g_free (timeval);
+            }
+            else
+                filter = g_strconcat ( filter, ",0", NULL);
+
+            PINFO("The filter to save is %s", filter);
+
+            gnc_plugin_page_register2_set_filter (plugin_page, filter);
+            g_free (filter);
+        }
+    }
+    priv->fd.dialog = NULL;
+    gtk_widget_destroy(GTK_WIDGET(dialog));
+    LEAVE(" ");
+}
+
+
+/************************************************************/
+/*                  Report Helper Functions                 */
+/************************************************************/
+
+static char *
+gnc_reg_get_name (GNCLedgerDisplay *ledger, gboolean for_window)
+{
+    Account *leader;
+    SplitRegister *reg;
+    gchar *account_name;
+    gchar *reg_name;
+    gchar *name;
+    GNCLedgerDisplayType ledger_type;
+
+    if (ledger == NULL)
+        return NULL;
+
+    reg = gnc_ledger_display_get_split_register (ledger);
+    ledger_type = gnc_ledger_display_type (ledger);
+
+    switch (reg->type)
+    {
+    case GENERAL_LEDGER:
+    case INCOME_LEDGER:
+        if (for_window)
+            reg_name = _("General Ledger");
+        else
+            reg_name = _("General Ledger Report");
+        break;
+    case PORTFOLIO_LEDGER:
+        if (for_window)
+            reg_name = _("Portfolio");
+        else
+            reg_name = _("Portfolio Report");
+        break;
+    case SEARCH_LEDGER:
+        if (for_window)
+            reg_name = _("Search Results");
+        else
+            reg_name = _("Search Results Report");
+        break;
+    default:
+        if (for_window)
+            reg_name = _("Register");
+        else
+            reg_name = _("Register Report");
+        break;
+    }
+
+    leader = gnc_ledger_display_leader (ledger);
+
+    if ((leader != NULL) && (ledger_type != LD_GL))
+    {
+        account_name = gnc_account_get_full_name (leader);
+
+        if (ledger_type == LD_SINGLE)
+        {
+            name = g_strconcat (account_name, " - ", reg_name, NULL);
+        }
+        else
+        {
+            name = g_strconcat (account_name, " ", _("and subaccounts"), " - ", reg_name, NULL);
+        }
+        g_free(account_name);
+    }
+    else
+        name = g_strdup (reg_name);
+
+    return name;
+}
+
+static int
+report_helper (GNCLedgerDisplay *ledger, Split *split, Query *query)
+{
+    SplitRegister *reg = gnc_ledger_display_get_split_register (ledger);
+    Account *account;
+    char *str;
+    swig_type_info * qtype;
+    SCM args;
+    SCM func;
+    SCM arg;
+
+    args = SCM_EOL;
+
+    func = scm_c_eval_string ("gnc:register-report-create");
+    g_return_val_if_fail (scm_is_procedure (func), -1);
+
+    arg = scm_makfrom0str (gnc_split_register_get_credit_string (reg));
+    args = scm_cons (arg, args);
+
+    arg = scm_makfrom0str (gnc_split_register_get_debit_string (reg));
+    args = scm_cons (arg, args);
+
+    str = gnc_reg_get_name (ledger, FALSE);
+    arg = scm_makfrom0str (str);
+    args = scm_cons (arg, args);
+    g_free (str);
+
+    arg = SCM_BOOL (reg->use_double_line);
+    args = scm_cons (arg, args);
+
+    arg = SCM_BOOL (reg->style == REG_STYLE_JOURNAL);
+    args = scm_cons (arg, args);
+
+    if (!query)
+    {
+        query = gnc_ledger_display_get_query (ledger);
+        g_return_val_if_fail (query != NULL, -1);
+    }
+
+    qtype = SWIG_TypeQuery ("_p__QofQuery");
+    g_return_val_if_fail (qtype, -1);
+
+    arg = SWIG_NewPointerObj (query, qtype, 0);
+    args = scm_cons (arg, args);
+    g_return_val_if_fail (arg != SCM_UNDEFINED, -1);
+
+
+    if (split)
+    {
+        qtype = SWIG_TypeQuery ("_p_Split");
+        g_return_val_if_fail (qtype, -1);
+        arg = SWIG_NewPointerObj (split, qtype, 0);
+    }
+    else
+    {
+        arg = SCM_BOOL_F;
+    }
+    args = scm_cons (arg, args);
+    g_return_val_if_fail (arg != SCM_UNDEFINED, -1);
+
+
+    qtype = SWIG_TypeQuery ("_p_Account");
+    g_return_val_if_fail (qtype, -1);
+
+    account = gnc_ledger_display_leader (ledger);
+    arg = SWIG_NewPointerObj (account, qtype, 0);
+    args = scm_cons (arg, args);
+    g_return_val_if_fail (arg != SCM_UNDEFINED, -1);
+
+
+    /* Apply the function to the args */
+    arg = scm_apply (func, args, SCM_EOL);
+    g_return_val_if_fail (scm_is_exact (arg), -1);
+
+    return scm_num2int (arg, SCM_ARG1, G_STRFUNC);
+}
+
+/************************************************************/
+/*                     Command callbacks                    */
+/************************************************************/
+
+static void
+gnc_plugin_page_register2_cmd_print_check (GtkAction *action,
+        GncPluginPageRegister2 *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+    SplitRegister * reg;
+    Split         * split;
+    Transaction   * trans;
+    GList         * splits = NULL, *item;
+    GNCLedgerDisplayType ledger_type;
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+#ifdef SKIP
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    reg = gnc_ledger_display_get_split_register (priv->ledger);
+    ledger_type = gnc_ledger_display_type(priv->ledger);
+    if (ledger_type == LD_SINGLE || ledger_type == LD_SUBACCOUNT)
+    {
+        split    = gnc_split_register_get_current_split(reg);
+        trans    = xaccSplitGetParent(split);
+
+        if (split && trans)
+        {
+            splits = g_list_append(splits, split);
+            gnc_ui_print_check_dialog_create(plugin_page, splits);
+            g_list_free(splits);
+        }
+    }
+    else if (ledger_type == LD_GL && reg->type == SEARCH_LEDGER)
+    {
+        Account *common_acct = NULL, *account;
+        splits = qof_query_run(gnc_ledger_display_get_query(priv->ledger));
+        /* Make sure each split is from the same account */
+        for (item = splits; item; item = g_list_next(item))
+        {
+            split = (Split *) item->data;
+            if (common_acct == NULL)
+            {
+                common_acct = xaccSplitGetAccount(split);
+            }
+            else
+            {
+                if (xaccSplitGetAccount(split) != common_acct)
+                {
+                    GtkWidget *dialog, *window;
+                    gint response;
+                    const gchar *title = _("Print checks from multiple accounts?");
+                    const gchar *message =
+                        _("This search result contains splits from more than one account. "
+                          "Do you want to print the checks even though they are not all "
+                          "from the same account?");
+                    window = gnc_plugin_page_get_window(GNC_PLUGIN_PAGE(plugin_page));
+                    dialog = gtk_message_dialog_new(GTK_WINDOW(window),
+                                                    GTK_DIALOG_DESTROY_WITH_PARENT,
+                                                    GTK_MESSAGE_WARNING,
+                                                    GTK_BUTTONS_CANCEL,
+                                                    "%s", title);
+                    gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
+                            "%s", message);
+                    gtk_dialog_add_button(GTK_DIALOG(dialog), _("_Print checks"),
+                                          GTK_RESPONSE_YES);
+                    response = gnc_dialog_run(GTK_DIALOG(dialog), "print_multi_acct_checks");
+                    gtk_widget_destroy(dialog);
+                    if (response != GTK_RESPONSE_YES)
+                    {
+                        LEAVE("Multiple accounts");
+                        return;
+                    }
+                    break;
+                }
+            }
+        }
+        gnc_ui_print_check_dialog_create(plugin_page, splits);
+    }
+    else
+    {
+        gnc_error_dialog(gnc_plugin_page_get_window(GNC_PLUGIN_PAGE(plugin_page)), "%s",
+                         _("You can only print checks from a bank account register or search results."));
+        LEAVE("Unsupported ledger type");
+        return;
+    }
+#endif
+    LEAVE(" ");
+}
+
+
+static void
+gnc_plugin_page_register2_cmd_cut (GtkAction *action,
+                                  GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    ENTER("(action %p, page %p)", action, page);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    gnucash_register_cut_clipboard(priv->gsr->reg);
+    LEAVE("");
+}
+
+
+static void
+gnc_plugin_page_register2_cmd_copy (GtkAction *action,
+                                   GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    ENTER("(action %p, page %p)", action, page);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    gnucash_register_copy_clipboard(priv->gsr->reg);
+    LEAVE("");
+}
+
+
+static void
+gnc_plugin_page_register2_cmd_paste (GtkAction *action,
+                                    GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    ENTER("(action %p, page %p)", action, page);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    gnucash_register_paste_clipboard(priv->gsr->reg);
+    LEAVE("");
+}
+
+
+static void
+gnc_plugin_page_register2_cmd_edit_account (GtkAction *action,
+        GncPluginPageRegister2 *page)
+{
+    Account *account;
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    ENTER("(action %p, page %p)", action, page);
+    account = gnc_plugin_page_register2_get_account (page);
+    if (account)
+        gnc_ui_edit_account_window (account);
+    LEAVE(" ");
+}
+
+
+static void
+gnc_plugin_page_register2_cmd_find_transactions (GtkAction *action,
+        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    ENTER("(action %p, page %p)", action, page);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+/* This function has the original ledger type */
+/*    gnc_ui_find_transactions_dialog_create(priv->ledger); */
+    LEAVE(" ");
+}
+
+
+static void
+gnc_plugin_page_register2_cmd_cut_transaction (GtkAction *action,
+        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    SplitRegister *reg;
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    ENTER("(action %p, page %p)", action, page);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    reg = gnc_ledger_display_get_split_register(priv->ledger);
+    gnc_split_register_cut_current(reg);
+    LEAVE(" ");
+}
+
+
+static void
+gnc_plugin_page_register2_cmd_copy_transaction (GtkAction *action,
+        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    SplitRegister *reg;
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    ENTER("(action %p, page %p)", action, page);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    reg = gnc_ledger_display_get_split_register(priv->ledger);
+    gnc_split_register_copy_current(reg);
+    LEAVE(" ");
+}
+
+
+static void
+gnc_plugin_page_register2_cmd_paste_transaction (GtkAction *action,
+        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    SplitRegister *reg;
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    ENTER("(action %p, page %p)", action, page);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    reg = gnc_ledger_display_get_split_register(priv->ledger);
+    gnc_split_register_paste_current(reg);
+    LEAVE(" ");
+}
+
+
+static void
+gnc_plugin_page_register2_cmd_void_transaction (GtkAction *action,
+        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    GtkWidget *dialog, *entry;
+    SplitRegister *reg;
+    Transaction *trans;
+    GtkBuilder *builder;
+    const char *reason;
+    gint result;
+
+    ENTER("(action %p, page %p)", action, page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    reg = gnc_ledger_display_get_split_register(priv->ledger);
+    trans = gnc_split_register_get_current_trans(reg);
+    if (trans == NULL)
+        return;
+    if (xaccTransHasSplitsInState(trans, VREC))
+        return;
+    if (xaccTransHasReconciledSplits(trans) || xaccTransHasSplitsInState(trans, CREC))
+    {
+        gnc_error_dialog(NULL, "%s", _("You cannot void a transaction with reconciled or cleared splits."));
+        return;
+    }
+
+    if (!gnc_plugin_page_register2_finish_pending(GNC_PLUGIN_PAGE(page)))
+        return;
+
+    builder = gtk_builder_new();
+    gnc_builder_add_from_file  (builder , "gnc-plugin-page-register.glade", "Void Transaction");
+    dialog = GTK_WIDGET(gtk_builder_get_object (builder, "Void Transaction"));
+    entry = GTK_WIDGET(gtk_builder_get_object (builder, "reason"));
+
+    result = gtk_dialog_run(GTK_DIALOG(dialog));
+    if (result == GTK_RESPONSE_OK)
+    {
+        reason = gtk_entry_get_text(GTK_ENTRY(entry));
+        if (reason == NULL)
+            reason = "";
+        gnc_split_register_void_current_trans(reg, reason);
+    }
+
+    /* All done. Get rid of it. */
+    gtk_widget_destroy(dialog);
+    g_object_unref(G_OBJECT(builder));
+}
+
+
+static void
+gnc_plugin_page_register2_cmd_unvoid_transaction (GtkAction *action,
+        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    SplitRegister *reg;
+    Transaction *trans;
+
+    ENTER("(action %p, page %p)", action, page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    reg = gnc_ledger_display_get_split_register(priv->ledger);
+    trans = gnc_split_register_get_current_trans(reg);
+    if (!xaccTransHasSplitsInState(trans, VREC))
+        return;
+    gnc_split_register_unvoid_current_trans(reg);
+    LEAVE(" ");
+}
+
+
+static void
+gnc_plugin_page_register2_cmd_reverse_transaction (GtkAction *action,
+        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    SplitRegister *reg;
+    GNCSplitReg *gsr;
+    Transaction *trans, *new_trans;
+
+    ENTER("(action %p, page %p)", action, page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    reg = gnc_ledger_display_get_split_register(priv->ledger);
+    trans = gnc_split_register_get_current_trans(reg);
+    if (trans == NULL)
+        return;
+
+    if (xaccTransGetReversedBy(trans))
+    {
+        gnc_error_dialog(gnc_plugin_page_get_window(GNC_PLUGIN_PAGE(page)), "%s",
+                         _("A reversing entry has already been created for this transaction."));
+        return;
+    }
+
+    qof_event_suspend();
+    new_trans = xaccTransReverse(trans);
+
+    /* Clear transaction level info */
+    xaccTransSetDatePostedSecs(new_trans, time(NULL));
+    xaccTransSetDateEnteredSecs(new_trans, time(NULL));
+
+    qof_event_resume();
+
+    /* Now jump to new trans */
+    gsr = gnc_plugin_page_register2_get_gsr(GNC_PLUGIN_PAGE(page));
+    gnc_split_reg_jump_to_split(gsr, xaccTransGetSplit(new_trans, 0));
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_shift_transaction_forward (GtkAction *action,
+        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    SplitRegister *reg;
+    GNCSplitReg *gsr;
+    Transaction *trans, *new_trans;
+    Timespec entered;
+
+    ENTER("(action %p, page %p)", action, page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    reg = gnc_ledger_display_get_split_register(priv->ledger);
+    trans = gnc_split_register_get_current_trans(reg);
+    if (trans == NULL)
+        return;
+
+    qof_event_suspend();
+
+    xaccTransGetDatePostedTS(trans, &entered);
+    xaccTransSetDatePostedSecs(trans, entered.tv_sec + 1);
+
+    qof_event_resume();
+
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_view_sort_by (GtkAction *action,
+        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    GtkWidget *dialog, *button;
+    GtkBuilder *builder;
+    SortType sort;
+    const gchar *name;
+    gchar *title;
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+    ENTER("(action %p, page %p)", action, page);
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    if (priv->sd.dialog)
+    {
+        gtk_window_present(GTK_WINDOW(priv->sd.dialog));
+        LEAVE("existing dialog");
+        return;
+    }
+
+    /* Create the dialog */
+
+    builder = gtk_builder_new();
+    gnc_builder_add_from_file  (builder, "gnc-plugin-page-register.glade", "Sort By");
+    dialog = GTK_WIDGET(gtk_builder_get_object (builder, "Sort By"));
+    priv->sd.dialog = dialog;
+    gtk_window_set_transient_for(GTK_WINDOW(dialog),
+                                 gnc_window_get_gtk_window(GNC_WINDOW(GNC_PLUGIN_PAGE(page)->window)));
+    /* Translations: The %s is the name of the plugin page */
+    title = g_strdup_printf(_("Sort %s by..."),
+                            gnc_plugin_page_get_page_name(GNC_PLUGIN_PAGE(page)));
+    gtk_window_set_title(GTK_WINDOW(dialog), title);
+    g_free(title);
+
+    /* Set the button for the current sort order */
+    sort = gnc_split_reg_get_sort_type(priv->gsr);
+    name = SortTypeasString(sort);
+    button = GTK_WIDGET(gtk_builder_get_object (builder, name));
+    DEBUG("current sort %d, button %s(%p)", sort, name, button);
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
+    priv->sd.original_sort_type = sort;
+
+    button = GTK_WIDGET(gtk_builder_get_object (builder, "sort_save"));
+    if (priv->sd.save_order == TRUE)
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
+
+    /* Wire it up */
+    gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, page);
+
+    /* Show it */
+    gtk_widget_show(dialog);
+    g_object_unref(G_OBJECT(builder));
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_view_filter_by (GtkAction *action,
+        GncPluginPageRegister2 *page)
+{
+    GncPluginPageRegister2Private *priv;
+    GtkWidget *dialog, *toggle, *button, *start_date, *end_date, *table, *hbox;
+    time_t start_time, end_time, time_val;
+    GtkBuilder *builder;
+    gboolean sensitive, value;
+    Query *query;
+    gchar *title;
+    int i;
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+    ENTER("(action %p, page %p)", action, page);
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    if (priv->fd.dialog)
+    {
+        gtk_window_present(GTK_WINDOW(priv->fd.dialog));
+        LEAVE("existing dialog");
+        return;
+    }
+
+    /* Create the dialog */
+    builder = gtk_builder_new();
+    gnc_builder_add_from_file (builder, "gnc-plugin-page-register.glade", "Filter By");
+    dialog = GTK_WIDGET(gtk_builder_get_object (builder, "Filter By"));
+    priv->fd.dialog = dialog;
+    gtk_window_set_transient_for(GTK_WINDOW(dialog),
+                                 gnc_window_get_gtk_window(GNC_WINDOW(GNC_PLUGIN_PAGE(page)->window)));
+
+    /* Translators: The %s is the name of the plugin page */
+    title = g_strdup_printf(_("Filter %s by..."),
+                            gnc_plugin_page_get_page_name(GNC_PLUGIN_PAGE(page)));
+    gtk_window_set_title(GTK_WINDOW(dialog), title);
+    g_free(title);
+
+    /* Set the check buttons for the current status */
+    for (i = 0; status_actions[i].action_name; i++)
+    {
+        toggle = GTK_WIDGET(gtk_builder_get_object (builder, status_actions[i].action_name));
+        value = priv->fd.cleared_match & status_actions[i].value;
+        status_actions[i].widget = toggle;
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), value);
+    }
+    priv->fd.original_cleared_match = priv->fd.cleared_match;
+
+    button = GTK_WIDGET(gtk_builder_get_object (builder, "filter_save"));
+    if (priv->fd.save_filter == TRUE)
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
+
+
+    /* Set the date info */
+    button = GTK_WIDGET(gtk_builder_get_object (builder, "filter_show_range"));
+    query = gnc_ledger_display_get_query (priv->ledger);
+    xaccQueryGetDateMatchTT(query, &start_time, &end_time);
+    priv->fd.original_start_time = start_time;
+    priv->fd.start_time = start_time;
+    priv->fd.original_end_time = end_time;
+    priv->fd.end_time = end_time;
+
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), start_time || end_time);
+    table = GTK_WIDGET(gtk_builder_get_object (builder, "select_range_table"));
+    priv->fd.table = table;
+    gtk_widget_set_sensitive(GTK_WIDGET(table), start_time || end_time);
+
+    priv->fd.start_date_choose = GTK_WIDGET(gtk_builder_get_object (builder, "start_date_choose"));
+    priv->fd.start_date_today = GTK_WIDGET(gtk_builder_get_object (builder, "start_date_today"));
+    priv->fd.end_date_choose = GTK_WIDGET(gtk_builder_get_object (builder, "end_date_choose"));
+    priv->fd.end_date_today = GTK_WIDGET(gtk_builder_get_object (builder, "end_date_today"));
+
+    {
+        /* Start date info */
+        if (start_time == 0)
+        {
+            button = GTK_WIDGET(gtk_builder_get_object (builder, "start_date_earliest"));
+            time_val = xaccQueryGetEarliestDateFound (query);
+            sensitive = FALSE;
+        }
+        else
+        {
+            time_val = start_time;
+            if ((start_time >= gnc_timet_get_today_start()) &&
+                    (start_time <= gnc_timet_get_today_end()))
+            {
+                button = priv->fd.start_date_today;
+                sensitive = FALSE;
+            }
+            else
+            {
+                button = priv->fd.start_date_choose;
+                sensitive = TRUE;
+            }
+        }
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
+        priv->fd.start_date = gnc_date_edit_new (time (NULL), FALSE, FALSE);
+        hbox = GTK_WIDGET(gtk_builder_get_object (builder, "start_date_hbox"));
+        gtk_box_pack_start (GTK_BOX (hbox), priv->fd.start_date, TRUE, TRUE, 0);
+        gtk_widget_show (priv->fd.start_date);
+        gtk_widget_set_sensitive(GTK_WIDGET(priv->fd.start_date), sensitive);
+        gnc_date_edit_set_time(GNC_DATE_EDIT(priv->fd.start_date), time_val);
+        g_signal_connect (G_OBJECT (priv->fd.start_date), "date-changed",
+                          G_CALLBACK (gnc_plugin_page_register2_filter_gde_changed_cb),
+                          page);
+    }
+
+    {
+        /* End date info */
+        if (end_time == 0)
+        {
+            button = GTK_WIDGET(gtk_builder_get_object (builder, "end_date_latest"));
+            time_val = xaccQueryGetLatestDateFound (query);
+            sensitive = FALSE;
+        }
+        else
+        {
+            time_val = end_time;
+            if ((end_time >= gnc_timet_get_today_start()) &&
+                    (end_time <= gnc_timet_get_today_end()))
+            {
+                button = priv->fd.end_date_today;
+                sensitive = FALSE;
+            }
+            else
+            {
+                button = priv->fd.end_date_choose;
+                sensitive = TRUE;
+            }
+        }
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
+        priv->fd.end_date = gnc_date_edit_new (time (NULL), FALSE, FALSE);
+        hbox = GTK_WIDGET(gtk_builder_get_object (builder, "end_date_hbox"));
+        gtk_box_pack_start (GTK_BOX (hbox), priv->fd.end_date, TRUE, TRUE, 0);
+        gtk_widget_show (priv->fd.end_date);
+        gtk_widget_set_sensitive(GTK_WIDGET(priv->fd.end_date), sensitive);
+        gnc_date_edit_set_time(GNC_DATE_EDIT(priv->fd.end_date), time_val);
+        g_signal_connect (G_OBJECT (priv->fd.end_date), "date-changed",
+                          G_CALLBACK (gnc_plugin_page_register2_filter_gde_changed_cb),
+                          page);
+    }
+
+    /* Wire it up */
+    gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, page);
+
+    /* Show it */
+    gtk_widget_show_all(dialog);
+    g_object_unref(G_OBJECT(builder));
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_style_changed (GtkAction *action,
+        GtkRadioAction *current,
+        GncPluginPageRegister2 *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+    SplitRegisterStyle value;
+
+    ENTER("(action %p, radio action %p, plugin_page %p)",
+          action, current, plugin_page);
+
+    g_return_if_fail(GTK_IS_ACTION(action));
+    g_return_if_fail(GTK_IS_RADIO_ACTION(current));
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    value = gtk_radio_action_get_current_value(current);
+    gnc_split_reg_change_style(priv->gsr, value);
+
+    gnc_plugin_page_register2_ui_update (NULL, plugin_page);
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_style_double_line (GtkToggleAction *action,
+        GncPluginPageRegister2 *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+    SplitRegister *reg;
+    gboolean use_double_line;
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+
+    g_return_if_fail(GTK_IS_ACTION(action));
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    reg = gnc_ledger_display_get_split_register (priv->ledger);
+
+    use_double_line =  gtk_toggle_action_get_active (action);
+    if (use_double_line != reg->use_double_line)
+    {
+        gnc_split_register_config(reg, reg->type, reg->style, use_double_line);
+        gnc_ledger_display_refresh(priv->ledger);
+    }
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_transfer (GtkAction *action,
+                                       GncPluginPageRegister2 *page)
+{
+    Account *account;
+    GncWindow *gnc_window;
+    GtkWidget *window;
+
+    ENTER("(action %p, plugin_page %p)", action, page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    account = gnc_plugin_page_register2_get_account (page);
+    gnc_window = GNC_WINDOW(GNC_PLUGIN_PAGE (page)->window);
+    window = GTK_WIDGET(gnc_window_get_gtk_window(gnc_window));
+    gnc_xfer_dialog (window, account);
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_reconcile (GtkAction *action,
+                                        GncPluginPageRegister2 *page)
+{
+    Account *account;
+    GtkWindow *window;
+    RecnWindow * recnData;
+
+    ENTER("(action %p, plugin_page %p)", action, page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    account = gnc_plugin_page_register2_get_account (page);
+
+    window = gnc_window_get_gtk_window(GNC_WINDOW(GNC_PLUGIN_PAGE (page)->window));
+    recnData = recnWindow (GTK_WIDGET(window), account);
+    gnc_ui_reconcile_window_raise (recnData);
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_autoclear (GtkAction *action,
+                                        GncPluginPageRegister2 *page)
+{
+    Account *account;
+    GtkWindow *window;
+    AutoClearWindow * autoClearData;
+
+    ENTER("(action %p, plugin_page %p)", action, page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    account = gnc_plugin_page_register2_get_account (page);
+
+    window = gnc_window_get_gtk_window(GNC_WINDOW(GNC_PLUGIN_PAGE (page)->window));
+    autoClearData = autoClearWindow (GTK_WIDGET(window), account);
+    gnc_ui_autoclear_window_raise (autoClearData);
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_stock_split (GtkAction *action,
+        GncPluginPageRegister2 *page)
+{
+    Account *account;
+
+    ENTER("(action %p, plugin_page %p)", action, page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    account = gnc_plugin_page_register2_get_account (page);
+    gnc_stock_split_dialog (NULL, account);
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_lots (GtkAction *action,
+                                   GncPluginPageRegister2 *page)
+{
+    Account *account;
+
+    ENTER("(action %p, plugin_page %p)", action, page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+
+    account = gnc_plugin_page_register2_get_account (page);
+    gnc_lot_viewer_dialog (account);
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_enter_transaction (GtkAction *action,
+        GncPluginPageRegister2 *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    gnc_split_reg_enter(priv->gsr, FALSE);
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_cancel_transaction (GtkAction *action,
+        GncPluginPageRegister2 *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    gnc_split_register_cancel_cursor_trans_changes
+    (gnc_ledger_display_get_split_register(priv->ledger));
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_delete_transaction (GtkAction *action,
+        GncPluginPageRegister2 *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    gsr_default_delete_handler(priv->gsr, NULL);
+    LEAVE(" ");
+
+}
+
+static void
+gnc_plugin_page_register2_cmd_blank_transaction (GtkAction *action,
+        GncPluginPageRegister2 *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+    SplitRegister *reg;
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    reg = gnc_ledger_display_get_split_register (priv->ledger);
+
+    if (gnc_split_register_save (reg, TRUE))
+        gnc_split_register_redraw (reg);
+
+    gnc_split_reg_jump_to_blank (priv->gsr);
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_duplicate_transaction (GtkAction *action,
+        GncPluginPageRegister2 *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    gnc_split_register_duplicate_current
+    (gnc_ledger_display_get_split_register(priv->ledger));
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_reinitialize_transaction (GtkAction *action,
+        GncPluginPageRegister2 *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    gsr_default_reinit_handler(priv->gsr, NULL);
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_expand_transaction (GtkToggleAction *action,
+        GncPluginPageRegister2 *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+    SplitRegister *reg;
+    gboolean expand;
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    reg = gnc_ledger_display_get_split_register (priv->ledger);
+    expand = gtk_toggle_action_get_active (action);
+    gnc_split_register_expand_current_trans (reg, expand);
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_exchange_rate (GtkAction *action,
+        GncPluginPageRegister2 *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+    SplitRegister *reg;
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    reg = gnc_ledger_display_get_split_register (priv->ledger);
+
+    /* XXX Ignore the return value -- we don't care if this succeeds */
+    (void)gnc_split_register_handle_exchange (reg, TRUE);
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_jump (GtkAction *action,
+                                   GncPluginPageRegister2 *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+    GncPluginPage *new_page;
+    GncPluginPageRegister2 *new_reg_page;
+    GtkWidget *window;
+    GNCSplitReg *gsr;
+    SplitRegister *reg;
+    Account *account;
+    Account *leader;
+    Split *split;
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    window = GNC_PLUGIN_PAGE (plugin_page)->window;
+    if (window == NULL)
+    {
+        LEAVE("no window");
+        return;
+    }
+
+    reg = gnc_ledger_display_get_split_register (priv->ledger);
+    split = gnc_split_register_get_current_split (reg);
+    if (split == NULL)
+    {
+        LEAVE("no split (1)");
+        return;
+    }
+
+    account = xaccSplitGetAccount (split);
+    if (account == NULL)
+    {
+        LEAVE("no account");
+        return;
+    }
+
+    leader = gnc_ledger_display_leader (priv->ledger);
+    if (account == leader)
+    {
+        split = xaccSplitGetOtherSplit (split);
+        if (split == NULL)
+        {
+            LEAVE("no split (2)");
+            return;
+        }
+
+        account = xaccSplitGetAccount (split);
+        if (account == NULL)
+        {
+            LEAVE("no account (2)");
+            return;
+        }
+
+        if (account == leader)
+        {
+            LEAVE("register open for account");
+            return;
+        }
+    }
+
+    new_page = gnc_plugin_page_register2_new (account, FALSE);
+    if (new_page == NULL)
+    {
+        LEAVE("couldn't create new page");
+        return;
+    }
+    new_reg_page = GNC_PLUGIN_PAGE_REGISTER2(new_page);
+
+    gnc_main_window_open_page (GNC_MAIN_WINDOW(window), new_page);
+    gsr = gnc_plugin_page_register2_get_gsr (new_page);
+    gnc_split_reg_jump_to_split(gsr, split);
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_schedule (GtkAction *action,
+                                       GncPluginPageRegister2 *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    gsr_default_schedule_handler(priv->gsr, NULL);
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_scrub_current (GtkAction *action,
+        GncPluginPageRegister2 *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+    Query *query;
+    Account *root;
+    Transaction *trans;
+    SplitRegister *reg;
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    query = gnc_ledger_display_get_query( priv->ledger );
+    if (query == NULL)
+    {
+        LEAVE("no query found");
+        return;
+    }
+
+    reg = gnc_ledger_display_get_split_register(priv->ledger);
+    trans = gnc_split_register_get_current_trans(reg);
+    if (trans == NULL)
+    {
+        LEAVE("no trans found");
+        return;
+    }
+
+    gnc_suspend_gui_refresh();
+    root = gnc_get_current_root_account();
+    xaccTransScrubOrphans(trans);
+    xaccTransScrubImbalance(trans, root, NULL);
+    gnc_resume_gui_refresh();
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_scrub_all (GtkAction *action,
+                                        GncPluginPageRegister2 *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+    Query *query;
+    Account *root;
+    Transaction *trans;
+    Split *split;
+    GList *node;
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    query = gnc_ledger_display_get_query( priv->ledger );
+    if (!query)
+    {
+        LEAVE("no query found");
+        return;
+    }
+
+    gnc_suspend_gui_refresh();
+    root = gnc_get_current_root_account();
+
+    for (node = qof_query_run(query); node; node = node->next)
+    {
+        split = node->data;
+        trans = xaccSplitGetParent(split);
+
+        xaccTransScrubOrphans(trans);
+        xaccTransScrubImbalance(trans, root, NULL);
+    }
+
+    gnc_resume_gui_refresh();
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_account_report (GtkAction *action,
+        GncPluginPageRegister2 *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+    GncMainWindow *window;
+    int id;
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+
+    window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    id = report_helper (priv->ledger, NULL, NULL);
+    if (id >= 0)
+        gnc_main_window_open_report(id, window);
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_register2_cmd_transaction_report (GtkAction *action,
+        GncPluginPageRegister2 *plugin_page)
+{
+    GncPluginPageRegister2Private *priv;
+    GncMainWindow *window;
+    SplitRegister *reg;
+    Split *split;
+    Query *query;
+    int id;
+
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(plugin_page);
+    reg = gnc_ledger_display_get_split_register (priv->ledger);
+
+    split = gnc_split_register_get_current_split (reg);
+    if (!split)
+        return;
+
+    query = qof_query_create_for(GNC_ID_SPLIT);
+
+    qof_query_set_book (query, gnc_get_current_book ());
+
+    xaccQueryAddGUIDMatch (query, xaccSplitGetGUID (split),
+                           GNC_ID_SPLIT, QOF_QUERY_AND);
+
+    window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
+    id = report_helper (priv->ledger, split, query);
+    if (id >= 0)
+        gnc_main_window_open_report(id, window);
+    LEAVE(" ");
+}
+
+/************************************************************/
+/*                    Auxiliary functions                   */
+/************************************************************/
+
+void
+gnc_plugin_page_register2_set_options (GncPluginPage *plugin_page,
+                                      gint lines_default,
+                                      gboolean read_only)
+{
+    GncPluginPageRegister2 *page;
+    GncPluginPageRegister2Private *priv;
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page));
+
+    page = GNC_PLUGIN_PAGE_REGISTER2 (plugin_page);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+    priv->lines_default     = lines_default;
+    priv->read_only         = read_only;
+}
+
+GNCSplitReg *
+gnc_plugin_page_register2_get_gsr (GncPluginPage *plugin_page)
+{
+    GncPluginPageRegister2 *page;
+    GncPluginPageRegister2Private *priv;
+
+    g_return_val_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(plugin_page), NULL);
+
+    page = GNC_PLUGIN_PAGE_REGISTER2 (plugin_page);
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+
+    return priv->gsr;
+}
+
+static void
+gnc_plugin_page_help_changed_cb (GNCSplitReg *gsr, GncPluginPageRegister2 *register_page)
+{
+    GncPluginPageRegister2Private *priv;
+    SplitRegister *reg;
+    GncWindow *window;
+    char *help;
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(register_page));
+
+    window = GNC_WINDOW(GNC_PLUGIN_PAGE(register_page)->window);
+    if (!window)
+    {
+        // This routine can be called before the page is added to a
+        // window.
+        return;
+    }
+
+    /* Get the text from the ledger */
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(register_page);
+    reg = gnc_ledger_display_get_split_register(priv->ledger);
+    help = gnc_table_get_help(reg->table);
+    gnc_window_set_status(window, GNC_PLUGIN_PAGE(register_page), help);
+    g_free(help);
+}
+
+static void
+gnc_plugin_page_register2_refresh_cb (GHashTable *changes, gpointer user_data)
+{
+    GncPluginPageRegister2 *page = user_data;
+    GncPluginPageRegister2Private *priv;
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER2(page));
+    priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+
+    if (changes)
+    {
+        const EventInfo* ei;
+        ei = gnc_gui_get_entity_events(changes, &priv->key);
+        if (ei)
+        {
+            if (ei->event_mask & QOF_EVENT_DESTROY)
+            {
+                gnc_main_window_close_page(GNC_PLUGIN_PAGE(page));
+                return;
+            }
+            if (ei->event_mask & QOF_EVENT_MODIFY)
+            {
+            }
+        }
+    }
+    else
+    {
+        /* forced updates */
+        gnucash_register_refresh_from_gconf(priv->gsr->reg);
+        gtk_widget_queue_draw(priv->widget);
+    }
+
+    gnc_plugin_page_register2_ui_update(NULL, page);
+}
+
+static void
+gnc_plugin_page_register2_close_cb (gpointer user_data)
+{
+    GncPluginPage *plugin_page = GNC_PLUGIN_PAGE(user_data);
+    gnc_main_window_close_page (plugin_page);
+}
+
+/** This function is called when an account has been edited and an
+ *  "extreme" change has been made to it.  (E.G. Changing from a
+ *  credit card account to an expense account.  This rouine is
+ *  responsible for finding all open registers containing the account
+ *  and closing them.
+ *
+ *  @param account A pointer to the account that was changed.
+ */
+static void
+gppr_account_destroy_cb (Account *account)
+{
+    GncPluginPageRegister2 *page;
+    GncPluginPageRegister2Private *priv;
+    GNCLedgerDisplayType ledger_type;
+    const GncGUID *acct_guid;
+    const GList *citem;
+    GList *item, *kill = NULL;
+
+    acct_guid = xaccAccountGetGUID(account);
+
+    /* Find all windows that need to be killed.  Don't kill them yet, as
+     * that would affect the list being walked.*/
+    citem = gnc_gobject_tracking_get_list(GNC_PLUGIN_PAGE_REGISTER2_NAME);
+    for ( ; citem; citem = g_list_next(citem))
+    {
+        page = (GncPluginPageRegister2 *)citem->data;
+        priv = GNC_PLUGIN_PAGE_REGISTER2_GET_PRIVATE(page);
+        ledger_type = gnc_ledger_display_type (priv->ledger);
+        if (ledger_type == LD_GL)
+        {
+            kill = g_list_append(kill, page);
+            /* kill it */
+        }
+        else if ((ledger_type == LD_SINGLE) || (ledger_type == LD_SUBACCOUNT))
+        {
+            if (guid_compare(acct_guid, &priv->key) == 0)
+            {
+                kill = g_list_append(kill, page);
+            }
+        }
+    }
+
+    /* Now kill them. */
+    for (item = kill; item; item = g_list_next(item))
+    {
+        page = (GncPluginPageRegister2 *)item->data;
+        gnc_main_window_close_page(GNC_PLUGIN_PAGE(page));
+    }
+}
+
+/** This function is the handler for all event messages from the
+ *  engine.  Its purpose is to update the register page any time
+ *  an account or transaction is changed.
+ *
+ *  @internal
+ *
+ *  @param entity A pointer to the affected item.
+ *
+ *  @param event_type The type of the affected item.
+ *
+ *  @param page A pointer to the register page.
+ *
+ *  @param ed
+ */
+static void
+gnc_plugin_page_register2_event_handler (QofInstance *entity,
+                                        QofEventId event_type,
+                                        GncPluginPageRegister2 *page,
+                                        GncEventData *ed)
+{
+    Transaction *trans;
+    QofBook *book;
+    GncPluginPage *visible_page;
+    GtkWidget *window;
+    gchar *label, *color;
+
+    g_return_if_fail(page);	/* Required */
+    if (!GNC_IS_TRANS(entity) && !GNC_IS_ACCOUNT(entity))
+        return;
+
+    ENTER("entity %p of type %d, page %p, event data %p",
+          entity, event_type, page, ed);
+
+    window = gnc_plugin_page_get_window(GNC_PLUGIN_PAGE(page));
+
+    if (GNC_IS_ACCOUNT(entity))
+    {
+        if (GNC_IS_MAIN_WINDOW(window))
+        {
+            label = gnc_plugin_page_register2_get_tab_name(GNC_PLUGIN_PAGE(page));
+            main_window_update_page_name(GNC_PLUGIN_PAGE(page), label);
+            color = gnc_plugin_page_register2_get_tab_color(GNC_PLUGIN_PAGE(page));
+            main_window_update_page_color(GNC_PLUGIN_PAGE(page), color);
+            g_free(color);
+            g_free(label);
+        }
+        LEAVE("tab name updated");
+        return;
+    }
+
+    if (!(event_type & (QOF_EVENT_MODIFY | QOF_EVENT_DESTROY)))
+    {
+        LEAVE("not a modify");
+        return;
+    }
+    trans = GNC_TRANS(entity);
+    book = qof_instance_get_book(QOF_INSTANCE(trans));
+    if (!gnc_plugin_page_has_book(GNC_PLUGIN_PAGE(page), book))
+    {
+        LEAVE("not in this book");
+        return;
+    }
+
+    if (GNC_IS_MAIN_WINDOW(window))
+    {
+        visible_page = gnc_main_window_get_current_page(GNC_MAIN_WINDOW(window));
+        if (visible_page != GNC_PLUGIN_PAGE(page))
+        {
+            LEAVE("page not visible");
+            return;
+        }
+    }
+
+    gnc_plugin_page_register2_ui_update(NULL, page);
+    LEAVE(" ");
+    return;
+}
+
+
+/** @} */
+/** @} */
Index: src/gnome/gnc-plugin-page-register2.h
===================================================================
--- src/gnome/gnc-plugin-page-register2.h	(revision 0)
+++ src/gnome/gnc-plugin-page-register2.h	(revision 0)
@@ -0,0 +1,151 @@
+/**********************************************************************
+ * gnc-plugin-page-register2.h -- register page functions              *
+ *                                                                    *
+ * Copyright (C) 2003 Jan Arne Petersen <jpetersen@uni-bonn.de>       *
+ * Copyright (C) 2003,2005,2006 David Hampton <hampton@employees.org> *
+ *                                                                    *
+ * This program is free software; you can redistribute it and/or      *
+ * modify it under the terms of the GNU General Public License as     *
+ * published by the Free Software Foundation; either version 2 of     *
+ * the License, or (at your option) any later version.                *
+ *                                                                    *
+ * This program is distributed in the hope that it will be useful,    *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of     *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *
+ * GNU General Public License for more details.                       *
+ *                                                                    *
+ * You should have received a copy of the GNU General Public License  *
+ * along with this program; if not, contact:                          *
+ *                                                                    *
+ * Free Software Foundation           Voice:  +1-617-542-5942         *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652         *
+ * Boston, MA  02110-1301,  USA       gnu@gnu.org                     *
+ **********************************************************************/
+
+/** @addtogroup ContentPlugins
+    @{ */
+/** @addtogroup Register2Plugin Register2 Page
+    @{ */
+/** @file gnc-plugin-page-register.h
+    @brief  Functions providing a register page for the GnuCash UI
+    @author Copyright (C) 2003 Jan Arne Petersen <jpetersen@uni-bonn.de>
+    @author Copyright (C) 2003 David Hampton <hampton@employees.org>
+*/
+
+#ifndef __GNC_PLUGIN_PAGE_REGISTER2_H
+#define __GNC_PLUGIN_PAGE_REGISTER2_H
+
+#include <gtk/gtk.h>
+
+#include "Account.h"
+#include "gnc-ledger-display.h"
+#include "gnc-plugin-page.h"
+#include "gnc-split-reg.h"
+
+G_BEGIN_DECLS
+
+/* type macros */
+#define GNC_TYPE_PLUGIN_PAGE_REGISTER2            (gnc_plugin_page_register2_get_type ())
+#define GNC_PLUGIN_PAGE_REGISTER2(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_PLUGIN_PAGE_REGISTER2, GncPluginPageRegister2))
+#define GNC_PLUGIN_PAGE_REGISTER2_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GNC_TYPE_PLUGIN_PAGE_REGISTER2, GncPluginPageRegister2Class))
+#define GNC_IS_PLUGIN_PAGE_REGISTER2(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNC_TYPE_PLUGIN_PAGE_REGISTER2))
+#define GNC_IS_PLUGIN_PAGE_REGISTER2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNC_TYPE_PLUGIN_PAGE_REGISTER2))
+#define GNC_PLUGIN_PAGE_REGISTER2_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GNC_TYPE_PLUGIN_PAGE_REGISTER2, GncPluginPageRegister2Class))
+#define GNC_PLUGIN_PAGE_REGISTER2_NAME "GncPluginPageRegister2"
+
+/* typedefs & structures */
+typedef struct
+{
+    GncPluginPage gnc_plugin_page;
+} GncPluginPageRegister2;
+
+typedef struct
+{
+    GncPluginPageClass gnc_plugin_page;
+} GncPluginPageRegister2Class;
+
+/* function prototypes */
+
+/** Retrieve the type number for the plugin page.
+ *
+ *  @return The type number.
+ */
+GType gnc_plugin_page_register2_get_type (void);
+
+
+/** Create a new "register" plugin page, given a pointer to an
+ *  account.
+ *
+ *  @param account The pointer to the account to embed in the
+ *  register.
+ *
+ *  @param subaccounts TRUE if all the sub-accounts of the specified
+ *  account should be included in the register.
+ *
+ *  @return The newly created plugin page.
+ */
+GncPluginPage *
+gnc_plugin_page_register2_new (Account *account, gboolean subaccounts);
+
+
+/** Create a new "register" plugin page, given a pointer to an already
+ *  created ledger.  This function should be used when the ledger
+ *  already exists.  (E.G.  From the "find transaction" code, or from
+ *  the scheduled transaction code.)
+ *
+ *  @param ledger The pointer to the ledger to embed into the
+ *  register.
+ *
+ *  @return The newly created plugin page.
+ */
+GncPluginPage *
+gnc_plugin_page_register2_new_ledger (GNCLedgerDisplay *ledger);
+
+
+/** Create a new "register" plugin page containing a general ledger.
+ *
+ *  @return The newly created plugin page.
+ */
+GncPluginPage *
+gnc_plugin_page_register2_new_gl (void);
+
+
+/** Set various register options on a newly created "register" plugin page.
+ *
+ *  @param plugin_page The "register" page to modify.
+ *
+ *  @param lines_default Used to calculate the minimum preferred height of
+ *                       the plugin page.
+ *
+ *  @param read_only True if the register should be read-only.
+ */
+void
+gnc_plugin_page_register2_set_options (GncPluginPage *plugin_page,
+                                      gint lines_default,
+                                      gboolean read_only);
+
+
+/** Get the GNCSplitReg data structure associated with this register page.
+ *
+ *  @param plugin_page A "register" page.
+ */
+GNCSplitReg *
+gnc_plugin_page_register2_get_gsr (GncPluginPage *plugin_page);
+
+
+/** Get the Account associated with this register page.
+ *
+ *  @param page A "register" page.
+ *
+ *  @return The account if the register contains only a single
+ *  account, or an account and its sub-accounts.  NULL otherwise.
+ */
+Account *
+gnc_plugin_page_register2_get_account (GncPluginPageRegister2 *page);
+
+G_END_DECLS
+/** @} */
+/** @} */
+
+#endif /* __GNC_PLUGIN_PAGE_REGISTER2_H */
+
Index: src/gnome/gnc-plugin-register2.c
===================================================================
--- src/gnome/gnc-plugin-register2.c	(revision 0)
+++ src/gnome/gnc-plugin-register2.c	(revision 0)
@@ -0,0 +1,202 @@
+/*
+ * gnc-plugin-register2.c --
+ *
+ * Copyright (C) 2003 Jan Arne Petersen
+ * Author: Jan Arne Petersen <jpetersen@uni-bonn.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu@gnu.org
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <string.h>
+
+#include "gnc-component-manager.h"
+#include "gnc-plugin-register2.h"
+#include "gnc-plugin-page-register2.h"
+
+
+static void gnc_plugin_register2_class_init (GncPluginRegister2Class *klass);
+static void gnc_plugin_register2_init (GncPluginRegister2 *plugin);
+static void gnc_plugin_register2_finalize (GObject *object);
+
+/* Command callbacks */
+static void gnc_plugin_register2_cmd_general_ledger (GtkAction *action, GncMainWindowActionData *data);
+
+#define PLUGIN_ACTIONS_NAME "gnc-plugin-register2-actions"
+#define PLUGIN_UI_FILENAME  "gnc-plugin-register2-ui.xml"
+#define GCONF_REGISTER2_SECTION "general/register"
+
+static GtkActionEntry gnc_plugin_actions [] =
+{
+    {
+        "ToolsGeneralLedgerAction", NULL, N_("_General Ledger"), NULL,
+        N_("Open a general ledger window"),
+        G_CALLBACK (gnc_plugin_register2_cmd_general_ledger)
+    },
+};
+static guint gnc_plugin_n_actions = G_N_ELEMENTS (gnc_plugin_actions);
+
+typedef struct GncPluginRegister2Private
+{
+    gpointer dummy;
+} GncPluginRegister2Private;
+
+#define GNC_PLUGIN_REGISTER2_GET_PRIVATE(o)  \
+   (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_PLUGIN_REGISTER2, GncPluginRegister2Private))
+
+static GObjectClass *parent_class = NULL;
+static QofLogModule log_module = GNC_MOD_GUI;
+
+/************************************************************
+ *                     Other Functions                      *
+ ************************************************************/
+
+/** This function is called whenever an entry in the general register
+ *  section of gconf is changed.  It does nothing more than kick off a
+ *  gui refresh which should be delivered to any open register page.
+ *  The register pages will then reread their settings from gconf and
+ *  update the screen.
+ *
+ *  @client Unused.
+ *
+ *  @cnxn_id Unused.
+ *
+ *  @entry Unused.
+ *
+ *  @user_data Unused.
+ */
+static void
+gnc_plugin_register2_gconf_changed (GConfClient *client,
+                                   guint cnxn_id,
+                                   GConfEntry *entry,
+                                   gpointer user_data)
+{
+    ENTER("");
+    gnc_gui_refresh_all ();
+    LEAVE("");
+}
+
+/************************************************************
+ *                  Object Implementation                   *
+ ************************************************************/
+
+GType
+gnc_plugin_register2_get_type (void)
+{
+    static GType gnc_plugin_register2_type = 0;
+
+    if (gnc_plugin_register2_type == 0)
+    {
+        static const GTypeInfo our_info =
+        {
+            sizeof (GncPluginRegister2Class),
+            NULL,		/* base_init */
+            NULL,		/* base_finalize */
+            (GClassInitFunc) gnc_plugin_register2_class_init,
+            NULL,		/* class_finalize */
+            NULL,		/* class_data */
+            sizeof (GncPluginRegister2),
+            0,		/* n_preallocs */
+            (GInstanceInitFunc) gnc_plugin_register2_init
+        };
+
+        gnc_plugin_register2_type = g_type_register_static (GNC_TYPE_PLUGIN,
+                                   "GncPluginRegister2",
+                                   &our_info, 0);
+    }
+
+    return gnc_plugin_register2_type;
+}
+
+GncPlugin *
+gnc_plugin_register2_new (void)
+{
+    GncPluginRegister2 *plugin;
+
+    /* Reference the register page plugin to ensure it exists in
+     * the gtk type system. */
+    GNC_TYPE_PLUGIN_PAGE_REGISTER2;
+
+    plugin = g_object_new (GNC_TYPE_PLUGIN_REGISTER2,
+                           NULL);
+
+    return GNC_PLUGIN (plugin);
+}
+
+static void
+gnc_plugin_register2_class_init (GncPluginRegister2Class *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+    GncPluginClass *plugin_class = GNC_PLUGIN_CLASS (klass);
+
+    parent_class = g_type_class_peek_parent (klass);
+
+    object_class->finalize = gnc_plugin_register2_finalize;
+
+    /* plugin info */
+    plugin_class->plugin_name  = GNC_PLUGIN_REGISTER2_NAME;
+
+    /* widget addition/removal */
+    plugin_class->actions_name = PLUGIN_ACTIONS_NAME;
+    plugin_class->actions      = gnc_plugin_actions;
+    plugin_class->n_actions    = gnc_plugin_n_actions;
+    plugin_class->ui_filename  = PLUGIN_UI_FILENAME;
+
+    plugin_class->gconf_section = GCONF_REGISTER2_SECTION;
+    plugin_class->gconf_notifications = gnc_plugin_register2_gconf_changed;
+
+    g_type_class_add_private(klass, sizeof(GncPluginRegister2Private));
+}
+
+static void
+gnc_plugin_register2_init (GncPluginRegister2 *plugin)
+{
+}
+
+static void
+gnc_plugin_register2_finalize (GObject *object)
+{
+    GncPluginRegister2 *plugin;
+    GncPluginRegister2Private *priv;
+
+    g_return_if_fail (GNC_IS_PLUGIN_REGISTER2 (object));
+
+    plugin = GNC_PLUGIN_REGISTER2 (object);
+    priv = GNC_PLUGIN_REGISTER2_GET_PRIVATE(plugin);
+
+    G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+/************************************************************
+ *                    Command Callbacks                     *
+ ************************************************************/
+
+static void
+gnc_plugin_register2_cmd_general_ledger (GtkAction *action,
+                                        GncMainWindowActionData *data)
+{
+    GncPluginPage *page;
+
+    g_return_if_fail (data != NULL);
+
+    page = gnc_plugin_page_register2_new_gl ();
+    gnc_main_window_open_page (data->window, page);
+}
Index: src/gnome/gnc-plugin-register2.h
===================================================================
--- src/gnome/gnc-plugin-register2.h	(revision 0)
+++ src/gnome/gnc-plugin-register2.h	(revision 0)
@@ -0,0 +1,60 @@
+/*
+ * gnc-plugin-register2.h --
+ *
+ * Copyright (C) 2003 Jan Arne Petersen
+ * Author: Jan Arne Petersen <jpetersen@uni-bonn.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu@gnu.org
+ */
+
+#ifndef __GNC_PLUGIN_REGISTER2_H
+#define __GNC_PLUGIN_REGISTER2_H
+
+#include "gnc-plugin.h"
+
+G_BEGIN_DECLS
+
+/* type macros */
+#define GNC_TYPE_PLUGIN_REGISTER2            (gnc_plugin_register2_get_type ())
+#define GNC_PLUGIN_REGISTER2(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_PLUGIN_REGISTER2, GncPluginRegister2))
+#define GNC_PLUGIN_REGISTER2_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GNC_TYPE_PLUGIN_REGISTER2, GncPluginRegister2Class))
+#define GNC_IS_PLUGIN_REGISTER2(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNC_TYPE_PLUGIN_REGISTER2))
+#define GNC_IS_PLUGIN_REGISTER2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNC_TYPE_PLUGIN_REGISTER2))
+#define GNC_PLUGIN_REGISTER2_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GNC_TYPE_PLUGIN_REGISTER2, GncPluginRegister2Class))
+
+#define GNC_PLUGIN_REGISTER2_NAME "gnc-plugin-register2"
+
+/* typedefs & structures */
+typedef struct
+{
+    GncPlugin gnc_plugin;
+} GncPluginRegister2;
+
+typedef struct
+{
+    GncPluginClass gnc_plugin;
+} GncPluginRegister2Class;
+
+/* function prototypes */
+GType      gnc_plugin_register2_get_type (void);
+
+GncPlugin *gnc_plugin_register2_new      (void);
+
+G_END_DECLS
+
+#endif /* __GNC_PLUGIN_REGISTER2_H */
Index: src/gnome/Makefile.am
===================================================================
--- src/gnome/Makefile.am	(revision 22178)
+++ src/gnome/Makefile.am	(working copy)
@@ -45,10 +45,12 @@
   gnc-plugin-basic-commands.c \
   gnc-plugin-budget.c \
   gnc-plugin-register.c \
+  gnc-plugin-register2.c \
   gnc-plugin-page-account-tree.c \
   gnc-plugin-page-budget.c \
   gnc-plugin-page-sx-list.c \
   gnc-plugin-page-register.c \
+  gnc-plugin-page-register2.c \
   gnc-split-reg.c \
   reconcile-list.c \
   top-level.c \
@@ -81,10 +83,12 @@
   gnc-plugin-basic-commands.h \
   gnc-plugin-budget.h \
   gnc-plugin-register.h \
+  gnc-plugin-register2.h \
   gnc-plugin-page-account-tree.h \
   gnc-plugin-page-budget.h \
   gnc-plugin-page-sx-list.h \
   gnc-plugin-page-register.h \
+  gnc-plugin-page-register2.h \
   gnc-split-reg.h \
   reconcile-list.h \
   top-level.h \
Index: src/gnome/ui/gnc-plugin-register2-ui.xml
===================================================================
--- src/gnome/ui/gnc-plugin-register2-ui.xml	(revision 0)
+++ src/gnome/ui/gnc-plugin-register2-ui.xml	(revision 0)
@@ -0,0 +1,9 @@
+<ui>
+  <menubar>
+    <menu name="Tools" action="ToolsAction">
+      <placeholder name="ToolsPlaceholder">
+        <menuitem name="ToolsGeneralLedger" action="ToolsGeneralLedgerAction"/>
+      </placeholder>
+    </menu>
+  </menubar>
+</ui>
Index: src/gnome/ui/gnc-plugin-page-register2-ui.xml
===================================================================
--- src/gnome/ui/gnc-plugin-page-register2-ui.xml	(revision 0)
+++ src/gnome/ui/gnc-plugin-page-register2-ui.xml	(revision 0)
@@ -0,0 +1,104 @@
+<ui>
+  <menubar>
+    <menu name="Edit" action="EditAction">
+      <placeholder name="EditAllSelectedPlaceholder">
+        <menuitem name="EditEditAccount"        action="EditEditAccountAction"/>
+      </placeholder>
+    </menu>
+
+    <menu name="Transaction" action="TransactionAction">
+      <menuitem name="CutTransaction"     	action="CutTransactionAction"/>
+      <menuitem name="CopyTransaction"    	action="CopyTransactionAction"/>
+      <menuitem name="PasteTransaction"   	action="PasteTransactionAction"/>
+      <menuitem name="DuplicateTransaction"    	action="DuplicateTransactionAction"/>
+      <menuitem name="DeleteTransaction"       	action="DeleteTransactionAction"/>
+      <menuitem name="RemoveTransactionSplits" 	action="RemoveTransactionSplitsAction"/>
+      <!--menuitem name="ShiftTransactionForward" 	action="ShiftTransactionForwardAction"/-->
+      <separator name="TransactionSep1"/>
+      <menuitem name="RecordTransaction"        action="RecordTransactionAction"/>
+      <menuitem name="CancelTransaction"        action="CancelTransactionAction"/>
+      <separator name="TransactionSep2"/>
+      <menuitem name="VoidTransaction"    	action="VoidTransactionAction"/>
+      <menuitem name="UnvoidTransaction"  	action="UnvoidTransactionAction"/>
+      <menuitem name="ReverseTransaction" 	action="ReverseTransactionAction"/>
+    </menu>
+
+    <menu name="View" action="ViewAction">
+      <placeholder name="ViewContentPlaceholder">
+        <menuitem name="ViewStyleBasic"        	action="ViewStyleBasicAction"/>
+        <menuitem name="ViewStyleAutoSplit"    	action="ViewStyleAutoSplitAction"/>
+        <menuitem name="ViewStyleJournal"      	action="ViewStyleJournalAction"/>
+        <separator name="ViewSep44"/>
+        <menuitem name="ViewStyleDoubleLine"   	action="ViewStyleDoubleLineAction"/>
+      </placeholder>
+    </menu>
+
+    <menu name="Actions" action="ActionsAction">
+      <placeholder name="ActionsPlaceholder">
+        <separator name="ActionsSep1"/>
+	<menuitem name="ActionsTransfer"         action="ActionsTransferAction"/>
+	<menuitem name="ActionsReconcile"        action="ActionsReconcileAction"/>
+	<menuitem name="ActionsStockSplit"       action="ActionsStockSplitAction"/>
+	<menuitem name="ActionLots"              action="ActionsLotsAction"/>
+        <separator name="ActionsSep4"/>
+        <menuitem name="BlankTransaction"        action="BlankTransactionAction"/>
+        <menuitem name="SplitTransaction"        action="SplitTransactionAction"/>
+        <menuitem name="EditExchangeRate"        action="EditExchangeRateAction"/>
+        <menuitem name="ScheduleTransaction"     action="ScheduleTransactionAction"/>
+        <menuitem name="JumpTransaction"         action="JumpTransactionAction"/>
+	<separator name="ActionsSep5"/>
+      </placeholder>
+      <menu name="ScrubMenu" action="ScrubMenuAction">
+	<menuitem name="ScrubAll" action="ScrubAllAction"/>
+	<menuitem name="ScrubCurrent" action="ScrubCurrentAction"/>
+      </menu>
+    </menu>
+
+    <menu name="Reports" action="ReportsAction">
+      <placeholder name="AccountReports">
+        <menuitem name="ReportsAccountReport"      action="ReportsAccountReportAction"/>
+        <menuitem name="ReportsAcctTransReport"    action="ReportsAcctTransReportAction"/>
+      </placeholder>
+    </menu>
+  </menubar>
+
+  <toolbar name="DefaultToolbar">
+    <placeholder name="DefaultToolbarPlaceholder">
+      <toolitem name="ToolbarDuplicateTransaction" action="DuplicateTransactionAction"/>
+      <toolitem name="ToolbarDeleteTransaction"    action="DeleteTransactionAction"/>
+      <separator name="ToolbarSep66"/>
+      <toolitem name="ToolbarRecordTransaction"    action="RecordTransactionAction"/>
+      <toolitem name="ToolbarCancelTransaction"    action="CancelTransactionAction"/>
+      <separator name="ToolbarSep67"/>
+      <toolitem name="ToolbarBlankTransaction"     action="BlankTransactionAction"/>
+      <toolitem name="ToolbarSplitTransaction"     action="SplitTransactionAction"/>
+      <toolitem name="ToolbarJumpTransaction"      action="JumpTransactionAction"/>
+      <toolitem name="ToolbarScheduleTransaction"  action="ScheduleTransactionAction"/>
+      <separator name="ToolbarSep68"/>
+      <toolitem name="ToolbarTransfer"             action="ActionsTransferAction"/>
+      <toolitem name="ActionsReconcile"            action="ActionsReconcileAction"/>
+    </placeholder>
+  </toolbar>
+
+  <popup name="MainPopup"                    action="FakeToplevel">
+    <placeholder name="PopupPlaceholder1">
+      <menuitem name="ViewSortBy"              action="ViewSortByAction"/>
+      <menuitem name="ViewFilterBy"            action="ViewFilterByAction"/>
+    </placeholder>
+    <placeholder name="PopupPlaceholder2">
+      <menuitem name="DuplicateTransaction"    action="DuplicateTransactionAction"/>
+      <menuitem name="DeleteTransaction"       action="DeleteTransactionAction"/>
+      <menuitem name="RemoveTransactionSplits" action="RemoveTransactionSplitsAction"/>
+      <!--menuitem name="ShiftTransactionForward" 	action="ShiftTransactionForwardAction"/-->
+      <separator name="PopupSep2"/>
+      <menuitem name="RecordTransaction"       action="RecordTransactionAction"/>
+      <menuitem name="CancelTransaction"       action="CancelTransactionAction"/>
+      <separator name="PopupSep3"/>
+      <menuitem name="BlankTransaction"        action="BlankTransactionAction"/>
+      <menuitem name="SplitTransaction"        action="SplitTransactionAction"/>
+      <menuitem name="EditExchangeRate"        action="EditExchangeRateAction"/>
+      <menuitem name="ScheduleTransaction"     action="ScheduleTransactionAction"/>
+      <menuitem name="JumpTransaction"         action="JumpTransactionAction"/>
+    </placeholder>
+  </popup>
+</ui>
Index: src/gnome/ui/Makefile.am
===================================================================
--- src/gnome/ui/Makefile.am	(revision 22178)
+++ src/gnome/ui/Makefile.am	(working copy)
@@ -7,7 +7,9 @@
 	gnc-plugin-page-account-tree-ui.xml \
 	gnc-plugin-file-history-ui.xml \
 	gnc-plugin-register-ui.xml \
+	gnc-plugin-register2-ui.xml \
 	gnc-plugin-page-register-ui.xml \
+	gnc-plugin-page-register2-ui.xml \
         gnc-plugin-page-sx-list-ui.xml \
 	gnc-plugin-page-sxregister-ui.xml \
 	gnc-sxed-to-create-window-ui.xml \
Index: src/gnome/ui/gnc-plugin-page-account-tree-ui.xml
===================================================================
--- src/gnome/ui/gnc-plugin-page-account-tree-ui.xml	(revision 22178)
+++ src/gnome/ui/gnc-plugin-page-account-tree-ui.xml	(working copy)
@@ -7,6 +7,7 @@
 	<menuitem name="EditRenumberSubaccounts" action="EditRenumberSubaccountsAction"/>
         <separator name="EditSep2"/>
         <menuitem name="FileOpenAccount" action="FileOpenAccountAction"/>
+        <menuitem name="FileOpenAccount2" action="FileOpenAccount2Action"/>
         <menuitem name="FileOpenSubaccounts" action="FileOpenSubaccountsAction"/>
       </placeholder>
     </menu>
@@ -34,6 +35,7 @@
   <popup name="MainPopup" action="FakeToplevel">
     <placeholder name="PopupPlaceholder2">
       <menuitem name="AccountOpenAccount" action="FileOpenAccountAction"/>
+      <menuitem name="AccountOpenAccount2" action="FileOpenAccount2Action"/>
       <menuitem name="AccountOpenSubaccounts" action="FileOpenSubaccountsAction"/>
       <menuitem name="AccountEditAccount" action="EditEditAccountAction"/>
       <separator name="AccountSep1"/>
@@ -60,6 +62,7 @@
     <placeholder name="DefaultToolbarPlaceholder">
       <separator name="ToolbarSep2"/>
       <toolitem name="ToolbarOpenAccount" action="FileOpenAccountAction"/>
+      <toolitem name="ToolbarOpenAccount2" action="FileOpenAccount2Action"/>
       <toolitem name="ToolbarEditAccount" action="EditEditAccountAction"/>
       <separator name="ToolbarSep3"/>
       <toolitem name="ToolbarNewAccount" action="FileNewAccountAction"/>
